1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2017-2020 NXP
4  * All rights reserved.
5  *
6  *
7  * SPDX-License-Identifier: BSD-3-Clause
8  */
9 
10 #ifndef FSL_SPDIF_H_
11 #define FSL_SPDIF_H_
12 
13 #include "fsl_common.h"
14 
15 /*!
16  * @addtogroup spdif
17  * @{
18  */
19 
20 /*******************************************************************************
21  * Definitions
22  ******************************************************************************/
23 
24 /*! @name Driver version */
25 /*! @{ */
26 #define FSL_SPDIF_DRIVER_VERSION (MAKE_VERSION(2, 0, 7)) /*!< Version 2.0.7 */
27 /*! @} */
28 
29 /*! @brief SPDIF return status*/
30 enum
31 {
32     kStatus_SPDIF_RxDPLLLocked     = MAKE_STATUS(kStatusGroup_SPDIF, 0), /*!< SPDIF Rx PLL locked. */
33     kStatus_SPDIF_TxFIFOError      = MAKE_STATUS(kStatusGroup_SPDIF, 1), /*!< SPDIF Tx FIFO error. */
34     kStatus_SPDIF_TxFIFOResync     = MAKE_STATUS(kStatusGroup_SPDIF, 2), /*!< SPDIF Tx left and right FIFO resync. */
35     kStatus_SPDIF_RxCnew           = MAKE_STATUS(kStatusGroup_SPDIF, 3), /*!< SPDIF Rx status channel value updated. */
36     kStatus_SPDIF_ValidatyNoGood   = MAKE_STATUS(kStatusGroup_SPDIF, 4), /*!< SPDIF validaty flag not good. */
37     kStatus_SPDIF_RxIllegalSymbol  = MAKE_STATUS(kStatusGroup_SPDIF, 5), /*!< SPDIF Rx receive illegal symbol. */
38     kStatus_SPDIF_RxParityBitError = MAKE_STATUS(kStatusGroup_SPDIF, 6), /*!< SPDIF Rx parity bit error. */
39     kStatus_SPDIF_UChannelOverrun  = MAKE_STATUS(kStatusGroup_SPDIF, 7), /*!< SPDIF receive U channel overrun. */
40     kStatus_SPDIF_QChannelOverrun  = MAKE_STATUS(kStatusGroup_SPDIF, 8), /*!< SPDIF receive Q channel overrun. */
41     kStatus_SPDIF_UQChannelSync    = MAKE_STATUS(kStatusGroup_SPDIF, 9), /*!< SPDIF U/Q channel sync found. */
42     kStatus_SPDIF_UQChannelFrameError = MAKE_STATUS(kStatusGroup_SPDIF, 10), /*!< SPDIF U/Q channel frame error. */
43     kStatus_SPDIF_RxFIFOError         = MAKE_STATUS(kStatusGroup_SPDIF, 11), /*!< SPDIF Rx FIFO error. */
44     kStatus_SPDIF_RxFIFOResync = MAKE_STATUS(kStatusGroup_SPDIF, 12), /*!< SPDIF Rx left and right FIFO resync. */
45     kStatus_SPDIF_LockLoss     = MAKE_STATUS(kStatusGroup_SPDIF, 13), /*!< SPDIF Rx PLL clock lock loss. */
46     kStatus_SPDIF_TxIdle       = MAKE_STATUS(kStatusGroup_SPDIF, 14), /*!< SPDIF Tx is idle */
47     kStatus_SPDIF_RxIdle       = MAKE_STATUS(kStatusGroup_SPDIF, 15), /*!< SPDIF Rx is idle */
48     kStatus_SPDIF_QueueFull    = MAKE_STATUS(kStatusGroup_SPDIF, 16)  /*!< SPDIF queue full */
49 };
50 
51 /*! @brief SPDIF Rx FIFO full falg select, it decides when assert the rx full flag */
52 typedef enum _spdif_rxfull_select
53 {
54     kSPDIF_RxFull1Sample = 0x0u, /*!< Rx full at least 1 sample in left and right FIFO */
55     kSPDIF_RxFull4Samples,       /*!< Rx full at least 4 sample in left and right FIFO*/
56     kSPDIF_RxFull8Samples,       /*!< Rx full at least 8 sample in left and right FIFO*/
57     kSPDIF_RxFull16Samples,      /*!< Rx full at least 16 sample in left and right FIFO*/
58 } spdif_rxfull_select_t;
59 
60 /*! @brief SPDIF tx FIFO EMPTY falg select, it decides when assert the tx empty flag */
61 typedef enum _spdif_txempty_select
62 {
63     kSPDIF_TxEmpty0Sample = 0x0u, /*!< Tx empty at most 0 sample in left and right FIFO */
64     kSPDIF_TxEmpty4Samples,       /*!< Tx empty at most 4 sample in left and right FIFO*/
65     kSPDIF_TxEmpty8Samples,       /*!< Tx empty at most 8 sample in left and right FIFO*/
66     kSPDIF_TxEmpty12Samples,      /*!< Tx empty at most 12 sample in left and right FIFO*/
67 } spdif_txempty_select_t;
68 
69 /*! @brief SPDIF U channel source */
70 typedef enum _spdif_uchannel_source
71 {
72     kSPDIF_NoUChannel     = 0x0U, /*!< No embedded U channel */
73     kSPDIF_UChannelFromRx = 0x1U, /*!< U channel from receiver, it is CD mode */
74     kSPDIF_UChannelFromTx = 0x3U, /*!< U channel from on chip tx */
75 } spdif_uchannel_source_t;
76 
77 /*! @brief SPDIF clock gain*/
78 typedef enum _spdif_gain_select
79 {
80     kSPDIF_GAIN_24 = 0x0U, /*!< Gain select is 24 */
81     kSPDIF_GAIN_16,        /*!< Gain select is 16 */
82     kSPDIF_GAIN_12,        /*!< Gain select is 12 */
83     kSPDIF_GAIN_8,         /*!< Gain select is 8 */
84     kSPDIF_GAIN_6,         /*!< Gain select is 6 */
85     kSPDIF_GAIN_4,         /*!< Gain select is 4 */
86     kSPDIF_GAIN_3,         /*!< Gain select is 3 */
87 } spdif_gain_select_t;
88 
89 /*! @brief SPDIF tx data source */
90 typedef enum _spdif_tx_source
91 {
92     kSPDIF_txFromReceiver = 0x1U, /*!< Tx data directly through SPDIF receiver */
93     kSPDIF_txNormal       = 0x5U, /*!< Normal operation, data from processor */
94 } spdif_tx_source_t;
95 
96 /*! @brief SPDIF tx data source */
97 typedef enum _spdif_validity_config
98 {
99     kSPDIF_validityFlagAlwaysSet = 0x0U, /*!< Outgoing validity flags always set */
100     kSPDIF_validityFlagAlwaysClear,      /*!< Outgoing validity flags always clear */
101 } spdif_validity_config_t;
102 
103 /*! @brief The SPDIF interrupt enable flag */
104 enum
105 {
106     kSPDIF_RxDPLLLocked                   = SPDIF_SIE_LOCK_MASK,        /*!< SPDIF DPLL locked */
107     kSPDIF_TxFIFOError                    = SPDIF_SIE_TXUNOV_MASK,      /*!< Tx FIFO underrun or overrun */
108     kSPDIF_TxFIFOResync                   = SPDIF_SIE_TXRESYN_MASK,     /*!< Tx FIFO left and right channel resync */
109     kSPDIF_RxControlChannelChange         = SPDIF_SIE_CNEW_MASK,        /*!< SPDIF Rx control channel value changed */
110     kSPDIF_ValidityFlagNoGood             = SPDIF_SIE_VALNOGOOD_MASK,   /*!< SPDIF validity flag no good */
111     kSPDIF_RxIllegalSymbol                = SPDIF_SIE_SYMERR_MASK,      /*!< SPDIF receiver found illegal symbol */
112     kSPDIF_RxParityBitError               = SPDIF_SIE_BITERR_MASK,      /*!< SPDIF receiver found parity bit error */
113     kSPDIF_UChannelReceiveRegisterFull    = SPDIF_SIE_URXFUL_MASK,      /*!< SPDIF U channel revceive register full */
114     kSPDIF_UChannelReceiveRegisterOverrun = SPDIF_SIE_URXOV_MASK,       /*!< SPDIF U channel receive register overrun */
115     kSPDIF_QChannelReceiveRegisterFull    = SPDIF_SIE_QRXFUL_MASK,      /*!< SPDIF Q channel receive reigster full */
116     kSPDIF_QChannelReceiveRegisterOverrun = SPDIF_SIE_QRXOV_MASK,       /*!< SPDIF Q channel receive register overrun */
117     kSPDIF_UQChannelSync                  = SPDIF_SIE_UQSYNC_MASK,      /*!< SPDIF U/Q channel sync found */
118     kSPDIF_UQChannelFrameError            = SPDIF_SIE_UQERR_MASK,       /*!< SPDIF U/Q channel frame error */
119     kSPDIF_RxFIFOError                    = SPDIF_SIE_RXFIFOUNOV_MASK,  /*!< SPDIF Rx FIFO underrun/overrun */
120     kSPDIF_RxFIFOResync                   = SPDIF_SIE_RXFIFORESYN_MASK, /*!< SPDIF Rx left and right FIFO resync */
121     kSPDIF_LockLoss                       = SPDIF_SIE_LOCKLOSS_MASK,    /*!< SPDIF receiver loss of lock */
122     kSPDIF_TxFIFOEmpty                    = SPDIF_SIE_TXEM_MASK,        /*!< SPDIF Tx FIFO empty */
123     kSPDIF_RxFIFOFull                     = SPDIF_SIE_RXFIFOFUL_MASK,   /*!< SPDIF Rx FIFO full */
124     kSPDIF_AllInterrupt                   = kSPDIF_RxDPLLLocked | kSPDIF_TxFIFOError | kSPDIF_TxFIFOResync |
125                           kSPDIF_RxControlChannelChange | kSPDIF_ValidityFlagNoGood | kSPDIF_RxIllegalSymbol |
126                           kSPDIF_RxParityBitError | kSPDIF_UChannelReceiveRegisterFull |
127                           kSPDIF_UChannelReceiveRegisterOverrun | kSPDIF_QChannelReceiveRegisterFull |
128                           kSPDIF_QChannelReceiveRegisterOverrun | kSPDIF_UQChannelSync | kSPDIF_UQChannelFrameError |
129                           kSPDIF_RxFIFOError | kSPDIF_RxFIFOResync | kSPDIF_LockLoss | kSPDIF_TxFIFOEmpty |
130                           kSPDIF_RxFIFOFull, /*!< all interrupt */
131 };
132 
133 /*! @brief The DMA request sources */
134 enum
135 {
136     kSPDIF_RxDMAEnable = SPDIF_SCR_DMA_RX_EN_MASK, /*!< Rx FIFO full */
137     kSPDIF_TxDMAEnable = SPDIF_SCR_DMA_TX_EN_MASK, /*!< Tx FIFO empty */
138 };
139 
140 /*! @brief SPDIF user configuration structure */
141 typedef struct _spdif_config
142 {
143     bool isTxAutoSync;                      /*!< If auto sync mechanism open */
144     bool isRxAutoSync;                      /*!< If auto sync mechanism open */
145     uint8_t DPLLClkSource;                  /*!< SPDIF DPLL clock source, range from 0~15, meaning is chip-specific */
146     uint8_t txClkSource;                    /*!< SPDIF tx clock source, range from 0~7, meaning is chip-specific */
147     spdif_rxfull_select_t rxFullSelect;     /*!< SPDIF rx buffer full select */
148     spdif_txempty_select_t txFullSelect;    /*!< SPDIF tx buffer empty select */
149     spdif_uchannel_source_t uChannelSrc;    /*!< U channel source */
150     spdif_tx_source_t txSource;             /*!< SPDIF tx data source */
151     spdif_validity_config_t validityConfig; /*!< Validity flag config */
152     spdif_gain_select_t gain;               /*!< Rx receive clock measure gain parameter. */
153 } spdif_config_t;
154 
155 /*!@brief SPDIF transfer queue size, user can refine it according to use case. */
156 #define SPDIF_XFER_QUEUE_SIZE (4U)
157 
158 /*! @brief SPDIF transfer structure */
159 typedef struct _spdif_transfer
160 {
161     uint8_t *data;   /*!< Data start address to transfer. */
162     uint8_t *qdata;  /*!< Data buffer for Q channel */
163     uint8_t *udata;  /*!< Data buffer for C channel */
164     size_t dataSize; /*!< Transfer size. */
165 } spdif_transfer_t;
166 
167 typedef struct _spdif_handle spdif_handle_t;
168 
169 /*! @brief SPDIF transfer callback prototype */
170 typedef void (*spdif_transfer_callback_t)(SPDIF_Type *base, spdif_handle_t *handle, status_t status, void *userData);
171 
172 /*! @brief SPDIF handle structure */
173 struct _spdif_handle
174 {
175     uint32_t state;                                     /*!< Transfer status */
176     spdif_transfer_callback_t callback;                 /*!< Callback function called at transfer event*/
177     void *userData;                                     /*!< Callback parameter passed to callback function*/
178     spdif_transfer_t spdifQueue[SPDIF_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
179     size_t transferSize[SPDIF_XFER_QUEUE_SIZE];         /*!< Data bytes need to transfer */
180     volatile uint8_t queueUser;                         /*!< Index for user to queue transfer */
181     volatile uint8_t queueDriver;                       /*!< Index for driver to get the transfer data and size */
182     uint8_t watermark;                                  /*!< Watermark value */
183 };
184 
185 /*******************************************************************************
186  * API
187  ******************************************************************************/
188 
189 #if defined(__cplusplus)
190 extern "C" {
191 #endif /*_cplusplus*/
192 
193 /*!
194  * @name Initialization and deinitialization
195  * @{
196  */
197 
198 /*!
199  * @brief Initializes the SPDIF peripheral.
200  *
201  * Ungates the SPDIF clock, resets the module, and configures SPDIF with a configuration structure.
202  * The configuration structure can be custom filled or set with default values by
203  * SPDIF_GetDefaultConfig().
204  *
205  * @note  This API should be called at the beginning of the application to use
206  * the SPDIF driver. Otherwise, accessing the SPDIF module can cause a hard fault
207  * because the clock is not enabled.
208  *
209  * @param base SPDIF base pointer
210  * @param config SPDIF configuration structure.
211  */
212 void SPDIF_Init(SPDIF_Type *base, const spdif_config_t *config);
213 
214 /*!
215  * @brief  Sets the SPDIF configuration structure to default values.
216  *
217  * This API initializes the configuration structure for use in SPDIF_Init.
218  * The initialized structure can remain unchanged in SPDIF_Init, or it can be modified
219  *  before calling SPDIF_Init.
220  * This is an example.
221    @code
222    spdif_config_t config;
223    SPDIF_GetDefaultConfig(&config);
224    @endcode
225  *
226  * @param config pointer to master configuration structure
227  */
228 void SPDIF_GetDefaultConfig(spdif_config_t *config);
229 
230 /*!
231  * @brief De-initializes the SPDIF peripheral.
232  *
233  * This API gates the SPDIF clock. The SPDIF module can't operate unless SPDIF_Init is called to enable the clock.
234  *
235  * @param base SPDIF base pointer
236  */
237 void SPDIF_Deinit(SPDIF_Type *base);
238 
239 /*!
240  * @brief Get the instance number for SPDIF.
241  *
242  * @param base SPDIF base pointer.
243  */
244 uint32_t SPDIF_GetInstance(SPDIF_Type *base);
245 
246 /*!
247  * @brief Resets the SPDIF Tx.
248  *
249  * This function makes Tx FIFO in reset mode.
250  *
251  * @param base SPDIF base pointer
252  */
SPDIF_TxFIFOReset(SPDIF_Type * base)253 static inline void SPDIF_TxFIFOReset(SPDIF_Type *base)
254 {
255     base->SCR |= SPDIF_SCR_RXFIFO_RST_MASK;
256 }
257 
258 /*!
259  * @brief Resets the SPDIF Rx.
260  *
261  * This function enables the software reset and FIFO reset of SPDIF Rx. After reset, clear the reset bit.
262  *
263  * @param base SPDIF base pointer
264  */
SPDIF_RxFIFOReset(SPDIF_Type * base)265 static inline void SPDIF_RxFIFOReset(SPDIF_Type *base)
266 {
267     base->SCR |= SPDIF_SCR_RXFIFO_RST_MASK;
268 }
269 
270 /*!
271  * @brief Enables/disables the SPDIF Tx.
272  *
273  * @param base SPDIF base pointer
274  * @param enable True means enable SPDIF Tx, false means disable.
275  */
276 void SPDIF_TxEnable(SPDIF_Type *base, bool enable);
277 
278 /*!
279  * @brief Enables/disables the SPDIF Rx.
280  *
281  * @param base SPDIF base pointer
282  * @param enable True means enable SPDIF Rx, false means disable.
283  */
SPDIF_RxEnable(SPDIF_Type * base,bool enable)284 static inline void SPDIF_RxEnable(SPDIF_Type *base, bool enable)
285 {
286     if (enable)
287     {
288         /* Open Rx FIFO */
289         base->SCR &= ~(SPDIF_SCR_RXFIFO_CTRL_MASK | SPDIF_SCR_RXFIFO_OFF_ON_MASK);
290     }
291     else
292     {
293         base->SCR |= SPDIF_SCR_RXFIFO_OFF_ON_MASK;
294     }
295 }
296 
297 /*! @} */
298 
299 /*!
300  * @name Status
301  * @{
302  */
303 
304 /*!
305  * @brief Gets the SPDIF status flag state.
306  *
307  * @param base SPDIF base pointer
308  * @return SPDIF status flag value. Use the _spdif_interrupt_enable_t to get the status value needed.
309  */
SPDIF_GetStatusFlag(SPDIF_Type * base)310 static inline uint32_t SPDIF_GetStatusFlag(SPDIF_Type *base)
311 {
312     return base->SIS;
313 }
314 
315 /*!
316  * @brief Clears the SPDIF status flag state.
317  *
318  * @param base SPDIF base pointer
319  * @param mask State mask. It can be a combination of the _spdif_interrupt_enable_t member. Notice these members
320  *             cannot be included, as these flags cannot be cleared by writing 1 to these bits:
321  *        @arg kSPDIF_UChannelReceiveRegisterFull
322  *        @arg kSPDIF_QChannelReceiveRegisterFull
323  *        @arg kSPDIF_TxFIFOEmpty
324  *        @arg kSPDIF_RxFIFOFull
325  */
SPDIF_ClearStatusFlags(SPDIF_Type * base,uint32_t mask)326 static inline void SPDIF_ClearStatusFlags(SPDIF_Type *base, uint32_t mask)
327 {
328 #if defined FSL_FEATURE_SPDIF_HAS_NO_SIC_REGISTER && FSL_FEATURE_SPDIF_HAS_NO_SIC_REGISTER
329     base->SIS = mask;
330 #else
331     base->SIC = mask;
332 #endif
333 }
334 
335 /*! @} */
336 
337 /*!
338  * @name Interrupts
339  * @{
340  */
341 
342 /*!
343  * @brief Enables the SPDIF Tx interrupt requests.
344  *
345  * @param base SPDIF base pointer
346  * @param mask interrupt source
347  *     The parameter can be a combination of the following sources if defined.
348  *     @arg kSPDIF_WordStartInterruptEnable
349  *     @arg kSPDIF_SyncErrorInterruptEnable
350  *     @arg kSPDIF_FIFOWarningInterruptEnable
351  *     @arg kSPDIF_FIFORequestInterruptEnable
352  *     @arg kSPDIF_FIFOErrorInterruptEnable
353  */
SPDIF_EnableInterrupts(SPDIF_Type * base,uint32_t mask)354 static inline void SPDIF_EnableInterrupts(SPDIF_Type *base, uint32_t mask)
355 {
356     base->SIE |= mask;
357 }
358 
359 /*!
360  * @brief Disables the SPDIF Tx interrupt requests.
361  *
362  * @param base SPDIF base pointer
363  * @param mask interrupt source
364  *     The parameter can be a combination of the following sources if defined.
365  *     @arg kSPDIF_WordStartInterruptEnable
366  *     @arg kSPDIF_SyncErrorInterruptEnable
367  *     @arg kSPDIF_FIFOWarningInterruptEnable
368  *     @arg kSPDIF_FIFORequestInterruptEnable
369  *     @arg kSPDIF_FIFOErrorInterruptEnable
370  */
SPDIF_DisableInterrupts(SPDIF_Type * base,uint32_t mask)371 static inline void SPDIF_DisableInterrupts(SPDIF_Type *base, uint32_t mask)
372 {
373     base->SIE &= ~mask;
374 }
375 
376 /*! @} */
377 
378 /*!
379  * @name DMA Control
380  * @{
381  */
382 
383 /*!
384  * @brief Enables/disables the SPDIF DMA requests.
385  * @param base SPDIF base pointer
386  * @param mask SPDIF DMA enable mask, The parameter can be a combination of the following sources if defined
387  *      @arg kSPDIF_RxDMAEnable
388  *      @arg kSPDIF_TxDMAEnable
389  * @param enable True means enable DMA, false means disable DMA.
390  */
SPDIF_EnableDMA(SPDIF_Type * base,uint32_t mask,bool enable)391 static inline void SPDIF_EnableDMA(SPDIF_Type *base, uint32_t mask, bool enable)
392 {
393     if (enable)
394     {
395         base->SCR |= mask;
396     }
397     else
398     {
399         base->SCR &= ~mask;
400     }
401 }
402 
403 /*!
404  * @brief  Gets the SPDIF Tx left data register address.
405  *
406  * This API is used to provide a transfer address for the SPDIF DMA transfer configuration.
407  *
408  * @param base SPDIF base pointer.
409  * @return data register address.
410  */
SPDIF_TxGetLeftDataRegisterAddress(SPDIF_Type * base)411 static inline uint32_t SPDIF_TxGetLeftDataRegisterAddress(SPDIF_Type *base)
412 {
413     return (uint32_t)(&(base->STL));
414 }
415 
416 /*!
417  * @brief  Gets the SPDIF Tx right data register address.
418  *
419  * This API is used to provide a transfer address for the SPDIF DMA transfer configuration.
420  *
421  * @param base SPDIF base pointer.
422  * @return data register address.
423  */
SPDIF_TxGetRightDataRegisterAddress(SPDIF_Type * base)424 static inline uint32_t SPDIF_TxGetRightDataRegisterAddress(SPDIF_Type *base)
425 {
426     return (uint32_t)(&(base->STR));
427 }
428 
429 /*!
430  * @brief  Gets the SPDIF Rx left data register address.
431  *
432  * This API is used to provide a transfer address for the SPDIF DMA transfer configuration.
433  *
434  * @param base SPDIF base pointer.
435  * @return data register address.
436  */
SPDIF_RxGetLeftDataRegisterAddress(SPDIF_Type * base)437 static inline uint32_t SPDIF_RxGetLeftDataRegisterAddress(SPDIF_Type *base)
438 {
439     return (uint32_t)(&(base->SRL));
440 }
441 
442 /*!
443  * @brief  Gets the SPDIF Rx right data register address.
444  *
445  * This API is used to provide a transfer address for the SPDIF DMA transfer configuration.
446  *
447  * @param base SPDIF base pointer.
448  * @return data register address.
449  */
SPDIF_RxGetRightDataRegisterAddress(SPDIF_Type * base)450 static inline uint32_t SPDIF_RxGetRightDataRegisterAddress(SPDIF_Type *base)
451 {
452     return (uint32_t)(&(base->SRR));
453 }
454 
455 /*! @} */
456 
457 /*!
458  * @name Bus Operations
459  * @{
460  */
461 
462 /*!
463  * @brief Configures the SPDIF Tx sample rate.
464  *
465  * The audio format can be changed at run-time. This function configures the sample rate.
466  *
467  * @param base SPDIF base pointer.
468  * @param sampleRate_Hz SPDIF sample rate frequency in Hz.
469  * @param sourceClockFreq_Hz SPDIF tx clock source frequency in Hz.
470  */
471 void SPDIF_TxSetSampleRate(SPDIF_Type *base, uint32_t sampleRate_Hz, uint32_t sourceClockFreq_Hz);
472 
473 /*!
474  * @brief Configures the SPDIF Rx audio format.
475  *
476  * The audio format can be changed at run-time. This function configures the sample rate and audio data
477  * format to be transferred.
478  *
479  * @param base SPDIF base pointer.
480  * @param clockSourceFreq_Hz SPDIF system clock frequency in hz.
481  */
482 uint32_t SPDIF_GetRxSampleRate(SPDIF_Type *base, uint32_t clockSourceFreq_Hz);
483 
484 /*!
485  * @brief Sends data using a blocking method.
486  *
487  * @note This function blocks by polling until data is ready to be sent.
488  *
489  * @param base SPDIF base pointer.
490  * @param buffer Pointer to the data to be written.
491  * @param size Bytes to be written.
492  */
493 void SPDIF_WriteBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size);
494 
495 /*!
496  * @brief Writes data into SPDIF FIFO.
497  *
498  * @param base SPDIF base pointer.
499  * @param data Data needs to be written.
500  */
SPDIF_WriteLeftData(SPDIF_Type * base,uint32_t data)501 static inline void SPDIF_WriteLeftData(SPDIF_Type *base, uint32_t data)
502 {
503     base->STL = data;
504 }
505 
506 /*!
507  * @brief Writes data into SPDIF FIFO.
508  *
509  * @param base SPDIF base pointer.
510  * @param data Data needs to be written.
511  */
SPDIF_WriteRightData(SPDIF_Type * base,uint32_t data)512 static inline void SPDIF_WriteRightData(SPDIF_Type *base, uint32_t data)
513 {
514     base->STR = data;
515 }
516 
517 /*!
518  * @brief Writes data into SPDIF FIFO.
519  *
520  * @param base SPDIF base pointer.
521  * @param data Data needs to be written.
522  */
SPDIF_WriteChannelStatusHigh(SPDIF_Type * base,uint32_t data)523 static inline void SPDIF_WriteChannelStatusHigh(SPDIF_Type *base, uint32_t data)
524 {
525     base->STCSCH = data;
526 }
527 
528 /*!
529  * @brief Writes data into SPDIF FIFO.
530  *
531  * @param base SPDIF base pointer.
532  * @param data Data needs to be written.
533  */
SPDIF_WriteChannelStatusLow(SPDIF_Type * base,uint32_t data)534 static inline void SPDIF_WriteChannelStatusLow(SPDIF_Type *base, uint32_t data)
535 {
536     base->STCSCL = data;
537 }
538 
539 /*!
540  * @brief Receives data using a blocking method.
541  *
542  * @note This function blocks by polling until data is ready to be sent.
543  *
544  * @param base SPDIF base pointer.
545  * @param buffer Pointer to the data to be read.
546  * @param size Bytes to be read.
547  */
548 void SPDIF_ReadBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size);
549 
550 /*!
551  * @brief Reads data from the SPDIF FIFO.
552  *
553  * @param base SPDIF base pointer.
554  * @return Data in SPDIF FIFO.
555  */
SPDIF_ReadLeftData(SPDIF_Type * base)556 static inline uint32_t SPDIF_ReadLeftData(SPDIF_Type *base)
557 {
558     return base->SRL;
559 }
560 
561 /*!
562  * @brief Reads data from the SPDIF FIFO.
563  *
564  * @param base SPDIF base pointer.
565  * @return Data in SPDIF FIFO.
566  */
SPDIF_ReadRightData(SPDIF_Type * base)567 static inline uint32_t SPDIF_ReadRightData(SPDIF_Type *base)
568 {
569     return base->SRR;
570 }
571 
572 /*!
573  * @brief Reads data from the SPDIF FIFO.
574  *
575  * @param base SPDIF base pointer.
576  * @return Data in SPDIF FIFO.
577  */
SPDIF_ReadChannelStatusHigh(SPDIF_Type * base)578 static inline uint32_t SPDIF_ReadChannelStatusHigh(SPDIF_Type *base)
579 {
580     return base->SRCSH;
581 }
582 
583 /*!
584  * @brief Reads data from the SPDIF FIFO.
585  *
586  * @param base SPDIF base pointer.
587  * @return Data in SPDIF FIFO.
588  */
SPDIF_ReadChannelStatusLow(SPDIF_Type * base)589 static inline uint32_t SPDIF_ReadChannelStatusLow(SPDIF_Type *base)
590 {
591     return base->SRCSL;
592 }
593 
594 /*!
595  * @brief Reads data from the SPDIF FIFO.
596  *
597  * @param base SPDIF base pointer.
598  * @return Data in SPDIF FIFO.
599  */
SPDIF_ReadQChannel(SPDIF_Type * base)600 static inline uint32_t SPDIF_ReadQChannel(SPDIF_Type *base)
601 {
602     return base->SRQ;
603 }
604 
605 /*!
606  * @brief Reads data from the SPDIF FIFO.
607  *
608  * @param base SPDIF base pointer.
609  * @return Data in SPDIF FIFO.
610  */
SPDIF_ReadUChannel(SPDIF_Type * base)611 static inline uint32_t SPDIF_ReadUChannel(SPDIF_Type *base)
612 {
613     return base->SRU;
614 }
615 
616 /*! @} */
617 
618 /*!
619  * @name Transactional
620  * @{
621  */
622 
623 /*!
624  * @brief Initializes the SPDIF Tx handle.
625  *
626  * This function initializes the Tx handle for the SPDIF Tx transactional APIs. Call
627  * this function once to get the handle initialized.
628  *
629  * @param base SPDIF base pointer
630  * @param handle SPDIF handle pointer.
631  * @param callback Pointer to the user callback function.
632  * @param userData User parameter passed to the callback function
633  */
634 void SPDIF_TransferTxCreateHandle(SPDIF_Type *base,
635                                   spdif_handle_t *handle,
636                                   spdif_transfer_callback_t callback,
637                                   void *userData);
638 
639 /*!
640  * @brief Initializes the SPDIF Rx handle.
641  *
642  * This function initializes the Rx handle for the SPDIF Rx transactional APIs. Call
643  * this function once to get the handle initialized.
644  *
645  * @param base SPDIF base pointer.
646  * @param handle SPDIF handle pointer.
647  * @param callback Pointer to the user callback function.
648  * @param userData User parameter passed to the callback function.
649  */
650 void SPDIF_TransferRxCreateHandle(SPDIF_Type *base,
651                                   spdif_handle_t *handle,
652                                   spdif_transfer_callback_t callback,
653                                   void *userData);
654 
655 /*!
656  * @brief Performs an interrupt non-blocking send transfer on SPDIF.
657  *
658  * @note This API returns immediately after the transfer initiates.
659  * Call the SPDIF_TxGetTransferStatusIRQ to poll the transfer status and check whether
660  * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer
661  * is finished.
662  *
663  * @param base SPDIF base pointer.
664  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
665  * @param xfer Pointer to the spdif_transfer_t structure.
666  * @retval kStatus_Success Successfully started the data receive.
667  * @retval kStatus_SPDIF_TxBusy Previous receive still not finished.
668  * @retval kStatus_InvalidArgument The input parameter is invalid.
669  */
670 status_t SPDIF_TransferSendNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer);
671 
672 /*!
673  * @brief Performs an interrupt non-blocking receive transfer on SPDIF.
674  *
675  * @note This API returns immediately after the transfer initiates.
676  * Call the SPDIF_RxGetTransferStatusIRQ to poll the transfer status and check whether
677  * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer
678  * is finished.
679  *
680  * @param base SPDIF base pointer
681  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
682  * @param xfer Pointer to the spdif_transfer_t structure.
683  * @retval kStatus_Success Successfully started the data receive.
684  * @retval kStatus_SPDIF_RxBusy Previous receive still not finished.
685  * @retval kStatus_InvalidArgument The input parameter is invalid.
686  */
687 status_t SPDIF_TransferReceiveNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer);
688 
689 /*!
690  * @brief Gets a set byte count.
691  *
692  * @param base SPDIF base pointer.
693  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
694  * @param count Bytes count sent.
695  * @retval kStatus_Success Succeed get the transfer count.
696  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
697  */
698 status_t SPDIF_TransferGetSendCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count);
699 
700 /*!
701  * @brief Gets a received byte count.
702  *
703  * @param base SPDIF base pointer.
704  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
705  * @param count Bytes count received.
706  * @retval kStatus_Success Succeed get the transfer count.
707  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
708  */
709 status_t SPDIF_TransferGetReceiveCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count);
710 
711 /*!
712  * @brief Aborts the current send.
713  *
714  * @note This API can be called any time when an interrupt non-blocking transfer initiates
715  * to abort the transfer early.
716  *
717  * @param base SPDIF base pointer.
718  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
719  */
720 void SPDIF_TransferAbortSend(SPDIF_Type *base, spdif_handle_t *handle);
721 
722 /*!
723  * @brief Aborts the current IRQ receive.
724  *
725  * @note This API can be called when an interrupt non-blocking transfer initiates
726  * to abort the transfer early.
727  *
728  * @param base SPDIF base pointer
729  * @param handle Pointer to the spdif_handle_t structure which stores the transfer state.
730  */
731 void SPDIF_TransferAbortReceive(SPDIF_Type *base, spdif_handle_t *handle);
732 
733 /*!
734  * @brief Tx interrupt handler.
735  *
736  * @param base SPDIF base pointer.
737  * @param handle Pointer to the spdif_handle_t structure.
738  */
739 void SPDIF_TransferTxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle);
740 
741 /*!
742  * @brief Tx interrupt handler.
743  *
744  * @param base SPDIF base pointer.
745  * @param handle Pointer to the spdif_handle_t structure.
746  */
747 void SPDIF_TransferRxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle);
748 
749 /*! @} */
750 
751 #if defined(__cplusplus)
752 }
753 #endif /*_cplusplus*/
754 
755 /*! @} */
756 
757 #endif /* FSL_SPDIF_H_ */
758