fsl_spdif.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /*
  2. * Copyright (c) 2017, NXP Semiconductor, Inc.
  3. * All rights reserved.
  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 Freescale Semiconductor, Inc. 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_spdif.h"
  31. /*******************************************************************************
  32. * Definitations
  33. ******************************************************************************/
  34. enum _spdif_transfer_state
  35. {
  36. kSPDIF_Busy = 0x0U, /*!< SPDIF is busy */
  37. kSPDIF_Idle, /*!< Transfer is done. */
  38. kSPDIF_Error /*!< Transfer error occured. */
  39. };
  40. /*! @brief Typedef for spdif tx interrupt handler. */
  41. typedef void (*spdif_isr_t)(SPDIF_Type *base, spdif_handle_t *handle);
  42. /*******************************************************************************
  43. * Prototypes
  44. ******************************************************************************/
  45. /*!
  46. * @brief Get the instance number for SPDIF.
  47. *
  48. * @param base SPDIF base pointer.
  49. */
  50. uint32_t SPDIF_GetInstance(SPDIF_Type *base);
  51. /*******************************************************************************
  52. * Variables
  53. ******************************************************************************/
  54. /* Base pointer array */
  55. static SPDIF_Type *const s_spdifBases[] = SPDIF_BASE_PTRS;
  56. /*! @brief SPDIF handle pointer */
  57. spdif_handle_t *s_spdifHandle[ARRAY_SIZE(s_spdifBases)][2];
  58. /* IRQ number array */
  59. static const IRQn_Type s_spdifIRQ[] = SPDIF_IRQS;
  60. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  61. /* Clock name array */
  62. static const clock_ip_name_t s_spdifClock[] = SPDIF_CLOCKS;
  63. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  64. /*! @brief Pointer to IRQ handler for each instance. */
  65. static spdif_isr_t s_spdifTxIsr;
  66. /*! @brief Pointer to IRQ handler for each instance. */
  67. static spdif_isr_t s_spdifRxIsr;
  68. /*! @brief Used for spdif gain */
  69. static uint8_t s_spdif_gain[8] = {24U, 16U, 12U, 8U, 6U, 4U, 3U, 1U};
  70. static uint8_t s_spdif_tx_watermark[4] = {16, 12, 8, 4};
  71. static uint8_t s_spdif_rx_watermark[4] = {1, 4, 8, 16};
  72. /*******************************************************************************
  73. * Code
  74. ******************************************************************************/
  75. uint32_t SPDIF_GetInstance(SPDIF_Type *base)
  76. {
  77. uint32_t instance;
  78. /* Find the instance index from base address mappings. */
  79. for (instance = 0; instance < ARRAY_SIZE(s_spdifBases); instance++)
  80. {
  81. if (s_spdifBases[instance] == base)
  82. {
  83. break;
  84. }
  85. }
  86. assert(instance < ARRAY_SIZE(s_spdifBases));
  87. return instance;
  88. }
  89. void SPDIF_Init(SPDIF_Type *base, const spdif_config_t *config)
  90. {
  91. uint32_t val = 0;
  92. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  93. /* Enable the SPDIF clock */
  94. CLOCK_EnableClock(s_spdifClock[SPDIF_GetInstance(base)]);
  95. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  96. /* Reset the internal logic */
  97. base->SCR |= SPDIF_SCR_SOFT_RESET_MASK;
  98. /* Waiting for reset finish */
  99. while (base->SCR & SPDIF_SCR_SOFT_RESET_MASK)
  100. {
  101. }
  102. /* Setting the SPDIF settings */
  103. base->SCR = SPDIF_SCR_RXFIFOFULL_SEL(config->rxFullSelect) | SPDIF_SCR_RXAUTOSYNC(config->isRxAutoSync) |
  104. SPDIF_SCR_TXAUTOSYNC(config->isRxAutoSync) | SPDIF_SCR_TXFIFOEMPTY_SEL(config->txFullSelect) |
  105. SPDIF_SCR_TXFIFO_CTRL(1U) | SPDIF_SCR_VALCTRL(config->validityConfig) |
  106. SPDIF_SCR_TXSEL(config->txSource) | SPDIF_SCR_USRC_SEL(config->uChannelSrc);
  107. /* Set DPLL clock source */
  108. base->SRPC = SPDIF_SRPC_CLKSRC_SEL(config->DPLLClkSource) | SPDIF_SRPC_GAINSEL(config->gain);
  109. /* Set SPDIF tx clock source */
  110. val = base->STC & ~SPDIF_STC_TXCLK_SOURCE_MASK;
  111. val |= SPDIF_STC_TXCLK_SOURCE(config->txClkSource);
  112. base->STC = val;
  113. }
  114. void SPDIF_Deinit(SPDIF_Type *base)
  115. {
  116. SPDIF_TxEnable(base, false);
  117. SPDIF_RxEnable(base, false);
  118. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  119. CLOCK_DisableClock(s_spdifClock[SPDIF_GetInstance(base)]);
  120. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  121. }
  122. void SPDIF_GetDefaultConfig(spdif_config_t *config)
  123. {
  124. config->isTxAutoSync = true;
  125. config->isRxAutoSync = true;
  126. config->DPLLClkSource = 1;
  127. config->txClkSource = 1;
  128. config->rxFullSelect = kSPDIF_RxFull8Samples;
  129. config->txFullSelect = kSPDIF_TxEmpty8Samples;
  130. config->uChannelSrc = kSPDIF_UChannelFromTx;
  131. config->txSource = kSPDIF_txNormal;
  132. config->validityConfig = kSPDIF_validityFlagAlwaysClear;
  133. config->gain = kSPDIF_GAIN_8;
  134. }
  135. void SPDIF_TxEnable(SPDIF_Type *base, bool enable)
  136. {
  137. uint32_t val = 0;
  138. if (enable)
  139. {
  140. /* Open Tx FIFO */
  141. val = base->SCR & (~SPDIF_SCR_TXFIFO_CTRL_MASK);
  142. val |= SPDIF_SCR_TXFIFO_CTRL(1U);
  143. base->SCR = val;
  144. /* Enable transfer clock */
  145. base->STC |= SPDIF_STC_TX_ALL_CLK_EN_MASK;
  146. }
  147. else
  148. {
  149. base->SCR &= ~(SPDIF_SCR_TXFIFO_CTRL_MASK | SPDIF_SCR_TXSEL_MASK);
  150. /* Disable transfer clock */
  151. base->STC &= ~SPDIF_STC_TX_ALL_CLK_EN_MASK;
  152. }
  153. }
  154. void SPDIF_TxSetSampleRate(SPDIF_Type *base, uint32_t sampleRate_Hz, uint32_t sourceClockFreq_Hz)
  155. {
  156. uint32_t clkDiv = sourceClockFreq_Hz / (sampleRate_Hz * 64);
  157. uint32_t mod = sourceClockFreq_Hz % (sampleRate_Hz * 64);
  158. uint32_t val = 0;
  159. uint8_t clockSource = (((base->STC) & SPDIF_STC_TXCLK_SOURCE_MASK) >> SPDIF_STC_TXCLK_SOURCE_SHIFT);
  160. /* Compute the nearest divider */
  161. if (mod > ((sampleRate_Hz * 64) / 2))
  162. {
  163. clkDiv += 1U;
  164. }
  165. /* If use divided systeme clock */
  166. if (clockSource == 5U)
  167. {
  168. if (clkDiv > 256)
  169. {
  170. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  171. val |= SPDIF_STC_SYSCLK_DF(clkDiv / 128U - 1U) | SPDIF_STC_TXCLK_DF(127U);
  172. base->STC = val;
  173. }
  174. else
  175. {
  176. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  177. val |= SPDIF_STC_SYSCLK_DF(1U) | SPDIF_STC_TXCLK_DF(clkDiv - 1U);
  178. base->STC = val;
  179. }
  180. }
  181. else
  182. {
  183. /* Other clock only uses txclk div */
  184. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  185. val |= SPDIF_STC_TXCLK_DF(clkDiv - 1U);
  186. base->STC = val;
  187. }
  188. }
  189. uint32_t SPDIF_GetRxSampleRate(SPDIF_Type *base, uint32_t clockSourceFreq_Hz)
  190. {
  191. uint32_t gain = s_spdif_gain[((base->SRPC & SPDIF_SRPC_GAINSEL_MASK) >> SPDIF_SRPC_GAINSEL_SHIFT)];
  192. uint32_t measure = 0, sampleRate = 0;
  193. uint64_t temp = 0;
  194. /* Wait the DPLL locked */
  195. while ((base->SRPC & SPDIF_SRPC_LOCK_MASK) == 0U)
  196. {
  197. }
  198. /* Get the measure value */
  199. measure = base->SRFM;
  200. temp = (uint64_t)measure * (uint64_t)clockSourceFreq_Hz;
  201. temp /= (uint64_t)(1024 * 1024 * 128 * gain);
  202. sampleRate = (uint32_t)temp;
  203. return sampleRate;
  204. }
  205. void SPDIF_WriteBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size)
  206. {
  207. assert(buffer);
  208. assert(size / 6U == 0U);
  209. uint32_t i = 0, j = 0, data = 0;
  210. while (i < size)
  211. {
  212. /* Wait until it can write data */
  213. while ((SPDIF_GetStatusFlag(base) & kSPDIF_TxFIFOEmpty) == 0U)
  214. {
  215. }
  216. /* Write left channel data */
  217. for (j = 0; j < 3U; j++)
  218. {
  219. data |= ((uint32_t)(*buffer) << (j * 8U));
  220. buffer++;
  221. }
  222. SPDIF_WriteLeftData(base, data);
  223. /* Write right channel data */
  224. data = 0;
  225. for (j = 0; j < 3U; j++)
  226. {
  227. data |= ((uint32_t)(*buffer) << (j * 8U));
  228. buffer++;
  229. }
  230. SPDIF_WriteRightData(base, data);
  231. i += 6U;
  232. }
  233. }
  234. void SPDIF_ReadBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size)
  235. {
  236. assert(buffer);
  237. assert(size / 6U == 0U);
  238. uint32_t i = 0, j = 0, data = 0;
  239. while (i < size)
  240. {
  241. /* Wait until it can write data */
  242. while ((SPDIF_GetStatusFlag(base) & kSPDIF_RxFIFOFull) == 0U)
  243. {
  244. }
  245. /* Write left channel data */
  246. data = SPDIF_ReadLeftData(base);
  247. for (j = 0; j < 3U; j++)
  248. {
  249. *buffer = ((data >> (j * 8U)) & 0xFFU);
  250. buffer++;
  251. }
  252. /* Write right channel data */
  253. data = SPDIF_ReadRightData(base);
  254. for (j = 0; j < 3U; j++)
  255. {
  256. *buffer = ((data >> (j * 8U)) & 0xFFU);
  257. buffer++;
  258. }
  259. i += 6U;
  260. }
  261. }
  262. void SPDIF_TransferTxCreateHandle(SPDIF_Type *base,
  263. spdif_handle_t *handle,
  264. spdif_transfer_callback_t callback,
  265. void *userData)
  266. {
  267. assert(handle);
  268. /* Zero the handle */
  269. memset(handle, 0, sizeof(*handle));
  270. s_spdifHandle[SPDIF_GetInstance(base)][0] = handle;
  271. handle->callback = callback;
  272. handle->userData = userData;
  273. handle->watermark =
  274. s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT];
  275. /* Set the isr pointer */
  276. s_spdifTxIsr = SPDIF_TransferTxHandleIRQ;
  277. /* Enable Tx irq */
  278. EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]);
  279. }
  280. void SPDIF_TransferRxCreateHandle(SPDIF_Type *base,
  281. spdif_handle_t *handle,
  282. spdif_transfer_callback_t callback,
  283. void *userData)
  284. {
  285. assert(handle);
  286. /* Zero the handle */
  287. memset(handle, 0, sizeof(*handle));
  288. s_spdifHandle[SPDIF_GetInstance(base)][1] = handle;
  289. handle->callback = callback;
  290. handle->userData = userData;
  291. handle->watermark =
  292. s_spdif_rx_watermark[(base->SCR & SPDIF_SCR_RXFIFOFULL_SEL_MASK) >> SPDIF_SCR_RXFIFOFULL_SEL_SHIFT];
  293. /* Set the isr pointer */
  294. s_spdifRxIsr = SPDIF_TransferRxHandleIRQ;
  295. /* Enable Rx irq */
  296. EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]);
  297. }
  298. status_t SPDIF_TransferSendNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer)
  299. {
  300. assert(handle);
  301. /* Check if the queue is full */
  302. if (handle->spdifQueue[handle->queueUser].data)
  303. {
  304. return kStatus_SPDIF_QueueFull;
  305. }
  306. /* Add into queue */
  307. handle->transferSize[handle->queueUser] = xfer->dataSize;
  308. handle->spdifQueue[handle->queueUser].data = xfer->data;
  309. handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
  310. handle->queueUser = (handle->queueUser + 1) % SPDIF_XFER_QUEUE_SIZE;
  311. /* Set the state to busy */
  312. handle->state = kSPDIF_Busy;
  313. /* Enable interrupt */
  314. SPDIF_EnableInterrupts(base, kSPDIF_TxFIFOEmpty);
  315. /* Enable Tx transfer */
  316. SPDIF_TxEnable(base, true);
  317. return kStatus_Success;
  318. }
  319. status_t SPDIF_TransferReceiveNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer)
  320. {
  321. assert(handle);
  322. /* Check if the queue is full */
  323. if (handle->spdifQueue[handle->queueUser].data)
  324. {
  325. return kStatus_SPDIF_QueueFull;
  326. }
  327. /* Add into queue */
  328. handle->transferSize[handle->queueUser] = xfer->dataSize;
  329. handle->spdifQueue[handle->queueUser].data = xfer->data;
  330. handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
  331. handle->spdifQueue[handle->queueUser].udata = xfer->udata;
  332. handle->spdifQueue[handle->queueUser].qdata = xfer->qdata;
  333. handle->queueUser = (handle->queueUser + 1) % SPDIF_XFER_QUEUE_SIZE;
  334. /* Set state to busy */
  335. handle->state = kSPDIF_Busy;
  336. /* Enable interrupt */
  337. SPDIF_EnableInterrupts(base, kSPDIF_UChannelReceiveRegisterFull | kSPDIF_QChannelReceiveRegisterFull |
  338. kSPDIF_RxFIFOFull | kSPDIF_RxControlChannelChange);
  339. /* Enable Rx transfer */
  340. SPDIF_RxEnable(base, true);
  341. return kStatus_Success;
  342. }
  343. status_t SPDIF_TransferGetSendCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count)
  344. {
  345. assert(handle);
  346. status_t status = kStatus_Success;
  347. if (handle->state != kSPDIF_Busy)
  348. {
  349. status = kStatus_NoTransferInProgress;
  350. }
  351. else
  352. {
  353. *count = (handle->transferSize[handle->queueDriver] - handle->spdifQueue[handle->queueDriver].dataSize);
  354. }
  355. return status;
  356. }
  357. status_t SPDIF_TransferGetReceiveCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count)
  358. {
  359. assert(handle);
  360. status_t status = kStatus_Success;
  361. if (handle->state != kSPDIF_Busy)
  362. {
  363. status = kStatus_NoTransferInProgress;
  364. }
  365. else
  366. {
  367. *count = (handle->transferSize[handle->queueDriver] - handle->spdifQueue[handle->queueDriver].dataSize);
  368. }
  369. return status;
  370. }
  371. void SPDIF_TransferAbortSend(SPDIF_Type *base, spdif_handle_t *handle)
  372. {
  373. assert(handle);
  374. /* Use FIFO request interrupt and fifo error */
  375. SPDIF_DisableInterrupts(base, kSPDIF_TxFIFOEmpty);
  376. handle->state = kSPDIF_Idle;
  377. /* Clear the queue */
  378. memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE);
  379. handle->queueDriver = 0;
  380. handle->queueUser = 0;
  381. }
  382. void SPDIF_TransferAbortReceive(SPDIF_Type *base, spdif_handle_t *handle)
  383. {
  384. assert(handle);
  385. /* Disable interrupt */
  386. SPDIF_DisableInterrupts(base, kSPDIF_UChannelReceiveRegisterFull | kSPDIF_QChannelReceiveRegisterFull |
  387. kSPDIF_RxFIFOFull | kSPDIF_RxControlChannelChange);
  388. handle->state = kSPDIF_Idle;
  389. /* Clear the queue */
  390. memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE);
  391. handle->queueDriver = 0;
  392. handle->queueUser = 0;
  393. }
  394. void SPDIF_TransferTxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle)
  395. {
  396. assert(handle);
  397. uint8_t *buffer = handle->spdifQueue[handle->queueDriver].data;
  398. uint8_t dataSize = 0;
  399. uint32_t i = 0, j = 0, data = 0;
  400. /* Do Transfer */
  401. if ((SPDIF_GetStatusFlag(base) & kSPDIF_TxFIFOEmpty) && (base->SIE & kSPDIF_TxFIFOEmpty))
  402. {
  403. dataSize = handle->watermark;
  404. while (i < dataSize)
  405. {
  406. data = 0;
  407. /* Write left channel data */
  408. for (j = 0; j < 3U; j++)
  409. {
  410. data |= ((uint32_t)(*buffer) << (j * 8U));
  411. buffer++;
  412. }
  413. SPDIF_WriteLeftData(base, data);
  414. /* Write right channel data */
  415. data = 0;
  416. for (j = 0; j < 3U; j++)
  417. {
  418. data |= ((uint32_t)(*buffer) << (j * 8U));
  419. buffer++;
  420. }
  421. SPDIF_WriteRightData(base, data);
  422. i++;
  423. }
  424. handle->spdifQueue[handle->queueDriver].dataSize -= dataSize * 6U;
  425. handle->spdifQueue[handle->queueDriver].data += dataSize * 6U;
  426. /* If finished a blcok, call the callback function */
  427. if (handle->spdifQueue[handle->queueDriver].dataSize == 0U)
  428. {
  429. memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t));
  430. handle->queueDriver = (handle->queueDriver + 1) % SPDIF_XFER_QUEUE_SIZE;
  431. if (handle->callback)
  432. {
  433. (handle->callback)(base, handle, kStatus_SPDIF_TxIdle, handle->userData);
  434. }
  435. }
  436. /* If all data finished, just stop the transfer */
  437. if (handle->spdifQueue[handle->queueDriver].data == NULL)
  438. {
  439. SPDIF_TransferAbortSend(base, handle);
  440. }
  441. }
  442. }
  443. void SPDIF_TransferRxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle)
  444. {
  445. assert(handle);
  446. uint8_t *buffer = NULL;
  447. uint8_t dataSize = 0;
  448. uint32_t i = 0, j = 0, data = 0;
  449. /* Handle Cnew flag */
  450. if (SPDIF_GetStatusFlag(base) & kSPDIF_RxControlChannelChange)
  451. {
  452. /* Clear the interrupt flag */
  453. SPDIF_ClearStatusFlags(base, SPDIF_SIE_CNEW_MASK);
  454. if (handle->callback)
  455. {
  456. (handle->callback)(base, handle, kStatus_SPDIF_RxCnew, handle->userData);
  457. }
  458. }
  459. /* Handle illegal symbol */
  460. if (SPDIF_GetStatusFlag(base) & kSPDIF_RxIllegalSymbol)
  461. {
  462. SPDIF_ClearStatusFlags(base, kSPDIF_RxIllegalSymbol);
  463. if (handle->callback)
  464. {
  465. (handle->callback)(base, handle, kStatus_SPDIF_RxIllegalSymbol, handle->userData);
  466. }
  467. }
  468. /* Handle Parity Bit Error */
  469. if (SPDIF_GetStatusFlag(base) & kSPDIF_RxParityBitError)
  470. {
  471. SPDIF_ClearStatusFlags(base, kSPDIF_RxParityBitError);
  472. if (handle->callback)
  473. {
  474. (handle->callback)(base, handle, kStatus_SPDIF_RxParityBitError, handle->userData);
  475. }
  476. }
  477. /* Handle DPlocked */
  478. if (SPDIF_GetStatusFlag(base) & kSPDIF_RxDPLLLocked)
  479. {
  480. SPDIF_ClearStatusFlags(base, kSPDIF_RxDPLLLocked);
  481. if (handle->callback)
  482. {
  483. (handle->callback)(base, handle, kStatus_SPDIF_RxDPLLLocked, handle->userData);
  484. }
  485. }
  486. /* Handle Q channel full flag */
  487. if ((SPDIF_GetStatusFlag(base) & kSPDIF_QChannelReceiveRegisterFull) &&
  488. (base->SIE & kSPDIF_QChannelReceiveRegisterFull))
  489. {
  490. buffer = handle->spdifQueue[handle->queueDriver].qdata;
  491. data = SPDIF_ReadQChannel(base);
  492. buffer[0] = data & 0xFFU;
  493. buffer[1] = (data >> 8U) & 0xFFU;
  494. buffer[2] = (data >> 16U) & 0xFFU;
  495. }
  496. /* Handle U channel full flag */
  497. if ((SPDIF_GetStatusFlag(base) & kSPDIF_UChannelReceiveRegisterFull) &&
  498. (base->SIE & kSPDIF_UChannelReceiveRegisterFull))
  499. {
  500. buffer = handle->spdifQueue[handle->queueDriver].udata;
  501. data = SPDIF_ReadUChannel(base);
  502. buffer[0] = data & 0xFFU;
  503. buffer[1] = (data >> 8U) & 0xFFU;
  504. buffer[2] = (data >> 16U) & 0xFFU;
  505. }
  506. /* Handle audio data transfer */
  507. if ((SPDIF_GetStatusFlag(base) & kSPDIF_RxFIFOFull) && (base->SIE & kSPDIF_RxFIFOFull))
  508. {
  509. dataSize = handle->watermark;
  510. buffer = handle->spdifQueue[handle->queueDriver].data;
  511. while (i < dataSize)
  512. {
  513. /* Read left channel data */
  514. data = SPDIF_ReadLeftData(base);
  515. for (j = 0; j < 3U; j++)
  516. {
  517. *buffer = ((data >> (j * 8U)) & 0xFFU);
  518. buffer++;
  519. }
  520. /* Read right channel data */
  521. data = SPDIF_ReadRightData(base);
  522. for (j = 0; j < 3U; j++)
  523. {
  524. *buffer = ((data >> (j * 8U)) & 0xFFU);
  525. buffer++;
  526. }
  527. i++;
  528. }
  529. handle->spdifQueue[handle->queueDriver].dataSize -= dataSize * 6U;
  530. handle->spdifQueue[handle->queueDriver].data += dataSize * 6U;
  531. /* If finished a blcok, call the callback function */
  532. if (handle->spdifQueue[handle->queueDriver].dataSize == 0U)
  533. {
  534. memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t));
  535. handle->queueDriver = (handle->queueDriver + 1) % SPDIF_XFER_QUEUE_SIZE;
  536. if (handle->callback)
  537. {
  538. (handle->callback)(base, handle, kStatus_SPDIF_RxIdle, handle->userData);
  539. }
  540. }
  541. /* If all data finished, just stop the transfer */
  542. if (handle->spdifQueue[handle->queueDriver].data == NULL)
  543. {
  544. SPDIF_TransferAbortReceive(base, handle);
  545. }
  546. }
  547. }
  548. #if defined(SPDIF)
  549. void SPDIF_DriverIRQHandler(void)
  550. {
  551. if ((s_spdifHandle[0][0]) && s_spdifTxIsr)
  552. {
  553. s_spdifTxIsr(SPDIF, s_spdifHandle[0][0]);
  554. }
  555. if ((s_spdifHandle[0][1]) && s_spdifRxIsr)
  556. {
  557. s_spdifRxIsr(SPDIF, s_spdifHandle[0][1]);
  558. }
  559. /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
  560. exception return operation might vector to incorrect interrupt */
  561. #if defined __CORTEX_M && (__CORTEX_M == 4U)
  562. __DSB();
  563. #endif
  564. }
  565. #endif