STM32F4xx HAL Documentation
Hardware Abstraction Layer for STM32F4 familiy
Loading...
Searching...
No Matches
stm32f4xx_hal_sai.c
Go to the documentation of this file.
1
215/* Includes ------------------------------------------------------------------*/
216#include "stm32f4xx_hal.h"
217
227#ifdef HAL_SAI_MODULE_ENABLED
228
229#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\
230 defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) ||\
231 defined(STM32F423xx)
232
245/* Private define ------------------------------------------------------------*/
246
250#define SAI_DEFAULT_TIMEOUT 4U /* 4ms */
251#define SAI_LONG_TIMEOUT 1000U /* 1s */
256/* Private macro -------------------------------------------------------------*/
257/* Private variables ---------------------------------------------------------*/
258/* Private function prototypes -----------------------------------------------*/
262static void SAI_FillFifo(SAI_HandleTypeDef *hsai);
263static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, uint32_t mode);
264static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
265static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
266
268static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai);
269static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai);
270static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai);
271static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai);
272static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai);
273static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai);
274
275static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma);
276static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
277static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma);
278static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
279static void SAI_DMAError(DMA_HandleTypeDef *hdma);
280static void SAI_DMAAbort(DMA_HandleTypeDef *hdma);
285/* Exported functions ---------------------------------------------------------*/
333HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
334{
335 HAL_StatusTypeDef status = HAL_OK;
336
337 /* Check the parameters */
340
341 switch (protocol)
342 {
343 case SAI_I2S_STANDARD :
346 status = SAI_InitI2S(hsai, protocol, datasize, nbslot);
347 break;
348 case SAI_PCM_LONG :
349 case SAI_PCM_SHORT :
350 status = SAI_InitPCM(hsai, protocol, datasize, nbslot);
351 break;
352 default :
353 status = HAL_ERROR;
354 break;
355 }
356
357 if (status == HAL_OK)
358 {
359 status = HAL_SAI_Init(hsai);
360 }
361
362 return status;
363}
364
373{
374 uint32_t tmpregisterGCR = 0U;
375
376 /* This variable used to store the SAI_CK_x (value in Hz) */
377 uint32_t freq = 0U;
378
379 /* This variable is used to compute CKSTR bits of SAI CR1 according to
380 ClockStrobing and AudioMode fields */
381 uint32_t ckstr_bits = 0U;
382 uint32_t syncen_bits = 0U;
383
384 /* Check the SAI handle allocation */
385 if (hsai == NULL)
386 {
387 return HAL_ERROR;
388 }
389
390 /* check the instance */
391 assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance));
392
393 /* Check the SAI Block parameters */
408
409 /* Check the SAI Block Frame parameters */
415
416 /* Check the SAI Block Slot parameters */
421
422 if (hsai->State == HAL_SAI_STATE_RESET)
423 {
424 /* Allocate lock resource and initialize it */
425 hsai->Lock = HAL_UNLOCKED;
426
427#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
428 /* Reset callback pointers to the weak predefined callbacks */
429 hsai->RxCpltCallback = HAL_SAI_RxCpltCallback;
430 hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback;
431 hsai->TxCpltCallback = HAL_SAI_TxCpltCallback;
432 hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback;
433 hsai->ErrorCallback = HAL_SAI_ErrorCallback;
434
435 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
436 if (hsai->MspInitCallback == NULL)
437 {
438 hsai->MspInitCallback = HAL_SAI_MspInit;
439 }
440 hsai->MspInitCallback(hsai);
441#else
442 /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
443 HAL_SAI_MspInit(hsai);
444#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
445 }
446
448
449 /* Disable the selected SAI peripheral */
450 SAI_Disable(hsai);
451
452 /* SAI Block Synchro Configuration -----------------------------------------*/
454
455 /* Configure Master Clock using the following formula :
456 MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS
457 FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256
458 MCKDIV[3:0] = SAI_CK_x / FS * 512 */
460 {
461 /* Get SAI clock source based on Source clock selection from RCC */
462 freq = SAI_GetInputClock(hsai);
463
464 /* (saiclocksource x 10) to keep Significant digits */
465 tmpregisterGCR = (((freq * 10U) / ((hsai->Init.AudioFrequency) * 512U)));
466
467 hsai->Init.Mckdiv = tmpregisterGCR / 10U;
468
469 /* Round result to the nearest integer */
470 if ((tmpregisterGCR % 10U) > 8U)
471 {
472 hsai->Init.Mckdiv += 1U;
473 }
474
475 /* For SPDIF protocol, SAI shall provide a bit clock twice faster the symbol-rate */
476 if (hsai->Init.Protocol == SAI_SPDIF_PROTOCOL)
477 {
478 hsai->Init.Mckdiv = hsai->Init.Mckdiv >> 1;
479 }
480 }
481
482 /* Check the SAI Block master clock divider parameter */
484
485 /* Compute CKSTR bits of SAI CR1 according to ClockStrobing and AudioMode */
486 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
487 {
488 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U : SAI_xCR1_CKSTR;
489 }
490 else
491 {
492 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0U;
493 }
494
495 /* SAI Block Configuration -------------------------------------------------*/
496 switch (hsai->Init.Synchro)
497 {
498 case SAI_ASYNCHRONOUS :
499 {
500 syncen_bits = 0U;
501 }
502 break;
503 case SAI_SYNCHRONOUS :
504 {
505 syncen_bits = SAI_xCR1_SYNCEN_0;
506 }
507 break;
510 {
511 syncen_bits = SAI_xCR1_SYNCEN_1;
512 }
513 break;
514 default:
515 break;
516 }
517
518 /* SAI CR1 Configuration */
519 hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
520 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
521 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
522 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV);
523
524 hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
525 hsai->Init.DataSize | hsai->Init.FirstBit | \
526 ckstr_bits | syncen_bits | \
527 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
528 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20U));
529
530 /* SAI CR2 Configuration */
531 hsai->Instance->CR2 &= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP | SAI_xCR2_CPL);
532 hsai->Instance->CR2 |= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState);
533
534 /* SAI Frame Configuration -----------------------------------------*/
535 hsai->Instance->FRCR &= (~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \
536 SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF));
537 hsai->Instance->FRCR |= ((hsai->FrameInit.FrameLength - 1U) |
538 hsai->FrameInit.FSOffset |
539 hsai->FrameInit.FSDefinition |
540 hsai->FrameInit.FSPolarity |
541 ((hsai->FrameInit.ActiveFrameLength - 1U) << 8U));
542
543 /* SAI Block_x SLOT Configuration ------------------------------------------*/
544 /* This register has no meaning in AC 97 and SPDIF audio protocol */
545 hsai->Instance->SLOTR &= ~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \
546 SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN);
547
548 hsai->Instance->SLOTR |= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize | \
549 (hsai->SlotInit.SlotActive << 16U) | ((hsai->SlotInit.SlotNumber - 1U) << 8U);
550
551 /* Initialize the error code */
553
554 /* Initialize the SAI state */
556
557 /* Release Lock */
558 __HAL_UNLOCK(hsai);
559
560 return HAL_OK;
561}
562
570{
571 /* Check the SAI handle allocation */
572 if (hsai == NULL)
573 {
574 return HAL_ERROR;
575 }
576
578
579 /* Disabled All interrupt and clear all the flag */
580 hsai->Instance->IMR = 0U;
581 hsai->Instance->CLRFR = 0xFFFFFFFFU;
582
583 /* Disable the SAI */
584 SAI_Disable(hsai);
585
586 /* Flush the fifo */
587 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
588
589 /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
590#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
591 if (hsai->MspDeInitCallback == NULL)
592 {
593 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
594 }
595 hsai->MspDeInitCallback(hsai);
596#else
597 HAL_SAI_MspDeInit(hsai);
598#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
599
600 /* Initialize the error code */
602
603 /* Initialize the SAI state */
605
606 /* Release Lock */
607 __HAL_UNLOCK(hsai);
608
609 return HAL_OK;
610}
611
619{
620 /* Prevent unused argument(s) compilation warning */
621 UNUSED(hsai);
622
623 /* NOTE : This function should not be modified, when the callback is needed,
624 the HAL_SAI_MspInit could be implemented in the user file
625 */
626}
627
635{
636 /* Prevent unused argument(s) compilation warning */
637 UNUSED(hsai);
638
639 /* NOTE : This function should not be modified, when the callback is needed,
640 the HAL_SAI_MspDeInit could be implemented in the user file
641 */
642}
643
644#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
661HAL_StatusTypeDef HAL_SAI_RegisterCallback(SAI_HandleTypeDef *hsai,
662 HAL_SAI_CallbackIDTypeDef CallbackID,
663 pSAI_CallbackTypeDef pCallback)
664{
665 HAL_StatusTypeDef status = HAL_OK;
666
667 if (pCallback == NULL)
668 {
669 /* update the error code */
670 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
671 /* update return status */
672 status = HAL_ERROR;
673 }
674 else
675 {
676 if (HAL_SAI_STATE_READY == hsai->State)
677 {
678 switch (CallbackID)
679 {
680 case HAL_SAI_RX_COMPLETE_CB_ID :
681 hsai->RxCpltCallback = pCallback;
682 break;
683 case HAL_SAI_RX_HALFCOMPLETE_CB_ID :
684 hsai->RxHalfCpltCallback = pCallback;
685 break;
686 case HAL_SAI_TX_COMPLETE_CB_ID :
687 hsai->TxCpltCallback = pCallback;
688 break;
689 case HAL_SAI_TX_HALFCOMPLETE_CB_ID :
690 hsai->TxHalfCpltCallback = pCallback;
691 break;
692 case HAL_SAI_ERROR_CB_ID :
693 hsai->ErrorCallback = pCallback;
694 break;
695 case HAL_SAI_MSPINIT_CB_ID :
696 hsai->MspInitCallback = pCallback;
697 break;
698 case HAL_SAI_MSPDEINIT_CB_ID :
699 hsai->MspDeInitCallback = pCallback;
700 break;
701 default :
702 /* update the error code */
703 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
704 /* update return status */
705 status = HAL_ERROR;
706 break;
707 }
708 }
709 else if (HAL_SAI_STATE_RESET == hsai->State)
710 {
711 switch (CallbackID)
712 {
713 case HAL_SAI_MSPINIT_CB_ID :
714 hsai->MspInitCallback = pCallback;
715 break;
716 case HAL_SAI_MSPDEINIT_CB_ID :
717 hsai->MspDeInitCallback = pCallback;
718 break;
719 default :
720 /* update the error code */
721 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
722 /* update return status */
723 status = HAL_ERROR;
724 break;
725 }
726 }
727 else
728 {
729 /* update the error code */
730 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
731 /* update return status */
732 status = HAL_ERROR;
733 }
734 }
735 return status;
736}
737
753HAL_StatusTypeDef HAL_SAI_UnRegisterCallback(SAI_HandleTypeDef *hsai,
754 HAL_SAI_CallbackIDTypeDef CallbackID)
755{
756 HAL_StatusTypeDef status = HAL_OK;
757
758 if (HAL_SAI_STATE_READY == hsai->State)
759 {
760 switch (CallbackID)
761 {
762 case HAL_SAI_RX_COMPLETE_CB_ID :
763 hsai->RxCpltCallback = HAL_SAI_RxCpltCallback;
764 break;
765 case HAL_SAI_RX_HALFCOMPLETE_CB_ID :
766 hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback;
767 break;
768 case HAL_SAI_TX_COMPLETE_CB_ID :
769 hsai->TxCpltCallback = HAL_SAI_TxCpltCallback;
770 break;
771 case HAL_SAI_TX_HALFCOMPLETE_CB_ID :
772 hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback;
773 break;
774 case HAL_SAI_ERROR_CB_ID :
775 hsai->ErrorCallback = HAL_SAI_ErrorCallback;
776 break;
777 case HAL_SAI_MSPINIT_CB_ID :
778 hsai->MspInitCallback = HAL_SAI_MspInit;
779 break;
780 case HAL_SAI_MSPDEINIT_CB_ID :
781 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
782 break;
783 default :
784 /* update the error code */
785 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
786 /* update return status */
787 status = HAL_ERROR;
788 break;
789 }
790 }
791 else if (HAL_SAI_STATE_RESET == hsai->State)
792 {
793 switch (CallbackID)
794 {
795 case HAL_SAI_MSPINIT_CB_ID :
796 hsai->MspInitCallback = HAL_SAI_MspInit;
797 break;
798 case HAL_SAI_MSPDEINIT_CB_ID :
799 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
800 break;
801 default :
802 /* update the error code */
803 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
804 /* update return status */
805 status = HAL_ERROR;
806 break;
807 }
808 }
809 else
810 {
811 /* update the error code */
812 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
813 /* update return status */
814 status = HAL_ERROR;
815 }
816 return status;
817}
818#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
819
875HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
876{
877 uint32_t tickstart = HAL_GetTick();
878
879 if ((pData == NULL) || (Size == 0))
880 {
881 return HAL_ERROR;
882 }
883
884 if (hsai->State == HAL_SAI_STATE_READY)
885 {
886 /* Process Locked */
887 __HAL_LOCK(hsai);
888
889 hsai->XferSize = Size;
890 hsai->XferCount = Size;
891 hsai->pBuffPtr = pData;
894
895 /* Check if the SAI is already enabled */
896 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
897 {
898 /* fill the fifo with data before to enabled the SAI */
899 SAI_FillFifo(hsai);
900 /* Enable SAI peripheral */
901 __HAL_SAI_ENABLE(hsai);
902 }
903
904 while (hsai->XferCount > 0U)
905 {
906 /* Write data if the FIFO is not full */
907 if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL)
908 {
909 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
910 {
911 hsai->Instance->DR = (*hsai->pBuffPtr++);
912 }
913 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
914 {
915 hsai->Instance->DR = *((uint16_t *)hsai->pBuffPtr);
916 hsai->pBuffPtr += 2U;
917 }
918 else
919 {
920 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
921 hsai->pBuffPtr += 4U;
922 }
923 hsai->XferCount--;
924 }
925 else
926 {
927 /* Check for the Timeout */
928 if ((Timeout != HAL_MAX_DELAY) && ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)))
929 {
930 /* Update error code */
932
933 /* Clear all the flags */
934 hsai->Instance->CLRFR = 0xFFFFFFFFU;
935
936 /* Disable SAI peripheral */
937 SAI_Disable(hsai);
938
939 /* Flush the fifo */
940 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
941
942 /* Change the SAI state */
944
945 /* Process Unlocked */
946 __HAL_UNLOCK(hsai);
947
948 return HAL_ERROR;
949 }
950 }
951 }
952
954
955 /* Process Unlocked */
956 __HAL_UNLOCK(hsai);
957
958 return HAL_OK;
959 }
960 else
961 {
962 return HAL_BUSY;
963 }
964}
965
975HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
976{
977 uint32_t tickstart = HAL_GetTick();
978
979 if ((pData == NULL) || (Size == 0))
980 {
981 return HAL_ERROR;
982 }
983
984 if (hsai->State == HAL_SAI_STATE_READY)
985 {
986 /* Process Locked */
987 __HAL_LOCK(hsai);
988
989 hsai->pBuffPtr = pData;
990 hsai->XferSize = Size;
991 hsai->XferCount = Size;
994
995 /* Check if the SAI is already enabled */
996 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
997 {
998 /* Enable SAI peripheral */
999 __HAL_SAI_ENABLE(hsai);
1000 }
1001
1002 /* Receive data */
1003 while (hsai->XferCount > 0U)
1004 {
1005 if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY)
1006 {
1007 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1008 {
1009 (*hsai->pBuffPtr++) = hsai->Instance->DR;
1010 }
1011 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1012 {
1013 *((uint16_t *)hsai->pBuffPtr) = hsai->Instance->DR;
1014 hsai->pBuffPtr += 2U;
1015 }
1016 else
1017 {
1018 *((uint32_t *)hsai->pBuffPtr) = hsai->Instance->DR;
1019 hsai->pBuffPtr += 4U;
1020 }
1021 hsai->XferCount--;
1022 }
1023 else
1024 {
1025 /* Check for the Timeout */
1026 if ((Timeout != HAL_MAX_DELAY) && ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)))
1027 {
1028 /* Update error code */
1030
1031 /* Clear all the flags */
1032 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1033
1034 /* Disable SAI peripheral */
1035 SAI_Disable(hsai);
1036
1037 /* Flush the fifo */
1038 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1039
1040 /* Change the SAI state */
1041 hsai->State = HAL_SAI_STATE_READY;
1042
1043 /* Process Unlocked */
1044 __HAL_UNLOCK(hsai);
1045
1046 return HAL_ERROR;
1047 }
1048 }
1049 }
1050
1051 hsai->State = HAL_SAI_STATE_READY;
1052
1053 /* Process Unlocked */
1054 __HAL_UNLOCK(hsai);
1055
1056 return HAL_OK;
1057 }
1058 else
1059 {
1060 return HAL_BUSY;
1061 }
1062}
1063
1072HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1073{
1074 if ((pData == NULL) || (Size == 0))
1075 {
1076 return HAL_ERROR;
1077 }
1078
1079 if (hsai->State == HAL_SAI_STATE_READY)
1080 {
1081 /* Process Locked */
1082 __HAL_LOCK(hsai);
1083
1084 hsai->pBuffPtr = pData;
1085 hsai->XferSize = Size;
1086 hsai->XferCount = Size;
1089
1090 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1091 {
1093 }
1094 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1095 {
1097 }
1098 else
1099 {
1101 }
1102
1103 /* Fill the fifo before starting the communication */
1104 SAI_FillFifo(hsai);
1105
1106 /* Enable FRQ and OVRUDR interrupts */
1108
1109 /* Check if the SAI is already enabled */
1110 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1111 {
1112 /* Enable SAI peripheral */
1113 __HAL_SAI_ENABLE(hsai);
1114 }
1115 /* Process Unlocked */
1116 __HAL_UNLOCK(hsai);
1117
1118 return HAL_OK;
1119 }
1120 else
1121 {
1122 return HAL_BUSY;
1123 }
1124}
1125
1134HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1135{
1136 if ((pData == NULL) || (Size == 0))
1137 {
1138 return HAL_ERROR;
1139 }
1140
1141 if (hsai->State == HAL_SAI_STATE_READY)
1142 {
1143 /* Process Locked */
1144 __HAL_LOCK(hsai);
1145
1146 hsai->pBuffPtr = pData;
1147 hsai->XferSize = Size;
1148 hsai->XferCount = Size;
1151
1152 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1153 {
1155 }
1156 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1157 {
1159 }
1160 else
1161 {
1163 }
1164
1165 /* Enable TXE and OVRUDR interrupts */
1167
1168 /* Check if the SAI is already enabled */
1169 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1170 {
1171 /* Enable SAI peripheral */
1172 __HAL_SAI_ENABLE(hsai);
1173 }
1174
1175 /* Process Unlocked */
1176 __HAL_UNLOCK(hsai);
1177
1178 return HAL_OK;
1179 }
1180 else
1181 {
1182 return HAL_BUSY;
1183 }
1184}
1185
1193{
1194 /* Process Locked */
1195 __HAL_LOCK(hsai);
1196
1197 /* Pause the audio file playing by disabling the SAI DMA requests */
1198 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1199
1200 /* Process Unlocked */
1201 __HAL_UNLOCK(hsai);
1202
1203 return HAL_OK;
1204}
1205
1213{
1214 /* Process Locked */
1215 __HAL_LOCK(hsai);
1216
1217 /* Enable the SAI DMA requests */
1218 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1219
1220 /* If the SAI peripheral is still not enabled, enable it */
1221 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1222 {
1223 /* Enable SAI peripheral */
1224 __HAL_SAI_ENABLE(hsai);
1225 }
1226
1227 /* Process Unlocked */
1228 __HAL_UNLOCK(hsai);
1229
1230 return HAL_OK;
1231}
1232
1240{
1241 HAL_StatusTypeDef status = HAL_OK;
1242
1243 /* Process Locked */
1244 __HAL_LOCK(hsai);
1245
1246 /* Disable SAI peripheral */
1247 SAI_Disable(hsai);
1248
1249 /* Disable the SAI DMA request */
1250 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1251
1252 /* Abort the SAI Tx DMA Stream */
1253 if ((hsai->hdmatx != NULL) && (hsai->State == HAL_SAI_STATE_BUSY_TX))
1254 {
1255 if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1256 {
1257 /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */
1259 {
1260 status = HAL_ERROR;
1262 }
1263 }
1264 }
1265
1266 /* Abort the SAI Rx DMA Stream */
1267 if ((hsai->hdmarx != NULL) && (hsai->State == HAL_SAI_STATE_BUSY_RX))
1268 {
1269 if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1270 {
1271 /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */
1273 {
1274 status = HAL_ERROR;
1276 }
1277 }
1278 }
1279
1280 /* Flush the fifo */
1281 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1282
1283 /* Set hsai state to ready */
1284 hsai->State = HAL_SAI_STATE_READY;
1285
1286 /* Process Unlocked */
1287 __HAL_UNLOCK(hsai);
1288
1289 return status;
1290}
1291
1299{
1300 HAL_StatusTypeDef status = HAL_OK;
1301
1302 /* Process Locked */
1303 __HAL_LOCK(hsai);
1304
1305 /* Disable SAI peripheral */
1306 SAI_Disable(hsai);
1307
1308 /* Check SAI DMA is enabled or not */
1309 if ((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1310 {
1311 /* Disable the SAI DMA request */
1312 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1313
1314 /* Abort the SAI Tx DMA Stream */
1315 if ((hsai->hdmatx != NULL) && (hsai->State == HAL_SAI_STATE_BUSY_TX))
1316 {
1317 if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1318 {
1319 /* If the DMA Tx errorCode is different from DMA No Transfer then return Error */
1321 {
1322 status = HAL_ERROR;
1324 }
1325 }
1326 }
1327
1328 /* Abort the SAI Rx DMA Stream */
1329 if ((hsai->hdmarx != NULL) && (hsai->State == HAL_SAI_STATE_BUSY_RX))
1330 {
1331 if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1332 {
1333 /* If the DMA Rx errorCode is different from DMA No Transfer then return Error */
1335 {
1336 status = HAL_ERROR;
1338 }
1339 }
1340 }
1341 }
1342
1343 /* Disabled All interrupt and clear all the flag */
1344 hsai->Instance->IMR = 0U;
1345 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1346
1347 /* Flush the fifo */
1348 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1349
1350 /* Set hsai state to ready */
1351 hsai->State = HAL_SAI_STATE_READY;
1352
1353 /* Process Unlocked */
1354 __HAL_UNLOCK(hsai);
1355
1356 return status;
1357}
1358
1367HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1368{
1369 uint32_t tickstart = HAL_GetTick();
1370
1371 if ((pData == NULL) || (Size == 0))
1372 {
1373 return HAL_ERROR;
1374 }
1375
1376 if (hsai->State == HAL_SAI_STATE_READY)
1377 {
1378 /* Process Locked */
1379 __HAL_LOCK(hsai);
1380
1381 hsai->pBuffPtr = pData;
1382 hsai->XferSize = Size;
1383 hsai->XferCount = Size;
1386
1387 /* Set the SAI Tx DMA Half transfer complete callback */
1389
1390 /* Set the SAI TxDMA transfer complete callback */
1392
1393 /* Set the DMA error callback */
1395
1396 /* Set the DMA Tx abort callback */
1397 hsai->hdmatx->XferAbortCallback = NULL;
1398
1399 /* Enable the Tx DMA Stream */
1400 if (HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
1401 {
1402 __HAL_UNLOCK(hsai);
1403 return HAL_ERROR;
1404 }
1405
1406 /* Enable the interrupts for error handling */
1408
1409 /* Enable SAI Tx DMA Request */
1410 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1411
1412 /* Wait until FIFO is not empty */
1413 while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY)
1414 {
1415 /* Check for the Timeout */
1416 if ((HAL_GetTick() - tickstart) > SAI_LONG_TIMEOUT)
1417 {
1418 /* Update error code */
1420
1421 /* Process Unlocked */
1422 __HAL_UNLOCK(hsai);
1423
1424 return HAL_TIMEOUT;
1425 }
1426 }
1427
1428 /* Check if the SAI is already enabled */
1429 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1430 {
1431 /* Enable SAI peripheral */
1432 __HAL_SAI_ENABLE(hsai);
1433 }
1434
1435 /* Process Unlocked */
1436 __HAL_UNLOCK(hsai);
1437
1438 return HAL_OK;
1439 }
1440 else
1441 {
1442 return HAL_BUSY;
1443 }
1444}
1445
1454HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1455{
1456 if ((pData == NULL) || (Size == 0))
1457 {
1458 return HAL_ERROR;
1459 }
1460
1461 if (hsai->State == HAL_SAI_STATE_READY)
1462 {
1463 /* Process Locked */
1464 __HAL_LOCK(hsai);
1465
1466 hsai->pBuffPtr = pData;
1467 hsai->XferSize = Size;
1468 hsai->XferCount = Size;
1471
1472 /* Set the SAI Rx DMA Half transfer complete callback */
1474
1475 /* Set the SAI Rx DMA transfer complete callback */
1477
1478 /* Set the DMA error callback */
1480
1481 /* Set the DMA Rx abort callback */
1482 hsai->hdmarx->XferAbortCallback = NULL;
1483
1484 /* Enable the Rx DMA Stream */
1485 if (HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
1486 {
1487 __HAL_UNLOCK(hsai);
1488 return HAL_ERROR;
1489 }
1490
1491 /* Enable the interrupts for error handling */
1493
1494 /* Enable SAI Rx DMA Request */
1495 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1496
1497 /* Check if the SAI is already enabled */
1498 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1499 {
1500 /* Enable SAI peripheral */
1501 __HAL_SAI_ENABLE(hsai);
1502 }
1503
1504 /* Process Unlocked */
1505 __HAL_UNLOCK(hsai);
1506
1507 return HAL_OK;
1508 }
1509 else
1510 {
1511 return HAL_BUSY;
1512 }
1513}
1514
1523{
1525
1526 if (hsai->State != HAL_SAI_STATE_RESET)
1527 {
1528 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1529 SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | val);
1530 return HAL_OK;
1531 }
1532 return HAL_ERROR;
1533}
1534
1542{
1543 if (hsai->State != HAL_SAI_STATE_RESET)
1544 {
1545 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1546 return HAL_OK;
1547 }
1548 return HAL_ERROR;
1549}
1550
1560{
1562
1563 if (hsai->State != HAL_SAI_STATE_RESET)
1564 {
1565 /* set the mute counter */
1566 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT);
1567 SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_Pos));
1568 hsai->mutecallback = callback;
1569 /* enable the IT interrupt */
1571 return HAL_OK;
1572 }
1573 return HAL_ERROR;
1574}
1575
1583{
1584 if (hsai->State != HAL_SAI_STATE_RESET)
1585 {
1586 /* set the mutecallback to NULL */
1587 hsai->mutecallback = (SAIcallback)NULL;
1588 /* enable the IT interrupt */
1590 return HAL_OK;
1591 }
1592 return HAL_ERROR;
1593}
1594
1602{
1603 if (hsai->State != HAL_SAI_STATE_RESET)
1604 {
1605 uint32_t itflags = hsai->Instance->SR;
1606 uint32_t itsources = hsai->Instance->IMR;
1607 uint32_t cr1config = hsai->Instance->CR1;
1608 uint32_t tmperror;
1609
1610 /* SAI Fifo request interrupt occurred ------------------------------------*/
1611 if (((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ))
1612 {
1613 hsai->InterruptServiceRoutine(hsai);
1614 }
1615 /* SAI Overrun error interrupt occurred ----------------------------------*/
1616 else if (((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR))
1617 {
1618 /* Clear the SAI Overrun flag */
1620
1621 /* Get the SAI error code */
1623
1624 /* Change the SAI error code */
1625 hsai->ErrorCode |= tmperror;
1626
1627 /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
1628#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1629 hsai->ErrorCallback(hsai);
1630#else
1632#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
1633 }
1634 /* SAI mutedet interrupt occurred ----------------------------------*/
1635 else if (((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET))
1636 {
1637 /* Clear the SAI mutedet flag */
1639
1640 /* call the call back function */
1641 if (hsai->mutecallback != (SAIcallback)NULL)
1642 {
1643 /* inform the user that an RX mute event has been detected */
1644 hsai->mutecallback();
1645 }
1646 }
1647 /* SAI AFSDET interrupt occurred ----------------------------------*/
1648 else if (((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET))
1649 {
1650 /* Clear the SAI AFSDET flag */
1652
1653 /* Change the SAI error code */
1655
1656 /* Check SAI DMA is enabled or not */
1657 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1658 {
1659 /* Abort the SAI DMA Streams */
1660 if (hsai->hdmatx != NULL)
1661 {
1662 /* Set the DMA Tx abort callback */
1664
1665 /* Abort DMA in IT mode */
1666 HAL_DMA_Abort_IT(hsai->hdmatx);
1667 }
1668 else if (hsai->hdmarx != NULL)
1669 {
1670 /* Set the DMA Rx abort callback */
1672
1673 /* Abort DMA in IT mode */
1674 HAL_DMA_Abort_IT(hsai->hdmarx);
1675 }
1676 }
1677 else
1678 {
1679 /* Abort SAI */
1680 HAL_SAI_Abort(hsai);
1681
1682 /* Set error callback */
1683#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1684 hsai->ErrorCallback(hsai);
1685#else
1687#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
1688 }
1689 }
1690 /* SAI LFSDET interrupt occurred ----------------------------------*/
1691 else if (((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET))
1692 {
1693 /* Clear the SAI LFSDET flag */
1695
1696 /* Change the SAI error code */
1698
1699 /* Check SAI DMA is enabled or not */
1700 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1701 {
1702 /* Abort the SAI DMA Streams */
1703 if (hsai->hdmatx != NULL)
1704 {
1705 /* Set the DMA Tx abort callback */
1707
1708 /* Abort DMA in IT mode */
1709 HAL_DMA_Abort_IT(hsai->hdmatx);
1710 }
1711 else if (hsai->hdmarx != NULL)
1712 {
1713 /* Set the DMA Rx abort callback */
1715
1716 /* Abort DMA in IT mode */
1717 HAL_DMA_Abort_IT(hsai->hdmarx);
1718 }
1719 }
1720 else
1721 {
1722 /* Abort SAI */
1723 HAL_SAI_Abort(hsai);
1724
1725 /* Set error callback */
1726#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1727 hsai->ErrorCallback(hsai);
1728#else
1730#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
1731 }
1732 }
1733 /* SAI WCKCFG interrupt occurred ----------------------------------*/
1734 else if (((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG))
1735 {
1736 /* Clear the SAI WCKCFG flag */
1738
1739 /* Change the SAI error code */
1741
1742 /* Check SAI DMA is enabled or not */
1743 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1744 {
1745 /* Abort the SAI DMA Streams */
1746 if (hsai->hdmatx != NULL)
1747 {
1748 /* Set the DMA Tx abort callback */
1750
1751 /* Abort DMA in IT mode */
1752 HAL_DMA_Abort_IT(hsai->hdmatx);
1753 }
1754 else if (hsai->hdmarx != NULL)
1755 {
1756 /* Set the DMA Rx abort callback */
1758
1759 /* Abort DMA in IT mode */
1760 HAL_DMA_Abort_IT(hsai->hdmarx);
1761 }
1762 }
1763 else
1764 {
1765 /* If WCKCFG occurs, SAI audio block is automatically disabled */
1766 /* Disable all interrupts and clear all flags */
1767 hsai->Instance->IMR = 0U;
1768 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1769
1770 /* Set the SAI state to ready to be able to start again the process */
1771 hsai->State = HAL_SAI_STATE_READY;
1772
1773 /* Initialize XferCount */
1774 hsai->XferCount = 0U;
1775
1776 /* SAI error Callback */
1777#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1778 hsai->ErrorCallback(hsai);
1779#else
1781#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
1782 }
1783 }
1784 /* SAI CNRDY interrupt occurred ----------------------------------*/
1785 else if (((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY))
1786 {
1787 /* Clear the SAI CNRDY flag */
1789
1790 /* Change the SAI error code */
1792
1793 /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
1794#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1795 hsai->ErrorCallback(hsai);
1796#else
1798#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
1799 }
1800 else
1801 {
1802 /* Nothing to do */
1803 }
1804 }
1805}
1806
1814{
1815 /* Prevent unused argument(s) compilation warning */
1816 UNUSED(hsai);
1817
1818 /* NOTE : This function should not be modified, when the callback is needed,
1819 the HAL_SAI_TxCpltCallback could be implemented in the user file
1820 */
1821}
1822
1830{
1831 /* Prevent unused argument(s) compilation warning */
1832 UNUSED(hsai);
1833
1834 /* NOTE : This function should not be modified, when the callback is needed,
1835 the HAL_SAI_TxHalfCpltCallback could be implemented in the user file
1836 */
1837}
1838
1846{
1847 /* Prevent unused argument(s) compilation warning */
1848 UNUSED(hsai);
1849
1850 /* NOTE : This function should not be modified, when the callback is needed,
1851 the HAL_SAI_RxCpltCallback could be implemented in the user file
1852 */
1853}
1854
1862{
1863 /* Prevent unused argument(s) compilation warning */
1864 UNUSED(hsai);
1865
1866 /* NOTE : This function should not be modified, when the callback is needed,
1867 the HAL_SAI_RxHalfCpltCallback could be implemented in the user file
1868 */
1869}
1870
1878{
1879 /* Prevent unused argument(s) compilation warning */
1880 UNUSED(hsai);
1881
1882 /* NOTE : This function should not be modified, when the callback is needed,
1883 the HAL_SAI_ErrorCallback could be implemented in the user file
1884 */
1885}
1886
1913{
1914 return hsai->State;
1915}
1916
1924{
1925 return hsai->ErrorCode;
1926}
1952static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
1953{
1956 /* Compute ClockStrobing according AudioMode */
1957 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
1958 {
1959 /* Transmit */
1961 }
1962 else
1963 {
1964 /* Receive */
1966 }
1969 hsai->SlotInit.FirstBitOffset = 0U;
1970 hsai->SlotInit.SlotNumber = nbslot;
1971
1972 /* in IS2 the number of slot must be even */
1973 if ((nbslot & 0x1U) != 0U)
1974 {
1975 return HAL_ERROR;
1976 }
1977
1978 if (protocol == SAI_I2S_STANDARD)
1979 {
1982 }
1983 else
1984 {
1985 /* SAI_I2S_MSBJUSTIFIED or SAI_I2S_LSBJUSTIFIED */
1988 }
1989
1990 /* Frame definition */
1991 switch (datasize)
1992 {
1995 hsai->FrameInit.FrameLength = 32U * (nbslot / 2U);
1996 hsai->FrameInit.ActiveFrameLength = 16U * (nbslot / 2U);
1998 break;
2001 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2002 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2004 break;
2007 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2008 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2010 break;
2013 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2014 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2016 break;
2017 default :
2018 return HAL_ERROR;
2019 }
2020 if (protocol == SAI_I2S_LSBJUSTIFIED)
2021 {
2023 {
2024 hsai->SlotInit.FirstBitOffset = 16U;
2025 }
2026 if (datasize == SAI_PROTOCOL_DATASIZE_24BIT)
2027 {
2028 hsai->SlotInit.FirstBitOffset = 8U;
2029 }
2030 }
2031 return HAL_OK;
2032}
2033
2044static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
2045{
2048 /* Compute ClockStrobing according AudioMode */
2049 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2050 {
2051 /* Transmit */
2053 }
2054 else
2055 {
2056 /* Receive */
2058 }
2062 hsai->SlotInit.FirstBitOffset = 0U;
2063 hsai->SlotInit.SlotNumber = nbslot;
2065
2066 if (protocol == SAI_PCM_SHORT)
2067 {
2068 hsai->FrameInit.ActiveFrameLength = 1;
2069 }
2070 else
2071 {
2072 /* SAI_PCM_LONG */
2073 hsai->FrameInit.ActiveFrameLength = 13;
2074 }
2075
2076 switch (datasize)
2077 {
2080 hsai->FrameInit.FrameLength = 16U * nbslot;
2082 break;
2085 hsai->FrameInit.FrameLength = 32U * nbslot;
2087 break;
2090 hsai->FrameInit.FrameLength = 32U * nbslot;
2092 break;
2095 hsai->FrameInit.FrameLength = 32U * nbslot;
2097 break;
2098 default :
2099 return HAL_ERROR;
2100 }
2101
2102 return HAL_OK;
2103}
2104
2112{
2113 /* fill the fifo with data before to enabled the SAI */
2114 while (((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0U))
2115 {
2116 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
2117 {
2118 hsai->Instance->DR = (*hsai->pBuffPtr++);
2119 }
2120 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
2121 {
2122 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
2123 hsai->pBuffPtr += 2U;
2124 }
2125 else
2126 {
2127 hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
2128 hsai->pBuffPtr += 4U;
2129 }
2130 hsai->XferCount--;
2131 }
2132}
2133
2141static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, uint32_t mode)
2142{
2143 uint32_t tmpIT = SAI_IT_OVRUDR;
2144
2145 if (mode == SAI_MODE_IT)
2146 {
2147 tmpIT |= SAI_IT_FREQ;
2148 }
2149
2150 if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
2152 {
2153 tmpIT |= SAI_IT_CNRDY;
2154 }
2155
2156 if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2157 {
2158 tmpIT |= SAI_IT_AFSDET | SAI_IT_LFSDET;
2159 }
2160 else
2161 {
2162 /* hsai has been configured in master mode */
2163 tmpIT |= SAI_IT_WCKCFG;
2164 }
2165 return tmpIT;
2166}
2167
2175{
2176 uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock / 7U / 1000U);
2177 HAL_StatusTypeDef status = HAL_OK;
2178
2179 /* Disable the SAI instance */
2180 __HAL_SAI_DISABLE(hsai);
2181
2182 do
2183 {
2184 /* Check for the Timeout */
2185 if (count-- == 0U)
2186 {
2187 /* Update error code */
2189 status = HAL_TIMEOUT;
2190 break;
2191 }
2192 }
2193 while ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != RESET);
2194
2195 return status;
2196}
2197
2205{
2206 if (hsai->XferCount == 0U)
2207 {
2208 /* Handle the end of the transmission */
2209 /* Disable FREQ and OVRUDR interrupts */
2211 hsai->State = HAL_SAI_STATE_READY;
2212#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2213 hsai->TxCpltCallback(hsai);
2214#else
2216#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2217 }
2218 else
2219 {
2220 /* Write data on DR register */
2221 hsai->Instance->DR = (*hsai->pBuffPtr++);
2222 hsai->XferCount--;
2223 }
2224}
2225
2233{
2234 if (hsai->XferCount == 0U)
2235 {
2236 /* Handle the end of the transmission */
2237 /* Disable FREQ and OVRUDR interrupts */
2239 hsai->State = HAL_SAI_STATE_READY;
2240#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2241 hsai->TxCpltCallback(hsai);
2242#else
2244#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2245 }
2246 else
2247 {
2248 /* Write data on DR register */
2249 hsai->Instance->DR = *(uint16_t *)hsai->pBuffPtr;
2250 hsai->pBuffPtr += 2U;
2251 hsai->XferCount--;
2252 }
2253}
2254
2262{
2263 if (hsai->XferCount == 0U)
2264 {
2265 /* Handle the end of the transmission */
2266 /* Disable FREQ and OVRUDR interrupts */
2268 hsai->State = HAL_SAI_STATE_READY;
2269#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2270 hsai->TxCpltCallback(hsai);
2271#else
2273#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2274 }
2275 else
2276 {
2277 /* Write data on DR register */
2278 hsai->Instance->DR = *(uint32_t *)hsai->pBuffPtr;
2279 hsai->pBuffPtr += 4U;
2280 hsai->XferCount--;
2281 }
2282}
2283
2291{
2292 /* Receive data */
2293 (*hsai->pBuffPtr++) = hsai->Instance->DR;
2294 hsai->XferCount--;
2295
2296 /* Check end of the transfer */
2297 if (hsai->XferCount == 0U)
2298 {
2299 /* Disable TXE and OVRUDR interrupts */
2301
2302 /* Clear the SAI Overrun flag */
2304
2305 hsai->State = HAL_SAI_STATE_READY;
2306#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2307 hsai->RxCpltCallback(hsai);
2308#else
2310#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2311 }
2312}
2313
2321{
2322 /* Receive data */
2323 *(uint16_t *)hsai->pBuffPtr = hsai->Instance->DR;
2324 hsai->pBuffPtr += 2U;
2325 hsai->XferCount--;
2326
2327 /* Check end of the transfer */
2328 if (hsai->XferCount == 0U)
2329 {
2330 /* Disable TXE and OVRUDR interrupts */
2332
2333 /* Clear the SAI Overrun flag */
2335
2336 hsai->State = HAL_SAI_STATE_READY;
2337#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2338 hsai->RxCpltCallback(hsai);
2339#else
2341#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2342 }
2343}
2344
2352{
2353 /* Receive data */
2354 *(uint32_t *)hsai->pBuffPtr = hsai->Instance->DR;
2355 hsai->pBuffPtr += 4U;
2356 hsai->XferCount--;
2357
2358 /* Check end of the transfer */
2359 if (hsai->XferCount == 0U)
2360 {
2361 /* Disable TXE and OVRUDR interrupts */
2363
2364 /* Clear the SAI Overrun flag */
2366
2367 hsai->State = HAL_SAI_STATE_READY;
2368#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2369 hsai->RxCpltCallback(hsai);
2370#else
2372#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2373 }
2374}
2375
2383{
2384 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2385
2386 if (hdma->Init.Mode != DMA_CIRCULAR)
2387 {
2388 hsai->XferCount = 0U;
2389
2390 /* Disable SAI Tx DMA Request */
2391 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2392
2393 /* Stop the interrupts error handling */
2395
2396 hsai->State = HAL_SAI_STATE_READY;
2397 }
2398#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2399 hsai->TxCpltCallback(hsai);
2400#else
2402#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2403}
2404
2412{
2413 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2414
2415#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2416 hsai->TxHalfCpltCallback(hsai);
2417#else
2419#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2420}
2421
2429{
2430 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2431
2432 if (hdma->Init.Mode != DMA_CIRCULAR)
2433 {
2434 /* Disable Rx DMA Request */
2435 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2436 hsai->XferCount = 0U;
2437
2438 /* Stop the interrupts error handling */
2440
2441 hsai->State = HAL_SAI_STATE_READY;
2442 }
2443#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2444 hsai->RxCpltCallback(hsai);
2445#else
2447#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2448}
2449
2457{
2458 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2459
2460#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2461 hsai->RxHalfCpltCallback(hsai);
2462#else
2464#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2465}
2466
2474{
2475 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2476
2477 /* Set SAI error code */
2479
2480 if ((hsai->hdmatx->ErrorCode == HAL_DMA_ERROR_TE) || (hsai->hdmarx->ErrorCode == HAL_DMA_ERROR_TE))
2481 {
2482 /* Disable the SAI DMA request */
2483 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2484
2485 /* Disable SAI peripheral */
2486 SAI_Disable(hsai);
2487
2488 /* Set the SAI state ready to be able to start again the process */
2489 hsai->State = HAL_SAI_STATE_READY;
2490
2491 /* Initialize XferCount */
2492 hsai->XferCount = 0U;
2493 }
2494 /* SAI error Callback */
2495#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2496 hsai->ErrorCallback(hsai);
2497#else
2499#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2500}
2501
2509{
2510 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2511
2512 /* Disable DMA request */
2513 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2514
2515 /* Disable all interrupts and clear all flags */
2516 hsai->Instance->IMR = 0U;
2517 hsai->Instance->CLRFR = 0xFFFFFFFFU;
2518
2519 if (hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG)
2520 {
2521 /* Disable SAI peripheral */
2522 SAI_Disable(hsai);
2523
2524 /* Flush the fifo */
2525 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
2526 }
2527 /* Set the SAI state to ready to be able to start again the process */
2528 hsai->State = HAL_SAI_STATE_READY;
2529
2530 /* Initialize XferCount */
2531 hsai->XferCount = 0U;
2532
2533 /* SAI error Callback */
2534#if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2535 hsai->ErrorCallback(hsai);
2536#else
2538#endif /* USE_HAL_SAI_REGISTER_CALLBACKS */
2539}
2540
2545#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx || STM32F423xx */
2546#endif /* HAL_SAI_MODULE_ENABLED */
#define HAL_DMA_ERROR_TE
#define HAL_DMA_ERROR_NO_XFER
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer.
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
Aborts the DMA Transfer in Interrupt mode.
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.
#define DMA_CIRCULAR
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
void SAI_BlockSynchroConfig(const SAI_HandleTypeDef *hsai)
Configure SAI Block synchronization mode.
uint32_t SAI_GetInputClock(const SAI_HandleTypeDef *hsai)
Get SAI Input Clock based on SAI source clock selection.
#define SAI_AUDIO_FREQUENCY_MCKDIV
#define SAI_CLOCKSTROBING_FALLINGEDGE
#define SAI_CLOCKSTROBING_RISINGEDGE
#define SAI_NOCOMPANDING
#define SAI_DATASIZE_16
#define SAI_DATASIZE_32
#define SAI_DATASIZE_24
#define SAI_DATASIZE_8
#define SAI_FS_STARTFRAME
#define SAI_FS_CHANNEL_IDENTIFICATION
#define SAI_FS_FIRSTBIT
#define SAI_FS_BEFOREFIRSTBIT
#define SAI_FS_ACTIVE_LOW
#define SAI_FS_ACTIVE_HIGH
#define SAI_FIFOSTATUS_FULL
#define SAI_FIFOSTATUS_EMPTY
#define SAI_FLAG_LFSDET
#define SAI_FLAG_WCKCFG
#define SAI_FLAG_OVRUDR
#define SAI_FLAG_MUTEDET
#define SAI_FLAG_CNRDY
#define SAI_FLAG_AFSDET
#define SAI_IT_CNRDY
#define SAI_IT_LFSDET
#define SAI_IT_WCKCFG
#define SAI_IT_FREQ
#define SAI_IT_AFSDET
#define SAI_IT_OVRUDR
#define SAI_IT_MUTEDET
#define SAI_FIRSTBIT_MSB
#define SAI_MODESLAVE_TX
#define SAI_MODEMASTER_RX
#define SAI_MODESLAVE_RX
#define SAI_MODEMASTER_TX
#define SAI_SPDIF_PROTOCOL
#define SAI_AC97_PROTOCOL
#define SAI_FREE_PROTOCOL
#define SAI_SLOTACTIVE_ALL
#define SAI_SLOTSIZE_32B
#define SAI_SLOTSIZE_16B
#define SAI_SYNCHRONOUS_EXT_SAI1
#define SAI_SYNCHRONOUS
#define SAI_ASYNCHRONOUS
#define SAI_SYNCHRONOUS_EXT_SAI2
#define HAL_SAI_ERROR_UDR
#define HAL_SAI_ERROR_LFSDET
#define HAL_SAI_ERROR_CNREADY
#define HAL_SAI_ERROR_NONE
#define HAL_SAI_ERROR_TIMEOUT
#define HAL_SAI_ERROR_WCKCFG
#define HAL_SAI_ERROR_DMA
#define HAL_SAI_ERROR_AFSDET
#define HAL_SAI_ERROR_OVR
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...
void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
Initialize the SAI MSP.
void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
DeInitialize the SAI MSP.
HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
Initialize the SAI according to the specified parameters. in the SAI_InitTypeDef structure and initia...
HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
DeInitialize the SAI peripheral.
HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
Abort the current transfer and disable the SAI.
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.
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer completed callback.
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.
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_DMAResume(SAI_HandleTypeDef *hsai)
Resume the audio stream playing from the Media.
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_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
Enable the Rx mute detection.
HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
Stop the audio stream playing from the Media.
void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai)
Handle SAI interrupt request.
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.
HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
Pause the audio stream playing from the Media.
void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
SAI error callback.
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Rx Transfer half completed callback.
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 HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer Half completed callback.
HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai)
Disable the Tx mute mode.
HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
Enable the Tx mute mode.
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
Rx Transfer completed callback.
uint32_t HAL_SAI_GetError(const SAI_HandleTypeDef *hsai)
Return the SAI error code.
HAL_SAI_StateTypeDef HAL_SAI_GetState(const SAI_HandleTypeDef *hsai)
Return the SAI handle state.
#define __HAL_SAI_CLEAR_FLAG(__HANDLE__, __FLAG__)
Clear the specified SAI pending flag.
#define __HAL_SAI_DISABLE_IT(__HANDLE__, __INTERRUPT__)
#define __HAL_SAI_ENABLE(__HANDLE__)
Enable SAI.
#define __HAL_SAI_DISABLE(__HANDLE__)
Disable SAI.
#define __HAL_SAI_ENABLE_IT(__HANDLE__, __INTERRUPT__)
Enable or disable the specified SAI interrupts.
void(* SAIcallback)(void)
SAI Callback prototype.
HAL_SAI_StateTypeDef
HAL State structures definition.
@ HAL_SAI_STATE_RESET
@ HAL_SAI_STATE_BUSY_RX
@ HAL_SAI_STATE_READY
@ HAL_SAI_STATE_BUSY
@ HAL_SAI_STATE_BUSY_TX
#define SAI_LONG_TIMEOUT
#define SAI_DEFAULT_TIMEOUT
static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode for 32-Bit transfer.
static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma)
DMA SAI receive process complete callback.
static void SAI_DMAAbort(DMA_HandleTypeDef *hdma)
DMA SAI Abort callback.
static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode for 32-Bit transfer.
static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode 8-Bit transfer.
static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode 8-Bit transfer.
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...
static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai)
Tx Handler for Transmit in Interrupt mode for 16-Bit transfer.
static void SAI_DMAError(DMA_HandleTypeDef *hdma)
DMA SAI communication error callback.
static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
DMA SAI receive process half complete callback.
static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
Disable the SAI and wait for the disabling.
static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
DMA SAI transmit process half complete callback.
static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai)
Rx Handler for Receive in Interrupt mode for 16-Bit transfer.
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_DMATxCplt(DMA_HandleTypeDef *hdma)
DMA SAI transmit process complete callback.
static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, uint32_t mode)
Return the interrupt flag to set according the SAI setup.
static void SAI_FillFifo(SAI_HandleTypeDef *hsai)
Fill the fifo.
#define IS_SAI_BLOCK_FIRSTBIT_OFFSET(OFFSET)
#define IS_SAI_BLOCK_MUTE_COUNTER(COUNTER)
#define IS_SAI_SUPPORTED_PROTOCOL(PROTOCOL)
#define IS_SAI_BLOCK_ACTIVE_FRAME(LENGTH)
#define IS_SAI_BLOCK_FS_OFFSET(OFFSET)
#define IS_SAI_BLOCK_SLOT_SIZE(SIZE)
#define IS_SAI_BLOCK_MODE(MODE)
#define IS_SAI_BLOCK_FIRST_BIT(BIT)
#define IS_SAI_BLOCK_MASTER_DIVIDER(DIVIDER)
#define IS_SAI_BLOCK_OUTPUT_DRIVE(DRIVE)
#define IS_SAI_BLOCK_PROTOCOL(PROTOCOL)
#define IS_SAI_BLOCK_SLOT_NUMBER(NUMBER)
#define IS_SAI_MONO_STEREO_MODE(MODE)
#define IS_SAI_BLOCK_SYNCHRO(SYNCHRO)
#define IS_SAI_SLOT_ACTIVE(ACTIVE)
#define IS_SAI_BLOCK_FS_POLARITY(POLARITY)
#define IS_SAI_BLOCK_MUTE_VALUE(VALUE)
#define IS_SAI_BLOCK_FS_DEFINITION(DEFINITION)
#define IS_SAI_BLOCK_FRAME_LENGTH(LENGTH)
#define IS_SAI_BLOCK_NODIVIDER(NODIVIDER)
#define IS_SAI_BLOCK_TRISTATE_MANAGEMENT(STATE)
#define IS_SAI_AUDIO_FREQUENCY(AUDIO)
#define IS_SAI_BLOCK_SYNCEXT(STATE)
#define IS_SAI_BLOCK_FIFO_THRESHOLD(THRESHOLD)
#define IS_SAI_BLOCK_COMPANDING_MODE(MODE)
#define IS_SAI_PROTOCOL_DATASIZE(DATASIZE)
#define IS_SAI_BLOCK_CLOCK_STROBING(CLOCK)
#define IS_SAI_BLOCK_DATASIZE(DATASIZE)
SAI_ModeTypedef
@ SAI_MODE_IT
@ SAI_MODE_DMA
#define SAI_PROTOCOL_DATASIZE_16BIT
#define SAI_PROTOCOL_DATASIZE_32BIT
#define SAI_PROTOCOL_DATASIZE_24BIT
#define SAI_PROTOCOL_DATASIZE_16BITEXTENDED
#define SAI_I2S_LSBJUSTIFIED
#define SAI_PCM_SHORT
#define SAI_I2S_MSBJUSTIFIED
#define SAI_PCM_LONG
#define SAI_I2S_STANDARD
#define assert_param(expr)
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef
HAL Status structures definition
@ HAL_TIMEOUT
@ HAL_ERROR
@ HAL_OK
@ HAL_BUSY
#define UNUSED(X)
#define __HAL_UNLOCK(__HANDLE__)
#define HAL_MAX_DELAY
@ HAL_UNLOCKED
#define __HAL_LOCK(__HANDLE__)
DMA handle Structure definition.
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
DMA_HandleTypeDef * hdmatx
SAI_FrameInitTypeDef FrameInit
SAI_SlotInitTypeDef SlotInit
void(* InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai)
__IO HAL_SAI_StateTypeDef State
SAI_Block_TypeDef * Instance
DMA_HandleTypeDef * hdmarx