fsl_flexio_i2c_master.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  4. * Copyright 2016-2017 NXP
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without modification,
  8. * are permitted (subject to the limitations in the disclaimer below) provided
  9. * that the following conditions are met:
  10. *
  11. * o Redistributions of source code must retain the above copyright notice, this list
  12. * of conditions and the following disclaimer.
  13. *
  14. * o Redistributions in binary form must reproduce the above copyright notice, this
  15. * list of conditions and the following disclaimer in the documentation and/or
  16. * other materials provided with the distribution.
  17. *
  18. * o Neither the name of the copyright holder nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include "fsl_flexio_i2c_master.h"
  35. /*******************************************************************************
  36. * Definitions
  37. ******************************************************************************/
  38. /* Component ID definition, used by tools. */
  39. #ifndef FSL_COMPONENT_ID
  40. #define FSL_COMPONENT_ID "platform.drivers.flexio_i2c_master"
  41. #endif
  42. /*! @brief FLEXIO I2C transfer state */
  43. enum _flexio_i2c_master_transfer_states
  44. {
  45. kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
  46. kFLEXIO_I2C_CheckAddress = 0x1U, /*!< 7-bit address check state */
  47. kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
  48. kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
  49. kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
  50. kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
  51. };
  52. /*******************************************************************************
  53. * Prototypes
  54. ******************************************************************************/
  55. /*!
  56. * @brief Set up master transfer, send slave address and decide the initial
  57. * transfer state.
  58. *
  59. * @param base pointer to FLEXIO_I2C_Type structure
  60. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  61. * @param transfer pointer to flexio_i2c_master_transfer_t structure
  62. */
  63. static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
  64. flexio_i2c_master_handle_t *handle,
  65. flexio_i2c_master_transfer_t *xfer);
  66. /*!
  67. * @brief Master run transfer state machine to perform a byte of transfer.
  68. *
  69. * @param base pointer to FLEXIO_I2C_Type structure
  70. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  71. * @param statusFlags flexio i2c hardware status
  72. * @retval kStatus_Success Successfully run state machine
  73. * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
  74. */
  75. static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
  76. flexio_i2c_master_handle_t *handle,
  77. uint32_t statusFlags);
  78. /*!
  79. * @brief Complete transfer, disable interrupt and call callback.
  80. *
  81. * @param base pointer to FLEXIO_I2C_Type structure
  82. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  83. * @param status flexio transfer status
  84. */
  85. static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
  86. flexio_i2c_master_handle_t *handle,
  87. status_t status);
  88. /*******************************************************************************
  89. * Codes
  90. ******************************************************************************/
  91. static uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
  92. {
  93. return FLEXIO_GetInstance(base->flexioBase);
  94. }
  95. static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
  96. flexio_i2c_master_handle_t *handle,
  97. flexio_i2c_master_transfer_t *xfer)
  98. {
  99. bool needRestart;
  100. uint32_t byteCount;
  101. /* Init the handle member. */
  102. handle->transfer.slaveAddress = xfer->slaveAddress;
  103. handle->transfer.direction = xfer->direction;
  104. handle->transfer.subaddress = xfer->subaddress;
  105. handle->transfer.subaddressSize = xfer->subaddressSize;
  106. handle->transfer.data = xfer->data;
  107. handle->transfer.dataSize = xfer->dataSize;
  108. handle->transfer.flags = xfer->flags;
  109. handle->transferSize = xfer->dataSize;
  110. /* Initial state, i2c check address state. */
  111. handle->state = kFLEXIO_I2C_CheckAddress;
  112. /* Clear all status before transfer. */
  113. FLEXIO_I2C_MasterClearStatusFlags(base, kFLEXIO_I2C_ReceiveNakFlag);
  114. /* Calculate whether need to send re-start. */
  115. needRestart = (handle->transfer.subaddressSize != 0) && (handle->transfer.direction == kFLEXIO_I2C_Read);
  116. /* Calculate total byte count in a frame. */
  117. byteCount = 1;
  118. if (!needRestart)
  119. {
  120. byteCount += handle->transfer.dataSize;
  121. }
  122. if (handle->transfer.subaddressSize != 0)
  123. {
  124. byteCount += handle->transfer.subaddressSize;
  125. /* Next state, send command byte. */
  126. handle->state = kFLEXIO_I2C_SendCommand;
  127. }
  128. /* Configure data count. */
  129. if (FLEXIO_I2C_MasterSetTransferCount(base, byteCount) != kStatus_Success)
  130. {
  131. return kStatus_InvalidArgument;
  132. }
  133. while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
  134. {
  135. }
  136. /* Send address byte first. */
  137. if (needRestart)
  138. {
  139. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
  140. }
  141. else
  142. {
  143. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
  144. }
  145. return kStatus_Success;
  146. }
  147. static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
  148. flexio_i2c_master_handle_t *handle,
  149. uint32_t statusFlags)
  150. {
  151. if (statusFlags & kFLEXIO_I2C_ReceiveNakFlag)
  152. {
  153. /* Clear receive nak flag. */
  154. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
  155. if ((!((handle->state == kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
  156. (!(((handle->state == kFLEXIO_I2C_ReceiveData) || (handle->state == kFLEXIO_I2C_ReceiveDataBegin)) &&
  157. (handle->transfer.dataSize == 1U))))
  158. {
  159. FLEXIO_I2C_MasterReadByte(base);
  160. FLEXIO_I2C_MasterAbortStop(base);
  161. handle->state = kFLEXIO_I2C_Idle;
  162. return kStatus_FLEXIO_I2C_Nak;
  163. }
  164. }
  165. if (handle->state == kFLEXIO_I2C_CheckAddress)
  166. {
  167. if (handle->transfer.direction == kFLEXIO_I2C_Write)
  168. {
  169. /* Next state, send data. */
  170. handle->state = kFLEXIO_I2C_SendData;
  171. }
  172. else
  173. {
  174. /* Next state, receive data begin. */
  175. handle->state = kFLEXIO_I2C_ReceiveDataBegin;
  176. }
  177. }
  178. if ((statusFlags & kFLEXIO_I2C_RxFullFlag) && (handle->state != kFLEXIO_I2C_ReceiveData))
  179. {
  180. FLEXIO_I2C_MasterReadByte(base);
  181. }
  182. switch (handle->state)
  183. {
  184. case kFLEXIO_I2C_SendCommand:
  185. if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
  186. {
  187. if (handle->transfer.subaddressSize > 0)
  188. {
  189. handle->transfer.subaddressSize--;
  190. FLEXIO_I2C_MasterWriteByte(
  191. base, ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)));
  192. if (handle->transfer.subaddressSize == 0)
  193. {
  194. /* Load re-start in advance. */
  195. if (handle->transfer.direction == kFLEXIO_I2C_Read)
  196. {
  197. while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
  198. {
  199. }
  200. FLEXIO_I2C_MasterRepeatedStart(base);
  201. }
  202. }
  203. }
  204. else
  205. {
  206. if (handle->transfer.direction == kFLEXIO_I2C_Write)
  207. {
  208. /* Next state, send data. */
  209. handle->state = kFLEXIO_I2C_SendData;
  210. /* Send first byte of data. */
  211. if (handle->transfer.dataSize > 0)
  212. {
  213. FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
  214. handle->transfer.data++;
  215. handle->transfer.dataSize--;
  216. }
  217. }
  218. else
  219. {
  220. FLEXIO_I2C_MasterSetTransferCount(base, (handle->transfer.dataSize + 1));
  221. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
  222. /* Next state, receive data begin. */
  223. handle->state = kFLEXIO_I2C_ReceiveDataBegin;
  224. }
  225. }
  226. }
  227. break;
  228. /* Send command byte. */
  229. case kFLEXIO_I2C_SendData:
  230. if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
  231. {
  232. /* Send one byte of data. */
  233. if (handle->transfer.dataSize > 0)
  234. {
  235. FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
  236. handle->transfer.data++;
  237. handle->transfer.dataSize--;
  238. }
  239. else
  240. {
  241. FLEXIO_I2C_MasterStop(base);
  242. while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
  243. {
  244. }
  245. FLEXIO_I2C_MasterReadByte(base);
  246. handle->state = kFLEXIO_I2C_Idle;
  247. }
  248. }
  249. break;
  250. case kFLEXIO_I2C_ReceiveDataBegin:
  251. if (statusFlags & kFLEXIO_I2C_RxFullFlag)
  252. {
  253. handle->state = kFLEXIO_I2C_ReceiveData;
  254. /* Send nak at the last receive byte. */
  255. if (handle->transfer.dataSize == 1)
  256. {
  257. FLEXIO_I2C_MasterEnableAck(base, false);
  258. while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
  259. {
  260. }
  261. FLEXIO_I2C_MasterStop(base);
  262. }
  263. else
  264. {
  265. FLEXIO_I2C_MasterEnableAck(base, true);
  266. }
  267. }
  268. else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
  269. {
  270. /* Read one byte of data. */
  271. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  272. }
  273. else
  274. {
  275. }
  276. break;
  277. case kFLEXIO_I2C_ReceiveData:
  278. if (statusFlags & kFLEXIO_I2C_RxFullFlag)
  279. {
  280. *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
  281. handle->transfer.data++;
  282. if (handle->transfer.dataSize--)
  283. {
  284. if (handle->transfer.dataSize == 0)
  285. {
  286. FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_RxFullInterruptEnable);
  287. handle->state = kFLEXIO_I2C_Idle;
  288. }
  289. /* Send nak at the last receive byte. */
  290. if (handle->transfer.dataSize == 1)
  291. {
  292. FLEXIO_I2C_MasterEnableAck(base, false);
  293. while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0]))))
  294. {
  295. }
  296. FLEXIO_I2C_MasterStop(base);
  297. }
  298. }
  299. }
  300. else if (statusFlags & kFLEXIO_I2C_TxEmptyFlag)
  301. {
  302. if (handle->transfer.dataSize > 1)
  303. {
  304. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  305. }
  306. }
  307. else
  308. {
  309. }
  310. break;
  311. default:
  312. break;
  313. }
  314. return kStatus_Success;
  315. }
  316. static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
  317. flexio_i2c_master_handle_t *handle,
  318. status_t status)
  319. {
  320. FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
  321. if (handle->completionCallback)
  322. {
  323. handle->completionCallback(base, handle, status, handle->userData);
  324. }
  325. }
  326. status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
  327. {
  328. assert(base && masterConfig);
  329. flexio_shifter_config_t shifterConfig;
  330. flexio_timer_config_t timerConfig;
  331. uint32_t controlVal = 0;
  332. uint16_t timerDiv = 0;
  333. status_t result = kStatus_Success;
  334. memset(&shifterConfig, 0, sizeof(shifterConfig));
  335. memset(&timerConfig, 0, sizeof(timerConfig));
  336. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  337. /* Ungate flexio clock. */
  338. CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
  339. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  340. /* Do hardware configuration. */
  341. /* 1. Configure the shifter 0 for tx. */
  342. shifterConfig.timerSelect = base->timerIndex[1];
  343. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  344. shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
  345. shifterConfig.pinSelect = base->SDAPinIndex;
  346. shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
  347. shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
  348. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  349. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
  350. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
  351. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
  352. /* 2. Configure the shifter 1 for rx. */
  353. shifterConfig.timerSelect = base->timerIndex[1];
  354. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  355. shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  356. shifterConfig.pinSelect = base->SDAPinIndex;
  357. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  358. shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
  359. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  360. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
  361. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  362. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
  363. /*3. Configure the timer 0 for generating bit clock. */
  364. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  365. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  366. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  367. timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
  368. timerConfig.pinSelect = base->SCLPinIndex;
  369. timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  370. timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit;
  371. timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
  372. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
  373. timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
  374. timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
  375. timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
  376. timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable;
  377. timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
  378. /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1. */
  379. timerDiv = (srcClock_Hz / masterConfig->baudRate_Bps) / 2 - 1;
  380. if (timerDiv > 0xFFU)
  381. {
  382. result = kStatus_InvalidArgument;
  383. return result;
  384. }
  385. timerConfig.timerCompare = timerDiv;
  386. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
  387. /* 4. Configure the timer 1 for controlling shifters. */
  388. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  389. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  390. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  391. timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  392. timerConfig.pinSelect = base->SCLPinIndex;
  393. timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
  394. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  395. timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
  396. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
  397. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  398. timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
  399. timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
  400. timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
  401. timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
  402. /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
  403. timerConfig.timerCompare = 8 * 2 - 1;
  404. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
  405. /* Configure FLEXIO I2C Master. */
  406. controlVal = base->flexioBase->CTRL;
  407. controlVal &=
  408. ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  409. controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
  410. FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
  411. if (!masterConfig->enableInDoze)
  412. {
  413. controlVal |= FLEXIO_CTRL_DOZEN_MASK;
  414. }
  415. base->flexioBase->CTRL = controlVal;
  416. return result;
  417. }
  418. void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
  419. {
  420. base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
  421. base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
  422. base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
  423. base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
  424. base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
  425. base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
  426. base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
  427. base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
  428. base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
  429. base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
  430. /* Clear the shifter flag. */
  431. base->flexioBase->SHIFTSTAT = (1U << base->shifterIndex[0]);
  432. base->flexioBase->SHIFTSTAT = (1U << base->shifterIndex[1]);
  433. /* Clear the timer flag. */
  434. base->flexioBase->TIMSTAT = (1U << base->timerIndex[0]);
  435. base->flexioBase->TIMSTAT = (1U << base->timerIndex[1]);
  436. }
  437. void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
  438. {
  439. assert(masterConfig);
  440. masterConfig->enableMaster = true;
  441. masterConfig->enableInDoze = false;
  442. masterConfig->enableInDebug = true;
  443. masterConfig->enableFastAccess = false;
  444. /* Default baud rate at 100kbps. */
  445. masterConfig->baudRate_Bps = 100000U;
  446. }
  447. uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
  448. {
  449. uint32_t status = 0;
  450. status =
  451. ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[0])) >> base->shifterIndex[0]);
  452. status |=
  453. (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
  454. << 1U);
  455. status |=
  456. (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1U << base->shifterIndex[1])) >> (base->shifterIndex[1]))
  457. << 2U);
  458. return status;
  459. }
  460. void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
  461. {
  462. if (mask & kFLEXIO_I2C_TxEmptyFlag)
  463. {
  464. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[0]);
  465. }
  466. if (mask & kFLEXIO_I2C_RxFullFlag)
  467. {
  468. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1U << base->shifterIndex[1]);
  469. }
  470. if (mask & kFLEXIO_I2C_ReceiveNakFlag)
  471. {
  472. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
  473. }
  474. }
  475. void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
  476. {
  477. if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
  478. {
  479. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
  480. }
  481. if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
  482. {
  483. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
  484. }
  485. }
  486. void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
  487. {
  488. if (mask & kFLEXIO_I2C_TxEmptyInterruptEnable)
  489. {
  490. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[0]);
  491. }
  492. if (mask & kFLEXIO_I2C_RxFullInterruptEnable)
  493. {
  494. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1U << base->shifterIndex[1]);
  495. }
  496. }
  497. void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
  498. {
  499. uint16_t timerDiv = 0;
  500. uint16_t timerCmp = 0;
  501. FLEXIO_Type *flexioBase = base->flexioBase;
  502. /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/
  503. timerDiv = srcClock_Hz / baudRate_Bps;
  504. timerDiv = timerDiv / 2 - 1U;
  505. timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
  506. timerCmp &= 0xFF00;
  507. timerCmp |= timerDiv;
  508. flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
  509. }
  510. status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint8_t count)
  511. {
  512. if (count > 14U)
  513. {
  514. return kStatus_InvalidArgument;
  515. }
  516. uint16_t timerCmp = 0;
  517. uint32_t timerConfig = 0;
  518. FLEXIO_Type *flexioBase = base->flexioBase;
  519. timerCmp = flexioBase->TIMCMP[base->timerIndex[0]];
  520. timerCmp &= 0x00FFU;
  521. timerCmp |= (count * 18 + 1U) << 8U;
  522. flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp;
  523. timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
  524. timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  525. timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
  526. flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
  527. return kStatus_Success;
  528. }
  529. void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
  530. {
  531. uint32_t data;
  532. data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
  533. FLEXIO_I2C_MasterWriteByte(base, data);
  534. }
  535. void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
  536. {
  537. /* Prepare for RESTART condition, no stop.*/
  538. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  539. }
  540. void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
  541. {
  542. /* Prepare normal stop. */
  543. FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
  544. FLEXIO_I2C_MasterWriteByte(base, 0x0U);
  545. }
  546. void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
  547. {
  548. uint32_t tmpConfig;
  549. /* Prepare abort stop. */
  550. tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
  551. tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  552. tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
  553. base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
  554. }
  555. void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
  556. {
  557. uint32_t tmpConfig = 0;
  558. tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
  559. tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
  560. if (enable)
  561. {
  562. tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
  563. }
  564. else
  565. {
  566. tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
  567. }
  568. base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
  569. }
  570. status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
  571. {
  572. assert(txBuff);
  573. assert(txSize);
  574. uint32_t status;
  575. while (txSize--)
  576. {
  577. FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
  578. /* Wait until data transfer complete. */
  579. while (!((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & kFLEXIO_I2C_RxFullFlag))
  580. {
  581. }
  582. if (status & kFLEXIO_I2C_ReceiveNakFlag)
  583. {
  584. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1U << base->shifterIndex[1]);
  585. return kStatus_FLEXIO_I2C_Nak;
  586. }
  587. }
  588. return kStatus_Success;
  589. }
  590. void FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
  591. {
  592. assert(rxBuff);
  593. assert(rxSize);
  594. while (rxSize--)
  595. {
  596. /* Wait until data transfer complete. */
  597. while (!(FLEXIO_I2C_MasterGetStatusFlags(base) & kFLEXIO_I2C_RxFullFlag))
  598. {
  599. }
  600. *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
  601. }
  602. }
  603. status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
  604. {
  605. assert(xfer);
  606. flexio_i2c_master_handle_t tmpHandle;
  607. uint32_t statusFlags;
  608. uint32_t result = kStatus_Success;
  609. /* Zero the handle. */
  610. memset(&tmpHandle, 0, sizeof(tmpHandle));
  611. /* Set up transfer machine. */
  612. FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
  613. do
  614. {
  615. /* Wait either tx empty or rx full flag is asserted. */
  616. while (!((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
  617. (kFLEXIO_I2C_TxEmptyFlag | kFLEXIO_I2C_RxFullFlag)))
  618. {
  619. }
  620. result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
  621. } while ((tmpHandle.state != kFLEXIO_I2C_Idle) && (result == kStatus_Success));
  622. return result;
  623. }
  624. status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
  625. flexio_i2c_master_handle_t *handle,
  626. flexio_i2c_master_transfer_callback_t callback,
  627. void *userData)
  628. {
  629. assert(handle);
  630. IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
  631. /* Zero the handle. */
  632. memset(handle, 0, sizeof(*handle));
  633. /* Register callback and userData. */
  634. handle->completionCallback = callback;
  635. handle->userData = userData;
  636. /* Enable interrupt in NVIC. */
  637. EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
  638. /* Save the context in global variables to support the double weak mechanism. */
  639. return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
  640. }
  641. status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
  642. flexio_i2c_master_handle_t *handle,
  643. flexio_i2c_master_transfer_t *xfer)
  644. {
  645. assert(handle);
  646. assert(xfer);
  647. if (handle->state != kFLEXIO_I2C_Idle)
  648. {
  649. return kStatus_FLEXIO_I2C_Busy;
  650. }
  651. else
  652. {
  653. /* Set up transfer machine. */
  654. FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
  655. /* Enable both tx empty and rxfull interrupt. */
  656. FLEXIO_I2C_MasterEnableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
  657. return kStatus_Success;
  658. }
  659. }
  660. void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
  661. {
  662. assert(handle);
  663. /* Disable interrupts. */
  664. FLEXIO_I2C_MasterDisableInterrupts(base, kFLEXIO_I2C_TxEmptyInterruptEnable | kFLEXIO_I2C_RxFullInterruptEnable);
  665. /* Reset to idle state. */
  666. handle->state = kFLEXIO_I2C_Idle;
  667. }
  668. status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
  669. {
  670. if (!count)
  671. {
  672. return kStatus_InvalidArgument;
  673. }
  674. *count = handle->transferSize - handle->transfer.dataSize;
  675. return kStatus_Success;
  676. }
  677. void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
  678. {
  679. FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
  680. flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
  681. uint32_t statusFlags;
  682. status_t result;
  683. statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
  684. result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
  685. if (handle->state == kFLEXIO_I2C_Idle)
  686. {
  687. FLEXIO_I2C_MasterTransferComplete(base, handle, result);
  688. }
  689. }