fsl_spdif.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /*
  2. * Copyright 2017-2020 NXP
  3. * All rights reserved.
  4. *
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include "fsl_spdif.h"
  9. /* Component ID definition, used by tools. */
  10. #ifndef FSL_COMPONENT_ID
  11. #define FSL_COMPONENT_ID "platform.drivers.spdif"
  12. #endif
  13. /*******************************************************************************
  14. * Definitations
  15. ******************************************************************************/
  16. /*! @brief spdif transfer state. */
  17. enum
  18. {
  19. kSPDIF_Busy = 0x0U, /*!< SPDIF is busy */
  20. kSPDIF_Idle, /*!< Transfer is done. */
  21. kSPDIF_Error /*!< Transfer error occurred. */
  22. };
  23. /*! @brief Typedef for spdif tx interrupt handler. */
  24. typedef void (*spdif_isr_t)(SPDIF_Type *base, spdif_handle_t *handle);
  25. /*******************************************************************************
  26. * Prototypes
  27. ******************************************************************************/
  28. /*******************************************************************************
  29. * Variables
  30. ******************************************************************************/
  31. /* Base pointer array */
  32. static SPDIF_Type *const s_spdifBases[] = SPDIF_BASE_PTRS;
  33. /*! @brief SPDIF handle pointer */
  34. static spdif_handle_t *s_spdifHandle[ARRAY_SIZE(s_spdifBases)][2];
  35. /* IRQ number array */
  36. static const IRQn_Type s_spdifIRQ[] = SPDIF_IRQS;
  37. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  38. /* Clock name array */
  39. static const clock_ip_name_t s_spdifClock[] = SPDIF_CLOCKS;
  40. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  41. /*! @brief Pointer to IRQ handler for each instance. */
  42. static spdif_isr_t s_spdifTxIsr;
  43. /*! @brief Pointer to IRQ handler for each instance. */
  44. static spdif_isr_t s_spdifRxIsr;
  45. /*! @brief Used for spdif gain */
  46. static uint8_t s_spdif_gain[8] = {24U, 16U, 12U, 8U, 6U, 4U, 3U, 1U};
  47. static uint8_t s_spdif_tx_watermark[4] = {16, 12, 8, 4};
  48. static uint8_t s_spdif_rx_watermark[4] = {1, 4, 8, 16};
  49. /*******************************************************************************
  50. * Code
  51. ******************************************************************************/
  52. uint32_t SPDIF_GetInstance(SPDIF_Type *base)
  53. {
  54. uint32_t instance;
  55. /* Find the instance index from base address mappings. */
  56. for (instance = 0; instance < ARRAY_SIZE(s_spdifBases); instance++)
  57. {
  58. if (s_spdifBases[instance] == base)
  59. {
  60. break;
  61. }
  62. }
  63. assert(instance < ARRAY_SIZE(s_spdifBases));
  64. return instance;
  65. }
  66. /*!
  67. * brief Initializes the SPDIF peripheral.
  68. *
  69. * Ungates the SPDIF clock, resets the module, and configures SPDIF with a configuration structure.
  70. * The configuration structure can be custom filled or set with default values by
  71. * SPDIF_GetDefaultConfig().
  72. *
  73. * note This API should be called at the beginning of the application to use
  74. * the SPDIF driver. Otherwise, accessing the SPDIF module can cause a hard fault
  75. * because the clock is not enabled.
  76. *
  77. * param base SPDIF base pointer
  78. * param config SPDIF configuration structure.
  79. */
  80. void SPDIF_Init(SPDIF_Type *base, const spdif_config_t *config)
  81. {
  82. uint32_t val = 0;
  83. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  84. /* Enable the SPDIF clock */
  85. CLOCK_EnableClock(s_spdifClock[SPDIF_GetInstance(base)]);
  86. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  87. /* Reset the internal logic */
  88. base->SCR |= SPDIF_SCR_SOFT_RESET_MASK;
  89. /* Waiting for reset finish */
  90. while ((base->SCR & SPDIF_SCR_SOFT_RESET_MASK) != 0x00U)
  91. {
  92. }
  93. /* Setting the SPDIF settings */
  94. base->SCR = SPDIF_SCR_RXFIFOFULL_SEL(config->rxFullSelect) | SPDIF_SCR_RXAUTOSYNC(config->isRxAutoSync) |
  95. SPDIF_SCR_TXAUTOSYNC(config->isRxAutoSync) | SPDIF_SCR_TXFIFOEMPTY_SEL(config->txFullSelect) |
  96. SPDIF_SCR_TXFIFO_CTRL(1U) | SPDIF_SCR_VALCTRL(config->validityConfig) |
  97. SPDIF_SCR_TXSEL(config->txSource) | SPDIF_SCR_USRC_SEL(config->uChannelSrc);
  98. /* Set DPLL clock source */
  99. base->SRPC = SPDIF_SRPC_CLKSRC_SEL(config->DPLLClkSource) | SPDIF_SRPC_GAINSEL(config->gain);
  100. /* Set SPDIF tx clock source */
  101. val = base->STC & ~SPDIF_STC_TXCLK_SOURCE_MASK;
  102. val |= SPDIF_STC_TXCLK_SOURCE(config->txClkSource);
  103. base->STC = val;
  104. /* clear and diable all the interrupt */
  105. base->SIC = (uint32_t)kSPDIF_AllInterrupt;
  106. base->SIE &= ~(uint32_t)kSPDIF_AllInterrupt;
  107. }
  108. /*!
  109. * brief De-initializes the SPDIF peripheral.
  110. *
  111. * This API gates the SPDIF clock. The SPDIF module can't operate unless SPDIF_Init is called to enable the clock.
  112. *
  113. * param base SPDIF base pointer
  114. */
  115. void SPDIF_Deinit(SPDIF_Type *base)
  116. {
  117. SPDIF_TxEnable(base, false);
  118. SPDIF_RxEnable(base, false);
  119. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  120. CLOCK_DisableClock(s_spdifClock[SPDIF_GetInstance(base)]);
  121. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  122. }
  123. /*!
  124. * brief Sets the SPDIF configuration structure to default values.
  125. *
  126. * This API initializes the configuration structure for use in SPDIF_Init.
  127. * The initialized structure can remain unchanged in SPDIF_Init, or it can be modified
  128. * before calling SPDIF_Init.
  129. * This is an example.
  130. code
  131. spdif_config_t config;
  132. SPDIF_GetDefaultConfig(&config);
  133. endcode
  134. *
  135. * param config pointer to master configuration structure
  136. */
  137. void SPDIF_GetDefaultConfig(spdif_config_t *config)
  138. {
  139. /* Initializes the configure structure to zero. */
  140. (void)memset(config, 0, sizeof(*config));
  141. config->isTxAutoSync = true;
  142. config->isRxAutoSync = true;
  143. config->DPLLClkSource = 1;
  144. config->txClkSource = 1;
  145. config->rxFullSelect = kSPDIF_RxFull8Samples;
  146. config->txFullSelect = kSPDIF_TxEmpty8Samples;
  147. config->uChannelSrc = kSPDIF_UChannelFromTx;
  148. config->txSource = kSPDIF_txNormal;
  149. config->validityConfig = kSPDIF_validityFlagAlwaysClear;
  150. config->gain = kSPDIF_GAIN_8;
  151. }
  152. /*!
  153. * brief Enables/disables the SPDIF Tx.
  154. *
  155. * param base SPDIF base pointer
  156. * param enable True means enable SPDIF Tx, false means disable.
  157. */
  158. void SPDIF_TxEnable(SPDIF_Type *base, bool enable)
  159. {
  160. uint32_t val = 0;
  161. if (enable)
  162. {
  163. /* Open Tx FIFO */
  164. val = base->SCR & (~SPDIF_SCR_TXFIFO_CTRL_MASK);
  165. val |= SPDIF_SCR_TXFIFO_CTRL(1U);
  166. base->SCR = val;
  167. /* Enable transfer clock */
  168. base->STC |= SPDIF_STC_TX_ALL_CLK_EN_MASK;
  169. }
  170. else
  171. {
  172. base->SCR &= ~(SPDIF_SCR_TXFIFO_CTRL_MASK | SPDIF_SCR_TXSEL_MASK);
  173. /* Disable transfer clock */
  174. base->STC &= ~SPDIF_STC_TX_ALL_CLK_EN_MASK;
  175. }
  176. }
  177. /*!
  178. * brief Configures the SPDIF Tx sample rate.
  179. *
  180. * The audio format can be changed at run-time. This function configures the sample rate.
  181. *
  182. * param base SPDIF base pointer.
  183. * param sampleRate_Hz SPDIF sample rate frequency in Hz.
  184. * param sourceClockFreq_Hz SPDIF tx clock source frequency in Hz.
  185. */
  186. void SPDIF_TxSetSampleRate(SPDIF_Type *base, uint32_t sampleRate_Hz, uint32_t sourceClockFreq_Hz)
  187. {
  188. uint32_t clkDiv = sourceClockFreq_Hz / (sampleRate_Hz * 64U);
  189. uint32_t mod = sourceClockFreq_Hz % (sampleRate_Hz * 64U);
  190. uint32_t val = 0;
  191. uint8_t clockSource = (uint8_t)(((base->STC) & SPDIF_STC_TXCLK_SOURCE_MASK) >> SPDIF_STC_TXCLK_SOURCE_SHIFT);
  192. /* Compute the nearest divider */
  193. if (mod > ((sampleRate_Hz * 64U) / 2U))
  194. {
  195. clkDiv += 1U;
  196. }
  197. /* If use divided systeme clock */
  198. if (clockSource == 5U)
  199. {
  200. if (clkDiv > 256U)
  201. {
  202. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  203. val |= SPDIF_STC_SYSCLK_DF((clkDiv / 128U) - 1U) | SPDIF_STC_TXCLK_DF(127U);
  204. base->STC = val;
  205. }
  206. else
  207. {
  208. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  209. val |= SPDIF_STC_SYSCLK_DF(1U) | SPDIF_STC_TXCLK_DF(clkDiv - 1U);
  210. base->STC = val;
  211. }
  212. }
  213. else
  214. {
  215. /* Other clock only uses txclk div */
  216. val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK));
  217. val |= SPDIF_STC_TXCLK_DF(clkDiv - 1U);
  218. base->STC = val;
  219. }
  220. }
  221. /*!
  222. * brief Configures the SPDIF Rx audio format.
  223. *
  224. * The audio format can be changed at run-time. This function configures the sample rate and audio data
  225. * format to be transferred.
  226. *
  227. * param base SPDIF base pointer.
  228. * param clockSourceFreq_Hz SPDIF system clock frequency in hz.
  229. */
  230. uint32_t SPDIF_GetRxSampleRate(SPDIF_Type *base, uint32_t clockSourceFreq_Hz)
  231. {
  232. uint64_t gain = s_spdif_gain[((base->SRPC & SPDIF_SRPC_GAINSEL_MASK) >> SPDIF_SRPC_GAINSEL_SHIFT)];
  233. uint32_t measure = 0;
  234. uint32_t sampleRate = 0;
  235. uint64_t temp = 0;
  236. /* Wait the DPLL locked */
  237. while ((base->SRPC & SPDIF_SRPC_LOCK_MASK) == 0U)
  238. {
  239. }
  240. /* Get the measure value */
  241. measure = base->SRFM;
  242. temp = (uint64_t)measure * (uint64_t)clockSourceFreq_Hz;
  243. temp /= 1024U * 1024U * 128U * gain;
  244. sampleRate = (uint32_t)temp;
  245. return sampleRate;
  246. }
  247. /*!
  248. * brief Sends data using a blocking method.
  249. *
  250. * note This function blocks by polling until data is ready to be sent.
  251. *
  252. * param base SPDIF base pointer.
  253. * param buffer Pointer to the data to be written.
  254. * param size Bytes to be written.
  255. */
  256. void SPDIF_WriteBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size)
  257. {
  258. assert(buffer != NULL);
  259. assert((size % 6U) == 0U);
  260. uint32_t i = 0, j = 0, data = 0;
  261. while (i < size)
  262. {
  263. /* Wait until it can write data */
  264. while ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_TxFIFOEmpty) == 0x00U)
  265. {
  266. }
  267. /* Write left channel data */
  268. for (j = 0; j < 3U; j++)
  269. {
  270. data |= ((uint32_t)(*buffer) << (j * 8U));
  271. buffer++;
  272. }
  273. SPDIF_WriteLeftData(base, data);
  274. /* Write right channel data */
  275. data = 0;
  276. for (j = 0; j < 3U; j++)
  277. {
  278. data |= ((uint32_t)(*buffer) << (j * 8U));
  279. buffer++;
  280. }
  281. SPDIF_WriteRightData(base, data);
  282. i += 6U;
  283. }
  284. }
  285. /*!
  286. * brief Receives data using a blocking method.
  287. *
  288. * note This function blocks by polling until data is ready to be sent.
  289. *
  290. * param base SPDIF base pointer.
  291. * param buffer Pointer to the data to be read.
  292. * param size Bytes to be read.
  293. */
  294. void SPDIF_ReadBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size)
  295. {
  296. assert(buffer != NULL);
  297. assert((size % 6U) == 0U);
  298. uint32_t i = 0, j = 0, data = 0;
  299. while (i < size)
  300. {
  301. /* Wait until it can write data */
  302. while ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxFIFOFull) == 0x00U)
  303. {
  304. }
  305. /* Write left channel data */
  306. data = SPDIF_ReadLeftData(base);
  307. for (j = 0; j < 3U; j++)
  308. {
  309. *buffer = ((uint8_t)(data >> (j * 8U)) & 0xFFU);
  310. buffer++;
  311. }
  312. /* Write right channel data */
  313. data = SPDIF_ReadRightData(base);
  314. for (j = 0; j < 3U; j++)
  315. {
  316. *buffer = ((uint8_t)(data >> (j * 8U)) & 0xFFU);
  317. buffer++;
  318. }
  319. i += 6U;
  320. }
  321. }
  322. /*!
  323. * brief Initializes the SPDIF Tx handle.
  324. *
  325. * This function initializes the Tx handle for the SPDIF Tx transactional APIs. Call
  326. * this function once to get the handle initialized.
  327. *
  328. * param base SPDIF base pointer
  329. * param handle SPDIF handle pointer.
  330. * param callback Pointer to the user callback function.
  331. * param userData User parameter passed to the callback function
  332. */
  333. void SPDIF_TransferTxCreateHandle(SPDIF_Type *base,
  334. spdif_handle_t *handle,
  335. spdif_transfer_callback_t callback,
  336. void *userData)
  337. {
  338. assert(handle != NULL);
  339. /* Zero the handle */
  340. (void)memset(handle, 0, sizeof(*handle));
  341. s_spdifHandle[SPDIF_GetInstance(base)][0] = handle;
  342. handle->callback = callback;
  343. handle->userData = userData;
  344. handle->watermark =
  345. s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT];
  346. /* Set the isr pointer */
  347. s_spdifTxIsr = SPDIF_TransferTxHandleIRQ;
  348. /* Enable Tx irq */
  349. (void)EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]);
  350. }
  351. /*!
  352. * brief Initializes the SPDIF Rx handle.
  353. *
  354. * This function initializes the Rx handle for the SPDIF Rx transactional APIs. Call
  355. * this function once to get the handle initialized.
  356. *
  357. * param base SPDIF base pointer.
  358. * param handle SPDIF handle pointer.
  359. * param callback Pointer to the user callback function.
  360. * param userData User parameter passed to the callback function.
  361. */
  362. void SPDIF_TransferRxCreateHandle(SPDIF_Type *base,
  363. spdif_handle_t *handle,
  364. spdif_transfer_callback_t callback,
  365. void *userData)
  366. {
  367. assert(handle != NULL);
  368. /* Zero the handle */
  369. (void)memset(handle, 0, sizeof(*handle));
  370. s_spdifHandle[SPDIF_GetInstance(base)][1] = handle;
  371. handle->callback = callback;
  372. handle->userData = userData;
  373. handle->watermark =
  374. s_spdif_rx_watermark[(base->SCR & SPDIF_SCR_RXFIFOFULL_SEL_MASK) >> SPDIF_SCR_RXFIFOFULL_SEL_SHIFT];
  375. /* Set the isr pointer */
  376. s_spdifRxIsr = SPDIF_TransferRxHandleIRQ;
  377. /* Enable Rx irq */
  378. (void)EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]);
  379. }
  380. /*!
  381. * brief Performs an interrupt non-blocking send transfer on SPDIF.
  382. *
  383. * note This API returns immediately after the transfer initiates.
  384. * Call the SPDIF_TxGetTransferStatusIRQ to poll the transfer status and check whether
  385. * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer
  386. * is finished.
  387. *
  388. * param base SPDIF base pointer.
  389. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  390. * param xfer Pointer to the spdif_transfer_t structure.
  391. * retval kStatus_Success Successfully started the data receive.
  392. * retval kStatus_SPDIF_TxBusy Previous receive still not finished.
  393. * retval kStatus_InvalidArgument The input parameter is invalid.
  394. */
  395. status_t SPDIF_TransferSendNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer)
  396. {
  397. assert(handle != NULL);
  398. /* Check if the queue is full */
  399. if (handle->spdifQueue[handle->queueUser].data != NULL)
  400. {
  401. return kStatus_SPDIF_QueueFull;
  402. }
  403. /* Add into queue */
  404. handle->transferSize[handle->queueUser] = xfer->dataSize;
  405. handle->spdifQueue[handle->queueUser].data = xfer->data;
  406. handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
  407. handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
  408. /* Set the state to busy */
  409. handle->state = kSPDIF_Busy;
  410. /* Enable interrupt */
  411. SPDIF_EnableInterrupts(base, kSPDIF_TxFIFOEmpty);
  412. /* Enable Tx transfer */
  413. SPDIF_TxEnable(base, true);
  414. return kStatus_Success;
  415. }
  416. /*!
  417. * brief Performs an interrupt non-blocking receive transfer on SPDIF.
  418. *
  419. * note This API returns immediately after the transfer initiates.
  420. * Call the SPDIF_RxGetTransferStatusIRQ to poll the transfer status and check whether
  421. * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer
  422. * is finished.
  423. *
  424. * param base SPDIF base pointer
  425. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  426. * param xfer Pointer to the spdif_transfer_t structure.
  427. * retval kStatus_Success Successfully started the data receive.
  428. * retval kStatus_SPDIF_RxBusy Previous receive still not finished.
  429. * retval kStatus_InvalidArgument The input parameter is invalid.
  430. */
  431. status_t SPDIF_TransferReceiveNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer)
  432. {
  433. assert(handle != NULL);
  434. uint32_t enableInterrupts = (uint32_t)kSPDIF_RxFIFOFull | (uint32_t)kSPDIF_RxControlChannelChange;
  435. /* Check if the queue is full */
  436. if (handle->spdifQueue[handle->queueUser].data != NULL)
  437. {
  438. return kStatus_SPDIF_QueueFull;
  439. }
  440. /* Add into queue */
  441. handle->transferSize[handle->queueUser] = xfer->dataSize;
  442. handle->spdifQueue[handle->queueUser].data = xfer->data;
  443. handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize;
  444. handle->spdifQueue[handle->queueUser].udata = xfer->udata;
  445. handle->spdifQueue[handle->queueUser].qdata = xfer->qdata;
  446. handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
  447. /* Set state to busy */
  448. handle->state = kSPDIF_Busy;
  449. if (xfer->qdata != NULL)
  450. {
  451. enableInterrupts |= (uint32_t)kSPDIF_QChannelReceiveRegisterFull;
  452. }
  453. if (xfer->udata != NULL)
  454. {
  455. enableInterrupts |= (uint32_t)kSPDIF_UChannelReceiveRegisterFull;
  456. }
  457. /* Enable interrupt */
  458. SPDIF_EnableInterrupts(base, enableInterrupts);
  459. /* Enable Rx transfer */
  460. SPDIF_RxEnable(base, true);
  461. return kStatus_Success;
  462. }
  463. /*!
  464. * brief Gets a set byte count.
  465. *
  466. * param base SPDIF base pointer.
  467. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  468. * param count Bytes count sent.
  469. * retval kStatus_Success Succeed get the transfer count.
  470. * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
  471. */
  472. status_t SPDIF_TransferGetSendCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count)
  473. {
  474. assert(handle != NULL);
  475. status_t status = kStatus_Success;
  476. uint8_t queueDriver = handle->queueDriver;
  477. if (handle->state != (uint32_t)kSPDIF_Busy)
  478. {
  479. status = kStatus_NoTransferInProgress;
  480. }
  481. else
  482. {
  483. *count = (handle->transferSize[queueDriver] - handle->spdifQueue[queueDriver].dataSize);
  484. }
  485. return status;
  486. }
  487. /*!
  488. * brief Gets a received byte count.
  489. *
  490. * param base SPDIF base pointer.
  491. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  492. * param count Bytes count received.
  493. * retval kStatus_Success Succeed get the transfer count.
  494. * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
  495. */
  496. status_t SPDIF_TransferGetReceiveCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count)
  497. {
  498. assert(handle != NULL);
  499. status_t status = kStatus_Success;
  500. uint8_t queueDriver = handle->queueDriver;
  501. if (handle->state != (uint32_t)kSPDIF_Busy)
  502. {
  503. status = kStatus_NoTransferInProgress;
  504. }
  505. else
  506. {
  507. *count = (handle->transferSize[queueDriver] - handle->spdifQueue[queueDriver].dataSize);
  508. }
  509. return status;
  510. }
  511. /*!
  512. * brief Aborts the current send.
  513. *
  514. * note This API can be called any time when an interrupt non-blocking transfer initiates
  515. * to abort the transfer early.
  516. *
  517. * param base SPDIF base pointer.
  518. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  519. */
  520. void SPDIF_TransferAbortSend(SPDIF_Type *base, spdif_handle_t *handle)
  521. {
  522. assert(handle != NULL);
  523. /* Use FIFO request interrupt and fifo error */
  524. SPDIF_DisableInterrupts(base, kSPDIF_TxFIFOEmpty);
  525. handle->state = kSPDIF_Idle;
  526. /* Clear the queue */
  527. (void)memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE);
  528. handle->queueDriver = 0;
  529. handle->queueUser = 0;
  530. }
  531. /*!
  532. * brief Aborts the current IRQ receive.
  533. *
  534. * note This API can be called when an interrupt non-blocking transfer initiates
  535. * to abort the transfer early.
  536. *
  537. * param base SPDIF base pointer
  538. * param handle Pointer to the spdif_handle_t structure which stores the transfer state.
  539. */
  540. void SPDIF_TransferAbortReceive(SPDIF_Type *base, spdif_handle_t *handle)
  541. {
  542. assert(handle != NULL);
  543. /* Disable interrupt */
  544. SPDIF_DisableInterrupts(base, (uint32_t)kSPDIF_UChannelReceiveRegisterFull |
  545. (uint32_t)kSPDIF_QChannelReceiveRegisterFull | (uint32_t)kSPDIF_RxFIFOFull |
  546. (uint32_t)kSPDIF_RxControlChannelChange);
  547. handle->state = kSPDIF_Idle;
  548. /* Clear the queue */
  549. (void)memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE);
  550. handle->queueDriver = 0;
  551. handle->queueUser = 0;
  552. }
  553. /*!
  554. * brief Tx interrupt handler.
  555. *
  556. * param base SPDIF base pointer.
  557. * param handle Pointer to the spdif_handle_t structure.
  558. */
  559. void SPDIF_TransferTxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle)
  560. {
  561. assert(handle != NULL);
  562. uint8_t *buffer = handle->spdifQueue[handle->queueDriver].data;
  563. uint8_t dataSize = 0;
  564. uint32_t i = 0, j = 0, data = 0;
  565. /* Do Transfer */
  566. if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_TxFIFOEmpty) != 0x00U) &&
  567. ((base->SIE & (uint32_t)kSPDIF_TxFIFOEmpty) != 0x00U))
  568. {
  569. dataSize = handle->watermark;
  570. while (i < dataSize)
  571. {
  572. data = 0;
  573. /* Write left channel data */
  574. for (j = 0; j < 3U; j++)
  575. {
  576. data |= ((uint32_t)(*buffer) << (j * 8U));
  577. buffer++;
  578. }
  579. SPDIF_WriteLeftData(base, data);
  580. /* Write right channel data */
  581. data = 0;
  582. for (j = 0; j < 3U; j++)
  583. {
  584. data |= ((uint32_t)(*buffer) << (j * 8U));
  585. buffer++;
  586. }
  587. SPDIF_WriteRightData(base, data);
  588. i++;
  589. }
  590. handle->spdifQueue[handle->queueDriver].dataSize -= (uint32_t)dataSize * 6U;
  591. handle->spdifQueue[handle->queueDriver].data += dataSize * 6U;
  592. /* If finished a block, call the callback function */
  593. if (handle->spdifQueue[handle->queueDriver].dataSize == 0U)
  594. {
  595. (void)memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t));
  596. handle->queueDriver = (handle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
  597. if (handle->callback != NULL)
  598. {
  599. (handle->callback)(base, handle, kStatus_SPDIF_TxIdle, handle->userData);
  600. }
  601. }
  602. /* If all data finished, just stop the transfer */
  603. if (handle->spdifQueue[handle->queueDriver].data == NULL)
  604. {
  605. SPDIF_TransferAbortSend(base, handle);
  606. }
  607. }
  608. }
  609. /*!
  610. * brief Tx interrupt handler.
  611. *
  612. * param base SPDIF base pointer.
  613. * param handle Pointer to the spdif_handle_t structure.
  614. */
  615. void SPDIF_TransferRxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle)
  616. {
  617. assert(handle != NULL);
  618. uint8_t *buffer = NULL;
  619. uint8_t dataSize = 0;
  620. uint32_t i = 0, j = 0, data = 0;
  621. /* Handle Cnew flag */
  622. if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxControlChannelChange) != 0x00U)
  623. {
  624. /* Clear the interrupt flag */
  625. SPDIF_ClearStatusFlags(base, SPDIF_SIE_CNEW_MASK);
  626. if (handle->callback != NULL)
  627. {
  628. (handle->callback)(base, handle, kStatus_SPDIF_RxCnew, handle->userData);
  629. }
  630. }
  631. /* Handle illegal symbol */
  632. if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxIllegalSymbol) != 0x00U)
  633. {
  634. SPDIF_ClearStatusFlags(base, kSPDIF_RxIllegalSymbol);
  635. if (handle->callback != NULL)
  636. {
  637. (handle->callback)(base, handle, kStatus_SPDIF_RxIllegalSymbol, handle->userData);
  638. }
  639. }
  640. /* Handle Parity Bit Error */
  641. if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxParityBitError) != 0x00U)
  642. {
  643. SPDIF_ClearStatusFlags(base, kSPDIF_RxParityBitError);
  644. if (handle->callback != NULL)
  645. {
  646. (handle->callback)(base, handle, kStatus_SPDIF_RxParityBitError, handle->userData);
  647. }
  648. }
  649. /* Handle DPlocked */
  650. if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxDPLLLocked) != 0x00U)
  651. {
  652. SPDIF_ClearStatusFlags(base, kSPDIF_RxDPLLLocked);
  653. if (handle->callback != NULL)
  654. {
  655. (handle->callback)(base, handle, kStatus_SPDIF_RxDPLLLocked, handle->userData);
  656. }
  657. }
  658. /* Handle Q channel full flag */
  659. if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_QChannelReceiveRegisterFull) != 0x00U) &&
  660. ((base->SIE & (uint32_t)kSPDIF_QChannelReceiveRegisterFull) != 0x00U))
  661. {
  662. buffer = handle->spdifQueue[handle->queueDriver].qdata;
  663. if (buffer != NULL)
  664. {
  665. data = SPDIF_ReadQChannel(base);
  666. buffer[0] = (uint8_t)data & 0xFFU;
  667. buffer[1] = (uint8_t)(data >> 8U) & 0xFFU;
  668. buffer[2] = (uint8_t)(data >> 16U) & 0xFFU;
  669. }
  670. }
  671. /* Handle U channel full flag */
  672. if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_UChannelReceiveRegisterFull) != 0x00U) &&
  673. ((base->SIE & (uint32_t)kSPDIF_UChannelReceiveRegisterFull) != 0x00U))
  674. {
  675. buffer = handle->spdifQueue[handle->queueDriver].udata;
  676. if (buffer != NULL)
  677. {
  678. data = SPDIF_ReadUChannel(base);
  679. buffer[0] = (uint8_t)data & 0xFFU;
  680. buffer[1] = (uint8_t)(data >> 8U) & 0xFFU;
  681. buffer[2] = (uint8_t)(data >> 16U) & 0xFFU;
  682. }
  683. }
  684. /* Handle audio data transfer */
  685. if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxFIFOFull) != 0x00U) &&
  686. ((base->SIE & (uint32_t)kSPDIF_RxFIFOFull) != 0x00U))
  687. {
  688. dataSize = handle->watermark;
  689. buffer = handle->spdifQueue[handle->queueDriver].data;
  690. while (i < dataSize)
  691. {
  692. /* Read left channel data */
  693. data = SPDIF_ReadLeftData(base);
  694. for (j = 0; j < 3U; j++)
  695. {
  696. *buffer = (uint8_t)((data >> (j * 8U)) & 0xFFU);
  697. buffer++;
  698. }
  699. /* Read right channel data */
  700. data = SPDIF_ReadRightData(base);
  701. for (j = 0; j < 3U; j++)
  702. {
  703. *buffer = (uint8_t)((data >> (j * 8U)) & 0xFFU);
  704. buffer++;
  705. }
  706. i++;
  707. }
  708. handle->spdifQueue[handle->queueDriver].dataSize -= (uint32_t)dataSize * 6U;
  709. handle->spdifQueue[handle->queueDriver].data += dataSize * 6U;
  710. /* If finished a block, call the callback function */
  711. if (handle->spdifQueue[handle->queueDriver].dataSize == 0x00U)
  712. {
  713. (void)memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t));
  714. handle->queueDriver = (handle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE;
  715. if (handle->callback != NULL)
  716. {
  717. (handle->callback)(base, handle, kStatus_SPDIF_RxIdle, handle->userData);
  718. }
  719. }
  720. /* If all data finished, just stop the transfer */
  721. if (handle->spdifQueue[handle->queueDriver].data == NULL)
  722. {
  723. SPDIF_TransferAbortReceive(base, handle);
  724. }
  725. }
  726. }
  727. #if defined(SPDIF)
  728. void SPDIF_DriverIRQHandler(void);
  729. void SPDIF_DriverIRQHandler(void)
  730. {
  731. if ((s_spdifHandle[0][0] != NULL) && (s_spdifTxIsr != NULL))
  732. {
  733. s_spdifTxIsr(SPDIF, s_spdifHandle[0][0]);
  734. }
  735. if ((s_spdifHandle[0][1] != NULL) && (s_spdifRxIsr != NULL))
  736. {
  737. s_spdifRxIsr(SPDIF, s_spdifHandle[0][1]);
  738. }
  739. SDK_ISR_EXIT_BARRIER;
  740. }
  741. #endif