File indexing completed on 2025-05-11 08:23:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216 #include "stm32h7xx_hal.h"
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227
0228 #ifdef HAL_SAI_MODULE_ENABLED
0229
0230
0231
0232
0233
0234
0235 typedef enum
0236 {
0237 SAI_MODE_DMA,
0238 SAI_MODE_IT
0239 } SAI_ModeTypedef;
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249 #define SAI_DEFAULT_TIMEOUT 4U
0250 #define SAI_LONG_TIMEOUT 1000U
0251 #define SAI_SPDIF_FRAME_LENGTH 64U
0252 #define SAI_AC97_FRAME_LENGTH 256U
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 static void SAI_FillFifo(SAI_HandleTypeDef *hsai);
0265 static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode);
0266 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
0267 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot);
0268
0269 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai);
0270 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai);
0271 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai);
0272 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai);
0273 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai);
0274 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai);
0275 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai);
0276
0277 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma);
0278 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
0279 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma);
0280 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
0281 static void SAI_DMAError(DMA_HandleTypeDef *hdma);
0282 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma);
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 HAL_StatusTypeDef HAL_SAI_InitProtocol(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
0339 {
0340 HAL_StatusTypeDef status;
0341
0342
0343 assert_param(IS_SAI_SUPPORTED_PROTOCOL(protocol));
0344 assert_param(IS_SAI_PROTOCOL_DATASIZE(datasize));
0345
0346 switch (protocol)
0347 {
0348 case SAI_I2S_STANDARD :
0349 case SAI_I2S_MSBJUSTIFIED :
0350 case SAI_I2S_LSBJUSTIFIED :
0351 status = SAI_InitI2S(hsai, protocol, datasize, nbslot);
0352 break;
0353 case SAI_PCM_LONG :
0354 case SAI_PCM_SHORT :
0355 status = SAI_InitPCM(hsai, protocol, datasize, nbslot);
0356 break;
0357 default :
0358 status = HAL_ERROR;
0359 break;
0360 }
0361
0362 if (status == HAL_OK)
0363 {
0364 status = HAL_SAI_Init(hsai);
0365 }
0366
0367 return status;
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377 HAL_StatusTypeDef HAL_SAI_Init(SAI_HandleTypeDef *hsai)
0378 {
0379 uint32_t tmpregisterGCR;
0380 uint32_t ckstr_bits;
0381 uint32_t syncen_bits;
0382 SAI_TypeDef *SaiBaseAddress;
0383
0384
0385 if (hsai == NULL)
0386 {
0387 return HAL_ERROR;
0388 }
0389
0390
0391 assert_param(IS_SAI_ALL_INSTANCE(hsai->Instance));
0392
0393
0394 assert_param(IS_SAI_AUDIO_FREQUENCY(hsai->Init.AudioFrequency));
0395 assert_param(IS_SAI_BLOCK_PROTOCOL(hsai->Init.Protocol));
0396 assert_param(IS_SAI_BLOCK_MODE(hsai->Init.AudioMode));
0397 assert_param(IS_SAI_BLOCK_DATASIZE(hsai->Init.DataSize));
0398 assert_param(IS_SAI_BLOCK_FIRST_BIT(hsai->Init.FirstBit));
0399 assert_param(IS_SAI_BLOCK_CLOCK_STROBING(hsai->Init.ClockStrobing));
0400 assert_param(IS_SAI_BLOCK_SYNCHRO(hsai->Init.Synchro));
0401 #if defined(SAI_VER_V2_X)
0402
0403 if (HAL_GetREVID() >= REV_ID_B)
0404 {
0405 assert_param(IS_SAI_BLOCK_MCK_OUTPUT(hsai->Init.MckOutput));
0406 }
0407 #else
0408 assert_param(IS_SAI_BLOCK_MCK_OUTPUT(hsai->Init.MckOutput));
0409 #endif
0410 assert_param(IS_SAI_BLOCK_OUTPUT_DRIVE(hsai->Init.OutputDrive));
0411 assert_param(IS_SAI_BLOCK_NODIVIDER(hsai->Init.NoDivider));
0412 assert_param(IS_SAI_BLOCK_FIFO_THRESHOLD(hsai->Init.FIFOThreshold));
0413 assert_param(IS_SAI_MONO_STEREO_MODE(hsai->Init.MonoStereoMode));
0414 assert_param(IS_SAI_BLOCK_COMPANDING_MODE(hsai->Init.CompandingMode));
0415 assert_param(IS_SAI_BLOCK_TRISTATE_MANAGEMENT(hsai->Init.TriState));
0416 assert_param(IS_SAI_BLOCK_SYNCEXT(hsai->Init.SynchroExt));
0417 assert_param(IS_SAI_BLOCK_MCK_OVERSAMPLING(hsai->Init.MckOverSampling));
0418
0419
0420 assert_param(IS_SAI_BLOCK_FRAME_LENGTH(hsai->FrameInit.FrameLength));
0421 assert_param(IS_SAI_BLOCK_ACTIVE_FRAME(hsai->FrameInit.ActiveFrameLength));
0422 assert_param(IS_SAI_BLOCK_FS_DEFINITION(hsai->FrameInit.FSDefinition));
0423 assert_param(IS_SAI_BLOCK_FS_POLARITY(hsai->FrameInit.FSPolarity));
0424 assert_param(IS_SAI_BLOCK_FS_OFFSET(hsai->FrameInit.FSOffset));
0425
0426
0427 assert_param(IS_SAI_BLOCK_FIRSTBIT_OFFSET(hsai->SlotInit.FirstBitOffset));
0428 assert_param(IS_SAI_BLOCK_SLOT_SIZE(hsai->SlotInit.SlotSize));
0429 assert_param(IS_SAI_BLOCK_SLOT_NUMBER(hsai->SlotInit.SlotNumber));
0430 assert_param(IS_SAI_SLOT_ACTIVE(hsai->SlotInit.SlotActive));
0431
0432
0433 assert_param(IS_FUNCTIONAL_STATE(hsai->Init.PdmInit.Activation));
0434 if (hsai->Init.PdmInit.Activation == ENABLE)
0435 {
0436 assert_param(IS_SAI_PDM_MIC_PAIRS_NUMBER(hsai->Init.PdmInit.MicPairsNbr));
0437 assert_param(IS_SAI_PDM_CLOCK_ENABLE(hsai->Init.PdmInit.ClockEnable));
0438
0439 #if defined(SAI4)
0440 if (((hsai->Instance != SAI1_Block_A) && (hsai->Instance != SAI4_Block_A)) ||
0441 (hsai->Init.AudioMode != SAI_MODEMASTER_RX) ||
0442 (hsai->Init.Protocol != SAI_FREE_PROTOCOL))
0443 {
0444 return HAL_ERROR;
0445 }
0446 #else
0447 if ((hsai->Instance != SAI1_Block_A) ||
0448 (hsai->Init.AudioMode != SAI_MODEMASTER_RX) ||
0449 (hsai->Init.Protocol != SAI_FREE_PROTOCOL))
0450 {
0451 return HAL_ERROR;
0452 }
0453 #endif
0454 }
0455
0456
0457 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
0458 {
0459 SaiBaseAddress = SAI1;
0460 }
0461 #if defined(SAI2)
0462 else if ((hsai->Instance == SAI2_Block_A) || (hsai->Instance == SAI2_Block_B))
0463 {
0464 SaiBaseAddress = SAI2;
0465 }
0466 #endif
0467 #if defined(SAI3)
0468 else if ((hsai->Instance == SAI3_Block_A) || (hsai->Instance == SAI3_Block_B))
0469 {
0470 SaiBaseAddress = SAI3;
0471 }
0472 #endif
0473 #if defined(SAI4)
0474 else if ((hsai->Instance == SAI4_Block_A) || (hsai->Instance == SAI4_Block_B))
0475 {
0476 SaiBaseAddress = SAI4;
0477 }
0478 #endif
0479 else
0480 {
0481 return HAL_ERROR;
0482 }
0483
0484 if (hsai->State == HAL_SAI_STATE_RESET)
0485 {
0486
0487 hsai->Lock = HAL_UNLOCKED;
0488
0489 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
0490
0491 hsai->RxCpltCallback = HAL_SAI_RxCpltCallback;
0492 hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback;
0493 hsai->TxCpltCallback = HAL_SAI_TxCpltCallback;
0494 hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback;
0495 hsai->ErrorCallback = HAL_SAI_ErrorCallback;
0496
0497
0498 if (hsai->MspInitCallback == NULL)
0499 {
0500 hsai->MspInitCallback = HAL_SAI_MspInit;
0501 }
0502 hsai->MspInitCallback(hsai);
0503 #else
0504
0505 HAL_SAI_MspInit(hsai);
0506 #endif
0507 }
0508
0509
0510 if(SAI_Disable(hsai) != HAL_OK)
0511 {
0512 return HAL_ERROR;
0513 }
0514
0515 hsai->State = HAL_SAI_STATE_BUSY;
0516
0517
0518
0519 switch (hsai->Init.SynchroExt)
0520 {
0521 case SAI_SYNCEXT_DISABLE :
0522 tmpregisterGCR = 0;
0523 break;
0524 case SAI_SYNCEXT_OUTBLOCKA_ENABLE :
0525 tmpregisterGCR = SAI_GCR_SYNCOUT_0;
0526 break;
0527 case SAI_SYNCEXT_OUTBLOCKB_ENABLE :
0528 tmpregisterGCR = SAI_GCR_SYNCOUT_1;
0529 break;
0530 default:
0531 tmpregisterGCR = 0;
0532 break;
0533 }
0534
0535 switch (hsai->Init.Synchro)
0536 {
0537 case SAI_ASYNCHRONOUS :
0538 syncen_bits = 0;
0539 break;
0540 case SAI_SYNCHRONOUS :
0541 syncen_bits = SAI_xCR1_SYNCEN_0;
0542 break;
0543 case SAI_SYNCHRONOUS_EXT_SAI1 :
0544 syncen_bits = SAI_xCR1_SYNCEN_1;
0545 break;
0546 #if defined(SAI2)
0547 case SAI_SYNCHRONOUS_EXT_SAI2 :
0548 syncen_bits = SAI_xCR1_SYNCEN_1;
0549 tmpregisterGCR |= SAI_GCR_SYNCIN_0;
0550 break;
0551 #endif
0552 #if defined(SAI3)
0553 case SAI_SYNCHRONOUS_EXT_SAI3 :
0554 syncen_bits = SAI_xCR1_SYNCEN_1;
0555 tmpregisterGCR |= SAI_GCR_SYNCIN_1;
0556 break;
0557 #endif
0558 #if defined(SAI4)
0559 case SAI_SYNCHRONOUS_EXT_SAI4 :
0560 syncen_bits = SAI_xCR1_SYNCEN_1;
0561 tmpregisterGCR |= (SAI_GCR_SYNCIN_1 | SAI_GCR_SYNCIN_0);
0562 break;
0563 #endif
0564 default:
0565 syncen_bits = 0;
0566 break;
0567 }
0568
0569
0570 SaiBaseAddress->GCR = tmpregisterGCR;
0571
0572 if (hsai->Init.AudioFrequency != SAI_AUDIO_FREQUENCY_MCKDIV)
0573 {
0574 uint32_t freq = 0;
0575 uint32_t tmpval;
0576
0577
0578 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI1_Block_B))
0579 {
0580 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI1);
0581 }
0582
0583 #if defined(SAI2)
0584 #if defined(RCC_PERIPHCLK_SAI2)
0585 if ((hsai->Instance == SAI2_Block_A) || (hsai->Instance == SAI2_Block_B))
0586 {
0587 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2);
0588 }
0589 #else
0590 if (hsai->Instance == SAI2_Block_A)
0591 {
0592 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2A);
0593 }
0594 if (hsai->Instance == SAI2_Block_B)
0595 {
0596 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI2B);
0597 }
0598 #endif
0599 #endif
0600
0601 #if defined(SAI3)
0602 if ((hsai->Instance == SAI3_Block_A) || (hsai->Instance == SAI3_Block_B))
0603 {
0604 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI3);
0605 }
0606 #endif
0607 #if defined(SAI4)
0608 if (hsai->Instance == SAI4_Block_A)
0609 {
0610 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI4A);
0611 }
0612 if (hsai->Instance == SAI4_Block_B)
0613 {
0614 freq = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SAI4B);
0615 }
0616 #endif
0617
0618
0619
0620
0621
0622
0623 if (hsai->Init.NoDivider == SAI_MASTERDIVIDER_DISABLE)
0624 {
0625
0626 uint32_t tmpframelength;
0627
0628 if (hsai->Init.Protocol == SAI_SPDIF_PROTOCOL)
0629 {
0630
0631 tmpframelength = SAI_SPDIF_FRAME_LENGTH;
0632 }
0633 else if (hsai->Init.Protocol == SAI_AC97_PROTOCOL)
0634 {
0635
0636 tmpframelength = SAI_AC97_FRAME_LENGTH;
0637 }
0638 else
0639 {
0640
0641 tmpframelength = hsai->FrameInit.FrameLength;
0642 }
0643
0644
0645 tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * tmpframelength);
0646 }
0647 else
0648 {
0649
0650 uint32_t tmposr;
0651 tmposr = (hsai->Init.MckOverSampling == SAI_MCK_OVERSAMPLING_ENABLE) ? 2U : 1U;
0652
0653 tmpval = (freq * 10U) / (hsai->Init.AudioFrequency * tmposr * 256U);
0654 }
0655 hsai->Init.Mckdiv = tmpval / 10U;
0656
0657
0658 if ((tmpval % 10U) > 8U)
0659 {
0660 hsai->Init.Mckdiv += 1U;
0661 }
0662
0663
0664 if (hsai->Init.Protocol == SAI_SPDIF_PROTOCOL)
0665 {
0666 hsai->Init.Mckdiv = hsai->Init.Mckdiv >> 1;
0667 }
0668 }
0669
0670
0671 assert_param(IS_SAI_BLOCK_MASTER_DIVIDER(hsai->Init.Mckdiv));
0672
0673
0674 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
0675 {
0676
0677 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? 0U : SAI_xCR1_CKSTR;
0678 }
0679 else
0680 {
0681
0682 ckstr_bits = (hsai->Init.ClockStrobing == SAI_CLOCKSTROBING_RISINGEDGE) ? SAI_xCR1_CKSTR : 0U;
0683 }
0684
0685
0686
0687 #if defined(SAI_VER_V2_X)
0688
0689 if (HAL_GetREVID() >= REV_ID_B)
0690 {
0691 hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
0692 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
0693 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
0694 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV | SAI_xCR1_OSR | \
0695 SAI_xCR1_MCKEN);
0696
0697 hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
0698 hsai->Init.DataSize | hsai->Init.FirstBit | \
0699 ckstr_bits | syncen_bits | \
0700 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
0701 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | \
0702 hsai->Init.MckOverSampling | hsai->Init.MckOutput);
0703 }
0704 else
0705 {
0706 hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
0707 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
0708 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
0709 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV | SAI_xCR1_OSR);
0710
0711 hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
0712 hsai->Init.DataSize | hsai->Init.FirstBit | \
0713 ckstr_bits | syncen_bits | \
0714 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
0715 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | \
0716 hsai->Init.MckOverSampling);
0717 }
0718 #else
0719 hsai->Instance->CR1 &= ~(SAI_xCR1_MODE | SAI_xCR1_PRTCFG | SAI_xCR1_DS | \
0720 SAI_xCR1_LSBFIRST | SAI_xCR1_CKSTR | SAI_xCR1_SYNCEN | \
0721 SAI_xCR1_MONO | SAI_xCR1_OUTDRIV | SAI_xCR1_DMAEN | \
0722 SAI_xCR1_NODIV | SAI_xCR1_MCKDIV | SAI_xCR1_OSR | \
0723 SAI_xCR1_MCKEN);
0724
0725 hsai->Instance->CR1 |= (hsai->Init.AudioMode | hsai->Init.Protocol | \
0726 hsai->Init.DataSize | hsai->Init.FirstBit | \
0727 ckstr_bits | syncen_bits | \
0728 hsai->Init.MonoStereoMode | hsai->Init.OutputDrive | \
0729 hsai->Init.NoDivider | (hsai->Init.Mckdiv << 20) | \
0730 hsai->Init.MckOverSampling | hsai->Init.MckOutput);
0731 #endif
0732
0733
0734 hsai->Instance->CR2 &= ~(SAI_xCR2_FTH | SAI_xCR2_FFLUSH | SAI_xCR2_COMP | SAI_xCR2_CPL);
0735 hsai->Instance->CR2 |= (hsai->Init.FIFOThreshold | hsai->Init.CompandingMode | hsai->Init.TriState);
0736
0737
0738 hsai->Instance->FRCR &= (~(SAI_xFRCR_FRL | SAI_xFRCR_FSALL | SAI_xFRCR_FSDEF | \
0739 SAI_xFRCR_FSPOL | SAI_xFRCR_FSOFF));
0740 hsai->Instance->FRCR |= ((hsai->FrameInit.FrameLength - 1U) |
0741 hsai->FrameInit.FSOffset |
0742 hsai->FrameInit.FSDefinition |
0743 hsai->FrameInit.FSPolarity |
0744 ((hsai->FrameInit.ActiveFrameLength - 1U) << 8));
0745
0746
0747
0748 hsai->Instance->SLOTR &= (~(SAI_xSLOTR_FBOFF | SAI_xSLOTR_SLOTSZ | \
0749 SAI_xSLOTR_NBSLOT | SAI_xSLOTR_SLOTEN));
0750
0751 hsai->Instance->SLOTR |= hsai->SlotInit.FirstBitOffset | hsai->SlotInit.SlotSize | \
0752 (hsai->SlotInit.SlotActive << 16) | ((hsai->SlotInit.SlotNumber - 1U) << 8);
0753
0754
0755 #if defined(SAI4)
0756 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI4_Block_A))
0757 #else
0758 if (hsai->Instance == SAI1_Block_A)
0759 #endif
0760 {
0761
0762 SaiBaseAddress->PDMCR &= ~(SAI_PDMCR_PDMEN);
0763 if (hsai->Init.PdmInit.Activation == ENABLE)
0764 {
0765
0766 SaiBaseAddress->PDMCR = (hsai->Init.PdmInit.ClockEnable |
0767 ((hsai->Init.PdmInit.MicPairsNbr - 1U) << SAI_PDMCR_MICNBR_Pos));
0768 SaiBaseAddress->PDMCR |= SAI_PDMCR_PDMEN;
0769 }
0770 }
0771
0772
0773 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
0774
0775
0776 hsai->State = HAL_SAI_STATE_READY;
0777
0778
0779 __HAL_UNLOCK(hsai);
0780
0781 return HAL_OK;
0782 }
0783
0784
0785
0786
0787
0788
0789
0790 HAL_StatusTypeDef HAL_SAI_DeInit(SAI_HandleTypeDef *hsai)
0791 {
0792 SAI_TypeDef *SaiBaseAddress;
0793
0794
0795 if (hsai == NULL)
0796 {
0797 return HAL_ERROR;
0798 }
0799
0800 hsai->State = HAL_SAI_STATE_BUSY;
0801
0802
0803 hsai->Instance->IMR = 0;
0804 hsai->Instance->CLRFR = 0xFFFFFFFFU;
0805
0806
0807 if (SAI_Disable(hsai) != HAL_OK)
0808 {
0809
0810 hsai->State = HAL_SAI_STATE_READY;
0811
0812
0813 __HAL_UNLOCK(hsai);
0814
0815 return HAL_ERROR;
0816 }
0817
0818
0819 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
0820
0821
0822 #if defined(SAI4)
0823 if ((hsai->Instance == SAI1_Block_A) || (hsai->Instance == SAI4_Block_A))
0824 #else
0825 if (hsai->Instance == SAI1_Block_A)
0826 #endif
0827 {
0828
0829 #if defined(SAI4)
0830 SaiBaseAddress = (hsai->Instance == SAI1_Block_A) ? SAI1 : SAI4;
0831 #else
0832 SaiBaseAddress = SAI1;
0833 #endif
0834
0835
0836 SaiBaseAddress->PDMDLY = 0U;
0837
0838
0839 SaiBaseAddress->PDMCR &= ~(SAI_PDMCR_PDMEN);
0840 }
0841
0842
0843 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
0844 if (hsai->MspDeInitCallback == NULL)
0845 {
0846 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
0847 }
0848 hsai->MspDeInitCallback(hsai);
0849 #else
0850 HAL_SAI_MspDeInit(hsai);
0851 #endif
0852
0853
0854 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
0855
0856
0857 hsai->State = HAL_SAI_STATE_RESET;
0858
0859
0860 __HAL_UNLOCK(hsai);
0861
0862 return HAL_OK;
0863 }
0864
0865
0866
0867
0868
0869
0870
0871 __weak void HAL_SAI_MspInit(SAI_HandleTypeDef *hsai)
0872 {
0873
0874 UNUSED(hsai);
0875
0876
0877
0878
0879 }
0880
0881
0882
0883
0884
0885
0886
0887 __weak void HAL_SAI_MspDeInit(SAI_HandleTypeDef *hsai)
0888 {
0889
0890 UNUSED(hsai);
0891
0892
0893
0894
0895 }
0896
0897 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914 HAL_StatusTypeDef HAL_SAI_RegisterCallback(SAI_HandleTypeDef *hsai,
0915 HAL_SAI_CallbackIDTypeDef CallbackID,
0916 pSAI_CallbackTypeDef pCallback)
0917 {
0918 HAL_StatusTypeDef status = HAL_OK;
0919
0920 if (pCallback == NULL)
0921 {
0922
0923 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
0924
0925 status = HAL_ERROR;
0926 }
0927 else
0928 {
0929 if (HAL_SAI_STATE_READY == hsai->State)
0930 {
0931 switch (CallbackID)
0932 {
0933 case HAL_SAI_RX_COMPLETE_CB_ID :
0934 hsai->RxCpltCallback = pCallback;
0935 break;
0936 case HAL_SAI_RX_HALFCOMPLETE_CB_ID :
0937 hsai->RxHalfCpltCallback = pCallback;
0938 break;
0939 case HAL_SAI_TX_COMPLETE_CB_ID :
0940 hsai->TxCpltCallback = pCallback;
0941 break;
0942 case HAL_SAI_TX_HALFCOMPLETE_CB_ID :
0943 hsai->TxHalfCpltCallback = pCallback;
0944 break;
0945 case HAL_SAI_ERROR_CB_ID :
0946 hsai->ErrorCallback = pCallback;
0947 break;
0948 case HAL_SAI_MSPINIT_CB_ID :
0949 hsai->MspInitCallback = pCallback;
0950 break;
0951 case HAL_SAI_MSPDEINIT_CB_ID :
0952 hsai->MspDeInitCallback = pCallback;
0953 break;
0954 default :
0955
0956 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
0957
0958 status = HAL_ERROR;
0959 break;
0960 }
0961 }
0962 else if (HAL_SAI_STATE_RESET == hsai->State)
0963 {
0964 switch (CallbackID)
0965 {
0966 case HAL_SAI_MSPINIT_CB_ID :
0967 hsai->MspInitCallback = pCallback;
0968 break;
0969 case HAL_SAI_MSPDEINIT_CB_ID :
0970 hsai->MspDeInitCallback = pCallback;
0971 break;
0972 default :
0973
0974 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
0975
0976 status = HAL_ERROR;
0977 break;
0978 }
0979 }
0980 else
0981 {
0982
0983 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
0984
0985 status = HAL_ERROR;
0986 }
0987 }
0988 return status;
0989 }
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006 HAL_StatusTypeDef HAL_SAI_UnRegisterCallback(SAI_HandleTypeDef *hsai,
1007 HAL_SAI_CallbackIDTypeDef CallbackID)
1008 {
1009 HAL_StatusTypeDef status = HAL_OK;
1010
1011 if (HAL_SAI_STATE_READY == hsai->State)
1012 {
1013 switch (CallbackID)
1014 {
1015 case HAL_SAI_RX_COMPLETE_CB_ID :
1016 hsai->RxCpltCallback = HAL_SAI_RxCpltCallback;
1017 break;
1018 case HAL_SAI_RX_HALFCOMPLETE_CB_ID :
1019 hsai->RxHalfCpltCallback = HAL_SAI_RxHalfCpltCallback;
1020 break;
1021 case HAL_SAI_TX_COMPLETE_CB_ID :
1022 hsai->TxCpltCallback = HAL_SAI_TxCpltCallback;
1023 break;
1024 case HAL_SAI_TX_HALFCOMPLETE_CB_ID :
1025 hsai->TxHalfCpltCallback = HAL_SAI_TxHalfCpltCallback;
1026 break;
1027 case HAL_SAI_ERROR_CB_ID :
1028 hsai->ErrorCallback = HAL_SAI_ErrorCallback;
1029 break;
1030 case HAL_SAI_MSPINIT_CB_ID :
1031 hsai->MspInitCallback = HAL_SAI_MspInit;
1032 break;
1033 case HAL_SAI_MSPDEINIT_CB_ID :
1034 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
1035 break;
1036 default :
1037
1038 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
1039
1040 status = HAL_ERROR;
1041 break;
1042 }
1043 }
1044 else if (HAL_SAI_STATE_RESET == hsai->State)
1045 {
1046 switch (CallbackID)
1047 {
1048 case HAL_SAI_MSPINIT_CB_ID :
1049 hsai->MspInitCallback = HAL_SAI_MspInit;
1050 break;
1051 case HAL_SAI_MSPDEINIT_CB_ID :
1052 hsai->MspDeInitCallback = HAL_SAI_MspDeInit;
1053 break;
1054 default :
1055
1056 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
1057
1058 status = HAL_ERROR;
1059 break;
1060 }
1061 }
1062 else
1063 {
1064
1065 hsai->ErrorCode |= HAL_SAI_ERROR_INVALID_CALLBACK;
1066
1067 status = HAL_ERROR;
1068 }
1069 return status;
1070 }
1071 #endif
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129 HAL_StatusTypeDef HAL_SAI_Transmit(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1130 {
1131 uint32_t tickstart = HAL_GetTick();
1132 uint32_t temp;
1133
1134 if ((pData == NULL) || (Size == 0U))
1135 {
1136 return HAL_ERROR;
1137 }
1138
1139 if (hsai->State == HAL_SAI_STATE_READY)
1140 {
1141
1142 __HAL_LOCK(hsai);
1143
1144 hsai->XferSize = Size;
1145 hsai->XferCount = Size;
1146 hsai->pBuffPtr = pData;
1147 hsai->State = HAL_SAI_STATE_BUSY_TX;
1148 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1149
1150
1151 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1152 {
1153
1154 SAI_FillFifo(hsai);
1155
1156 __HAL_SAI_ENABLE(hsai);
1157 }
1158
1159 while (hsai->XferCount > 0U)
1160 {
1161
1162 if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL)
1163 {
1164 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1165 {
1166 hsai->Instance->DR = *hsai->pBuffPtr;
1167 hsai->pBuffPtr++;
1168 }
1169 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1170 {
1171 temp = (uint32_t)(*hsai->pBuffPtr);
1172 hsai->pBuffPtr++;
1173 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
1174 hsai->pBuffPtr++;
1175 hsai->Instance->DR = temp;
1176 }
1177 else
1178 {
1179 temp = (uint32_t)(*hsai->pBuffPtr);
1180 hsai->pBuffPtr++;
1181 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
1182 hsai->pBuffPtr++;
1183 temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
1184 hsai->pBuffPtr++;
1185 temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
1186 hsai->pBuffPtr++;
1187 hsai->Instance->DR = temp;
1188 }
1189 hsai->XferCount--;
1190 }
1191 else
1192 {
1193
1194 if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY))
1195 {
1196
1197 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1198
1199
1200 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1201
1202
1203
1204 (void) SAI_Disable(hsai);
1205
1206
1207 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1208
1209
1210 hsai->State = HAL_SAI_STATE_READY;
1211
1212
1213 __HAL_UNLOCK(hsai);
1214
1215 return HAL_ERROR;
1216 }
1217 }
1218 }
1219
1220 hsai->State = HAL_SAI_STATE_READY;
1221
1222
1223 __HAL_UNLOCK(hsai);
1224
1225 return HAL_OK;
1226 }
1227 else
1228 {
1229 return HAL_BUSY;
1230 }
1231 }
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242 HAL_StatusTypeDef HAL_SAI_Receive(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size, uint32_t Timeout)
1243 {
1244 uint32_t tickstart = HAL_GetTick();
1245 uint32_t temp;
1246
1247 if ((pData == NULL) || (Size == 0U))
1248 {
1249 return HAL_ERROR;
1250 }
1251
1252 if (hsai->State == HAL_SAI_STATE_READY)
1253 {
1254
1255 __HAL_LOCK(hsai);
1256
1257 hsai->pBuffPtr = pData;
1258 hsai->XferSize = Size;
1259 hsai->XferCount = Size;
1260 hsai->State = HAL_SAI_STATE_BUSY_RX;
1261 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1262
1263
1264 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1265 {
1266
1267 __HAL_SAI_ENABLE(hsai);
1268 }
1269
1270
1271 while (hsai->XferCount > 0U)
1272 {
1273 if ((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_EMPTY)
1274 {
1275 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1276 {
1277 *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR;
1278 hsai->pBuffPtr++;
1279 }
1280 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1281 {
1282 temp = hsai->Instance->DR;
1283 *hsai->pBuffPtr = (uint8_t)temp;
1284 hsai->pBuffPtr++;
1285 *hsai->pBuffPtr = (uint8_t)(temp >> 8);
1286 hsai->pBuffPtr++;
1287 }
1288 else
1289 {
1290 temp = hsai->Instance->DR;
1291 *hsai->pBuffPtr = (uint8_t)temp;
1292 hsai->pBuffPtr++;
1293 *hsai->pBuffPtr = (uint8_t)(temp >> 8);
1294 hsai->pBuffPtr++;
1295 *hsai->pBuffPtr = (uint8_t)(temp >> 16);
1296 hsai->pBuffPtr++;
1297 *hsai->pBuffPtr = (uint8_t)(temp >> 24);
1298 hsai->pBuffPtr++;
1299 }
1300 hsai->XferCount--;
1301 }
1302 else
1303 {
1304
1305 if ((((HAL_GetTick() - tickstart) > Timeout) || (Timeout == 0U)) && (Timeout != HAL_MAX_DELAY))
1306 {
1307
1308 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1309
1310
1311 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1312
1313
1314
1315 (void) SAI_Disable(hsai);
1316
1317
1318 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1319
1320
1321 hsai->State = HAL_SAI_STATE_READY;
1322
1323
1324 __HAL_UNLOCK(hsai);
1325
1326 return HAL_ERROR;
1327 }
1328 }
1329 }
1330
1331 hsai->State = HAL_SAI_STATE_READY;
1332
1333
1334 __HAL_UNLOCK(hsai);
1335
1336 return HAL_OK;
1337 }
1338 else
1339 {
1340 return HAL_BUSY;
1341 }
1342 }
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352 HAL_StatusTypeDef HAL_SAI_Transmit_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1353 {
1354 if ((pData == NULL) || (Size == 0U))
1355 {
1356 return HAL_ERROR;
1357 }
1358
1359 if (hsai->State == HAL_SAI_STATE_READY)
1360 {
1361
1362 __HAL_LOCK(hsai);
1363
1364 hsai->pBuffPtr = pData;
1365 hsai->XferSize = Size;
1366 hsai->XferCount = Size;
1367 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1368 hsai->State = HAL_SAI_STATE_BUSY_TX;
1369
1370 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1371 {
1372 hsai->InterruptServiceRoutine = SAI_Transmit_IT8Bit;
1373 }
1374 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1375 {
1376 hsai->InterruptServiceRoutine = SAI_Transmit_IT16Bit;
1377 }
1378 else
1379 {
1380 hsai->InterruptServiceRoutine = SAI_Transmit_IT32Bit;
1381 }
1382
1383
1384 SAI_FillFifo(hsai);
1385
1386
1387 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1388
1389
1390 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1391 {
1392
1393 __HAL_SAI_ENABLE(hsai);
1394 }
1395
1396 __HAL_UNLOCK(hsai);
1397
1398 return HAL_OK;
1399 }
1400 else
1401 {
1402 return HAL_BUSY;
1403 }
1404 }
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414 HAL_StatusTypeDef HAL_SAI_Receive_IT(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1415 {
1416 if ((pData == NULL) || (Size == 0U))
1417 {
1418 return HAL_ERROR;
1419 }
1420
1421 if (hsai->State == HAL_SAI_STATE_READY)
1422 {
1423
1424 __HAL_LOCK(hsai);
1425
1426 hsai->pBuffPtr = pData;
1427 hsai->XferSize = Size;
1428 hsai->XferCount = Size;
1429 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1430 hsai->State = HAL_SAI_STATE_BUSY_RX;
1431
1432 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
1433 {
1434 hsai->InterruptServiceRoutine = SAI_Receive_IT8Bit;
1435 }
1436 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
1437 {
1438 hsai->InterruptServiceRoutine = SAI_Receive_IT16Bit;
1439 }
1440 else
1441 {
1442 hsai->InterruptServiceRoutine = SAI_Receive_IT32Bit;
1443 }
1444
1445
1446 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
1447
1448
1449 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1450 {
1451
1452 __HAL_SAI_ENABLE(hsai);
1453 }
1454
1455
1456 __HAL_UNLOCK(hsai);
1457
1458 return HAL_OK;
1459 }
1460 else
1461 {
1462 return HAL_BUSY;
1463 }
1464 }
1465
1466
1467
1468
1469
1470
1471
1472 HAL_StatusTypeDef HAL_SAI_DMAPause(SAI_HandleTypeDef *hsai)
1473 {
1474
1475 __HAL_LOCK(hsai);
1476
1477
1478 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1479
1480
1481 __HAL_UNLOCK(hsai);
1482
1483 return HAL_OK;
1484 }
1485
1486
1487
1488
1489
1490
1491
1492 HAL_StatusTypeDef HAL_SAI_DMAResume(SAI_HandleTypeDef *hsai)
1493 {
1494
1495 __HAL_LOCK(hsai);
1496
1497
1498 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1499
1500
1501 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1502 {
1503
1504 __HAL_SAI_ENABLE(hsai);
1505 }
1506
1507
1508 __HAL_UNLOCK(hsai);
1509
1510 return HAL_OK;
1511 }
1512
1513
1514
1515
1516
1517
1518
1519 HAL_StatusTypeDef HAL_SAI_DMAStop(SAI_HandleTypeDef *hsai)
1520 {
1521 HAL_StatusTypeDef status = HAL_OK;
1522
1523
1524 __HAL_LOCK(hsai);
1525
1526
1527 if (SAI_Disable(hsai) != HAL_OK)
1528 {
1529 status = HAL_ERROR;
1530 }
1531
1532
1533 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1534
1535
1536 if ((hsai->State == HAL_SAI_STATE_BUSY_TX) && (hsai->hdmatx != NULL))
1537 {
1538 if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1539 {
1540
1541 if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1542 {
1543 status = HAL_ERROR;
1544 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1545 }
1546 }
1547 }
1548
1549
1550 if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL))
1551 {
1552 if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1553 {
1554
1555 if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1556 {
1557 status = HAL_ERROR;
1558 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1559 }
1560 }
1561 }
1562
1563
1564 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1565
1566
1567 hsai->State = HAL_SAI_STATE_READY;
1568
1569
1570 __HAL_UNLOCK(hsai);
1571
1572 return status;
1573 }
1574
1575
1576
1577
1578
1579
1580
1581 HAL_StatusTypeDef HAL_SAI_Abort(SAI_HandleTypeDef *hsai)
1582 {
1583 HAL_StatusTypeDef status = HAL_OK;
1584
1585
1586 __HAL_LOCK(hsai);
1587
1588
1589 if (SAI_Disable(hsai) != HAL_OK)
1590 {
1591 status = HAL_ERROR;
1592 }
1593
1594
1595 if ((hsai->Instance->CR1 & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1596 {
1597
1598 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
1599
1600
1601 if ((hsai->State == HAL_SAI_STATE_BUSY_TX)&& (hsai->hdmatx != NULL))
1602 {
1603 if (HAL_DMA_Abort(hsai->hdmatx) != HAL_OK)
1604 {
1605
1606 if (hsai->hdmatx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1607 {
1608 status = HAL_ERROR;
1609 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1610 }
1611 }
1612 }
1613
1614
1615 if ((hsai->State == HAL_SAI_STATE_BUSY_RX) && (hsai->hdmarx != NULL))
1616 {
1617 if (HAL_DMA_Abort(hsai->hdmarx) != HAL_OK)
1618 {
1619
1620 if (hsai->hdmarx->ErrorCode != HAL_DMA_ERROR_NO_XFER)
1621 {
1622 status = HAL_ERROR;
1623 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1624 }
1625 }
1626 }
1627 }
1628
1629
1630 hsai->Instance->IMR = 0;
1631 hsai->Instance->CLRFR = 0xFFFFFFFFU;
1632
1633
1634 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
1635
1636
1637 hsai->State = HAL_SAI_STATE_READY;
1638
1639
1640 __HAL_UNLOCK(hsai);
1641
1642 return status;
1643 }
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653 HAL_StatusTypeDef HAL_SAI_Transmit_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1654 {
1655 uint32_t tickstart = HAL_GetTick();
1656
1657 if ((pData == NULL) || (Size == 0U))
1658 {
1659 return HAL_ERROR;
1660 }
1661
1662 if (hsai->State == HAL_SAI_STATE_READY)
1663 {
1664
1665 __HAL_LOCK(hsai);
1666
1667 hsai->pBuffPtr = pData;
1668 hsai->XferSize = Size;
1669 hsai->XferCount = Size;
1670 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1671 hsai->State = HAL_SAI_STATE_BUSY_TX;
1672
1673
1674 hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
1675
1676
1677 hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
1678
1679
1680 hsai->hdmatx->XferErrorCallback = SAI_DMAError;
1681
1682
1683 hsai->hdmatx->XferAbortCallback = NULL;
1684
1685
1686 if (HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
1687 {
1688 __HAL_UNLOCK(hsai);
1689 return HAL_ERROR;
1690 }
1691
1692
1693 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1694
1695
1696 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1697
1698
1699 while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY)
1700 {
1701
1702 if ((HAL_GetTick() - tickstart) > SAI_LONG_TIMEOUT)
1703 {
1704
1705 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
1706
1707
1708 __HAL_UNLOCK(hsai);
1709
1710 return HAL_TIMEOUT;
1711 }
1712 }
1713
1714
1715 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1716 {
1717
1718 __HAL_SAI_ENABLE(hsai);
1719 }
1720
1721
1722 __HAL_UNLOCK(hsai);
1723
1724 return HAL_OK;
1725 }
1726 else
1727 {
1728 return HAL_BUSY;
1729 }
1730 }
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740 HAL_StatusTypeDef HAL_SAI_Receive_DMA(SAI_HandleTypeDef *hsai, uint8_t *pData, uint16_t Size)
1741 {
1742
1743 if ((pData == NULL) || (Size == 0U))
1744 {
1745 return HAL_ERROR;
1746 }
1747
1748 if (hsai->State == HAL_SAI_STATE_READY)
1749 {
1750
1751 __HAL_LOCK(hsai);
1752
1753 hsai->pBuffPtr = pData;
1754 hsai->XferSize = Size;
1755 hsai->XferCount = Size;
1756 hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1757 hsai->State = HAL_SAI_STATE_BUSY_RX;
1758
1759
1760 hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt;
1761
1762
1763 hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt;
1764
1765
1766 hsai->hdmarx->XferErrorCallback = SAI_DMAError;
1767
1768
1769 hsai->hdmarx->XferAbortCallback = NULL;
1770
1771
1772 if (HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
1773 {
1774 __HAL_UNLOCK(hsai);
1775 return HAL_ERROR;
1776 }
1777
1778
1779 __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
1780
1781
1782 hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1783
1784
1785 if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1786 {
1787
1788 __HAL_SAI_ENABLE(hsai);
1789 }
1790
1791
1792 __HAL_UNLOCK(hsai);
1793
1794 return HAL_OK;
1795 }
1796 else
1797 {
1798 return HAL_BUSY;
1799 }
1800 }
1801
1802
1803
1804
1805
1806
1807
1808
1809 HAL_StatusTypeDef HAL_SAI_EnableTxMuteMode(SAI_HandleTypeDef *hsai, uint16_t val)
1810 {
1811 assert_param(IS_SAI_BLOCK_MUTE_VALUE(val));
1812
1813 if (hsai->State != HAL_SAI_STATE_RESET)
1814 {
1815 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1816 SET_BIT(hsai->Instance->CR2, SAI_xCR2_MUTE | (uint32_t)val);
1817 return HAL_OK;
1818 }
1819 return HAL_ERROR;
1820 }
1821
1822
1823
1824
1825
1826
1827
1828 HAL_StatusTypeDef HAL_SAI_DisableTxMuteMode(SAI_HandleTypeDef *hsai)
1829 {
1830 if (hsai->State != HAL_SAI_STATE_RESET)
1831 {
1832 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTEVAL | SAI_xCR2_MUTE);
1833 return HAL_OK;
1834 }
1835 return HAL_ERROR;
1836 }
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846 HAL_StatusTypeDef HAL_SAI_EnableRxMuteMode(SAI_HandleTypeDef *hsai, SAIcallback callback, uint16_t counter)
1847 {
1848 assert_param(IS_SAI_BLOCK_MUTE_COUNTER(counter));
1849
1850 if (hsai->State != HAL_SAI_STATE_RESET)
1851 {
1852
1853 CLEAR_BIT(hsai->Instance->CR2, SAI_xCR2_MUTECNT);
1854 SET_BIT(hsai->Instance->CR2, (uint32_t)((uint32_t)counter << SAI_xCR2_MUTECNT_Pos));
1855 hsai->mutecallback = callback;
1856
1857 __HAL_SAI_ENABLE_IT(hsai, SAI_IT_MUTEDET);
1858 return HAL_OK;
1859 }
1860 return HAL_ERROR;
1861 }
1862
1863
1864
1865
1866
1867
1868
1869 HAL_StatusTypeDef HAL_SAI_DisableRxMuteMode(SAI_HandleTypeDef *hsai)
1870 {
1871 if (hsai->State != HAL_SAI_STATE_RESET)
1872 {
1873
1874 hsai->mutecallback = NULL;
1875
1876 __HAL_SAI_DISABLE_IT(hsai, SAI_IT_MUTEDET);
1877 return HAL_OK;
1878 }
1879 return HAL_ERROR;
1880 }
1881
1882
1883
1884
1885
1886
1887
1888 void HAL_SAI_IRQHandler(SAI_HandleTypeDef *hsai)
1889 {
1890 if (hsai->State != HAL_SAI_STATE_RESET)
1891 {
1892 uint32_t itflags = hsai->Instance->SR;
1893 uint32_t itsources = hsai->Instance->IMR;
1894 uint32_t cr1config = hsai->Instance->CR1;
1895 uint32_t tmperror;
1896
1897
1898 if (((itflags & SAI_xSR_FREQ) == SAI_xSR_FREQ) && ((itsources & SAI_IT_FREQ) == SAI_IT_FREQ))
1899 {
1900 hsai->InterruptServiceRoutine(hsai);
1901 }
1902
1903 else if (((itflags & SAI_FLAG_OVRUDR) == SAI_FLAG_OVRUDR) && ((itsources & SAI_IT_OVRUDR) == SAI_IT_OVRUDR))
1904 {
1905
1906 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
1907
1908 tmperror = ((hsai->State == HAL_SAI_STATE_BUSY_RX) ? HAL_SAI_ERROR_OVR : HAL_SAI_ERROR_UDR);
1909
1910 hsai->ErrorCode |= tmperror;
1911
1912 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1913 hsai->ErrorCallback(hsai);
1914 #else
1915 HAL_SAI_ErrorCallback(hsai);
1916 #endif
1917 }
1918
1919 else if (((itflags & SAI_FLAG_MUTEDET) == SAI_FLAG_MUTEDET) && ((itsources & SAI_IT_MUTEDET) == SAI_IT_MUTEDET))
1920 {
1921
1922 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_MUTEDET);
1923
1924 if (hsai->mutecallback != NULL)
1925 {
1926
1927 hsai->mutecallback();
1928 }
1929 }
1930
1931 else if (((itflags & SAI_FLAG_AFSDET) == SAI_FLAG_AFSDET) && ((itsources & SAI_IT_AFSDET) == SAI_IT_AFSDET))
1932 {
1933
1934 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_AFSDET);
1935
1936
1937 hsai->ErrorCode |= HAL_SAI_ERROR_AFSDET;
1938
1939
1940 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
1941 {
1942
1943 if (hsai->hdmatx != NULL)
1944 {
1945
1946 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
1947
1948
1949 if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
1950 {
1951
1952 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1953
1954
1955 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1956 hsai->ErrorCallback(hsai);
1957 #else
1958 HAL_SAI_ErrorCallback(hsai);
1959 #endif
1960 }
1961 }
1962 if (hsai->hdmarx != NULL)
1963 {
1964
1965 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
1966
1967
1968 if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
1969 {
1970
1971 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
1972
1973
1974 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1975 hsai->ErrorCallback(hsai);
1976 #else
1977 HAL_SAI_ErrorCallback(hsai);
1978 #endif
1979 }
1980 }
1981 }
1982 else
1983 {
1984
1985
1986 (void) HAL_SAI_Abort(hsai);
1987
1988
1989 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
1990 hsai->ErrorCallback(hsai);
1991 #else
1992 HAL_SAI_ErrorCallback(hsai);
1993 #endif
1994 }
1995 }
1996
1997 else if (((itflags & SAI_FLAG_LFSDET) == SAI_FLAG_LFSDET) && ((itsources & SAI_IT_LFSDET) == SAI_IT_LFSDET))
1998 {
1999
2000 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_LFSDET);
2001
2002
2003 hsai->ErrorCode |= HAL_SAI_ERROR_LFSDET;
2004
2005
2006 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
2007 {
2008
2009 if (hsai->hdmatx != NULL)
2010 {
2011
2012 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
2013
2014
2015 if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
2016 {
2017
2018 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2019
2020
2021 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2022 hsai->ErrorCallback(hsai);
2023 #else
2024 HAL_SAI_ErrorCallback(hsai);
2025 #endif
2026 }
2027 }
2028 if (hsai->hdmarx != NULL)
2029 {
2030
2031 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
2032
2033
2034 if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
2035 {
2036
2037 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2038
2039
2040 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2041 hsai->ErrorCallback(hsai);
2042 #else
2043 HAL_SAI_ErrorCallback(hsai);
2044 #endif
2045 }
2046 }
2047 }
2048 else
2049 {
2050
2051
2052 (void) HAL_SAI_Abort(hsai);
2053
2054
2055 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2056 hsai->ErrorCallback(hsai);
2057 #else
2058 HAL_SAI_ErrorCallback(hsai);
2059 #endif
2060 }
2061 }
2062
2063 else if (((itflags & SAI_FLAG_WCKCFG) == SAI_FLAG_WCKCFG) && ((itsources & SAI_IT_WCKCFG) == SAI_IT_WCKCFG))
2064 {
2065
2066 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_WCKCFG);
2067
2068
2069 hsai->ErrorCode |= HAL_SAI_ERROR_WCKCFG;
2070
2071
2072 if ((cr1config & SAI_xCR1_DMAEN) == SAI_xCR1_DMAEN)
2073 {
2074
2075 if (hsai->hdmatx != NULL)
2076 {
2077
2078 hsai->hdmatx->XferAbortCallback = SAI_DMAAbort;
2079
2080
2081 if (HAL_DMA_Abort_IT(hsai->hdmatx) != HAL_OK)
2082 {
2083
2084 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2085
2086
2087 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2088 hsai->ErrorCallback(hsai);
2089 #else
2090 HAL_SAI_ErrorCallback(hsai);
2091 #endif
2092 }
2093 }
2094 if (hsai->hdmarx != NULL)
2095 {
2096
2097 hsai->hdmarx->XferAbortCallback = SAI_DMAAbort;
2098
2099
2100 if (HAL_DMA_Abort_IT(hsai->hdmarx) != HAL_OK)
2101 {
2102
2103 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2104
2105
2106 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2107 hsai->ErrorCallback(hsai);
2108 #else
2109 HAL_SAI_ErrorCallback(hsai);
2110 #endif
2111 }
2112 }
2113 }
2114 else
2115 {
2116
2117
2118 hsai->Instance->IMR = 0U;
2119 hsai->Instance->CLRFR = 0xFFFFFFFFU;
2120
2121 hsai->State = HAL_SAI_STATE_READY;
2122
2123
2124 hsai->XferCount = 0U;
2125
2126
2127 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2128 hsai->ErrorCallback(hsai);
2129 #else
2130 HAL_SAI_ErrorCallback(hsai);
2131 #endif
2132 }
2133 }
2134
2135 else if (((itflags & SAI_FLAG_CNRDY) == SAI_FLAG_CNRDY) && ((itsources & SAI_IT_CNRDY) == SAI_IT_CNRDY))
2136 {
2137
2138 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_CNRDY);
2139
2140 hsai->ErrorCode |= HAL_SAI_ERROR_CNREADY;
2141
2142 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2143 hsai->ErrorCallback(hsai);
2144 #else
2145 HAL_SAI_ErrorCallback(hsai);
2146 #endif
2147 }
2148 else
2149 {
2150
2151 }
2152 }
2153 }
2154
2155
2156
2157
2158
2159
2160
2161 __weak void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
2162 {
2163
2164 UNUSED(hsai);
2165
2166
2167
2168
2169 }
2170
2171
2172
2173
2174
2175
2176
2177 __weak void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
2178 {
2179
2180 UNUSED(hsai);
2181
2182
2183
2184
2185 }
2186
2187
2188
2189
2190
2191
2192
2193 __weak void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
2194 {
2195
2196 UNUSED(hsai);
2197
2198
2199
2200
2201 }
2202
2203
2204
2205
2206
2207
2208
2209 __weak void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
2210 {
2211
2212 UNUSED(hsai);
2213
2214
2215
2216
2217 }
2218
2219
2220
2221
2222
2223
2224
2225 __weak void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
2226 {
2227
2228 UNUSED(hsai);
2229
2230
2231
2232
2233 }
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261 HAL_SAI_StateTypeDef HAL_SAI_GetState(const SAI_HandleTypeDef *hsai)
2262 {
2263 return hsai->State;
2264 }
2265
2266
2267
2268
2269
2270
2271
2272 uint32_t HAL_SAI_GetError(const SAI_HandleTypeDef *hsai)
2273 {
2274 return hsai->ErrorCode;
2275 }
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301 static HAL_StatusTypeDef SAI_InitI2S(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
2302 {
2303 HAL_StatusTypeDef status = HAL_OK;
2304
2305 hsai->Init.Protocol = SAI_FREE_PROTOCOL;
2306 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
2307
2308 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2309 {
2310
2311 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
2312 }
2313 else
2314 {
2315
2316 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
2317 }
2318 hsai->FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
2319 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
2320 hsai->SlotInit.FirstBitOffset = 0;
2321 hsai->SlotInit.SlotNumber = nbslot;
2322
2323
2324 if ((nbslot & 0x1U) != 0U)
2325 {
2326 return HAL_ERROR;
2327 }
2328
2329 if (protocol == SAI_I2S_STANDARD)
2330 {
2331 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
2332 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
2333 }
2334 else
2335 {
2336
2337 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
2338 hsai->FrameInit.FSOffset = SAI_FS_FIRSTBIT;
2339 }
2340
2341
2342 switch (datasize)
2343 {
2344 case SAI_PROTOCOL_DATASIZE_16BIT:
2345 hsai->Init.DataSize = SAI_DATASIZE_16;
2346 hsai->FrameInit.FrameLength = 32U * (nbslot / 2U);
2347 hsai->FrameInit.ActiveFrameLength = 16U * (nbslot / 2U);
2348 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
2349 break;
2350 case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
2351 hsai->Init.DataSize = SAI_DATASIZE_16;
2352 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2353 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2354 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2355 break;
2356 case SAI_PROTOCOL_DATASIZE_24BIT:
2357 hsai->Init.DataSize = SAI_DATASIZE_24;
2358 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2359 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2360 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2361 break;
2362 case SAI_PROTOCOL_DATASIZE_32BIT:
2363 hsai->Init.DataSize = SAI_DATASIZE_32;
2364 hsai->FrameInit.FrameLength = 64U * (nbslot / 2U);
2365 hsai->FrameInit.ActiveFrameLength = 32U * (nbslot / 2U);
2366 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2367 break;
2368 default :
2369 status = HAL_ERROR;
2370 break;
2371 }
2372 if (protocol == SAI_I2S_LSBJUSTIFIED)
2373 {
2374 if (datasize == SAI_PROTOCOL_DATASIZE_16BITEXTENDED)
2375 {
2376 hsai->SlotInit.FirstBitOffset = 16;
2377 }
2378 if (datasize == SAI_PROTOCOL_DATASIZE_24BIT)
2379 {
2380 hsai->SlotInit.FirstBitOffset = 8;
2381 }
2382 }
2383 return status;
2384 }
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396 static HAL_StatusTypeDef SAI_InitPCM(SAI_HandleTypeDef *hsai, uint32_t protocol, uint32_t datasize, uint32_t nbslot)
2397 {
2398 HAL_StatusTypeDef status = HAL_OK;
2399
2400 hsai->Init.Protocol = SAI_FREE_PROTOCOL;
2401 hsai->Init.FirstBit = SAI_FIRSTBIT_MSB;
2402
2403 if ((hsai->Init.AudioMode == SAI_MODEMASTER_TX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2404 {
2405
2406 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
2407 }
2408 else
2409 {
2410
2411 hsai->Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
2412 }
2413 hsai->FrameInit.FSDefinition = SAI_FS_STARTFRAME;
2414 hsai->FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
2415 hsai->FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
2416 hsai->SlotInit.FirstBitOffset = 0;
2417 hsai->SlotInit.SlotNumber = nbslot;
2418 hsai->SlotInit.SlotActive = SAI_SLOTACTIVE_ALL;
2419
2420 if (protocol == SAI_PCM_SHORT)
2421 {
2422 hsai->FrameInit.ActiveFrameLength = 1;
2423 }
2424 else
2425 {
2426
2427 hsai->FrameInit.ActiveFrameLength = 13;
2428 }
2429
2430 switch (datasize)
2431 {
2432 case SAI_PROTOCOL_DATASIZE_16BIT:
2433 hsai->Init.DataSize = SAI_DATASIZE_16;
2434 hsai->FrameInit.FrameLength = 16U * nbslot;
2435 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_16B;
2436 break;
2437 case SAI_PROTOCOL_DATASIZE_16BITEXTENDED :
2438 hsai->Init.DataSize = SAI_DATASIZE_16;
2439 hsai->FrameInit.FrameLength = 32U * nbslot;
2440 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2441 break;
2442 case SAI_PROTOCOL_DATASIZE_24BIT :
2443 hsai->Init.DataSize = SAI_DATASIZE_24;
2444 hsai->FrameInit.FrameLength = 32U * nbslot;
2445 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2446 break;
2447 case SAI_PROTOCOL_DATASIZE_32BIT:
2448 hsai->Init.DataSize = SAI_DATASIZE_32;
2449 hsai->FrameInit.FrameLength = 32U * nbslot;
2450 hsai->SlotInit.SlotSize = SAI_SLOTSIZE_32B;
2451 break;
2452 default :
2453 status = HAL_ERROR;
2454 break;
2455 }
2456
2457 return status;
2458 }
2459
2460
2461
2462
2463
2464
2465
2466 static void SAI_FillFifo(SAI_HandleTypeDef *hsai)
2467 {
2468 uint32_t temp;
2469
2470
2471 while (((hsai->Instance->SR & SAI_xSR_FLVL) != SAI_FIFOSTATUS_FULL) && (hsai->XferCount > 0U))
2472 {
2473 if ((hsai->Init.DataSize == SAI_DATASIZE_8) && (hsai->Init.CompandingMode == SAI_NOCOMPANDING))
2474 {
2475 hsai->Instance->DR = *hsai->pBuffPtr;
2476 hsai->pBuffPtr++;
2477 }
2478 else if (hsai->Init.DataSize <= SAI_DATASIZE_16)
2479 {
2480 temp = (uint32_t)(*hsai->pBuffPtr);
2481 hsai->pBuffPtr++;
2482 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2483 hsai->pBuffPtr++;
2484 hsai->Instance->DR = temp;
2485 }
2486 else
2487 {
2488 temp = (uint32_t)(*hsai->pBuffPtr);
2489 hsai->pBuffPtr++;
2490 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2491 hsai->pBuffPtr++;
2492 temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
2493 hsai->pBuffPtr++;
2494 temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
2495 hsai->pBuffPtr++;
2496 hsai->Instance->DR = temp;
2497 }
2498 hsai->XferCount--;
2499 }
2500 }
2501
2502
2503
2504
2505
2506
2507
2508
2509 static uint32_t SAI_InterruptFlag(const SAI_HandleTypeDef *hsai, SAI_ModeTypedef mode)
2510 {
2511 uint32_t tmpIT = SAI_IT_OVRUDR;
2512
2513 if (mode == SAI_MODE_IT)
2514 {
2515 tmpIT |= SAI_IT_FREQ;
2516 }
2517
2518 if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
2519 ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODEMASTER_RX)))
2520 {
2521 tmpIT |= SAI_IT_CNRDY;
2522 }
2523
2524 if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2525 {
2526 tmpIT |= SAI_IT_AFSDET | SAI_IT_LFSDET;
2527 }
2528 else
2529 {
2530
2531 tmpIT |= SAI_IT_WCKCFG;
2532 }
2533 return tmpIT;
2534 }
2535
2536
2537
2538
2539
2540
2541
2542 static HAL_StatusTypeDef SAI_Disable(SAI_HandleTypeDef *hsai)
2543 {
2544 uint32_t count = SAI_DEFAULT_TIMEOUT * (SystemCoreClock / 7U / 1000U);
2545 HAL_StatusTypeDef status = HAL_OK;
2546
2547
2548 __HAL_SAI_DISABLE(hsai);
2549
2550 do
2551 {
2552
2553 if (count == 0U)
2554 {
2555
2556 hsai->ErrorCode |= HAL_SAI_ERROR_TIMEOUT;
2557 status = HAL_TIMEOUT;
2558 break;
2559 }
2560 count--;
2561 }
2562 while ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) != 0U);
2563
2564 return status;
2565 }
2566
2567
2568
2569
2570
2571
2572
2573 static void SAI_Transmit_IT8Bit(SAI_HandleTypeDef *hsai)
2574 {
2575 if (hsai->XferCount == 0U)
2576 {
2577
2578
2579 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2580 hsai->State = HAL_SAI_STATE_READY;
2581 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2582 hsai->TxCpltCallback(hsai);
2583 #else
2584 HAL_SAI_TxCpltCallback(hsai);
2585 #endif
2586 }
2587 else
2588 {
2589
2590 hsai->Instance->DR = *hsai->pBuffPtr;
2591 hsai->pBuffPtr++;
2592 hsai->XferCount--;
2593 }
2594 }
2595
2596
2597
2598
2599
2600
2601
2602 static void SAI_Transmit_IT16Bit(SAI_HandleTypeDef *hsai)
2603 {
2604 if (hsai->XferCount == 0U)
2605 {
2606
2607
2608 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2609 hsai->State = HAL_SAI_STATE_READY;
2610 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2611 hsai->TxCpltCallback(hsai);
2612 #else
2613 HAL_SAI_TxCpltCallback(hsai);
2614 #endif
2615 }
2616 else
2617 {
2618
2619 uint32_t temp;
2620 temp = (uint32_t)(*hsai->pBuffPtr);
2621 hsai->pBuffPtr++;
2622 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2623 hsai->pBuffPtr++;
2624 hsai->Instance->DR = temp;
2625 hsai->XferCount--;
2626 }
2627 }
2628
2629
2630
2631
2632
2633
2634
2635 static void SAI_Transmit_IT32Bit(SAI_HandleTypeDef *hsai)
2636 {
2637 if (hsai->XferCount == 0U)
2638 {
2639
2640
2641 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2642 hsai->State = HAL_SAI_STATE_READY;
2643 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2644 hsai->TxCpltCallback(hsai);
2645 #else
2646 HAL_SAI_TxCpltCallback(hsai);
2647 #endif
2648 }
2649 else
2650 {
2651
2652 uint32_t temp;
2653 temp = (uint32_t)(*hsai->pBuffPtr);
2654 hsai->pBuffPtr++;
2655 temp |= ((uint32_t)(*hsai->pBuffPtr) << 8);
2656 hsai->pBuffPtr++;
2657 temp |= ((uint32_t)(*hsai->pBuffPtr) << 16);
2658 hsai->pBuffPtr++;
2659 temp |= ((uint32_t)(*hsai->pBuffPtr) << 24);
2660 hsai->pBuffPtr++;
2661 hsai->Instance->DR = temp;
2662 hsai->XferCount--;
2663 }
2664 }
2665
2666
2667
2668
2669
2670
2671
2672 static void SAI_Receive_IT8Bit(SAI_HandleTypeDef *hsai)
2673 {
2674
2675 *hsai->pBuffPtr = (uint8_t)hsai->Instance->DR;
2676 hsai->pBuffPtr++;
2677 hsai->XferCount--;
2678
2679
2680 if (hsai->XferCount == 0U)
2681 {
2682
2683 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2684
2685
2686 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2687
2688 hsai->State = HAL_SAI_STATE_READY;
2689 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2690 hsai->RxCpltCallback(hsai);
2691 #else
2692 HAL_SAI_RxCpltCallback(hsai);
2693 #endif
2694 }
2695 }
2696
2697
2698
2699
2700
2701
2702
2703 static void SAI_Receive_IT16Bit(SAI_HandleTypeDef *hsai)
2704 {
2705 uint32_t temp;
2706
2707
2708 temp = hsai->Instance->DR;
2709 *hsai->pBuffPtr = (uint8_t)temp;
2710 hsai->pBuffPtr++;
2711 *hsai->pBuffPtr = (uint8_t)(temp >> 8);
2712 hsai->pBuffPtr++;
2713 hsai->XferCount--;
2714
2715
2716 if (hsai->XferCount == 0U)
2717 {
2718
2719 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2720
2721
2722 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2723
2724 hsai->State = HAL_SAI_STATE_READY;
2725 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2726 hsai->RxCpltCallback(hsai);
2727 #else
2728 HAL_SAI_RxCpltCallback(hsai);
2729 #endif
2730 }
2731 }
2732
2733
2734
2735
2736
2737
2738
2739 static void SAI_Receive_IT32Bit(SAI_HandleTypeDef *hsai)
2740 {
2741 uint32_t temp;
2742
2743
2744 temp = hsai->Instance->DR;
2745 *hsai->pBuffPtr = (uint8_t)temp;
2746 hsai->pBuffPtr++;
2747 *hsai->pBuffPtr = (uint8_t)(temp >> 8);
2748 hsai->pBuffPtr++;
2749 *hsai->pBuffPtr = (uint8_t)(temp >> 16);
2750 hsai->pBuffPtr++;
2751 *hsai->pBuffPtr = (uint8_t)(temp >> 24);
2752 hsai->pBuffPtr++;
2753 hsai->XferCount--;
2754
2755
2756 if (hsai->XferCount == 0U)
2757 {
2758
2759 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_IT));
2760
2761
2762 __HAL_SAI_CLEAR_FLAG(hsai, SAI_FLAG_OVRUDR);
2763
2764 hsai->State = HAL_SAI_STATE_READY;
2765 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2766 hsai->RxCpltCallback(hsai);
2767 #else
2768 HAL_SAI_RxCpltCallback(hsai);
2769 #endif
2770 }
2771 }
2772
2773
2774
2775
2776
2777
2778
2779 static void SAI_DMATxCplt(DMA_HandleTypeDef *hdma)
2780 {
2781 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2782
2783 if (hdma->Init.Mode != DMA_CIRCULAR)
2784 {
2785 hsai->XferCount = 0;
2786
2787
2788 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2789
2790
2791 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2792
2793 hsai->State = HAL_SAI_STATE_READY;
2794 }
2795 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2796 hsai->TxCpltCallback(hsai);
2797 #else
2798 HAL_SAI_TxCpltCallback(hsai);
2799 #endif
2800 }
2801
2802
2803
2804
2805
2806
2807
2808 static void SAI_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
2809 {
2810 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2811
2812 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2813 hsai->TxHalfCpltCallback(hsai);
2814 #else
2815 HAL_SAI_TxHalfCpltCallback(hsai);
2816 #endif
2817 }
2818
2819
2820
2821
2822
2823
2824
2825 static void SAI_DMARxCplt(DMA_HandleTypeDef *hdma)
2826 {
2827 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2828
2829 if (hdma->Init.Mode != DMA_CIRCULAR)
2830 {
2831
2832 hsai->Instance->CR1 &= (uint32_t)(~SAI_xCR1_DMAEN);
2833 hsai->XferCount = 0;
2834
2835
2836 __HAL_SAI_DISABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
2837
2838 hsai->State = HAL_SAI_STATE_READY;
2839 }
2840 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2841 hsai->RxCpltCallback(hsai);
2842 #else
2843 HAL_SAI_RxCpltCallback(hsai);
2844 #endif
2845 }
2846
2847
2848
2849
2850
2851
2852
2853 static void SAI_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
2854 {
2855 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2856
2857 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2858 hsai->RxHalfCpltCallback(hsai);
2859 #else
2860 HAL_SAI_RxHalfCpltCallback(hsai);
2861 #endif
2862 }
2863
2864
2865
2866
2867
2868
2869
2870 static void SAI_DMAError(DMA_HandleTypeDef *hdma)
2871 {
2872 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2873
2874
2875 if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2876 {
2877
2878 hsai->ErrorCode |= HAL_SAI_ERROR_DMA;
2879
2880
2881 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2882
2883
2884
2885 (void) SAI_Disable(hsai);
2886
2887
2888 hsai->State = HAL_SAI_STATE_READY;
2889
2890
2891 hsai->XferCount = 0U;
2892
2893
2894 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2895 hsai->ErrorCallback(hsai);
2896 #else
2897 HAL_SAI_ErrorCallback(hsai);
2898 #endif
2899 }
2900 }
2901
2902
2903
2904
2905
2906
2907
2908 static void SAI_DMAAbort(DMA_HandleTypeDef *hdma)
2909 {
2910 SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2911
2912
2913 hsai->Instance->CR1 &= ~SAI_xCR1_DMAEN;
2914
2915
2916 hsai->Instance->IMR = 0U;
2917 hsai->Instance->CLRFR = 0xFFFFFFFFU;
2918
2919 if (hsai->ErrorCode != HAL_SAI_ERROR_WCKCFG)
2920 {
2921
2922
2923 (void) SAI_Disable(hsai);
2924
2925
2926 SET_BIT(hsai->Instance->CR2, SAI_xCR2_FFLUSH);
2927 }
2928
2929 hsai->State = HAL_SAI_STATE_READY;
2930
2931
2932 hsai->XferCount = 0U;
2933
2934
2935 #if (USE_HAL_SAI_REGISTER_CALLBACKS == 1)
2936 hsai->ErrorCallback(hsai);
2937 #else
2938 HAL_SAI_ErrorCallback(hsai);
2939 #endif
2940 }
2941
2942
2943
2944
2945
2946 #endif
2947
2948
2949
2950
2951
2952
2953
2954