fsl_i2c_edma.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. /*
  2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "fsl_i2c_edma.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. /*<! @breif Structure definition for i2c_master_edma_private_handle_t. The structure is private. */
  35. typedef struct _i2c_master_edma_private_handle
  36. {
  37. I2C_Type *base;
  38. i2c_master_edma_handle_t *handle;
  39. } i2c_master_edma_private_handle_t;
  40. /*! @brief i2c master DMA transfer state. */
  41. enum _i2c_master_dma_transfer_states
  42. {
  43. kIdleState = 0x0U, /*!< I2C bus idle. */
  44. kTransferDataState = 0x1U, /*!< 7-bit address check state. */
  45. };
  46. /*! @brief Common sets of flags used by the driver. */
  47. enum _i2c_flag_constants
  48. {
  49. /*! All flags which are cleared by the driver upon starting a transfer. */
  50. #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT
  51. kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StartDetectFlag | kI2C_StopDetectFlag,
  52. #elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT
  53. kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag | kI2C_StopDetectFlag,
  54. #else
  55. kClearFlags = kI2C_ArbitrationLostFlag | kI2C_IntPendingFlag,
  56. #endif
  57. };
  58. /*******************************************************************************
  59. * Prototypes
  60. ******************************************************************************/
  61. /*!
  62. * @brief EDMA callback for I2C master EDMA driver.
  63. *
  64. * @param handle EDMA handler for I2C master EDMA driver
  65. * @param userData user param passed to the callback function
  66. */
  67. static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds);
  68. /*!
  69. * @brief Check and clear status operation.
  70. *
  71. * @param base I2C peripheral base address.
  72. * @param status current i2c hardware status.
  73. * @retval kStatus_Success No error found.
  74. * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost.
  75. * @retval kStatus_I2C_Nak Received Nak error.
  76. */
  77. static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status);
  78. /*!
  79. * @brief EDMA config for I2C master driver.
  80. *
  81. * @param base I2C peripheral base address.
  82. * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
  83. */
  84. static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle);
  85. /*!
  86. * @brief Set up master transfer, send slave address and sub address(if any), wait until the
  87. * wait until address sent status return.
  88. *
  89. * @param base I2C peripheral base address.
  90. * @param handle pointer to i2c_master_edma_handle_t structure which stores the transfer state
  91. * @param xfer pointer to i2c_master_transfer_t structure
  92. */
  93. static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
  94. i2c_master_edma_handle_t *handle,
  95. i2c_master_transfer_t *xfer);
  96. /*!
  97. * @brief Get the I2C instance from peripheral base address.
  98. *
  99. * @param base I2C peripheral base address.
  100. * @return I2C instance.
  101. */
  102. extern uint32_t I2C_GetInstance(I2C_Type *base);
  103. /*******************************************************************************
  104. * Variables
  105. ******************************************************************************/
  106. /*<! Private handle only used for internally. */
  107. static i2c_master_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_I2C_COUNT];
  108. /*******************************************************************************
  109. * Codes
  110. ******************************************************************************/
  111. static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData, bool transferDone, uint32_t tcds)
  112. {
  113. i2c_master_edma_private_handle_t *i2cPrivateHandle = (i2c_master_edma_private_handle_t *)userData;
  114. status_t result = kStatus_Success;
  115. /* Disable DMA. */
  116. I2C_EnableDMA(i2cPrivateHandle->base, false);
  117. /* Send stop if kI2C_TransferNoStop flag is not asserted. */
  118. if (!(i2cPrivateHandle->handle->transfer.flags & kI2C_TransferNoStopFlag))
  119. {
  120. if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
  121. {
  122. /* Change to send NAK at the last byte. */
  123. i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
  124. /* Wait the last data to be received. */
  125. while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
  126. {
  127. }
  128. /* Send stop signal. */
  129. result = I2C_MasterStop(i2cPrivateHandle->base);
  130. /* Read the last data byte. */
  131. *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
  132. i2cPrivateHandle->base->D;
  133. }
  134. else
  135. {
  136. /* Wait the last data to be sent. */
  137. while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
  138. {
  139. }
  140. /* Send stop signal. */
  141. result = I2C_MasterStop(i2cPrivateHandle->base);
  142. }
  143. }
  144. else
  145. {
  146. if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read)
  147. {
  148. /* Change to send NAK at the last byte. */
  149. i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK;
  150. /* Wait the last data to be received. */
  151. while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag))
  152. {
  153. }
  154. /* Change direction to send. */
  155. i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK;
  156. /* Read the last data byte. */
  157. *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) =
  158. i2cPrivateHandle->base->D;
  159. }
  160. }
  161. i2cPrivateHandle->handle->state = kIdleState;
  162. if (i2cPrivateHandle->handle->completionCallback)
  163. {
  164. i2cPrivateHandle->handle->completionCallback(i2cPrivateHandle->base, i2cPrivateHandle->handle, result,
  165. i2cPrivateHandle->handle->userData);
  166. }
  167. }
  168. static status_t I2C_CheckAndClearError(I2C_Type *base, uint32_t status)
  169. {
  170. status_t result = kStatus_Success;
  171. /* Check arbitration lost. */
  172. if (status & kI2C_ArbitrationLostFlag)
  173. {
  174. /* Clear arbitration lost flag. */
  175. base->S = kI2C_ArbitrationLostFlag;
  176. result = kStatus_I2C_ArbitrationLost;
  177. }
  178. /* Check NAK */
  179. else if (status & kI2C_ReceiveNakFlag)
  180. {
  181. result = kStatus_I2C_Nak;
  182. }
  183. else
  184. {
  185. }
  186. return result;
  187. }
  188. static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
  189. i2c_master_edma_handle_t *handle,
  190. i2c_master_transfer_t *xfer)
  191. {
  192. assert(handle);
  193. assert(xfer);
  194. status_t result = kStatus_Success;
  195. if (handle->state != kIdleState)
  196. {
  197. return kStatus_I2C_Busy;
  198. }
  199. else
  200. {
  201. i2c_direction_t direction = xfer->direction;
  202. /* Init the handle member. */
  203. handle->transfer = *xfer;
  204. /* Save total transfer size. */
  205. handle->transferSize = xfer->dataSize;
  206. handle->state = kTransferDataState;
  207. /* Clear all status before transfer. */
  208. I2C_MasterClearStatusFlags(base, kClearFlags);
  209. /* Change to send write address when it's a read operation with command. */
  210. if ((xfer->subaddressSize > 0) && (xfer->direction == kI2C_Read))
  211. {
  212. direction = kI2C_Write;
  213. }
  214. /* If repeated start is requested, send repeated start. */
  215. if (handle->transfer.flags & kI2C_TransferRepeatedStartFlag)
  216. {
  217. result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, direction);
  218. }
  219. else /* For normal transfer, send start. */
  220. {
  221. result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction);
  222. }
  223. if (result)
  224. {
  225. return result;
  226. }
  227. while (!(base->S & kI2C_IntPendingFlag))
  228. {
  229. }
  230. /* Check if there's transfer error. */
  231. result = I2C_CheckAndClearError(base, base->S);
  232. /* Return if error. */
  233. if (result)
  234. {
  235. if (result == kStatus_I2C_Nak)
  236. {
  237. result = kStatus_I2C_Addr_Nak;
  238. if (I2C_MasterStop(base) != kStatus_Success)
  239. {
  240. result = kStatus_I2C_Timeout;
  241. }
  242. if (handle->completionCallback)
  243. {
  244. (handle->completionCallback)(base, handle, result, handle->userData);
  245. }
  246. }
  247. return result;
  248. }
  249. /* Send subaddress. */
  250. if (handle->transfer.subaddressSize)
  251. {
  252. do
  253. {
  254. /* Clear interrupt pending flag. */
  255. base->S = kI2C_IntPendingFlag;
  256. handle->transfer.subaddressSize--;
  257. base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize));
  258. /* Wait until data transfer complete. */
  259. while (!(base->S & kI2C_IntPendingFlag))
  260. {
  261. }
  262. /* Check if there's transfer error. */
  263. result = I2C_CheckAndClearError(base, base->S);
  264. if (result)
  265. {
  266. return result;
  267. }
  268. } while ((handle->transfer.subaddressSize > 0) && (result == kStatus_Success));
  269. if (handle->transfer.direction == kI2C_Read)
  270. {
  271. /* Clear pending flag. */
  272. base->S = kI2C_IntPendingFlag;
  273. /* Send repeated start and slave address. */
  274. result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read);
  275. if (result)
  276. {
  277. return result;
  278. }
  279. /* Wait until data transfer complete. */
  280. while (!(base->S & kI2C_IntPendingFlag))
  281. {
  282. }
  283. /* Check if there's transfer error. */
  284. result = I2C_CheckAndClearError(base, base->S);
  285. if (result)
  286. {
  287. return result;
  288. }
  289. }
  290. }
  291. /* Clear pending flag. */
  292. base->S = kI2C_IntPendingFlag;
  293. }
  294. return result;
  295. }
  296. static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_t *handle)
  297. {
  298. edma_transfer_config_t transfer_config;
  299. if (handle->transfer.direction == kI2C_Read)
  300. {
  301. transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base);
  302. transfer_config.destAddr = (uint32_t)(handle->transfer.data);
  303. transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
  304. transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
  305. transfer_config.srcOffset = 0;
  306. transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
  307. transfer_config.destOffset = 1;
  308. transfer_config.minorLoopBytes = 1;
  309. }
  310. else
  311. {
  312. transfer_config.srcAddr = (uint32_t)(handle->transfer.data + 1);
  313. transfer_config.destAddr = (uint32_t)I2C_GetDataRegAddr(base);
  314. transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1);
  315. transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes;
  316. transfer_config.srcOffset = 1;
  317. transfer_config.destTransferSize = kEDMA_TransferSize1Bytes;
  318. transfer_config.destOffset = 0;
  319. transfer_config.minorLoopBytes = 1;
  320. }
  321. /* Store the initially configured eDMA minor byte transfer count into the I2C handle */
  322. handle->nbytes = transfer_config.minorLoopBytes;
  323. EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config);
  324. EDMA_StartTransfer(handle->dmaHandle);
  325. }
  326. void I2C_MasterCreateEDMAHandle(I2C_Type *base,
  327. i2c_master_edma_handle_t *handle,
  328. i2c_master_edma_transfer_callback_t callback,
  329. void *userData,
  330. edma_handle_t *edmaHandle)
  331. {
  332. assert(handle);
  333. assert(edmaHandle);
  334. uint32_t instance = I2C_GetInstance(base);
  335. /* Zero handle. */
  336. memset(handle, 0, sizeof(*handle));
  337. /* Set the user callback and userData. */
  338. handle->completionCallback = callback;
  339. handle->userData = userData;
  340. /* Set the base for the handle. */
  341. base = base;
  342. /* Set the handle for EDMA. */
  343. handle->dmaHandle = edmaHandle;
  344. s_edmaPrivateHandle[instance].base = base;
  345. s_edmaPrivateHandle[instance].handle = handle;
  346. EDMA_SetCallback(edmaHandle, (edma_callback)I2C_MasterTransferCallbackEDMA, &s_edmaPrivateHandle[instance]);
  347. }
  348. status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer)
  349. {
  350. assert(handle);
  351. assert(xfer);
  352. status_t result;
  353. uint8_t tmpReg;
  354. volatile uint8_t dummy = 0;
  355. /* Add this to avoid build warning. */
  356. dummy++;
  357. /* Disable dma xfer. */
  358. I2C_EnableDMA(base, false);
  359. /* Send address and command buffer(if there is), until senddata phase or receive data phase. */
  360. result = I2C_InitTransferStateMachineEDMA(base, handle, xfer);
  361. if (result)
  362. {
  363. /* Send stop if received Nak. */
  364. if (result == kStatus_I2C_Nak)
  365. {
  366. if (I2C_MasterStop(base) != kStatus_Success)
  367. {
  368. result = kStatus_I2C_Timeout;
  369. }
  370. }
  371. /* Reset the state to idle state. */
  372. handle->state = kIdleState;
  373. return result;
  374. }
  375. /* Configure dma transfer. */
  376. /* For i2c send, need to send 1 byte first to trigger the dma, for i2c read,
  377. need to send stop before reading the last byte, so the dma transfer size should
  378. be (xSize - 1). */
  379. if (handle->transfer.dataSize > 1)
  380. {
  381. I2C_MasterTransferEDMAConfig(base, handle);
  382. if (handle->transfer.direction == kI2C_Read)
  383. {
  384. /* Change direction for receive. */
  385. base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);
  386. /* Read dummy to release the bus. */
  387. dummy = base->D;
  388. /* Enabe dma transfer. */
  389. I2C_EnableDMA(base, true);
  390. }
  391. else
  392. {
  393. /* Enabe dma transfer. */
  394. I2C_EnableDMA(base, true);
  395. /* Send the first data. */
  396. base->D = *handle->transfer.data;
  397. }
  398. }
  399. else /* If transfer size is 1, use polling method. */
  400. {
  401. if (handle->transfer.direction == kI2C_Read)
  402. {
  403. tmpReg = base->C1;
  404. /* Change direction to Rx. */
  405. tmpReg &= ~I2C_C1_TX_MASK;
  406. /* Configure send NAK */
  407. tmpReg |= I2C_C1_TXAK_MASK;
  408. base->C1 = tmpReg;
  409. /* Read dummy to release the bus. */
  410. dummy = base->D;
  411. }
  412. else
  413. {
  414. base->D = *handle->transfer.data;
  415. }
  416. /* Wait until data transfer complete. */
  417. while (!(base->S & kI2C_IntPendingFlag))
  418. {
  419. }
  420. /* Clear pending flag. */
  421. base->S = kI2C_IntPendingFlag;
  422. /* Send stop if kI2C_TransferNoStop flag is not asserted. */
  423. if (!(handle->transfer.flags & kI2C_TransferNoStopFlag))
  424. {
  425. result = I2C_MasterStop(base);
  426. }
  427. else
  428. {
  429. /* Change direction to send. */
  430. base->C1 |= I2C_C1_TX_MASK;
  431. }
  432. /* Read the last byte of data. */
  433. if (handle->transfer.direction == kI2C_Read)
  434. {
  435. *handle->transfer.data = base->D;
  436. }
  437. /* Reset the state to idle. */
  438. handle->state = kIdleState;
  439. }
  440. return result;
  441. }
  442. status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count)
  443. {
  444. assert(handle->dmaHandle);
  445. if (!count)
  446. {
  447. return kStatus_InvalidArgument;
  448. }
  449. if (kIdleState != handle->state)
  450. {
  451. *count = (handle->transferSize -
  452. (uint32_t)handle->nbytes *
  453. EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel));
  454. }
  455. else
  456. {
  457. *count = handle->transferSize;
  458. }
  459. return kStatus_Success;
  460. }
  461. void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle)
  462. {
  463. EDMA_AbortTransfer(handle->dmaHandle);
  464. /* Disable dma transfer. */
  465. I2C_EnableDMA(base, false);
  466. /* Reset the state to idle. */
  467. handle->state = kIdleState;
  468. }