/** * @brief Changes the Audio Out Configuration. * @param AudioOutOption: specifies the audio out new configuration * This parameter can be any value of @ref BSP_Audio_Out_Option * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the * audio out configuration. * @retval None */ void BSP_AUDIO_OUT_ChangeAudioConfig(uint32_t AudioOutOption) { /********** Playback Buffer circular/normal mode **********/ if(AudioOutOption & BSP_AUDIO_OUT_CIRCULARMODE) { /* Deinitialize the Stream to update DMA mode */ HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx); /* Update the SAI audio Transfer DMA mode */ BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_CIRCULAR; /* Configure the DMA Stream with new Transfer DMA mode */ HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx); } else /* BSP_AUDIO_OUT_NORMALMODE */ { /* Deinitialize the Stream to update DMA mode */ HAL_DMA_DeInit(BSP_AUDIO_hSai.hdmatx); /* Update the SAI audio Transfer DMA mode */ BSP_AUDIO_hSai.hdmatx->Init.Mode = DMA_NORMAL; /* Configure the DMA Stream with new Transfer DMA mode */ HAL_DMA_Init(BSP_AUDIO_hSai.hdmatx); } /********** Playback Buffer stereo/mono mode **********/ if(AudioOutOption & BSP_AUDIO_OUT_STEREOMODE) { /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); /* Update the SAI audio frame slot configuration */ BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE; HAL_SAI_Init(&BSP_AUDIO_hSai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); } else /* BSP_AUDIO_OUT_MONOMODE */ { /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); /* Update the SAI audio frame slot configuration */ BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_MONOMODE; HAL_SAI_Init(&BSP_AUDIO_hSai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); } }
/** * @brief Deinitializes SAI MSP. * @param hsai: SAI handle * @param Params * @retval None */ __weak void BSP_AUDIO_OUT_MspDeInit(SAI_HandleTypeDef *hsai, void *Params) { GPIO_InitTypeDef gpio_init_structure; /* SAI DMA IRQ Channel deactivation */ HAL_NVIC_DisableIRQ(AUDIO_OUT_SAIx_DMAx_IRQ); if(hsai->Instance == AUDIO_OUT_SAIx) { /* Deinitialize the DMA stream */ HAL_DMA_DeInit(hsai->hdmatx); } /* Disable SAI peripheral */ __HAL_SAI_DISABLE(hsai); /* Deactives CODEC_SAI pins FS, SCK, MCK and SD by putting them in input mode */ gpio_init_structure.Pin = AUDIO_OUT_SAIx_FS_PIN; HAL_GPIO_DeInit(AUDIO_OUT_SAIx_FS_GPIO_PORT, gpio_init_structure.Pin); gpio_init_structure.Pin = AUDIO_OUT_SAIx_SCK_PIN; HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, gpio_init_structure.Pin); gpio_init_structure.Pin = AUDIO_OUT_SAIx_SD_PIN; HAL_GPIO_DeInit(AUDIO_OUT_SAIx_SCK_SD_GPIO_PORT, gpio_init_structure.Pin); gpio_init_structure.Pin = AUDIO_OUT_SAIx_MCLK_PIN; HAL_GPIO_DeInit(AUDIO_OUT_SAIx_MCLK_GPIO_PORT, gpio_init_structure.Pin); /* Disable SAI clock */ AUDIO_OUT_SAIx_CLK_DISABLE(); /* GPIO pins clock and DMA clock can be shut down in the application by surcharging this __weak function */ }
/** * @brief DeInitializes BSP_AUDIO_IN MSP. * @param hsai: SAI handle * @param Params * @retval None */ __weak void BSP_AUDIO_IN_MspDeInit(SAI_HandleTypeDef *hsai, void *Params) { GPIO_InitTypeDef gpio_init_structure; static DMA_HandleTypeDef hdma_sai_rx; /* SAI IN DMA IRQ Channel deactivation */ HAL_NVIC_DisableIRQ(AUDIO_IN_SAIx_DMAx_IRQ); if(hsai->Instance == AUDIO_IN_SAIx) { /* Deinitialize the Stream for new transfer */ HAL_DMA_DeInit(&hdma_sai_rx); } /* Disable SAI block */ __HAL_SAI_DISABLE(hsai); /* Disable pin: SD pin */ gpio_init_structure.Pin = AUDIO_IN_SAIx_SD_PIN; HAL_GPIO_DeInit(AUDIO_IN_SAIx_SD_GPIO_PORT, gpio_init_structure.Pin); /* Disable SAI clock */ AUDIO_IN_SAIx_CLK_DISABLE(); /* GPIO pins clock and DMA clock can be shut down in the application by surcharging this __weak function */ }
/** * @brief Deinitializes the output Audio Codec audio interface (SAI). * @retval None */ static void SAIx_Out_DeInit(void) { /* Initialize the haudio_out_sai Instance parameter */ haudio_out_sai.Instance = AUDIO_OUT_SAIx; /* Disable SAI peripheral */ __HAL_SAI_DISABLE(&haudio_out_sai); HAL_SAI_DeInit(&haudio_out_sai); }
/** * @brief Updates the Audio frame slot configuration. * @param AudioFrameSlot: specifies the audio Frame slot * This parameter can be one of the following values * @arg CODEC_AUDIOFRAME_SLOT_0123 * @arg CODEC_AUDIOFRAME_SLOT_02 * @arg CODEC_AUDIOFRAME_SLOT_13 * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the * audio frame slot. * @retval None */ void BSP_AUDIO_OUT_SetAudioFrameSlot(uint32_t AudioFrameSlot) { /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&haudio_out_sai); /* Update the SAI audio frame slot configuration */ haudio_out_sai.SlotInit.SlotActive = AudioFrameSlot; HAL_SAI_Init(&haudio_out_sai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&haudio_out_sai); }
/** * @brief Updates the audio frequency. * @param AudioFreq: Audio frequency used to play the audio stream. * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the * audio frequency. * @retval None */ void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) { /* PLL clock is set depending by the AudioFreq (44.1khz vs 48khz groups) */ BSP_AUDIO_OUT_ClockConfig(&haudio_out_sai, AudioFreq, NULL); /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&haudio_out_sai); /* Update the SAI audio frequency configuration */ haudio_out_sai.Init.AudioFrequency = AudioFreq; HAL_SAI_Init(&haudio_out_sai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&haudio_out_sai); }
/** * @brief De-initializes the Audio Codec audio interface (SAI). * @retval BSP AUDIO status */ static uint8_t AUDIO_SAIx_DeInit(void) { /* Disable the SAI audio block */ __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); /* De-initializes the SAI peripheral */ if (HAL_SAI_DeInit(&BSP_AUDIO_hSai) != HAL_OK) { return AUDIO_ERROR; } /* Disable SAIx PLL */ if (AUDIO_SAIx_PLL_DISABLE() != AUDIO_OK) { return AUDIO_ERROR; } return AUDIO_OK; }
/** * @brief Updates the audio frequency. * @param AudioFreq: Audio frequency used to play the audio stream. * @note The SAI PLL input clock must be configure in the user application. * The SAI PLL configuration done within this function assumes that * the SAI PLL input clock runs at 8 MHz. * @retval BSP AUDIO status */ uint8_t BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) { /* Configure the SAI PLL according to the requested audio frequency */ if (AUDIO_SAIPLLConfig(AudioFreq) != AUDIO_OK) { return AUDIO_ERROR; } /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); /* Update the SAI audio frequency configuration */ BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq); HAL_SAI_Init(&BSP_AUDIO_hSai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); return AUDIO_OK; }
/** * @brief Playback initialization * @param None * @retval None */ static void Playback_Init(void) { RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; /* Configure PLLSAI prescalers */ /* PLLSAI_VCO: VCO_429M SAI_CLK(first level) = PLLSAI_VCO/PLLSAIQ = 429/2 = 214.5 Mhz SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ = 214.5/19 = 11.289 Mhz */ RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2; RCC_PeriphCLKInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI; RCC_PeriphCLKInitStruct.PLLSAI.PLLSAIM = 8; RCC_PeriphCLKInitStruct.PLLSAI.PLLSAIN = 429; RCC_PeriphCLKInitStruct.PLLSAI.PLLSAIQ = 2; RCC_PeriphCLKInitStruct.PLLSAIDivQ = 19; if(HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct) != HAL_OK) { Error_Handler(); } /* Initialize SAI */ __HAL_SAI_RESET_HANDLE_STATE(&SaiHandle); SaiHandle.Instance = AUDIO_SAIx; __HAL_SAI_DISABLE(&SaiHandle); SaiHandle.Init.AudioMode = SAI_MODEMASTER_TX; SaiHandle.Init.Synchro = SAI_ASYNCHRONOUS; SaiHandle.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; SaiHandle.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; SaiHandle.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; SaiHandle.Init.ClockSource = SAI_CLKSOURCE_PLLSAI; SaiHandle.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_22K; SaiHandle.Init.Protocol = SAI_FREE_PROTOCOL; SaiHandle.Init.DataSize = SAI_DATASIZE_16; SaiHandle.Init.FirstBit = SAI_FIRSTBIT_MSB; SaiHandle.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; SaiHandle.FrameInit.FrameLength = 32; SaiHandle.FrameInit.ActiveFrameLength = 16; SaiHandle.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; SaiHandle.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; SaiHandle.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; SaiHandle.SlotInit.FirstBitOffset = 0; SaiHandle.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; SaiHandle.SlotInit.SlotNumber = 2; SaiHandle.SlotInit.SlotActive = (SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1); if(HAL_OK != HAL_SAI_Init(&SaiHandle)) { Error_Handler(); } /* Enable SAI to generate clock used by audio driver */ __HAL_SAI_ENABLE(&SaiHandle); /* Initialize audio driver */ if(WM8994_ID != wm8994_drv.ReadID(AUDIO_I2C_ADDRESS)) { Error_Handler(); } audio_drv = &wm8994_drv; audio_drv->Reset(AUDIO_I2C_ADDRESS); if(0 != audio_drv->Init(AUDIO_I2C_ADDRESS, OUTPUT_DEVICE_HEADPHONE, 20, AUDIO_FREQUENCY_22K)) { Error_Handler(); } }
/** * @brief Initializes the Audio Codec audio interface (SAI). * @param AudioFreq: Audio frequency to be configured for the SAI peripheral. * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 * and user can update this configuration using * @retval BSP AUDIO status */ static uint8_t AUDIO_SAIx_Init(uint32_t AudioFreq) { /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&BSP_AUDIO_hSai); /* Initialize the BSP_AUDIO_hSai Instance parameter */ BSP_AUDIO_hSai.Instance = AUDIO_SAIx; /* Configure SAI_Block_x LSBFirst: Disabled DataSize: 16 */ BSP_AUDIO_hSai.Init.AudioMode = SAI_MODEMASTER_TX; BSP_AUDIO_hSai.Init.Synchro = SAI_ASYNCHRONOUS; BSP_AUDIO_hSai.Init.SynchroExt = SAI_SYNCEXT_DISABLE; BSP_AUDIO_hSai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE; BSP_AUDIO_hSai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE; BSP_AUDIO_hSai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; BSP_AUDIO_hSai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV; BSP_AUDIO_hSai.Init.Mckdiv = SAIClockDivider(AudioFreq); BSP_AUDIO_hSai.Init.MonoStereoMode = SAI_STEREOMODE; BSP_AUDIO_hSai.Init.CompandingMode = SAI_NOCOMPANDING; BSP_AUDIO_hSai.Init.TriState = SAI_OUTPUT_NOTRELEASED; BSP_AUDIO_hSai.Init.Protocol = SAI_FREE_PROTOCOL; BSP_AUDIO_hSai.Init.DataSize = SAI_DATASIZE_16; BSP_AUDIO_hSai.Init.FirstBit = SAI_FIRSTBIT_MSB; BSP_AUDIO_hSai.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE; /* Configure SAI_Block_x Frame Frame Length: 32 Frame active Length: 16 FS Definition: Start frame + Channel Side identification FS Polarity: FS active Low FS Offset: FS asserted one bit before the first bit of slot 0 */ BSP_AUDIO_hSai.FrameInit.FrameLength = 32; BSP_AUDIO_hSai.FrameInit.ActiveFrameLength = 16; BSP_AUDIO_hSai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; BSP_AUDIO_hSai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; BSP_AUDIO_hSai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; /* Configure SAI Block_x Slot Slot First Bit Offset: 0 Slot Size : 16 Slot Number: 2 Slot Active: Slots 0 and 1 actives */ BSP_AUDIO_hSai.SlotInit.FirstBitOffset = 0; BSP_AUDIO_hSai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; BSP_AUDIO_hSai.SlotInit.SlotNumber = 2; BSP_AUDIO_hSai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1; /* Initializes the SAI peripheral*/ if (HAL_SAI_Init(&BSP_AUDIO_hSai) != HAL_OK) { return AUDIO_ERROR; } /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&BSP_AUDIO_hSai); return AUDIO_OK; }
/** * @brief Initializes the output Audio Codec audio interface (SAI). * @param AudioFreq: Audio frequency to be configured for the SAI peripheral. * @note The default SlotActive configuration is set to CODEC_AUDIOFRAME_SLOT_0123 * and user can update this configuration using * @retval None */ static void SAIx_Out_Init(uint32_t AudioFreq) { /* Initialize the haudio_out_sai Instance parameter */ haudio_out_sai.Instance = AUDIO_OUT_SAIx; /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&haudio_out_sai); /* Configure SAI_Block_x LSBFirst: Disabled DataSize: 16 */ haudio_out_sai.Init.AudioFrequency = AudioFreq; haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX; haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED; haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL; #ifdef AUDIO_FORMAT_32BITS haudio_out_sai.Init.DataSize = SAI_DATASIZE_32; #else haudio_out_sai.Init.DataSize = SAI_DATASIZE_16; #endif haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB; // haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_LSB; haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS; haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLED; haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; haudio_out_sai.Init.MonoStereoMode=SAI_STEREOMODE; /* Configure SAI_Block_x Frame Frame Length: 64 Frame active Length: 32 FS Definition: Start frame + Channel Side identification FS Polarity: FS active Low FS Offset: FS asserted one bit before the first bit of slot 0 */ #ifdef AUDIO_FORMAT_32BITS haudio_out_sai.FrameInit.FrameLength = 64*2; haudio_out_sai.FrameInit.ActiveFrameLength = 32*2; #else haudio_out_sai.FrameInit.FrameLength = 64; haudio_out_sai.FrameInit.ActiveFrameLength = 32; #endif haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; /* Configure SAI Block_x Slot Slot First Bit Offset: 0 Slot Size : 16 Slot Number: 4 Slot Active: All slot actives */ haudio_out_sai.SlotInit.FirstBitOffset = 0; #ifdef AUDIO_FORMAT_32BITS haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_32B; #else haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; #endif haudio_out_sai.SlotInit.SlotNumber = 4; haudio_out_sai.SlotInit.SlotActive = CODEC_AUDIOFRAME_SLOT_0123; HAL_SAI_Init(&haudio_out_sai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&haudio_out_sai); }
/** * @brief Initializes the input Audio Codec audio interface (SAI). * @param SaiOutMode: SAI_MODEMASTER_TX (for record and playback in parallel) * or SAI_MODEMASTER_RX (for record only). * @param SlotActive: CODEC_AUDIOFRAME_SLOT_02 or CODEC_AUDIOFRAME_SLOT_13 * @param AudioFreq: Audio frequency to be configured for the SAI peripheral. * @retval None */ static void SAIx_In_Init(uint32_t SaiOutMode, uint32_t SlotActive, uint32_t AudioFreq) { /* Initialize SAI2 block A in MASTER RX */ /* Initialize the haudio_out_sai Instance parameter */ haudio_out_sai.Instance = AUDIO_OUT_SAIx; /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&haudio_out_sai); /* Configure SAI_Block_x LSBFirst: Disabled DataSize: 16 */ haudio_out_sai.Init.AudioFrequency = AudioFreq; haudio_out_sai.Init.AudioMode = SaiOutMode; haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED; haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL; haudio_out_sai.Init.DataSize = SAI_DATASIZE_16; haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB; haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS; haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLED; haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; /* Configure SAI_Block_x Frame Frame Length: 64 Frame active Length: 32 FS Definition: Start frame + Channel Side identification FS Polarity: FS active Low FS Offset: FS asserted one bit before the first bit of slot 0 */ haudio_out_sai.FrameInit.FrameLength = 64; haudio_out_sai.FrameInit.ActiveFrameLength = 32; haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; /* Configure SAI Block_x Slot Slot First Bit Offset: 0 Slot Size : 16 Slot Number: 4 Slot Active: All slot actives */ haudio_out_sai.SlotInit.FirstBitOffset = 0; haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; haudio_out_sai.SlotInit.SlotNumber = 4; haudio_out_sai.SlotInit.SlotActive = SlotActive; HAL_SAI_Init(&haudio_out_sai); /* Initialize SAI2 block B in SLAVE RX synchronous from SAI2 block A */ /* Initialize the haudio_in_sai Instance parameter */ haudio_in_sai.Instance = AUDIO_IN_SAIx; /* Disable SAI peripheral to allow access to SAI internal registers */ __HAL_SAI_DISABLE(&haudio_in_sai); /* Configure SAI_Block_x LSBFirst: Disabled DataSize: 16 */ haudio_in_sai.Init.AudioFrequency = AudioFreq; haudio_in_sai.Init.AudioMode = SAI_MODESLAVE_RX; haudio_in_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLED; haudio_in_sai.Init.Protocol = SAI_FREE_PROTOCOL; haudio_in_sai.Init.DataSize = SAI_DATASIZE_16; haudio_in_sai.Init.FirstBit = SAI_FIRSTBIT_MSB; haudio_in_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE; haudio_in_sai.Init.Synchro = SAI_SYNCHRONOUS; haudio_in_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLED; haudio_in_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF; /* Configure SAI_Block_x Frame Frame Length: 64 Frame active Length: 32 FS Definition: Start frame + Channel Side identification FS Polarity: FS active Low FS Offset: FS asserted one bit before the first bit of slot 0 */ haudio_in_sai.FrameInit.FrameLength = 64; haudio_in_sai.FrameInit.ActiveFrameLength = 32; haudio_in_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION; haudio_in_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW; haudio_in_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT; /* Configure SAI Block_x Slot Slot First Bit Offset: 0 Slot Size : 16 Slot Number: 4 Slot Active: All slot active */ haudio_in_sai.SlotInit.FirstBitOffset = 0; haudio_in_sai.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE; haudio_in_sai.SlotInit.SlotNumber = 4; haudio_in_sai.SlotInit.SlotActive = SlotActive; HAL_SAI_Init(&haudio_in_sai); /* Enable SAI peripheral to generate MCLK */ __HAL_SAI_ENABLE(&haudio_out_sai); /* Enable SAI peripheral */ __HAL_SAI_ENABLE(&haudio_in_sai); }