fsl_i2s.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. /*
  2. * The Clear BSD License
  3. * Copyright (c) 2016, 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_i2s.h"
  35. #include "fsl_flexcomm.h"
  36. #include <string.h>
  37. /*******************************************************************************
  38. * Definitions
  39. ******************************************************************************/
  40. /* Component ID definition, used by tools. */
  41. #ifndef FSL_COMPONENT_ID
  42. #define FSL_COMPONENT_ID "platform.drivers.flexcomm_i2s"
  43. #endif
  44. /* TODO - absent in device header files, should be there */
  45. #define I2S_FIFOCFG_TXI2SE0_MASK (0x4U)
  46. #define I2S_FIFOCFG_TXI2SE0_SHIFT (2U)
  47. #define I2S_FIFOCFG_TXI2SE0(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_TXI2SE0_SHIFT)) & I2S_FIFOCFG_TXI2SE0_MASK)
  48. #define I2S_FIFOCFG_PACK48_MASK (0x8U)
  49. #define I2S_FIFOCFG_PACK48_SHIFT (3U)
  50. #define I2S_FIFOCFG_PACK48(x) (((uint32_t)(((uint32_t)(x)) << I2S_FIFOCFG_PACK48_SHIFT)) & I2S_FIFOCFG_PACK48_MASK)
  51. /*! @brief I2S states. */
  52. enum _i2s_state
  53. {
  54. kI2S_StateIdle = 0x0, /*!< Not performing transfer */
  55. kI2S_StateTx, /*!< Performing transmit */
  56. kI2S_StateTxWaitToWriteDummyData, /*!< Wait on FIFO in order to write final dummy data there */
  57. kI2S_StateTxWaitForEmptyFifo, /*!< Wait for FIFO to be flushed */
  58. kI2S_StateRx, /*!< Performing receive */
  59. };
  60. /*******************************************************************************
  61. * Prototypes
  62. ******************************************************************************/
  63. static void I2S_Config(I2S_Type *base, const i2s_config_t *config);
  64. static void I2S_TxEnable(I2S_Type *base, bool enable);
  65. static void I2S_RxEnable(I2S_Type *base, bool enable);
  66. static status_t I2S_ValidateBuffer(i2s_handle_t *handle, i2s_transfer_t *transfer);
  67. /*******************************************************************************
  68. * Code
  69. ******************************************************************************/
  70. void I2S_TxInit(I2S_Type *base, const i2s_config_t *config)
  71. {
  72. uint32_t cfg = 0U;
  73. uint32_t trig = 0U;
  74. FLEXCOMM_Init(base, FLEXCOMM_PERIPH_I2S_TX);
  75. I2S_Config(base, config);
  76. /* Configure FIFO */
  77. cfg |= I2S_FIFOCFG_ENABLETX(1U); /* enable TX FIFO */
  78. cfg |= I2S_FIFOCFG_EMPTYTX(1U); /* empty TX FIFO */
  79. cfg |= I2S_FIFOCFG_TXI2SE0(config->txEmptyZero); /* transmit zero when buffer becomes empty or last item */
  80. cfg |= I2S_FIFOCFG_PACK48(config->pack48); /* set pack 48-bit format or not */
  81. trig |= I2S_FIFOTRIG_TXLVLENA(1U); /* enable TX FIFO trigger */
  82. trig |= I2S_FIFOTRIG_TXLVL(config->watermark); /* set TX FIFO trigger level */
  83. base->FIFOCFG = cfg;
  84. base->FIFOTRIG = trig;
  85. }
  86. void I2S_RxInit(I2S_Type *base, const i2s_config_t *config)
  87. {
  88. uint32_t cfg = 0U;
  89. uint32_t trig = 0U;
  90. FLEXCOMM_Init(base, FLEXCOMM_PERIPH_I2S_RX);
  91. I2S_Config(base, config);
  92. /* Configure FIFO */
  93. cfg |= I2S_FIFOCFG_ENABLERX(1U); /* enable RX FIFO */
  94. cfg |= I2S_FIFOCFG_EMPTYRX(1U); /* empty RX FIFO */
  95. cfg |= I2S_FIFOCFG_PACK48(config->pack48); /* set pack 48-bit format or not */
  96. trig |= I2S_FIFOTRIG_RXLVLENA(1U); /* enable RX FIFO trigger */
  97. trig |= I2S_FIFOTRIG_RXLVL(config->watermark); /* set RX FIFO trigger level */
  98. base->FIFOCFG = cfg;
  99. base->FIFOTRIG = trig;
  100. }
  101. void I2S_TxGetDefaultConfig(i2s_config_t *config)
  102. {
  103. config->masterSlave = kI2S_MasterSlaveNormalMaster;
  104. config->mode = kI2S_ModeI2sClassic;
  105. config->rightLow = false;
  106. config->leftJust = false;
  107. config->pdmData = false;
  108. config->sckPol = false;
  109. config->wsPol = false;
  110. config->divider = 1U;
  111. config->oneChannel = false;
  112. config->dataLength = 16U;
  113. config->frameLength = 32U;
  114. config->position = 0U;
  115. config->watermark = 4U;
  116. config->txEmptyZero = true;
  117. config->pack48 = false;
  118. }
  119. void I2S_RxGetDefaultConfig(i2s_config_t *config)
  120. {
  121. config->masterSlave = kI2S_MasterSlaveNormalSlave;
  122. config->mode = kI2S_ModeI2sClassic;
  123. config->rightLow = false;
  124. config->leftJust = false;
  125. config->pdmData = false;
  126. config->sckPol = false;
  127. config->wsPol = false;
  128. config->divider = 1U;
  129. config->oneChannel = false;
  130. config->dataLength = 16U;
  131. config->frameLength = 32U;
  132. config->position = 0U;
  133. config->watermark = 4U;
  134. config->txEmptyZero = false;
  135. config->pack48 = false;
  136. }
  137. static void I2S_Config(I2S_Type *base, const i2s_config_t *config)
  138. {
  139. assert(config);
  140. uint32_t cfg1 = 0U;
  141. uint32_t cfg2 = 0U;
  142. /* set master/slave configuration */
  143. cfg1 |= I2S_CFG1_MSTSLVCFG(config->masterSlave);
  144. /* set I2S mode */
  145. cfg1 |= I2S_CFG1_MODE(config->mode);
  146. /* set right low (channel swap) */
  147. cfg1 |= I2S_CFG1_RIGHTLOW(config->rightLow);
  148. /* set data justification */
  149. cfg1 |= I2S_CFG1_LEFTJUST(config->leftJust);
  150. /* set source to PDM dmic */
  151. cfg1 |= I2S_CFG1_PDMDATA(config->pdmData);
  152. /* set SCLK polarity */
  153. cfg1 |= I2S_CFG1_SCK_POL(config->sckPol);
  154. /* set WS polarity */
  155. cfg1 |= I2S_CFG1_WS_POL(config->wsPol);
  156. /* set mono mode */
  157. cfg1 |= I2S_CFG1_ONECHANNEL(config->oneChannel);
  158. /* set data length */
  159. cfg1 |= I2S_CFG1_DATALEN(config->dataLength - 1U);
  160. /* set frame length */
  161. cfg2 |= I2S_CFG2_FRAMELEN(config->frameLength - 1U);
  162. /* set data position of this channel pair within the frame */
  163. cfg2 |= I2S_CFG2_POSITION(config->position);
  164. /* write to registers */
  165. base->CFG1 = cfg1;
  166. base->CFG2 = cfg2;
  167. /* set the clock divider */
  168. base->DIV = I2S_DIV_DIV(config->divider - 1U);
  169. }
  170. void I2S_Deinit(I2S_Type *base)
  171. {
  172. /* TODO gate FLEXCOMM clock via FLEXCOMM driver */
  173. }
  174. static void I2S_TxEnable(I2S_Type *base, bool enable)
  175. {
  176. if (enable)
  177. {
  178. I2S_EnableInterrupts(base, kI2S_TxErrorFlag | kI2S_TxLevelFlag);
  179. I2S_Enable(base);
  180. }
  181. else
  182. {
  183. I2S_DisableInterrupts(base, kI2S_TxErrorFlag | kI2S_TxLevelFlag);
  184. I2S_Disable(base);
  185. base->FIFOCFG |= I2S_FIFOCFG_EMPTYTX_MASK;
  186. }
  187. }
  188. static void I2S_RxEnable(I2S_Type *base, bool enable)
  189. {
  190. if (enable)
  191. {
  192. I2S_EnableInterrupts(base, kI2S_RxErrorFlag | kI2S_RxLevelFlag);
  193. I2S_Enable(base);
  194. }
  195. else
  196. {
  197. I2S_DisableInterrupts(base, kI2S_RxErrorFlag | kI2S_RxLevelFlag);
  198. I2S_Disable(base);
  199. base->FIFOCFG |= I2S_FIFOCFG_EMPTYRX_MASK;
  200. }
  201. }
  202. static status_t I2S_ValidateBuffer(i2s_handle_t *handle, i2s_transfer_t *transfer)
  203. {
  204. assert(transfer->data);
  205. if (!transfer->data)
  206. {
  207. return kStatus_InvalidArgument;
  208. }
  209. assert(transfer->dataSize > 0U);
  210. if (transfer->dataSize <= 0U)
  211. {
  212. return kStatus_InvalidArgument;
  213. }
  214. if (handle->dataLength == 4U)
  215. {
  216. /* No alignment and data length requirements */
  217. }
  218. else if ((handle->dataLength >= 5U) && (handle->dataLength <= 8U))
  219. {
  220. assert((((uint32_t)transfer->data) % 2U) == 0U);
  221. if ((((uint32_t)transfer->data) % 2U) != 0U)
  222. {
  223. /* Data not 2-bytes aligned */
  224. return kStatus_InvalidArgument;
  225. }
  226. assert((transfer->dataSize % 2U) == 0U);
  227. if ((transfer->dataSize % 2U) != 0U)
  228. {
  229. /* Data not in pairs of left/right channel bytes */
  230. return kStatus_InvalidArgument;
  231. }
  232. }
  233. else if ((handle->dataLength >= 9U) && (handle->dataLength <= 16U))
  234. {
  235. assert((((uint32_t)transfer->data) % 4U) == 0U);
  236. if ((((uint32_t)transfer->data) % 4U) != 0U)
  237. {
  238. /* Data not 4-bytes aligned */
  239. return kStatus_InvalidArgument;
  240. }
  241. assert((transfer->dataSize % 4U) == 0U);
  242. if ((transfer->dataSize % 4U) != 0U)
  243. {
  244. /* Data lenght not multiply of 4 */
  245. return kStatus_InvalidArgument;
  246. }
  247. }
  248. else if ((handle->dataLength >= 17U) && (handle->dataLength <= 24U))
  249. {
  250. assert((transfer->dataSize % 6U) == 0U);
  251. if ((transfer->dataSize % 6U) != 0U)
  252. {
  253. /* Data lenght not multiply of 6 */
  254. return kStatus_InvalidArgument;
  255. }
  256. assert(!((handle->pack48) && ((((uint32_t)transfer->data) % 4U) != 0U)));
  257. if ((handle->pack48) && ((((uint32_t)transfer->data) % 4U) != 0U))
  258. {
  259. /* Data not 4-bytes aligned */
  260. return kStatus_InvalidArgument;
  261. }
  262. }
  263. else /* if (handle->dataLength >= 25U) */
  264. {
  265. assert((((uint32_t)transfer->data) % 4U) == 0U);
  266. if ((((uint32_t)transfer->data) % 4U) != 0U)
  267. {
  268. /* Data not 4-bytes aligned */
  269. return kStatus_InvalidArgument;
  270. }
  271. if (handle->oneChannel)
  272. {
  273. assert((transfer->dataSize % 4U) == 0U);
  274. if ((transfer->dataSize % 4U) != 0U)
  275. {
  276. /* Data lenght not multiply of 4 */
  277. return kStatus_InvalidArgument;
  278. }
  279. }
  280. else
  281. {
  282. assert((transfer->dataSize % 8U) == 0U);
  283. if ((transfer->dataSize % 8U) != 0U)
  284. {
  285. /* Data lenght not multiply of 8 */
  286. return kStatus_InvalidArgument;
  287. }
  288. }
  289. }
  290. return kStatus_Success;
  291. }
  292. void I2S_TxTransferCreateHandle(I2S_Type *base, i2s_handle_t *handle, i2s_transfer_callback_t callback, void *userData)
  293. {
  294. assert(handle);
  295. /* Clear out the handle */
  296. memset(handle, 0U, sizeof(*handle));
  297. /* Save callback and user data */
  298. handle->completionCallback = callback;
  299. handle->userData = userData;
  300. /* Remember some items set previously by configuration */
  301. handle->watermark = ((base->FIFOTRIG & I2S_FIFOTRIG_TXLVL_MASK) >> I2S_FIFOTRIG_TXLVL_SHIFT);
  302. handle->oneChannel = ((base->CFG1 & I2S_CFG1_ONECHANNEL_MASK) >> I2S_CFG1_ONECHANNEL_SHIFT);
  303. handle->dataLength = ((base->CFG1 & I2S_CFG1_DATALEN_MASK) >> I2S_CFG1_DATALEN_SHIFT) + 1U;
  304. handle->pack48 = ((base->FIFOCFG & I2S_FIFOCFG_PACK48_MASK) >> I2S_FIFOCFG_PACK48_SHIFT);
  305. handle->useFifo48H = false;
  306. /* Register IRQ handling */
  307. FLEXCOMM_SetIRQHandler(base, (flexcomm_irq_handler_t)I2S_TxHandleIRQ, handle);
  308. }
  309. status_t I2S_TxTransferNonBlocking(I2S_Type *base, i2s_handle_t *handle, i2s_transfer_t transfer)
  310. {
  311. assert(handle);
  312. if (!handle)
  313. {
  314. return kStatus_InvalidArgument;
  315. }
  316. status_t result;
  317. result = I2S_ValidateBuffer(handle, &transfer);
  318. if (result != kStatus_Success)
  319. {
  320. return result;
  321. }
  322. if (handle->i2sQueue[handle->queueUser].dataSize)
  323. {
  324. /* Previously prepared buffers not processed yet */
  325. return kStatus_I2S_Busy;
  326. }
  327. handle->state = kI2S_StateTx;
  328. handle->i2sQueue[handle->queueUser].data = transfer.data;
  329. handle->i2sQueue[handle->queueUser].dataSize = transfer.dataSize;
  330. handle->queueUser = (handle->queueUser + 1U) % I2S_NUM_BUFFERS;
  331. base->FIFOTRIG = (base->FIFOTRIG & (~I2S_FIFOTRIG_TXLVL_MASK)) | I2S_FIFOTRIG_TXLVL(handle->watermark);
  332. I2S_TxEnable(base, true);
  333. return kStatus_Success;
  334. }
  335. void I2S_TxTransferAbort(I2S_Type *base, i2s_handle_t *handle)
  336. {
  337. assert(handle);
  338. /* Disable I2S operation and interrupts */
  339. I2S_TxEnable(base, false);
  340. /* Reset state */
  341. handle->state = kI2S_StateIdle;
  342. /* Clear transfer queue */
  343. memset((void *)&handle->i2sQueue, 0U, sizeof(i2s_transfer_t) * I2S_NUM_BUFFERS);
  344. handle->queueDriver = 0U;
  345. handle->queueUser = 0U;
  346. }
  347. void I2S_RxTransferCreateHandle(I2S_Type *base, i2s_handle_t *handle, i2s_transfer_callback_t callback, void *userData)
  348. {
  349. assert(handle);
  350. /* Clear out the handle */
  351. memset(handle, 0U, sizeof(*handle));
  352. /* Save callback and user data */
  353. handle->completionCallback = callback;
  354. handle->userData = userData;
  355. /* Remember some items set previously by configuration */
  356. handle->watermark = ((base->FIFOTRIG & I2S_FIFOTRIG_RXLVL_MASK) >> I2S_FIFOTRIG_RXLVL_SHIFT);
  357. handle->oneChannel = ((base->CFG1 & I2S_CFG1_ONECHANNEL_MASK) >> I2S_CFG1_ONECHANNEL_SHIFT);
  358. handle->dataLength = ((base->CFG1 & I2S_CFG1_DATALEN_MASK) >> I2S_CFG1_DATALEN_SHIFT) + 1U;
  359. handle->pack48 = ((base->FIFOCFG & I2S_FIFOCFG_PACK48_MASK) >> I2S_FIFOCFG_PACK48_SHIFT);
  360. handle->useFifo48H = false;
  361. /* Register IRQ handling */
  362. FLEXCOMM_SetIRQHandler(base, (flexcomm_irq_handler_t)I2S_RxHandleIRQ, handle);
  363. }
  364. status_t I2S_RxTransferNonBlocking(I2S_Type *base, i2s_handle_t *handle, i2s_transfer_t transfer)
  365. {
  366. assert(handle);
  367. if (!handle)
  368. {
  369. return kStatus_InvalidArgument;
  370. }
  371. status_t result;
  372. result = I2S_ValidateBuffer(handle, &transfer);
  373. if (result != kStatus_Success)
  374. {
  375. return result;
  376. }
  377. if (handle->i2sQueue[handle->queueUser].dataSize)
  378. {
  379. /* Previously prepared buffers not processed yet */
  380. return kStatus_I2S_Busy;
  381. }
  382. handle->state = kI2S_StateRx;
  383. handle->i2sQueue[handle->queueUser].data = transfer.data;
  384. handle->i2sQueue[handle->queueUser].dataSize = transfer.dataSize;
  385. handle->queueUser = (handle->queueUser + 1U) % I2S_NUM_BUFFERS;
  386. base->FIFOTRIG = (base->FIFOTRIG & (~I2S_FIFOTRIG_RXLVL_MASK)) | I2S_FIFOTRIG_RXLVL(handle->watermark);
  387. I2S_RxEnable(base, true);
  388. return kStatus_Success;
  389. }
  390. void I2S_RxTransferAbort(I2S_Type *base, i2s_handle_t *handle)
  391. {
  392. assert(handle);
  393. /* Disable I2S operation and interrupts */
  394. I2S_RxEnable(base, false);
  395. /* Reset state */
  396. handle->state = kI2S_StateIdle;
  397. /* Clear transfer queue */
  398. memset((void *)&handle->i2sQueue, 0U, sizeof(i2s_transfer_t) * I2S_NUM_BUFFERS);
  399. handle->queueDriver = 0U;
  400. handle->queueUser = 0U;
  401. }
  402. status_t I2S_TransferGetCount(I2S_Type *base, i2s_handle_t *handle, size_t *count)
  403. {
  404. assert(handle);
  405. if (!handle)
  406. {
  407. return kStatus_InvalidArgument;
  408. }
  409. assert(count);
  410. if (!count)
  411. {
  412. return kStatus_InvalidArgument;
  413. }
  414. if (handle->state == kI2S_StateIdle)
  415. {
  416. return kStatus_NoTransferInProgress;
  417. }
  418. *count = handle->transferCount;
  419. return kStatus_Success;
  420. }
  421. status_t I2S_TransferGetErrorCount(I2S_Type *base, i2s_handle_t *handle, size_t *count)
  422. {
  423. assert(handle);
  424. if (!handle)
  425. {
  426. return kStatus_InvalidArgument;
  427. }
  428. assert(count);
  429. if (!count)
  430. {
  431. return kStatus_InvalidArgument;
  432. }
  433. if (handle->state == kI2S_StateIdle)
  434. {
  435. return kStatus_NoTransferInProgress;
  436. }
  437. *count = handle->errorCount;
  438. return kStatus_Success;
  439. }
  440. void I2S_TxHandleIRQ(I2S_Type *base, i2s_handle_t *handle)
  441. {
  442. uint32_t intstat = base->FIFOINTSTAT;
  443. uint32_t data;
  444. if (intstat & I2S_FIFOINTSTAT_TXERR_MASK)
  445. {
  446. handle->errorCount++;
  447. /* Clear TX error interrupt flag */
  448. base->FIFOSTAT = I2S_FIFOSTAT_TXERR(1U);
  449. }
  450. if (intstat & I2S_FIFOINTSTAT_TXLVL_MASK)
  451. {
  452. if (handle->state == kI2S_StateTx)
  453. {
  454. /* Send data */
  455. while ((base->FIFOSTAT & I2S_FIFOSTAT_TXNOTFULL_MASK) &&
  456. (handle->i2sQueue[handle->queueDriver].dataSize > 0U))
  457. {
  458. /* Write output data */
  459. if (handle->dataLength == 4U)
  460. {
  461. data = *(handle->i2sQueue[handle->queueDriver].data);
  462. base->FIFOWR = ((data & 0xF0U) << 12U) | (data & 0xFU);
  463. handle->i2sQueue[handle->queueDriver].data++;
  464. handle->transferCount++;
  465. handle->i2sQueue[handle->queueDriver].dataSize--;
  466. }
  467. else if (handle->dataLength <= 8U)
  468. {
  469. data = *((volatile uint16_t *)handle->i2sQueue[handle->queueDriver].data);
  470. base->FIFOWR = ((data & 0xFF00U) << 8U) | (data & 0xFFU);
  471. handle->i2sQueue[handle->queueDriver].data += sizeof(uint16_t);
  472. handle->transferCount += sizeof(uint16_t);
  473. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint16_t);
  474. }
  475. else if (handle->dataLength <= 16U)
  476. {
  477. base->FIFOWR = *((volatile uint32_t *)(handle->i2sQueue[handle->queueDriver].data));
  478. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  479. handle->transferCount += sizeof(uint32_t);
  480. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  481. }
  482. else if (handle->dataLength <= 24U)
  483. {
  484. if (handle->pack48)
  485. {
  486. if (handle->useFifo48H)
  487. {
  488. base->FIFOWR48H = *((volatile uint16_t *)(handle->i2sQueue[handle->queueDriver].data));
  489. handle->i2sQueue[handle->queueDriver].data += sizeof(uint16_t);
  490. handle->transferCount += sizeof(uint16_t);
  491. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint16_t);
  492. handle->useFifo48H = false;
  493. }
  494. else
  495. {
  496. base->FIFOWR = *((volatile uint32_t *)(handle->i2sQueue[handle->queueDriver].data));
  497. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  498. handle->transferCount += sizeof(uint32_t);
  499. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  500. handle->useFifo48H = true;
  501. }
  502. }
  503. else
  504. {
  505. data = (uint32_t)(*(handle->i2sQueue[handle->queueDriver].data++));
  506. data |= ((uint32_t)(*(handle->i2sQueue[handle->queueDriver].data++))) << 8U;
  507. data |= ((uint32_t)(*(handle->i2sQueue[handle->queueDriver].data++))) << 16U;
  508. if (handle->useFifo48H)
  509. {
  510. base->FIFOWR48H = data;
  511. handle->useFifo48H = false;
  512. }
  513. else
  514. {
  515. base->FIFOWR = data;
  516. handle->useFifo48H = true;
  517. }
  518. handle->transferCount += 3U;
  519. handle->i2sQueue[handle->queueDriver].dataSize -= 3U;
  520. }
  521. }
  522. else /* if (handle->dataLength <= 32U) */
  523. {
  524. base->FIFOWR = *((volatile uint32_t *)(handle->i2sQueue[handle->queueDriver].data));
  525. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  526. handle->transferCount += sizeof(uint32_t);
  527. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  528. }
  529. if (handle->i2sQueue[handle->queueDriver].dataSize == 0U)
  530. {
  531. /* Actual data buffer sent out, switch to a next one */
  532. handle->queueDriver = (handle->queueDriver + 1U) % I2S_NUM_BUFFERS;
  533. /* Notify user */
  534. if (handle->completionCallback)
  535. {
  536. handle->completionCallback(base, handle, kStatus_I2S_BufferComplete, handle->userData);
  537. }
  538. /* Check if the next buffer contains anything to send */
  539. if (handle->i2sQueue[handle->queueDriver].dataSize == 0U)
  540. {
  541. /* Everything has been written to FIFO */
  542. handle->state = kI2S_StateTxWaitToWriteDummyData;
  543. break;
  544. }
  545. }
  546. }
  547. }
  548. else if (handle->state == kI2S_StateTxWaitToWriteDummyData)
  549. {
  550. /* Write dummy data */
  551. if ((handle->dataLength > 16U) && (handle->dataLength < 25U))
  552. {
  553. if (handle->useFifo48H)
  554. {
  555. base->FIFOWR48H = 0U;
  556. handle->useFifo48H = false;
  557. }
  558. else
  559. {
  560. base->FIFOWR = 0U;
  561. base->FIFOWR48H = 0U;
  562. }
  563. }
  564. else
  565. {
  566. base->FIFOWR = 0U;
  567. }
  568. /* Next time invoke this handler when FIFO becomes empty (TX level 0) */
  569. base->FIFOTRIG &= ~I2S_FIFOTRIG_TXLVL_MASK;
  570. handle->state = kI2S_StateTxWaitForEmptyFifo;
  571. }
  572. else if (handle->state == kI2S_StateTxWaitForEmptyFifo)
  573. {
  574. /* FIFO, including additional dummy data, has been emptied now,
  575. * all relevant data should have been output from peripheral */
  576. /* Stop transfer */
  577. I2S_Disable(base);
  578. I2S_DisableInterrupts(base, kI2S_TxErrorFlag | kI2S_TxLevelFlag);
  579. base->FIFOCFG |= I2S_FIFOCFG_EMPTYTX_MASK;
  580. /* Reset state */
  581. handle->state = kI2S_StateIdle;
  582. /* Notify user */
  583. if (handle->completionCallback)
  584. {
  585. handle->completionCallback(base, handle, kStatus_I2S_Done, handle->userData);
  586. }
  587. }
  588. else
  589. {
  590. /* Do nothing */
  591. }
  592. /* Clear TX level interrupt flag */
  593. base->FIFOSTAT = I2S_FIFOSTAT_TXLVL(1U);
  594. }
  595. }
  596. void I2S_RxHandleIRQ(I2S_Type *base, i2s_handle_t *handle)
  597. {
  598. uint32_t intstat = base->FIFOINTSTAT;
  599. uint32_t data;
  600. if (intstat & I2S_FIFOINTSTAT_RXERR_MASK)
  601. {
  602. handle->errorCount++;
  603. /* Clear RX error interrupt flag */
  604. base->FIFOSTAT = I2S_FIFOSTAT_RXERR(1U);
  605. }
  606. if (intstat & I2S_FIFOINTSTAT_RXLVL_MASK)
  607. {
  608. while ((base->FIFOSTAT & I2S_FIFOSTAT_RXNOTEMPTY_MASK) && (handle->i2sQueue[handle->queueDriver].dataSize > 0U))
  609. {
  610. /* Read input data */
  611. if (handle->dataLength == 4U)
  612. {
  613. data = base->FIFORD;
  614. *(handle->i2sQueue[handle->queueDriver].data) = ((data & 0x000F0000U) >> 12U) | (data & 0x0000000FU);
  615. handle->i2sQueue[handle->queueDriver].data++;
  616. handle->transferCount++;
  617. handle->i2sQueue[handle->queueDriver].dataSize--;
  618. }
  619. else if (handle->dataLength <= 8U)
  620. {
  621. data = base->FIFORD;
  622. *((volatile uint16_t *)handle->i2sQueue[handle->queueDriver].data) = ((data >> 8U) & 0xFF00U) | (data & 0xFFU);
  623. handle->i2sQueue[handle->queueDriver].data += sizeof(uint16_t);
  624. handle->transferCount += sizeof(uint16_t);
  625. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint16_t);
  626. }
  627. else if (handle->dataLength <= 16U)
  628. {
  629. data = base->FIFORD;
  630. *((volatile uint32_t *)handle->i2sQueue[handle->queueDriver].data) = data;
  631. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  632. handle->transferCount += sizeof(uint32_t);
  633. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  634. }
  635. else if (handle->dataLength <= 24U)
  636. {
  637. if (handle->pack48)
  638. {
  639. if (handle->useFifo48H)
  640. {
  641. data = base->FIFORD48H;
  642. handle->useFifo48H = false;
  643. *((volatile uint16_t *)handle->i2sQueue[handle->queueDriver].data) = data;
  644. handle->i2sQueue[handle->queueDriver].data += sizeof(uint16_t);
  645. handle->transferCount += sizeof(uint16_t);
  646. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint16_t);
  647. }
  648. else
  649. {
  650. data = base->FIFORD;
  651. handle->useFifo48H = true;
  652. *((volatile uint32_t *)handle->i2sQueue[handle->queueDriver].data) = data;
  653. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  654. handle->transferCount += sizeof(uint32_t);
  655. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  656. }
  657. }
  658. else
  659. {
  660. if (handle->useFifo48H)
  661. {
  662. data = base->FIFORD48H;
  663. handle->useFifo48H = false;
  664. }
  665. else
  666. {
  667. data = base->FIFORD;
  668. handle->useFifo48H = true;
  669. }
  670. *(handle->i2sQueue[handle->queueDriver].data++) = data & 0xFFU;
  671. *(handle->i2sQueue[handle->queueDriver].data++) = (data >> 8U) & 0xFFU;
  672. *(handle->i2sQueue[handle->queueDriver].data++) = (data >> 16U) & 0xFFU;
  673. handle->transferCount += 3U;
  674. handle->i2sQueue[handle->queueDriver].dataSize -= 3U;
  675. }
  676. }
  677. else /* if (handle->dataLength <= 32U) */
  678. {
  679. data = base->FIFORD;
  680. *((volatile uint32_t *)handle->i2sQueue[handle->queueDriver].data) = data;
  681. handle->i2sQueue[handle->queueDriver].data += sizeof(uint32_t);
  682. handle->transferCount += sizeof(uint32_t);
  683. handle->i2sQueue[handle->queueDriver].dataSize -= sizeof(uint32_t);
  684. }
  685. if (handle->i2sQueue[handle->queueDriver].dataSize == 0U)
  686. {
  687. /* Actual data buffer filled with input data, switch to a next one */
  688. handle->queueDriver = (handle->queueDriver + 1U) % I2S_NUM_BUFFERS;
  689. /* Notify user */
  690. if (handle->completionCallback)
  691. {
  692. handle->completionCallback(base, handle, kStatus_I2S_BufferComplete, handle->userData);
  693. }
  694. if (handle->i2sQueue[handle->queueDriver].dataSize == 0U)
  695. {
  696. /* No other buffer prepared to receive data into */
  697. /* Disable I2S operation and interrupts */
  698. I2S_Disable(base);
  699. I2S_DisableInterrupts(base, kI2S_RxErrorFlag | kI2S_RxLevelFlag);
  700. base->FIFOCFG |= I2S_FIFOCFG_EMPTYRX_MASK;
  701. /* Reset state */
  702. handle->state = kI2S_StateIdle;
  703. /* Notify user */
  704. if (handle->completionCallback)
  705. {
  706. handle->completionCallback(base, handle, kStatus_I2S_Done, handle->userData);
  707. }
  708. /* Clear RX level interrupt flag */
  709. base->FIFOSTAT = I2S_FIFOSTAT_RXLVL(1U);
  710. return;
  711. }
  712. }
  713. }
  714. /* Clear RX level interrupt flag */
  715. base->FIFOSTAT = I2S_FIFOSTAT_RXLVL(1U);
  716. }
  717. }