1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef _FSL_ESAI_H_
10 #define _FSL_ESAI_H_
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup esai
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 /*! @name Driver version */
24 /*@{*/
25 #define FSL_ESAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1 */
26 /*@}*/
27 
28 /*! @brief ESAI return status, _esai_status_t*/
29 enum
30 {
31     kStatus_ESAI_TxBusy    = MAKE_STATUS(kStatusGroup_ESAI, 0), /*!< ESAI Tx is busy. */
32     kStatus_ESAI_RxBusy    = MAKE_STATUS(kStatusGroup_ESAI, 1), /*!< ESAI Rx is busy. */
33     kStatus_ESAI_TxError   = MAKE_STATUS(kStatusGroup_ESAI, 2), /*!< ESAI Tx FIFO error. */
34     kStatus_ESAI_RxError   = MAKE_STATUS(kStatusGroup_ESAI, 3), /*!< ESAI Rx FIFO error. */
35     kStatus_ESAI_QueueFull = MAKE_STATUS(kStatusGroup_ESAI, 4), /*!< ESAI transfer queue is full. */
36     kStatus_ESAI_TxIdle    = MAKE_STATUS(kStatusGroup_ESAI, 5), /*!< ESAI Tx is idle */
37     kStatus_ESAI_RxIdle    = MAKE_STATUS(kStatusGroup_ESAI, 6)  /*!< ESAI Rx is idle */
38 };
39 
40 /*! @brief Define the ESAI bus type */
41 typedef enum _esai_mode
42 {
43     kESAI_NormalMode = 0x0U, /*!< Use normal mode.*/
44     kESAI_NetworkMode        /*!< Network mode. */
45 } esai_mode_t;
46 
47 /*! @brief Define the ESAI bus type */
48 typedef enum _esai_protocol
49 {
50     kESAI_BusLeftJustified = 0x0U, /*!< Uses left justified format.*/
51     kESAI_BusRightJustified,       /*!< Uses right justified format. */
52     kESAI_BusI2S,                  /*!< Uses I2S format. */
53     kESAI_BusPCMA,                 /*!< Uses I2S PCM A format.*/
54     kESAI_BusPCMB,                 /*!< Uses I2S PCM B format. */
55     kESAI_BusTDM,                  /*!< Use TDM mode */
56     kESAI_BusCustomerNormal,       /*!< Customer defined normal mode */
57     kESAI_BusCustomerNetwork       /*!< Customer defined network mode */
58 } esai_protocol_t;
59 
60 /*! @brief Master or slave mode */
61 typedef enum _esai_master_slave
62 {
63     kESAI_Master = 0x0U, /*!< Master mode */
64     kESAI_Slave  = 0x1U  /*!< Slave mode */
65 } esai_master_slave_t;
66 
67 /*! @brief Synchronous or asynchronous mode */
68 typedef enum _esai_sync_mode
69 {
70     kESAI_ModeAsync = 0x0U, /*!< Asynchronous mode */
71     kESAI_ModeSync,         /*!< Synchronous mode (with receiver or transmit) */
72 } esai_sync_mode_t;
73 
74 /*! @brief Mater clock source */
75 typedef enum _esai_hclk_source
76 {
77     kESAI_HckSourceInternal = 0x0U, /* HCK from ESAI internal clock, gnerally 133Mhz */
78     kESAI_HckSourceExternal = 0x1U  /* HCK from external, soc specific, can be an audio PLL. */
79 } esai_hclk_source_t;
80 
81 /*! @brief Bit clock source */
82 typedef enum _esai_clock_polarity
83 {
84     kESAI_ClockActiveHigh = 0x0U, /*!< Clock active while high */
85     kESAI_ClockActiveLow,         /*!< Clock actie while low */
86 } esai_clock_polarity_t;
87 
88 /*! @brief ESAI shifter register shift direction */
89 typedef enum _esai_shift_direction
90 {
91     kESAI_ShifterMSB = 0x0, /*!< Data is shifted MSB first */
92     kESAI_ShifterLSB = 0x1  /*!< Data is shifted LSB first */
93 } esai_shift_direction_t;
94 
95 /*! @brief ESAI clock direction */
96 typedef enum _esai_clock_direction
97 {
98     kESAI_ClockInput  = 0x0, /*!< Clock direction is input */
99     kESAI_ClockOutput = 0x1  /*!< Clock direction is output */
100 } esai_clock_direction_t;
101 
102 /*! @brief The ESAI interrupt enable flag, _esai_interrupt_enable_t */
103 enum
104 {
105     kESAI_LastSlotInterruptEnable =
106         ESAI_TCR_TLIE_MASK, /*!< Enable interrupt at the beginning of last slot of frame in network mode */
107     kESAI_TransmitInterruptEnable     = ESAI_TCR_TIE_MASK,   /*!< Transmit/receive even slot data interrupt */
108     kESAI_EvenSlotDataInterruptEnable = ESAI_TCR_TEDIE_MASK, /*!< Transmit/receive even slot data interrupt */
109     kESAI_ExceptionInterruptEnable    = ESAI_TCR_TEIE_MASK,  /*!< FIFO error flag */
110 };
111 
112 /*! @brief The ESAI status flag, _esai_flags*/
113 enum
114 {
115     kESAI_TransmitInitFlag          = ESAI_ESR_TINIT_MASK, /*!< Indicates transmit FIFO is writing the first word */
116     kESAI_ReceiveFIFOFullFlag       = ESAI_ESR_RFF_MASK,   /*!< Receive FIFO full flag */
117     kESAI_TransmitFIFOEmptyFlag     = ESAI_ESR_TFE_MASK,   /*!< Transmit FIFO empty */
118     kESAI_TransmitLastSlotFlag      = ESAI_ESR_TLS_MASK,   /*!< Transmit last slot */
119     kESAI_TransmitDataExceptionFlag = ESAI_ESR_TDE_MASK,   /*!< Transmit data exception */
120     kESAI_TransmitEvenDataFlag      = ESAI_ESR_TED_MASK,   /*!< Transmit even data */
121     kESAI_TransmitDataFlag          = ESAI_ESR_TD_MASK,    /*!< Transmit data */
122     kESAI_ReceiveLastSlot           = ESAI_ESR_RLS_MASK,   /*!< Receive last slot */
123     kESAI_ReceiveDataException      = ESAI_ESR_RDE_MASK,   /*!< Receive data exception */
124     kESAI_ReceiveEvenData           = ESAI_ESR_RED_MASK,   /*!< Receive even data */
125     kESAI_ReceiveData               = ESAI_ESR_RD_MASK,    /*!< Receive data */
126 };
127 
128 /*! @brief SAI interface port status flag, _esai_sai_flags*/
129 enum
130 {
131     kESAI_TransmitOddRegEmpty   = ESAI_SAISR_TODFE_MASK, /*!< Enabled transmitter register empty at odd slot */
132     kESAI_TransmitEvenRegEmpty  = ESAI_SAISR_TEDE_MASK,  /*!< Enabled transmitter register empty at even slot */
133     kESAI_TransmitRegEmpty      = ESAI_SAISR_TDE_MASK,  /*!< All data in enabled transmitter regsiter send to shifter */
134     kESAI_TransmitUnderrunError = ESAI_SAISR_TUE_MASK,  /*!< Serial shifter empty  and a transmit slot begins */
135     kESAI_TransmitFrameSync     = ESAI_SAISR_TFS_MASK,  /*!< A transmit frame sync occurred in the current time slot */
136     kESAI_RecceiveOddRegFull    = ESAI_SAISR_RODF_MASK, /*!< Enabled receiver register full at odd slot */
137     kESAI_ReceiveEvenRegFull    = ESAI_SAISR_RDF_MASK,  /*!< Enabled receiver register full at even slot */
138     kESAI_RecceiveOverrunError  = ESAI_SAISR_ROE_MASK,  /*!< Receive data register overrun flag */
139     kESAI_ReceiveFrameSync      = ESAI_SAISR_RFS_MASK,  /*!< Receive frame sync flag, indicate a frame sync occurs */
140     kESAI_SerialInputFlag2      = ESAI_SAISR_IF2_MASK,  /*!< Serial input flag 2 */
141     kESAI_SerialInputFlag1      = ESAI_SAISR_IF1_MASK,  /*!< Serial in out flag 1 */
142     kESAI_SerialInputFlag0      = ESAI_SAISR_IF0_MASK   /*!< Serial input flag 0 */
143 };
144 
145 /*! @brief Audio sample rate */
146 typedef enum _esai_sample_rate
147 {
148     kESAI_SampleRate8KHz    = 8000U,  /*!< Sample rate 8000 Hz */
149     kESAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025 Hz */
150     kESAI_SampleRate12KHz   = 12000U, /*!< Sample rate 12000 Hz */
151     kESAI_SampleRate16KHz   = 16000U, /*!< Sample rate 16000 Hz */
152     kESAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050 Hz */
153     kESAI_SampleRate24KHz   = 24000U, /*!< Sample rate 24000 Hz */
154     kESAI_SampleRate32KHz   = 32000U, /*!< Sample rate 32000 Hz */
155     kESAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100 Hz */
156     kESAI_SampleRate48KHz   = 48000U, /*!< Sample rate 48000 Hz */
157     kESAI_SampleRate96KHz   = 96000U  /*!< Sample rate 96000 Hz */
158 } esai_sample_rate_t;
159 
160 /*! @brief Audio word width */
161 typedef enum _esai_word_width
162 {
163     kESAI_WordWidth8bits  = 8U,  /*!< Audio data width 8 bits */
164     kESAI_WordWidth16bits = 16U, /*!< Audio data width 16 bits */
165     kESAI_WordWidth24bits = 24U, /*!< Audio data width 24 bits */
166     kESAI_WordWidth32bits = 32U  /*!< Audio data width 32 bits */
167 } esai_word_width_t;
168 
169 /*! @brief esai slot word length */
170 typedef enum _esai_slot_format
171 {
172     kESAI_SlotLen8WordLen8   = 0x0U,  /*!< Slot length 8 bits, word length 8 bits */
173     kESAI_SlotLen12WordLen8  = 0x04U, /*!< Slot length 12 bits, word length 8 bits */
174     kESAI_SlotLen12WordLen12 = 0x01U, /*!< Slot length 12 bits, word length 12 bits */
175     kESAI_SlotLen16WordLen8  = 0x08U, /*!< Slot length 16 bits, word length 8 bits */
176     kESAI_SlotLen16WordLen12 = 0x05U, /*!< Slot length 16 bits, word length 12 bits */
177     kESAI_SlotLen16WordLen16 = 0x02U, /*!< Slot length 16 bits, word length 16 bits */
178     kESAI_SlotLen20WordLen8  = 0x0CU, /*!< Slot length 20 bits, word length 8 bits */
179     kESAI_SlotLen20WordLen12 = 0x09U, /*!< Slot length 20 bits, word length 12 bits */
180     kESAI_SlotLen20WordLen16 = 0x06U, /*!< Slot length 20 bits, word length 16 bits */
181     kESAI_SlotLen20WordLen20 = 0x03U, /*!< Slot length 20 bits, word length 20 bits */
182     kESAI_SlotLen24WordLen8  = 0x10U, /*!< Slot length 24 bits, word length 8 bits */
183     kESAI_SlotLen24WordLen12 = 0x0DU, /*!< Slot length 24 bits, word length 12 bits */
184     kESAI_SlotLen24WordLen16 = 0x0AU, /*!< Slot length 24 bits, word length 16 bits */
185     kESAI_SlotLen24WordLen20 = 0x07U, /*!< Slot length 24 bits, word length 20 bits */
186     kESAI_SlotLen24WordLen24 = 0x1EU, /*!< Slot length 24 bits, word length 24 bits */
187     kESAI_SlotLen32WordLen8  = 0x18U, /*!< Slot length 32 bits, word length 8 bits */
188     kESAI_SlotLen32WordLen12 = 0x15U, /*!< Slot length 32 bits, word length 12 bits */
189     kESAI_SlotLen32WordLen16 = 0x12U, /*!< Slot length 32 bits, word length 16 bits */
190     kESAI_SlotLen32WordLen20 = 0x0FU, /*!< Slot length 32 bits, word length 20 bits */
191     kESAI_SlotLen32WordLen24 = 0x1FU  /*!< Slot length 32 bits, word length 24 bits */
192 } esai_slot_format_t;
193 
194 /*! @brief ESAI customer defined audio format */
195 typedef struct _esai_customer_protocol
196 {
197     esai_mode_t mode;                      /*!< ESAI mode, network, normal or on demand mode */
198     esai_shift_direction_t shiftDirection; /*!< Data shift direction, MSB or LSB */
199     bool fsEarly;                          /*!< If the frame sync one bit early */
200     bool ifZeroPading;                     /*!< If padding zero */
201     bool dataAlign;                        /*!< Data left aligned or right aligned */
202     bool fsOneBit;                         /*!< If the frame sync one word length or one bit length */
203     uint8_t slotNum;                       /*!< Slot number for the audio format */
204 } esai_customer_protocol_t;
205 
206 /*! @brief ESAI user configuration structure */
207 typedef struct _esai_config
208 {
209     esai_sync_mode_t syncMode;             /*!< ESAI sync mode, control Tx/Rx clock sync */
210     esai_protocol_t txProtocol;            /*!< Use which kind of protocol */
211     esai_protocol_t rxProtocol;            /*!< Use which kind of protocol */
212     esai_customer_protocol_t txCustomer;   /*!< Audio protocol customer uses for tx */
213     esai_customer_protocol_t rxCustomer;   /*!< Audio protocol customer uses for rx */
214     esai_master_slave_t master;            /*!< Master or slave */
215     esai_clock_direction_t txHckDirection; /*!< Tx HCK direction, input or output */
216     esai_clock_direction_t rxHckDirection; /*!< Rx HCK direction, input or output */
217     esai_hclk_source_t txHckSource;        /*!< Tx HCK input clock source */
218     esai_hclk_source_t rxHckSource;        /*!< Rx HCK input clock source */
219     esai_hclk_source_t txHckOutputSource;  /*!< Tx HCK pin output clock source */
220     esai_hclk_source_t rxHckOutputSource;  /*!< Rx HCK pin output clock source */
221     esai_clock_polarity_t txHckPolarity;   /*!< Tx HCK polarity */
222     esai_clock_polarity_t txFsPolarity;    /*!< Tx frame sync polarity */
223     esai_clock_polarity_t txSckPolarity;   /*!< Tx bit clock polarity */
224     esai_clock_polarity_t rxHckPolarity;   /*!< Rx HCK polarity */
225     esai_clock_polarity_t rxFsPolarity;    /*!< Rx frame sync polarity */
226     esai_clock_polarity_t rxSckPolarity;   /*!< Rx bit clock polarity */
227     uint8_t txWatermark;                   /*!< Tx transfer watermark */
228     uint8_t rxWatermark;                   /*!< Rx receive watermark */
229 } esai_config_t;
230 
231 /*!@brief ESAI transfer queue size, user can refine it according to use case. */
232 #define ESAI_XFER_QUEUE_SIZE (4U)
233 
234 /*! @brief esai transfer format */
235 typedef struct _esai_format
236 {
237     esai_sample_rate_t sampleRate_Hz; /*!< Sample rate of audio data */
238     esai_slot_format_t slotType;      /*!< Slot format for audio format */
239     uint8_t sectionMap; /*!< The sections enabled, 0x1 means TE0 enabled, 0x2 means TE1 enabled, 0x4 means TE2, etc  */
240 } esai_format_t;
241 
242 /*! @brief ESAI transfer structure */
243 typedef struct _esai_transfer
244 {
245     uint8_t *data;   /*!< Data start address to transfer. */
246     size_t dataSize; /*!< Transfer size. */
247 } esai_transfer_t;
248 
249 typedef struct _esai_handle esai_handle_t;
250 
251 /*! @brief ESAI transfer callback prototype */
252 typedef void (*esai_transfer_callback_t)(ESAI_Type *base, esai_handle_t *handle, status_t status, void *userData);
253 
254 /*! @brief ESAI handle structure */
255 struct _esai_handle
256 {
257     uint32_t state;                                  /*!< Transfer status */
258     esai_transfer_callback_t callback;               /*!< Callback function called at transfer event*/
259     void *userData;                                  /*!< Callback parameter passed to callback function*/
260     uint8_t bitWidth;                                /*!< Bit width for transfer, 8/16/24/32 bits */
261     uint8_t slotLen;                                 /*!< Slot length of the audio data */
262     uint8_t sectionMap;                              /*!< Enabled section map */
263     esai_transfer_t esaiQueue[ESAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */
264     size_t transferSize[ESAI_XFER_QUEUE_SIZE];       /*!< Data bytes need to transfer */
265     volatile uint8_t queueUser;                      /*!< Index for user to queue transfer */
266     volatile uint8_t queueDriver;                    /*!< Index for driver to get the transfer data and size */
267     uint8_t watermark;                               /*!< Watermark value */
268 };
269 
270 /*******************************************************************************
271  * API
272  ******************************************************************************/
273 
274 #if defined(__cplusplus)
275 extern "C" {
276 #endif /*_cplusplus*/
277 
278 /*!
279  * @name Initialization and deinitialization
280  * @{
281  */
282 
283 /*!
284  * @brief Initializes the ESAI peripheral.
285  *
286  * Ungates the ESAI clock, resets the module, and configures ESAI with a configuration structure.
287  * The configuration structure can be custom filled or set with default values by
288  * ESAI_GetDefaultConfig().
289  *
290  * @note  This API should be called at the beginning of the application to use
291  * the ESAI driver. Otherwise, accessing the ESAI module can cause a hard fault
292  * because the clock is not enabled.
293  *
294  * @param base ESAI base pointer
295  * @param config ESAI configuration structure.
296  */
297 void ESAI_Init(ESAI_Type *base, esai_config_t *config);
298 
299 /*!
300  * @brief  Sets the ESAI configuration structure to default values.
301  *
302  * This API initializes the configuration structure for use in ESAI_TxConfig().
303  * The initialized structure can remain unchanged in ESAI_Init(), or it can be modified
304  *  before calling ESAI_Init().
305  *
306  * @param config pointer to master configuration structure
307  */
308 void ESAI_GetDefaultConfig(esai_config_t *config);
309 
310 /*!
311  * @brief De-initializes the ESAI peripheral.
312  *
313  * This API gates the ESAI clock. The ESAI module can't operate unless ESAI_Init
314  * is called to enable the clock.
315  *
316  * @param base ESAI base pointer
317  */
318 void ESAI_Deinit(ESAI_Type *base);
319 
320 /*!
321  * @brief Enable/Disable the ESAI peripheral internal logic.
322  *
323  * @param base ESAI base pointer
324  * @param enable True meanse enable, false means disable.
325  */
ESAI_Enable(ESAI_Type * base,bool enable)326 static inline void ESAI_Enable(ESAI_Type *base, bool enable)
327 {
328     if (enable)
329     {
330         base->ECR |= ESAI_ECR_ESAIEN_MASK;
331     }
332     else
333     {
334         base->ECR &= ~ESAI_ECR_ESAIEN_MASK;
335     }
336 }
337 
338 /*!
339  * @brief Reset ESAI internal logic.
340  *
341  * This API only resets the core logic, including the configuration registers, but not the ESAI FIFOs, users
342  * still needs to reset the ESAI fifo by calling ESAI_TxResetFIFO and ESAI_RxResetFIFO.
343  *
344  * @param base ESAI base pointer
345  */
ESAI_Reset(ESAI_Type * base)346 static inline void ESAI_Reset(ESAI_Type *base)
347 {
348     base->ECR |= ESAI_ECR_ERST_MASK;
349     base->ECR &= ~ESAI_ECR_ERST_MASK;
350 }
351 
352 /*!
353  * @brief Reset ESAI all tx sections.
354  *
355  * This API only resets the core logic of tx and all tx sections.
356  *
357  * @param base ESAI base pointer
358  */
359 void ESAI_TxReset(ESAI_Type *base);
360 
361 /*!
362  * @brief Reset ESAI all rx sections.
363  *
364  * This API only resets the core logic of rx and all rx sections.
365  *
366  * @param base ESAI base pointer
367  */
368 void ESAI_RxReset(ESAI_Type *base);
369 
370 /*!
371  * @brief Resets the ESAI Tx FIFO.
372  *
373  * This function only resets the ESAI Tx FIFO.
374  *
375  * @param base ESAI base pointer
376  */
ESAI_TxResetFIFO(ESAI_Type * base)377 static inline void ESAI_TxResetFIFO(ESAI_Type *base)
378 {
379     base->TFCR |= ESAI_TFCR_TFR_MASK;
380 }
381 
382 /*!
383  * @brief Resets the ESAI Rx FIFO.
384  *
385  * This function only resets the ESAI Rx FIFO.
386  *
387  * @param base ESAI base pointer
388  */
ESAI_RxResetFIFO(ESAI_Type * base)389 static inline void ESAI_RxResetFIFO(ESAI_Type *base)
390 {
391     base->RFCR |= ESAI_TFCR_TFR_MASK;
392 }
393 
394 /*!
395  * @brief Enables/disables ESAI Tx.
396  *
397  * @param base ESAI base pointer
398  * @param sectionMap Which sections need to be enabled. 0 means all section disabled. This parameter can be a
399  * combination of each sections, every section N is 2^N in section map.
400  */
401 void ESAI_TxEnable(ESAI_Type *base, uint8_t sectionMap);
402 
403 /*!
404  * @brief Enables/disables ESAI Rx.
405  *
406  * @param base ESAI base pointer
407  * @param sectionMap Which sections need to be enabled. 0 means all section disabled. This parameter can be a
408  * combination of each sections, every section N is 2^N in section map.
409  */
410 void ESAI_RxEnable(ESAI_Type *base, uint8_t sectionMap);
411 
412 /*!
413  * @brief Enables/disables ESAI Tx FIFO.
414  *
415  * @param base ESAI base pointer
416  * @param enable True means enable ESAI Tx, false means disable.
417  */
ESAI_TxEnableFIFO(ESAI_Type * base,bool enable)418 static inline void ESAI_TxEnableFIFO(ESAI_Type *base, bool enable)
419 {
420     if (enable)
421     {
422         base->TFCR |= ESAI_TFCR_TFE_MASK;
423     }
424     else
425     {
426         base->TFCR &= ~ESAI_TFCR_TFE_MASK;
427     }
428 }
429 
430 /*!
431  * @brief Enables/disables ESAI Rx FIFO.
432  *
433  * @param base ESAI base pointer
434  * @param enable True means enable ESAI Rx, false means disable.
435  */
ESAI_RxEnableFIFO(ESAI_Type * base,bool enable)436 static inline void ESAI_RxEnableFIFO(ESAI_Type *base, bool enable)
437 {
438     if (enable)
439     {
440         base->RFCR |= ESAI_RFCR_RFE_MASK;
441     }
442     else
443     {
444         base->RFCR &= ~ESAI_RFCR_RFE_MASK;
445     }
446 }
447 
448 /*!
449  * @brief Set ESAI Tx slot mask value.
450  *
451  * @param base ESAI base pointer
452  * @param slot Slot number need to be masked for Tx.
453  */
ESAI_TxSetSlotMask(ESAI_Type * base,uint32_t slot)454 static inline void ESAI_TxSetSlotMask(ESAI_Type *base, uint32_t slot)
455 {
456     base->TSMA = (slot & 0xFFFFU);
457     base->TSMB = (slot & 0xFFFF0000U) >> 16U;
458 }
459 
460 /*!
461  * @brief Set ESAI Rx slot mask value.
462  *
463  * @param base ESAI base pointer
464  * @param slot Slot number need to be masked for Rx
465  */
EASI_RxSetSlotMask(ESAI_Type * base,uint32_t slot)466 static inline void EASI_RxSetSlotMask(ESAI_Type *base, uint32_t slot)
467 {
468     base->RSMA = (slot & 0xFFFFU);
469     base->RSMB = (slot & 0xFFFF0000U) >> 16U;
470 }
471 
472 /*!
473  * @brief Get the data length and slot length from the input.
474  *
475  * This API sets the audio protocol defined by users.
476  *
477  * @param slotFormat Slot type.
478  * @param slotLen Pointer to the return slot length value.
479  * @param dataLen Pointer to the return data length in a slot.
480  */
481 void ESAI_AnalysisSlot(esai_slot_format_t slotFormat, uint8_t *slotLen, uint8_t *dataLen);
482 
483 /*!
484  * @brief Get the instance number for ESAI.
485  *
486  * @param base ESAI base pointer.
487  */
488 uint32_t ESAI_GetInstance(ESAI_Type *base);
489 
490 /*! @} */
491 
492 /*!
493  * @name Status
494  * @{
495  */
496 
497 /*!
498  * @brief Gets the ESAI status flag state.
499  *
500  * @param base ESAI base pointer
501  * @return ESAI staus flag value. Use status flag to AND _esai_flags to get the related status.
502  */
ESAI_GetStatusFlag(ESAI_Type * base)503 static inline uint32_t ESAI_GetStatusFlag(ESAI_Type *base)
504 {
505     return base->ESR;
506 }
507 
508 /*!
509  * @brief Gets the ESAI SAI port status flag state.
510  *
511  * @param base ESAI base pointer
512  * @return ESAI staus flag value. Use status flag to AND _esai_sai_flags to get the related status.
513  */
ESAI_GetSAIStatusFlag(ESAI_Type * base)514 static inline uint32_t ESAI_GetSAIStatusFlag(ESAI_Type *base)
515 {
516     return base->SAISR;
517 }
518 
519 /*!
520  * @brief Gets the ESAI Tx FIFO state.
521  *
522  * @param base ESAI base pointer
523  * @return ESAI Tx status flag value.
524  */
ESAI_GetTxFIFOStatus(ESAI_Type * base)525 static inline uint32_t ESAI_GetTxFIFOStatus(ESAI_Type *base)
526 {
527     return base->TFSR;
528 }
529 
530 /*!
531  * @brief Gets the ESAI Tx status flag state.
532  *
533  * @param base ESAI base pointer
534  * @return ESAI Rx status flag value.
535  */
ESAI_GetRxFIFOStatus(ESAI_Type * base)536 static inline uint32_t ESAI_GetRxFIFOStatus(ESAI_Type *base)
537 {
538     return base->RFSR;
539 }
540 
541 /*! @} */
542 
543 /*!
544  * @name Interrupts
545  * @{
546  */
547 
548 /*!
549  * @brief Enables ESAI Tx interrupt requests.
550  *
551  * @param base ESAI base pointer
552  * @param mask interrupt source. The parameter can be a combination of elements in _esai_interrupt_enable_t.
553  */
ESAI_TxEnableInterrupts(ESAI_Type * base,uint32_t mask)554 static inline void ESAI_TxEnableInterrupts(ESAI_Type *base, uint32_t mask)
555 {
556     base->TCR |= mask;
557 }
558 
559 /*!
560  * @brief Enables ESAI Rx interrupt requests.
561  *
562  * @param base ESAI base pointer
563  * @param mask interrupt source. The parameter can be a combination of elements in _esai_interrupt_enable_t.
564  */
ESAI_RxEnableInterrupts(ESAI_Type * base,uint32_t mask)565 static inline void ESAI_RxEnableInterrupts(ESAI_Type *base, uint32_t mask)
566 {
567     base->RCR |= mask;
568 }
569 
570 /*!
571  * @brief Disables ESAI Tx interrupt requests.
572  *
573  * @param base ESAI base pointer
574  * @param mask interrupt source. The parameter can be a combination of elements in _esai_interrupt_enable_t.
575  */
ESAI_TxDisableInterrupts(ESAI_Type * base,uint32_t mask)576 static inline void ESAI_TxDisableInterrupts(ESAI_Type *base, uint32_t mask)
577 {
578     base->TCR &= (~mask);
579 }
580 
581 /*!
582  * @brief Disables ESAI Rx interrupt requests.
583  *
584  * @param base ESAI base pointer
585  * @param mask interrupt source. The parameter can be a combination of elements in _esai_interrupt_enable_t.
586  */
ESAI_RxDisableInterrupts(ESAI_Type * base,uint32_t mask)587 static inline void ESAI_RxDisableInterrupts(ESAI_Type *base, uint32_t mask)
588 {
589     base->RCR &= (~mask);
590 }
591 
592 /*! @} */
593 
594 /*!
595  * @name DMA Control
596  * @{
597  */
598 
599 /*!
600  * @brief  Gets the ESAI Tx data register address.
601  *
602  * This API is used to provide a transfer address for ESAI DMA transfer configuration.
603  *
604  * @param base ESAI base pointer.
605  * @return data register address.
606  */
ESAI_TxGetDataRegisterAddress(ESAI_Type * base)607 static inline uint32_t ESAI_TxGetDataRegisterAddress(ESAI_Type *base)
608 {
609     return (uint32_t)(&(base->ETDR));
610 }
611 
612 /*!
613  * @brief  Gets the ESAI Rx data register address.
614  *
615  * This API is used to provide a transfer address for ESAI DMA transfer configuration.
616  *
617  * @param base ESAI base pointer.
618  * @return data register address.
619  */
ESAI_RxGetDataRegisterAddress(ESAI_Type * base)620 static inline uint32_t ESAI_RxGetDataRegisterAddress(ESAI_Type *base)
621 {
622     return (uint32_t)(&(base->ERDR));
623 }
624 
625 /*! @} */
626 
627 /*!
628  * @name Bus Operations
629  * @{
630  */
631 
632 /*!
633  * @brief Configures the ESAI Tx audio format.
634  *
635  * The audio format can be changed at run-time. This function configures the sample rate and audio data
636  * format to be transferred.
637  *
638  * @param base ESAI base pointer.
639  * @param format Pointer to ESAI audio data format structure.
640  * @param hckClockHz HCK clock frequency in Hz.
641  * @param hckSourceClockHz HCK source clock frequency in Hz.
642  */
643 void ESAI_TxSetFormat(ESAI_Type *base, esai_format_t *format, uint32_t hckClockHz, uint32_t hckSourceClockHz);
644 
645 /*!
646  * @brief Configures the ESAI Rx audio format.
647  *
648  * The audio format can be changed at run-time. This function configures the sample rate and audio data
649  * format to be transferred.
650  *
651  * @param base ESAI base pointer.
652  * @param format Pointer to ESAI audio data format structure.
653  * @param hckClockHz HCK clock frequency in Hz.
654  * @param hckSourceClockHz HCK source clock frequency in Hz.
655  */
656 void ESAI_RxSetFormat(ESAI_Type *base, esai_format_t *format, uint32_t hckClockHz, uint32_t hckSourceClockHz);
657 
658 /*!
659  * @brief Sends data using a blocking method.
660  *
661  * @note This function blocks by polling until data is ready to be sent.
662  *
663  * @param base ESAI base pointer.
664  * @param bitWidth How many bits in a audio word, usually 8/16/24 bits.
665  * @param buffer Pointer to the data to be written.
666  * @param size Bytes to be written.
667  */
668 void ESAI_WriteBlocking(ESAI_Type *base, uint32_t bitWidth, uint8_t *buffer, uint32_t size);
669 
670 /*!
671  * @brief Writes data into ESAI FIFO.
672  *
673  * @param base ESAI base pointer.
674  * @param data Data needs to be written.
675  */
ESAI_WriteData(ESAI_Type * base,uint32_t data)676 static inline void ESAI_WriteData(ESAI_Type *base, uint32_t data)
677 {
678     base->ETDR = data;
679 }
680 
681 /*!
682  * @brief Receives data using a blocking method.
683  *
684  * @note This function blocks by polling until data is ready to be sent.
685  *
686  * @param base ESAI base pointer.
687  * @param bitWidth How many bits in a audio word, usually 8/16/24 bits.
688  * @param buffer Pointer to the data to be read.
689  * @param size Bytes to be read.
690  */
691 void ESAI_ReadBlocking(ESAI_Type *base, uint32_t bitWidth, uint8_t *buffer, uint32_t size);
692 
693 /*!
694  * @brief Reads data from ESAI FIFO.
695  *
696  * @param base ESAI base pointer.
697  * @param channel Data channel used.
698  * @return Data in ESAI FIFO.
699  */
ESAI_ReadData(ESAI_Type * base,uint32_t channel)700 static inline uint32_t ESAI_ReadData(ESAI_Type *base, uint32_t channel)
701 {
702     return base->ERDR;
703 }
704 
705 /*! @} */
706 
707 /*!
708  * @name Transactional
709  * @{
710  */
711 
712 /*!
713  * @brief Initializes the ESAI Tx handle.
714  *
715  * This function initializes the Tx handle for ESAI Tx transactional APIs. Call
716  * this function one time to get the handle initialized.
717  *
718  * @param base ESAI base pointer
719  * @param handle ESAI handle pointer.
720  * @param callback pointer to user callback function
721  * @param userData user parameter passed to the callback function
722  */
723 void ESAI_TransferTxCreateHandle(ESAI_Type *base,
724                                  esai_handle_t *handle,
725                                  esai_transfer_callback_t callback,
726                                  void *userData);
727 
728 /*!
729  * @brief Initializes the ESAI Rx handle.
730  *
731  * This function initializes the Rx handle for ESAI Rx transactional APIs. Call
732  * this function one time to get the handle initialized.
733  *
734  * @param base ESAI base pointer.
735  * @param handle ESAI handle pointer.
736  * @param callback pointer to user callback function
737  * @param userData user parameter passed to the callback function
738  */
739 void ESAI_TransferRxCreateHandle(ESAI_Type *base,
740                                  esai_handle_t *handle,
741                                  esai_transfer_callback_t callback,
742                                  void *userData);
743 
744 /*!
745  * @brief Configures the ESAI Tx audio format.
746  *
747  * The audio format can be changed at run-time. This function configures the sample rate and audio data
748  * format to be transferred.
749  *
750  * @param base ESAI base pointer.
751  * @param handle ESAI handle pointer.
752  * @param format Pointer to ESAI audio data format structure.
753  * @param hckClockHz HCK clock frequency in Hz.
754  * @param hckSourceClockHz HCK clock source frequency in Hz.
755  * @return Status of this function. Return value is one of status_t.
756  */
757 status_t ESAI_TransferTxSetFormat(
758     ESAI_Type *base, esai_handle_t *handle, esai_format_t *format, uint32_t hckClockHz, uint32_t hckSourceClockHz);
759 
760 /*!
761  * @brief Configures the ESAI Rx audio format.
762  *
763  * The audio format can be changed at run-time. This function configures the sample rate and audio data
764  * format to be transferred.
765  *
766  * @param base ESAI base pointer.
767  * @param handle ESAI handle pointer.
768  * @param format Pointer to ESAI audio data format structure.
769  * @param hckClockHz HCK clock frequency in Hz.
770  * @param hckSourceClockHz HCK clock source frequency in Hz.
771  * @return Status of this function. Return value is one of status_t.
772  */
773 status_t ESAI_TransferRxSetFormat(
774     ESAI_Type *base, esai_handle_t *handle, esai_format_t *format, uint32_t hckClockHz, uint32_t hckSourceClockHz);
775 
776 /*!
777  * @brief Performs an interrupt non-blocking send transfer on ESAI.
778  *
779  * @note This API returns immediately after the transfer initiates.
780  * Call the ESAI_TxGetTransferStatusIRQ to poll the transfer status and check whether
781  * the transfer is finished. If the return status is not kStatus_ESAI_Busy, the transfer
782  * is finished.
783  *
784  * @param base ESAI base pointer
785  * @param handle pointer to esai_handle_t structure which stores the transfer state
786  * @param xfer pointer to esai_transfer_t structure
787  * @retval kStatus_Success Successfully started the data receive.
788  * @retval kStatus_ESAI_TxBusy Previous receive still not finished.
789  * @retval kStatus_InvalidArgument The input parameter is invalid.
790  */
791 status_t ESAI_TransferSendNonBlocking(ESAI_Type *base, esai_handle_t *handle, esai_transfer_t *xfer);
792 
793 /*!
794  * @brief Performs an interrupt non-blocking receive transfer on ESAI.
795  *
796  * @note This API returns immediately after the transfer initiates.
797  * Call the ESAI_RxGetTransferStatusIRQ to poll the transfer status and check whether
798  * the transfer is finished. If the return status is not kStatus_ESAI_Busy, the transfer
799  * is finished.
800  *
801  * @param base ESAI base pointer
802  * @param handle pointer to esai_handle_t structure which stores the transfer state
803  * @param xfer pointer to esai_transfer_t structure
804  * @retval kStatus_Success Successfully started the data receive.
805  * @retval kStatus_ESAI_RxBusy Previous receive still not finished.
806  * @retval kStatus_InvalidArgument The input parameter is invalid.
807  */
808 status_t ESAI_TransferReceiveNonBlocking(ESAI_Type *base, esai_handle_t *handle, esai_transfer_t *xfer);
809 
810 /*!
811  * @brief Gets a set byte count.
812  *
813  * @param base ESAI base pointer.
814  * @param handle pointer to esai_handle_t structure which stores the transfer state.
815  * @param count Bytes count sent.
816  * @retval kStatus_Success Succeed get the transfer count.
817  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
818  */
819 status_t ESAI_TransferGetSendCount(ESAI_Type *base, esai_handle_t *handle, size_t *count);
820 
821 /*!
822  * @brief Gets a received byte count.
823  *
824  * @param base ESAI base pointer.
825  * @param handle pointer to esai_handle_t structure which stores the transfer state.
826  * @param count Bytes count received.
827  * @retval kStatus_Success Succeed get the transfer count.
828  * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
829  */
830 status_t ESAI_TransferGetReceiveCount(ESAI_Type *base, esai_handle_t *handle, size_t *count);
831 
832 /*!
833  * @brief Aborts the current send.
834  *
835  * @note This API can be called any time when an interrupt non-blocking transfer initiates
836  * to abort the transfer early.
837  *
838  * @param base ESAI base pointer.
839  * @param handle pointer to esai_handle_t structure which stores the transfer state.
840  */
841 void ESAI_TransferAbortSend(ESAI_Type *base, esai_handle_t *handle);
842 
843 /*!
844  * @brief Aborts the current IRQ receive.
845  *
846  * @note This API can be called any time when an interrupt non-blocking transfer initiates
847  * to abort the transfer early.
848  *
849  * @param base ESAI base pointer
850  * @param handle pointer to esai_handle_t structure which stores the transfer state.
851  */
852 void ESAI_TransferAbortReceive(ESAI_Type *base, esai_handle_t *handle);
853 
854 /*!
855  * @brief Tx interrupt handler.
856  *
857  * @param base ESAI base pointer.
858  * @param handle pointer to esai_handle_t structure.
859  */
860 void ESAI_TransferTxHandleIRQ(ESAI_Type *base, esai_handle_t *handle);
861 
862 /*!
863  * @brief Tx interrupt handler.
864  *
865  * @param base ESAI base pointer.
866  * @param handle pointer to esai_handle_t structure.
867  */
868 void ESAI_TransferRxHandleIRQ(ESAI_Type *base, esai_handle_t *handle);
869 
870 /*! @} */
871 
872 #if defined(__cplusplus)
873 }
874 #endif /*_cplusplus*/
875 
876 /*! @} */
877 
878 #endif /* _FSL_ESAI_H_ */
879