STM32F769IDiscovery  1.00
uDANTE Audio Networking with STM32F7 DISCO board
stm32f7xx_hal_sai.c
Go to the documentation of this file.
1 
166 /* Includes ------------------------------------------------------------------*/
167 #include "stm32f7xx_hal.h"
168 
178 #ifdef HAL_SAI_MODULE_ENABLED
179 
180 /* Private typedef -----------------------------------------------------------*/
181 
185 typedef enum {
186  SAI_MODE_DMA,
187  SAI_MODE_IT
188 }SAI_ModeTypedef;
193 /* Private define ------------------------------------------------------------*/
194 
198 #define SAI_FIFO_SIZE 8
199 #define SAI_DEFAULT_TIMEOUT 4 /* 4ms */
200 #define SAI_xCR2_MUTECNT_OFFSET POSITION_VAL(SAI_xCR2_MUTECNT)
201 
205 /* Private macro -------------------------------------------------------------*/
206 /* Private variables ---------------------------------------------------------*/
207 /* Private function prototypes -----------------------------------------------*/
208 
212 static void SAI_FillFifo(SAI_HandleTypeDef *hsai);
213 static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode);
214 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
215 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
216 
217 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai);
218 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai);
219 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai);
220 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai);
221 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai);
222 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai);
223 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai);
224 
225 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma);
226 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
227 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma);
228 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
229 static void SAI_DMAError(DMA_HandleTypeDef *hdma);
230 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma);
235 /* Exported functions ---------------------------------------------------------*/
236 
284 HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
285 {
286  HAL_StatusTypeDef status = HAL_OK;
287 
288  /* Check the parameters */
291 
292  switch(protocol)
293  {
294  case SAI_I2S_STANDARD :
295  case SAI_I2S_MSBJUSTIFIED :
296  case SAI_I2S_LSBJUSTIFIED :
297  status = SAI_InitI2S(hsai, protocol, datasize, nbslot);
298  break;
299  case SAI_PCM_LONG :
300  case SAI_PCM_SHORT :
301  status = SAI_InitPCM(hsai, protocol, datasize, nbslot);
302  break;
303  default :
304  status = HAL_ERROR;
305  break;
306  }
307 
308  if(status == HAL_OK)
309  {
310  status = HAL_SAI_Init(hsai);
311  }
312 
313  return status;
314 }
315 
324 {
325  uint32_t tmpregisterGCR = 0;
326  uint32_t ckstr_bits = 0;
327  uint32_t syncen_bits = 0;
328 
329  /* Check the SAI handle allocation */
330  if(hsai == NULL)
331  {
332  return HAL_ERROR;
333  }
334 
335  /* check the instance */
337 
338  /* Check the SAI Block parameters */
353 
354  /* Check the SAI Block Frame parameters */
360 
361  /* Check the SAI Block Slot parameters */
366 
367  if(hsai->State == HAL_SAI_STATE_RESET)
368  {
369  /* Allocate lock resource and initialize it */
370  hsai->Lock = HAL_UNLOCKED;
371 
372  /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
373  HAL_SAI_MspInit(hsai);
374  }
375 
376  hsai->State = HAL_SAI_STATE_BUSY;
377 
378  /* Disable the selected SAI peripheral */
379  SAI_Disable(hsai);
380 
381  /* SAI Block Synchro Configuration -----------------------------------------*/
382  /* This setting must be done with both audio block (A & B) disabled */
383  switch(hsai->Init.SynchroExt)
384  {
385  case SAI_SYNCEXT_DISABLE :
386  tmpregisterGCR = 0;
387  break;
389  tmpregisterGCR = SAI_GCR_SYNCOUT_0;
390  break;
392  tmpregisterGCR = SAI_GCR_SYNCOUT_1;
393  break;
394  default:
395  break;
396  }
397 
398  switch(hsai->Init.Synchro)
399  {
400  case SAI_ASYNCHRONOUS :
401  {
402  syncen_bits = 0;
403  }
404  break;
405  case SAI_SYNCHRONOUS :
406  {
407  syncen_bits = SAI_xCR1_SYNCEN_0;
408  }
409  break;
411  {
412  syncen_bits = SAI_xCR1_SYNCEN_1;
413  }
414  break;
416  {
417  syncen_bits = SAI_xCR1_SYNCEN_1;
418  tmpregisterGCR |= SAI_GCR_SYNCIN_0;
419  }
420  break;
421  default:
422  break;
423  }
424 
425  if((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
426  {
427  SAI1->GCR = tmpregisterGCR;
428  }
429  else
430  {
431  SAI2->GCR = tmpregisterGCR;
432  }
433 
435  {
436  uint32_t freq = 0;
437  uint32_t tmpval;
438 
439  if((hsai->Instance == SAI1_Block_A ) || (hsai->Instance == SAI1_Block_B ))
440  {
442  }
443  if((hsai->Instance == SAI2_Block_A ) || (hsai->Instance == SAI2_Block_B ))
444  {
446  }
447 
448  /* Configure Master Clock using the following formula :
449  MCLK_x = SAI_CK_x / (MCKDIV[3:0] * 2) with MCLK_x = 256 * FS
450  FS = SAI_CK_x / (MCKDIV[3:0] * 2) * 256
451  MCKDIV[3:0] = SAI_CK_x / FS * 512 */
452  /* (freq x 10) to keep Significant digits */
453  tmpval = (freq * 10) / (hsai->Init.AudioFrequency * 2 * 256);
454  hsai->Init.Mckdiv = tmpval / 10;
455 
456  /* Round result to the nearest integer */
457  if((tmpval % 10) > 8)
458  {
459  hsai->Init.Mckdiv+= 1;
460  }
461  }
462 
463  /* Compute CKSTR bits of SAI CR1 according ClockStrobing and AudioMode */
464  if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
465  { /* Transmit */
466  ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0 : SAI_xCR1_CKSTR;
467  }
468  else
469  { /* Receive */
470  ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0;
471  }
472 
473  /* SAI Block Configuration -------------------------------------------------*/
474  /* SAI CR1 Configuration */
476  SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN |\
477  SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
478  SAI_xCR1_NODIV | SAI_xCR1_MCKDIV);
479 
480  hsai->Instance->CR1|=(hsai->Init.AudioMode | hsai->Init.Protocol | \
481  hsai->Init.DataSize | hsai->Init.FirstBit | \
482  ckstr_bits | syncen_bits | \
483  hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
484  hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20));
485 
486  /* SAI CR2 Configuration */
488  hsai->Instance->CR2|= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState);
489 
490  /* SAI Frame Configuration -----------------------------------------*/
492  SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF));
493  hsai->Instance->FRCR|=((hsai->FrameInit.FrameLength - 1) |
494  hsai->FrameInit.FSOffset |
495  hsai->FrameInit.FSDefinition |
496  hsai->FrameInit.FSPolarity |
497  ((hsai->FrameInit.ActiveFrameLength - 1) << 8));
498 
499  /* SAI Block_x SLOT Configuration ------------------------------------------*/
500  /* This register has no meaning in AC 97 and SPDIF audio protocol */
502  SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN ));
503 
504  hsai->Instance->SLOTR|= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize
505  | (hsai->SlotInit.SlotActive << 16) | ((hsai->SlotInit.SlotNumber - 1) << 8);
506 
507  /* Initialize the error code */
509 
510  /* Initialize the SAI state */
511  hsai->State= HAL_SAI_STATE_READY;
512 
513  /* Release Lock */
514  __HAL_UNLOCK(hsai);
515 
516  return HAL_OK;
517 }
518 
526 {
527  /* Check the SAI handle allocation */
528  if(hsai == NULL)
529  {
530  return HAL_ERROR;
531  }
532 
533  hsai->State = HAL_SAI_STATE_BUSY;
534 
535  /* Disabled All interrupt and clear all the flag */
536  hsai->Instance->IMR = 0;
537  hsai->Instance->CLRFR = 0xFFFFFFFFU;
538 
539  /* Disable the SAI */
540  SAI_Disable(hsai);
541 
542  /* Flush the fifo */
544 
545  /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
546  HAL_SAI_MspDeInit(hsai);
547 
548  /* Initialize the error code */
550 
551  /* Initialize the SAI state */
552  hsai->State = HAL_SAI_STATE_RESET;
553 
554  /* Release Lock */
555  __HAL_UNLOCK(hsai);
556 
557  return HAL_OK;
558 }
559 
566 __weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
567 {
568  /* Prevent unused argument(s) compilation warning */
569  UNUSED(hsai);
570 
571  /* NOTE : This function should not be modified, when the callback is needed,
572  the HAL_SAI_MspInit could be implemented in the user file
573  */
574 }
575 
582 __weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
583 {
584  /* Prevent unused argument(s) compilation warning */
585  UNUSED(hsai);
586 
587  /* NOTE : This function should not be modified, when the callback is needed,
588  the HAL_SAI_MspDeInit could be implemented in the user file
589  */
590 }
591 
650 HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t* pData, uint16_t Size, uint32_t Timeout)
651 {
652  uint32_t tickstart = HAL_GetTick();
653 
654  if((pData == NULL ) || (Size == 0))
655  {
656  return HAL_ERROR;
657  }
658 
659  if(hsai->State == HAL_SAI_STATE_READY)
660  {
661  /* Process Locked */
662  __HAL_LOCK(hsai);
663 
664  hsai->XferSize = Size;
665  hsai->XferCount = Size;
666  hsai->pBuffPtr = pData;
669 
670  /* Check if the SAI is already enabled */
671  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
672  {
673  /* fill the fifo with data before to enabled the SAI */
674  SAI_FillFifo(hsai);
675  /* Enable SAI peripheral */
676  __HAL_SAI_ENABLE(hsai);
677  }
678 
679  while(hsai->XferCount > 0)
680  {
681  /* Write data if the FIFO is not full */
682  if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL)
683  {
684  if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
685  {
686  hsai->Instance->DR = (*hsai->pBuffPtr++);
687  }
688  else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
689  {
690  hsai->Instance->DR = *((uint16_t *)hsai->pBuffPtr);
691  hsai->pBuffPtr+= 2;
692  }
693  else
694  {
695  hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
696  hsai->pBuffPtr+= 4;
697  }
698  hsai->XferCount--;
699  }
700  else
701  {
702  /* Check for the Timeout */
703  if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0)||((HAL_GetTick() - tickstart) > Timeout)))
704  {
705  /* Update error code */
707 
708  /* Clear all the flags */
709  hsai->Instance->CLRFR = 0xFFFFFFFFU;
710 
711  /* Disable SAI peripheral */
712  SAI_Disable(hsai);
713 
714  /* Flush the fifo */
716 
717  /* Change the SAI state */
718  hsai->State = HAL_SAI_STATE_READY;
719 
720  /* Process Unlocked */
721  __HAL_UNLOCK(hsai);
722 
723  return HAL_ERROR;
724  }
725  }
726  }
727 
728  hsai->State = HAL_SAI_STATE_READY;
729 
730  /* Process Unlocked */
731  __HAL_UNLOCK(hsai);
732 
733  return HAL_OK;
734  }
735  else
736  {
737  return HAL_BUSY;
738  }
739 }
740 
750 HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
751 {
752  uint32_t tickstart = HAL_GetTick();
753 
754  if((pData == NULL ) || (Size == 0))
755  {
756  return HAL_ERROR;
757  }
758 
759  if(hsai->State == HAL_SAI_STATE_READY)
760  {
761  /* Process Locked */
762  __HAL_LOCK(hsai);
763 
764  hsai->pBuffPtr = pData;
765  hsai->XferSize = Size;
766  hsai->XferCount = Size;
769 
770  /* Check if the SAI is already enabled */
771  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
772  {
773  /* Enable SAI peripheral */
774  __HAL_SAI_ENABLE(hsai);
775  }
776 
777  /* Receive data */
778  while(hsai->XferCount > 0)
779  {
780  if((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY)
781  {
782  if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
783  {
784  (*hsai->pBuffPtr++) = hsai->Instance->DR;
785  }
786  else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
787  {
788  *((uint16_t*)hsai->pBuffPtr) = hsai->Instance->DR;
789  hsai->pBuffPtr+= 2;
790  }
791  else
792  {
793  *((uint32_t*)hsai->pBuffPtr) = hsai->Instance->DR;
794  hsai->pBuffPtr+= 4;
795  }
796  hsai->XferCount--;
797  }
798  else
799  {
800  /* Check for the Timeout */
801  if((Timeout != HAL_MAX_DELAY) && ((Timeout == 0)||((HAL_GetTick() - tickstart) > Timeout)))
802  {
803  /* Update error code */
805 
806  /* Clear all the flags */
807  hsai->Instance->CLRFR = 0xFFFFFFFFU;
808 
809  /* Disable SAI peripheral */
810  SAI_Disable(hsai);
811 
812  /* Flush the fifo */
814 
815  /* Change the SAI state */
816  hsai->State = HAL_SAI_STATE_READY;
817 
818  /* Process Unlocked */
819  __HAL_UNLOCK(hsai);
820 
821  return HAL_ERROR;
822  }
823  }
824  }
825 
826  hsai->State = HAL_SAI_STATE_READY;
827 
828  /* Process Unlocked */
829  __HAL_UNLOCK(hsai);
830 
831  return HAL_OK;
832  }
833  else
834  {
835  return HAL_BUSY;
836  }
837 }
838 
847 HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
848 {
849  if((pData == NULL) || (Size == 0))
850  {
851  return HAL_ERROR;
852  }
853 
854  if(hsai->State == HAL_SAI_STATE_READY)
855  {
856  /* Process Locked */
857  __HAL_LOCK(hsai);
858 
859  hsai->pBuffPtr = pData;
860  hsai->XferSize = Size;
861  hsai->XferCount = Size;
864 
865  if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
866  {
867  hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit;
868  }
869  else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
870  {
871  hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit;
872  }
873  else
874  {
875  hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit;
876  }
877 
878  /* Fill the fifo before starting the communication */
879  SAI_FillFifo(hsai);
880 
881  /* Enable FRQ and OVRUDR interrupts */
882  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
883 
884  /* Check if the SAI is already enabled */
885  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
886  {
887  /* Enable SAI peripheral */
888  __HAL_SAI_ENABLE(hsai);
889  }
890  /* Process Unlocked */
891  __HAL_UNLOCK(hsai);
892 
893  return HAL_OK;
894  }
895  else
896  {
897  return HAL_BUSY;
898  }
899 }
900 
909 HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
910 {
911  if((pData == NULL) || (Size == 0))
912  {
913  return HAL_ERROR;
914  }
915 
916  if(hsai->State == HAL_SAI_STATE_READY)
917  {
918  /* Process Locked */
919  __HAL_LOCK(hsai);
920 
921  hsai->pBuffPtr = pData;
922  hsai->XferSize = Size;
923  hsai->XferCount = Size;
926 
927  if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
928  {
929  hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit;
930  }
931  else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
932  {
933  hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit;
934  }
935  else
936  {
937  hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit;
938  }
939 
940  /* Enable TXE and OVRUDR interrupts */
941  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
942 
943  /* Check if the SAI is already enabled */
944  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
945  {
946  /* Enable SAI peripheral */
947  __HAL_SAI_ENABLE(hsai);
948  }
949 
950  /* Process Unlocked */
951  __HAL_UNLOCK(hsai);
952 
953  return HAL_OK;
954  }
955  else
956  {
957  return HAL_BUSY;
958  }
959 }
960 
968 {
969  /* Process Locked */
970  __HAL_LOCK(hsai);
971 
972  /* Pause the audio file playing by disabling the SAI DMA requests */
973  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
974 
975  /* Process Unlocked */
976  __HAL_UNLOCK(hsai);
977 
978  return HAL_OK;
979 }
980 
988 {
989  /* Process Locked */
990  __HAL_LOCK(hsai);
991 
992  /* Enable the SAI DMA requests */
993  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
994 
995  /* If the SAI peripheral is still not enabled, enable it */
996  if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
997  {
998  /* Enable SAI peripheral */
999  __HAL_SAI_ENABLE(hsai);
1000  }
1001 
1002  /* Process Unlocked */
1003  __HAL_UNLOCK(hsai);
1004 
1005  return HAL_OK;
1006 }
1007 
1015 {
1016  /* Process Locked */
1017  __HAL_LOCK(hsai);
1018 
1019  /* Disable the SAI DMA request */
1020  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1021 
1022  /* Abort the SAI DMA Streams */
1023  if(hsai->hdmatx != NULL)
1024  {
1025  if(HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1026  {
1027  return HAL_ERROR;
1028  }
1029  }
1030 
1031  if(hsai->hdmarx != NULL)
1032  {
1033  if(HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1034  {
1035  return HAL_ERROR;
1036  }
1037  }
1038 
1039  /* Disable SAI peripheral */
1040  SAI_Disable(hsai);
1041 
1042  hsai->State = HAL_SAI_STATE_READY;
1043 
1044  /* Process Unlocked */
1045  __HAL_UNLOCK(hsai);
1046 
1047  return HAL_OK;
1048 }
1049 
1057 {
1058  /* Process Locked */
1059  __HAL_LOCK(hsai);
1060 
1061  /* Check SAI DMA is enabled or not */
1062  if((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1063  {
1064  /* Disable the SAI DMA request */
1065  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1066 
1067  /* Abort the SAI DMA Streams */
1068  if(hsai->hdmatx != NULL)
1069  {
1070  if(HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1071  {
1072  return HAL_ERROR;
1073  }
1074  }
1075 
1076  if(hsai->hdmarx != NULL)
1077  {
1078  if(HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1079  {
1080  return HAL_ERROR;
1081  }
1082  }
1083  }
1084  /* Disabled All interrupt and clear all the flag */
1085  hsai->Instance->IMR = 0;
1086  hsai->Instance->CLRFR = 0xFFFFFFFFU;
1087 
1088  /* Disable SAI peripheral */
1089  SAI_Disable(hsai);
1090 
1091  /* Flush the fifo */
1093 
1094  hsai->State = HAL_SAI_STATE_READY;
1095 
1096  /* Process Unlocked */
1097  __HAL_UNLOCK(hsai);
1098 
1099  return HAL_OK;
1100 }
1101 
1110 HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1111 {
1112  if((pData == NULL) || (Size == 0))
1113  {
1114  return HAL_ERROR;
1115  }
1116 
1117  if(hsai->State == HAL_SAI_STATE_READY)
1118  {
1119  /* Process Locked */
1120  __HAL_LOCK(hsai);
1121 
1122  hsai->pBuffPtr = pData;
1123  hsai->XferSize = Size;
1124  hsai->XferCount = Size;
1125  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1126  hsai->State = HAL_SAI_STATE_BUSY_TX;
1127 
1128  /* Set the SAI Tx DMA Half transfer complete callback */
1129  hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
1130 
1131  /* Set the SAI TxDMA transfer complete callback */
1132  hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
1133 
1134  /* Set the DMA error callback */
1135  hsai->hdmatx->XferErrorCallback = SAI_DMAError;
1136 
1137  /* Set the DMA Tx abort callback */
1138  hsai->hdmatx->XferAbortCallback = NULL;
1139 
1140  /* Enable the Tx DMA Stream */
1141  if(HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
1142  {
1143  __HAL_UNLOCK(hsai);
1144  return HAL_ERROR;
1145  }
1146 
1147  /* Check if the SAI is already enabled */
1148  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1149  {
1150  /* Enable SAI peripheral */
1151  __HAL_SAI_ENABLE(hsai);
1152  }
1153 
1154  /* Enable the interrupts for error handling */
1155  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1156 
1157  /* Enable SAI Tx DMA Request */
1158  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1159 
1160  /* Process Unlocked */
1161  __HAL_UNLOCK(hsai);
1162 
1163  return HAL_OK;
1164  }
1165  else
1166  {
1167  return HAL_BUSY;
1168  }
1169 }
1170 
1179 HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1180 {
1181 
1182  if((pData == NULL) || (Size == 0))
1183  {
1184  return HAL_ERROR;
1185  }
1186 
1187  if(hsai->State == HAL_SAI_STATE_READY)
1188  {
1189  /* Process Locked */
1190  __HAL_LOCK(hsai);
1191 
1192  hsai->pBuffPtr = pData;
1193  hsai->XferSize = Size;
1194  hsai->XferCount = Size;
1195  hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1196  hsai->State = HAL_SAI_STATE_BUSY_RX;
1197 
1198  /* Set the SAI Rx DMA Half transfer complete callback */
1199  hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt;
1200 
1201  /* Set the SAI Rx DMA transfer complete callback */
1202  hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt;
1203 
1204  /* Set the DMA error callback */
1205  hsai->hdmarx->XferErrorCallback = SAI_DMAError;
1206 
1207  /* Set the DMA Rx abort callback */
1208  hsai->hdmarx->XferAbortCallback = NULL;
1209 
1210  /* Enable the Rx DMA Stream */
1211  if(HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
1212  {
1213  __HAL_UNLOCK(hsai);
1214  return HAL_ERROR;
1215  }
1216 
1217  /* Check if the SAI is already enabled */
1218  if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == RESET)
1219  {
1220  /* Enable SAI peripheral */
1221  __HAL_SAI_ENABLE(hsai);
1222  }
1223 
1224  /* Enable the interrupts for error handling */
1225  __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1226 
1227  /* Enable SAI Rx DMA Request */
1228  hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1229 
1230  /* Process Unlocked */
1231  __HAL_UNLOCK(hsai);
1232 
1233  return HAL_OK;
1234  }
1235  else
1236  {
1237  return HAL_BUSY;
1238  }
1239 }
1240 
1249 {
1251 
1252  if(hsai->State != HAL_SAI_STATE_RESET)
1253  {
1255  SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | val);
1256  return HAL_OK;
1257  }
1258  return HAL_ERROR;
1259 }
1260 
1268 {
1269  if(hsai->State != HAL_SAI_STATE_RESET)
1270  {
1272  return HAL_OK;
1273  }
1274  return HAL_ERROR;
1275 }
1276 
1286 {
1288 
1289  if(hsai->State != HAL_SAI_STATE_RESET)
1290  {
1291  /* set the mute counter */
1293  SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_OFFSET));
1294  hsai->mutecallback = callback;
1295  /* enable the IT interrupt */
1297  return HAL_OK;
1298  }
1299  return HAL_ERROR;
1300 }
1301 
1309 {
1310  if(hsai->State != HAL_SAI_STATE_RESET)
1311  {
1312  /* set the mutecallback to NULL */
1313  hsai->mutecallback = (SAIcallback)NULL;
1314  /* enable the IT interrupt */
1316  return HAL_OK;
1317  }
1318  return HAL_ERROR;
1319 }
1320 
1328 {
1329  if(hsai->State != HAL_SAI_STATE_RESET)
1330  {
1331  uint32_t itflags = hsai->Instance->SR;
1332  uint32_t itsources = hsai->Instance->IMR;
1333  uint32_t cr1config = hsai->Instance->CR1;
1334  uint32_t tmperror;
1335 
1336  /* SAI Fifo request interrupt occured ------------------------------------*/
1337  if(((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ))
1338  {
1339  hsai->InterruptServiceRoutine(hsai);
1340  }
1341  /* SAI Overrun error interrupt occurred ----------------------------------*/
1342  else if(((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR))
1343  {
1344  /* Clear the SAI Overrun flag */
1345  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
1346  /* Get the SAI error code */
1347  tmperror = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR);
1348  /* Change the SAI error code */
1349  hsai->ErrorCode |= tmperror;
1350  /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
1351  HAL_SAI_ErrorCallback(hsai);
1352  }
1353  /* SAI mutedet interrupt occurred ----------------------------------*/
1354  else if(((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET))
1355  {
1356  /* Clear the SAI mutedet flag */
1357  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET);
1358  /* call the call back function */
1359  if(hsai->mutecallback != (SAIcallback)NULL)
1360  {
1361  /* inform the user that an RX mute event has been detected */
1362  hsai->mutecallback();
1363  }
1364  }
1365  /* SAI AFSDET interrupt occurred ----------------------------------*/
1366  else if(((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET))
1367  {
1368  /* Change the SAI error code */
1370  /* Check SAI DMA is enabled or not */
1371  if((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1372  {
1373  /* Abort the SAI DMA Streams */
1374  if(hsai->hdmatx != NULL)
1375  {
1376  /* Set the DMA Tx abort callback */
1377  hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
1378 
1379  /* Abort DMA in IT mode */
1380  HAL_DMA_Abort_IT(hsai->hdmatx);
1381  }
1382  else if(hsai->hdmarx != NULL)
1383  {
1384  /* Set the DMA Rx abort callback */
1385  hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
1386  /* Abort DMA in IT mode */
1387  HAL_DMA_Abort_IT(hsai->hdmarx);
1388  }
1389  }
1390  else
1391  {
1392  /* Abort SAI */
1393  HAL_SAI_Abort(hsai);
1394 
1395  /* Set error callback */
1396  HAL_SAI_ErrorCallback(hsai);
1397  }
1398  }
1399  /* SAI LFSDET interrupt occurred ----------------------------------*/
1400  else if(((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET))
1401  {
1402  /* Change the SAI error code */
1404 
1405  /* Check SAI DMA is enabled or not */
1406  if((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1407  {
1408  /* Abort the SAI DMA Streams */
1409  if(hsai->hdmatx != NULL)
1410  {
1411  /* Set the DMA Tx abort callback */
1412  hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
1413  /* Abort DMA in IT mode */
1414  HAL_DMA_Abort_IT(hsai->hdmatx);
1415  }
1416  else if(hsai->hdmarx != NULL)
1417  {
1418  /* Set the DMA Rx abort callback */
1419  hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
1420  /* Abort DMA in IT mode */
1421  HAL_DMA_Abort_IT(hsai->hdmarx);
1422  }
1423  }
1424  else
1425  {
1426  /* Abort SAI */
1427  HAL_SAI_Abort(hsai);
1428 
1429  /* Set error callback */
1430  HAL_SAI_ErrorCallback(hsai);
1431  }
1432  }
1433  /* SAI WCKCFG interrupt occurred ----------------------------------*/
1434  else if(((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG))
1435  {
1436  /* Change the SAI error code */
1438 
1439  /* Abort the SAI DMA Streams */
1440  if(hsai->hdmatx != NULL)
1441  {
1442  /* Set the DMA Tx abort callback */
1443  hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
1444  /* Abort DMA in IT mode */
1445  HAL_DMA_Abort_IT(hsai->hdmatx);
1446  }
1447  else if(hsai->hdmarx != NULL)
1448  {
1449  /* Set the DMA Rx abort callback */
1450  hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
1451  /* Abort DMA in IT mode */
1452  HAL_DMA_Abort_IT(hsai->hdmarx);
1453  }
1454  else
1455  {
1456  /* If WCKCFG occurs, SAI audio block is automatically disabled */
1457  /* Disable all interrupts and clear all flags */
1458  hsai->Instance->IMR = 0U;
1459  hsai->Instance->CLRFR = 0xFFFFFFFFU;
1460  /* Set the SAI state to ready to be able to start again the process */
1461  hsai->State = HAL_SAI_STATE_READY;
1462 
1463  /* Initialize XferCount */
1464  hsai->XferCount = 0U;
1465 
1466  /* SAI error Callback */
1467  HAL_SAI_ErrorCallback(hsai);
1468  }
1469  }
1470  /* SAI CNRDY interrupt occurred ----------------------------------*/
1471  else if(((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY))
1472  {
1473  /* Clear the SAI CNRDY flag */
1474  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_CNRDY);
1475  /* Change the SAI error code */
1477  /* the transfer is not stopped, we will forward the information to the user and we let the user decide what needs to be done */
1478  HAL_SAI_ErrorCallback(hsai);
1479  }
1480  else
1481  {
1482  /* Nothing to do */
1483  }
1484  }
1485 }
1486 
1493 __weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
1494 {
1495  /* Prevent unused argument(s) compilation warning */
1496  UNUSED(hsai);
1497 
1498  /* NOTE : This function should not be modified, when the callback is needed,
1499  the HAL_SAI_TxCpltCallback could be implemented in the user file
1500  */
1501 }
1502 
1510 {
1511  /* Prevent unused argument(s) compilation warning */
1512  UNUSED(hsai);
1513 
1514  /* NOTE : This function should not be modified, when the callback is needed,
1515  the HAL_SAI_TxHalfCpltCallback could be implemented in the user file
1516  */
1517 }
1518 
1525 __weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
1526 {
1527  /* Prevent unused argument(s) compilation warning */
1528  UNUSED(hsai);
1529 
1530  /* NOTE : This function should not be modified, when the callback is needed,
1531  the HAL_SAI_RxCpltCallback could be implemented in the user file
1532  */
1533 }
1534 
1542 {
1543  /* Prevent unused argument(s) compilation warning */
1544  UNUSED(hsai);
1545 
1546  /* NOTE : This function should not be modified, when the callback is needed,
1547  the HAL_SAI_RxHalfCpltCallback could be implemented in the user file
1548  */
1549 }
1550 
1557 __weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
1558 {
1559  /* Prevent unused argument(s) compilation warning */
1560  UNUSED(hsai);
1561 
1562  /* NOTE : This function should not be modified, when the callback is needed,
1563  the HAL_SAI_ErrorCallback could be implemented in the user file
1564  */
1565 }
1566 
1594 {
1595  return hsai->State;
1596 }
1597 
1604 uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai)
1605 {
1606  return hsai->ErrorCode;
1607 }
1633 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
1634 {
1636  hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
1637  /* Compute ClockStrobing according AudioMode */
1638  if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
1639  { /* Transmit */
1641  }
1642  else
1643  { /* Receive */
1645  }
1648  hsai->SlotInit.FirstBitOffset = 0;
1649  hsai->SlotInit.SlotNumber = nbslot;
1650 
1651  /* in IS2 the number of slot must be even */
1652  if((nbslot & 0x1) != 0 )
1653  {
1654  return HAL_ERROR;
1655  }
1656 
1657  switch(protocol)
1658  {
1659  case SAI_I2S_STANDARD :
1662  break;
1663  case SAI_I2S_MSBJUSTIFIED :
1664  case SAI_I2S_LSBJUSTIFIED :
1667  break;
1668  default :
1669  return HAL_ERROR;
1670  }
1671 
1672  /* Frame definition */
1673  switch(datasize)
1674  {
1676  hsai->Init.DataSize = SAI_DATASIZE_16;
1677  hsai->FrameInit.FrameLength = 32*(nbslot/2);
1678  hsai->FrameInit.ActiveFrameLength = 16*(nbslot/2);
1680  break;
1682  hsai->Init.DataSize = SAI_DATASIZE_16;
1683  hsai->FrameInit.FrameLength = 64*(nbslot/2);
1684  hsai->FrameInit.ActiveFrameLength = 32*(nbslot/2);
1686  break;
1688  hsai->Init.DataSize = SAI_DATASIZE_24;
1689  hsai->FrameInit.FrameLength = 64*(nbslot/2);
1690  hsai->FrameInit.ActiveFrameLength = 32*(nbslot/2);
1692  break;
1694  hsai->Init.DataSize = SAI_DATASIZE_32;
1695  hsai->FrameInit.FrameLength = 64*(nbslot/2);
1696  hsai->FrameInit.ActiveFrameLength = 32*(nbslot/2);
1698  break;
1699  default :
1700  return HAL_ERROR;
1701  }
1702  if(protocol == SAI_I2S_LSBJUSTIFIED)
1703  {
1704  if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED)
1705  {
1706  hsai->SlotInit.FirstBitOffset = 16;
1707  }
1708  if (datasize == SAI_PROTOCOL_DATASIZE_24BIT)
1709  {
1710  hsai->SlotInit.FirstBitOffset = 8;
1711  }
1712  }
1713  return HAL_OK;
1714 }
1715 
1726 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
1727 {
1729  hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
1730  /* Compute ClockStrobing according AudioMode */
1731  if((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
1732  { /* Transmit */
1734  }
1735  else
1736  { /* Receive */
1738  }
1742  hsai->SlotInit.FirstBitOffset = 0;
1743  hsai->SlotInit.SlotNumber = nbslot;
1745 
1746  switch(protocol)
1747  {
1748  case SAI_PCM_SHORT :
1749  hsai->FrameInit.ActiveFrameLength = 1;
1750  break;
1751  case SAI_PCM_LONG :
1752  hsai->FrameInit.ActiveFrameLength = 13;
1753  break;
1754  default :
1755  return HAL_ERROR;
1756  }
1757 
1758  switch(datasize)
1759  {
1761  hsai->Init.DataSize = SAI_DATASIZE_16;
1762  hsai->FrameInit.FrameLength = 16 * nbslot;
1764  break;
1766  hsai->Init.DataSize = SAI_DATASIZE_16;
1767  hsai->FrameInit.FrameLength = 32 * nbslot;
1769  break;
1771  hsai->Init.DataSize = SAI_DATASIZE_24;
1772  hsai->FrameInit.FrameLength = 32 * nbslot;
1774  break;
1776  hsai->Init.DataSize = SAI_DATASIZE_32;
1777  hsai->FrameInit.FrameLength = 32 * nbslot;
1779  break;
1780  default :
1781  return HAL_ERROR;
1782  }
1783 
1784  return HAL_OK;
1785 }
1786 
1793 static void SAI_FillFifo(SAI_HandleTypeDef *hsai)
1794 {
1795  /* fill the fifo with data before to enabled the SAI */
1796  while(((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0))
1797  {
1798  if((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1799  {
1800  hsai->Instance->DR = (*hsai->pBuffPtr++);
1801  }
1802  else if(hsai->Init.DataSize <= SAI_DATASIZE_16)
1803  {
1804  hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
1805  hsai->pBuffPtr+= 2;
1806  }
1807  else
1808  {
1809  hsai->Instance->DR = *((uint32_t *)hsai->pBuffPtr);
1810  hsai->pBuffPtr+= 4;
1811  }
1812  hsai->XferCount--;
1813  }
1814 }
1815 
1823 static uint32_t SAI_InterruptFlag(SAI_HandleTypeDef *hsai, uint32_t mode)
1824 {
1825  uint32_t tmpIT = SAI_IT_OVRUDR;
1826 
1827  if(mode == SAI_MODE_IT)
1828  {
1829  tmpIT|= SAI_IT_FREQ;
1830  }
1831 
1832  if((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
1833  ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODEMASTER_RX)))
1834  {
1835  tmpIT|= SAI_IT_CNRDY;
1836  }
1837 
1838  if((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
1839  {
1840  tmpIT|= SAI_IT_AFSDET | SAI_IT_LFSDET;
1841  }
1842  else
1843  {
1844  /* hsai has been configured in master mode */
1845  tmpIT|= SAI_IT_WCKCFG;
1846  }
1847  return tmpIT;
1848 }
1849 
1856 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
1857 {
1858  register uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock /7/1000);
1859  HAL_StatusTypeDef status = HAL_OK;
1860 
1861  /* Disable the SAI instance */
1862  __HAL_SAI_DISABLE(hsai);
1863 
1864  do
1865  {
1866  /* Check for the Timeout */
1867  if (count-- == 0)
1868  {
1869  /* Update error code */
1871  status = HAL_TIMEOUT;
1872  break;
1873  }
1874  } while((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != RESET);
1875 
1876  return status;
1877 }
1878 
1885 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai)
1886 {
1887  if(hsai->XferCount == 0)
1888  {
1889  /* Handle the end of the transmission */
1890  /* Disable FREQ and OVRUDR interrupts */
1891  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1892  hsai->State = HAL_SAI_STATE_READY;
1893  HAL_SAI_TxCpltCallback(hsai);
1894  }
1895  else
1896  {
1897  /* Write data on DR register */
1898  hsai->Instance->DR = (*hsai->pBuffPtr++);
1899  hsai->XferCount--;
1900  }
1901 }
1902 
1909 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai)
1910 {
1911  if(hsai->XferCount == 0)
1912  {
1913  /* Handle the end of the transmission */
1914  /* Disable FREQ and OVRUDR interrupts */
1915  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1916  hsai->State = HAL_SAI_STATE_READY;
1917  HAL_SAI_TxCpltCallback(hsai);
1918  }
1919  else
1920  {
1921  /* Write data on DR register */
1922  hsai->Instance->DR = *(uint16_t *)hsai->pBuffPtr;
1923  hsai->pBuffPtr+=2;
1924  hsai->XferCount--;
1925  }
1926 }
1927 
1934 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai)
1935 {
1936  if(hsai->XferCount == 0)
1937  {
1938  /* Handle the end of the transmission */
1939  /* Disable FREQ and OVRUDR interrupts */
1940  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1941  hsai->State = HAL_SAI_STATE_READY;
1942  HAL_SAI_TxCpltCallback(hsai);
1943  }
1944  else
1945  {
1946  /* Write data on DR register */
1947  hsai->Instance->DR = *(uint32_t *)hsai->pBuffPtr;
1948  hsai->pBuffPtr+=4;
1949  hsai->XferCount--;
1950  }
1951 }
1952 
1959 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai)
1960 {
1961  /* Receive data */
1962  (*hsai->pBuffPtr++) = hsai->Instance->DR;
1963  hsai->XferCount--;
1964 
1965  /* Check end of the transfer */
1966  if(hsai->XferCount == 0)
1967  {
1968  /* Disable TXE and OVRUDR interrupts */
1969  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1970 
1971  /* Clear the SAI Overrun flag */
1972  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
1973 
1974  hsai->State = HAL_SAI_STATE_READY;
1975  HAL_SAI_RxCpltCallback(hsai);
1976  }
1977 }
1978 
1985 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai)
1986 {
1987  /* Receive data */
1988  *(uint16_t*)hsai->pBuffPtr = hsai->Instance->DR;
1989  hsai->pBuffPtr+=2;
1990  hsai->XferCount--;
1991 
1992  /* Check end of the transfer */
1993  if(hsai->XferCount == 0)
1994  {
1995  /* Disable TXE and OVRUDR interrupts */
1996  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1997 
1998  /* Clear the SAI Overrun flag */
1999  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2000 
2001  hsai->State = HAL_SAI_STATE_READY;
2002  HAL_SAI_RxCpltCallback(hsai);
2003  }
2004 }
2011 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai)
2012 {
2013  /* Receive data */
2014  *(uint32_t*)hsai->pBuffPtr = hsai->Instance->DR;
2015  hsai->pBuffPtr+=4;
2016  hsai->XferCount--;
2017 
2018  /* Check end of the transfer */
2019  if(hsai->XferCount == 0)
2020  {
2021  /* Disable TXE and OVRUDR interrupts */
2022  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2023 
2024  /* Clear the SAI Overrun flag */
2025  __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2026 
2027  hsai->State = HAL_SAI_STATE_READY;
2028  HAL_SAI_RxCpltCallback(hsai);
2029  }
2030 }
2031 
2038 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma)
2039 {
2040  SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef* )hdma)->Parent;
2041 
2042  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
2043  {
2044  hsai->XferCount = 0;
2045 
2046  /* Disable SAI Tx DMA Request */
2047  hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2048 
2049  /* Stop the interrupts error handling */
2050  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2051 
2052  hsai->State= HAL_SAI_STATE_READY;
2053  }
2054  HAL_SAI_TxCpltCallback(hsai);
2055 }
2056 
2063 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2064 {
2065  SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
2066 
2068 }
2069 
2076 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma)
2077 {
2078  SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2079  if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
2080  {
2081  /* Disable Rx DMA Request */
2082  hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2083  hsai->XferCount = 0;
2084 
2085  /* Stop the interrupts error handling */
2086  __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2087 
2088  hsai->State = HAL_SAI_STATE_READY;
2089  }
2090  HAL_SAI_RxCpltCallback(hsai);
2091 }
2092 
2099 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2100 {
2101  SAI_HandleTypeDef* hsai = (SAI_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
2102 
2104 }
2111 static void SAI_DMAError(DMA_HandleTypeDef *hdma)
2112 {
2113  SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2114 
2115  /* Set SAI error code */
2116  hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2117 
2118  if((hsai->hdmatx->ErrorCode == HAL_DMA_ERROR_TE) || (hsai->hdmarx->ErrorCode == HAL_DMA_ERROR_TE))
2119  {
2120  /* Disable the SAI DMA request */
2121  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2122 
2123  /* Disable SAI peripheral */
2124  SAI_Disable(hsai);
2125 
2126  /* Set the SAI state ready to be able to start again the process */
2127  hsai->State = HAL_SAI_STATE_READY;
2128 
2129  /* Initialize XferCount */
2130  hsai->XferCount = 0U;
2131  }
2132  /* SAI error Callback */
2133  HAL_SAI_ErrorCallback(hsai);
2134 }
2135 
2142 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma)
2143 {
2144  SAI_HandleTypeDef* hsai = ( SAI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
2145 
2146  /* Disable DMA request */
2147  hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2148 
2149  /* Disable all interrupts and clear all flags */
2150  hsai->Instance->IMR = 0U;
2151  hsai->Instance->CLRFR = 0xFFFFFFFFU;
2152 
2153  if(hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG)
2154  {
2155  /* Disable SAI peripheral */
2156  SAI_Disable(hsai);
2157 
2158  /* Flush the fifo */
2160  }
2161  /* Set the SAI state to ready to be able to start again the process */
2162  hsai->State = HAL_SAI_STATE_READY;
2163 
2164  /* Initialize XferCount */
2165  hsai->XferCount = 0U;
2166 
2167  /* SAI error Callback */
2168  HAL_SAI_ErrorCallback(hsai);
2169 }
2170 
2175 #endif /* HAL_SAI_MODULE_ENABLED */
2176 
2184 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
__IO uint32_t DR
Definition: stm32f745xx.h:790
#define CLEAR_BIT(REG, BIT)
Definition: stm32f7xx.h:180
#define IS_SAI_BLOCK_SLOT_NUMBER(NUMBER)
#define SAI_xCR1_SYNCEN
Definition: stm32f745xx.h:6235
SAI_SlotInitTypeDef SlotInit
__IO uint32_t IMR
Definition: stm32f745xx.h:787
__IO uint32_t SLOTR
Definition: stm32f745xx.h:786
#define __HAL_SAI_ENABLE_IT(__HANDLE__, __INTERRUPT__)
Enable or disable the specified SAI interrupts.
#define SAI_SLOTACTIVE_ALL
#define SAI_FS_ACTIVE_HIGH
#define HAL_SAI_ERROR_LFSDET
#define IS_SAI_BLOCK_DATASIZE(DATASIZE)
HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
#define SAI_xCR1_CKSTR
Definition: stm32f745xx.h:6233
#define IS_SAI_BLOCK_CLOCK_STROBING(CLOCK)
#define SAI_SLOTSIZE_32B
#define IS_SAI_MONO_STEREO_MODE(MODE)
#define SAI_MODEMASTER_RX
#define SAI_DATASIZE_32
HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
#define SAI_CLOCKSTROBING_FALLINGEDGE
#define SAI_PROTOCOL_DATASIZE_32BIT
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
#define SAI_DATASIZE_16
#define IS_SAI_SUPPORTED_PROTOCOL(PROTOCOL)
#define HAL_SAI_ERROR_NONE
#define assert_param(expr)
Include module&#39;s header file.
HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
DMA_HandleTypeDef * hdmarx
#define IS_SAI_BLOCK_FS_OFFSET(OFFSET)
#define SAI_IT_LFSDET
uint32_t SystemCoreClock
#define SAI_SYNCEXT_OUTBLOCKA_ENABLE
HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai)
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
Reception complete callback.
HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
#define IS_SAI_BLOCK_SYNCHRO(SYNCHRO)
#define SAI_xCR2_CPL
Definition: stm32f745xx.h:6270
#define IS_SAI_BLOCK_FRAME_LENGTH(LENGTH)
HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai)
#define SAI_xCR1_DS
Definition: stm32f745xx.h:6227
#define SAI_I2S_STANDARD
#define __HAL_UNLOCK(__HANDLE__)
HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Half reception complete callback.
#define IS_SAI_BLOCK_SLOT_SIZE(SIZE)
void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai)
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
#define SAI_xSLOTR_SLOTEN
Definition: stm32f745xx.h:6321
#define SAI_xFRCR_FRL
Definition: stm32f745xx.h:6277
#define SAI_FLAG_MUTEDET
__IO uint32_t CLRFR
Definition: stm32f745xx.h:789
#define IS_SAI_BLOCK_SYNCEXT(STATE)
#define IS_SAI_BLOCK_ACTIVE_FRAME(LENGTH)
#define SAI_FIRSTBIT_MSB
#define SAI_IT_FREQ
#define HAL_DMA_ERROR_TE
__IO uint32_t FRCR
Definition: stm32f745xx.h:785
#define IS_SAI_BLOCK_FIRST_BIT(BIT)
SAI_Block_TypeDef * Instance
#define SAI_xCR1_PRTCFG
Definition: stm32f745xx.h:6223
#define SAI_ASYNCHRONOUS
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer completed callbacks.
HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
HAL_LockTypeDef Lock
#define IS_SAI_ALL_INSTANCE(__PERIPH__)
Definition: stm32f745xx.h:8876
#define IS_SAI_BLOCK_MUTE_COUNTER(COUNTER)
#define SAI_PROTOCOL_DATASIZE_24BIT
#define SAI_xSLOTR_SLOTSZ
Definition: stm32f745xx.h:6311
#define SAI_SYNCHRONOUS_EXT_SAI2
#define SAI_xCR1_OUTDRIV
Definition: stm32f745xx.h:6240
HAL_SAI_StateTypeDef
HAL State structures definition.
#define __HAL_SAI_ENABLE(__HANDLE__)
HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
#define SAI_xFRCR_FSOFF
Definition: stm32f745xx.h:6298
#define SAI_FS_FIRSTBIT
#define SAI2_Block_A
Definition: stm32f745xx.h:1311
void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
#define SAI_FLAG_WCKCFG
#define SAI_xCR1_SYNCEN_0
Definition: stm32f745xx.h:6236
#define SAI_AUDIO_FREQUENCY_MCKDIV
__IO uint32_t SR
Definition: stm32f745xx.h:788
#define SAI_PROTOCOL_DATASIZE_16BIT
uint32_t HAL_SAI_GetError(SAI_HandleTypeDef *hsai)
HAL_SAI_StateTypeDef HAL_SAI_GetState(SAI_HandleTypeDef *hsai)
#define IS_SAI_BLOCK_FIFO_THRESHOLD(THRESHOLD)
void(* XferCpltCallback)(struct __DMA_HandleTypeDef *hdma)
#define __HAL_LOCK(__HANDLE__)
HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
#define NULL
Definition: usbd_def.h:53
#define DMA_SxCR_CIRC
Definition: stm32f745xx.h:3313
#define SAI_IT_OVRUDR
#define SAI_xFRCR_FSDEF
Definition: stm32f745xx.h:6296
#define HAL_MAX_DELAY
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
#define SAI_MODESLAVE_RX
HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
#define SAI1_Block_A
Definition: stm32f745xx.h:1309
DMA_HandleTypeDef * hdmatx
#define SAI_I2S_MSBJUSTIFIED
void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
SAI error callbacks.
#define SAI_PCM_LONG
#define SAI_SYNCEXT_DISABLE
#define SAI_FS_ACTIVE_LOW
#define SAI_FLAG_CNRDY
HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
#define IS_SAI_BLOCK_MUTE_VALUE(VALUE)
#define SAI_IT_MUTEDET
__IO HAL_SAI_StateTypeDef State
#define SAI_FS_STARTFRAME
#define SAI_FREE_PROTOCOL
#define SAI_SYNCHRONOUS_EXT_SAI1
This file contains all the functions prototypes for the HAL module driver.
#define SAI1_Block_B
Definition: stm32f745xx.h:1310
#define SAI_xCR2_COMP
Definition: stm32f745xx.h:6272
#define SAI_xCR1_MCKDIV
Definition: stm32f745xx.h:6245
#define SAI_xCR2_MUTEVAL
Definition: stm32f745xx.h:6260
#define SAI_NOCOMPANDING
DMA_Stream_TypeDef * Instance
#define SAI_PROTOCOL_DATASIZE_16BITEXTENDED
#define SAI_DATASIZE_8
__IO uint32_t CR1
Definition: stm32f745xx.h:783
#define SAI_FLAG_LFSDET
#define SAI_xCR2_FFLUSH
Definition: stm32f745xx.h:6257
#define SAI_xCR1_DMAEN
Definition: stm32f745xx.h:6242
__IO uint32_t CR2
Definition: stm32f745xx.h:784
#define SAI_IT_AFSDET
#define SAI_xSLOTR_FBOFF
Definition: stm32f745xx.h:6304
#define HAL_SAI_ERROR_DMA
#define IS_SAI_BLOCK_OUTPUT_DRIVE(DRIVE)
SAI_FrameInitTypeDef FrameInit
#define HAL_SAI_ERROR_WCKCFG
#define IS_SAI_BLOCK_NODIVIDER(NODIVIDER)
HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
#define SAI_FLAG_AFSDET
#define SAI_IT_WCKCFG
#define SAI_MODEMASTER_TX
#define SAI_CLOCKSTROBING_RISINGEDGE
void(* XferHalfCpltCallback)(struct __DMA_HandleTypeDef *hdma)
#define SAI_FLAG_OVRUDR
#define HAL_SAI_ERROR_TIMEOUT
#define IS_SAI_SLOT_ACTIVE(ACTIVE)
__IO uint32_t CR
Definition: stm32f745xx.h:392
#define UNUSED(x)
#define SAI_FIFOSTATUS_FULL
void(* XferAbortCallback)(struct __DMA_HandleTypeDef *hdma)
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Tx Half Transfer completed callbacks.
#define SAI_xCR1_SYNCEN_1
Definition: stm32f745xx.h:6237
#define SAI2
Definition: stm32f745xx.h:1308
#define SAI_FIFOSTATUS_EMPTY
#define RCC_PERIPHCLK_SAI2
#define IS_SAI_BLOCK_MODE(MODE)
#define SET_BIT(REG, BIT)
Definition: stm32f7xx.h:178
#define IS_SAI_BLOCK_COMPANDING_MODE(MODE)
#define IS_SAI_AUDIO_FREQUENCY(AUDIO)
HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
#define SAI_SYNCEXT_OUTBLOCKB_ENABLE
#define HAL_SAI_ERROR_UDR
HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
SAI_InitTypeDef Init
#define __HAL_SAI_DISABLE(__HANDLE__)
#define SAI1
Definition: stm32f745xx.h:1307
#define SAI_xSR_FREQ
Definition: stm32f745xx.h:6336
DMA handle Structure definition.
#define SAI_MODESLAVE_TX
#define IS_SAI_BLOCK_FS_DEFINITION(DEFINITION)
#define SAI_FS_BEFOREFIRSTBIT
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
SAI MSP Init.
#define SAI_xCR1_SAIEN
Definition: stm32f745xx.h:6241
#define SAI_IT_CNRDY
#define SAI_xCR2_FTH
Definition: stm32f745xx.h:6252
#define SAI_FS_CHANNEL_IDENTIFICATION
#define SAI_I2S_LSBJUSTIFIED
#define __HAL_SAI_CLEAR_FLAG(__HANDLE__, __FLAG__)
Clear the specified SAI pending flag.
#define SAI_GCR_SYNCOUT_0
Definition: stm32f745xx.h:6215
#define HAL_SAI_ERROR_AFSDET
#define SAI_SYNCHRONOUS
void(* SAIcallback)(void)
SAI Callback prototype.
#define IS_SAI_PROTOCOL_DATASIZE(DATASIZE)
#define SAI_xCR1_MODE
Definition: stm32f745xx.h:6219
#define HAL_SAI_ERROR_CNREADY
#define RCC_PERIPHCLK_SAI1
#define SAI_SLOTSIZE_16B
#define SAI2_Block_B
Definition: stm32f745xx.h:1312
HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai)
HAL_StatusTypeDef
HAL Status structures definition.
#define SAI_PCM_SHORT
void(* XferErrorCallback)(struct __DMA_HandleTypeDef *hdma)
#define SAI_xFRCR_FSALL
Definition: stm32f745xx.h:6287
uint32_t HAL_GetTick(void)
Provides a tick value in millisecond.
void(* InterruptServiceRoutine)(struct __SAI_HandleTypeDef *hsai)
#define IS_SAI_BLOCK_PROTOCOL(PROTOCOL)
#define HAL_SAI_ERROR_OVR
#define SAI_DATASIZE_24
#define SAI_GCR_SYNCIN_0
Definition: stm32f745xx.h:6211
#define SAI_xCR2_MUTECNT
Definition: stm32f745xx.h:6262
#define SAI_GCR_SYNCOUT_1
Definition: stm32f745xx.h:6216
#define __HAL_SAI_DISABLE_IT(__HANDLE__, __INTERRUPT__)
#define IS_SAI_BLOCK_FS_POLARITY(POLARITY)
#define IS_SAI_BLOCK_FIRSTBIT_OFFSET(OFFSET)
#define SAI_xCR2_MUTE
Definition: stm32f745xx.h:6259
HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
#define SAI_xSR_FLVL
Definition: stm32f745xx.h:6341
#define IS_SAI_BLOCK_TRISTATE_MANAGEMENT(STATE)
#define SAI_AC97_PROTOCOL