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