S32 SDK
sai_driver.c
Go to the documentation of this file.
1 /*
2  * Copyright 2017 NXP
3  * All rights reserved.
4  *
5  * THIS SOFTWARE IS PROVIDED BY NXP "AS IS" AND ANY EXPRESSED OR
6  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
8  * IN NO EVENT SHALL NXP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
9  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
10  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
11  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
13  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
14  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
15  * THE POSSIBILITY OF SUCH DAMAGE.
16  */
69 #include "sai_driver.h"
70 
73 /* default values set by driver */
74 #define TX_WATERMARK 2U
75 #define RX_WATERMARK 5U
76 #define FIFO_SIZE 8U
77 #define BIT_CLK_SWAP false
78 #define BIT_CLK_AS_EXTERNAL false
79 #define WORD_FLAG_INDEX 0
80 #define CONT_ON_ERROR true
81 #define PACK_MODE 0
82 #define SYNC_ON_DEMAND true
83 #define TX_FIFO_SIZE (FIFO_SIZE-TX_WATERMARK)
84 #define RX_FIFO_SIZE (RX_WATERMARK+1U)
85 /*******************************************************************************
86  * Private Functions
87  ******************************************************************************/
88 
89 static void SAI_DRV_TxResetVar(uint32_t instNum);
90 static void SAI_DRV_RxResetVar(uint32_t instNum);
91 static void SAI_DRV_CompleteSendDataUsingDma(void * parameter,
92  edma_chn_status_t status);
93 static void SAI_DRV_CompleteReceiveDataUsingDma(void * parameter,
94  edma_chn_status_t status);
95 static void SAI_DRV_TxIRQ(uint32_t instNum);
96 static void SAI_DRV_RxIRQ(uint32_t instNum);
97 static void SAI_DRV_SendInt(uint32_t instNum,
98  const uint8_t* data[],
99  uint32_t count);
100 static void SAI_DRV_SendDma(uint32_t instNum,
101  const uint8_t* data[],
102  uint32_t count);
103 static void SAI_DRV_ReceiveDma(uint32_t instNum,
104  uint8_t* data[],
105  uint32_t count);
106 static void SAI_DRV_ReceiveInt(uint32_t instNum,
107  uint8_t* data[],
108  uint32_t count);
109 void SAI0_Tx_IRQHandler(void);
110 void SAI0_Rx_IRQHandler(void);
111 void SAI1_Tx_IRQHandler(void);
112 void SAI1_Rx_IRQHandler(void);
113 
114 #if (SAI_INSTANCE_COUNT > 0U)
115 /* Implementation of SAI0 handler named in startup code. */
116 void SAI0_Tx_IRQHandler(void)
117 {
118  SAI_DRV_TxIRQ(0U);
119 }
120 void SAI0_Rx_IRQHandler(void)
121 {
122  SAI_DRV_RxIRQ(0U);
123 }
124 #endif
125 
126 #if (SAI_INSTANCE_COUNT > 1U)
127 /* Implementation of SAI1 handler named in startup code. */
128 void SAI1_Tx_IRQHandler(void)
129 {
130  SAI_DRV_TxIRQ(1U);
131 }
132 void SAI1_Rx_IRQHandler(void)
133 {
134  SAI_DRV_RxIRQ(1U);
135 }
136 #endif
137 
138 /* Channel count for each instance */
139 #if (SAI_INSTANCE_COUNT == 2U)
140 static const uint8_t sai_channel_count[SAI_INSTANCE_COUNT] = {SAI0_CHANNEL_COUNT, SAI1_CHANNEL_COUNT};
141 #elif (SAI_INSTANCE_COUNT == 3U)
142 static const uint8_t sai_channel_count[SAI_INSTANCE_COUNT] = {SAI0_CHANNEL_COUNT, SAI1_CHANNEL_COUNT, SAI2_CHANNEL_COUNT};
143 #endif
144 #if (SAI_INSTANCE_COUNT == 2U)
145 static const clock_names_t SAIClkNames[SAI_INSTANCE_COUNT] = {SAI0_CLK, SAI1_CLK};
146 #elif (SAI_INSTANCE_COUNT == 3U)
147 static const clock_names_t SAIClkNames[SAI_INSTANCE_COUNT] = {SAI0_CLK, SAI1_CLK, SAI2_CLK};
148 #endif
149 /*******************************************************************************
150  * Variables
151  ******************************************************************************/
152 static SAI_Type * const SAIBase[SAI_INSTANCE_COUNT] = SAI_BASE_PTRS;
153 static const IRQn_Type SAITxIrqId[SAI_INSTANCE_COUNT] = SAI_TX_IRQS;
154 static const IRQn_Type SAIRxIrqId[SAI_INSTANCE_COUNT] = SAI_RX_IRQS;
155 
156 /* state variables */
157 static sai_state_t* TxState[SAI_INSTANCE_COUNT];
158 static sai_state_t* RxState[SAI_INSTANCE_COUNT];
159 
160 /*FUNCTION**********************************************************************
161  *
162  * Function Name : TO_BIT
163  * Description : Convert bool to interger
164  *
165  *END**************************************************************************/
166 static inline uint32_t TO_BIT(bool x)
167 {
168  return x ? 1UL : 0UL;
169 }
170 
171 /*FUNCTION**********************************************************************
172  *
173  * Function Name : SAI_DRV_TxResetVar
174  * Description : Reset driver variable
175  *
176  *END**************************************************************************/
177 static void SAI_DRV_TxResetVar(uint32_t instNum)
178 {
179  uint8_t j;
180  for (j = 0; j < sai_channel_count[instNum]; j++)
181  {
182  TxState[instNum]->ChnState[j].data = NULL;
183  TxState[instNum]->ChnState[j].count = 0U;
184  }
185  /* unsupported means uninitialized */
186  TxState[instNum]->status = STATUS_UNSUPPORTED;
187  TxState[instNum]->Blocking = false;
188  TxState[instNum]->Callback = NULL;
189  TxState[instNum]->NextChn = 0U;
190 }
191 
192 /*FUNCTION**********************************************************************
193  *
194  * Function Name : SAI_DRV_RxResetVar
195  * Description : Reset driver variable
196  *
197  *END**************************************************************************/
198 static void SAI_DRV_RxResetVar(uint32_t instNum)
199 {
200  uint8_t j;
201  for (j = 0; j < sai_channel_count[instNum]; j++)
202  {
203  RxState[instNum]->ChnState[j].data = NULL;
204  RxState[instNum]->ChnState[j].count = 0U;
205  }
206  /* unsupported means uninitialized */
207  RxState[instNum]->status = STATUS_UNSUPPORTED;
208  RxState[instNum]->Blocking = false;
209  RxState[instNum]->Callback = NULL;
210  RxState[instNum]->NextChn = 0U;
211 }
212 
213 /*FUNCTION**********************************************************************
214  *
215  * Function Name : SAI_DRV_CompleteSendDataUsingDma
216  * Description : Finish sending data using dma
217  *
218  *END**************************************************************************/
219 static void SAI_DRV_CompleteSendDataUsingDma(void * parameter,
220  edma_chn_status_t status)
221 {
222  uint32_t instNum = ((uint32_t)parameter & 0xffUL);
223  uint8_t ChnNum = (uint8_t)(((uint32_t)parameter >> 16UL) & 0xffUL);
224  uint8_t DmaChn = (uint8_t)(((uint32_t)parameter >> 8UL) & 0xffUL);
225  uint8_t c = 0;
226  SAI_Type* inst = SAIBase[instNum];
227  uint8_t i;
228  bool finish = true;
229 
230  /* Release the DMA channel */
231  if (status != EDMA_CHN_NORMAL)
232  {
233  TxState[instNum]->status = STATUS_ERROR;
234  /* stop all other dma channel*/
235  if ((TxState[instNum]->mux == SAI_MUX_DISABLED) || (TxState[instNum]->mux == SAI_MUX_LINE))
236  {
237  for (i = 0; i < sai_channel_count[instNum]; i++)
238  {
239  if (SAI_DRV_IsTxChannelEnabled(inst, i))
240  {
241  (void)EDMA_DRV_StopChannel(TxState[instNum]->DmaChannel[c]);
242  c++;
243  TxState[instNum]->ChnState[i].count = 0U;
244  }
245  }
246  }
247  else
248  {
249  (void)EDMA_DRV_StopChannel(TxState[instNum]->DmaChannel[0]);
250  TxState[instNum]->ChnState[0].count = 0U;
251  }
252  finish = true;
253  }
254  else
255  {
256  (void)EDMA_DRV_StopChannel(TxState[instNum]->DmaChannel[DmaChn]);
257  TxState[instNum]->ChnState[ChnNum].count = 0U;
258  /* check if all channel finished */
259  if ((TxState[instNum]->mux == SAI_MUX_DISABLED) || (TxState[instNum]->mux == SAI_MUX_LINE))
260  {
261  for (i = 0; i < sai_channel_count[instNum]; i++)
262  {
263  if (SAI_DRV_IsTxChannelEnabled(inst, i))
264  {
265  if (TxState[instNum]->ChnState[i].count > 0U)
266  {
267  finish = false;
268  break;
269  }
270  }
271  }
272  }
273  else /* mux mem only one channel */
274  {
275  finish = true;
276  }
277  }
278  if (finish)
279  {
280  /* Disable tx DMA requests for the current instance */
281  SAI_DRV_TxDisableFifoReqDma(inst);
282  if (TxState[instNum]->status != STATUS_ERROR)
283  {
284  TxState[instNum]->status = STATUS_SUCCESS;
285  }
286  if (TxState[instNum]->Blocking)
287  {
288  (void)OSIF_SemaPost(&TxState[instNum]->Sema);
289  }
290  else
291  {
292  /* Invoke callback if there is one */
293  if (TxState[instNum]->Callback != NULL)
294  {
295  TxState[instNum]->Callback(ChnNum, SAI_TRANSFER_COMPLETE, TxState[instNum]->status);
296  }
297  }
298  }
299 }
300 
301 /*FUNCTION**********************************************************************
302  *
303  * Function Name : SAI_DRV_CompleteReceiveDataUsingDma
304  * Description : Finish receiving data using dma
305  *
306  *END**************************************************************************/
307 static void SAI_DRV_CompleteReceiveDataUsingDma(void * parameter,
308  edma_chn_status_t status)
309 {
310  uint32_t instNum = ((uint32_t)parameter & 0xffUL);
311  uint8_t ChnNum = (uint8_t)(((uint32_t)parameter >> 16U) & 0xffUL);
312  uint8_t DmaChn = (uint8_t)(((uint32_t)parameter >> 8U) & 0xffUL);
313  uint8_t c = 0;
314  SAI_Type* inst = SAIBase[instNum];
315  uint8_t i;
316  bool finish = true;
317 
318  /* Release the DMA channel */
319  if (status != EDMA_CHN_NORMAL)
320  {
321  RxState[instNum]->status = STATUS_ERROR;
322  /* stop all other dma channel*/
323  if ((RxState[instNum]->mux == SAI_MUX_DISABLED) || (RxState[instNum]->mux == SAI_MUX_LINE))
324  {
325  for (i = 0; i < sai_channel_count[instNum]; i++)
326  {
327  if (SAI_DRV_IsRxChannelEnabled(inst, i))
328  {
329  (void)EDMA_DRV_StopChannel(RxState[instNum]->DmaChannel[c]);
330  c++;
331  RxState[instNum]->ChnState[i].count = 0U;
332  }
333  }
334  }
335  else
336  {
337  (void)EDMA_DRV_StopChannel(RxState[instNum]->DmaChannel[0]);
338  RxState[instNum]->ChnState[0].count = 0U;
339  }
340  finish = true;
341  }
342  else
343  {
344  (void)EDMA_DRV_StopChannel(RxState[instNum]->DmaChannel[DmaChn]);
345  RxState[instNum]->ChnState[ChnNum].count = 0U;
346  /* check if all channel finished */
347  if ((RxState[instNum]->mux == SAI_MUX_DISABLED) || (RxState[instNum]->mux == SAI_MUX_LINE))
348  {
349  for (i = 0; i < sai_channel_count[instNum]; i++)
350  {
351  if (SAI_DRV_IsRxChannelEnabled(inst, i))
352  {
353  if (RxState[instNum]->ChnState[i].count > 0U)
354  {
355  finish = false;
356  break;
357  }
358  }
359  }
360  }
361  else /* mux mem only one channel */
362  {
363  finish = true;
364  }
365  }
366  if (finish)
367  {
368  /* Disable Rx DMA requests for the current instance */
369  SAI_DRV_RxDisableFifoReqDma(inst);
370  if (RxState[instNum]->status != STATUS_ERROR)
371  {
372  RxState[instNum]->status = STATUS_SUCCESS;
373  }
374  if (RxState[instNum]->Blocking)
375  {
376  (void)OSIF_SemaPost(&RxState[instNum]->Sema);
377  }
378  else
379  {
380  /* Invoke callback if there is one */
381  if (RxState[instNum]->Callback != NULL)
382  {
383  RxState[instNum]->Callback(ChnNum, SAI_TRANSFER_COMPLETE, RxState[instNum]->status);
384  }
385  }
386  }
387 }
388 
389 /*FUNCTION**********************************************************************
390  *
391  * Function Name : SAI_DRV_TxIRQ
392  * Description : Manage interrupt transfer using fifo request, execute
393  * other user interrupt func (fifo error, word start,
394  * sync error)
395  *
396  *END**************************************************************************/
397 static void SAI_DRV_TxIRQ(uint32_t instNum)
398 {
399  SAI_Type* inst = SAIBase[instNum];
400  uint8_t i,j;
401  uint32_t temp;
402  bool finish;
403 
404  if (SAI_DRV_TxGetFifoReqFlag(inst))
405  {
406  if ((TxState[instNum]->XferType == SAI_INTERRUPT) && (TxState[instNum]->status == STATUS_BUSY))
407  {
408  finish = false;
409  if (TxState[instNum]->mux == SAI_MUX_LINE)
410  {
411  for (i = 0U; i < sai_channel_count[instNum]; i++)
412  {
413  if (SAI_DRV_IsTxChannelEnabled(inst, i))
414  {
415  if (TxState[instNum]->ChnState[0].count < TX_FIFO_SIZE)
416  {
417  temp = TxState[instNum]->ChnState[0].count;
418  }
419  else
420  {
421  temp = TX_FIFO_SIZE;
422  }
423  for (j = 0U; j < temp; j++)
424  {
425  if (TxState[instNum]->ElementSize == 1U)
426  {
427  SAI_DRV_TxWrite(inst, i, (uint32_t)*TxState[instNum]->ChnState[TxState[instNum]->NextChn].data);
428  }
429  else if (TxState[instNum]->ElementSize == 2U)
430  {
431  SAI_DRV_TxWrite(inst, i, (uint32_t)*((uint16_t*) TxState[instNum]->ChnState[TxState[instNum]->NextChn].data));
432  }
433  else if (TxState[instNum]->ElementSize == 4U)
434  {
435  SAI_DRV_TxWrite(inst, i, *((uint32_t*) TxState[instNum]->ChnState[TxState[instNum]->NextChn].data));
436  }
437  else
438  {
439  DEV_ASSERT(false);
440  }
441  TxState[instNum]->ChnState[TxState[instNum]->NextChn].data += TxState[instNum]->ElementSize;
442  TxState[instNum]->NextChn++; /* alternate between data block */
443  if (TxState[instNum]->NextChn == TxState[instNum]->ChannelCount)
444  {
445  TxState[instNum]->NextChn = 0U;
446  }
447  }
448  if (TxState[instNum]->ChnState[0].count <= TX_FIFO_SIZE)
449  {
450  finish = true;
451  TxState[instNum]->ChnState[0].count = 0;
452  }
453  else
454  {
455  TxState[instNum]->ChnState[0].count -= TX_FIFO_SIZE;
456  }
457  break; /* only one channle enabled in this mode */
458  }
459  }
460  }
461  else if (TxState[instNum]->mux == SAI_MUX_MEM)
462  {
463  if (TxState[instNum]->ChnState[0].count < TX_FIFO_SIZE)
464  {
465  temp = TxState[instNum]->ChnState[0].count;
466  }
467  else
468  {
469  temp = TX_FIFO_SIZE;
470  }
471  for (j = 0U; j < temp; j++)
472  {
473  for (i = 0U; i < sai_channel_count[instNum]; i++)
474  {
475  if (SAI_DRV_IsTxChannelEnabled(inst, i))
476  {
477  if (TxState[instNum]->ElementSize == 1U)
478  {
479  SAI_DRV_TxWrite(inst, i, (uint32_t)*TxState[instNum]->ChnState[0].data);
480  }
481  else if (TxState[instNum]->ElementSize == 2U)
482  {
483  SAI_DRV_TxWrite(inst, i, (uint32_t)*((uint16_t*) TxState[instNum]->ChnState[0U].data));
484  }
485  else if (TxState[instNum]->ElementSize == 4U)
486  {
487  SAI_DRV_TxWrite(inst, i, *((uint32_t*) TxState[instNum]->ChnState[0U].data));
488  }
489  else
490  {
491  DEV_ASSERT(false);
492  }
493  TxState[instNum]->ChnState[0U].data += TxState[instNum]->ElementSize;
494  }
495  }
496  }
497  if (TxState[instNum]->ChnState[0].count <= TX_FIFO_SIZE)
498  {
499  finish = true;
500  TxState[instNum]->ChnState[0].count = 0;
501  }
502  else
503  {
504  TxState[instNum]->ChnState[0].count -= TX_FIFO_SIZE;
505  }
506  }
507  else /* mux disabled */
508  {
509  if (TxState[instNum]->ChnState[0].count < TX_FIFO_SIZE)
510  {
511  temp = TxState[instNum]->ChnState[0].count;
512  }
513  else
514  {
515  temp = TX_FIFO_SIZE;
516  }
517  for (i = 0U; i < sai_channel_count[instNum]; i++)
518  {
519  if (SAI_DRV_IsTxChannelEnabled(inst, i))
520  {
521  for (j = 0U; j < temp; j++)
522  {
523  if (TxState[instNum]->ElementSize == 1U)
524  {
525  SAI_DRV_TxWrite(inst, i, (uint32_t)*TxState[instNum]->ChnState[i].data);
526  }
527  else if (TxState[instNum]->ElementSize == 2U)
528  {
529  SAI_DRV_TxWrite(inst, i, (uint32_t)*((uint16_t*) TxState[instNum]->ChnState[i].data));
530  }
531  else if (TxState[instNum]->ElementSize == 4U)
532  {
533  SAI_DRV_TxWrite(inst, i, *((uint32_t*) TxState[instNum]->ChnState[i].data));
534  }
535  else
536  {
537  DEV_ASSERT(false);
538  }
539  TxState[instNum]->ChnState[i].data += TxState[instNum]->ElementSize;
540  }
541  }
542  }
543  if (TxState[instNum]->ChnState[0].count <= TX_FIFO_SIZE)
544  {
545  finish = true;
546  TxState[instNum]->ChnState[0].count = 0;
547  }
548  else
549  {
550  TxState[instNum]->ChnState[0].count -= TX_FIFO_SIZE;
551  }
552  }
553  if (finish)
554  {
555  TxState[instNum]->status = STATUS_SUCCESS;
556  SAI_DRV_TxDisableFifoReqInt(inst);
557  if (TxState[instNum]->Blocking)
558  {
559  (void)OSIF_SemaPost(&TxState[instNum]->Sema);
560  }
561  else
562  {
563  if (TxState[instNum]->Callback != NULL)
564  {
565  TxState[instNum]->Callback(0U, SAI_TRANSFER_COMPLETE, STATUS_SUCCESS);
566  }
567  }
568  }
569  }
570  }
571  if (TxState[instNum]->Callback != NULL)
572  {
573  if (SAI_DRV_TxGetFifoErrorFlag(inst))
574  {
575  for (i = 0; i < sai_channel_count[instNum]; i++)
576  {
577  if (SAI_DRV_IsTxChannelEnabled(inst, i))
578  {
579  if (SAI_DRV_IsTxFifoEmpty(inst, i))
580  {
581  TxState[instNum]->Callback(i, SAI_RUN_ERROR, STATUS_ERROR);
582  }
583  }
584  SAI_DRV_TxClearFlag (inst, SAI_TCSR_FEF_SHIFT);
585  }
586  }
587  if (SAI_DRV_TxGetWordStartFlag(inst))
588  {
589  TxState[instNum]->Callback(0U, SAI_FRAME_START, STATUS_SUCCESS);
590  SAI_DRV_TxClearFlag (inst, SAI_TCSR_WSF_SHIFT);
591  }
592  if (SAI_DRV_TxGetSyncErrorFlag(inst))
593  {
594  TxState[instNum]->Callback(0U, SAI_SYNC_ERROR, STATUS_ERROR);
595  SAI_DRV_TxClearFlag (inst, SAI_TCSR_SEF_SHIFT);
596  }
597  }
598 }
599 
600 /*FUNCTION**********************************************************************
601  *
602  * Function Name : SAI_DRV_RxIRQ
603  * Description : Manage interrupt transfer using fifo request, execute
604  * other user interrupt func (fifo error, word start,
605  * sync error)
606  *
607  *END**************************************************************************/
608 static void SAI_DRV_RxIRQ(uint32_t instNum)
609 {
610  SAI_Type* inst = SAIBase[instNum];
611  uint8_t i, j;
612  uint32_t temp;
613  bool finish;
614 
615  if (SAI_DRV_RxGetFifoReqFlag(inst))
616  {
617  if ((RxState[instNum]->XferType == SAI_INTERRUPT) && (RxState[instNum]->status == STATUS_BUSY))
618  {
619  finish = false;
620  if (RxState[instNum]->mux == SAI_MUX_LINE)
621  {
622  for (i = 0U; i < sai_channel_count[instNum]; i++)
623  {
624  if (SAI_DRV_IsRxChannelEnabled(inst, i))
625  {
626  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE)
627  {
628  temp = RxState[instNum]->ChnState[0].count;
629  }
630  else
631  {
632  temp = RX_FIFO_SIZE;
633  }
634  for (j = 0U; j < temp; j++)
635  {
636  if (RxState[instNum]->ElementSize == 1U)
637  {
638  *RxState[instNum]->ChnState[RxState[instNum]->NextChn].data = (uint8_t) SAI_DRV_RxRead(inst, i);
639  }
640  else if (RxState[instNum]->ElementSize == 2U)
641  {
642  *(uint16_t*)RxState[instNum]->ChnState[RxState[instNum]->NextChn].data = (uint16_t) SAI_DRV_RxRead(inst, i);
643  }
644  else if (RxState[instNum]->ElementSize == 4U)
645  {
646  *(uint32_t*)RxState[instNum]->ChnState[RxState[instNum]->NextChn].data = SAI_DRV_RxRead(inst, i);
647  }
648  else
649  {
650  DEV_ASSERT(false);
651  }
652  RxState[instNum]->ChnState[RxState[instNum]->NextChn].data += RxState[instNum]->ElementSize;
653  RxState[instNum]->NextChn++; /* alternate between data block */
654  if (RxState[instNum]->NextChn == RxState[instNum]->ChannelCount)
655  {
656  RxState[instNum]->NextChn = 0U;
657  }
658  }
659  if (RxState[instNum]->ChnState[0].count <= RX_FIFO_SIZE)
660  {
661  finish = true;
662  RxState[instNum]->ChnState[0].count = 0;
663  }
664  else
665  {
666  RxState[instNum]->ChnState[0].count -= RX_FIFO_SIZE;
667  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE) /* set watermark below normal level */
668  {
669  SAI_DRV_RxSetWatermark(inst, (uint8_t)(RxState[instNum]->ChnState[0].count - 1UL));
670  }
671  }
672  break; /* only one channel is enabled in this mode */
673  }
674  }
675  }
676  else if (RxState[instNum]->mux == SAI_MUX_MEM)
677  {
678  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE)
679  {
680  temp = RxState[instNum]->ChnState[0].count;
681  }
682  else
683  {
684  temp = RX_FIFO_SIZE;
685  }
686  for (j = 0U; j < temp; j++)
687  {
688  for (i = 0U; i < sai_channel_count[instNum]; i++)
689  {
690  if (SAI_DRV_IsRxChannelEnabled(inst, i))
691  {
692  if (RxState[instNum]->ElementSize == 1U)
693  {
694  *RxState[instNum]->ChnState[0U].data = (uint8_t) SAI_DRV_RxRead(inst, i);
695  }
696  else if (RxState[instNum]->ElementSize == 2U)
697  {
698  *(uint16_t*)RxState[instNum]->ChnState[0U].data = (uint16_t) SAI_DRV_RxRead(inst, i);
699  }
700  else if (RxState[instNum]->ElementSize == 4U)
701  {
702  *(uint32_t*)RxState[instNum]->ChnState[0U].data = SAI_DRV_RxRead(inst, i);
703  }
704  else
705  {
706  DEV_ASSERT(false);
707  }
708  RxState[instNum]->ChnState[0U].data += RxState[instNum]->ElementSize;
709  }
710  }
711  }
712  if (RxState[instNum]->ChnState[0].count <= RX_FIFO_SIZE)
713  {
714  finish = true;
715  RxState[instNum]->ChnState[0].count = 0;
716  }
717  else
718  {
719  RxState[instNum]->ChnState[0].count -= RX_FIFO_SIZE;
720  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE) /* set watermark below normal level */
721  {
722  SAI_DRV_RxSetWatermark(inst, (uint8_t)(RxState[instNum]->ChnState[0].count - 1UL));
723  }
724  }
725  }
726  else /* mux disabled */
727  {
728  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE)
729  {
730  temp = RxState[instNum]->ChnState[0].count;
731  }
732  else
733  {
734  temp = RX_FIFO_SIZE;
735  }
736  for (i = 0U; i < sai_channel_count[instNum]; i++)
737  {
738  if (SAI_DRV_IsRxChannelEnabled(inst, i))
739  {
740  for (j = 0U; j < temp; j++)
741  {
742  if (RxState[instNum]->ElementSize == 1U)
743  {
744  *RxState[instNum]->ChnState[i].data = (uint8_t) SAI_DRV_RxRead(inst, i);
745  }
746  else if (RxState[instNum]->ElementSize == 2U)
747  {
748  *(uint16_t*)RxState[instNum]->ChnState[i].data = (uint16_t) SAI_DRV_RxRead(inst, i);
749  }
750  else if (RxState[instNum]->ElementSize == 4U)
751  {
752  *(uint32_t*)RxState[instNum]->ChnState[i].data = SAI_DRV_RxRead(inst, i);
753  }
754  else
755  {
756  DEV_ASSERT(false);
757  }
758  RxState[instNum]->ChnState[i].data += RxState[instNum]->ElementSize;
759  }
760  }
761  }
762  if (RxState[instNum]->ChnState[0].count <= RX_FIFO_SIZE)
763  {
764  finish = true;
765  RxState[instNum]->ChnState[0].count = 0;
766  }
767  else
768  {
769  RxState[instNum]->ChnState[0].count -= RX_FIFO_SIZE;
770  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE) /* set watermark below normal level */
771  {
772  SAI_DRV_RxSetWatermark(inst, (uint8_t)(RxState[instNum]->ChnState[0].count - 1UL));
773  }
774  }
775  }
776  if (finish)
777  {
778  RxState[instNum]->status = STATUS_SUCCESS;
779  SAI_DRV_RxSetWatermark(inst, RX_WATERMARK);
780  SAI_DRV_RxDisableFifoReqInt(inst);
781  if (RxState[instNum]->Blocking)
782  {
783  (void)OSIF_SemaPost(&RxState[instNum]->Sema);
784  }
785  else
786  {
787  if (RxState[instNum]->Callback != NULL)
788  {
789  RxState[instNum]->Callback(0U, SAI_TRANSFER_COMPLETE, STATUS_SUCCESS);
790  }
791  }
792  }
793  }
794  }
795  if (RxState[instNum]->Callback != NULL)
796  {
797  if (SAI_DRV_RxGetFifoErrorFlag(inst))
798  {
799  for (i = 0; i < sai_channel_count[instNum]; i++)
800  {
801  if (SAI_DRV_IsRxChannelEnabled(inst, i))
802  {
803  if (SAI_DRV_IsRxFifoFull(inst, i))
804  {
805  RxState[instNum]->Callback(i, SAI_RUN_ERROR, STATUS_ERROR);
806  }
807  }
808  SAI_DRV_RxClearFlag (inst, SAI_RCSR_FEF_SHIFT);
809  }
810  }
811  if (SAI_DRV_RxGetWordStartFlag(inst))
812  {
813  RxState[instNum]->Callback(0U, SAI_FRAME_START, STATUS_SUCCESS);
814  SAI_DRV_RxClearFlag (inst, SAI_RCSR_WSF_SHIFT);
815  }
816  if (SAI_DRV_RxGetSyncErrorFlag(inst))
817  {
818  RxState[instNum]->Callback(0U, SAI_SYNC_ERROR, STATUS_ERROR);
819  SAI_DRV_RxClearFlag (inst, SAI_RCSR_SEF_SHIFT);
820  }
821  }
822 }
823 
824 /*FUNCTION**********************************************************************
825  *
826  * Function Name : SAI_DRV_TxSendInt
827  * Description : Start sending data using interrupt, return immediately
828  *
829  *END**************************************************************************/
830 static void SAI_DRV_SendInt(uint32_t instNum,
831  const uint8_t* data[],
832  uint32_t count)
833 {
834  SAI_Type* inst = SAIBase[instNum];
835  uint8_t i;
836  uint8_t c = 0;
837 
838  TxState[instNum]->status = STATUS_BUSY;
839  if (TxState[instNum]->mux == SAI_MUX_LINE)
840  {
841  for (i = 0; i < TxState[instNum]->ChannelCount; i++)
842  {
843  DEV_ASSERT(data[i] != NULL);
844  /* cast to non-const type to avoid compile error/warning */
845  TxState[instNum]->ChnState[i].data = (uint8_t*) data[i];
846  }
847  TxState[instNum]->ChnState[0].count = count * TxState[instNum]->ChannelCount;
848  }
849  else if (TxState[instNum]->mux == SAI_MUX_MEM)
850  {
851  DEV_ASSERT(data[0] != NULL);
852  /* cast to non-const type to avoid compile error/warning */
853  TxState[instNum]->ChnState[0].data = (uint8_t*) data[0];
854  TxState[instNum]->ChnState[0].count = count;
855  }
856  else
857  {
858  for (i = 0; i < sai_channel_count[instNum]; i++)
859  {
860  if (SAI_DRV_IsTxChannelEnabled(inst, i))
861  {
862  DEV_ASSERT(data[c] != NULL);
863  /* cast to non-const type to avoid compile error/warning */
864  TxState[instNum]->ChnState[i].data = (uint8_t*) data[c];
865  c++;
866  }
867  }
868  TxState[instNum]->ChnState[0].count = count;
869  }
870  SAI_DRV_TxEnableFifoReqInt(inst);
871 }
872 
873 /*FUNCTION**********************************************************************
874  *
875  * Function Name : SAI_DRV_SendDMA
876  * Description : Start sending data using dma, return immediately
877  *
878  *END**************************************************************************/
879 static void SAI_DRV_SendDma(uint32_t instNum,
880  const uint8_t* data[],
881  uint32_t count)
882 {
883  SAI_Type* inst = SAIBase[instNum];
884  uint8_t i;
885  uint8_t c;
887  uint8_t numChan = 0;
888  uint32_t temp;
889 
890  if (TxState[instNum]->ElementSize == 1U)
891  {
892  xferSize = EDMA_TRANSFER_SIZE_1B;
893  }
894  else if (TxState[instNum]->ElementSize == 2U)
895  {
896  xferSize = EDMA_TRANSFER_SIZE_2B;
897  }
898  else if (TxState[instNum]->ElementSize == 4U)
899  {
900  xferSize = EDMA_TRANSFER_SIZE_4B;
901  }
902  else
903  {
904  DEV_ASSERT(false);
905  }
906  TxState[instNum]->status = STATUS_BUSY;
907  if ((TxState[instNum]->mux == SAI_MUX_LINE) || (TxState[instNum]->mux == SAI_MUX_DISABLED))
908  {
909  c = 0;
910  for (i = 0; i < sai_channel_count[instNum]; i++)
911  {
912  if (SAI_DRV_IsTxChannelEnabled(inst, i))
913  {
914  DEV_ASSERT(data[c] != NULL);
915  TxState[instNum]->ChnState[i].count = count;
916  (void)EDMA_DRV_ConfigMultiBlockTransfer(TxState[instNum]->DmaChannel[c], EDMA_TRANSFER_MEM2PERIPH,
917  (uint32_t)data[c], (uint32_t)(&(inst->TDR[i])), xferSize,
918  TxState[instNum]->ElementSize, count, true);
919 
920  /* Call driver function to end the transmission when the DMA transfer is done */
921  (void)EDMA_DRV_InstallCallback(TxState[instNum]->DmaChannel[c],
922  (edma_callback_t)(SAI_DRV_CompleteSendDataUsingDma),
923  (void*)(instNum | ((uint32_t)i << 16U) | ((uint32_t)c << 8U)));
924  /* Start the DMA channel */
925  (void)EDMA_DRV_StartChannel(TxState[instNum]->DmaChannel[c]);
926  c++;
927  }
928  }
929  }
930  else if (TxState[instNum]->mux == SAI_MUX_MEM)
931  {
932  DEV_ASSERT(data[0] != NULL);
933  for (i = 0; i < sai_channel_count[instNum]; i++)
934  {
935  if (SAI_DRV_IsTxChannelEnabled(inst, i))
936  {
937  numChan++;
938  }
939  }
940  temp = count * numChan;
941  TxState[instNum]->ChnState[0].count = count;
942 
943  (void)EDMA_DRV_ConfigMultiBlockTransfer(TxState[instNum]->DmaChannel[0], EDMA_TRANSFER_MEM2PERIPH,
944  (uint32_t)data[0], (uint32_t)(&(inst->TDR[0])), xferSize,
945  TxState[instNum]->ElementSize, temp, true);
946 
947  /* Call driver function to end the transmission when the DMA transfer is done */
948  (void)EDMA_DRV_InstallCallback(TxState[instNum]->DmaChannel[0],
949  (edma_callback_t)(SAI_DRV_CompleteSendDataUsingDma),
950  (void*)(instNum));
951  /* Start the DMA channel */
952  (void)EDMA_DRV_StartChannel(TxState[instNum]->DmaChannel[0]);
953  }
954  else
955  {
956  /* do nothing */
957  }
958  /* Enable tx DMA requests for the current instance */
959  SAI_DRV_TxEnableFifoReqDma(inst);
960 }
961 
962 /*FUNCTION**********************************************************************
963  *
964  * Function Name : SAI_DRV_RxReceiveInt
965  * Description : Start receiving data using interrupt, return immediately
966  *
967  *END**************************************************************************/
968 static void SAI_DRV_ReceiveInt(uint32_t instNum,
969  uint8_t* data[],
970  uint32_t count)
971 {
972  SAI_Type* inst = SAIBase[instNum];
973  uint8_t i;
974  uint8_t c = 0;
975 
976  RxState[instNum]->status = STATUS_BUSY;
977  if (RxState[instNum]->mux == SAI_MUX_LINE)
978  {
979  for (i = 0; i < RxState[instNum]->ChannelCount; i++)
980  {
981  DEV_ASSERT(data[i] != NULL);
982  RxState[instNum]->ChnState[i].data = data[i];
983  }
984  RxState[instNum]->ChnState[0].count = RxState[instNum]->ChannelCount * count;
985  if (RxState[instNum]->ChnState[0].count < RX_FIFO_SIZE)
986  {
987  SAI_DRV_RxSetWatermark(inst, (uint8_t)(RxState[instNum]->ChnState[0].count - 1UL));
988  }
989  else
990  {
991  SAI_DRV_RxSetWatermark(inst, RX_WATERMARK);
992  }
993  }
994  else if (RxState[instNum]->mux == SAI_MUX_MEM)
995  {
996  DEV_ASSERT(data[0] != NULL);
997  RxState[instNum]->ChnState[0].data = data[0];
998  RxState[instNum]->ChnState[0].count = count;
999  if (count < RX_FIFO_SIZE)
1000  {
1001  SAI_DRV_RxSetWatermark(inst, (uint8_t)(RxState[instNum]->ChnState[0].count - 1UL));
1002  }
1003  else
1004  {
1005  SAI_DRV_RxSetWatermark(inst, RX_WATERMARK);
1006  }
1007  }
1008  else
1009  {
1010  for (i = 0; i < sai_channel_count[instNum]; i++)
1011  {
1012  if (SAI_DRV_IsRxChannelEnabled(inst, i))
1013  {
1014  DEV_ASSERT(data[c] != NULL);
1015  RxState[instNum]->ChnState[i].data = data[c];
1016  c++;
1017  }
1018  }
1019  RxState[instNum]->ChnState[0].count = count;
1020  if (count < RX_FIFO_SIZE)
1021  {
1022  SAI_DRV_RxSetWatermark(inst, (uint8_t) (count - 1UL));
1023  }
1024  else
1025  {
1026  SAI_DRV_RxSetWatermark(inst, RX_WATERMARK);
1027  }
1028  }
1029  SAI_DRV_RxEnableFifoReqInt(inst);
1030 }
1031 
1032 /*FUNCTION**********************************************************************
1033  *
1034  * Function Name : SAI_DRV_ReceiveDMA
1035  * Description : Start receiving data using dma, return immediately
1036  *
1037  *END**************************************************************************/
1038 static void SAI_DRV_ReceiveDma(uint32_t instNum,
1039  uint8_t* data[],
1040  uint32_t count)
1041 {
1042  SAI_Type* inst = SAIBase[instNum];
1043  uint8_t i;
1044  uint8_t c;
1046  uint8_t numChan = 0;
1047  uint32_t temp;
1048 
1049  if (RxState[instNum]->ElementSize == 1U)
1050  {
1051  xferSize = EDMA_TRANSFER_SIZE_1B;
1052  }
1053  else if (RxState[instNum]->ElementSize == 2U)
1054  {
1055  xferSize = EDMA_TRANSFER_SIZE_2B;
1056  }
1057  else if (RxState[instNum]->ElementSize == 4U)
1058  {
1059  xferSize = EDMA_TRANSFER_SIZE_4B;
1060  }
1061  else
1062  {
1063  DEV_ASSERT(false);
1064  }
1065  RxState[instNum]->status = STATUS_BUSY;
1066  if ((RxState[instNum]->mux == SAI_MUX_LINE) || (RxState[instNum]->mux == SAI_MUX_DISABLED))
1067  {
1068  c = 0;
1069  for (i = 0; i < sai_channel_count[instNum]; i++)
1070  {
1071  if (SAI_DRV_IsRxChannelEnabled(inst, i))
1072  {
1073  DEV_ASSERT(data[c] != NULL);
1074  RxState[instNum]->ChnState[i].count = count;
1075  (void)EDMA_DRV_ConfigMultiBlockTransfer(RxState[instNum]->DmaChannel[c], EDMA_TRANSFER_PERIPH2MEM,
1076  (uint32_t)(&(inst->RDR[i])), (uint32_t)data[c], xferSize,
1077  RxState[instNum]->ElementSize, count, true);
1078 
1079  /* Call driver function to end the transmission when the DMA transfer is done */
1080  (void)EDMA_DRV_InstallCallback(RxState[instNum]->DmaChannel[c],
1081  (edma_callback_t)(SAI_DRV_CompleteReceiveDataUsingDma),
1082  (void*)(instNum | ((uint32_t)i << 16U) | ((uint32_t)c << 8U)));
1083  /* Start the DMA channel */
1084  (void)EDMA_DRV_StartChannel(RxState[instNum]->DmaChannel[c]);
1085  c++;
1086  }
1087  }
1088  }
1089  else if (RxState[instNum]->mux == SAI_MUX_MEM)
1090  {
1091  DEV_ASSERT(data[0] != NULL);
1092  for (i = 0; i < sai_channel_count[instNum]; i++)
1093  {
1094  if (SAI_DRV_IsRxChannelEnabled(inst, i))
1095  {
1096  numChan++;
1097  }
1098  }
1099  temp = count * numChan;
1100  RxState[instNum]->ChnState[0].count = count;
1101 
1102  (void)EDMA_DRV_ConfigMultiBlockTransfer(RxState[instNum]->DmaChannel[0], EDMA_TRANSFER_PERIPH2MEM,
1103  (uint32_t)(&(inst->RDR[0])), (uint32_t)data[0], xferSize,
1104  RxState[instNum]->ElementSize, temp, true);
1105 
1106  /* Call driver function to end the transmission when the DMA transfer is done */
1107  (void)EDMA_DRV_InstallCallback(RxState[instNum]->DmaChannel[0],
1108  (edma_callback_t)(SAI_DRV_CompleteReceiveDataUsingDma),
1109  (void*)(instNum));
1110  /* Start the DMA channel */
1111  (void)EDMA_DRV_StartChannel(RxState[instNum]->DmaChannel[0]);
1112  }
1113  else
1114  {
1115  DEV_ASSERT(false);
1116  }
1117  /* Enable rx DMA requests for the current instance */
1118  SAI_DRV_RxEnableFifoReqDma(inst);
1119 }
1120 
1121 /*******************************************************************************
1122  * Code
1123  ******************************************************************************/
1124 /*FUNCTION**********************************************************************
1125 *
1126 * Function Name : SAI_DRV_TxInit
1127 * Description : Init tx core
1128 * These params are set by driver:
1129 * bool BIT_CLK_SWAP = false < Enable or disable bit clock swap mode.>
1130 * bool BIT_CLK_AS_EXTERNAL = false; < Delay internal clock as if clock is generated externally.>
1131 * uint8_t BitClkDiv = calculate for nearest value to user config value,
1132 * only set by driver if master clock and bit clock is internal, otherwise set by user
1133 * < If bit clock is internal, it is divided from master clock by this.>
1134 * uint8_t WORD_FLAG_INDEX = 0; < Index of word in frame that raise word start flag.>
1135 * bool CONT_ON_ERROR = true; < Continue on fifo error.>
1136 * sai_combine_mode CombineMode = combine line or combine memory, user choice
1137 * < Select fifo combine mode.>
1138 * sai_packing_mode PACK_MODE = false; < Select fifo pack mode.>
1139 * bool SYNC_ON_DEMAND; = false < Generate frame sync only when fifo is not empty (transmit)
1140 * or not full (receive).>
1141 * Implements : SAI_DRV_TxInit_Activity
1142 *END*************************************************************************/
1143 void SAI_DRV_TxInit(uint32_t instNum,
1144  const sai_user_config_t* saiUserConfig,
1145  sai_state_t* StateAlloc)
1146 {
1147  SAI_Type* inst = SAIBase[instNum];
1148 
1149  DEV_ASSERT(saiUserConfig != NULL);
1150  DEV_ASSERT(StateAlloc != NULL);
1151  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1152  DEV_ASSERT((saiUserConfig->FrameSize <= (1U << (SAI_DRV_GetParamFrameSize(inst)))) && (saiUserConfig->FrameSize > 0U));
1153  /* if sync with other, receiver must be async and enabled */
1154 #ifdef DEV_ERROR_DETECT
1155  uint32_t temp = inst->RCSR;
1156  uint32_t temp2 = inst->RCR2;
1157  DEV_ASSERT((saiUserConfig->SyncMode == SAI_ASYNC) || ((saiUserConfig->SyncMode == SAI_SYNC_WITH_OTHER) && ((temp2 & SAI_RCR2_SYNC_MASK) == 0U) && ((temp & SAI_RCSR_RE_MASK) != 0U)));
1158 #endif /* DEV_ERROR_DETECT */
1159  DEV_ASSERT(saiUserConfig->Word0Width > 0U);
1160  DEV_ASSERT(saiUserConfig->WordNWidth > 0U);
1161  DEV_ASSERT(saiUserConfig->SyncWidth > 0U);
1162  DEV_ASSERT(saiUserConfig->FirstBitIndex < 32U);
1163  DEV_ASSERT((saiUserConfig->MuxMode != SAI_MUX_LINE) || (saiUserConfig->TransferType != SAI_INTERRUPT) ||
1164  ((saiUserConfig->MuxMode == SAI_MUX_LINE) && (saiUserConfig->ChannelCount > 0U) &&
1165  ((saiUserConfig->FrameSize % saiUserConfig->ChannelCount) == 0U) && (saiUserConfig->TransferType == SAI_INTERRUPT)));
1166  DEV_ASSERT((saiUserConfig->ElementSize == 1U) || (saiUserConfig->ElementSize == 2U) || (saiUserConfig->ElementSize == 4U));
1167 
1168  uint32_t SourceClock = 0U;
1169  uint32_t divisor = 0U;
1170  uint8_t CombineMode = 0U;
1171  status_t osifError = STATUS_SUCCESS;
1172  uint8_t i;
1173  uint8_t channel = 0U;
1174 
1175  /* Get clock as configured in the clock manager */
1176  if (saiUserConfig->MasterClkSrc == SAI_SOSC_CLK)
1177  {
1178  (void)CLOCK_SYS_GetFreq(SOSC_CLK, &SourceClock);
1179  DEV_ASSERT(SourceClock > 0U);
1180  }
1181  else if (saiUserConfig->MasterClkSrc == SAI_BUS_CLK)
1182  {
1183  (void)CLOCK_SYS_GetFreq(BUS_CLK, &SourceClock);
1184  DEV_ASSERT(SourceClock > 0U);
1185  }
1186  else
1187  {
1188  /* do nothing */
1189  }
1190  /* Check if current instance is clock gated off. */
1191  DEV_ASSERT(CLOCK_SYS_GetFreq(SAIClkNames[instNum], NULL) == STATUS_SUCCESS);
1192 
1193  TxState[instNum] = StateAlloc;
1194  SAI_DRV_TxResetVar(instNum);
1195  /* calculate divisor parameter */
1196  if (saiUserConfig->SyncMode != SAI_SYNC_WITH_OTHER)
1197  {
1198  if ((saiUserConfig->MasterClkSrc != SAI_EXTERNAL_CLK) && (saiUserConfig->BitClkInternal == true))
1199  {
1200  DEV_ASSERT(saiUserConfig->BitClkFreq != 0U);
1201  divisor = ((SourceClock / saiUserConfig->BitClkFreq) / 2UL) - 1UL;
1202  if (divisor > 255U)
1203  {
1204  divisor = 255U;
1205  }
1206  }
1207  else
1208  {
1209  divisor = ((uint32_t)saiUserConfig->BitClkDiv / 2UL) - 1UL;
1210  }
1211  }
1212  TxState[instNum]->ElementSize = saiUserConfig->ElementSize;
1213  TxState[instNum]->XferType = saiUserConfig->TransferType;
1214  TxState[instNum]->mux = saiUserConfig->MuxMode;
1215  if (saiUserConfig->TransferType == SAI_DMA)
1216  {
1217  for (i = 0; i < sai_channel_count[instNum]; i++)
1218  {
1219  TxState[instNum]->DmaChannel[i] = saiUserConfig->DmaChannel[i];
1220  }
1221  CombineMode = (uint8_t)saiUserConfig->MuxMode;
1222  }
1223  else
1224  {
1225  CombineMode = 0U; /* emulate combine mode */
1226  TxState[instNum]->ChannelCount = saiUserConfig->ChannelCount;
1227  }
1228  channel = saiUserConfig->ChannelEnable;
1229  osifError = OSIF_SemaCreate(&TxState[instNum]->Sema, 0U);
1230  DEV_ASSERT(osifError == STATUS_SUCCESS);
1231  inst->TCSR = SAI_TCSR_SR(1U); /* call reset bit, reset fifo and logic */
1232  inst->TCSR = SAI_TCSR_FEIE(TO_BIT(saiUserConfig->RunErrorReport)) |
1233  SAI_TCSR_SEIE(TO_BIT(saiUserConfig->SyncErrorReport)) |
1234  SAI_TCSR_WSIE(TO_BIT(saiUserConfig->FrameStartReport));
1235  TxState[instNum]->Callback = saiUserConfig->callback;
1236  inst->TCR1 = SAI_TCR1_TFW(TX_WATERMARK);
1237  inst->TCR2 = SAI_TCR2_SYNC(saiUserConfig->SyncMode) |
1238  SAI_TCR2_BCS(TO_BIT(BIT_CLK_SWAP)) |
1239  SAI_TCR2_BCI(TO_BIT(BIT_CLK_AS_EXTERNAL)) |
1240  SAI_TCR2_MSEL(saiUserConfig->MasterClkSrc) |
1241  SAI_TCR2_BCP(TO_BIT(saiUserConfig->BitClkNegPolar)) |
1242  SAI_TCR2_BCD(TO_BIT(saiUserConfig->BitClkInternal)) |
1243  SAI_TCR2_DIV((uint8_t) divisor);
1244  inst->TCR3 = SAI_TCR3_TCE(channel) |
1245  SAI_TCR3_WDFL(WORD_FLAG_INDEX);
1246  inst->TCR4 = SAI_TCR4_FCONT(TO_BIT(CONT_ON_ERROR)) |
1247  SAI_TCR4_FCOMB(CombineMode) |
1248  SAI_TCR4_FPACK(PACK_MODE) |
1249  SAI_TCR4_FRSZ((uint32_t)saiUserConfig->FrameSize - 1U) |
1250  SAI_TCR4_SYWD((uint32_t)saiUserConfig->SyncWidth - 1U) |
1251  SAI_TCR4_CHMOD(saiUserConfig->MaskMode) |
1252  SAI_TCR4_MF(TO_BIT(saiUserConfig->MsbFirst)) |
1253  SAI_TCR4_FSE(TO_BIT(saiUserConfig->SyncEarly)) |
1254  SAI_TCR4_ONDEM(TO_BIT(SYNC_ON_DEMAND)) |
1255  SAI_TCR4_FSP(TO_BIT(saiUserConfig->SyncNegPolar)) |
1256  SAI_TCR4_FSD(TO_BIT(saiUserConfig->SyncInternal));
1257  inst->TCR5 = SAI_TCR5_WNW((uint32_t)saiUserConfig->WordNWidth - 1U) |
1258  SAI_TCR5_W0W((uint32_t)saiUserConfig->Word0Width - 1U) |
1259  SAI_TCR5_FBT(saiUserConfig->MsbFirst ? ~(31U - (uint32_t)saiUserConfig->FirstBitIndex) : (uint32_t)saiUserConfig->FirstBitIndex);
1260  if ((saiUserConfig->TransferType == SAI_INTERRUPT) || (saiUserConfig->RunErrorReport) ||
1261  (saiUserConfig->SyncErrorReport) || (saiUserConfig->FrameStartReport))
1262  {
1263  INT_SYS_EnableIRQ(SAITxIrqId[instNum]);
1264  };
1265  inst->TCSR &= ~SAI_TCSR_SR_MASK;
1266  inst->TCSR |= SAI_TCSR_TE(1U);
1267 }
1268 
1269 /*FUNCTION**********************************************************************
1270 *
1271 * Function Name : SAI_DRV_RxInit
1272 * Description : Init rx core
1273 * These params are set by driver:
1274 * Others are the same as TxInit
1275 * Implements : SAI_DRV_RxInit_Activity
1276 *END*************************************************************************/
1277 void SAI_DRV_RxInit(uint32_t instNum,
1278  const sai_user_config_t* saiUserConfig,
1279  sai_state_t* StateAlloc)
1280 {
1281  SAI_Type* inst = SAIBase[instNum];
1282 
1283  DEV_ASSERT(saiUserConfig != NULL);
1284  DEV_ASSERT(StateAlloc != NULL);
1285  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1286  DEV_ASSERT((saiUserConfig->FrameSize <= (1U << (SAI_DRV_GetParamFrameSize(inst)))) && (saiUserConfig->FrameSize > 0U));
1287  /* if sync with other, trasnmiter must be async and enabled */
1288 #ifdef DEV_ERROR_DETECT
1289  uint32_t temp = inst->TCSR;
1290  uint32_t temp2 = inst->TCR2;
1291  DEV_ASSERT((saiUserConfig->SyncMode == SAI_ASYNC) || ((saiUserConfig->SyncMode == SAI_SYNC_WITH_OTHER) && ((temp2 & SAI_TCR2_SYNC_MASK) == 0U) && ((temp & SAI_TCSR_TE_MASK) != 0U)));
1292 #endif /* DEV_ERROR_DETECT */
1293  DEV_ASSERT(saiUserConfig->Word0Width > 0U);
1294  DEV_ASSERT(saiUserConfig->WordNWidth > 0U);
1295  DEV_ASSERT(saiUserConfig->SyncWidth > 0U);
1296  DEV_ASSERT(saiUserConfig->FirstBitIndex < 32U);
1297  DEV_ASSERT((saiUserConfig->MuxMode != SAI_MUX_LINE) || (saiUserConfig->TransferType != SAI_INTERRUPT) ||
1298  ((saiUserConfig->MuxMode == SAI_MUX_LINE) && (saiUserConfig->ChannelCount > 0U) &&
1299  ((saiUserConfig->FrameSize % saiUserConfig->ChannelCount) == 0U) && (saiUserConfig->TransferType == SAI_INTERRUPT)));
1300  DEV_ASSERT((saiUserConfig->ElementSize == 1U) || (saiUserConfig->ElementSize == 2U) || (saiUserConfig->ElementSize == 4U));
1301 
1302  uint32_t SourceClock = 0U;
1303  uint32_t divisor = 0U;
1304  uint8_t CombineMode = 0U;
1305  status_t osifError = STATUS_SUCCESS;
1306  uint8_t i;
1307  uint8_t channel = 0U;
1308 
1309  /* Get clock as configured in the clock manager */
1310  if (saiUserConfig->MasterClkSrc == SAI_SOSC_CLK)
1311  {
1312  (void)CLOCK_SYS_GetFreq(SOSC_CLK, &SourceClock);
1313  DEV_ASSERT(SourceClock > 0U);
1314  }
1315  else if (saiUserConfig->MasterClkSrc == SAI_BUS_CLK)
1316  {
1317  (void)CLOCK_SYS_GetFreq(BUS_CLK, &SourceClock);
1318  DEV_ASSERT(SourceClock > 0U);
1319  }
1320  else
1321  {
1322  /* do nothing */
1323  }
1324  /* Check if current instance is clock gated off. */
1325  DEV_ASSERT(CLOCK_SYS_GetFreq(SAIClkNames[instNum], NULL) == STATUS_SUCCESS);
1326 
1327  RxState[instNum] = StateAlloc;
1328  SAI_DRV_RxResetVar(instNum);
1329  /* calculate divisor parameter */
1330  if (saiUserConfig->SyncMode != SAI_SYNC_WITH_OTHER)
1331  {
1332  if ((saiUserConfig->MasterClkSrc != SAI_EXTERNAL_CLK) && (saiUserConfig->BitClkInternal == true))
1333  {
1334  DEV_ASSERT(saiUserConfig->BitClkFreq != 0U);
1335  divisor = ((SourceClock / saiUserConfig->BitClkFreq) / 2UL) - 1UL;
1336  if (divisor > 255U)
1337  {
1338  divisor = 255U;
1339  }
1340  }
1341  else
1342  {
1343  divisor = ((uint32_t)saiUserConfig->BitClkDiv / 2UL) - 1UL;
1344  }
1345  }
1346  RxState[instNum]->ElementSize = saiUserConfig->ElementSize;
1347  RxState[instNum]->XferType = saiUserConfig->TransferType;
1348  RxState[instNum]->mux = saiUserConfig->MuxMode;
1349  if (saiUserConfig->TransferType == SAI_DMA)
1350  {
1351  for (i = 0; i < sai_channel_count[instNum]; i++)
1352  {
1353  RxState[instNum]->DmaChannel[i] = saiUserConfig->DmaChannel[i];
1354  }
1355  CombineMode = (uint8_t)saiUserConfig->MuxMode;
1356  }
1357  else
1358  {
1359  CombineMode = 0U; /* emulate combine mode */
1360  RxState[instNum]->ChannelCount = saiUserConfig->ChannelCount;
1361  }
1362  channel = saiUserConfig->ChannelEnable;
1363  osifError = OSIF_SemaCreate(&RxState[instNum]->Sema, 0U);
1364  DEV_ASSERT(osifError == STATUS_SUCCESS);
1365  inst->RCSR = SAI_RCSR_SR(1UL); /* call reset bit, reset fifo and logic */
1366  inst->RCSR = SAI_RCSR_FEIE(TO_BIT(saiUserConfig->RunErrorReport)) |
1367  SAI_RCSR_SEIE(TO_BIT(saiUserConfig->SyncErrorReport)) |
1368  SAI_RCSR_WSIE(TO_BIT(saiUserConfig->FrameStartReport));
1369  RxState[instNum]->Callback = saiUserConfig->callback;
1370  inst->RCR1 = SAI_RCR1_RFW((saiUserConfig->TransferType == SAI_DMA) ? 0UL : RX_WATERMARK);
1371  inst->RCR2 = SAI_RCR2_SYNC(saiUserConfig->SyncMode) |
1372  SAI_RCR2_BCS(TO_BIT(BIT_CLK_SWAP)) |
1373  SAI_RCR2_BCI(TO_BIT(BIT_CLK_AS_EXTERNAL)) |
1374  SAI_RCR2_MSEL(saiUserConfig->MasterClkSrc) |
1375  SAI_RCR2_BCP(TO_BIT(saiUserConfig->BitClkNegPolar)) |
1376  SAI_RCR2_BCD(TO_BIT(saiUserConfig->BitClkInternal)) |
1377  SAI_RCR2_DIV((uint8_t) divisor);
1378  inst->RCR3 = SAI_RCR3_RCE(channel) |
1379  SAI_RCR3_WDFL(WORD_FLAG_INDEX);
1380  inst->RCR4 = SAI_RCR4_FCONT(TO_BIT(CONT_ON_ERROR)) |
1381  SAI_RCR4_FCOMB(CombineMode) |
1382  SAI_RCR4_FPACK(PACK_MODE) |
1383  SAI_RCR4_FRSZ(saiUserConfig->FrameSize - 1UL) |
1384  SAI_RCR4_SYWD(saiUserConfig->SyncWidth - 1UL) |
1385  SAI_RCR4_MF(TO_BIT(saiUserConfig->MsbFirst)) |
1386  SAI_RCR4_FSE(TO_BIT(saiUserConfig->SyncEarly)) |
1387  SAI_RCR4_ONDEM(TO_BIT(SYNC_ON_DEMAND)) |
1388  SAI_RCR4_FSP(TO_BIT(saiUserConfig->SyncNegPolar)) |
1389  SAI_RCR4_FSD(TO_BIT(saiUserConfig->SyncInternal));
1390  inst->RCR5 = SAI_RCR5_WNW((uint32_t)saiUserConfig->WordNWidth - 1UL) |
1391  SAI_RCR5_W0W((uint32_t)saiUserConfig->Word0Width - 1UL) |
1392  SAI_RCR5_FBT(saiUserConfig->MsbFirst ? ~(31UL - (uint32_t)saiUserConfig->FirstBitIndex) : (uint32_t)saiUserConfig->FirstBitIndex);
1393  if ((saiUserConfig->TransferType == SAI_INTERRUPT) || (saiUserConfig->RunErrorReport) ||
1394  (saiUserConfig->SyncErrorReport) || (saiUserConfig->FrameStartReport))
1395  {
1396  INT_SYS_EnableIRQ(SAIRxIrqId[instNum]);
1397  };
1398  inst->RCSR &= ~SAI_RCSR_SR_MASK;
1399  inst->RCSR |= SAI_RCSR_RE(1U);
1400 }
1401 
1402 /*FUNCTION**********************************************************************
1403  *
1404  * Function Name : SAI_DRV_TxDeinit
1405  * Description : DeInit tx core
1406  * Implements : SAI_DRV_TxDeinit_Activity
1407  *
1408  *END**************************************************************************/
1409 void SAI_DRV_TxDeinit(uint32_t instNum)
1410 {
1411  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1412 
1413  SAI_Type* inst = SAIBase[instNum];
1414  inst->TCSR = 0; /* clear all interrupt enable bits */
1415  inst->TCSR = SAI_TCSR_SR(1U); /* call reset bit*/
1416  inst->TMR = 0; /* reset mask bits */
1417  if (RxState[instNum]->XferType == SAI_INTERRUPT)
1418  {
1419  /* Disable interrupt. */
1420  INT_SYS_DisableIRQ(SAITxIrqId[instNum]);
1421  }
1422  (void)OSIF_SemaDestroy(&RxState[instNum]->Sema);
1423  SAI_DRV_TxResetVar(instNum);
1424 }
1425 
1426 /*FUNCTION**********************************************************************
1427  *
1428  * Function Name : SAI_DRV_RxDeinit
1429  * Description : DeInit rx core
1430  * Implements : SAI_DRV_RxDeinit_Activity
1431  *
1432  *END**************************************************************************/
1433 void SAI_DRV_RxDeinit(uint32_t instNum)
1434 {
1435  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1436 
1437  SAI_Type* inst = SAIBase[instNum];
1438  inst->RCSR = 0; /* clear all interrupt enable bits */
1439  inst->RCSR = SAI_RCSR_SR(1U); /* call reset bit*/
1440  inst->RMR = 0; /* reset mask bits */
1441  if (RxState[instNum]->XferType == SAI_INTERRUPT)
1442  {
1443  /* Disable interrupt. */
1444  INT_SYS_DisableIRQ(SAIRxIrqId[instNum]);
1445  }
1446  (void)OSIF_SemaDestroy(&RxState[instNum]->Sema);
1447  SAI_DRV_RxResetVar(instNum);
1448 }
1449 
1450 /*FUNCTION**********************************************************************
1451 *
1452 * Function Name : SAI_DRV_RxGetBitClockFreq
1453 * Description : Return true freq
1454 * Implements : SAI_DRV_RxGetBitClockFreq_Activity
1455 *
1456 *END**************************************************************************/
1457 uint32_t SAI_DRV_RxGetBitClockFreq(uint32_t instNum)
1458 {
1459  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1460 
1461  const SAI_Type* inst = SAIBase[instNum];
1462  uint32_t div;
1463  uint32_t SourceClock = 0U;
1464  uint32_t ClockSetting;
1465 
1466  /* check if sync with other */
1467  DEV_ASSERT ((inst->RCR2 & SAI_RCR2_SYNC_MASK) == 0U);
1468  /* check if external master clock or external bit clock */
1469 #ifdef DEV_ERROR_DETECT
1470  uint32_t temp = inst->RCR2;
1471  DEV_ASSERT (((temp & SAI_RCR2_MSEL_MASK) != SAI_RCR2_MSEL(1U)) && ((temp & SAI_RCR2_BCD_MASK) == SAI_RCR2_BCD(1U)));
1472 #endif /* DEV_ERROR_DETECT */
1473  /* Get clock as configured */
1474  ClockSetting = (inst->RCR2 & SAI_RCR2_MSEL_MASK) >> SAI_RCR2_MSEL_SHIFT;
1475  if (ClockSetting == (uint32_t) SAI_BUS_CLK)
1476  {
1477  (void)CLOCK_SYS_GetFreq(BUS_CLK, &SourceClock);
1478  }
1479  else if (ClockSetting == (uint32_t) SAI_SOSC_CLK)
1480  {
1481  (void)CLOCK_SYS_GetFreq(SOSC_CLK, &SourceClock);
1482  }
1483  else
1484  {
1485  /* do nothing */
1486  }
1487  div = SAI_DRV_RxGetBitClockDiv(instNum);
1488  return SourceClock / div;
1489 }
1490 
1491 /*FUNCTION**********************************************************************
1492 *
1493 * Function Name : SAI_DRV_TxGetBitClockFreq
1494 * Description : Return true freq
1495 * Implements : SAI_DRV_TxGetBitClockFreq_Activity
1496 *
1497 *END**************************************************************************/
1498 uint32_t SAI_DRV_TxGetBitClockFreq(uint32_t instNum)
1499 {
1500  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1501 
1502  const SAI_Type* inst = SAIBase[instNum];
1503  uint32_t div;
1504  uint32_t SourceClock = 0U;
1505  uint32_t ClockSetting;
1506 
1507  /* check if sync with other */
1508  DEV_ASSERT ((inst->TCR2 & SAI_TCR2_SYNC_MASK) == 0U);
1509  /* check if external master clock or external bit clock */
1510 #ifdef DEV_ERROR_DETECT
1511  uint32_t temp = inst->TCR2;
1512  DEV_ASSERT (((temp & SAI_TCR2_MSEL_MASK) != SAI_TCR2_MSEL(1U)) && ((temp & SAI_TCR2_BCD_MASK) == SAI_TCR2_BCD(1U)));
1513 #endif /* DEV_ERROR_DETECT */
1514 
1515  /* Get clock as configured */
1516  ClockSetting = (inst->TCR2 & SAI_TCR2_MSEL_MASK) >> SAI_TCR2_MSEL_SHIFT;
1517  if (ClockSetting == (uint32_t) SAI_BUS_CLK)
1518  {
1519  (void)CLOCK_SYS_GetFreq(BUS_CLK, &SourceClock);
1520  }
1521  else if (ClockSetting == (uint32_t) SAI_SOSC_CLK)
1522  {
1523  (void)CLOCK_SYS_GetFreq(SOSC_CLK, &SourceClock);
1524  }
1525  else
1526  {
1527  /* do nothing */
1528  }
1529  div = SAI_DRV_TxGetBitClockDiv(instNum);
1530  return SourceClock / div;
1531 }
1532 
1533 /*FUNCTION**********************************************************************
1534 *
1535 * Function Name : SAI_DRV_TxGetBitClockDiv
1536 * Description : Return true divisor
1537 * Implements : SAI_DRV_TxGetBitClockDiv_Activity
1538 *
1539 *END**************************************************************************/
1540 uint32_t SAI_DRV_TxGetBitClockDiv(uint32_t instNum)
1541 {
1542  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1543 
1544  const SAI_Type* inst = SAIBase[instNum];
1545  return (((inst->TCR2 & SAI_TCR2_DIV_MASK) >> SAI_TCR2_DIV_SHIFT) + 1U) * 2U;
1546 }
1547 
1548 /*FUNCTION**********************************************************************
1549 *
1550 * Function Name : SAI_DRV_RxGetBitClockDiv
1551 * Description : Return true divisor
1552 * Implements : SAI_DRV_RxGetBitClockDiv_Activity
1553 *
1554 *END**************************************************************************/
1555 uint32_t SAI_DRV_RxGetBitClockDiv(uint32_t instNum)
1556 {
1557  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1558 
1559  const SAI_Type* inst = SAIBase[instNum];
1560  return (((inst->RCR2 & SAI_RCR2_DIV_MASK) >> SAI_RCR2_DIV_SHIFT) + 1U) * 2U;
1561 }
1562 
1563 /*FUNCTION**********************************************************************
1564 *
1565 * Function Name : SAI_DRV_TxSetMaskWord
1566 * Description : Set next frame masked word index
1567 * Implements : SAI_DRV_TxSetNextMaskWords_Activity
1568 *
1569 *END**************************************************************************/
1570 void SAI_DRV_TxSetNextMaskWords(uint32_t instNum, uint16_t Words)
1571 {
1572  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1573 
1574  SAI_Type* inst = SAIBase[instNum];
1575  inst->TMR = Words;
1576 }
1577 
1578 /*FUNCTION**********************************************************************
1579 *
1580 * Function Name : SAI_DRV_RxSetMaskWord
1581 * Description : Set next frame masked word index
1582 * Implements : SAI_DRV_RxSetNextMaskWords_Activity
1583 *
1584 *END**************************************************************************/
1585 void SAI_DRV_RxSetNextMaskWords(uint32_t instNum, uint16_t Words)
1586 {
1587  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1588 
1589  SAI_Type* inst = SAIBase[instNum];
1590  inst->RMR = Words;
1591 }
1592 
1593 /*****************************SENDING FUNCTIONS************************************************/
1594 /*FUNCTION**********************************************************************
1595  *
1596  * Function Name : SAI_DRV_SendBlocking
1597  * Description : Send block of data, return when finish sending
1598  * Implements : SAI_DRV_SendBlocking_Activity
1599  *
1600  *END**************************************************************************/
1601 status_t SAI_DRV_SendBlocking(uint32_t instNum,
1602  const uint8_t* data[],
1603  uint32_t count,
1604  uint32_t timeout)
1605 {
1606  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1607  DEV_ASSERT(TxState[instNum]->status != STATUS_BUSY);
1608 
1609  status_t res;
1610  status_t osifError;
1611 
1612  TxState[instNum]->Blocking = true;
1613  SAI_DRV_Send (instNum, data, count);
1614  osifError = OSIF_SemaWait(&TxState[instNum]->Sema, timeout);
1615  TxState[instNum]->Blocking = false;
1616  if (osifError == STATUS_TIMEOUT)
1617  {
1618  /* abort current transfer */
1619  SAI_DRV_AbortSending (instNum);
1620  res = STATUS_TIMEOUT;
1621  }
1622  else
1623  {
1624  /* not time out */
1625  res = TxState[instNum]->status;
1626  }
1627 
1628  return res;
1629 }
1630 
1631 /*FUNCTION**********************************************************************
1632  *
1633  * Function Name : SAI_DRV_Send
1634  * Description : Send block of data, return immediately
1635  * Implements : SAI_DRV_Send_Activity
1636  *
1637  *END**************************************************************************/
1638 void SAI_DRV_Send(uint32_t instNum,
1639  const uint8_t* data[],
1640  uint32_t count)
1641 {
1642  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1643  DEV_ASSERT(TxState[instNum]->status != STATUS_BUSY);
1644 
1645  if (TxState[instNum]->XferType == SAI_DMA)
1646  {
1647  SAI_DRV_SendDma(instNum, data, count);
1648  }
1649  else if (TxState[instNum]->XferType == SAI_INTERRUPT)
1650  {
1651  SAI_DRV_SendInt(instNum, data, count);
1652  }
1653  else
1654  {
1655  DEV_ASSERT(false);
1656  }
1657 }
1658 
1659 /*FUNCTION**********************************************************************
1660  *
1661  * Function Name : SAI_DRV_GetSendingStatus
1662  * Description : Get sending status (dma or interrupt)
1663  * Implements : SAI_DRV_GetSendingStatus_Activity
1664  *
1665  *END**************************************************************************/
1666 status_t SAI_DRV_GetSendingStatus(uint32_t instNum,
1667  uint32_t *countRemain)
1668 {
1669  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1670 
1671  status_t ret = STATUS_ERROR;
1672  status_t CurStatus = TxState[instNum]->status;
1673 
1674  if ((CurStatus == STATUS_UNSUPPORTED) || (CurStatus == STATUS_SUCCESS))
1675  {
1676  if (countRemain != NULL)
1677  {
1678  *countRemain = 0;
1679  }
1680  ret = STATUS_SUCCESS;
1681  }
1682  else if (CurStatus == STATUS_ERROR)
1683  {
1684  if (countRemain != NULL)
1685  {
1686  *countRemain = 0;
1687  }
1688  ret = STATUS_ERROR;
1689  }
1690  else if (CurStatus == STATUS_BUSY)
1691  {
1692  if (TxState[instNum]->XferType == SAI_DMA)
1693  {
1694  if (countRemain != NULL)
1695  {
1696  *countRemain = EDMA_DRV_GetRemainingMajorIterationsCount(TxState[instNum]->DmaChannel[0]);
1697  }
1698  }
1699  else
1700  {
1701  if (countRemain != NULL)
1702  {
1703  *countRemain = TxState[instNum]->ChnState[0].count;
1704  }
1705  }
1706  ret = STATUS_BUSY;
1707  }
1708  else if (CurStatus == STATUS_SAI_ABORTED)
1709  {
1710  if (countRemain != NULL)
1711  {
1712  *countRemain = TxState[instNum]->ChnState[0].count;
1713  }
1714  ret = STATUS_SAI_ABORTED;
1715  }
1716  else
1717  {
1718  /* undefined value */
1719  DEV_ASSERT(false);
1720  }
1721  return ret;
1722 }
1723 
1724 /*FUNCTION**********************************************************************
1725  *
1726  * Function Name : SAI_DRV_AbortSending
1727  * Description : Abort ongoing sending (dma or interrupt)
1728  * Implements : SAI_DRV_AbortSending_Activity
1729  *
1730  *END**************************************************************************/
1731 void SAI_DRV_AbortSending(uint32_t instNum)
1732 {
1733  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1734 
1735  SAI_Type* inst = SAIBase[instNum];
1736  uint8_t c = 0;
1737  uint8_t i;
1738 
1739  if (TxState[instNum]->status == STATUS_BUSY)
1740  {
1741  TxState[instNum]->status = STATUS_SAI_ABORTED;
1742  if (TxState[instNum]->XferType == SAI_DMA)
1743  {
1744  TxState[instNum]->ChnState[0].count = EDMA_DRV_GetRemainingMajorIterationsCount(TxState[instNum]->DmaChannel[0]);
1745  /* Disable tx DMA requests for the current instance */
1746  SAI_DRV_TxDisableFifoReqDma(inst);
1747  /* stop all dma channel*/
1748  if ((TxState[instNum]->mux == SAI_MUX_DISABLED) || (TxState[instNum]->mux == SAI_MUX_LINE))
1749  {
1750  for (i = 0; i < sai_channel_count[instNum]; i++)
1751  {
1752  if (SAI_DRV_IsTxChannelEnabled(inst, i))
1753  {
1754  (void)EDMA_DRV_StopChannel(TxState[instNum]->DmaChannel[c]);
1755  c++;
1756  }
1757  }
1758  }
1759  else
1760  {
1761  (void)EDMA_DRV_StopChannel(TxState[instNum]->DmaChannel[0]);
1762  }
1763  }
1764  else
1765  {
1766  SAI_DRV_TxDisableFifoReqInt(inst);
1767  }
1768  SAI_DRV_TxResetFifo(inst);
1769  if (TxState[instNum]->Blocking)
1770  {
1771  (void)OSIF_SemaPost(&TxState[instNum]->Sema);
1772  }
1773  }
1774 }
1775 
1776 /*****************************RECEIVING FUNCTIONS*********************************/
1777 /*FUNCTION**********************************************************************
1778  *
1779  * Function Name : SAI_DRV_ReceiveBlocking
1780  * Description : Receive block of data, return when finish Receiving
1781  * Implements : SAI_DRV_ReceiveBlocking_Activity
1782  *
1783  *END**************************************************************************/
1784 status_t SAI_DRV_ReceiveBlocking(uint32_t instNum,
1785  uint8_t* data[],
1786  uint32_t count,
1787  uint32_t timeout)
1788 {
1789  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1790  DEV_ASSERT(RxState[instNum]->status != STATUS_BUSY);
1791 
1792  status_t res;
1793  status_t osifError;
1794 
1795  RxState[instNum]->Blocking = true;
1796  SAI_DRV_Receive (instNum, data, count);
1797  osifError = OSIF_SemaWait(&RxState[instNum]->Sema, timeout);
1798  RxState[instNum]->Blocking = false;
1799  if (osifError == STATUS_TIMEOUT)
1800  {
1801  /* abort current transfer */
1802  SAI_DRV_AbortReceiving (instNum);
1803  res = STATUS_TIMEOUT;
1804  }
1805  else
1806  {
1807  /* not time out */
1808  res = RxState[instNum]->status;
1809  }
1810 
1811  return res;
1812 }
1813 
1814 /*FUNCTION**********************************************************************
1815  *
1816  * Function Name : SAI_DRV_Send
1817  * Description : Receive block of data, return immediately
1818  * Implements : SAI_DRV_Receive_Activity
1819  *
1820  *END**************************************************************************/
1821 void SAI_DRV_Receive(uint32_t instNum,
1822  uint8_t* data[],
1823  uint32_t count)
1824 {
1825  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1826  DEV_ASSERT(RxState[instNum]->status != STATUS_BUSY);
1827 
1828  if (RxState[instNum]->XferType == SAI_DMA)
1829  {
1830  SAI_DRV_ReceiveDma(instNum, data, count);
1831  }
1832  else if (RxState[instNum]->XferType == SAI_INTERRUPT)
1833  {
1834  SAI_DRV_ReceiveInt(instNum, data, count);
1835  }
1836  else
1837  {
1838  DEV_ASSERT(false);
1839  }
1840 }
1841 
1842 /*FUNCTION**********************************************************************
1843  *
1844  * Function Name : SAI_DRV_GetReceivingStatus
1845  * Description : Get receiving status (dma or interrupt)
1846  * Implements : SAI_DRV_GetReceivingStatus_Activity
1847  *
1848  *END**************************************************************************/
1849 status_t SAI_DRV_GetReceivingStatus(uint32_t instNum,
1850  uint32_t *countRemain)
1851 {
1852  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1853 
1854  status_t ret = STATUS_ERROR;
1855  /* temp variable to avoid status change while checking */
1856  status_t CurStatus = RxState[instNum]->status;
1857 
1858  if ((CurStatus == STATUS_UNSUPPORTED) || (CurStatus == STATUS_SUCCESS))
1859  {
1860  if (countRemain != NULL)
1861  {
1862  *countRemain = 0;
1863  }
1864  ret = STATUS_SUCCESS;
1865  }
1866  else if (CurStatus == STATUS_ERROR)
1867  {
1868  if (countRemain != NULL)
1869  {
1870  *countRemain = 0;
1871  }
1872  ret = STATUS_ERROR;
1873  }
1874  else if (CurStatus == STATUS_BUSY)
1875  {
1876  if (RxState[instNum]->XferType == SAI_DMA)
1877  {
1878  if (countRemain != NULL)
1879  {
1880  *countRemain = EDMA_DRV_GetRemainingMajorIterationsCount(RxState[instNum]->DmaChannel[0]);
1881  }
1882  }
1883  else
1884  {
1885  if (countRemain != NULL)
1886  {
1887  *countRemain = RxState[instNum]->ChnState[0].count;
1888  }
1889  }
1890  ret = STATUS_BUSY;
1891  }
1892  else if (CurStatus == STATUS_SAI_ABORTED)
1893  {
1894  if (countRemain != NULL)
1895  {
1896  *countRemain = RxState[instNum]->ChnState[0].count;
1897  }
1898  ret = STATUS_SAI_ABORTED;
1899  }
1900  else
1901  {
1902  /* undefined value */
1903  DEV_ASSERT(false);
1904  }
1905  return ret;
1906 }
1907 
1908 /*FUNCTION**********************************************************************
1909  *
1910  * Function Name : SAI_DRV_AbortReceiving
1911  * Description : Abort ongoing receiving (dma or interrupt)
1912  * Implements : SAI_DRV_AbortReceiving_Activity
1913  *
1914  *END**************************************************************************/
1915 void SAI_DRV_AbortReceiving(uint32_t instNum)
1916 {
1917  DEV_ASSERT(instNum < SAI_INSTANCE_COUNT);
1918 
1919  SAI_Type* inst = SAIBase[instNum];
1920  uint8_t c = 0;
1921  uint8_t i;
1922 
1923  if (RxState[instNum]->status == STATUS_BUSY)
1924  {
1925  RxState[instNum]->status = STATUS_SAI_ABORTED;
1926  if (RxState[instNum]->XferType == SAI_DMA)
1927  {
1928  RxState[instNum]->ChnState[0].count = EDMA_DRV_GetRemainingMajorIterationsCount(RxState[instNum]->DmaChannel[0]);
1929  /* Disable Rx DMA requests for the current instance */
1930  SAI_DRV_RxDisableFifoReqDma(inst);
1931  /* stop all dma channel*/
1932  if ((RxState[instNum]->mux == SAI_MUX_DISABLED) || (RxState[instNum]->mux == SAI_MUX_LINE))
1933  {
1934  for (i = 0; i < sai_channel_count[instNum]; i++)
1935  {
1936  if (SAI_DRV_IsRxChannelEnabled(inst, i))
1937  {
1938  (void)EDMA_DRV_StopChannel(RxState[instNum]->DmaChannel[c]);
1939  c++;
1940  }
1941  }
1942  }
1943  else
1944  {
1945  (void)EDMA_DRV_StopChannel(RxState[instNum]->DmaChannel[0]);
1946  }
1947  }
1948  else
1949  {
1950  SAI_DRV_RxDisableFifoReqInt(inst);
1951  }
1952  SAI_DRV_RxResetFifo(inst);
1953  if (RxState[instNum]->Blocking)
1954  {
1955  (void)OSIF_SemaPost(&RxState[instNum]->Sema);
1956  }
1957  }
1958 }
1959 
1960 /*FUNCTION**********************************************************************
1961  *
1962  * Function Name : SAI_DRV_GetDefaultConfig
1963  * Description : Init config structure for I2S interface, interrupt,
1964  * internal generated bit clock 1.4112 MHz, 16 bit word,
1965  * 2 channel 1 data line (data line 0), msb first
1966  * Implements : SAI_DRV_GetDefaultConfig_Activity
1967  *
1968  *END**************************************************************************/
1970 {
1971  uc->BitClkInternal = true;
1972  uc->MasterClkSrc = SAI_BUS_CLK;
1973  uc->BitClkNegPolar = false;
1974  uc->BitClkFreq = 1411200U;
1975  uc->ChannelCount = 2U; /* 2 buffer, one for each channel */
1976  uc->ChannelEnable = SAI_CHANNEL_0; /* select data line 0 */
1977  uc->ElementSize = 2U; /* 2 byte to transfer */
1978  uc->FirstBitIndex = 15U; /* first bit to transfer is 15 because of msb first */
1979  uc->FrameSize = 2U; /* 2 word per frame */
1980  uc->FrameStartReport = false;
1982  uc->MsbFirst = true;
1983  uc->MuxMode = SAI_MUX_LINE; /* 2 data buffer is muxed in to one data line */
1984  uc->RunErrorReport = false;
1985  uc->SyncEarly = false;
1986  uc->SyncErrorReport = false;
1987  uc->SyncMode = SAI_ASYNC;
1988  uc->SyncNegPolar = false;
1989  uc->SyncInternal = true;
1990  uc->SyncWidth = 16U; /* sync width is first word */
1992  uc->Word0Width = 16U;
1993  uc->WordNWidth = 16U;
1994  uc->callback = NULL;
1995 }
1996 
1997 /*******************************************************************************
1998  * EOF
1999  ******************************************************************************/
#define SAI_TCSR_WSIE(x)
Definition: S32K148.h:12137
void SAI_DRV_AbortSending(uint32_t instNum)
Abort an ongoing transfer.
uint8_t ElementSize
Definition: sai_driver.h:172
__IO uint32_t RMR
Definition: S32K148.h:12044
__O uint32_t TDR[SAI_TDR_COUNT]
Definition: S32K148.h:12028
#define SAI_RCR3_WDFL(x)
Definition: S32K148.h:12413
#define SAI_CHANNEL_0
Definition: sai_driver.h:46
sai_transfer_type_t TransferType
Definition: sai_driver.h:170
#define SAI_RCR2_MSEL_MASK
Definition: S32K148.h:12393
void SAI_DRV_RxInit(uint32_t instNum, const sai_user_config_t *saiUserConfig, sai_state_t *StateAlloc)
Initialize the receiver of driver.
#define SAI_TCR2_DIV_MASK
Definition: S32K148.h:12184
__IO uint32_t RCR3
Definition: S32K148.h:12037
status_t OSIF_SemaDestroy(const semaphore_t *const pSem)
Destroys a previously created semaphore.
#define SAI_RCSR_SR_MASK
Definition: S32K148.h:12355
sai_sync_mode_t SyncMode
Definition: sai_driver.h:146
status_t SAI_DRV_GetSendingStatus(uint32_t instNum, uint32_t *countRemain)
Get status of a non-blocking transfer.
uint8_t ChannelCount
Definition: sai_driver.h:173
uint32_t EDMA_DRV_GetRemainingMajorIterationsCount(uint8_t channel)
Returns the remaining major loop iteration count.
Definition: edma_driver.c:1141
#define SAI_TCSR_TE(x)
Definition: S32K148.h:12177
#define SAI_TCSR_FEF_SHIFT
Definition: S32K148.h:12147
#define SAI_TCR2_SYNC(x)
Definition: S32K148.h:12211
#define SAI_RCR4_FPACK(x)
Definition: S32K148.h:12454
#define SAI_TCSR_SEF_SHIFT
Definition: S32K148.h:12151
#define SAI_RCR2_DIV_SHIFT
Definition: S32K148.h:12382
#define SAI_RCR2_MSEL_SHIFT
Definition: S32K148.h:12394
uint32_t SAI_DRV_RxGetBitClockFreq(uint32_t instNum)
Return true bit clock frequency of receiver.
#define SAI_RCSR_SR(x)
Definition: S32K148.h:12358
#define SAI_BASE_PTRS
Definition: S32K148.h:12063
status_t SAI_DRV_ReceiveBlocking(uint32_t instNum, uint8_t *data[], uint32_t count, uint32_t timeout)
Receive a block of data, return when transfer complete.
void SAI_DRV_RxSetNextMaskWords(uint32_t instNum, uint16_t Words)
Set masked word index of subsequent frames for receiver.
void SAI_DRV_GetDefaultConfig(sai_user_config_t *uc)
Get default config structure for I2S standard. Init config structure for I2S interface: Interrupt mod...
#define SAI_TCR4_MF(x)
Definition: S32K148.h:12245
__IO uint32_t RCR1
Definition: S32K148.h:12035
#define SAI_TCR2_BCI(x)
Definition: S32K148.h:12203
#define SAI_RCR4_FSE(x)
Definition: S32K148.h:12438
status_t EDMA_DRV_StopChannel(uint8_t channel)
Stops the eDMA channel.
Definition: edma_driver.c:838
#define SAI_TCR2_BCP(x)
Definition: S32K148.h:12195
#define SAI_RCR2_BCI(x)
Definition: S32K148.h:12400
sai_transfer_callback_t callback
Definition: sai_driver.h:174
sai_mux_mode_t MuxMode
Definition: sai_driver.h:169
sai_master_clk_source_t MasterClkSrc
Definition: sai_driver.h:147
#define SAI_RCSR_SEF_SHIFT
Definition: S32K148.h:12348
#define SAI_TCR3_TCE(x)
Definition: S32K148.h:12220
#define SAI_RCR2_DIV(x)
Definition: S32K148.h:12384
#define SAI_TCR5_WNW(x)
Definition: S32K148.h:12282
#define SAI_TCSR_SEIE(x)
Definition: S32K148.h:12133
__IO uint32_t RCSR
Definition: S32K148.h:12034
#define SAI_TCR2_DIV_SHIFT
Definition: S32K148.h:12185
status_t OSIF_SemaCreate(semaphore_t *const pSem, const uint8_t initValue)
Creates a semaphore with a given value.
IRQn_Type
Defines the Interrupt Numbers definitions.
Definition: S32K148.h:192
#define SAI_TCR2_DIV(x)
Definition: S32K148.h:12187
uint8_t ChannelEnable
Definition: sai_driver.h:152
#define SAI_TCR2_BCD(x)
Definition: S32K148.h:12191
Structure for internal use. This structure is used by the driver for its internal logic...
Definition: sai_driver.h:98
#define SAI_RCR4_FSD(x)
Definition: S32K148.h:12426
#define SAI1_CHANNEL_COUNT
#define SAI_RCSR_FEF_SHIFT
Definition: S32K148.h:12344
#define SAI_TCSR_WSF_SHIFT
Definition: S32K148.h:12155
uint16_t BitClkDiv
Definition: sai_driver.h:150
#define SAI_TCR4_CHMOD(x)
Definition: S32K148.h:12249
uint32_t SAI_DRV_RxGetBitClockDiv(uint32_t instNum)
Return true bit clock divisor of receiver.
#define SAI_TCR2_BCD_MASK
Definition: S32K148.h:12188
__I uint32_t RDR[SAI_RDR_COUNT]
Definition: S32K148.h:12040
#define SAI_TCR2_BCS(x)
Definition: S32K148.h:12207
void INT_SYS_DisableIRQ(IRQn_Type irqNumber)
Disables an interrupt for a given IRQ number.
#define DEV_ASSERT(x)
Definition: devassert.h:77
__IO uint32_t TMR
Definition: S32K148.h:12032
#define SAI_RCR2_BCP(x)
Definition: S32K148.h:12392
#define SAI_RCR4_FRSZ(x)
Definition: S32K148.h:12450
#define SAI_TCSR_FEIE(x)
Definition: S32K148.h:12129
#define SAI_RCSR_RE(x)
Definition: S32K148.h:12374
#define SAI_RCR4_FSP(x)
Definition: S32K148.h:12430
#define SAI_RCR2_MSEL(x)
Definition: S32K148.h:12396
edma_chn_status_t
Channel status for eDMA channel.
Definition: edma_driver.h:193
#define SAI_RCR3_RCE(x)
Definition: S32K148.h:12417
edma_transfer_size_t
eDMA transfer configuration Implements : edma_transfer_size_t_Class
Definition: edma_driver.h:160
#define SAI_TCR4_FSE(x)
Definition: S32K148.h:12241
uint8_t WordNWidth
Definition: sai_driver.h:161
uint8_t DmaChannel[SAI_MAX_CHANNEL_COUNT]
Definition: sai_driver.h:171
#define SAI_TCSR_SR_MASK
Definition: S32K148.h:12158
#define SAI_RCR2_BCD_MASK
Definition: S32K148.h:12385
status_t CLOCK_SYS_GetFreq(clock_names_t clockName, uint32_t *frequency)
Gets the clock frequency for a specific clock name.
void SAI_DRV_TxInit(uint32_t instNum, const sai_user_config_t *saiUserConfig, sai_state_t *StateAlloc)
Initialize the transmitter of driver.
#define SAI_RCR1_RFW(x)
Definition: S32K148.h:12379
status_t
Status return codes. Common error codes will be a unified enumeration (C enum) that will contain all ...
Definition: status.h:44
clock_names_t
Clock names.
#define SAI_RCSR_RE_MASK
Definition: S32K148.h:12371
#define SAI_TCR4_FPACK(x)
Definition: S32K148.h:12261
uint8_t FirstBitIndex
Definition: sai_driver.h:162
#define SAI_TCSR_SR(x)
Definition: S32K148.h:12161
uint32_t SAI_DRV_TxGetBitClockDiv(uint32_t instNum)
Return true bit clock divisor of transmitter.
#define SAI_TCR4_FRSZ(x)
Definition: S32K148.h:12257
#define SAI_TCR4_SYWD(x)
Definition: S32K148.h:12253
__IO uint32_t TCR2
Definition: S32K148.h:12024
#define SAI_TCR4_ONDEM(x)
Definition: S32K148.h:12237
void SAI_DRV_AbortReceiving(uint32_t instNum)
Abort an ongoing transfer.
__IO uint32_t RCR2
Definition: S32K148.h:12036
__IO uint32_t RCR4
Definition: S32K148.h:12038
#define SAI_RCR5_WNW(x)
Definition: S32K148.h:12475
void SAI_DRV_RxDeinit(uint32_t instNum)
De-initialize receiver.
void SAI_DRV_Receive(uint32_t instNum, uint8_t *data[], uint32_t count)
Receive a block of data, return immidiately.
#define SAI_RCR4_MF(x)
Definition: S32K148.h:12442
void SAI_DRV_TxDeinit(uint32_t instNum)
De-initialize transmitter.
status_t SAI_DRV_SendBlocking(uint32_t instNum, const uint8_t *data[], uint32_t count, uint32_t timeout)
Send a block of data, return when transfer complete.
#define SAI_TCR4_FCOMB(x)
Definition: S32K148.h:12265
status_t OSIF_SemaWait(semaphore_t *const pSem, const uint32_t timeout)
Decrement a semaphore with timeout.
#define SAI_TCR4_FSP(x)
Definition: S32K148.h:12233
#define SAI_RCSR_FEIE(x)
Definition: S32K148.h:12326
__IO uint32_t RCR5
Definition: S32K148.h:12039
#define SAI_RCR2_BCD(x)
Definition: S32K148.h:12388
status_t EDMA_DRV_StartChannel(uint8_t channel)
Starts an eDMA channel.
Definition: edma_driver.c:813
#define SAI0_CHANNEL_COUNT
__IO uint32_t TCR1
Definition: S32K148.h:12023
#define SAI_RCR2_SYNC_MASK
Definition: S32K148.h:12405
#define SAI_TCR2_MSEL(x)
Definition: S32K148.h:12199
#define SAI_TCR3_WDFL(x)
Definition: S32K148.h:12216
status_t SAI_DRV_GetReceivingStatus(uint32_t instNum, uint32_t *countRemain)
Get status of a non-blocking transfer.
#define SAI_RCSR_SEIE(x)
Definition: S32K148.h:12330
status_t OSIF_SemaPost(semaphore_t *const pSem)
Increment a semaphore.
#define SAI_TCR2_MSEL_SHIFT
Definition: S32K148.h:12197
#define SAI_RCR4_ONDEM(x)
Definition: S32K148.h:12434
#define SAI_RX_IRQS
Definition: S32K148.h:12071
sai_mask_mode_t MaskMode
Definition: sai_driver.h:155
#define SAI_TCR5_W0W(x)
Definition: S32K148.h:12278
#define SAI_TCSR_TE_MASK
Definition: S32K148.h:12174
__IO uint32_t TCSR
Definition: S32K148.h:12022
uint32_t SAI_DRV_TxGetBitClockFreq(uint32_t instNum)
Return true bit clock frequency of transmitter.
#define SAI_TCR4_FSD(x)
Definition: S32K148.h:12229
void INT_SYS_EnableIRQ(IRQn_Type irqNumber)
Enables an interrupt for a given IRQ number.
#define SAI_RCR4_FCOMB(x)
Definition: S32K148.h:12458
#define SAI_RCR5_W0W(x)
Definition: S32K148.h:12471
#define SAI_RCR4_FCONT(x)
Definition: S32K148.h:12462
#define SAI_TCR1_TFW(x)
Definition: S32K148.h:12182
#define SAI_RCR2_SYNC(x)
Definition: S32K148.h:12408
void SAI_DRV_TxSetNextMaskWords(uint32_t instNum, uint16_t Words)
Set masked word index of subsequent frames for transmitter.
void(* edma_callback_t)(void *parameter, edma_chn_status_t status)
Definition for the eDMA channel callback function.
Definition: edma_driver.h:204
__IO uint32_t TCR4
Definition: S32K148.h:12026
#define SAI_TX_IRQS
Definition: S32K148.h:12072
#define SAI_RCR2_BCS(x)
Definition: S32K148.h:12404
#define SAI_TCR5_FBT(x)
Definition: S32K148.h:12274
#define SAI_RCR4_SYWD(x)
Definition: S32K148.h:12446
#define SAI_RCSR_WSF_SHIFT
Definition: S32K148.h:12352
__IO uint32_t TCR5
Definition: S32K148.h:12027
#define SAI_RCR2_DIV_MASK
Definition: S32K148.h:12381
#define SAI_TCR4_FCONT(x)
Definition: S32K148.h:12269
void SAI_DRV_Send(uint32_t instNum, const uint8_t *data[], uint32_t count)
Send a block of data, return immidiately.
status_t EDMA_DRV_ConfigMultiBlockTransfer(uint8_t channel, edma_transfer_type_t type, uint32_t srcAddr, uint32_t destAddr, edma_transfer_size_t transferSize, uint32_t blockSize, uint32_t blockCount, bool disableReqOnCompletion)
Configures a multiple block data transfer with DMA.
Definition: edma_driver.c:589
status_t EDMA_DRV_InstallCallback(uint8_t channel, edma_callback_t callback, void *parameter)
Registers the callback function and the parameter for eDMA channel.
Definition: edma_driver.c:293
__IO uint32_t TCR3
Definition: S32K148.h:12025
#define SAI_INSTANCE_COUNT
Definition: S32K148.h:12048
#define SAI_TCR2_MSEL_MASK
Definition: S32K148.h:12196
#define SAI_RCSR_WSIE(x)
Definition: S32K148.h:12334
#define SAI_RCR5_FBT(x)
Definition: S32K148.h:12467
uint8_t Word0Width
Definition: sai_driver.h:160
uint32_t BitClkFreq
Definition: sai_driver.h:164
User config structure.
Definition: sai_driver.h:144
#define SAI_TCR2_SYNC_MASK
Definition: S32K148.h:12208