STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_sai.c
Go to the documentation of this file.
1 
214 /* Includes ------------------------------------------------------------------*/
215 #include "stm32l4xx_hal.h"
216 
221 #ifdef HAL_SAI_MODULE_ENABLED
222 #if !defined(STM32L412xx) && !defined(STM32L422xx)
223 
229 /* Private typedef -----------------------------------------------------------*/
233 typedef enum
234 {
242 /* Private define ------------------------------------------------------------*/
246 #define SAI_DEFAULT_TIMEOUT 4U
247 #define SAI_LONG_TIMEOUT 1000U
248 
252 /* Private macro -------------------------------------------------------------*/
253 /* Private variables ---------------------------------------------------------*/
254 /* Private function prototypes -----------------------------------------------*/
258 static void SAI_FillFifo(SAI_HandleTypeDef *hsai);
259 static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode);
260 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
261 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
262 
263 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai);
264 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai);
265 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai);
266 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai);
267 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai);
268 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai);
269 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai);
270 
271 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma);
272 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
273 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma);
274 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
275 static void SAI_DMAError(DMA_HandleTypeDef *hdma);
276 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma);
281 /* Exported functions ---------------------------------------------------------*/
330 HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
331 {
332  HAL_StatusTypeDef status;
333 
334  /* Check the parameters */
335  assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol));
336  assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize));
337 
338  switch (protocol)
339  {
340  case SAI_I2S_STANDARD :
341  case SAI_I2S_MSBJUSTIFIED :
342  case SAI_I2S_LSBJUSTIFIED :
343  status = SAI_InitI2S(hsai, protocol, datasize, nbslot);
344  break;
345  case SAI_PCM_LONG :
346  case SAI_PCM_SHORT :
347  status = SAI_InitPCM(hsai, protocol, datasize, nbslot);
348  break;
349  default :
350  status = HAL_ERROR;
351  break;
352  }
353 
354  if (status == HAL_OK)
355  {
356  status = HAL_SAI_Init(hsai);
357  }
358 
359  return status;
360 }
361 
369 HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
370 {
371  uint32_t tmpregisterGCR;
372  uint32_t ckstr_bits;
373  uint32_t syncen_bits;
374 
375  /* Check the SAI handle allocation */
376  if (hsai == NULL)
377  {
378  return HAL_ERROR;
379  }
380 
381  /* check the instance */
382  assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance));
383 
384  /* Check the SAI Block parameters */
385  assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency));
386  assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol));
387  assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode));
388  assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize));
389  assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit));
390  assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing));
391  assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro));
392  assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive));
393  assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider));
394  assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold));
395  assert_param(IS_SAI_MONO_STEREO_MODE(hsai->Init.MonoStereoMode));
396  assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode));
397  assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState));
398  assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt));
399 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
400  assert_param(IS_SAI_BLOCK_MCK_OVERSAMPLING(hsai->Init.MckOverSampling));
401 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
402 
403  /* Check the SAI Block Frame parameters */
404  assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength));
405  assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength));
406  assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition));
407  assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity));
408  assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset));
409 
410  /* Check the SAI Block Slot parameters */
411  assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset));
412  assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize));
413  assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber));
414  assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive));
415 
416 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
417  /* Check the SAI PDM parameters */
418  assert_param(IS_FUNCTIONAL_STATE(hsai->Init.PdmInit.Activation));
419  if (hsai->Init.PdmInit.Activation == ENABLE)
420  {
421  assert_param(IS_SAI_PDM_MIC_PAIRS_NUMBER(hsai->Init.PdmInit.MicPairsNbr));
422  assert_param(IS_SAI_PDM_CLOCK_ENABLE(hsai->Init.PdmInit.ClockEnable));
423  /* Check that SAI sub-block is SAI1 sub-block A, in master RX mode with free protocol */
424  if ((hsai->Instance != SAI1_Block_A) ||
425  (hsai->Init.AudioMode != SAI_MODEMASTER_RX) ||
426  (hsai->Init.Protocol != SAI_FREE_PROTOCOL))
427  {
428  return HAL_ERROR;
429  }
430  }
431 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
432 
433  if (hsai->State == HAL_SAI_STATE_RESET)
434  {
435  /* Allocate lock resource and initialize it */
436  hsai->Lock = HAL_UNLOCKED;
437 
438 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
439  /* Reset callback pointers to the weak predefined callbacks */
445 
446  /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
447  if (hsai->MspInitCallback == NULL)
448  {
450  }
451  hsai->MspInitCallback(hsai);
452 #else
453  /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
454  HAL_SAI_MspInit(hsai);
455 #endif
456  }
457 
458  /* Disable the selected SAI peripheral */
459  if (SAI_Disable(hsai) != HAL_OK)
460  {
461  return HAL_ERROR;
462  }
463 
464  hsai->State = HAL_SAI_STATE_BUSY;
465 
466  /* SAI Block Synchro Configuration -----------------------------------------*/
467  /* This setting must be done with both audio block (A & B) disabled */
468  switch (hsai->Init.SynchroExt)
469  {
470  case SAI_SYNCEXT_DISABLE :
471  tmpregisterGCR = 0;
472  break;
473  case SAI_SYNCEXT_OUTBLOCKA_ENABLE :
474  tmpregisterGCR = SAI_GCR_SYNCOUT_0;
475  break;
476  case SAI_SYNCEXT_OUTBLOCKB_ENABLE :
477  tmpregisterGCR = SAI_GCR_SYNCOUT_1;
478  break;
479  default :
480  tmpregisterGCR = 0;
481  break;
482  }
483 
484  switch (hsai->Init.Synchro)
485  {
486  case SAI_ASYNCHRONOUS :
487  syncen_bits = 0;
488  break;
489  case SAI_SYNCHRONOUS :
490  syncen_bits = SAI_xCR1_SYNCEN_0;
491  break;
492  case SAI_SYNCHRONOUS_EXT_SAI1 :
493  syncen_bits = SAI_xCR1_SYNCEN_1;
494  break;
495  case SAI_SYNCHRONOUS_EXT_SAI2 :
496  syncen_bits = SAI_xCR1_SYNCEN_1;
497  tmpregisterGCR |= SAI_GCR_SYNCIN_0;
498  break;
499  default :
500  syncen_bits = 0;
501  break;
502  }
503 
504 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \
505  defined(STM32L496xx) || defined(STM32L4A6xx) || \
506  defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
507 
508  if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
509  {
510  SAI1->GCR = tmpregisterGCR;
511  }
512  else
513  {
514  SAI2->GCR = tmpregisterGCR;
515  }
516 
517 #else
518 
519  SAI1->GCR = tmpregisterGCR;
520 
521 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || */
522  /* STM32L496xx || STM32L4A6xx || */
523  /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
524 
525  if (hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV)
526  {
527  uint32_t freq;
528  uint32_t tmpval;
529 
530  /* In this case, the MCKDIV value is calculated to get AudioFrequency */
531 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \
532  defined(STM32L496xx) || defined(STM32L4A6xx) || \
533  defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
534 
535  if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
536  {
537  freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1);
538  }
539  else
540  {
541  /* SAI2_Block_A or SAI2_Block_B */
542  freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2);
543  }
544 
545 #else
546 
547  freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1);
548 
549 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx || */
550  /* STM32L496xx || STM32L4A6xx || */
551  /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
552 
553 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
554  /* Configure Master Clock Divider using the following formula :
555  - If NOMCK = 1 :
556  MCKDIV[5:0] = SAI_CK_x / (FS * (FRL + 1))
557  - If NOMCK = 0 :
558  MCKDIV[5:0] = SAI_CK_x / (FS * (OSR + 1) * 256) */
559  if (hsai->Init.NoDivider == SAI_MASTERDIVIDER_DISABLE)
560  {
561  /* NOMCK = 1 */
562  /* (freq x 10) to keep Significant digits */
563  tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * hsai->FrameInit.FrameLength);
564  }
565  else
566  {
567  /* NOMCK = 0 */
568  uint32_t tmposr;
569  tmposr = (hsai->Init.MckOverSampling == SAI_MCK_OVERSAMPLING_ENABLE) ? 2U : 1U;
570  /* (freq x 10) to keep Significant digits */
571  tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * tmposr * 256U);
572  }
573  hsai->Init.Mckdiv = tmpval / 10U;
574 
575  /* Round result to the nearest integer */
576  if ((tmpval % 10U) > 8U)
577  {
578  hsai->Init.Mckdiv += 1U;
579  }
580 #else
581  /* Configure Master Clock using the following formula :
582  MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS
583  FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256
584  MCKDIV[3:0] = SAI_CK_x / FS * 512 */
585  /* (freq x 10) to keep Significant digits */
586  tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * 2U * 256U);
587  hsai->Init.Mckdiv = tmpval / 10U;
588 
589  /* Round result to the nearest integer */
590  if ((tmpval % 10U) > 8U)
591  {
592  hsai->Init.Mckdiv += 1U;
593  }
594 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
595  }
596  /* Check the SAI Block master clock divider parameter */
597  assert_param(IS_SAI_BLOCK_MASTER_DIVIDER(hsai->Init.Mckdiv));
598 
599  /* Compute CKSTR bits of SAI CR1 according ClockStrobing and AudioMode */
600  if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
601  {
602  /* Transmit */
603  ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U : SAI_xCR1_CKSTR;
604  }
605  else
606  {
607  /* Receive */
608  ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0U;
609  }
610 
611  /* SAI Block Configuration -------------------------------------------------*/
612  /* SAI CR1 Configuration */
613 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
614  hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
615  SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
616  SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
617  SAI_xCR1_NOMCK | SAI_xCR1_MCKDIV | SAI_xCR1_OSR);
618 
619  hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
620  hsai->Init.DataSize | hsai->Init.FirstBit | \
621  ckstr_bits | syncen_bits | \
622  hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
623  hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | \
624  hsai->Init.MckOverSampling);
625 #else
626  hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
627  SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
628  SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
629  SAI_xCR1_NODIV | SAI_xCR1_MCKDIV);
630 
631  hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
632  hsai->Init.DataSize | hsai->Init.FirstBit | \
633  ckstr_bits | syncen_bits | \
634  hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
635  hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20));
636 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
637 
638  /* SAI CR2 Configuration */
639  hsai->Instance->CR2 &= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP | SAI_xCR2_CPL);
640  hsai->Instance->CR2 |= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState);
641 
642  /* SAI Frame Configuration -----------------------------------------*/
643  hsai->Instance->FRCR &= (~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \
644  SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF));
645  hsai->Instance->FRCR |= ((hsai->FrameInit.FrameLength - 1U) |
646  hsai->FrameInit.FSOffset |
647  hsai->FrameInit.FSDefinition |
648  hsai->FrameInit.FSPolarity |
649  ((hsai->FrameInit.ActiveFrameLength - 1U) << 8));
650 
651  /* SAI Block_x SLOT Configuration ------------------------------------------*/
652  /* This register has no meaning in AC 97 and SPDIF audio protocol */
653  hsai->Instance->SLOTR &= (~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \
654  SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN));
655 
656  hsai->Instance->SLOTR |= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize | \
657  (hsai->SlotInit.SlotActive << 16) | ((hsai->SlotInit.SlotNumber - 1U) << 8);
658 
659 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
660  /* SAI PDM Configuration ---------------------------------------------------*/
661  if (hsai->Instance == SAI1_Block_A)
662  {
663  /* Disable PDM interface */
664  SAI1->PDMCR &= ~(SAI_PDMCR_PDMEN);
665  if (hsai->Init.PdmInit.Activation == ENABLE)
666  {
667  /* Configure and enable PDM interface */
668  SAI1->PDMCR = (hsai->Init.PdmInit.ClockEnable |
669  ((hsai->Init.PdmInit.MicPairsNbr - 1U) << SAI_PDMCR_MICNBR_Pos));
670  SAI1->PDMCR |= SAI_PDMCR_PDMEN;
671  }
672  }
673 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
674 
675  /* Initialize the error code */
676  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
677 
678  /* Initialize the SAI state */
679  hsai->State = HAL_SAI_STATE_READY;
680 
681  /* Release Lock */
682  __HAL_UNLOCK(hsai);
683 
684  return HAL_OK;
685 }
686 
693 HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
694 {
695  /* Check the SAI handle allocation */
696  if (hsai == NULL)
697  {
698  return HAL_ERROR;
699  }
700 
701  hsai->State = HAL_SAI_STATE_BUSY;
702 
703  /* Disabled All interrupt and clear all the flag */
704  hsai->Instance->IMR = 0;
705  hsai->Instance->CLRFR = 0xFFFFFFFFU;
706 
707  /* Disable the SAI */
708  if (SAI_Disable(hsai) != HAL_OK)
709  {
710  /* Reset SAI state to ready */
711  hsai->State = HAL_SAI_STATE_READY;
712 
713  /* Release Lock */
714  __HAL_UNLOCK(hsai);
715 
716  return HAL_ERROR;
717  }
718 
719  /* Flush the fifo */
720  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
721 
722 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
723  /* Disable SAI PDM interface */
724  if (hsai->Instance == SAI1_Block_A)
725  {
726  /* Reset PDM delays */
727  SAI1->PDMDLY = 0U;
728 
729  /* Disable PDM interface */
730  SAI1->PDMCR &= ~(SAI_PDMCR_PDMEN);
731  }
732 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */
733 
734  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
735 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
736  if (hsai->MspDeInitCallback == NULL)
737  {
739  }
740  hsai->MspDeInitCallback(hsai);
741 #else
742  HAL_SAI_MspDeInit(hsai);
743 #endif
744 
745  /* Initialize the error code */
746  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
747 
748  /* Initialize the SAI state */
749  hsai->State = HAL_SAI_STATE_RESET;
750 
751  /* Release Lock */
752  __HAL_UNLOCK(hsai);
753 
754  return HAL_OK;
755 }
756 
764 {
765  /* Prevent unused argument(s) compilation warning */
766  UNUSED(hsai);
767 
768  /* NOTE : This function should not be modified, when the callback is needed,
769  the HAL_SAI_MspInit could be implemented in the user file
770  */
771 }
772 
780 {
781  /* Prevent unused argument(s) compilation warning */
782  UNUSED(hsai);
783 
784  /* NOTE : This function should not be modified, when the callback is needed,
785  the HAL_SAI_MspDeInit could be implemented in the user file
786  */
787 }
788 
789 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
790 
807  HAL_SAI_CallbackIDTypeDef CallbackID,
808  pSAI_CallbackTypeDef pCallback)
809 {
810  HAL_StatusTypeDef status = HAL_OK;
811 
812  if (pCallback == NULL)
813  {
814  /* update the error code */
815  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
816  /* update return status */
817  status = HAL_ERROR;
818  }
819  else
820  {
821  if (HAL_SAI_STATE_READY == hsai->State)
822  {
823  switch (CallbackID)
824  {
826  hsai->RxCpltCallback = pCallback;
827  break;
829  hsai->RxHalfCpltCallback = pCallback;
830  break;
832  hsai->TxCpltCallback = pCallback;
833  break;
835  hsai->TxHalfCpltCallback = pCallback;
836  break;
837  case HAL_SAI_ERROR_CB_ID :
838  hsai->ErrorCallback = pCallback;
839  break;
840  case HAL_SAI_MSPINIT_CB_ID :
841  hsai->MspInitCallback = pCallback;
842  break;
844  hsai->MspDeInitCallback = pCallback;
845  break;
846  default :
847  /* update the error code */
848  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
849  /* update return status */
850  status = HAL_ERROR;
851  break;
852  }
853  }
854  else if (HAL_SAI_STATE_RESET == hsai->State)
855  {
856  switch (CallbackID)
857  {
858  case HAL_SAI_MSPINIT_CB_ID :
859  hsai->MspInitCallback = pCallback;
860  break;
862  hsai->MspDeInitCallback = pCallback;
863  break;
864  default :
865  /* update the error code */
866  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
867  /* update return status */
868  status = HAL_ERROR;
869  break;
870  }
871  }
872  else
873  {
874  /* update the error code */
875  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
876  /* update return status */
877  status = HAL_ERROR;
878  }
879  }
880  return status;
881 }
882 
899  HAL_SAI_CallbackIDTypeDef CallbackID)
900 {
901  HAL_StatusTypeDef status = HAL_OK;
902 
903  if (HAL_SAI_STATE_READY == hsai->State)
904  {
905  switch (CallbackID)
906  {
909  break;
912  break;
915  break;
918  break;
919  case HAL_SAI_ERROR_CB_ID :
921  break;
922  case HAL_SAI_MSPINIT_CB_ID :
924  break;
927  break;
928  default :
929  /* update the error code */
930  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
931  /* update return status */
932  status = HAL_ERROR;
933  break;
934  }
935  }
936  else if (HAL_SAI_STATE_RESET == hsai->State)
937  {
938  switch (CallbackID)
939  {
940  case HAL_SAI_MSPINIT_CB_ID :
942  break;
945  break;
946  default :
947  /* update the error code */
948  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
949  /* update return status */
950  status = HAL_ERROR;
951  break;
952  }
953  }
954  else
955  {
956  /* update the error code */
957  hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
958  /* update return status */
959  status = HAL_ERROR;
960  }
961  return status;
962 }
963 #endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
964 
1020 HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1021 {
1022  uint32_t tickstart = HAL_GetTick();
1023  uint32_t temp;
1024 
1025  if ((pData == NULL) || (Size == 0U))
1026  {
1027  return HAL_ERROR;
1028  }
1029 
1030  if (hsai->State == HAL_SAI_STATE_READY)
1031  {
1032  /* Process Locked */
1033  __HAL_LOCK(hsai);
1034 
1035  hsai->XferSize = Size;
1036  hsai->XferCount = Size;
1037  hsai->pBuffPtr = pData;
1038  hsai->State = HAL_SAI_STATE_BUSY_TX;
1039  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1040 
1041  /* Check if the SAI is already enabled */
1042  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1043  {
1044  /* fill the fifo with data before to enabled the SAI */
1045  SAI_FillFifo(hsai);
1046  /* Enable SAI peripheral */
1047  __HAL_SAI_ENABLE(hsai);
1048  }
1049 
1050  while (hsai->XferCount > 0U)
1051  {
1052  /* Write data if the FIFO is not full */
1053  if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL)
1054  {
1055  if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1056  {
1057  hsai->Instance->DR = *hsai->pBuffPtr;
1058  hsai->pBuffPtr++;
1059  }
1060  else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1061  {
1062  temp = (uint32_t)(*hsai->pBuffPtr);
1063  hsai->pBuffPtr++;
1064  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
1065  hsai->pBuffPtr++;
1066  hsai->Instance->DR = temp;
1067  }
1068  else
1069  {
1070  temp = (uint32_t)(*hsai->pBuffPtr);
1071  hsai->pBuffPtr++;
1072  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
1073  hsai->pBuffPtr++;
1074  temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
1075  hsai->pBuffPtr++;
1076  temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
1077  hsai->pBuffPtr++;
1078  hsai->Instance->DR = temp;
1079  }
1080  hsai->XferCount--;
1081  }
1082  else
1083  {
1084  /* Check for the Timeout */
1085  if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY))
1086  {
1087  /* Update error code */
1088  hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1089 
1090  /* Clear all the flags */
1091  hsai->Instance->CLRFR = 0xFFFFFFFFU;
1092 
1093  /* Disable SAI peripheral */
1094  /* No need to check return value because state update, unlock and error return will be performed later */
1095  (void) SAI_Disable(hsai);
1096 
1097  /* Flush the fifo */
1098  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1099 
1100  /* Change the SAI state */
1101  hsai->State = HAL_SAI_STATE_READY;
1102 
1103  /* Process Unlocked */
1104  __HAL_UNLOCK(hsai);
1105 
1106  return HAL_ERROR;
1107  }
1108  }
1109  }
1110 
1111  hsai->State = HAL_SAI_STATE_READY;
1112 
1113  /* Process Unlocked */
1114  __HAL_UNLOCK(hsai);
1115 
1116  return HAL_OK;
1117  }
1118  else
1119  {
1120  return HAL_BUSY;
1121  }
1122 }
1123 
1133 HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1134 {
1135  uint32_t tickstart = HAL_GetTick();
1136  uint32_t temp;
1137 
1138  if ((pData == NULL) || (Size == 0U))
1139  {
1140  return HAL_ERROR;
1141  }
1142 
1143  if (hsai->State == HAL_SAI_STATE_READY)
1144  {
1145  /* Process Locked */
1146  __HAL_LOCK(hsai);
1147 
1148  hsai->pBuffPtr = pData;
1149  hsai->XferSize = Size;
1150  hsai->XferCount = Size;
1151  hsai->State = HAL_SAI_STATE_BUSY_RX;
1152  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1153 
1154  /* Check if the SAI is already enabled */
1155  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1156  {
1157  /* Enable SAI peripheral */
1158  __HAL_SAI_ENABLE(hsai);
1159  }
1160 
1161  /* Receive data */
1162  while (hsai->XferCount > 0U)
1163  {
1164  if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY)
1165  {
1166  if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1167  {
1168  *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR;
1169  hsai->pBuffPtr++;
1170  }
1171  else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1172  {
1173  temp = hsai->Instance->DR;
1174  *hsai->pBuffPtr = (uint8_t)temp;
1175  hsai->pBuffPtr++;
1176  *hsai->pBuffPtr = (uint8_t)(temp >> 8);
1177  hsai->pBuffPtr++;
1178  }
1179  else
1180  {
1181  temp = hsai->Instance->DR;
1182  *hsai->pBuffPtr = (uint8_t)temp;
1183  hsai->pBuffPtr++;
1184  *hsai->pBuffPtr = (uint8_t)(temp >> 8);
1185  hsai->pBuffPtr++;
1186  *hsai->pBuffPtr = (uint8_t)(temp >> 16);
1187  hsai->pBuffPtr++;
1188  *hsai->pBuffPtr = (uint8_t)(temp >> 24);
1189  hsai->pBuffPtr++;
1190  }
1191  hsai->XferCount--;
1192  }
1193  else
1194  {
1195  /* Check for the Timeout */
1196  if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY))
1197  {
1198  /* Update error code */
1199  hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1200 
1201  /* Clear all the flags */
1202  hsai->Instance->CLRFR = 0xFFFFFFFFU;
1203 
1204  /* Disable SAI peripheral */
1205  /* No need to check return value because state update, unlock and error return will be performed later */
1206  (void) SAI_Disable(hsai);
1207 
1208  /* Flush the fifo */
1209  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1210 
1211  /* Change the SAI state */
1212  hsai->State = HAL_SAI_STATE_READY;
1213 
1214  /* Process Unlocked */
1215  __HAL_UNLOCK(hsai);
1216 
1217  return HAL_ERROR;
1218  }
1219  }
1220  }
1221 
1222  hsai->State = HAL_SAI_STATE_READY;
1223 
1224  /* Process Unlocked */
1225  __HAL_UNLOCK(hsai);
1226 
1227  return HAL_OK;
1228  }
1229  else
1230  {
1231  return HAL_BUSY;
1232  }
1233 }
1234 
1243 HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1244 {
1245  if ((pData == NULL) || (Size == 0U))
1246  {
1247  return HAL_ERROR;
1248  }
1249 
1250  if (hsai->State == HAL_SAI_STATE_READY)
1251  {
1252  /* Process Locked */
1253  __HAL_LOCK(hsai);
1254 
1255  hsai->pBuffPtr = pData;
1256  hsai->XferSize = Size;
1257  hsai->XferCount = Size;
1258  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1259  hsai->State = HAL_SAI_STATE_BUSY_TX;
1260 
1261  if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1262  {
1264  }
1265  else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1266  {
1268  }
1269  else
1270  {
1272  }
1273 
1274  /* Fill the fifo before starting the communication */
1275  SAI_FillFifo(hsai);
1276 
1277  /* Enable FRQ and OVRUDR interrupts */
1278  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1279 
1280  /* Check if the SAI is already enabled */
1281  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1282  {
1283  /* Enable SAI peripheral */
1284  __HAL_SAI_ENABLE(hsai);
1285  }
1286  /* Process Unlocked */
1287  __HAL_UNLOCK(hsai);
1288 
1289  return HAL_OK;
1290  }
1291  else
1292  {
1293  return HAL_BUSY;
1294  }
1295 }
1296 
1305 HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1306 {
1307  if ((pData == NULL) || (Size == 0U))
1308  {
1309  return HAL_ERROR;
1310  }
1311 
1312  if (hsai->State == HAL_SAI_STATE_READY)
1313  {
1314  /* Process Locked */
1315  __HAL_LOCK(hsai);
1316 
1317  hsai->pBuffPtr = pData;
1318  hsai->XferSize = Size;
1319  hsai->XferCount = Size;
1320  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1321  hsai->State = HAL_SAI_STATE_BUSY_RX;
1322 
1323  if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1324  {
1326  }
1327  else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1328  {
1330  }
1331  else
1332  {
1334  }
1335 
1336  /* Enable TXE and OVRUDR interrupts */
1337  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1338 
1339  /* Check if the SAI is already enabled */
1340  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1341  {
1342  /* Enable SAI peripheral */
1343  __HAL_SAI_ENABLE(hsai);
1344  }
1345 
1346  /* Process Unlocked */
1347  __HAL_UNLOCK(hsai);
1348 
1349  return HAL_OK;
1350  }
1351  else
1352  {
1353  return HAL_BUSY;
1354  }
1355 }
1356 
1363 HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
1364 {
1365  /* Process Locked */
1366  __HAL_LOCK(hsai);
1367 
1368  /* Pause the audio file playing by disabling the SAI DMA requests */
1369  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1370 
1371  /* Process Unlocked */
1372  __HAL_UNLOCK(hsai);
1373 
1374  return HAL_OK;
1375 }
1376 
1383 HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai)
1384 {
1385  /* Process Locked */
1386  __HAL_LOCK(hsai);
1387 
1388  /* Enable the SAI DMA requests */
1389  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1390 
1391  /* If the SAI peripheral is still not enabled, enable it */
1392  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1393  {
1394  /* Enable SAI peripheral */
1395  __HAL_SAI_ENABLE(hsai);
1396  }
1397 
1398  /* Process Unlocked */
1399  __HAL_UNLOCK(hsai);
1400 
1401  return HAL_OK;
1402 }
1403 
1410 HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
1411 {
1412  HAL_StatusTypeDef status = HAL_OK;
1413 
1414  /* Process Locked */
1415  __HAL_LOCK(hsai);
1416 
1417  /* Disable the SAI DMA request */
1418  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1419 
1420  /* Abort the SAI Tx DMA Stream */
1421  if ((hsai->State == HAL_SAI_STATE_BUSY_TX) && (hsai->hdmatx != NULL))
1422  {
1423  if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1424  {
1425  /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */
1426  if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1427  {
1428  status = HAL_ERROR;
1429  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1430  }
1431  }
1432  }
1433 
1434  /* Abort the SAI Rx DMA Stream */
1435  if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL))
1436  {
1437  if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1438  {
1439  /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */
1440  if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1441  {
1442  status = HAL_ERROR;
1443  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1444  }
1445  }
1446  }
1447 
1448  /* Disable SAI peripheral */
1449  if (SAI_Disable(hsai) != HAL_OK)
1450  {
1451  status = HAL_ERROR;
1452  }
1453 
1454  /* Flush the fifo */
1455  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1456 
1457  /* Set hsai state to ready */
1458  hsai->State = HAL_SAI_STATE_READY;
1459 
1460  /* Process Unlocked */
1461  __HAL_UNLOCK(hsai);
1462 
1463  return status;
1464 }
1465 
1472 HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
1473 {
1474  HAL_StatusTypeDef status = HAL_OK;
1475 
1476  /* Process Locked */
1477  __HAL_LOCK(hsai);
1478 
1479  /* Check SAI DMA is enabled or not */
1480  if ((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1481  {
1482  /* Disable the SAI DMA request */
1483  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1484 
1485  /* Abort the SAI Tx DMA Stream */
1486  if ((hsai->State == HAL_SAI_STATE_BUSY_TX) && (hsai->hdmatx != NULL))
1487  {
1488  if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1489  {
1490  /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */
1491  if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1492  {
1493  status = HAL_ERROR;
1494  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1495  }
1496  }
1497  }
1498 
1499  /* Abort the SAI Rx DMA Stream */
1500  if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL))
1501  {
1502  if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1503  {
1504  /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */
1505  if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1506  {
1507  status = HAL_ERROR;
1508  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1509  }
1510  }
1511  }
1512  }
1513 
1514  /* Disabled All interrupt and clear all the flag */
1515  hsai->Instance->IMR = 0;
1516  hsai->Instance->CLRFR = 0xFFFFFFFFU;
1517 
1518  /* Disable SAI peripheral */
1519  if (SAI_Disable(hsai) != HAL_OK)
1520  {
1521  status = HAL_ERROR;
1522  }
1523 
1524  /* Flush the fifo */
1525  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1526 
1527  /* Set hsai state to ready */
1528  hsai->State = HAL_SAI_STATE_READY;
1529 
1530  /* Process Unlocked */
1531  __HAL_UNLOCK(hsai);
1532 
1533  return status;
1534 }
1535 
1544 HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1545 {
1546  uint32_t tickstart = HAL_GetTick();
1547 
1548  if ((pData == NULL) || (Size == 0U))
1549  {
1550  return HAL_ERROR;
1551  }
1552 
1553  if (hsai->State == HAL_SAI_STATE_READY)
1554  {
1555  /* Process Locked */
1556  __HAL_LOCK(hsai);
1557 
1558  hsai->pBuffPtr = pData;
1559  hsai->XferSize = Size;
1560  hsai->XferCount = Size;
1561  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1562  hsai->State = HAL_SAI_STATE_BUSY_TX;
1563 
1564  /* Set the SAI Tx DMA Half transfer complete callback */
1566 
1567  /* Set the SAI TxDMA transfer complete callback */
1569 
1570  /* Set the DMA error callback */
1572 
1573  /* Set the DMA Tx abort callback */
1574  hsai->hdmatx->XferAbortCallback = NULL;
1575 
1576  /* Enable the Tx DMA Stream */
1577  if (HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
1578  {
1579  __HAL_UNLOCK(hsai);
1580  return HAL_ERROR;
1581  }
1582 
1583  /* Enable the interrupts for error handling */
1584  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1585 
1586  /* Enable SAI Tx DMA Request */
1587  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1588 
1589  /* Wait untill FIFO is not empty */
1590  while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY)
1591  {
1592  /* Check for the Timeout */
1593  if ((HAL_GetTick() - tickstart) > SAI_LONG_TIMEOUT)
1594  {
1595  /* Update error code */
1596  hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1597 
1598  /* Process Unlocked */
1599  __HAL_UNLOCK(hsai);
1600 
1601  return HAL_TIMEOUT;
1602  }
1603  }
1604 
1605  /* Check if the SAI is already enabled */
1606  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1607  {
1608  /* Enable SAI peripheral */
1609  __HAL_SAI_ENABLE(hsai);
1610  }
1611 
1612  /* Process Unlocked */
1613  __HAL_UNLOCK(hsai);
1614 
1615  return HAL_OK;
1616  }
1617  else
1618  {
1619  return HAL_BUSY;
1620  }
1621 }
1622 
1631 HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1632 {
1633 
1634  if ((pData == NULL) || (Size == 0U))
1635  {
1636  return HAL_ERROR;
1637  }
1638 
1639  if (hsai->State == HAL_SAI_STATE_READY)
1640  {
1641  /* Process Locked */
1642  __HAL_LOCK(hsai);
1643 
1644  hsai->pBuffPtr = pData;
1645  hsai->XferSize = Size;
1646  hsai->XferCount = Size;
1647  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1648  hsai->State = HAL_SAI_STATE_BUSY_RX;
1649 
1650  /* Set the SAI Rx DMA Half transfer complete callback */
1652 
1653  /* Set the SAI Rx DMA transfer complete callback */
1655 
1656  /* Set the DMA error callback */
1658 
1659  /* Set the DMA Rx abort callback */
1660  hsai->hdmarx->XferAbortCallback = NULL;
1661 
1662  /* Enable the Rx DMA Stream */
1663  if (HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
1664  {
1665  __HAL_UNLOCK(hsai);
1666  return HAL_ERROR;
1667  }
1668 
1669  /* Check if the SAI is already enabled */
1670  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1671  {
1672  /* Enable SAI peripheral */
1673  __HAL_SAI_ENABLE(hsai);
1674  }
1675 
1676  /* Enable the interrupts for error handling */
1677  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1678 
1679  /* Enable SAI Rx DMA Request */
1680  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1681 
1682  /* Process Unlocked */
1683  __HAL_UNLOCK(hsai);
1684 
1685  return HAL_OK;
1686  }
1687  else
1688  {
1689  return HAL_BUSY;
1690  }
1691 }
1692 
1700 HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
1701 {
1702  assert_param(IS_SAI_BLOCK_MUTE_VALUE(val));
1703 
1704  if (hsai->State != HAL_SAI_STATE_RESET)
1705  {
1706  CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1707  SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | (uint32_t)val);
1708  return HAL_OK;
1709  }
1710  return HAL_ERROR;
1711 }
1712 
1720 {
1721  if (hsai->State != HAL_SAI_STATE_RESET)
1722  {
1723  CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1724  return HAL_OK;
1725  }
1726  return HAL_ERROR;
1727 }
1728 
1737 HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
1738 {
1739  assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter));
1740 
1741  if (hsai->State != HAL_SAI_STATE_RESET)
1742  {
1743  /* set the mute counter */
1744  CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT);
1745  SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_Pos));
1746  hsai->mutecallback = callback;
1747  /* enable the IT interrupt */
1748  __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET);
1749  return HAL_OK;
1750  }
1751  return HAL_ERROR;
1752 }
1753 
1761 {
1762  if (hsai->State != HAL_SAI_STATE_RESET)
1763  {
1764  /* set the mutecallback to NULL */
1765  hsai->mutecallback = NULL;
1766  /* enable the IT interrupt */
1767  __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET);
1768  return HAL_OK;
1769  }
1770  return HAL_ERROR;
1771 }
1772 
1780 {
1781  if (hsai->State != HAL_SAI_STATE_RESET)
1782  {
1783  uint32_t itflags = hsai->Instance->SR;
1784  uint32_t itsources = hsai->Instance->IMR;
1785  uint32_t cr1config = hsai->Instance->CR1;
1786  uint32_t tmperror;
1787 
1788  /* SAI Fifo request interrupt occurred -----------------------------------*/
1789  if (((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ))
1790  {
1791  hsai->InterruptServiceRoutine(hsai);
1792  }
1793  /* SAI Overrun error interrupt occurred ----------------------------------*/
1794  else if (((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR))
1795  {
1796  /* Clear the SAI Overrun flag */
1797  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
1798  /* Get the SAI error code */
1799  tmperror = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR);
1800  /* Change the SAI error code */
1801  hsai->ErrorCode |= tmperror;
1802  /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
1803 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1804  hsai->ErrorCallback(hsai);
1805 #else
1806  HAL_SAI_ErrorCallback(hsai);
1807 #endif
1808  }
1809  /* SAI mutedet interrupt occurred ----------------------------------*/
1810  else if (((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET))
1811  {
1812  /* Clear the SAI mutedet flag */
1813  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET);
1814  /* call the call back function */
1815  if (hsai->mutecallback != NULL)
1816  {
1817  /* inform the user that an RX mute event has been detected */
1818  hsai->mutecallback();
1819  }
1820  }
1821  /* SAI AFSDET interrupt occurred ----------------------------------*/
1822  else if (((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET))
1823  {
1824  /* Change the SAI error code */
1825  hsai->ErrorCode |= HAL_SAI_ERROR_AFSDET;
1826 
1827  /* Check SAI DMA is enabled or not */
1828  if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1829  {
1830  /* Abort the SAI DMA Streams */
1831  if (hsai->hdmatx != NULL)
1832  {
1833  /* Set the DMA Tx abort callback */
1835 
1836  /* Abort DMA in IT mode */
1837  if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
1838  {
1839  /* Update SAI error code */
1840  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1841 
1842  /* Call SAI error callback */
1843 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1844  hsai->ErrorCallback(hsai);
1845 #else
1846  HAL_SAI_ErrorCallback(hsai);
1847 #endif
1848  }
1849  }
1850  if (hsai->hdmarx != NULL)
1851  {
1852  /* Set the DMA Rx abort callback */
1854 
1855  /* Abort DMA in IT mode */
1856  if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
1857  {
1858  /* Update SAI error code */
1859  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1860 
1861  /* Call SAI error callback */
1862 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1863  hsai->ErrorCallback(hsai);
1864 #else
1865  HAL_SAI_ErrorCallback(hsai);
1866 #endif
1867  }
1868  }
1869  }
1870  else
1871  {
1872  /* Abort SAI */
1873  /* No need to check return value because HAL_SAI_ErrorCallback will be called later */
1874  (void) HAL_SAI_Abort(hsai);
1875 
1876  /* Set error callback */
1877 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1878  hsai->ErrorCallback(hsai);
1879 #else
1880  HAL_SAI_ErrorCallback(hsai);
1881 #endif
1882  }
1883  }
1884  /* SAI LFSDET interrupt occurred ----------------------------------*/
1885  else if (((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET))
1886  {
1887  /* Change the SAI error code */
1888  hsai->ErrorCode |= HAL_SAI_ERROR_LFSDET;
1889 
1890  /* Check SAI DMA is enabled or not */
1891  if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1892  {
1893  /* Abort the SAI DMA Streams */
1894  if (hsai->hdmatx != NULL)
1895  {
1896  /* Set the DMA Tx abort callback */
1898 
1899  /* Abort DMA in IT mode */
1900  if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
1901  {
1902  /* Update SAI error code */
1903  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1904 
1905  /* Call SAI error callback */
1906 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1907  hsai->ErrorCallback(hsai);
1908 #else
1909  HAL_SAI_ErrorCallback(hsai);
1910 #endif
1911  }
1912  }
1913  if (hsai->hdmarx != NULL)
1914  {
1915  /* Set the DMA Rx abort callback */
1917 
1918  /* Abort DMA in IT mode */
1919  if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
1920  {
1921  /* Update SAI error code */
1922  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1923 
1924  /* Call SAI error callback */
1925 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1926  hsai->ErrorCallback(hsai);
1927 #else
1928  HAL_SAI_ErrorCallback(hsai);
1929 #endif
1930  }
1931  }
1932  }
1933  else
1934  {
1935  /* Abort SAI */
1936  /* No need to check return value because HAL_SAI_ErrorCallback will be called later */
1937  (void) HAL_SAI_Abort(hsai);
1938 
1939  /* Set error callback */
1940 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1941  hsai->ErrorCallback(hsai);
1942 #else
1943  HAL_SAI_ErrorCallback(hsai);
1944 #endif
1945  }
1946  }
1947  /* SAI WCKCFG interrupt occurred ----------------------------------*/
1948  else if (((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG))
1949  {
1950  /* Change the SAI error code */
1951  hsai->ErrorCode |= HAL_SAI_ERROR_WCKCFG;
1952 
1953  /* Check SAI DMA is enabled or not */
1954  if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1955  {
1956  /* Abort the SAI DMA Streams */
1957  if (hsai->hdmatx != NULL)
1958  {
1959  /* Set the DMA Tx abort callback */
1961 
1962  /* Abort DMA in IT mode */
1963  if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
1964  {
1965  /* Update SAI error code */
1966  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1967 
1968  /* Call SAI error callback */
1969 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1970  hsai->ErrorCallback(hsai);
1971 #else
1972  HAL_SAI_ErrorCallback(hsai);
1973 #endif
1974  }
1975  }
1976  if (hsai->hdmarx != NULL)
1977  {
1978  /* Set the DMA Rx abort callback */
1980 
1981  /* Abort DMA in IT mode */
1982  if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
1983  {
1984  /* Update SAI error code */
1985  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1986 
1987  /* Call SAI error callback */
1988 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1989  hsai->ErrorCallback(hsai);
1990 #else
1991  HAL_SAI_ErrorCallback(hsai);
1992 #endif
1993  }
1994  }
1995  }
1996  else
1997  {
1998  /* If WCKCFG occurs, SAI audio block is automatically disabled */
1999  /* Disable all interrupts and clear all flags */
2000  hsai->Instance->IMR = 0U;
2001  hsai->Instance->CLRFR = 0xFFFFFFFFU;
2002  /* Set the SAI state to ready to be able to start again the process */
2003  hsai->State = HAL_SAI_STATE_READY;
2004 
2005  /* Initialize XferCount */
2006  hsai->XferCount = 0U;
2007 
2008  /* SAI error Callback */
2009 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2010  hsai->ErrorCallback(hsai);
2011 #else
2012  HAL_SAI_ErrorCallback(hsai);
2013 #endif
2014  }
2015  }
2016  /* SAI CNRDY interrupt occurred ----------------------------------*/
2017  else if (((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY))
2018  {
2019  /* Clear the SAI CNRDY flag */
2020  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_CNRDY);
2021  /* Change the SAI error code */
2022  hsai->ErrorCode |= HAL_SAI_ERROR_CNREADY;
2023  /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
2024 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2025  hsai->ErrorCallback(hsai);
2026 #else
2027  HAL_SAI_ErrorCallback(hsai);
2028 #endif
2029  }
2030  else
2031  {
2032  /* Nothing to do */
2033  }
2034  }
2035 }
2036 
2044 {
2045  /* Prevent unused argument(s) compilation warning */
2046  UNUSED(hsai);
2047 
2048  /* NOTE : This function should not be modified, when the callback is needed,
2049  the HAL_SAI_TxCpltCallback could be implemented in the user file
2050  */
2051 }
2052 
2060 {
2061  /* Prevent unused argument(s) compilation warning */
2062  UNUSED(hsai);
2063 
2064  /* NOTE : This function should not be modified, when the callback is needed,
2065  the HAL_SAI_TxHalfCpltCallback could be implemented in the user file
2066  */
2067 }
2068 
2076 {
2077  /* Prevent unused argument(s) compilation warning */
2078  UNUSED(hsai);
2079 
2080  /* NOTE : This function should not be modified, when the callback is needed,
2081  the HAL_SAI_RxCpltCallback could be implemented in the user file
2082  */
2083 }
2084 
2092 {
2093  /* Prevent unused argument(s) compilation warning */
2094  UNUSED(hsai);
2095 
2096  /* NOTE : This function should not be modified, when the callback is needed,
2097  the HAL_SAI_RxHalfCpltCallback could be implemented in the user file
2098  */
2099 }
2100 
2108 {
2109  /* Prevent unused argument(s) compilation warning */
2110  UNUSED(hsai);
2111 
2112  /* NOTE : This function should not be modified, when the callback is needed,
2113  the HAL_SAI_ErrorCallback could be implemented in the user file
2114  */
2115 }
2116 
2143 {
2144  return hsai->State;
2145 }
2146 
2154 {
2155  return hsai->ErrorCode;
2156 }
2157 
2182 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
2183 {
2184  HAL_StatusTypeDef status = HAL_OK;
2185 
2186  hsai->Init.Protocol = SAI_FREE_PROTOCOL;
2187  hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
2188  /* Compute ClockStrobing according AudioMode */
2189  if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2190  {
2191  /* Transmit */
2192  hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
2193  }
2194  else
2195  {
2196  /* Receive */
2197  hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
2198  }
2199  hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
2200  hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
2201  hsai->SlotInit.FirstBitOffset = 0;
2202  hsai->SlotInit.SlotNumber = nbslot;
2203 
2204  /* in IS2 the number of slot must be even */
2205  if ((nbslot & 0x1U) != 0U)
2206  {
2207  return HAL_ERROR;
2208  }
2209 
2210  switch (protocol)
2211  {
2212  case SAI_I2S_STANDARD :
2213  hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
2214  hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
2215  break;
2216  case SAI_I2S_MSBJUSTIFIED :
2217  case SAI_I2S_LSBJUSTIFIED :
2218  hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
2219  hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT;
2220  break;
2221  default :
2222  status = HAL_ERROR;
2223  break;
2224  }
2225 
2226  /* Frame definition */
2227  switch (datasize)
2228  {
2229  case SAI_PROTOCOL_DATASIZE_16BIT:
2230  hsai->Init.DataSize = SAI_DATASIZE_16;
2231  hsai->FrameInit.FrameLength = 32U * (nbslot / 2U);
2232  hsai->FrameInit.ActiveFrameLength = 16U * (nbslot / 2U);
2233  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
2234  break;
2235  case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
2236  hsai->Init.DataSize = SAI_DATASIZE_16;
2237  hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2238  hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2239  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2240  break;
2241  case SAI_PROTOCOL_DATASIZE_24BIT:
2242  hsai->Init.DataSize = SAI_DATASIZE_24;
2243  hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2244  hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2245  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2246  break;
2247  case SAI_PROTOCOL_DATASIZE_32BIT:
2248  hsai->Init.DataSize = SAI_DATASIZE_32;
2249  hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2250  hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2251  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2252  break;
2253  default :
2254  status = HAL_ERROR;
2255  break;
2256  }
2257  if (protocol == SAI_I2S_LSBJUSTIFIED)
2258  {
2259  if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED)
2260  {
2261  hsai->SlotInit.FirstBitOffset = 16;
2262  }
2263  if (datasize == SAI_PROTOCOL_DATASIZE_24BIT)
2264  {
2265  hsai->SlotInit.FirstBitOffset = 8;
2266  }
2267  }
2268  return status;
2269 }
2270 
2281 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
2282 {
2283  HAL_StatusTypeDef status = HAL_OK;
2284 
2285  hsai->Init.Protocol = SAI_FREE_PROTOCOL;
2286  hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
2287  /* Compute ClockStrobing according AudioMode */
2288  if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2289  {
2290  /* Transmit */
2291  hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
2292  }
2293  else
2294  {
2295  /* Receive */
2296  hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
2297  }
2298  hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME;
2299  hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
2300  hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
2301  hsai->SlotInit.FirstBitOffset = 0;
2302  hsai->SlotInit.SlotNumber = nbslot;
2303  hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
2304 
2305  switch (protocol)
2306  {
2307  case SAI_PCM_SHORT :
2308  hsai->FrameInit.ActiveFrameLength = 1;
2309  break;
2310  case SAI_PCM_LONG :
2311  hsai->FrameInit.ActiveFrameLength = 13;
2312  break;
2313  default :
2314  status = HAL_ERROR;
2315  break;
2316  }
2317 
2318  switch (datasize)
2319  {
2320  case SAI_PROTOCOL_DATASIZE_16BIT:
2321  hsai->Init.DataSize = SAI_DATASIZE_16;
2322  hsai->FrameInit.FrameLength = 16U * nbslot;
2323  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
2324  break;
2325  case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
2326  hsai->Init.DataSize = SAI_DATASIZE_16;
2327  hsai->FrameInit.FrameLength = 32U * nbslot;
2328  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2329  break;
2330  case SAI_PROTOCOL_DATASIZE_24BIT :
2331  hsai->Init.DataSize = SAI_DATASIZE_24;
2332  hsai->FrameInit.FrameLength = 32U * nbslot;
2333  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2334  break;
2335  case SAI_PROTOCOL_DATASIZE_32BIT:
2336  hsai->Init.DataSize = SAI_DATASIZE_32;
2337  hsai->FrameInit.FrameLength = 32U * nbslot;
2338  hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2339  break;
2340  default :
2341  status = HAL_ERROR;
2342  break;
2343  }
2344 
2345  return status;
2346 }
2347 
2355 {
2356  uint32_t temp;
2357 
2358  /* fill the fifo with data before to enabled the SAI */
2359  while (((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0U))
2360  {
2361  if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
2362  {
2363  hsai->Instance->DR = *hsai->pBuffPtr;
2364  hsai->pBuffPtr++;
2365  }
2366  else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
2367  {
2368  temp = (uint32_t)(*hsai->pBuffPtr);
2369  hsai->pBuffPtr++;
2370  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2371  hsai->pBuffPtr++;
2372  hsai->Instance->DR = temp;
2373  }
2374  else
2375  {
2376  temp = (uint32_t)(*hsai->pBuffPtr);
2377  hsai->pBuffPtr++;
2378  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2379  hsai->pBuffPtr++;
2380  temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
2381  hsai->pBuffPtr++;
2382  temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
2383  hsai->pBuffPtr++;
2384  hsai->Instance->DR = temp;
2385  }
2386  hsai->XferCount--;
2387  }
2388 }
2389 
2397 static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode)
2398 {
2399  uint32_t tmpIT = SAI_IT_OVRUDR;
2400 
2401  if (mode == SAI_MODE_IT)
2402  {
2403  tmpIT |= SAI_IT_FREQ;
2404  }
2405 
2406  if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
2407  ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODEMASTER_RX)))
2408  {
2409  tmpIT |= SAI_IT_CNRDY;
2410  }
2411 
2412  if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2413  {
2414  tmpIT |= SAI_IT_AFSDET | SAI_IT_LFSDET;
2415  }
2416  else
2417  {
2418  /* hsai has been configured in master mode */
2419  tmpIT |= SAI_IT_WCKCFG;
2420  }
2421  return tmpIT;
2422 }
2423 
2430 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
2431 {
2432  register uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock / 7U / 1000U);
2433  HAL_StatusTypeDef status = HAL_OK;
2434 
2435  /* Disable the SAI instance */
2436  __HAL_SAI_DISABLE(hsai);
2437 
2438  do
2439  {
2440  /* Check for the Timeout */
2441  if (count == 0U)
2442  {
2443  /* Update error code */
2444  hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
2445  status = HAL_TIMEOUT;
2446  break;
2447  }
2448  count--;
2449  }
2450  while ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != 0U);
2451 
2452  return status;
2453 }
2454 
2462 {
2463  if (hsai->XferCount == 0U)
2464  {
2465  /* Handle the end of the transmission */
2466  /* Disable FREQ and OVRUDR interrupts */
2467  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2468  hsai->State = HAL_SAI_STATE_READY;
2469 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2470  hsai->TxCpltCallback(hsai);
2471 #else
2472  HAL_SAI_TxCpltCallback(hsai);
2473 #endif
2474  }
2475  else
2476  {
2477  /* Write data on DR register */
2478  hsai->Instance->DR = *hsai->pBuffPtr;
2479  hsai->pBuffPtr++;
2480  hsai->XferCount--;
2481  }
2482 }
2483 
2491 {
2492  if (hsai->XferCount == 0U)
2493  {
2494  /* Handle the end of the transmission */
2495  /* Disable FREQ and OVRUDR interrupts */
2496  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2497  hsai->State = HAL_SAI_STATE_READY;
2498 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2499  hsai->TxCpltCallback(hsai);
2500 #else
2501  HAL_SAI_TxCpltCallback(hsai);
2502 #endif
2503  }
2504  else
2505  {
2506  /* Write data on DR register */
2507  uint32_t temp;
2508  temp = (uint32_t)(*hsai->pBuffPtr);
2509  hsai->pBuffPtr++;
2510  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2511  hsai->pBuffPtr++;
2512  hsai->Instance->DR = temp;
2513  hsai->XferCount--;
2514  }
2515 }
2516 
2524 {
2525  if (hsai->XferCount == 0U)
2526  {
2527  /* Handle the end of the transmission */
2528  /* Disable FREQ and OVRUDR interrupts */
2529  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2530  hsai->State = HAL_SAI_STATE_READY;
2531 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2532  hsai->TxCpltCallback(hsai);
2533 #else
2534  HAL_SAI_TxCpltCallback(hsai);
2535 #endif
2536  }
2537  else
2538  {
2539  /* Write data on DR register */
2540  uint32_t temp;
2541  temp = (uint32_t)(*hsai->pBuffPtr);
2542  hsai->pBuffPtr++;
2543  temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2544  hsai->pBuffPtr++;
2545  temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
2546  hsai->pBuffPtr++;
2547  temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
2548  hsai->pBuffPtr++;
2549  hsai->Instance->DR = temp;
2550  hsai->XferCount--;
2551  }
2552 }
2553 
2561 {
2562  /* Receive data */
2563  *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR;
2564  hsai->pBuffPtr++;
2565  hsai->XferCount--;
2566 
2567  /* Check end of the transfer */
2568  if (hsai->XferCount == 0U)
2569  {
2570  /* Disable TXE and OVRUDR interrupts */
2571  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2572 
2573  /* Clear the SAI Overrun flag */
2574  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2575 
2576  hsai->State = HAL_SAI_STATE_READY;
2577 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2578  hsai->RxCpltCallback(hsai);
2579 #else
2580  HAL_SAI_RxCpltCallback(hsai);
2581 #endif
2582  }
2583 }
2584 
2592 {
2593  uint32_t temp;
2594 
2595  /* Receive data */
2596  temp = hsai->Instance->DR;
2597  *hsai->pBuffPtr = (uint8_t)temp;
2598  hsai->pBuffPtr++;
2599  *hsai->pBuffPtr = (uint8_t)(temp >> 8);
2600  hsai->pBuffPtr++;
2601  hsai->XferCount--;
2602 
2603  /* Check end of the transfer */
2604  if (hsai->XferCount == 0U)
2605  {
2606  /* Disable TXE and OVRUDR interrupts */
2607  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2608 
2609  /* Clear the SAI Overrun flag */
2610  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2611 
2612  hsai->State = HAL_SAI_STATE_READY;
2613 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2614  hsai->RxCpltCallback(hsai);
2615 #else
2616  HAL_SAI_RxCpltCallback(hsai);
2617 #endif
2618  }
2619 }
2620 
2628 {
2629  uint32_t temp;
2630 
2631  /* Receive data */
2632  temp = hsai->Instance->DR;
2633  *hsai->pBuffPtr = (uint8_t)temp;
2634  hsai->pBuffPtr++;
2635  *hsai->pBuffPtr = (uint8_t)(temp >> 8);
2636  hsai->pBuffPtr++;
2637  *hsai->pBuffPtr = (uint8_t)(temp >> 16);
2638  hsai->pBuffPtr++;
2639  *hsai->pBuffPtr = (uint8_t)(temp >> 24);
2640  hsai->pBuffPtr++;
2641  hsai->XferCount--;
2642 
2643  /* Check end of the transfer */
2644  if (hsai->XferCount == 0U)
2645  {
2646  /* Disable TXE and OVRUDR interrupts */
2647  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2648 
2649  /* Clear the SAI Overrun flag */
2650  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2651 
2652  hsai->State = HAL_SAI_STATE_READY;
2653 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2654  hsai->RxCpltCallback(hsai);
2655 #else
2656  HAL_SAI_RxCpltCallback(hsai);
2657 #endif
2658  }
2659 }
2660 
2668 {
2669  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2670 
2671  if (hdma->Init.Mode != DMA_CIRCULAR)
2672  {
2673  hsai->XferCount = 0;
2674 
2675  /* Disable SAI Tx DMA Request */
2676  hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2677 
2678  /* Stop the interrupts error handling */
2679  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2680 
2681  hsai->State = HAL_SAI_STATE_READY;
2682  }
2683 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2684  hsai->TxCpltCallback(hsai);
2685 #else
2686  HAL_SAI_TxCpltCallback(hsai);
2687 #endif
2688 }
2689 
2697 {
2698  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2699 
2700 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2701  hsai->TxHalfCpltCallback(hsai);
2702 #else
2704 #endif
2705 }
2706 
2714 {
2715  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2716 
2717  if (hdma->Init.Mode != DMA_CIRCULAR)
2718  {
2719  /* Disable Rx DMA Request */
2720  hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2721  hsai->XferCount = 0;
2722 
2723  /* Stop the interrupts error handling */
2724  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2725 
2726  hsai->State = HAL_SAI_STATE_READY;
2727  }
2728 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2729  hsai->RxCpltCallback(hsai);
2730 #else
2731  HAL_SAI_RxCpltCallback(hsai);
2732 #endif
2733 }
2734 
2742 {
2743  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2744 
2745 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2746  hsai->RxHalfCpltCallback(hsai);
2747 #else
2749 #endif
2750 }
2751 
2759 {
2760  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2761 
2762  /* Set SAI error code */
2763  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2764 
2765  /* Disable the SAI DMA request */
2766  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2767 
2768  /* Disable SAI peripheral */
2769  /* No need to check return value because state will be updated and HAL_SAI_ErrorCallback will be called later */
2770  (void) SAI_Disable(hsai);
2771 
2772  /* Set the SAI state ready to be able to start again the process */
2773  hsai->State = HAL_SAI_STATE_READY;
2774 
2775  /* Initialize XferCount */
2776  hsai->XferCount = 0U;
2777 
2778  /* SAI error Callback */
2779 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2780  hsai->ErrorCallback(hsai);
2781 #else
2782  HAL_SAI_ErrorCallback(hsai);
2783 #endif
2784 }
2785 
2793 {
2794  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2795 
2796  /* Disable DMA request */
2797  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2798 
2799  /* Disable all interrupts and clear all flags */
2800  hsai->Instance->IMR = 0U;
2801  hsai->Instance->CLRFR = 0xFFFFFFFFU;
2802 
2803  if (hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG)
2804  {
2805  /* Disable SAI peripheral */
2806  /* No need to check return value because state will be updated and HAL_SAI_ErrorCallback will be called later */
2807  (void) SAI_Disable(hsai);
2808 
2809  /* Flush the fifo */
2810  SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
2811  }
2812  /* Set the SAI state to ready to be able to start again the process */
2813  hsai->State = HAL_SAI_STATE_READY;
2814 
2815  /* Initialize XferCount */
2816  hsai->XferCount = 0U;
2817 
2818  /* SAI error Callback */
2819 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2820  hsai->ErrorCallback(hsai);
2821 #else
2822  HAL_SAI_ErrorCallback(hsai);
2823 #endif
2824 }
2825 
2834 #endif /* !STM32L412xx && !STM32L422xx */
2835 #endif /* HAL_SAI_MODULE_ENABLED */
2836 
2841 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
DMA_HandleTypeDef * hdmarx
HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
Receive an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai)
Disable the Rx mute detection.
HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai)
Return the SAI handle state.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
Initialize the SAI PCM protocol according to the specified parameters in the SAI_InitTypeDef and crea...
static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
DMA SAI receive process half complete callback.
static void SAI_FillFifo(SAI_HandleTypeDef *hsai)
Fill the fifo.
static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
Disable the SAI and wait for the disabling.
SAI_ModeTypedef
void(* TxCpltCallback)(struct __SAI_HandleTypeDef *hsai)
HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Receive an amount of data in blocking mode.
DMA handle Structure definition.
void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai)
Handle SAI interrupt request.
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
if(lpuartdiv >=LPUART_BRR_MIN_VALUE)
HAL_SAI_CallbackIDTypeDef
SAI callback ID enumeration definition.
static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
DMA SAI transmit process half complete callback.
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
DeInitialize the SAI peripheral.
HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
Stop the audio stream playing from the Media.
HAL_LockTypeDef Lock
void(* RxHalfCpltCallback)(struct __SAI_HandleTypeDef *hsai)
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Rx Transfer half completed callback.
void(* RxCpltCallback)(struct __SAI_HandleTypeDef *hsai)
HAL_StatusTypeDef HAL_SAI_RegisterCallback(SAI_HandleTypeDef *hsai, HAL_SAI_CallbackIDTypeDef CallbackID, pSAI_CallbackTypeDef pCallback)
Register a user SAI callback to be used instead of the weak predefined callback.
static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode)
Return the interrupt flag to set according the SAI setup.
uint32_t HAL_GetTick(void)
Provide a tick value in millisecond.
uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai)
Return the SAI error code.
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
__HAL_UNLOCK(hrtc)
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
DMA_InitTypeDef Init
HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
Initialize the structure FrameInit, SlotInit and the low part of Init according to the specified para...
static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode 8-Bit transfer.
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
Start the DMA Transfer with interrupt enabled.
CLEAR_BIT(hrtc->Instance->CR, RTC_CR_WUTE)
SAI_Block_TypeDef * Instance
__HAL_LOCK(hrtc)
DMA_HandleTypeDef * hdmatx
__IO HAL_SAI_StateTypeDef State
return HAL_OK
HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Transmit an amount of data in blocking mode.
void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
SAI error callback.
HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai)
Resume the audio stream playing from the Media.
void(* InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai)
void(* pSAI_CallbackTypeDef)(SAI_HandleTypeDef *hsai)
SAI callback pointer definition.
SAI_InitTypeDef Init
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Abort the DMA Transfer.
HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
Transmit an amount of data in non-blocking mode with Interrupt.
HAL_StatusTypeDef HAL_SAI_UnRegisterCallback(SAI_HandleTypeDef *hsai, HAL_SAI_CallbackIDTypeDef CallbackID)
Unregister a user SAI callback. SAI callback is redirected to the weak predefined callback...
static void SAI_DMAError(DMA_HandleTypeDef *hdma)
DMA SAI communication error callback.
HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
Initialize the SAI according to the specified parameters. in the SAI_InitTypeDef structure and initia...
SAI_SlotInitTypeDef SlotInit
static void SAI_DMAAbort(DMA_HandleTypeDef *hdma)
DMA SAI Abort callback.
HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
Enable the Tx mute mode.
void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
DeInitialize the SAI MSP.
HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
Receive an amount of data in non-blocking mode with DMA.
FunctionalState Activation
HAL_SAI_StateTypeDef
HAL State structures definition.
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
Rx Transfer completed callback.
static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode for 32-Bit transfer.
static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma)
DMA SAI transmit process complete callback.
SAI_FrameInitTypeDef FrameInit
HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
Enable the Rx mute detection.
static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma)
DMA SAI receive process complete callback.
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
Return the peripheral clock frequency for peripherals with clock source from PLLSAIs.
void(* SAIcallback)(void)
SAI Callback prototype.
static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode 8-Bit transfer.
SAI_PdmInitTypeDef PdmInit
static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode for 16-Bit transfer.
HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
Transmit an amount of data in non-blocking mode with DMA.
void(* MspDeInitCallback)(struct __SAI_HandleTypeDef *hsai)
void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
Initialize the SAI MSP.
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer completed callback.
void(* TxHalfCpltCallback)(struct __SAI_HandleTypeDef *hsai)
void(* MspInitCallback)(struct __SAI_HandleTypeDef *hsai)
static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
Initialize the SAI I2S protocol according to the specified parameters in the SAI_InitTypeDef and crea...
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))
HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
Pause the audio stream playing from the Media.
HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
Abort the current transfer and disable the SAI.
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer Half completed callback.
static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode for 32-Bit transfer.
void(* ErrorCallback)(struct __SAI_HandleTypeDef *hsai)
HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai)
Disable the Tx mute mode.
static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode for 16-Bit transfer.