40 #include "stm32l4xx_hal.h" 76 #define SAIClockDivider(__FREQUENCY__) \ 77 ((__FREQUENCY__ == AUDIO_FREQUENCY_8K) ? 12 \ 78 : (__FREQUENCY__ == AUDIO_FREQUENCY_11K) ? 2 \ 79 : (__FREQUENCY__ == AUDIO_FREQUENCY_16K) ? 6 \ 80 : (__FREQUENCY__ == AUDIO_FREQUENCY_22K) ? 1 \ 81 : (__FREQUENCY__ == AUDIO_FREQUENCY_32K) ? 3 \ 82 : (__FREQUENCY__ == AUDIO_FREQUENCY_44K) ? 0 \ 83 : (__FREQUENCY__ == AUDIO_FREQUENCY_48K) ? 2 : 1) 93 static DrvContextTypeDef CODEC_Handle[CODEC_SENSORS_MAX_NUM ];
96 SAI_HandleTypeDef haudio_out_sai;
98 static void SAIx_Init(uint32_t AudioFreq);
109 static DrvStatusTypeDef BSP_PCM1774_CODEC_Init(
void **handle, uint8_t Volume, uint32_t AudioFreq);
129 uint8_t
BSP_AUDIO_OUT_Init(CODEX_ID_t
id,
void **handle, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
131 if (AudioFreq != AUDIO_FREQUENCY_8K && AudioFreq != AUDIO_FREQUENCY_16K && AudioFreq && AudioFreq != AUDIO_FREQUENCY_32K && AudioFreq != AUDIO_FREQUENCY_48K)
132 return COMPONENT_ERROR;
140 case CODEX_SENSORS_AUTO:
144 if(BSP_PCM1774_CODEC_Init(handle, Volume, AudioFreq) == COMPONENT_ERROR )
146 return COMPONENT_ERROR;
152 if( BSP_PCM1774_CODEC_Init(handle, Volume, AudioFreq) == COMPONENT_ERROR )
154 return COMPONENT_ERROR;
167 static DrvStatusTypeDef BSP_PCM1774_CODEC_Init(
void **handle, uint8_t Volume, uint32_t AudioFreq)
169 AUDIO_DrvTypeDef *driver = NULL;
171 if(CODEC_Handle[PCM1774_0].isInitialized == 1)
174 return COMPONENT_ERROR;
179 return COMPONENT_ERROR;
183 CODEC_Handle[PCM1774_0].who_am_i = 0;
184 CODEC_Handle[PCM1774_0].ifType = 0;
185 CODEC_Handle[PCM1774_0].address = PCM1774_CODEC_I2C_ADDRESS_LOW;
186 CODEC_Handle[PCM1774_0].instance = PCM1774_0;
187 CODEC_Handle[PCM1774_0].isInitialized = 0;
188 CODEC_Handle[PCM1774_0].isEnabled = 0;
189 CODEC_Handle[PCM1774_0].isCombo = 1;
190 CODEC_Handle[PCM1774_0].pData = (
void * )NULL;
191 CODEC_Handle[PCM1774_0].pVTable = (
void * )&PCM1774_drv;
192 CODEC_Handle[PCM1774_0].pExtVTable = 0;
194 *handle = (
void *)&CODEC_Handle[PCM1774_0];
196 driver = ( AUDIO_DrvTypeDef * )((DrvContextTypeDef *)(*handle))->pVTable;
198 if ( driver->Init == NULL )
200 memset((*handle), 0,
sizeof(DrvContextTypeDef));
202 return COMPONENT_ERROR;
205 if (driver->Init( (DrvContextTypeDef *)(*handle), Volume, AudioFreq ) == COMPONENT_ERROR )
207 memset((*handle), 0,
sizeof(DrvContextTypeDef));
209 return COMPONENT_ERROR;
224 if ( HAL_SAI_Transmit_DMA(&haudio_out_sai, (uint8_t *)pBuffer, DMA_MAX(Size))!= HAL_OK)
244 if (HAL_SAI_DMAPause(&haudio_out_sai)!= HAL_OK)
264 if (HAL_SAI_DMAResume(&haudio_out_sai)!= HAL_OK)
282 DrvContextTypeDef *ctx = (DrvContextTypeDef *)handle;
283 AUDIO_DrvTypeDef *driver = NULL;
287 return COMPONENT_ERROR;
290 driver = ( AUDIO_DrvTypeDef *)ctx->pVTable;
292 if ( driver->Stop == NULL )
294 return COMPONENT_ERROR;
297 if ( driver->Stop(ctx, Option ) == COMPONENT_ERROR )
299 return COMPONENT_ERROR;
303 if (HAL_SAI_DMAStop(&haudio_out_sai)!= HAL_OK)
305 return COMPONENT_ERROR;
319 DrvContextTypeDef *ctx = (DrvContextTypeDef *)handle;
320 AUDIO_DrvTypeDef *driver = NULL;
324 return COMPONENT_ERROR;
327 driver = ( AUDIO_DrvTypeDef *)ctx->pVTable;
329 if ( driver->SetVolume == NULL )
331 return COMPONENT_ERROR;
334 if ( driver->SetVolume(ctx, Volume ) == COMPONENT_ERROR )
336 return COMPONENT_ERROR;
350 DrvContextTypeDef *ctx = (DrvContextTypeDef *)handle;
351 AUDIO_DrvTypeDef *driver = NULL;
355 return COMPONENT_ERROR;
358 driver = ( AUDIO_DrvTypeDef *)ctx->pVTable;
360 if ( driver->SetMute == NULL )
362 return COMPONENT_ERROR;
365 if ( driver->SetMute(ctx, Cmd ) == COMPONENT_ERROR )
367 return COMPONENT_ERROR;
384 RCC_PeriphCLKInitTypeDef RCC_ExCLKInitStruct;
385 HAL_RCCEx_GetPeriphCLKConfig(&RCC_ExCLKInitStruct);
390 RCC_ExCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI2;
391 RCC_ExCLKInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI1;
392 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1N = 43;
393 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
394 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
395 RCC_ExCLKInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1CFGR_PLLSAI1PEN;
396 HAL_RCCEx_PeriphCLKConfig(&RCC_ExCLKInitStruct);
412 __HAL_SAI_DISABLE(&haudio_out_sai);
415 haudio_out_sai.Init.Mckdiv = SAIClockDivider(AudioFreq);
416 HAL_SAI_Init(&haudio_out_sai);
419 __HAL_SAI_ENABLE(&haudio_out_sai);
493 static DMA_HandleTypeDef hdma_saiTx;
494 GPIO_InitTypeDef GPIO_InitStruct;
495 SAI_HandleTypeDef *hsai = &haudio_out_sai;
498 AUDIO_SAIx_CLK_ENABLE();
501 AUDIO_SAIx_MCKB_SCKB_SDB_FSB_ENABLE();
504 HAL_PWREx_EnableVddIO2();
507 GPIO_InitStruct.Pin = AUDIO_SAIx_FSB_PIN | AUDIO_SAIx_SCKB_PIN | AUDIO_SAIx_SDB_PIN | AUDIO_SAIx_MCKB_PIN;
508 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
509 GPIO_InitStruct.Pull = GPIO_NOPULL;
510 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
511 GPIO_InitStruct.Alternate = AUDIO_SAIx_MCKB_SCKB_SDB_FSB_AF;
512 HAL_GPIO_Init(AUDIO_SAIx_MCKB_SCKB_SDB_FSB_GPIO_PORT, &GPIO_InitStruct);
515 AUDIO_SAIx_DMAx_CLK_ENABLE();
517 if(hsai->Instance == AUDIO_SAIx)
520 hdma_saiTx.Init.Request = DMA_REQUEST_1;
521 hdma_saiTx.Init.Direction = DMA_MEMORY_TO_PERIPH;
522 hdma_saiTx.Init.PeriphInc = DMA_PINC_DISABLE;
523 hdma_saiTx.Init.MemInc = DMA_MINC_ENABLE;
524 hdma_saiTx.Init.PeriphDataAlignment = AUDIO_SAIx_DMAx_PERIPH_DATA_SIZE;
525 hdma_saiTx.Init.MemDataAlignment = AUDIO_SAIx_DMAx_MEM_DATA_SIZE;
526 hdma_saiTx.Init.Mode = DMA_CIRCULAR;
527 hdma_saiTx.Init.Priority = DMA_PRIORITY_HIGH;
529 hdma_saiTx.Instance = AUDIO_SAIx_DMAx_CHANNEL;
532 __HAL_LINKDMA(hsai, hdmatx, hdma_saiTx);
535 HAL_DMA_DeInit(&hdma_saiTx);
538 HAL_DMA_Init(&hdma_saiTx);
542 HAL_NVIC_SetPriority(AUDIO_SAIx_DMAx_IRQ, AUDIO_OUT_IRQ_PREPRIO, 0);
543 HAL_NVIC_EnableIRQ(AUDIO_SAIx_DMAx_IRQ);
556 haudio_out_sai.Instance = AUDIO_SAIx;
559 __HAL_SAI_DISABLE(&haudio_out_sai);
564 haudio_out_sai.Init.MonoStereoMode = SAI_STEREOMODE;
565 haudio_out_sai.Init.Mckdiv = SAIClockDivider(AudioFreq);
566 haudio_out_sai.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_MCKDIV;
567 haudio_out_sai.Init.AudioMode = SAI_MODEMASTER_TX;
568 haudio_out_sai.Init.NoDivider = SAI_MASTERDIVIDER_ENABLE;
569 haudio_out_sai.Init.Protocol = SAI_FREE_PROTOCOL;
570 haudio_out_sai.Init.DataSize = SAI_DATASIZE_16;
571 haudio_out_sai.Init.FirstBit = SAI_FIRSTBIT_MSB;
572 haudio_out_sai.Init.ClockStrobing = SAI_CLOCKSTROBING_RISINGEDGE;
573 haudio_out_sai.Init.Synchro = SAI_ASYNCHRONOUS;
574 haudio_out_sai.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
575 haudio_out_sai.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_1QF;
583 haudio_out_sai.FrameInit.FrameLength = 32;
584 haudio_out_sai.FrameInit.ActiveFrameLength = 16;
585 haudio_out_sai.FrameInit.FSDefinition = SAI_FS_CHANNEL_IDENTIFICATION;
586 haudio_out_sai.FrameInit.FSPolarity = SAI_FS_ACTIVE_LOW;
587 haudio_out_sai.FrameInit.FSOffset = SAI_FS_BEFOREFIRSTBIT;
594 haudio_out_sai.SlotInit.FirstBitOffset = 0;
595 haudio_out_sai.SlotInit.SlotSize = SAI_SLOTSIZE_16B;
596 haudio_out_sai.SlotInit.SlotNumber = 2;
597 haudio_out_sai.SlotInit.SlotActive = SAI_SLOTACTIVE_0 | SAI_SLOTACTIVE_1;
602 HAL_SAI_Init(&haudio_out_sai);
605 __HAL_SAI_ENABLE(&haudio_out_sai);
uint8_t BSP_AUDIO_OUT_SetVolume(void *handle, uint8_t Volume)
Controls the current audio volume level.
uint8_t BSP_AUDIO_OUT_Pause(void *handle)
This function Pauses the audio file stream. In case of using DMA, the DMA Pause feature is used...
uint8_t BSP_AUDIO_OUT_SetFrequency(void *handle, uint32_t AudioFreq)
Update the audio frequency.
__weak uint8_t BSP_AUDIO_OUT_ClockConfig(uint32_t AudioFreq, void *Params)
Clock Config.
void HAL_SAI_ErrorCallback(SAI_HandleTypeDef *hsai)
SAI error callbacks.
uint8_t BSP_AUDIO_OUT_Init(CODEX_ID_t id, void **handle, uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq)
Configures the audio peripherals.
This file contains definitions for SensorTile_audio_out.c driver.
__weak void BSP_AUDIO_OUT_HalfTransfer_CallBack(void)
Manages the DMA Half Transfer complete event.
uint8_t BSP_AUDIO_OUT_SetMute(void *handle, uint32_t Cmd)
Enables or disables the MUTE mode by software.
void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
Tx Half Transfer completed callbacks.
static void SAIx_MspInit(void)
Initializes SAI MSP.
DrvStatusTypeDef Sensor_IO_I2C_Init(void)
Configures sensor SPI interface.
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
Tx Transfer completed callbacks.
uint8_t BSP_AUDIO_OUT_Stop(void *handle, uint32_t Option)
Stops audio playing and Power down the Audio Codec.
__weak void BSP_AUDIO_OUT_Error_CallBack(void)
Manages the DMA FIFO error event.
uint8_t BSP_AUDIO_OUT_Resume(void *handle)
This function Resumes the audio file stream.
static void SAIx_Init(uint32_t AudioFreq)
Initializes the Audio Codec audio interface (SAI).
uint8_t BSP_AUDIO_OUT_Play(void *handle, uint16_t *pBuffer, uint32_t Size)
Starts playing audio stream from a data buffer for a determined size.
__weak void BSP_AUDIO_OUT_TransferComplete_CallBack(void)
Manages the DMA full Transfer complete event.