fsl_i2c_edma.c 18 KB

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