1 //*****************************************************************************
2 //
3 //! @file am_hal_i2s.c
4 //!
5 //! @brief HAL implementation for the Inter-IC Sound module.
6 //!
7 //! @addtogroup i2s4_4p I2S - Inter-IC Sound
8 //! @ingroup apollo4p_hal
9 //! @{
10 //
11 //*****************************************************************************
12 
13 //*****************************************************************************
14 //
15 // Copyright (c) 2023, Ambiq Micro, Inc.
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are met:
20 //
21 // 1. Redistributions of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
23 //
24 // 2. Redistributions in binary form must reproduce the above copyright
25 // notice, this list of conditions and the following disclaimer in the
26 // documentation and/or other materials provided with the distribution.
27 //
28 // 3. Neither the name of the copyright holder nor the names of its
29 // contributors may be used to endorse or promote products derived from this
30 // software without specific prior written permission.
31 //
32 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
36 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 // POSSIBILITY OF SUCH DAMAGE.
43 //
44 // This is part of revision release_sdk_4_4_0-3c5977e664 of the AmbiqSuite Development Package.
45 //
46 //*****************************************************************************
47 
48 #include <stdint.h>
49 #include <stdbool.h>
50 #include "am_mcu_apollo.h"
51 
52 //*****************************************************************************
53 //
54 //! @name I2S magic number macros for handle verification.
55 //! @{
56 //
57 //*****************************************************************************
58 #define AM_HAL_MAGIC_I2S            0x125125
59 #define AM_HAL_I2S_HANDLE_VALID(h)    ((h) && ((am_hal_handle_prefix_t *)(h))->s.bInit && (((am_hal_handle_prefix_t *)(h))->s.magic == AM_HAL_MAGIC_I2S))
60 
61 #define AM_HAL_I2S_CHK_HANDLE(h)                                              \
62     if (!AM_HAL_I2S_HANDLE_VALID(h))                                          \
63     {                                                                         \
64         return AM_HAL_STATUS_INVALID_HANDLE;                                  \
65     }
66 //! @}
67 
68 //*****************************************************************************
69 //
70 //! Structure for I2S registers.
71 //
72 //*****************************************************************************
73 typedef struct
74 {
75     bool        bValid;
76 
77     uint32_t    regI2SCTL;
78     uint32_t    regI2SDATACFG;
79     uint32_t    regI2SIOCFG;
80     uint32_t    regAMQCFG;
81     uint32_t    regI2SCLKCFG;
82     uint32_t    regIPBIRPT;
83     uint32_t    regRXUPPERLIMIT;
84     uint32_t    regTXLOWERLIMIT;
85     uint32_t    regINTEN;
86     uint32_t    regI2SDMACFG;
87 } am_hal_i2s_register_state_t;
88 
89 //*****************************************************************************
90 //
91 //! Structure for handling I2S HAL state information.
92 //
93 //*****************************************************************************
94 typedef struct
95 {
96     am_hal_handle_prefix_t           prefix;
97 
98     uint32_t                         ui32Module;
99 
100     am_hal_i2s_register_state_t      sRegState;
101     //
102     // DMA transaction Tranfer Control Buffer.
103     //
104     uint32_t                ui32RxBufferPing;
105     uint32_t                ui32RxBufferPong;
106     uint32_t                ui32TxBufferPing;
107     uint32_t                ui32TxBufferPong;
108     //
109     // Current DMA buffer ptr.
110     //
111     uint32_t                ui32RxBufferPtr;
112     uint32_t                ui32TxBufferPtr;
113 }am_hal_i2s_state_t;
114 
115 //*****************************************************************************
116 //
117 // Globals
118 //
119 //*****************************************************************************
120 am_hal_i2s_state_t          g_I2Shandles[AM_REG_I2S_NUM_MODULES];
121 
122 //*****************************************************************************
123 //
124 // I2S initialization function
125 //
126 //*****************************************************************************
127 uint32_t
am_hal_i2s_initialize(uint32_t ui32Module,void ** ppHandle)128 am_hal_i2s_initialize(uint32_t ui32Module, void **ppHandle)
129 {
130     //
131     // Compile time check to ensure ENTRY_SIZE macros are defined correctly
132     // incorrect definition will cause divide by 0 error at build time
133     //
134 #ifndef AM_HAL_DISABLE_API_VALIDATION
135     //
136     // Validate the module number
137     //
138     if ( ui32Module >= AM_REG_I2S_NUM_MODULES )
139     {
140         return AM_HAL_STATUS_OUT_OF_RANGE;
141     }
142 
143     if (ppHandle == NULL)
144     {
145         return AM_HAL_STATUS_INVALID_ARG;
146     }
147 
148     if (g_I2Shandles[ui32Module].prefix.s.bInit)
149     {
150         return AM_HAL_STATUS_INVALID_OPERATION;
151     }
152 #endif // AM_HAL_DISABLE_API_VALIDATION
153 
154     g_I2Shandles[ui32Module].prefix.s.bInit = true;
155     g_I2Shandles[ui32Module].prefix.s.bEnable = false;
156     g_I2Shandles[ui32Module].prefix.s.magic = AM_HAL_MAGIC_I2S;
157     //
158     // Initialize the handle.
159     //
160     g_I2Shandles[ui32Module].ui32Module = ui32Module;
161     //
162     // Return the handle.
163     //
164     *ppHandle = (void *)&g_I2Shandles[ui32Module];
165     //
166     // Return the status
167     //
168     return AM_HAL_STATUS_SUCCESS;
169 } // am_hal_i2s_initialize()
170 
171 //*****************************************************************************
172 //
173 // am_hal_i2s_deinitialize
174 //
175 //*****************************************************************************
176 uint32_t
am_hal_i2s_deinitialize(void * pHandle)177 am_hal_i2s_deinitialize(void *pHandle)
178 {
179     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *)pHandle;
180     //
181     // Check the handle.
182     //
183     AM_HAL_I2S_CHK_HANDLE(pHandle);
184     //
185     // Reset the handle.
186     //
187     pState->prefix.s.bInit = false;
188     pState->prefix.s.magic = 0;
189     pState->ui32Module = 0;
190     //
191     // Return the status.
192     //
193     return AM_HAL_STATUS_SUCCESS;
194 }
195 
196 //*****************************************************************************
197 //
198 // I2S control function
199 // This function allows advanced settings
200 //
201 //*****************************************************************************
am_hal_i2s_control(void * pHandle,am_hal_i2s_request_e eReq,void * pArgs)202 uint32_t am_hal_i2s_control(void *pHandle, am_hal_i2s_request_e eReq, void *pArgs)
203 {
204     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t*)pHandle;
205     uint32_t ui32Module = pState->ui32Module;
206 
207 #ifndef AM_HAL_DISABLE_API_VALIDATION
208     //
209     // Validate the parameters
210     //
211     AM_HAL_I2S_CHK_HANDLE(pHandle);
212 #endif // AM_HAL_DISABLE_API_VALIDATION
213 
214     switch (eReq)
215     {
216         case AM_HAL_I2S_REQ_INTSET:
217             I2Sn(ui32Module)->INTSET = *((uint32_t *)pArgs);
218             break;
219         case AM_HAL_I2S_REQ_INTCLR:
220             I2Sn(ui32Module)->INTCLR = *((uint32_t *)pArgs);
221             break;
222         case AM_HAL_I2S_REQ_TXFIFOCNT:
223             *((uint32_t*)pArgs) = I2Sn(ui32Module)->TXFIFOSTATUS_b.TXFIFOCNT;
224             break;
225         case AM_HAL_I2S_REQ_READ_RXUPPERLIMIT:
226             *((uint32_t*)pArgs) = I2Sn(ui32Module)->RXUPPERLIMIT;
227             break;
228         case AM_HAL_I2S_REQ_READ_TXLOWERLIMIT:
229             *((uint32_t*)pArgs) = I2Sn(ui32Module)->TXLOWERLIMIT;
230             break;
231         case AM_HAL_I2S_REQ_WRITE_RXUPPERLIMIT:
232             I2Sn(ui32Module)->RXUPPERLIMIT = *((uint32_t*)pArgs);
233             break;
234         case AM_HAL_I2S_REQ_WRITE_TXLOWERLIMIT:
235             I2Sn(ui32Module)->TXLOWERLIMIT = *((uint32_t*)pArgs);
236             break;
237         case AM_HAL_I2S_REQ_MAX:
238             return AM_HAL_STATUS_INVALID_ARG;
239     }
240 
241     return AM_HAL_STATUS_SUCCESS;
242 }
243 
244 //*****************************************************************************
245 //
246 // I2S configuration function.
247 //
248 //*****************************************************************************
249 uint32_t
am_hal_i2s_configure(void * pHandle,am_hal_i2s_config_t * psConfig)250 am_hal_i2s_configure(void *pHandle, am_hal_i2s_config_t *psConfig)
251 {
252     uint32_t status = AM_HAL_STATUS_SUCCESS;
253 
254     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t*)pHandle;
255     uint32_t ui32Module = pState->ui32Module;
256     uint32_t ui32FramePeriod = 0;
257 
258 #ifndef AM_HAL_DISABLE_API_VALIDATION
259     //
260     // Validate the parameters
261     //
262     if ((pHandle == NULL) || (psConfig == NULL) || (pState->ui32Module >= AM_REG_I2S_NUM_MODULES))
263     {
264         return AM_HAL_STATUS_INVALID_ARG;
265     }
266 
267     AM_HAL_I2S_CHK_HANDLE(pHandle);
268     //
269     // Configure not allowed in Enabled state
270     //
271     if (pState->prefix.s.bEnable)
272     {
273         return AM_HAL_STATUS_INVALID_OPERATION;
274     }
275 #endif // AM_HAL_DISABLE_API_VALIDATION
276 
277     am_hal_i2s_data_format_t* pI2SData = psConfig->eData;
278     am_hal_i2s_io_signal_t* pI2SIOCfg  = psConfig->eIO;
279 
280 #ifndef AM_HAL_DISABLE_API_VALIDATION
281     if ((pI2SData->ui32ChannelNumbersPhase1 > 8) || (pI2SData->ui32ChannelNumbersPhase2 > 8) || \
282         (pI2SData->ui32ChannelNumbersPhase1 == 0) || (pI2SData->ui32ChannelNumbersPhase1 + pI2SData->ui32ChannelNumbersPhase2 > 8) )
283     {
284         return AM_HAL_STATUS_INVALID_ARG;
285     }
286     if ((pI2SData->eSampleLenPhase1 != AM_HAL_I2S_SAMPLE_LENGTH_8BITS) && (pI2SData->eSampleLenPhase1 != AM_HAL_I2S_SAMPLE_LENGTH_16BITS) && \
287         (pI2SData->eSampleLenPhase1 != AM_HAL_I2S_SAMPLE_LENGTH_24BITS) && (pI2SData->eSampleLenPhase1 != AM_HAL_I2S_SAMPLE_LENGTH_32BITS) )
288     {
289         return AM_HAL_STATUS_INVALID_ARG;
290     }
291     if ((pI2SData->eSampleLenPhase2 != AM_HAL_I2S_SAMPLE_LENGTH_8BITS) && (pI2SData->eSampleLenPhase2 != AM_HAL_I2S_SAMPLE_LENGTH_16BITS) && \
292         (pI2SData->eSampleLenPhase2 != AM_HAL_I2S_SAMPLE_LENGTH_24BITS) && (pI2SData->eSampleLenPhase2 != AM_HAL_I2S_SAMPLE_LENGTH_32BITS) )
293     {
294         return AM_HAL_STATUS_INVALID_ARG;
295     }
296     if ((pI2SData->eChannelLenPhase1 != AM_HAL_I2S_FRAME_WDLEN_8BITS) && (pI2SData->eChannelLenPhase1 != AM_HAL_I2S_FRAME_WDLEN_16BITS) && \
297         (pI2SData->eChannelLenPhase1 != AM_HAL_I2S_FRAME_WDLEN_24BITS) && (pI2SData->eChannelLenPhase1 != AM_HAL_I2S_FRAME_WDLEN_32BITS) )
298     {
299         return AM_HAL_STATUS_INVALID_ARG;
300     }
301     if ((pI2SData->eChannelLenPhase2 != AM_HAL_I2S_FRAME_WDLEN_8BITS) && (pI2SData->eChannelLenPhase2 != AM_HAL_I2S_FRAME_WDLEN_16BITS) && \
302         (pI2SData->eChannelLenPhase2 != AM_HAL_I2S_FRAME_WDLEN_24BITS) && (pI2SData->eChannelLenPhase2 != AM_HAL_I2S_FRAME_WDLEN_32BITS) )
303     {
304         return AM_HAL_STATUS_INVALID_ARG;
305     }
306 #endif // AM_HAL_DISABLE_API_VALIDATION
307     //
308     // 1.Reset the serial receiver or transmitter by asserting bits RXRST and/or TXRST in the I2SCTL register
309     //
310     I2Sn(ui32Module)->I2SCTL_b.RXRST = 1;
311     I2Sn(ui32Module)->I2SCTL_b.TXRST = 1;
312     am_hal_delay_us(200);
313     //
314     //2.I2S IPB clocks and IO signals
315     //
316     uint32_t ui32OEN = (psConfig->eXfer == AM_HAL_I2S_XFER_TX || psConfig->eXfer == AM_HAL_I2S_XFER_RXTX) ? 1 : 0;
317 
318     if (pI2SData->ePhase == AM_HAL_I2S_DATA_PHASE_SINGLE)
319     {
320         ui32FramePeriod = (pI2SData->ui32ChannelNumbersPhase1 * ui32I2sWordLength[pI2SData->eChannelLenPhase1]);
321     }
322     else
323     {
324         ui32FramePeriod = ((pI2SData->ui32ChannelNumbersPhase1 * ui32I2sWordLength[pI2SData->eChannelLenPhase1]) +  \
325                            (pI2SData->ui32ChannelNumbersPhase2 * ui32I2sWordLength[pI2SData->eChannelLenPhase2]) );
326     }
327 
328     I2Sn(ui32Module)->I2SIOCFG =
329          _VAL2FLD(I2S0_I2SIOCFG_OEN, ui32OEN)                | /*Output enable for SDATA output */
330          _VAL2FLD(I2S0_I2SIOCFG_FPER, ui32FramePeriod - 1)   | /*specifying a frame period of 2x WDLEN1 cycles*/
331          _VAL2FLD(I2S0_I2SIOCFG_FSP, pI2SIOCfg->eFyncCpol)   |
332          _VAL2FLD(I2S0_I2SIOCFG_PRTX, pI2SIOCfg->eTxCpol)    |
333          _VAL2FLD(I2S0_I2SIOCFG_MSL, psConfig->eMode)        |
334          _VAL2FLD(I2S0_I2SIOCFG_PRx, pI2SIOCfg->eRxCpol)     |
335          _VAL2FLD(I2S0_I2SIOCFG_FWID, (ui32I2sWordLength[pI2SData->eChannelLenPhase1] - 1) );
336     //
337     // 3.Set the audio data format.
338     //
339     I2Sn(ui32Module)->I2SDATACFG =
340          _VAL2FLD(I2S0_I2SDATACFG_SSZ1,   pI2SData->eSampleLenPhase1)     |
341          _VAL2FLD(I2S0_I2SDATACFG_JUST,   pI2SData->eDataJust)            |
342          _VAL2FLD(I2S0_I2SDATACFG_WDLEN1, pI2SData->eChannelLenPhase1)    |
343          _VAL2FLD(I2S0_I2SDATACFG_FRLEN1, (pI2SData->ui32ChannelNumbersPhase1-1))    |
344          _VAL2FLD(I2S0_I2SDATACFG_SSZ2,   pI2SData->eSampleLenPhase2)     |
345          _VAL2FLD(I2S0_I2SDATACFG_DATADLY, pI2SData->eDataDelay)          |
346          _VAL2FLD(I2S0_I2SDATACFG_WDLEN2, pI2SData->eChannelLenPhase2)    |
347          _VAL2FLD(I2S0_I2SDATACFG_FRLEN2, (pI2SData->ui32ChannelNumbersPhase2-1))    |
348          _VAL2FLD(I2S0_I2SDATACFG_PH, pI2SData->ePhase);
349     //
350     // 4.Control the enablement of the ASRC module and the source of the MCLK used in the IPB core.
351     //  [1..1] ASRC sub module enable. 0: Enabled. 1: Disabled/Bypassed
352     if ( psConfig->eMode == AM_HAL_I2S_IO_MODE_MASTER )
353     {
354         I2Sn(ui32Module)->AMQCFG = 0x2;
355     }
356     else
357     {
358         if ( psConfig->eASRC )
359         {
360             I2Sn(ui32Module)->AMQCFG = 0x0;
361         }
362         else
363         {
364           I2Sn(ui32Module)->AMQCFG = 0x2;
365         }
366     }
367     //
368     // 5.MCLK/sclk clock setting.
369     //
370     uint32_t clk_sel = psConfig->eClock;
371     I2Sn(ui32Module)->CLKCFG_b.DIV3 = psConfig->eDiv3;
372     I2Sn(ui32Module)->CLKCFG_b.FSEL = clk_sel;
373     I2Sn(ui32Module)->CLKCFG_b.MCLKEN = 0x1;
374     am_hal_delay_us(50);
375     //
376     // 6.RXTX DMA limit: FIFO 50 percent full
377     //
378     I2Sn(ui32Module)->RXUPPERLIMIT = 0x20;
379     I2Sn(ui32Module)->TXLOWERLIMIT = 0x20;
380     //
381     // Return the status.
382     //
383     return status;
384 } // am_hal_i2s_configure()
385 
386 //*****************************************************************************
387 //
388 // I2S DMA nonblocking transfer function
389 //
390 //*****************************************************************************
391 uint32_t
am_hal_i2s_dma_transfer_start(void * pHandle,am_hal_i2s_config_t * pConfig)392 am_hal_i2s_dma_transfer_start(void *pHandle,  am_hal_i2s_config_t *pConfig)
393 {
394     uint32_t ui32Status = AM_HAL_STATUS_SUCCESS;
395     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
396     uint32_t ui32Module = pState->ui32Module;
397     //
398     // Check the handle.
399     //
400     AM_HAL_I2S_CHK_HANDLE(pHandle);
401     //
402     // Poll Transmit FIFO Status register to
403     // prevent the Transmit FIFO from becoming empty.
404     //
405     uint32_t ui32Fifocnt  = I2Sn(ui32Module)->TXFIFOSTATUS_b.TXFIFOCNT;
406     uint32_t ui32Fifofull = I2Sn(ui32Module)->TXFIFOSTATUS_b.TXFIFOFULL;
407     if ( ui32Fifocnt || ui32Fifofull )
408     {
409         return AM_HAL_STATUS_FAIL;
410     }
411     //
412     // Enable the transmission of serial audio.
413     // TXRST & RXRST must be cleared in advance!!!
414     //
415     if ( pConfig->eXfer == AM_HAL_I2S_XFER_RX )
416     {
417         I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x1;
418         I2Sn(ui32Module)->I2SCTL_b.RXRST   = 0x0;
419         I2Sn(ui32Module)->I2SCTL_b.RXEN    = 0x1;
420     }
421     else if ( pConfig->eXfer == AM_HAL_I2S_XFER_TX )
422     {
423         //
424         // Need to make sure all buffer writes are flushed
425         //
426         am_hal_sysctrl_bus_write_flush();
427 
428         I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x1;
429         I2Sn(ui32Module)->I2SCTL_b.TXRST   = 0x0;
430         I2Sn(ui32Module)->I2SCTL_b.TXEN    = 0x1;
431     }
432     else if ( pConfig->eXfer == AM_HAL_I2S_XFER_RXTX )
433     {
434         //
435         // Need to make sure all buffer writes are flushed
436         //
437         am_hal_sysctrl_bus_write_flush();
438 
439         I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x1;
440         I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x1;
441         I2Sn(ui32Module)->I2SCTL           = I2S0_I2SCTL_TXEN_Msk |
442                                              I2S0_I2SCTL_RXEN_Msk;
443     }
444 
445     return ui32Status;
446 }
447 
448 //*****************************************************************************
449 //
450 // am_hal_i2s_dma_transfer_continue
451 //
452 //*****************************************************************************
453 uint32_t
am_hal_i2s_dma_transfer_continue(void * pHandle,am_hal_i2s_config_t * psConfig,am_hal_i2s_transfer_t * pTransferCfg)454 am_hal_i2s_dma_transfer_continue(void *pHandle, am_hal_i2s_config_t* psConfig, am_hal_i2s_transfer_t *pTransferCfg)
455 {
456     uint32_t ui32Status = AM_HAL_STATUS_SUCCESS;
457     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
458     uint32_t ui32Module = pState->ui32Module;
459     //
460     // Once completed, software must first write the DMACFG register to 0.
461     //
462     I2Sn(ui32Module)->DMACFG = 0x0;
463     //
464     // Clear dma status.
465     //
466     I2Sn(ui32Module)->RXDMASTAT = 0x0;
467     I2Sn(ui32Module)->TXDMASTAT = 0x0;
468     //
469     // High Priority (service immediately)
470     //
471     I2Sn(ui32Module)->DMACFG_b.RXDMAPRI = 0x1;
472     I2Sn(ui32Module)->DMACFG_b.TXDMAPRI = 0x1;
473 
474     switch(psConfig->eXfer)
475     {
476         case AM_HAL_I2S_XFER_RX:
477             I2Sn(ui32Module)->RXDMATOTCNT = pTransferCfg->ui32RxTotalCount;
478             I2Sn(ui32Module)->RXDMAADDR   = pState->ui32RxBufferPtr
479                                           = pTransferCfg->ui32RxTargetAddr;
480             I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x1;
481             break;
482 
483         case AM_HAL_I2S_XFER_TX:
484             //
485             // Need to make sure all buffer writes are flushed
486             //
487             am_hal_sysctrl_bus_write_flush();
488 
489             I2Sn(ui32Module)->TXDMATOTCNT = pTransferCfg->ui32TxTotalCount;
490             I2Sn(ui32Module)->TXDMAADDR   = pState->ui32TxBufferPtr
491                                           = pTransferCfg->ui32TxTargetAddr;
492             I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x1;
493             break;
494 
495         case AM_HAL_I2S_XFER_RXTX:
496             //
497             // Need to make sure all buffer writes are flushed
498             //
499             am_hal_sysctrl_bus_write_flush();
500 
501             I2Sn(ui32Module)->RXDMATOTCNT = pTransferCfg->ui32RxTotalCount;
502             I2Sn(ui32Module)->RXDMAADDR   = pState->ui32RxBufferPtr
503                                           = pTransferCfg->ui32RxTargetAddr;
504             I2Sn(ui32Module)->TXDMATOTCNT = pTransferCfg->ui32TxTotalCount;
505             I2Sn(ui32Module)->TXDMAADDR   = pState->ui32TxBufferPtr
506                                           = pTransferCfg->ui32TxTargetAddr;
507             I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x1;
508             I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x1;
509             break;
510     }
511 
512     return ui32Status;
513 }
514 
515 //*****************************************************************************
516 //
517 // Power control function.
518 //
519 //*****************************************************************************
520 uint32_t
am_hal_i2s_power_control(void * pHandle,am_hal_sysctrl_power_state_e ePowerState,bool bRetainState)521 am_hal_i2s_power_control(void *pHandle,
522                          am_hal_sysctrl_power_state_e ePowerState,
523                          bool bRetainState)
524 {
525     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
526     uint32_t ui32Module = pState->ui32Module;
527 
528     am_hal_pwrctrl_periph_e eI2SPowerModule = ((am_hal_pwrctrl_periph_e)(AM_HAL_PWRCTRL_PERIPH_I2S0 + ui32Module));
529     //
530     // Check the handle.
531     //
532     AM_HAL_I2S_CHK_HANDLE(pHandle);
533     //
534     // Decode the requested power state and update I2S operation accordingly.
535     //
536     switch (ePowerState)
537     {
538         //
539         // Turn on the I2S.
540         //
541         case AM_HAL_SYSCTRL_WAKE:
542             //
543             // Make sure we don't try to restore an invalid state.
544             //
545             if (bRetainState && !pState->sRegState.bValid)
546             {
547                 return AM_HAL_STATUS_INVALID_OPERATION;
548             }
549             //
550             // Enable power control.
551             //
552             am_hal_pwrctrl_periph_enable(eI2SPowerModule);
553 
554             if (bRetainState)
555             {
556                 //
557                 // Restore I2S registers
558                 //
559                 I2Sn(ui32Module)->I2SCTL       = pState->sRegState.regI2SCTL;
560                 I2Sn(ui32Module)->I2SDATACFG   = pState->sRegState.regI2SDATACFG;
561                 I2Sn(ui32Module)->I2SIOCFG     = pState->sRegState.regI2SIOCFG;
562                 I2Sn(ui32Module)->AMQCFG       = pState->sRegState.regAMQCFG;
563                 I2Sn(ui32Module)->CLKCFG       = pState->sRegState.regI2SCLKCFG;
564                 I2Sn(ui32Module)->IPBIRPT      = pState->sRegState.regIPBIRPT;
565                 I2Sn(ui32Module)->RXUPPERLIMIT = pState->sRegState.regRXUPPERLIMIT;
566                 I2Sn(ui32Module)->TXLOWERLIMIT = pState->sRegState.regTXLOWERLIMIT;
567                 I2Sn(ui32Module)->INTEN        = pState->sRegState.regINTEN;
568                 I2Sn(ui32Module)->DMACFG       = pState->sRegState.regI2SDMACFG;
569 
570                 pState->sRegState.bValid = false;
571             }
572             break;
573         //
574         // Turn off the I2S.
575         //
576         case AM_HAL_SYSCTRL_NORMALSLEEP:
577         case AM_HAL_SYSCTRL_DEEPSLEEP:
578             if (bRetainState)
579             {
580                 //
581                 // Save I2S Registers
582                 //
583                 pState->sRegState.regI2SCTL       = I2Sn(ui32Module)->I2SCTL;
584                 pState->sRegState.regI2SDATACFG   = I2Sn(ui32Module)->I2SDATACFG;
585                 pState->sRegState.regI2SIOCFG     = I2Sn(ui32Module)->I2SIOCFG;
586                 pState->sRegState.regAMQCFG       = I2Sn(ui32Module)->AMQCFG;
587                 pState->sRegState.regI2SCLKCFG    = I2Sn(ui32Module)->CLKCFG;
588                 pState->sRegState.regIPBIRPT      = I2Sn(ui32Module)->IPBIRPT;
589                 pState->sRegState.regRXUPPERLIMIT = I2Sn(ui32Module)->RXUPPERLIMIT;
590                 pState->sRegState.regTXLOWERLIMIT = I2Sn(ui32Module)->TXLOWERLIMIT;
591                 pState->sRegState.regINTEN        = I2Sn(ui32Module)->INTEN;
592                 pState->sRegState.regI2SDMACFG    = I2Sn(ui32Module)->DMACFG;
593 
594                 pState->sRegState.bValid = true;
595             }
596             //
597             // Disable power control.
598             //
599             am_hal_pwrctrl_periph_disable(eI2SPowerModule);
600             break;
601 
602         default:
603             return AM_HAL_STATUS_INVALID_ARG;
604     }
605     //
606     // Return the status.
607     //
608     return AM_HAL_STATUS_SUCCESS;
609 }
610 
611 //*****************************************************************************
612 //
613 // Interrupt disable.
614 //
615 //*****************************************************************************
616 uint32_t
am_hal_i2s_interrupt_disable(void * pHandle,uint32_t ui32IntMask)617 am_hal_i2s_interrupt_disable(void *pHandle, uint32_t ui32IntMask)
618 {
619     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
620     uint32_t ui32Module = pState->ui32Module;
621     //
622     // Check the handle.
623     //
624     AM_HAL_I2S_CHK_HANDLE(pHandle);
625 
626     I2Sn(ui32Module)->INTEN &= ~ui32IntMask;
627 
628     return AM_HAL_STATUS_SUCCESS;
629 }
630 
631 //*****************************************************************************
632 //
633 // Interrupt clear.
634 //
635 //*****************************************************************************
636 uint32_t
am_hal_i2s_interrupt_clear(void * pHandle,uint32_t ui32IntMask)637 am_hal_i2s_interrupt_clear(void *pHandle, uint32_t ui32IntMask)
638 {
639     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
640     uint32_t ui32Module = pState->ui32Module;
641     //
642     // Check the handle.
643     //
644     AM_HAL_I2S_CHK_HANDLE(pHandle);
645 
646     I2Sn(ui32Module)->INTCLR = ui32IntMask;
647 
648     return AM_HAL_STATUS_SUCCESS;
649 }
650 
651 //*****************************************************************************
652 //
653 // Returns the interrupt status.
654 //
655 //*****************************************************************************
656 uint32_t
am_hal_i2s_interrupt_status_get(void * pHandle,uint32_t * pui32Status,bool bEnabledOnly)657 am_hal_i2s_interrupt_status_get(void *pHandle, uint32_t *pui32Status, bool bEnabledOnly)
658 {
659     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
660     uint32_t ui32Module = pState->ui32Module;
661     //
662     // Check the handle.
663     //
664     AM_HAL_I2S_CHK_HANDLE(pHandle);
665     //
666     // If requested, only return the interrupts that are enabled.
667     //
668     if ( bEnabledOnly )
669     {
670         *pui32Status = I2Sn(ui32Module)->INTSTAT;
671         *pui32Status &= I2Sn(ui32Module)->INTEN;
672     }
673     else
674     {
675         *pui32Status = I2Sn(ui32Module)->INTSTAT;
676     }
677 
678     return AM_HAL_STATUS_SUCCESS;
679 }
680 
681 //*****************************************************************************
682 //
683 // Returns the DMA status(TXMDASTAT/RXDMASTAT)
684 //
685 //*****************************************************************************
686 uint32_t
am_hal_i2s_dma_status_get(void * pHandle,uint32_t * pui32Status,am_hal_i2s_xfer_dir_e xfer)687 am_hal_i2s_dma_status_get(void *pHandle, uint32_t *pui32Status, am_hal_i2s_xfer_dir_e xfer)
688 {
689     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
690     uint32_t ui32Module = pState->ui32Module;
691     //
692     // If requested, only return the interrupts that are enabled.
693     //
694     if (xfer == AM_HAL_I2S_XFER_RX)
695     {
696         *pui32Status = I2Sn(ui32Module)->RXDMASTAT;
697     }
698     else if (xfer == AM_HAL_I2S_XFER_TX)
699     {
700       *pui32Status = I2Sn(ui32Module)->TXDMASTAT;
701     }
702 
703     return AM_HAL_STATUS_SUCCESS;
704 }
705 
706 //*****************************************************************************
707 //
708 // I2S interrupt service routine
709 //
710 //*****************************************************************************
am_hal_i2s_interrupt_service(void * pHandle,uint32_t ui32IntMask,am_hal_i2s_config_t * psConfig)711 uint32_t am_hal_i2s_interrupt_service(void *pHandle, uint32_t ui32IntMask, am_hal_i2s_config_t* psConfig)
712 {
713     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
714     uint32_t ui32Module = ((am_hal_i2s_state_t*)pHandle)->ui32Module;
715     //
716     // Full duplex RX/TX mode
717     //
718     if ( psConfig->eXfer == AM_HAL_I2S_XFER_RXTX )
719     {
720         //
721         // The RX DMACPL interrupt asserts when the programmed DMA completes,
722         // or ends with an error condition.
723         //
724         if (ui32IntMask & AM_HAL_I2S_INT_RXDMACPL)
725         {
726             if ( I2Sn(ui32Module)->RXDMASTAT & AM_HAL_I2S_STAT_DMA_RX_ERR )
727             {
728                 //
729                 // Clear DMAERR bit.
730                 //
731                 am_hal_i2s_dma_error(pHandle, AM_HAL_I2S_XFER_RX);
732             }
733             //
734             // restart dma transcation.
735             //
736             I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x0;
737             I2Sn(ui32Module)->RXDMASTAT        = 0x0;
738             I2Sn(ui32Module)->RXDMAADDR        = pState->ui32RxBufferPtr = (pState->ui32RxBufferPtr == pState->ui32RxBufferPong)? pState->ui32RxBufferPing: pState->ui32RxBufferPong;
739             I2Sn(ui32Module)->RXDMATOTCNT      = psConfig->eTransfer->ui32RxTotalCount;
740             I2Sn(ui32Module)->DMACFG_b.RXDMAEN = 0x1;
741         }
742         //
743         // The TX DMACPL interrupt asserts when the programmed DMA completes,
744         // or ends with an error condition.
745         //
746         if (ui32IntMask & AM_HAL_I2S_INT_TXDMACPL)
747         {
748             if ( I2Sn(ui32Module)->TXDMASTAT & AM_HAL_I2S_STAT_DMA_TX_ERR )
749             {
750                 am_hal_i2s_dma_error(pHandle, AM_HAL_I2S_XFER_TX);
751             }
752             //
753             // Need to make sure all buffer writes are flushed
754             //
755             am_hal_sysctrl_bus_write_flush();
756             //
757             //restart DMA transaction
758             //
759             I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x0;
760             //
761             // Clear dma status.
762             //
763             I2Sn(ui32Module)->TXDMASTAT        = 0x0;
764             I2Sn(ui32Module)->TXDMAADDR        = pState->ui32TxBufferPtr = (pState->ui32TxBufferPtr == pState->ui32TxBufferPong)? pState->ui32TxBufferPing: pState->ui32TxBufferPong;
765             I2Sn(ui32Module)->TXDMATOTCNT      = psConfig->eTransfer->ui32TxTotalCount;
766             I2Sn(ui32Module)->DMACFG_b.TXDMAEN = 0x1;
767         }
768 
769         if (ui32IntMask & AM_HAL_I2S_INT_IPB)
770         {
771             am_hal_i2s_ipb_interrupt_service(pHandle);
772         }
773     }
774     else
775     {
776         if (ui32IntMask & AM_HAL_I2S_INT_RXDMACPL)
777         {
778             //
779             // Once completed, software must first write the DMACFG register to 0
780             //
781             I2Sn(ui32Module)->DMACFG = 0x0;
782 
783             if ( I2Sn(ui32Module)->RXDMASTAT & AM_HAL_I2S_STAT_DMA_RX_ERR )
784             {
785                 //
786                 // Clear DMAERR bit.
787                 //
788                 am_hal_i2s_dma_error(pHandle, AM_HAL_I2S_XFER_RX);
789             }
790             //
791             // Clear dma status.
792             //
793             I2Sn(ui32Module)->RXDMASTAT = 0x0;
794             //
795             // restart DMA transaction
796             //
797             I2Sn(ui32Module)->RXDMATOTCNT = psConfig->eTransfer->ui32RxTotalCount;
798             I2Sn(ui32Module)->RXDMAADDR   = pState->ui32RxBufferPtr = (pState->ui32RxBufferPtr == pState->ui32RxBufferPong)? pState->ui32RxBufferPing: pState->ui32RxBufferPong;
799             //
800             // High Priority (service immediately)
801             //
802             I2Sn(ui32Module)->DMACFG = I2S0_DMACFG_RXDMAPRI_Msk |
803                                        I2S0_DMACFG_RXDMAEN_Msk;
804         }
805         //
806         // The TX DMACPL interrupt asserts when the programmed DMA completes,
807         // or ends with an error condition.
808         //
809         if (ui32IntMask & AM_HAL_I2S_INT_TXDMACPL)
810         {
811             //
812             // Once completed, software must first write the DMACFG register to 0
813             //
814             I2Sn(ui32Module)->DMACFG = 0x0;
815 
816             if ( I2Sn(ui32Module)->TXDMASTAT & AM_HAL_I2S_STAT_DMA_TX_ERR )
817             {
818               //
819               // Clear DMAERR bit.
820               //
821               am_hal_i2s_dma_error(pHandle, AM_HAL_I2S_XFER_TX);
822             }
823             //
824             // Need to make sure all buffer writes are flushed
825             //
826             am_hal_sysctrl_bus_write_flush();
827             //
828             // Clear dma status.
829             //
830             I2Sn(ui32Module)->TXDMASTAT = 0x0;
831             //
832             // restart DMA transaction
833             //
834             I2Sn(ui32Module)->TXDMATOTCNT = psConfig->eTransfer->ui32TxTotalCount;
835             I2Sn(ui32Module)->TXDMAADDR   = pState->ui32TxBufferPtr = (pState->ui32TxBufferPtr == pState->ui32TxBufferPong) ? pState->ui32TxBufferPing : pState->ui32TxBufferPong;
836             //
837             // High Priority (service immediately)
838             //
839             I2Sn(ui32Module)->DMACFG = I2S0_DMACFG_TXDMAPRI_Msk |
840                                        I2S0_DMACFG_TXDMAEN_Msk;
841         }
842         if (ui32IntMask & AM_HAL_I2S_INT_IPB)
843         {
844             am_hal_i2s_ipb_interrupt_service(pHandle);
845         }
846     }
847     //
848     // Return the status.
849     //
850     return AM_HAL_STATUS_SUCCESS;
851 }
852 
853 //*****************************************************************************
854 //
855 // I2S IPB interrupt service routine
856 //
857 //*****************************************************************************
am_hal_i2s_ipb_interrupt_service(void * pHandle)858 uint32_t am_hal_i2s_ipb_interrupt_service(void *pHandle)
859 {
860     uint32_t ui32Module;
861     uint32_t ui32Status = AM_HAL_STATUS_SUCCESS;
862 
863     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t*)pHandle;
864     ui32Module = pState->ui32Module;
865 
866     uint32_t ui32IntMask = I2Sn(ui32Module)->IPBIRPT;
867     //
868     // When the number of samples in the Transmit FIFO drops below the value in the Transmit
869     // FIFO Lower Limit register (TXLOWERLIMIT)
870     //
871     // Transmit FIFO become empty
872     //
873     if (ui32IntMask & I2S0_IPBIRPT_TXEI_Msk)
874     {
875         //
876         // clear TX_Ei
877         //
878         I2Sn(ui32Module)->IPBIRPT_b.TXEI = 0x0;
879 
880         //I2Sn(ui32Module)->I2SCTL_b.TXEN  = 0x0;
881         //I2Sn(ui32Module)->I2SCTL_b.TXRST = 0x0;
882     }
883 
884     if (ui32IntMask & I2S0_IPBIRPT_TXFFI_Msk)
885     {
886         I2Sn(ui32Module)->IPBIRPT_b.TXFFI = 0x0;
887     }
888     //
889     // Receive FIFO become full
890     //
891     if (ui32IntMask & I2S0_IPBIRPT_RXFI_Msk)
892     {
893         //
894         // To clear TX_Ei and RX_Fi, '0' must be written in these fields.
895         // Otherwise, the interrupt signal will remain active.
896         //
897         I2Sn(ui32Module)->IPBIRPT_b.RXFI = 0x0;
898 
899         //I2Sn(ui32Module)->I2SCTL_b.RXEN  = 0x0;
900         //I2Sn(ui32Module)->I2SCTL_b.RXRST = 0x0;
901     }
902     //
903     // Receive fifo high limit interrupt
904     //
905     if (ui32IntMask & I2S0_IPBIRPT_RXFFI_Msk)
906     {
907         I2Sn(ui32Module)->IPBIRPT_b.RXFFI = 0x0;
908     }
909     //
910     // Return the status.
911     //
912     return ui32Status;
913 }
914 
915 //*****************************************************************************
916 //
917 // DMA transaction configuration.
918 //
919 //*****************************************************************************
920 uint32_t
am_hal_i2s_dma_configure(void * pHandle,am_hal_i2s_config_t * psConfig,am_hal_i2s_transfer_t * pTransferCfg)921 am_hal_i2s_dma_configure(void *pHandle, am_hal_i2s_config_t* psConfig, am_hal_i2s_transfer_t *pTransferCfg)
922 {
923     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
924     uint32_t ui32Module = pState->ui32Module;
925 
926 #ifndef AM_HAL_DISABLE_API_VALIDATION
927     AM_HAL_I2S_CHK_HANDLE(pHandle);
928 #endif // AM_HAL_DISABLE_API_VALIDATION
929     //
930     // Save the buffers.
931     //
932     pState->ui32RxBufferPtr  = pState->ui32RxBufferPing = pTransferCfg->ui32RxTargetAddr;
933     pState->ui32RxBufferPong = pTransferCfg->ui32RxTargetAddrReverse;
934     pState->ui32TxBufferPtr  = pState->ui32TxBufferPing = pTransferCfg->ui32TxTargetAddr;
935     pState->ui32TxBufferPong = pTransferCfg->ui32TxTargetAddrReverse;
936     //
937     // Save the handle.
938     //
939     psConfig->eTransfer      = pTransferCfg;
940     //
941     // Clear the interrupts
942     //
943     I2Sn(ui32Module)->INTCLR = AM_HAL_I2S_INT_RXDMACPL | AM_HAL_I2S_INT_TXDMACPL |
944                                AM_HAL_I2S_INT_TXREQCNT | AM_HAL_I2S_INT_RXREQCNT |
945                                AM_HAL_I2S_INT_IPB;
946 
947     I2Sn(ui32Module)->IPBIRPT = 0x0;
948 
949     switch ( psConfig->eXfer )
950     {
951         case AM_HAL_I2S_XFER_RX:
952             //
953             // Set RX/TX DMATOTCOUNT.
954             //
955             I2Sn(ui32Module)->RXDMATOTCNT = pTransferCfg->ui32RxTotalCount;
956             I2Sn(ui32Module)->RXDMAADDR   = pTransferCfg->ui32RxTargetAddr;
957             //
958             // Enable IP interrupts
959             //
960             I2Sn(ui32Module)->IPBIRPT = AM_HAL_I2S_INT_IPBIRPT_RXFF | AM_HAL_I2S_INT_IPBIRPT_RXDMA;
961             I2Sn(ui32Module)->INTEN   = AM_HAL_I2S_INT_RXDMACPL ; //| AM_HAL_I2S_INT_IPB;
962             break;
963 
964         case AM_HAL_I2S_XFER_TX:
965             I2Sn(ui32Module)->TXDMATOTCNT = pTransferCfg->ui32TxTotalCount;
966             I2Sn(ui32Module)->TXDMAADDR   = pTransferCfg->ui32TxTargetAddr;
967             //
968             // Enable IP interrupts
969             //
970             I2Sn(ui32Module)->IPBIRPT = AM_HAL_I2S_INT_IPBIRPT_TXFF | AM_HAL_I2S_INT_IPBIRPT_TXDMA;
971             I2Sn(ui32Module)->INTEN   = AM_HAL_I2S_INT_TXDMACPL; // | AM_HAL_I2S_INT_IPB;
972             break;
973 
974         case AM_HAL_I2S_XFER_RXTX:
975             I2Sn(ui32Module)->TXDMATOTCNT = pTransferCfg->ui32TxTotalCount;
976             I2Sn(ui32Module)->TXDMAADDR   = pTransferCfg->ui32TxTargetAddr;
977             I2Sn(ui32Module)->RXDMATOTCNT = pTransferCfg->ui32RxTotalCount;
978             I2Sn(ui32Module)->RXDMAADDR   = pTransferCfg->ui32RxTargetAddr;
979             //
980             // Enable IP interrupts
981             //
982             I2Sn(ui32Module)->IPBIRPT = AM_HAL_I2S_INT_IPBIRPT_RXFF | AM_HAL_I2S_INT_IPBIRPT_RXDMA |
983                                         AM_HAL_I2S_INT_IPBIRPT_TXFF | AM_HAL_I2S_INT_IPBIRPT_TXDMA;
984             I2Sn(ui32Module)->INTEN   = AM_HAL_I2S_INT_TXDMACPL | AM_HAL_I2S_INT_RXDMACPL;
985             break;
986     }
987     //
988     // High Priority (service immediately)
989     //
990     I2Sn(ui32Module)->DMACFG_b.RXDMAPRI = 0x1;
991     I2Sn(ui32Module)->DMACFG_b.TXDMAPRI = 0x1;
992 
993     return AM_HAL_STATUS_SUCCESS;
994 }
995 
996 //*****************************************************************************
997 //
998 // am_hal_i2s_dma_get_buffer
999 //
1000 //*****************************************************************************
1001 uint32_t
am_hal_i2s_dma_get_buffer(void * pHandle,am_hal_i2s_xfer_dir_e xfer)1002 am_hal_i2s_dma_get_buffer(void *pHandle, am_hal_i2s_xfer_dir_e xfer)
1003 {
1004     uint32_t ui32BufferPtr;
1005     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
1006 
1007     if ( AM_HAL_I2S_XFER_RX == xfer )
1008     {
1009         //
1010         // Invalidate DAXI to make sure CPU sees the new data when loaded
1011         //
1012         am_hal_daxi_control(AM_HAL_DAXI_CONTROL_INVALIDATE, 0);
1013 
1014         ui32BufferPtr = (pState->ui32RxBufferPtr == pState->ui32RxBufferPong)? pState->ui32RxBufferPing: pState->ui32RxBufferPong;
1015     }
1016     else
1017     {
1018         ui32BufferPtr = (pState->ui32TxBufferPtr == pState->ui32TxBufferPong)? pState->ui32TxBufferPing: pState->ui32TxBufferPong;
1019     }
1020 
1021     return ui32BufferPtr;
1022 }
1023 
1024 //*****************************************************************************
1025 //
1026 // I2S enable function
1027 //
1028 //*****************************************************************************
1029 uint32_t
am_hal_i2s_enable(void * pHandle)1030 am_hal_i2s_enable(void *pHandle)
1031 {
1032     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
1033 
1034 #ifndef AM_HAL_DISABLE_API_VALIDATION
1035     AM_HAL_I2S_CHK_HANDLE(pHandle);
1036 #endif // AM_HAL_DISABLE_API_VALIDATION
1037 
1038     if (pState->prefix.s.bEnable)
1039     {
1040         return AM_HAL_STATUS_SUCCESS;
1041     }
1042     //
1043     // Enable the audio clock.
1044     //
1045     //I2Sn(ui32Module)->CLKCFG_b.MCLKEN = 0x1;
1046 
1047     pState->prefix.s.bEnable = true;
1048 
1049     return AM_HAL_STATUS_SUCCESS;
1050 }
1051 
1052 //*****************************************************************************
1053 //
1054 // I2S disable function
1055 //
1056 //*****************************************************************************
1057 uint32_t
am_hal_i2s_disable(void * pHandle)1058 am_hal_i2s_disable(void *pHandle)
1059 {
1060     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t*)pHandle;
1061     uint32_t ui32Module = pState->ui32Module;
1062 
1063 #ifndef AM_HAL_DISABLE_API_VALIDATION
1064     AM_HAL_I2S_CHK_HANDLE(pHandle);
1065 #endif // AM_HAL_DISABLE_API_VALIDATION
1066 
1067     if (!pState->prefix.s.bEnable)
1068     {
1069         return AM_HAL_STATUS_SUCCESS;
1070     }
1071 
1072     I2Sn(ui32Module)->CLKCFG = 0x0;
1073 
1074     pState->prefix.s.bEnable = false;
1075 
1076     return AM_HAL_STATUS_SUCCESS;
1077 } // am_hal_i2s_disable()
1078 
1079 //*****************************************************************************
1080 //
1081 // am_hal_i2s_dma_transfer_complete
1082 //
1083 //*****************************************************************************
1084 uint32_t
am_hal_i2s_dma_transfer_complete(void * pHandle)1085 am_hal_i2s_dma_transfer_complete(void *pHandle)
1086 {
1087     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
1088     uint32_t ui32Module = pState->ui32Module;
1089     //
1090     // Once completed, software must first write the DMACFG register to 0,
1091     // prior to making any update
1092     //
1093     I2Sn(ui32Module)->DMACFG = 0x0;
1094     //
1095     // Clear dma status.
1096     //
1097     I2Sn(ui32Module)->RXDMASTAT = 0x0;
1098     I2Sn(ui32Module)->TXDMASTAT = 0x0;
1099 
1100     return AM_HAL_STATUS_SUCCESS;
1101 }
1102 
1103 //*****************************************************************************
1104 //
1105 // am_hal_i2s_tx_fifo_empty
1106 //
1107 //*****************************************************************************
1108 bool
am_hal_i2s_tx_fifo_empty(void * pHandle)1109 am_hal_i2s_tx_fifo_empty(void *pHandle)
1110 {
1111     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
1112     uint32_t ui32Module = pState->ui32Module;
1113     //
1114     // AM_HAL_I2S_INT_TXDMACPL is always triggered before the completion of FIFO TX,
1115     // So check the FIFOCNT to guarantee all datas transfered completely before next DMA transaction.
1116     //
1117     if ( I2Sn(ui32Module)->TXFIFOSTATUS_b.TXFIFOCNT == 0 )
1118     {
1119         return true;
1120     }
1121     else
1122     {
1123         return false;
1124     }
1125 }
1126 
1127 //*****************************************************************************
1128 //
1129 // am_hal_i2s_dma_error
1130 //
1131 //*****************************************************************************
1132 uint32_t
am_hal_i2s_dma_error(void * pHandle,am_hal_i2s_xfer_dir_e xfer)1133 am_hal_i2s_dma_error(void *pHandle, am_hal_i2s_xfer_dir_e xfer)
1134 {
1135     am_hal_i2s_state_t *pState = (am_hal_i2s_state_t *) pHandle;
1136     uint32_t ui32Module = pState->ui32Module;
1137     //
1138     // If an error condition did occur during a DMA operation, the DMA must first be disabled
1139     //
1140     I2Sn(ui32Module)->DMACFG = 0x0;
1141     //
1142     // DMA status bits cleared.
1143     //
1144     if (xfer == AM_HAL_I2S_XFER_RX)
1145     {
1146         I2Sn(ui32Module)->RXDMASTAT = 0x0;
1147     }
1148     else if (xfer == AM_HAL_I2S_XFER_TX)
1149     {
1150         I2Sn(ui32Module)->TXDMASTAT = 0x0;
1151     }
1152 
1153     return AM_HAL_STATUS_SUCCESS;
1154 }
1155 
1156 //*****************************************************************************
1157 //
1158 // End Doxygen group.
1159 //! @}
1160 //
1161 //*****************************************************************************
1162