2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "fsl_sai_hal.h"
33 /******************************************************************************
35 ******************************************************************************/
37 /*FUNCTION**********************************************************************
39 * Function Name : SAI_HAL_TxInit
40 * Description : Initialize the sai Tx register, just set the register vaule to zero.
41 *This function just clear the register value of sai.
42 *END**************************************************************************/
43 void SAI_HAL_TxInit(uint32_t saiBaseAddr
)
45 /* Software reset and FIFO reset */
46 BW_I2S_TCSR_SR(saiBaseAddr
, 1);
47 BW_I2S_TCSR_FR(saiBaseAddr
, 1);
48 /* Clear all registers */
49 HW_I2S_TCSR_WR(saiBaseAddr
, 0);
50 HW_I2S_TCR1_WR(saiBaseAddr
, 0);
51 HW_I2S_TCR2_WR(saiBaseAddr
, 0);
52 HW_I2S_TCR3_WR(saiBaseAddr
, 0);
53 HW_I2S_TCR4_WR(saiBaseAddr
, 0);
54 HW_I2S_TCR5_WR(saiBaseAddr
, 0);
55 HW_I2S_TMR_WR(saiBaseAddr
,0);
58 /*FUNCTION**********************************************************************
60 * Function Name : SAI_HAL_RxInit
61 * Description : Initialize the sai Rx register, just set the register vaule to zero.
62 *This function just clear the register value of sai.
63 *END**************************************************************************/
64 void SAI_HAL_RxInit(uint32_t saiBaseAddr
)
66 /* Software reset and FIFO reset */
67 BW_I2S_RCSR_SR(saiBaseAddr
, 1);
68 BW_I2S_RCSR_FR(saiBaseAddr
, 1);
69 /* Clear all registers */
70 HW_I2S_RCSR_WR(saiBaseAddr
, 0);
71 HW_I2S_RCR1_WR(saiBaseAddr
, 0);
72 HW_I2S_RCR2_WR(saiBaseAddr
, 0);
73 HW_I2S_RCR3_WR(saiBaseAddr
, 0);
74 HW_I2S_RCR4_WR(saiBaseAddr
, 0);
75 HW_I2S_RCR5_WR(saiBaseAddr
, 0);
76 HW_I2S_RMR_WR(saiBaseAddr
,0);
79 /*FUNCTION**********************************************************************
81 * Function Name : SAI_HAL_TxSetProtocol
82 * Description : According to the protocol type to set the registers for tx.
83 *The protocol can be I2S left, I2S right, I2S and so on.
84 *END**************************************************************************/
85 void SAI_HAL_TxSetProtocol(uint32_t saiBaseAddr
,sai_protocol_t protocol
)
90 BW_I2S_TCR2_BCP(saiBaseAddr
,1);/* Bit clock polarity */
91 BW_I2S_TCR4_MF(saiBaseAddr
,1);/* MSB transmitted fisrt */
92 BW_I2S_TCR4_FSE(saiBaseAddr
,0);/*Frame sync not early */
93 BW_I2S_TCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left channel is high */
94 BW_I2S_TCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
98 BW_I2S_TCR2_BCP(saiBaseAddr
,1);/* Bit clock polarity */
99 BW_I2S_TCR4_MF(saiBaseAddr
,1);/* MSB transmitted firsrt */
100 BW_I2S_TCR4_FSE(saiBaseAddr
,0);/*Frame sync not early */
101 BW_I2S_TCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
102 BW_I2S_TCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
106 BW_I2S_TCR2_BCP(saiBaseAddr
,1);/*Bit clock polarity */
107 BW_I2S_TCR4_MF(saiBaseAddr
,1);/*MSB transmitted firsrt */
108 BW_I2S_TCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
109 BW_I2S_TCR4_FSP(saiBaseAddr
,1);/* Frame sync polarity, left channel is low */
110 BW_I2S_TCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
114 BW_I2S_TCR2_BCP(saiBaseAddr
,0); /* Bit clock active low */
115 BW_I2S_TCR4_MF(saiBaseAddr
, 1); /* MSB transmitted first */
116 BW_I2S_TCR4_SYWD(saiBaseAddr
, 0); /* Only one bit clock in a frame sync */
117 BW_I2S_TCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
118 BW_I2S_TCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
119 BW_I2S_TCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
123 BW_I2S_TCR2_BCP(saiBaseAddr
,0); /* Bit clock active high */
124 BW_I2S_TCR4_MF(saiBaseAddr
, 1); /* MSB transmitted first */
125 BW_I2S_TCR4_FSE(saiBaseAddr
,0);/* Frame sync not early */
126 BW_I2S_TCR4_SYWD(saiBaseAddr
, 0); /* Only one bit clock in a frame sync */
127 BW_I2S_TCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
128 BW_I2S_TCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
132 BW_I2S_TCR2_BCP(saiBaseAddr
,1); /* Bit clock active high */
133 BW_I2S_TCR4_MF(saiBaseAddr
,1); /* MSB transmitted first */
134 BW_I2S_TCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
135 BW_I2S_TCR4_FRSZ(saiBaseAddr
,12); /* There are 13 words in a frame in AC'97 */
136 BW_I2S_TCR4_SYWD(saiBaseAddr
,15); /* Length of frame sync, 16 bit transmitted in first word */
137 BW_I2S_TCR5_W0W(saiBaseAddr
,15); /* The first word have 16 bits */
138 BW_I2S_TCR5_WNW(saiBaseAddr
,19); /* Other word is 20 bits */
146 /*FUNCTION**********************************************************************
148 * Function Name : SAI_HAL_RxSetProtocol
149 * Description : According to the protocol type to set the registers for rx.
150 *The protocol can be I2S left, I2S right, I2S and so on.
151 *END**************************************************************************/
152 void SAI_HAL_RxSetProtocol(uint32_t saiBaseAddr
,sai_protocol_t protocol
)
157 BW_I2S_RCR2_BCP(saiBaseAddr
,1);/* Bit clock polarity */
158 BW_I2S_RCR4_MF(saiBaseAddr
,1);/* MSB transmitted fisrt */
159 BW_I2S_RCR4_FSE(saiBaseAddr
,0);/*Frame sync one bit early */
160 BW_I2S_RCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left channel is high */
161 BW_I2S_RCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
164 case kSaiBusI2SRight
:
165 BW_I2S_RCR2_BCP(saiBaseAddr
,1);/* Bit clock polarity */
166 BW_I2S_RCR4_MF(saiBaseAddr
,1);/* MSB transmitted fisrt */
167 BW_I2S_RCR4_FSE(saiBaseAddr
,0);/*Frame sync one bit early */
168 BW_I2S_RCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
169 BW_I2S_RCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
173 BW_I2S_RCR2_BCP(saiBaseAddr
,1);/*Bit clock polarity */
174 BW_I2S_RCR4_MF(saiBaseAddr
,1);/*MSB transmitted fisrt */
175 BW_I2S_RCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
176 BW_I2S_RCR4_FSP(saiBaseAddr
,1);/* Frame sync polarity, left channel is low */
177 BW_I2S_RCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
181 BW_I2S_RCR2_BCP(saiBaseAddr
,0); /* Bit clock active high */
182 BW_I2S_RCR4_MF(saiBaseAddr
, 1); /* MSB transmitted first */
183 BW_I2S_RCR4_SYWD(saiBaseAddr
, 0); /* Only one bit clock in a frame sync */
184 BW_I2S_RCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
185 BW_I2S_RCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
186 BW_I2S_RCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
190 BW_I2S_RCR2_BCP(saiBaseAddr
,0); /* Bit clock active high */
191 BW_I2S_RCR4_MF(saiBaseAddr
, 1); /* MSB transmitted first */
192 BW_I2S_RCR4_FSE(saiBaseAddr
,0);/* Frame sync not early */
193 BW_I2S_RCR4_SYWD(saiBaseAddr
, 0); /* Only one bit clock in a frame sync */
194 BW_I2S_RCR4_FSP(saiBaseAddr
,0);/* Frame sync polarity, left chennel is high */
195 BW_I2S_RCR4_FRSZ(saiBaseAddr
,1);/* I2S uses 2 word in a frame */
199 BW_I2S_RCR2_BCP(saiBaseAddr
,1); /* Bit clock active high */
200 BW_I2S_RCR4_MF(saiBaseAddr
,1); /* MSB transmitted first */
201 BW_I2S_RCR4_FSE(saiBaseAddr
,1);/* Frame sync one bit early */
202 BW_I2S_RCR4_FRSZ(saiBaseAddr
,12); /* There are 13 words in a frame in AC'97 */
203 BW_I2S_RCR4_SYWD(saiBaseAddr
,15); /* Length of frame sync, 16 bit transmitted in first word */
204 BW_I2S_RCR5_W0W(saiBaseAddr
,15); /* The first word have 16 bits */
205 BW_I2S_RCR5_WNW(saiBaseAddr
,19); /* Other word is 20 bits */
213 /*FUNCTION**********************************************************************
215 * Function Name : SAI_HAL_SetMclkDiv
216 * Description : Set the divider from the clock source to get the master clock.
217 *The function would compute the divider number and set the number to the registers.
218 *END**************************************************************************/
219 void SAI_HAL_SetMclkDiv(uint32_t saiBaseAddr
, uint32_t mclk
, uint32_t src_clk
)
221 uint32_t freq
= src_clk
;
222 uint16_t fract
, divide
;
223 uint32_t remaind
= 0;
224 uint32_t current_remainder
= 0xffffffff;
225 uint16_t current_fract
= 0;
226 uint16_t current_divide
= 0;
227 uint32_t mul_freq
= 0;
228 uint32_t max_fract
= SAI_FRACT_MAX
;
229 /*In order to prevent overflow */
232 max_fract
= mclk
* SAI_DIV_MAX
/freq
;
233 if(max_fract
> SAI_FRACT_MAX
)
235 max_fract
= SAI_FRACT_MAX
;
237 /* Looking for the closet frequency */
238 for (fract
= 1; fract
< max_fract
; fract
++)
240 mul_freq
= freq
* fract
;
241 remaind
= mul_freq
% mclk
;
242 divide
= mul_freq
/mclk
;
243 /* Find the exactly frequency */
246 current_fract
= fract
;
247 current_divide
= mul_freq
/mclk
;
250 /* closer to next one */
251 if (remaind
> mclk
/2)
253 remaind
= mclk
- remaind
;
256 /* Update the closest div and fract */
257 if (remaind
< current_remainder
)
259 current_fract
= fract
;
260 current_divide
= divide
;
261 current_remainder
= remaind
;
264 BW_I2S_MDR_DIVIDE(saiBaseAddr
, current_divide
-1);
265 /* Waiting for the divider updated */
266 while(BR_I2S_MCR_DUF(saiBaseAddr
))
268 BW_I2S_MDR_FRACT(saiBaseAddr
, current_fract
- 1);
269 /* Waiting for the divider updated */
270 while(BR_I2S_MCR_DUF(saiBaseAddr
))
274 /*FUNCTION**********************************************************************
276 * Function Name : SAI_HAL_TxSetMasterSlave
277 * Description : Set the tx master or slave mode.
278 *The slave or master mode only would affect the clock direction relevant registers.
279 *END**************************************************************************/
280 void SAI_HAL_TxSetMasterSlave(uint32_t saiBaseAddr
, sai_master_slave_t master_slave_mode
)
282 if (master_slave_mode
== kSaiMaster
)
284 BW_I2S_TCR2_BCD(saiBaseAddr
,1);/* Bit clock generated internal */
285 BW_I2S_TCR4_FSD(saiBaseAddr
,1);/* Frame sync generated internal */
286 BW_I2S_MCR_MOE(saiBaseAddr
,1);/* Master clock generated internal */
290 BW_I2S_TCR2_BCD(saiBaseAddr
,0);/* Bit clock generated external */
291 BW_I2S_TCR4_FSD(saiBaseAddr
,0);/* Frame sync generated external */
292 BW_I2S_MCR_MOE(saiBaseAddr
,0);/* Master clock generated external */
296 /*FUNCTION**********************************************************************
298 * Function Name : SAI_HAL_RxSetMasterSlave
299 * Description : Set the rx master or slave mode.
300 *The slave or master mode only would affect the clock direction relevant registers.
301 *END**************************************************************************/
302 void SAI_HAL_RxSetMasterSlave(uint32_t saiBaseAddr
, sai_master_slave_t master_slave_mode
)
304 if (master_slave_mode
== kSaiMaster
)
306 BW_I2S_RCR2_BCD(saiBaseAddr
,1);/* Bit clock generated internal */
307 BW_I2S_RCR4_FSD(saiBaseAddr
,1);/* Frame sync generated internal */
308 BW_I2S_MCR_MOE(saiBaseAddr
,1);/* Master clock generated internal */
312 BW_I2S_RCR2_BCD(saiBaseAddr
,0);/* Bit clock generated external */
313 BW_I2S_RCR4_FSD(saiBaseAddr
,0);/* Frame sync generated external */
314 BW_I2S_MCR_MOE(saiBaseAddr
,0);/* Master clock generated external */
318 /*FUNCTION**********************************************************************
320 * Function Name : SAI_HAL_TxSetSyncMode
321 * Description : Set the tx sync mode.
322 *Theer are four kinds of sync mode, async, sync, sync with other sai tx, sync with other sai rx.
323 *END**************************************************************************/
324 void SAI_HAL_TxSetSyncMode(uint32_t saiBaseAddr
, sai_sync_mode_t sync_mode
)
329 BW_I2S_TCR2_SYNC(saiBaseAddr
,0);
332 BW_I2S_TCR2_SYNC(saiBaseAddr
,1);
333 BW_I2S_RCR2_SYNC(saiBaseAddr
,0);/* Receiver must be async mode */
335 case kSaiModeSyncWithOtherTx
:
336 BW_I2S_TCR2_SYNC(saiBaseAddr
,2);
338 case kSaiModeSyncWithOtherRx
:
339 BW_I2S_TCR2_SYNC(saiBaseAddr
,3);
346 /*FUNCTION**********************************************************************
348 * Function Name : SAI_HAL_RxSetSyncMode
349 * Description : Set the rx sync mode.
350 *Theer are four kinds of sync mode, async, sync, sync with other sai tx, sync with other sai rx.
351 *END**************************************************************************/
352 void SAI_HAL_RxSetSyncMode(uint32_t saiBaseAddr
,sai_sync_mode_t sync_mode
)
357 BW_I2S_RCR2_SYNC(saiBaseAddr
,0);
360 BW_I2S_RCR2_SYNC(saiBaseAddr
,1);
361 BW_I2S_TCR2_SYNC(saiBaseAddr
,0);/* Receiver must be async mode */
363 case kSaiModeSyncWithOtherTx
:
364 BW_I2S_RCR2_SYNC(saiBaseAddr
,3);
366 case kSaiModeSyncWithOtherRx
:
367 BW_I2S_RCR2_SYNC(saiBaseAddr
,2);
374 /*FUNCTION**********************************************************************
376 * Function Name : SAI_HAL_TxSetIntCmd
377 * Description : Enable the interrupt request source for tx.
378 *The source can be word start, sync error, FIFO empty, FIFO error and FIFO request.
379 *END**************************************************************************/
380 void SAI_HAL_TxSetIntCmd(uint32_t saiBaseAddr
, sai_interrupt_request_t source
, bool enable
)
384 case kSaiIntrequestWordStart
:
385 BW_I2S_TCSR_WSIE(saiBaseAddr
, enable
);
387 case kSaiIntrequestSyncError
:
388 BW_I2S_TCSR_SEIE(saiBaseAddr
, enable
);
390 case kSaiIntrequestFIFOWarning
:
391 BW_I2S_TCSR_FWIE(saiBaseAddr
, enable
);
393 case kSaiIntrequestFIFOError
:
394 BW_I2S_TCSR_FEIE(saiBaseAddr
, enable
);
396 case kSaiIntrequestFIFORequest
:
397 BW_I2S_TCSR_FRIE(saiBaseAddr
, enable
);
404 /*FUNCTION**********************************************************************
406 * Function Name : SAI_HAL_RxSetIntCmd
407 * Description : Enable the interrupt request source for rx.
408 *The source can be word start, sync error, FIFO empty, FIFO error and FIFO request.
409 *END**************************************************************************/
410 void SAI_HAL_RxSetIntCmd(uint32_t saiBaseAddr
,sai_interrupt_request_t source
,bool enable
)
414 case kSaiIntrequestWordStart
:
415 BW_I2S_RCSR_WSIE(saiBaseAddr
, enable
);
417 case kSaiIntrequestSyncError
:
418 BW_I2S_RCSR_SEIE(saiBaseAddr
, enable
);
420 case kSaiIntrequestFIFOWarning
:
421 BW_I2S_RCSR_FWIE(saiBaseAddr
, enable
);
423 case kSaiIntrequestFIFOError
:
424 BW_I2S_RCSR_FEIE(saiBaseAddr
, enable
);
426 case kSaiIntrequestFIFORequest
:
427 BW_I2S_RCSR_FRIE(saiBaseAddr
, enable
);
434 /*FUNCTION**********************************************************************
436 * Function Name : SAI_HAL_TxGetIntCmd
437 * Description : Gets state of tx interrupt source.
438 *The source can be word start, sync error, FIFO empty, FIFO error and FIFO request.
439 *END**************************************************************************/
440 bool SAI_HAL_TxGetIntCmd(uint32_t saiBaseAddr
, sai_interrupt_request_t source
)
445 case kSaiIntrequestWordStart
:
446 ret
= BR_I2S_TCSR_WSIE(saiBaseAddr
);
448 case kSaiIntrequestSyncError
:
449 ret
= BR_I2S_TCSR_SEIE(saiBaseAddr
);
451 case kSaiIntrequestFIFOWarning
:
452 ret
= BR_I2S_TCSR_FWIE(saiBaseAddr
);
454 case kSaiIntrequestFIFOError
:
455 ret
= BR_I2S_TCSR_FEIE(saiBaseAddr
);
457 case kSaiIntrequestFIFORequest
:
458 ret
= BR_I2S_TCSR_FRIE(saiBaseAddr
);
466 /*FUNCTION**********************************************************************
468 * Function Name : SAI_HAL_RxGetIntCmd
469 * Description : Gets state of rx interrupt source.
470 *The source can be word start, sync error, FIFO empty, FIFO error and FIFO request.
471 *END**************************************************************************/
472 bool SAI_HAL_RxGetIntCmd(uint32_t saiBaseAddr
,sai_interrupt_request_t source
)
477 case kSaiIntrequestWordStart
:
478 ret
= BR_I2S_RCSR_WSIE(saiBaseAddr
);
480 case kSaiIntrequestSyncError
:
481 ret
= BR_I2S_RCSR_SEIE(saiBaseAddr
);
483 case kSaiIntrequestFIFOWarning
:
484 ret
= BR_I2S_RCSR_FWIE(saiBaseAddr
);
486 case kSaiIntrequestFIFOError
:
487 ret
= BR_I2S_RCSR_FEIE(saiBaseAddr
);
489 case kSaiIntrequestFIFORequest
:
490 ret
= BR_I2S_RCSR_FRIE(saiBaseAddr
);
498 /*FUNCTION**********************************************************************
500 * Function Name : SAI_HAL_TxSetDmaCmd
501 * Description : Enable the dma request source for tx.
502 *The source can be FIFO empty or FIFO request.
503 *END**************************************************************************/
504 void SAI_HAL_TxSetDmaCmd(uint32_t saiBaseAddr
, sai_dma_request_t source
, bool enable
)
508 case kSaiDmaReqFIFOWarning
:
509 BW_I2S_TCSR_FWDE(saiBaseAddr
, enable
);
511 case kSaiDmaReqFIFORequest
:
512 BW_I2S_TCSR_FRDE(saiBaseAddr
, enable
);
519 /*FUNCTION**********************************************************************
521 * Function Name : SAI_HAL_RxSetDmaCmd
522 * Description : Enable the dma request source for rx.
523 *The source can be FIFO empty or FIFO request.
524 *END**************************************************************************/
525 void SAI_HAL_RxSetDmaCmd(uint32_t saiBaseAddr
,sai_dma_request_t source
,bool enable
)
529 case kSaiDmaReqFIFOWarning
:
530 BW_I2S_RCSR_FWDE(saiBaseAddr
,enable
);
532 case kSaiDmaReqFIFORequest
:
533 BW_I2S_RCSR_FRDE(saiBaseAddr
,enable
);
540 /*FUNCTION**********************************************************************
542 * Function Name : SAI_HAL_TxGetDmaCmd
543 * Description : Gets state of tx dma request source.
544 *The source can be FIFO empty or FIFO request.
545 *END**************************************************************************/
546 bool SAI_HAL_TxGetDmaCmd(uint32_t saiBaseAddr
, sai_dma_request_t source
)
551 case kSaiDmaReqFIFOWarning
:
552 ret
= BR_I2S_TCSR_FWDE(saiBaseAddr
);
554 case kSaiDmaReqFIFORequest
:
555 ret
= BR_I2S_TCSR_FRDE(saiBaseAddr
);
563 /*FUNCTION**********************************************************************
565 * Function Name : SAI_HAL_RxGetDmaCmd
566 * Description : Gets state of rx dma request source.
567 *The source can be FIFO empty or FIFO request.
568 *END**************************************************************************/
569 bool SAI_HAL_RxGetDmaCmd(uint32_t saiBaseAddr
,sai_dma_request_t source
)
574 case kSaiDmaReqFIFOWarning
:
575 ret
= BR_I2S_RCSR_FWDE(saiBaseAddr
);
577 case kSaiDmaReqFIFORequest
:
578 ret
= BR_I2S_RCSR_FRDE(saiBaseAddr
);
586 /*FUNCTION**********************************************************************
588 * Function Name : SAI_HAL_TxClearStateFlag
589 * Description : Clear the state flag of tx registers.
590 *The state flag incudes word start flag, sync error flag and fifo error flag.
591 *END**************************************************************************/
592 void SAI_HAL_TxClearStateFlag(uint32_t saiBaseAddr
, sai_state_flag_t flag
)
596 case kSaiStateFlagWordStart
:
597 BW_I2S_TCSR_WSF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
599 case kSaiStateFlagSyncError
:
600 BW_I2S_TCSR_SEF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
602 case kSaiStateFlagFIFOError
:
603 BW_I2S_TCSR_FEF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
605 case kSaiStateFlagSoftReset
:
606 BW_I2S_TCSR_SR(saiBaseAddr
, 0);
613 /*FUNCTION**********************************************************************
615 * Function Name : SAI_HAL_RxClearStateFlag
616 * Description : Clear the state flag of rx registers.
617 *The state flag incudes word start flag, sync error flag and fifo error flag.
618 *END**************************************************************************/
619 void SAI_HAL_RxClearStateFlag(uint32_t saiBaseAddr
,sai_state_flag_t flag
)
623 case kSaiStateFlagWordStart
:
624 BW_I2S_RCSR_WSF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
626 case kSaiStateFlagSyncError
:
627 BW_I2S_RCSR_SEF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
629 case kSaiStateFlagFIFOError
:
630 BW_I2S_RCSR_FEF(saiBaseAddr
,1);/* Write logic 1 to clear this bit */
632 case kSaiStateFlagSoftReset
:
633 BW_I2S_RCSR_SR(saiBaseAddr
, 0);
640 /*FUNCTION**********************************************************************
642 * Function Name : SAI_HAL_TxSetReset
643 * Description : Reset tx according to reset mode.
644 *The reset mode can be software reset and FIFO reset.
645 *END**************************************************************************/
646 void SAI_HAL_TxSetReset(uint32_t saiBaseAddr
, sai_reset_type_t type
)
650 case kSaiResetTypeSoftware
:
651 BW_I2S_TCSR_SR(saiBaseAddr
,1);
653 case kSaiResetTypeFIFO
:
654 BW_I2S_TCSR_FR(saiBaseAddr
, 1);
661 /*FUNCTION**********************************************************************
663 * Function Name : SAI_HAL_RxSetReset
664 * Description : Reset rx according to reset mode.
665 *The reset mode can be software reset and FIFO reset.
666 *END**************************************************************************/
667 void SAI_HAL_RxSetReset(uint32_t saiBaseAddr
,sai_reset_type_t type
)
671 case kSaiResetTypeSoftware
:
672 BW_I2S_RCSR_SR(saiBaseAddr
,1);
674 case kSaiResetTypeFIFO
:
675 BW_I2S_RCSR_FR(saiBaseAddr
, 1);
682 /*FUNCTION**********************************************************************
684 * Function Name : SAI_HAL_TxSetRunModeCmd
685 * Description : Set the work mode for tx.
686 *The work mode have stop mode, debug mode and normal mode.
687 *END**************************************************************************/
688 void SAI_HAL_TxSetRunModeCmd(uint32_t saiBaseAddr
, sai_run_mode_t run_mode
, bool enable
)
692 case kSaiRunModeStop
:
693 BW_I2S_TCSR_STOPE(saiBaseAddr
, enable
);/* Stop mode */
695 case kSaiRunModeDebug
:
696 BW_I2S_TCSR_DBGE(saiBaseAddr
, enable
);/* Debug mode */
703 /*FUNCTION**********************************************************************
705 * Function Name : SAI_HAL_RxSetRunModeCmd
706 * Description : Set the work mode for rx.
707 *The work mode have stop mode, debug mode and normal mode.
708 *END**************************************************************************/
709 void SAI_HAL_RxSetRunModeCmd(uint32_t saiBaseAddr
,sai_run_mode_t run_mode
,bool enable
)
713 case kSaiRunModeStop
:
714 BW_I2S_RCSR_STOPE(saiBaseAddr
, enable
);/* Stop mode */
716 case kSaiRunModeDebug
:
717 BW_I2S_RCSR_DBGE(saiBaseAddr
, enable
);/* Debug mode */
724 /*FUNCTION**********************************************************************
726 * Function Name : SAI_HAL_TxGetFlagState
727 * Description : Get the state flag value of tx.
728 *The state flag includes fifo error, fifo warning, fifo request, software reset,
729 * sync error and word start.
730 *END**************************************************************************/
731 bool SAI_HAL_TxGetStateFlag(uint32_t saiBaseAddr
,sai_state_flag_t flag
)
736 case kSaiStateFlagFIFOError
:
737 ret
= BR_I2S_TCSR_FEF(saiBaseAddr
);
739 case kSaiStateFlagFIFORequest
:
740 ret
= BR_I2S_TCSR_FRF(saiBaseAddr
);
742 case kSaiStateFlagFIFOWarning
:
743 ret
= BR_I2S_TCSR_FWF(saiBaseAddr
);
745 case kSaiStateFlagSoftReset
:
746 ret
= BR_I2S_TCSR_SR(saiBaseAddr
);
748 case kSaiStateFlagSyncError
:
749 ret
= BR_I2S_TCSR_SEF(saiBaseAddr
);
751 case kSaiStateFlagWordStart
:
752 ret
= BR_I2S_TCSR_WSF(saiBaseAddr
);
760 /*FUNCTION**********************************************************************
762 * Function Name : SAI_HAL_RxGetFlagState
763 * Description : Get the state flag value of rx.
764 *The state flag includes fifo error, fifo warning, fifo request, software reset,
765 * sync error and word start.
766 *END**************************************************************************/
767 bool SAI_HAL_RxGetStateFlag(uint32_t saiBaseAddr
,sai_state_flag_t flag
)
772 case kSaiStateFlagFIFOError
:
773 ret
= BR_I2S_RCSR_FEF(saiBaseAddr
);
775 case kSaiStateFlagFIFORequest
:
776 ret
= BR_I2S_RCSR_FRF(saiBaseAddr
);
778 case kSaiStateFlagFIFOWarning
:
779 ret
= BR_I2S_RCSR_FWF(saiBaseAddr
);
781 case kSaiStateFlagSoftReset
:
782 ret
= BR_I2S_RCSR_SR(saiBaseAddr
);
784 case kSaiStateFlagSyncError
:
785 ret
= BR_I2S_RCSR_SEF(saiBaseAddr
);
787 case kSaiStateFlagWordStart
:
788 ret
= BR_I2S_RCSR_WSF(saiBaseAddr
);
796 /*FUNCTION**********************************************************************
798 * Function Name : SAI_HAL_ReceiveDataBlocking
799 * Description : Receive data in blocking way.
800 *The sending would wait until there is vaild data in FIFO for reading.
801 *END**************************************************************************/
802 uint32_t SAI_HAL_ReceiveDataBlocking(uint32_t saiBaseAddr
,uint32_t rx_channel
)
804 assert(rx_channel
< FSL_FEATURE_SAI_CHANNEL_COUNT
);
805 /* Wait while fifo is empty */
806 uint8_t w_ptr
= BR_I2S_RFRn_WFP(saiBaseAddr
,rx_channel
);
807 uint8_t r_ptr
= BR_I2S_RFRn_RFP(saiBaseAddr
,rx_channel
);
808 while(w_ptr
== r_ptr
)
810 w_ptr
= BR_I2S_RFRn_WFP(saiBaseAddr
,rx_channel
);
811 r_ptr
= BR_I2S_RFRn_RFP(saiBaseAddr
,rx_channel
);
813 return BR_I2S_RDRn_RDR(saiBaseAddr
,rx_channel
);
816 /*FUNCTION**********************************************************************
818 * Function Name : SAI_HAL_SendDataBlocking
819 * Description : Send data in blocking way.
820 *The sending would wait until there is space for writing.
821 *END**************************************************************************/
822 void SAI_HAL_SendDataBlocking(uint32_t saiBaseAddr
,uint32_t tx_channel
,uint32_t data
)
824 assert(tx_channel
< FSL_FEATURE_SAI_CHANNEL_COUNT
);
825 /* Wait while fifo is full */
826 uint8_t w_ptr
= BR_I2S_TFRn_WFP(saiBaseAddr
,tx_channel
);
827 uint8_t r_ptr
= BR_I2S_TFRn_RFP(saiBaseAddr
,tx_channel
);
828 while((w_ptr
^ r_ptr
) == 0x8)
830 w_ptr
= BR_I2S_TFRn_WFP(saiBaseAddr
,tx_channel
);
831 r_ptr
= BR_I2S_TFRn_RFP(saiBaseAddr
,tx_channel
);
833 BW_I2S_TDRn_TDR(saiBaseAddr
, tx_channel
, data
);