fsl_i2c_edma.c 18 KB

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