fsl_flexio_i2c_master.c 46 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2020 NXP
  4. * All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_flexio_i2c_master.h"
  9. /*******************************************************************************
  10. * Definitions
  11. ******************************************************************************/
  12. /* Component ID definition, used by tools. */
  13. #ifndef FSL_COMPONENT_ID
  14. #define FSL_COMPONENT_ID "platform.drivers.flexio_i2c_master"
  15. #endif
  16. /*! @brief FLEXIO I2C transfer state */
  17. enum _flexio_i2c_master_transfer_states
  18. {
  19. kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */
  20. kFLEXIO_I2C_Start = 0x1U, /*!< I2C start phase */
  21. kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */
  22. kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/
  23. kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/
  24. kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/
  25. };
  26. /*******************************************************************************
  27. * Prototypes
  28. ******************************************************************************/
  29. /*!
  30. * @brief Set up master transfer, send slave address and decide the initial
  31. * transfer state.
  32. *
  33. * @param base pointer to FLEXIO_I2C_Type structure
  34. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  35. * @param transfer pointer to flexio_i2c_master_transfer_t structure
  36. */
  37. static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
  38. flexio_i2c_master_handle_t *handle,
  39. flexio_i2c_master_transfer_t *xfer);
  40. /*!
  41. * @brief Master run transfer state machine to perform a byte of transfer.
  42. *
  43. * @param base pointer to FLEXIO_I2C_Type structure
  44. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  45. * @param statusFlags flexio i2c hardware status
  46. * @retval kStatus_Success Successfully run state machine
  47. * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer
  48. */
  49. static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
  50. flexio_i2c_master_handle_t *handle,
  51. uint32_t statusFlags);
  52. /*!
  53. * @brief Complete transfer, disable interrupt and call callback.
  54. *
  55. * @param base pointer to FLEXIO_I2C_Type structure
  56. * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  57. * @param status flexio transfer status
  58. */
  59. static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
  60. flexio_i2c_master_handle_t *handle,
  61. status_t status);
  62. /*******************************************************************************
  63. * Codes
  64. ******************************************************************************/
  65. static uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base)
  66. {
  67. return FLEXIO_GetInstance(base->flexioBase);
  68. }
  69. static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base,
  70. flexio_i2c_master_handle_t *handle,
  71. flexio_i2c_master_transfer_t *xfer)
  72. {
  73. bool needRestart;
  74. uint32_t byteCount;
  75. /* Init the handle member. */
  76. handle->transfer.slaveAddress = xfer->slaveAddress;
  77. handle->transfer.direction = xfer->direction;
  78. handle->transfer.subaddress = xfer->subaddress;
  79. handle->transfer.subaddressSize = xfer->subaddressSize;
  80. handle->transfer.data = xfer->data;
  81. handle->transfer.dataSize = xfer->dataSize;
  82. handle->transfer.flags = xfer->flags;
  83. handle->transferSize = xfer->dataSize;
  84. /* Initial state, i2c start state. */
  85. handle->state = (uint8_t)kFLEXIO_I2C_Start;
  86. /* Clear all status before transfer. */
  87. FLEXIO_I2C_MasterClearStatusFlags(base, (uint32_t)kFLEXIO_I2C_ReceiveNakFlag);
  88. /* Calculate whether need to send re-start. */
  89. needRestart = (handle->transfer.subaddressSize != 0U) && (handle->transfer.direction == kFLEXIO_I2C_Read);
  90. handle->needRestart = needRestart;
  91. /* Calculate total byte count in a frame. */
  92. byteCount = 1U;
  93. if (!needRestart)
  94. {
  95. byteCount += handle->transfer.dataSize;
  96. }
  97. if (handle->transfer.subaddressSize != 0U)
  98. {
  99. byteCount += handle->transfer.subaddressSize;
  100. }
  101. /* Configure data count. */
  102. if (FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)byteCount) != kStatus_Success)
  103. {
  104. return kStatus_InvalidArgument;
  105. }
  106. /* Configure timer1 disable condition. */
  107. uint32_t tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
  108. tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  109. tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPreTimerDisable);
  110. base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
  111. #if I2C_RETRY_TIMES
  112. uint32_t waitTimes = I2C_RETRY_TIMES;
  113. while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
  114. (0U != --waitTimes))
  115. {
  116. }
  117. if (0U == waitTimes)
  118. {
  119. return kStatus_FLEXIO_I2C_Timeout;
  120. }
  121. #else
  122. while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
  123. {
  124. }
  125. #endif
  126. return kStatus_Success;
  127. }
  128. static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base,
  129. flexio_i2c_master_handle_t *handle,
  130. uint32_t statusFlags)
  131. {
  132. #if I2C_RETRY_TIMES
  133. uint32_t waitTimes = I2C_RETRY_TIMES;
  134. #endif
  135. if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
  136. {
  137. /* Clear receive nak flag. */
  138. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
  139. if ((!((handle->state == (uint8_t)kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) &&
  140. (!(((handle->state == (uint8_t)kFLEXIO_I2C_ReceiveData) ||
  141. (handle->state == (uint8_t)kFLEXIO_I2C_ReceiveDataBegin)) &&
  142. (handle->transfer.dataSize == 1U))))
  143. {
  144. (void)FLEXIO_I2C_MasterReadByte(base);
  145. FLEXIO_I2C_MasterAbortStop(base);
  146. /* Delay one clk cycle to ensure the bus is idle. */
  147. SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  148. handle->state = (uint8_t)kFLEXIO_I2C_Idle;
  149. return kStatus_FLEXIO_I2C_Nak;
  150. }
  151. }
  152. if (((statusFlags & (uint8_t)kFLEXIO_I2C_RxFullFlag) != 0U) && (handle->state != (uint8_t)kFLEXIO_I2C_ReceiveData))
  153. {
  154. (void)FLEXIO_I2C_MasterReadByte(base);
  155. }
  156. switch (handle->state)
  157. {
  158. /* Initial state, i2c start state. */
  159. case (uint8_t)kFLEXIO_I2C_Start:
  160. /* Send address byte first. */
  161. if (handle->needRestart)
  162. {
  163. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write);
  164. }
  165. else
  166. {
  167. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction);
  168. }
  169. if (handle->transfer.subaddressSize == 0U)
  170. {
  171. if (handle->transfer.direction == kFLEXIO_I2C_Write)
  172. {
  173. /* Next state, send data. */
  174. handle->state = (uint8_t)kFLEXIO_I2C_SendData;
  175. }
  176. else
  177. {
  178. /* Next state, receive data begin. */
  179. handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
  180. }
  181. }
  182. else
  183. {
  184. /* Next state, send command byte. */
  185. handle->state = (uint8_t)kFLEXIO_I2C_SendCommand;
  186. }
  187. break;
  188. /* Check address only needed for transfer with subaddress */
  189. case (uint8_t)kFLEXIO_I2C_SendCommand:
  190. if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
  191. {
  192. if (handle->transfer.subaddressSize > 0U)
  193. {
  194. handle->transfer.subaddressSize--;
  195. FLEXIO_I2C_MasterWriteByte(
  196. base, ((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize)));
  197. if (handle->transfer.subaddressSize == 0U)
  198. {
  199. /* Load re-start in advance. */
  200. if (handle->transfer.direction == kFLEXIO_I2C_Read)
  201. {
  202. #if I2C_RETRY_TIMES
  203. while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) &
  204. (1UL << base->shifterIndex[0]))) &&
  205. (0U != --waitTimes))
  206. {
  207. }
  208. if (0U == waitTimes)
  209. {
  210. return kStatus_FLEXIO_I2C_Timeout;
  211. }
  212. #else
  213. while (0U ==
  214. (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
  215. {
  216. }
  217. #endif
  218. FLEXIO_I2C_MasterRepeatedStart(base);
  219. }
  220. }
  221. }
  222. else
  223. {
  224. if (handle->transfer.direction == kFLEXIO_I2C_Write)
  225. {
  226. /* Send first byte of data. */
  227. if (handle->transfer.dataSize > 0U)
  228. {
  229. /* Next state, send data. */
  230. handle->state = (uint8_t)kFLEXIO_I2C_SendData;
  231. FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
  232. handle->transfer.data++;
  233. handle->transfer.dataSize--;
  234. }
  235. else
  236. {
  237. FLEXIO_I2C_MasterStop(base);
  238. #if I2C_RETRY_TIMES
  239. while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
  240. (0U != --waitTimes))
  241. {
  242. }
  243. if (0U == waitTimes)
  244. {
  245. return kStatus_FLEXIO_I2C_Timeout;
  246. }
  247. #else
  248. while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
  249. {
  250. }
  251. #endif
  252. (void)FLEXIO_I2C_MasterReadByte(base);
  253. handle->state = (uint8_t)kFLEXIO_I2C_Idle;
  254. }
  255. }
  256. else
  257. {
  258. (void)FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)(handle->transfer.dataSize + 1U));
  259. /* Delay at least one clock cycle so that the restart setup time is up to spec standard. */
  260. SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
  261. FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read);
  262. /* Next state, receive data begin. */
  263. handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin;
  264. }
  265. }
  266. }
  267. break;
  268. /* Send command byte. */
  269. case (uint8_t)kFLEXIO_I2C_SendData:
  270. if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
  271. {
  272. /* Send one byte of data. */
  273. if (handle->transfer.dataSize > 0U)
  274. {
  275. FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data);
  276. handle->transfer.data++;
  277. handle->transfer.dataSize--;
  278. }
  279. else
  280. {
  281. FLEXIO_I2C_MasterStop(base);
  282. #if I2C_RETRY_TIMES
  283. while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
  284. (0U != --waitTimes))
  285. {
  286. }
  287. if (0U == waitTimes)
  288. {
  289. return kStatus_FLEXIO_I2C_Timeout;
  290. }
  291. #else
  292. while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
  293. {
  294. }
  295. #endif
  296. (void)FLEXIO_I2C_MasterReadByte(base);
  297. handle->state = (uint8_t)kFLEXIO_I2C_Idle;
  298. }
  299. }
  300. break;
  301. case (uint8_t)kFLEXIO_I2C_ReceiveDataBegin:
  302. if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
  303. {
  304. handle->state = (uint8_t)kFLEXIO_I2C_ReceiveData;
  305. /* Send nak at the last receive byte. */
  306. if (handle->transfer.dataSize == 1U)
  307. {
  308. FLEXIO_I2C_MasterEnableAck(base, false);
  309. #if I2C_RETRY_TIMES
  310. while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
  311. (0U != --waitTimes))
  312. {
  313. }
  314. if (0U == waitTimes)
  315. {
  316. return kStatus_FLEXIO_I2C_Timeout;
  317. }
  318. #else
  319. while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
  320. {
  321. }
  322. #endif
  323. FLEXIO_I2C_MasterStop(base);
  324. }
  325. else
  326. {
  327. FLEXIO_I2C_MasterEnableAck(base, true);
  328. }
  329. }
  330. else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
  331. {
  332. /* Read one byte of data. */
  333. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  334. }
  335. else
  336. {
  337. ; /* Avoid MISRA 2012 rule 15.7 */
  338. }
  339. break;
  340. case (uint8_t)kFLEXIO_I2C_ReceiveData:
  341. if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
  342. {
  343. *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base);
  344. handle->transfer.data++;
  345. if (0U != handle->transfer.dataSize--)
  346. {
  347. if (handle->transfer.dataSize == 0U)
  348. {
  349. FLEXIO_I2C_MasterDisableInterrupts(base, (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
  350. handle->state = (uint8_t)kFLEXIO_I2C_Idle;
  351. /* Return nak if ReceiveNakFlag is not set */
  352. if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) == 0U)
  353. {
  354. return kStatus_FLEXIO_I2C_Nak;
  355. }
  356. }
  357. /* Send nak at the last receive byte. */
  358. if (handle->transfer.dataSize == 1U)
  359. {
  360. FLEXIO_I2C_MasterEnableAck(base, false);
  361. #if I2C_RETRY_TIMES
  362. while (
  363. (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) &&
  364. (0U != --waitTimes))
  365. {
  366. }
  367. if (0U == waitTimes)
  368. {
  369. return kStatus_FLEXIO_I2C_Timeout;
  370. }
  371. #else
  372. while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])))
  373. {
  374. }
  375. #endif
  376. FLEXIO_I2C_MasterStop(base);
  377. }
  378. }
  379. }
  380. else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
  381. {
  382. if (handle->transfer.dataSize > 1U)
  383. {
  384. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  385. }
  386. }
  387. else
  388. {
  389. ; /* Avoid MISRA 2012 rule 15.7 */
  390. }
  391. break;
  392. default:
  393. /* Add comment to avoid MISRA violation */
  394. break;
  395. }
  396. return kStatus_Success;
  397. }
  398. static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base,
  399. flexio_i2c_master_handle_t *handle,
  400. status_t status)
  401. {
  402. FLEXIO_I2C_MasterDisableInterrupts(
  403. base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
  404. if (handle->completionCallback != NULL)
  405. {
  406. handle->completionCallback(base, handle, status, handle->userData);
  407. }
  408. }
  409. #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
  410. /*!
  411. * brief Make sure the bus isn't already pulled down.
  412. *
  413. * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down.
  414. *
  415. * param base Pointer to FLEXIO_I2C_Type structure..
  416. * retval kStatus_Success
  417. * retval kStatus_FLEXIO_I2C_Busy
  418. */
  419. status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base)
  420. {
  421. uint32_t mask;
  422. /* If in certain loops the SDA/SCL is continuously pulled down, then return bus busy status. */
  423. /* The loop count is determined by maximum CPU clock frequency */
  424. for (uint32_t i = 0U; i < SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY / 600000U; ++i)
  425. {
  426. mask = 1UL << base->SDAPinIndex | 1UL << base->SCLPinIndex;
  427. if ((FLEXIO_ReadPinInput(base->flexioBase) & mask) == mask)
  428. {
  429. return kStatus_Success;
  430. }
  431. }
  432. return kStatus_FLEXIO_I2C_Busy;
  433. }
  434. #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
  435. /*!
  436. * brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C
  437. * hardware configuration.
  438. *
  439. * Example
  440. code
  441. FLEXIO_I2C_Type base = {
  442. .flexioBase = FLEXIO,
  443. .SDAPinIndex = 0,
  444. .SCLPinIndex = 1,
  445. .shifterIndex = {0,1},
  446. .timerIndex = {0,1}
  447. };
  448. flexio_i2c_master_config_t config = {
  449. .enableInDoze = false,
  450. .enableInDebug = true,
  451. .enableFastAccess = false,
  452. .baudRate_Bps = 100000
  453. };
  454. FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz);
  455. endcode
  456. *
  457. * param base Pointer to FLEXIO_I2C_Type structure.
  458. * param masterConfig Pointer to flexio_i2c_master_config_t structure.
  459. * param srcClock_Hz FlexIO source clock in Hz.
  460. * retval kStatus_Success Initialization successful
  461. * retval kStatus_InvalidArgument The source clock exceed upper range limitation
  462. */
  463. status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz)
  464. {
  465. assert((base != NULL) && (masterConfig != NULL));
  466. flexio_shifter_config_t shifterConfig;
  467. flexio_timer_config_t timerConfig;
  468. uint32_t controlVal = 0;
  469. uint16_t timerDiv = 0;
  470. status_t result = kStatus_Success;
  471. (void)memset(&shifterConfig, 0, sizeof(shifterConfig));
  472. (void)memset(&timerConfig, 0, sizeof(timerConfig));
  473. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  474. /* Ungate flexio clock. */
  475. CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]);
  476. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  477. /* Do hardware configuration. */
  478. /* 1. Configure the shifter 0 for tx. */
  479. shifterConfig.timerSelect = base->timerIndex[2];
  480. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive;
  481. shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
  482. shifterConfig.pinSelect = base->SDAPinIndex;
  483. shifterConfig.pinPolarity = kFLEXIO_PinActiveLow;
  484. shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit;
  485. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  486. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh;
  487. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow;
  488. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig);
  489. /* 2. Configure the shifter 1 for rx. */
  490. shifterConfig.timerSelect = base->timerIndex[2];
  491. shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive;
  492. shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  493. shifterConfig.pinSelect = base->SDAPinIndex;
  494. shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  495. shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive;
  496. shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin;
  497. shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow;
  498. shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable;
  499. FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig);
  500. /*3. Configure the timer 0 and timer 1 for generating bit clock. */
  501. /* timer 1 is used to config baudrate */
  502. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  503. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  504. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  505. timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection;
  506. timerConfig.pinSelect = base->SCLPinIndex;
  507. timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  508. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  509. timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset;
  510. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput;
  511. timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput;
  512. timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
  513. timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
  514. timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
  515. timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
  516. /* Set TIMCMP = (baud rate divider / 2) - 1. */
  517. timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps) / 2U - 1U;
  518. /* Calculate and assign the actual baudrate. */
  519. base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
  520. timerConfig.timerCompare = timerDiv;
  521. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig);
  522. /* timer 0 is used to config total shift clock edges */
  523. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  524. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  525. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  526. timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  527. timerConfig.pinSelect = base->SCLPinIndex;
  528. timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;
  529. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  530. timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
  531. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
  532. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  533. timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare;
  534. timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh;
  535. timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled;
  536. timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled;
  537. /* Set TIMCMP when confinguring transfer bytes. */
  538. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig);
  539. /* 4. Configure the timer 2 for controlling shifters. */
  540. timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]);
  541. timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow;
  542. timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal;
  543. timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  544. timerConfig.pinSelect = base->SCLPinIndex;
  545. timerConfig.pinPolarity = kFLEXIO_PinActiveLow;
  546. timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  547. timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
  548. timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
  549. timerConfig.timerReset = kFLEXIO_TimerResetNever;
  550. timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable;
  551. timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable;
  552. timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare;
  553. timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled;
  554. /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */
  555. timerConfig.timerCompare = 8U * 2U - 1U;
  556. FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[2], &timerConfig);
  557. /* Configure FLEXIO I2C Master. */
  558. controlVal = base->flexioBase->CTRL;
  559. controlVal &=
  560. ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK);
  561. controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) |
  562. FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster));
  563. if (!masterConfig->enableInDoze)
  564. {
  565. controlVal |= FLEXIO_CTRL_DOZEN_MASK;
  566. }
  567. base->flexioBase->CTRL = controlVal;
  568. /* Disable internal IRQs. */
  569. FLEXIO_I2C_MasterDisableInterrupts(
  570. base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
  571. return result;
  572. }
  573. /*!
  574. * brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master
  575. * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called.
  576. *
  577. * param base pointer to FLEXIO_I2C_Type structure.
  578. */
  579. void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base)
  580. {
  581. base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0;
  582. base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0;
  583. base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0;
  584. base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0;
  585. base->flexioBase->TIMCFG[base->timerIndex[0]] = 0;
  586. base->flexioBase->TIMCMP[base->timerIndex[0]] = 0;
  587. base->flexioBase->TIMCTL[base->timerIndex[0]] = 0;
  588. base->flexioBase->TIMCFG[base->timerIndex[1]] = 0;
  589. base->flexioBase->TIMCMP[base->timerIndex[1]] = 0;
  590. base->flexioBase->TIMCTL[base->timerIndex[1]] = 0;
  591. base->flexioBase->TIMCFG[base->timerIndex[2]] = 0;
  592. base->flexioBase->TIMCMP[base->timerIndex[2]] = 0;
  593. base->flexioBase->TIMCTL[base->timerIndex[2]] = 0;
  594. /* Clear the shifter flag. */
  595. base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[0]);
  596. base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[1]);
  597. /* Clear the timer flag. */
  598. base->flexioBase->TIMSTAT = (1UL << base->timerIndex[0]);
  599. base->flexioBase->TIMSTAT = (1UL << base->timerIndex[1]);
  600. base->flexioBase->TIMSTAT = (1UL << base->timerIndex[2]);
  601. }
  602. /*!
  603. * brief Gets the default configuration to configure the FlexIO module. The configuration
  604. * can be used directly for calling the FLEXIO_I2C_MasterInit().
  605. *
  606. * Example:
  607. code
  608. flexio_i2c_master_config_t config;
  609. FLEXIO_I2C_MasterGetDefaultConfig(&config);
  610. endcode
  611. * param masterConfig Pointer to flexio_i2c_master_config_t structure.
  612. */
  613. void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig)
  614. {
  615. assert(masterConfig != NULL);
  616. /* Initializes the configure structure to zero. */
  617. (void)memset(masterConfig, 0, sizeof(*masterConfig));
  618. masterConfig->enableMaster = true;
  619. masterConfig->enableInDoze = false;
  620. masterConfig->enableInDebug = true;
  621. masterConfig->enableFastAccess = false;
  622. /* Default baud rate at 100kbps. */
  623. masterConfig->baudRate_Bps = 100000U;
  624. }
  625. /*!
  626. * brief Gets the FlexIO I2C master status flags.
  627. *
  628. * param base Pointer to FLEXIO_I2C_Type structure
  629. * return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status.
  630. */
  631. uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base)
  632. {
  633. uint32_t status = 0;
  634. status =
  635. ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]);
  636. status |=
  637. (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
  638. << 1U);
  639. status |=
  640. (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1]))
  641. << 2U);
  642. return status;
  643. }
  644. /*!
  645. * brief Clears the FlexIO I2C master status flags.
  646. *
  647. * param base Pointer to FLEXIO_I2C_Type structure.
  648. * param mask Status flag.
  649. * The parameter can be any combination of the following values:
  650. * arg kFLEXIO_I2C_RxFullFlag
  651. * arg kFLEXIO_I2C_ReceiveNakFlag
  652. */
  653. void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask)
  654. {
  655. if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U)
  656. {
  657. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]);
  658. }
  659. if ((mask & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U)
  660. {
  661. FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
  662. }
  663. if ((mask & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
  664. {
  665. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
  666. }
  667. }
  668. /*!
  669. * brief Enables the FlexIO i2c master interrupt requests.
  670. *
  671. * param base Pointer to FLEXIO_I2C_Type structure.
  672. * param mask Interrupt source.
  673. * Currently only one interrupt request source:
  674. * arg kFLEXIO_I2C_TransferCompleteInterruptEnable
  675. */
  676. void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
  677. {
  678. if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
  679. {
  680. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
  681. }
  682. if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
  683. {
  684. FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
  685. }
  686. }
  687. /*!
  688. * brief Disables the FlexIO I2C master interrupt requests.
  689. *
  690. * param base Pointer to FLEXIO_I2C_Type structure.
  691. * param mask Interrupt source.
  692. */
  693. void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask)
  694. {
  695. if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U)
  696. {
  697. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]);
  698. }
  699. if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U)
  700. {
  701. FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]);
  702. }
  703. }
  704. /*!
  705. * brief Sets the FlexIO I2C master transfer baudrate.
  706. *
  707. * param base Pointer to FLEXIO_I2C_Type structure
  708. * param baudRate_Bps the baud rate value in HZ
  709. * param srcClock_Hz source clock in HZ
  710. */
  711. void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
  712. {
  713. uint16_t timerDiv = 0;
  714. FLEXIO_Type *flexioBase = base->flexioBase;
  715. /* Set TIMCMP = (baud rate divider / 2) - 1.*/
  716. timerDiv = (uint16_t)((srcClock_Hz / baudRate_Bps) / 2U - 1U);
  717. flexioBase->TIMCMP[base->timerIndex[1]] = timerDiv;
  718. /* Calculate and assign the actual baudrate. */
  719. base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U));
  720. }
  721. /*!
  722. * brief Sets the number of bytes to be transferred from a start signal to a stop signal.
  723. *
  724. * note Call this API before a transfer begins because the timer generates a number of clocks according
  725. * to the number of bytes that need to be transferred.
  726. *
  727. * param base Pointer to FLEXIO_I2C_Type structure.
  728. * param count Number of bytes need to be transferred from a start signal to a re-start/stop signal
  729. * retval kStatus_Success Successfully configured the count.
  730. * retval kStatus_InvalidArgument Input argument is invalid.
  731. */
  732. status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count)
  733. {
  734. /* Calculate whether the transfer count is larger than the max value compare register can achieve */
  735. if (count > ((0xFFFFUL - 1UL) / (16UL + 1UL + 1UL)))
  736. {
  737. return kStatus_InvalidArgument;
  738. }
  739. uint32_t timerConfig = 0U;
  740. FLEXIO_Type *flexioBase = base->flexioBase;
  741. flexioBase->TIMCMP[base->timerIndex[0]] = (uint32_t)count * 18U + 1U;
  742. timerConfig = flexioBase->TIMCFG[base->timerIndex[0]];
  743. timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  744. timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare);
  745. flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig;
  746. return kStatus_Success;
  747. }
  748. /*!
  749. * brief Sends START + 7-bit address to the bus.
  750. *
  751. * note This API should be called when the transfer configuration is ready to send a START signal
  752. * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address
  753. * is put into the data register but the address transfer is not finished on the bus. Ensure that
  754. * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API.
  755. * param base Pointer to FLEXIO_I2C_Type structure.
  756. * param address 7-bit address.
  757. * param direction transfer direction.
  758. * This parameter is one of the values in flexio_i2c_direction_t:
  759. * arg kFLEXIO_I2C_Write: Transmit
  760. * arg kFLEXIO_I2C_Read: Receive
  761. */
  762. void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction)
  763. {
  764. uint32_t data;
  765. data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U);
  766. FLEXIO_I2C_MasterWriteByte(base, data);
  767. }
  768. /*!
  769. * brief Sends the repeated start signal on the bus.
  770. *
  771. * param base Pointer to FLEXIO_I2C_Type structure.
  772. */
  773. void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base)
  774. {
  775. /* Prepare for RESTART condition, no stop.*/
  776. FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU);
  777. }
  778. /*!
  779. * brief Sends the stop signal on the bus.
  780. *
  781. * param base Pointer to FLEXIO_I2C_Type structure.
  782. */
  783. void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base)
  784. {
  785. /* Prepare normal stop. */
  786. (void)FLEXIO_I2C_MasterSetTransferCount(base, 0x0U);
  787. FLEXIO_I2C_MasterWriteByte(base, 0x0U);
  788. }
  789. /*!
  790. * brief Sends the stop signal when transfer is still on-going.
  791. *
  792. * param base Pointer to FLEXIO_I2C_Type structure.
  793. */
  794. void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base)
  795. {
  796. uint32_t tmpConfig;
  797. /* Prepare abort stop. */
  798. /* Disable timer 0. */
  799. tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]];
  800. tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  801. tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
  802. base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig;
  803. /* Disable timer 1. */
  804. tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]];
  805. tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK;
  806. tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge);
  807. base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig;
  808. }
  809. /*!
  810. * brief Configures the sent ACK/NAK for the following byte.
  811. *
  812. * param base Pointer to FLEXIO_I2C_Type structure.
  813. * param enable True to configure send ACK, false configure to send NAK.
  814. */
  815. void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable)
  816. {
  817. uint32_t tmpConfig = 0;
  818. tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]];
  819. tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK;
  820. if (enable)
  821. {
  822. tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow);
  823. }
  824. else
  825. {
  826. tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh);
  827. }
  828. base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig;
  829. }
  830. /*!
  831. * brief Sends a buffer of data in bytes.
  832. *
  833. * note This function blocks via polling until all bytes have been sent.
  834. *
  835. * param base Pointer to FLEXIO_I2C_Type structure.
  836. * param txBuff The data bytes to send.
  837. * param txSize The number of data bytes to send.
  838. * retval kStatus_Success Successfully write data.
  839. * retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data.
  840. * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
  841. */
  842. status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize)
  843. {
  844. assert(txBuff != NULL);
  845. assert(txSize != 0U);
  846. uint32_t status;
  847. #if I2C_RETRY_TIMES
  848. uint32_t waitTimes = I2C_RETRY_TIMES;
  849. #endif
  850. while (0U != txSize--)
  851. {
  852. FLEXIO_I2C_MasterWriteByte(base, *txBuff++);
  853. /* Wait until data transfer complete. */
  854. #if I2C_RETRY_TIMES
  855. waitTimes = I2C_RETRY_TIMES;
  856. while ((0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
  857. (0U != --waitTimes))
  858. {
  859. }
  860. if (0U == waitTimes)
  861. {
  862. return kStatus_FLEXIO_I2C_Timeout;
  863. }
  864. #else
  865. while (0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
  866. {
  867. }
  868. #endif
  869. if ((status & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U)
  870. {
  871. FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]);
  872. return kStatus_FLEXIO_I2C_Nak;
  873. }
  874. }
  875. return kStatus_Success;
  876. }
  877. /*!
  878. * brief Receives a buffer of bytes.
  879. *
  880. * note This function blocks via polling until all bytes have been received.
  881. *
  882. * param base Pointer to FLEXIO_I2C_Type structure.
  883. * param rxBuff The buffer to store the received bytes.
  884. * param rxSize The number of data bytes to be received.
  885. * retval kStatus_Success Successfully read data.
  886. * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags.
  887. */
  888. status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize)
  889. {
  890. assert(rxBuff != NULL);
  891. assert(rxSize != 0U);
  892. #if I2C_RETRY_TIMES
  893. uint32_t waitTimes = I2C_RETRY_TIMES;
  894. #endif
  895. while (0U != rxSize--)
  896. {
  897. /* Wait until data transfer complete. */
  898. #if I2C_RETRY_TIMES
  899. waitTimes = I2C_RETRY_TIMES;
  900. while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) &&
  901. (0U != --waitTimes))
  902. {
  903. }
  904. if (0U == waitTimes)
  905. {
  906. return kStatus_FLEXIO_I2C_Timeout;
  907. }
  908. #else
  909. while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag))
  910. {
  911. }
  912. #endif
  913. *rxBuff++ = FLEXIO_I2C_MasterReadByte(base);
  914. }
  915. return kStatus_Success;
  916. }
  917. /*!
  918. * brief Performs a master polling transfer on the I2C bus.
  919. *
  920. * note The API does not return until the transfer succeeds or fails due
  921. * to receiving NAK.
  922. *
  923. * param base pointer to FLEXIO_I2C_Type structure.
  924. * param xfer pointer to flexio_i2c_master_transfer_t structure.
  925. * return status of status_t.
  926. */
  927. status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer)
  928. {
  929. assert(xfer != NULL);
  930. #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
  931. /* Return an error if the bus is already in use not by us.*/
  932. status_t status = FLEXIO_I2C_CheckForBusyBus(base);
  933. if (status != kStatus_Success)
  934. {
  935. return status;
  936. }
  937. #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
  938. flexio_i2c_master_handle_t tmpHandle;
  939. uint32_t statusFlags;
  940. status_t result = kStatus_Success;
  941. #if I2C_RETRY_TIMES
  942. uint32_t waitTimes = I2C_RETRY_TIMES;
  943. #endif
  944. /* Zero the handle. */
  945. (void)memset(&tmpHandle, 0, sizeof(tmpHandle));
  946. /* Set up transfer machine. */
  947. result = FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer);
  948. if (result != kStatus_Success)
  949. {
  950. return result;
  951. }
  952. do
  953. {
  954. /* Wait either tx empty or rx full flag is asserted. */
  955. #if I2C_RETRY_TIMES
  956. waitTimes = I2C_RETRY_TIMES;
  957. while ((0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
  958. ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag))) &&
  959. (0U != --waitTimes))
  960. {
  961. }
  962. if (0U == waitTimes)
  963. {
  964. return kStatus_FLEXIO_I2C_Timeout;
  965. }
  966. #else
  967. while (0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) &
  968. ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag)))
  969. {
  970. }
  971. #endif
  972. FLEXIO_ClearTimerStatusFlags(base->flexioBase, ((1UL << base->timerIndex[0]) | (1UL << base->timerIndex[1])));
  973. result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags);
  974. } while ((tmpHandle.state != (uint8_t)kFLEXIO_I2C_Idle) && (result == kStatus_Success));
  975. /* Timer disable on timer compare, wait until bit clock TSF set, which means timer disable and stop has been sent.
  976. */
  977. while (0U == (FLEXIO_GetTimerStatusFlags(base->flexioBase) & (1UL << base->timerIndex[1])))
  978. {
  979. }
  980. return result;
  981. }
  982. /*!
  983. * brief Initializes the I2C handle which is used in transactional functions.
  984. *
  985. * param base Pointer to FLEXIO_I2C_Type structure.
  986. * param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state.
  987. * param callback Pointer to user callback function.
  988. * param userData User param passed to the callback function.
  989. * retval kStatus_Success Successfully create the handle.
  990. * retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range.
  991. */
  992. status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base,
  993. flexio_i2c_master_handle_t *handle,
  994. flexio_i2c_master_transfer_callback_t callback,
  995. void *userData)
  996. {
  997. assert(handle != NULL);
  998. IRQn_Type flexio_irqs[] = FLEXIO_IRQS;
  999. /* Zero the handle. */
  1000. (void)memset(handle, 0, sizeof(*handle));
  1001. /* Register callback and userData. */
  1002. handle->completionCallback = callback;
  1003. handle->userData = userData;
  1004. /* Clear pending NVIC IRQ before enable NVIC IRQ. */
  1005. NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
  1006. (void)EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]);
  1007. /* Save the context in global variables to support the double weak mechanism. */
  1008. return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ);
  1009. }
  1010. /*!
  1011. * brief Performs a master interrupt non-blocking transfer on the I2C bus.
  1012. *
  1013. * note The API returns immediately after the transfer initiates.
  1014. * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether
  1015. * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer
  1016. * is finished.
  1017. *
  1018. * param base Pointer to FLEXIO_I2C_Type structure
  1019. * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  1020. * param xfer pointer to flexio_i2c_master_transfer_t structure
  1021. * retval kStatus_Success Successfully start a transfer.
  1022. * retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer.
  1023. */
  1024. status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base,
  1025. flexio_i2c_master_handle_t *handle,
  1026. flexio_i2c_master_transfer_t *xfer)
  1027. {
  1028. assert(handle != NULL);
  1029. assert(xfer != NULL);
  1030. status_t result = kStatus_Success;
  1031. #if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS
  1032. /* Return an error if the bus is already in use not by us.*/
  1033. result = FLEXIO_I2C_CheckForBusyBus(base);
  1034. if (result != kStatus_Success)
  1035. {
  1036. return result;
  1037. }
  1038. #endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/
  1039. if (handle->state != (uint8_t)kFLEXIO_I2C_Idle)
  1040. {
  1041. return kStatus_FLEXIO_I2C_Busy;
  1042. }
  1043. else
  1044. {
  1045. /* Set up transfer machine. */
  1046. result = FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer);
  1047. if (result != kStatus_Success)
  1048. {
  1049. return result;
  1050. }
  1051. /* Enable both tx empty and rxfull interrupt. */
  1052. FLEXIO_I2C_MasterEnableInterrupts(
  1053. base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
  1054. return kStatus_Success;
  1055. }
  1056. }
  1057. /*!
  1058. * brief Aborts an interrupt non-blocking transfer early.
  1059. *
  1060. * note This API can be called at any time when an interrupt non-blocking transfer initiates
  1061. * to abort the transfer early.
  1062. *
  1063. * param base Pointer to FLEXIO_I2C_Type structure
  1064. * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state
  1065. */
  1066. void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle)
  1067. {
  1068. assert(handle != NULL);
  1069. /* Disable interrupts. */
  1070. FLEXIO_I2C_MasterDisableInterrupts(
  1071. base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable);
  1072. /* Reset to idle state. */
  1073. handle->state = (uint8_t)kFLEXIO_I2C_Idle;
  1074. }
  1075. /*!
  1076. * brief Gets the master transfer status during a interrupt non-blocking transfer.
  1077. *
  1078. * param base Pointer to FLEXIO_I2C_Type structure.
  1079. * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state.
  1080. * param count Number of bytes transferred so far by the non-blocking transaction.
  1081. * retval kStatus_InvalidArgument count is Invalid.
  1082. * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
  1083. * retval kStatus_Success Successfully return the count.
  1084. */
  1085. status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count)
  1086. {
  1087. if (NULL == count)
  1088. {
  1089. return kStatus_InvalidArgument;
  1090. }
  1091. /* Catch when there is not an active transfer. */
  1092. if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
  1093. {
  1094. *count = 0;
  1095. return kStatus_NoTransferInProgress;
  1096. }
  1097. *count = handle->transferSize - handle->transfer.dataSize;
  1098. return kStatus_Success;
  1099. }
  1100. /*!
  1101. * brief Master interrupt handler.
  1102. *
  1103. * param i2cType Pointer to FLEXIO_I2C_Type structure
  1104. * param i2cHandle Pointer to flexio_i2c_master_transfer_t structure
  1105. */
  1106. void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle)
  1107. {
  1108. FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType;
  1109. flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle;
  1110. uint32_t statusFlags;
  1111. status_t result;
  1112. statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base);
  1113. result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags);
  1114. if (handle->state == (uint8_t)kFLEXIO_I2C_Idle)
  1115. {
  1116. FLEXIO_I2C_MasterTransferComplete(base, handle, result);
  1117. }
  1118. }