/** * @brief System Clock Configuration * The system Clock is configured as follow : * System Clock source = PLL (HSE) * SYSCLK(Hz) = 72000000 * HCLK(Hz) = 72000000 * AHB Prescaler = 1 * APB1 Prescaler = 2 * APB2 Prescaler = 1 * HSE Frequency(Hz) = 8000000 * HSE PREDIV = 1 * PLLMUL = RCC_PLL_MUL9 (9) * Flash Latency(WS) = 2 * @param None * @retval None */ static void SystemClock_Config(void) { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; HAL_RCC_OscConfig(&RCC_OscInitStruct); /* Configures the USB clock */ HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); RCC_PeriphClkInit.USBClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5; HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit); /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); }
/** * @brief Update the audio frequency. * @param AudioFreq: Audio frequency used to play the audio stream. * @retval None * @note This API should be called after the BSP_AUDIO_OUT_Init() to adjust the * audio frequency. */ void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) { RCC_PeriphCLKInitTypeDef rccclkinit; /* Enable PLLI2S clock */ HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ if ((AudioFreq & 0x7) == 0) { /* Audio frequency multiple of 8 (8/16/32/48/96/192)*/ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 192 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 192/6 = 32 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 192; rccclkinit.PLLI2S.PLLI2SR = 6; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } else { /* Other Frequency (11.025/22.500/44.100) */ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 290 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 290/2 = 145 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 290; rccclkinit.PLLI2S.PLLI2SR = 2; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } /* Update the I2S audio frequency configuration */ I2S3_Init(AudioFreq); }
/** * @brief Configure the audio peripherals. * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to play the audio stream. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint8_t ret = AUDIO_ERROR; uint32_t deviceid = 0x00; RCC_PeriphCLKInitTypeDef rccclkinit; /* Enable PLLI2S clock */ HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ if((AudioFreq & 0x7) == 0) { /* Audio frequency multiple of 8 (8/16/32/48/96/192)*/ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 192 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 192/6 = 32 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 192; rccclkinit.PLLI2S.PLLI2SR = 6; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } else { /* Other Frequency (11.025/22.500/44.100) */ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 290 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 290/2 = 145 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 290; rccclkinit.PLLI2S.PLLI2SR = 2; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } deviceid = cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS); if((deviceid & CS43L22_ID_MASK) == CS43L22_ID) { /* Initialize the audio driver structure */ pAudioDrv = &cs43l22_drv; ret = AUDIO_OK; } else { ret = AUDIO_ERROR; } if(ret == AUDIO_OK) { pAudioDrv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq); /* I2S data transfer preparation: Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ /* Configure the I2S peripheral */ I2S3_Init(AudioFreq); } return ret; }
/** * @brief Initializes the SD MSP. * @note The SDMMC clock configuration done within this function assumes that * the PLLSAI1 input clock runs at 8 MHz. * @param hsd: SD handle * @param Params: Additional parameters * @retval None */ __weak void BSP_SD_MspInit(SD_HandleTypeDef *hsd, void *Params) { GPIO_InitTypeDef gpioinitstruct = {0}; RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit; /* Prevent unused argument(s) compilation warning */ UNUSED(Params); HAL_RCCEx_GetPeriphCLKConfig(&RCC_PeriphClkInit); /* Configure the SDMMC1 clock source. The clock is derived from the PLLSAI1 */ /* Hypothesis is that PLLSAI1 VCO input is 8Mhz */ RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC1; RCC_PeriphClkInit.PLLSAI1.PLLSAI1N = 24; RCC_PeriphClkInit.PLLSAI1.PLLSAI1Q = 4; RCC_PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK; RCC_PeriphClkInit.Sdmmc1ClockSelection = RCC_SDMMC1CLKSOURCE_PLLSAI1; if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) { while (1) {} } /* Enable SDMMC1 clock */ __HAL_RCC_SDMMC1_CLK_ENABLE(); /* Enable DMA2 clocks */ SD_DMAx_CLK_ENABLE(); /* Enable GPIOs clock */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /* Common GPIO configuration */ gpioinitstruct.Mode = GPIO_MODE_AF_PP; gpioinitstruct.Pull = GPIO_PULLUP; gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; gpioinitstruct.Alternate = GPIO_AF12_SDMMC1; /* GPIOC configuration */ gpioinitstruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; HAL_GPIO_Init(GPIOC, &gpioinitstruct); /* GPIOD configuration */ gpioinitstruct.Pin = GPIO_PIN_2; HAL_GPIO_Init(GPIOD, &gpioinitstruct); /* NVIC configuration for SDMMC1 interrupts */ HAL_NVIC_SetPriority(SDMMCx_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SDMMCx_IRQn); /* DMA initialization should be done here but , as there is only one channel for RX and TX it is configured and done directly when required*/ }
/** * @brief Configures the SAI PLL clock according to the required audio frequency. * @param Frequency: Audio frequency. * @retval BSP AUDIO status * @note The SAI PLL input clock must be configured in the user application. * The SAI PLL configuration done within this function assumes that * the SAI PLL input clock runs at 8 MHz. */ static uint8_t AUDIO_SAIPLLConfig(uint32_t Frequency) { RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct; /* Retreive actual RCC configuration */ HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct); if ( (Frequency == AUDIO_FREQUENCY_11K) || (Frequency == AUDIO_FREQUENCY_22K) || (Frequency == AUDIO_FREQUENCY_44K) ) { /* Configure PLLSAI prescalers */ /* SAI clock config PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 24 = VCO_192M SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 192/17 = 11.294 Mhz */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 24; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 17; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK; RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; } else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K, AUDIO_FREQUENCY_96K */ { /* SAI clock config PLLSAI1_VCO= 8 Mhz * PLLSAI1N = 8 * 43 = VCO_344M SAI_CK_x = PLLSAI1_VCO/PLLSAI1P = 344/7 = 49.142 Mhz */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 43; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = 7; RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK; RCC_ExCLKInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1; } if (HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct) != HAL_OK) { return AUDIO_ERROR; } return AUDIO_OK; }
/** * @brief Clock Config. * @param hsai: might be required to set audio peripheral predivider if any. * @param AudioFreq: Audio frequency used to play the audio stream. * @note This API is called by BSP_AUDIO_OUT_Init() and BSP_AUDIO_OUT_SetFrequency() * Being __weak it can be overwritten by the application * @retval None */ void BSP_AUDIO_OUT_ClockConfig(SAI_HandleTypeDef *hsai, uint32_t AudioFreq, void *Params) { RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct; HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct); /* Set the PLL configuration according to the audio frequency */ if((AudioFreq == AUDIO_FREQUENCY_11K) || (AudioFreq == AUDIO_FREQUENCY_22K) || (AudioFreq == AUDIO_FREQUENCY_44K)) { /* 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_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2; RCC_ExCLKInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SM = 8; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = 429; RCC_ExCLKInitStruct.PLLI2S.PLLI2SQ = 2; RCC_ExCLKInitStruct.PLLI2SDivQ = 19; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } else /* AUDIO_FREQUENCY_8K, AUDIO_FREQUENCY_16K, AUDIO_FREQUENCY_48K), AUDIO_FREQUENCY_96K */ { /* SAI clock config PLLSAI_VCO: VCO_344M SAI_CLK(first level) = PLLSAI_VCO/PLLSAIQ = 344/7 = 49.142 Mhz SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ = 49.142/1 = 49.142 Mhz */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2; RCC_ExCLKInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLI2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SM = 8; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = 344; RCC_ExCLKInitStruct.PLLI2S.PLLI2SQ = 7; RCC_ExCLKInitStruct.PLLI2SDivQ = 1; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } }
static void clock_init() { RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_OscInitTypeDef RCC_OscInitStruct; //HAL_InitTick(0); __PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 8; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1 |RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); /* configure I2S clock for 48kHz audio frequency */ RCC_PeriphCLKInitTypeDef rccclkinit; HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 192; rccclkinit.PLLI2S.PLLI2SR = 4; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); HAL_InitTick(0); }
/** * @brief Initializes wave recording. * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. * @param BitRes: Audio frequency to be configured for the I2S peripheral. * @param ChnlNbr: Audio frequency to be configured for the I2S peripheral. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_IN_Init(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr) { RCC_PeriphCLKInitTypeDef rccclkinit; /* Enable PLLI2S clock */ HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ if ((AudioFreq & 0x7) == 0) { /* Audio frequency multiple of 8 (8/16/32/48/96/192)*/ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 192 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 192/6 = 32 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 192; rccclkinit.PLLI2S.PLLI2SR = 6; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } else { /* Other Frequency (11.025/22.500/44.100) */ /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN = 290 Mhz */ /* I2SCLK = PLLI2S_VCO Output/PLLI2SR = 290/2 = 145 Mhz */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 290; rccclkinit.PLLI2S.PLLI2SR = 2; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } /* Configure the PDM library */ PDMDecoder_Init(AudioFreq, ChnlNbr); /* Configure the I2S2 */ I2S2_Init(AudioFreq); /* Return AUDIO_OK when all operations are correctly done */ return AUDIO_OK; }
/** * @brief Updates the audio frequency. * @param AudioFreq: Audio frequency used to play the audio stream. * @retval AUDIO_OK if correct communication, else wrong communication */ void BSP_AUDIO_OUT_SetFrequency(uint32_t AudioFreq) { RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct; uint8_t index = 0, freqindex = 0xFF; for(index = 0; index < 8; index++) { if(I2SFreq[index] == AudioFreq) { freqindex = index; } } HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct); if(freqindex != 0xFF) { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = I2SPLLN[freqindex]; RCC_ExCLKInitStruct.PLLI2S.PLLI2SR = I2SPLLR[freqindex]; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } else /* Default PLL I2S configuration */ { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = 258; RCC_ExCLKInitStruct.PLLI2S.PLLI2SR = 3; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } /* Update the I2S audio frequency configuration */ I2Sx_Init(AudioFreq); }
/** * @brief Configures the audio peripherals. * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to play the audio stream. * @retval AUDIO_OK if correct communication, else wrong communication */ uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint8_t ret = AUDIO_ERROR; uint32_t deviceid = 0x00; RCC_PeriphCLKInitTypeDef rccclkinit; uint8_t index = 0, freqindex = 0xFF; for(index = 0; index < 8; index++) { if(I2SFreq[index] == AudioFreq) { freqindex = index; } } /* Enable PLLI2S clock */ HAL_RCCEx_GetPeriphCLKConfig(&rccclkinit); /* PLLI2S_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */ if ((freqindex & 0x7) == 0) { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = I2SPLLN[freqindex]; rccclkinit.PLLI2S.PLLI2SR = I2SPLLR[freqindex]; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } else { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ rccclkinit.PeriphClockSelection = RCC_PERIPHCLK_I2S; rccclkinit.PLLI2S.PLLI2SN = 258; rccclkinit.PLLI2S.PLLI2SR = 3; HAL_RCCEx_PeriphCLKConfig(&rccclkinit); } deviceid = cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS); if((deviceid & CS43L22_ID_MASK) == CS43L22_ID) { /* Initialize the audio driver structure */ pAudioDrv = &cs43l22_drv; ret = AUDIO_OK; } else { ret = AUDIO_ERROR; } if(ret == AUDIO_OK) { pAudioDrv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq); /* I2S data transfer preparation: Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ /* Configure the I2S peripheral */ I2S3_Init(AudioFreq); } return ret; }
/** * @brief Configures the audio peripherals. * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) * @param AudioFreq: Audio frequency used to play the audio stream. * @note This function configure also that the I2S PLL input clock. * @retval 0 if correct communication, else wrong communication */ uint8_t BSP_AUDIO_OUT_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) { uint8_t ret = AUDIO_ERROR; uint32_t deviceid = 0x00; RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct; uint8_t index = 0, freqindex = 0xFF; for(index = 0; index < 8; index++) { if(I2SFreq[index] == AudioFreq) { freqindex = index; } } HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct); if(freqindex != 0xFF) { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = I2SPLLN[freqindex]; RCC_ExCLKInitStruct.PLLI2S.PLLI2SR = I2SPLLR[freqindex]; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } else /* Default PLL I2S configuration */ { /* I2S clock config PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S; RCC_ExCLKInitStruct.PLLI2S.PLLI2SN = 258; RCC_ExCLKInitStruct.PLLI2S.PLLI2SR = 3; HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct); } /* Reset the Codec Registers */ CODEC_Reset(); deviceid = cs43l22_drv.ReadID(AUDIO_I2C_ADDRESS); if((deviceid & CS43L22_ID_MASK) == CS43L22_ID) { /* Initialize the audio driver structure */ audio_drv = &cs43l22_drv; ret = AUDIO_OK; } else { ret = AUDIO_ERROR; } if(ret == AUDIO_OK) { audio_drv->Init(AUDIO_I2C_ADDRESS, OutputDevice, Volume, AudioFreq); /* I2S data transfer preparation: Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ /* Configure the I2S peripheral */ I2Sx_Init(AudioFreq); } return ret; }