cancel
Showing results for 
Search instead for 
Did you mean: 

Understanding I2S and SAI clock configuration

Posted on March 13, 2017 at 14:15

Hi.

So I've got STM32F469I-Discovery board. I've connected MEMS microphone to I2S input that outputs 16khz and 16bit (in 32bit frame) stereo PCM output. I'm using the SAI1 via BSP_AUDIO interface (defined in stm32469i_discovery_audio.c) to output data to audio codec like in audio record and playback example. Only difference is the data rate of the source.

Anyho I'm totally baffled with the clock configuration. I've read the reference manual SAI part and what ever I've managed to google about the STM SAI/I2S clock generation. Also I've tried to setup them via CubeMX. However none of the configurations seem to work properly, but I managed to iterate the clock in ballpark just by changing the PLLSAI.PLLSAIN by hand. However I really don't understand how should I really calculate the clocks properly. Is there any documentation that would clear this?

Input I2S: 16bit stereo in 32bit frame @ 16khz (1.029Mhz clock checked with scope)

About working config:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.HSIState = RCC_HSI_ON;

RCC_OscInitStruct.HSICalibrationValue = 16;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 15;

RCC_OscInitStruct.PLL.PLLN = 144;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;

RCC_OscInitStruct.PLL.PLLQ = 5;

RCC_OscInitStruct.PLL.PLLR = 2;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

/**Initializes the CPU, AHB and APB busses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

{

Error_Handler();

}

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S|RCC_PERIPHCLK_SAI_PLLSAI

|RCC_PERIPHCLK_SDIO|RCC_PERIPHCLK_CLK48;

PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;

PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;

// PeriphClkInitStruct.PLLSAI.PLLSAIN = 116;

// PeriphClkInitStruct.PLLSAI.PLLSAIN = 213;

PeriphClkInitStruct.PLLSAI.PLLSAIN = 240;

PeriphClkInitStruct.PLLSAI.PLLSAIQ = 2;

PeriphClkInitStruct.PLLSAIDivQ = 1;

PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ;

PeriphClkInitStruct.SdioClockSelection = RCC_SDIOCLKSOURCE_CLK48;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

The 240 SAIn isn't even close to one suggested by cubemx. Can anyone open this up at all?

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on May 17, 2017 at 12:44

This came bite me again and now the clocks make more sense.

In both cube and in library the HSE clock is 25Mhz. However when measured from board (or checked from the schematics), it's 8Mhz. Also the discovery_audio doesn't handle the slot configuration or mckdiv properly in case of 16k mono.

View solution in original post

2 REPLIES 2
Posted on March 14, 2017 at 15:02

Regarding stm32469i_discovery_audio.c. There's a bug in the BSP_AUDIO_OUT_Play. The codec is potentially been given different amount of data than DMA.

if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, Size) != 0)

and it should be:

if(audio_drv->Play(AUDIO_I2C_ADDRESS, pBuffer, DMA_MAX(Size / AUDIODATA_SIZE)) != 0)

Posted on May 17, 2017 at 12:44

This came bite me again and now the clocks make more sense.

In both cube and in library the HSE clock is 25Mhz. However when measured from board (or checked from the schematics), it's 8Mhz. Also the discovery_audio doesn't handle the slot configuration or mckdiv properly in case of 16k mono.