Skip to main content
N4l3p
Associate
May 17, 2021
Question

How to correctly configure the output clock of DFSDM (Source: Audio Clock) for STM32H743?

  • May 17, 2021
  • 2 replies
  • 2999 views

Hello everyone,

I think that I am missing some parameter in my calculation. I want to feed the clock to a microphone and I want the output clock to have a frequency of 48kHz x 64 = 3.072MHz. The 48kHz is the audio sampling freq and 64 is the decimation factor on the filter side. But I keep getting wrong frequency when I measure it with oscilloscope.

Btw, I am using Nucleo-144 STM32H743

I know the formula look like this (But somehow this is not true):

Decimation factor x Audio sampling freq = DFSDM clock source / Divider

And below are the details:

  • DFSDM Clock source: Audio Clock
  • Decimation factor: 64
  • Audio Sampling freq: 48 kHz
  • DFSDM Clock Source: 49.152 MHz
  • Divider: 16

Output Clock that I want (DFSDM1_CKOUT): 3.072 MHz

Output Clock that I got (DFSDM1_CKOUT): 978 kHz

What am I missing here? And is the formula correct? I also include screenshot from MXCube.

Hope someone can help me. Thanks in advance.

Here are my codes:

//SystemClock----------------------------------------------------------------------------------------------------
void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
 /** Supply configuration update enable
 */
 HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
 /** Configure the main internal regulator output voltage
 */
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
 
 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
 /** Macro to configure the PLL clock source
 */
 __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE);
 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_ON;
 RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 2;
 RCC_OscInitStruct.PLL.PLLN = 30;
 RCC_OscInitStruct.PLL.PLLP = 20;
 RCC_OscInitStruct.PLL.PLLQ = 13;
 RCC_OscInitStruct.PLL.PLLR = 2;
 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;
 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
 RCC_OscInitStruct.PLL.PLLFRACN = 0;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
 RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV16;
 RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
 
 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 Error_Handler();
 }
}
 
//MX_DFSDM1_Init----------------------------------------------------------------------------------------------------
static void MX_DFSDM1_Init(void)
{
 
 /* USER CODE BEGIN DFSDM1_Init 0 */
 
 /* USER CODE END DFSDM1_Init 0 */
 
 /* USER CODE BEGIN DFSDM1_Init 1 */
 
 /* USER CODE END DFSDM1_Init 1 */
 hdfsdm1_filter0.Instance = DFSDM1_Filter0;
 hdfsdm1_filter0.Init.RegularParam.Trigger = DFSDM_FILTER_SW_TRIGGER;
 hdfsdm1_filter0.Init.RegularParam.FastMode = ENABLE;
 hdfsdm1_filter0.Init.RegularParam.DmaMode = ENABLE;
 hdfsdm1_filter0.Init.FilterParam.SincOrder = DFSDM_FILTER_FASTSINC_ORDER;
 hdfsdm1_filter0.Init.FilterParam.Oversampling = 64;
 hdfsdm1_filter0.Init.FilterParam.IntOversampling = 1;
 if (HAL_DFSDM_FilterInit(&hdfsdm1_filter0) != HAL_OK)
 {
 Error_Handler();
 }
 hdfsdm1_channel0.Instance = DFSDM1_Channel0;
 hdfsdm1_channel0.Init.OutputClock.Activation = ENABLE;
 hdfsdm1_channel0.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
 hdfsdm1_channel0.Init.OutputClock.Divider = 16;
 hdfsdm1_channel0.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
 hdfsdm1_channel0.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
 hdfsdm1_channel0.Init.Input.Pins = DFSDM_CHANNEL_FOLLOWING_CHANNEL_PINS;
 hdfsdm1_channel0.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
 hdfsdm1_channel0.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
 hdfsdm1_channel0.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
 hdfsdm1_channel0.Init.Awd.Oversampling = 1;
 hdfsdm1_channel0.Init.Offset = 0;
 hdfsdm1_channel0.Init.RightBitShift = 0x00;
 if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel0) != HAL_OK)
 {
 Error_Handler();
 }
 hdfsdm1_channel1.Instance = DFSDM1_Channel1;
 hdfsdm1_channel1.Init.OutputClock.Activation = ENABLE;
 hdfsdm1_channel1.Init.OutputClock.Selection = DFSDM_CHANNEL_OUTPUT_CLOCK_AUDIO;
 hdfsdm1_channel1.Init.OutputClock.Divider = 16;
 hdfsdm1_channel1.Init.Input.Multiplexer = DFSDM_CHANNEL_EXTERNAL_INPUTS;
 hdfsdm1_channel1.Init.Input.DataPacking = DFSDM_CHANNEL_STANDARD_MODE;
 hdfsdm1_channel1.Init.Input.Pins = DFSDM_CHANNEL_SAME_CHANNEL_PINS;
 hdfsdm1_channel1.Init.SerialInterface.Type = DFSDM_CHANNEL_SPI_RISING;
 hdfsdm1_channel1.Init.SerialInterface.SpiClock = DFSDM_CHANNEL_SPI_CLOCK_INTERNAL;
 hdfsdm1_channel1.Init.Awd.FilterOrder = DFSDM_CHANNEL_FASTSINC_ORDER;
 hdfsdm1_channel1.Init.Awd.Oversampling = 1;
 hdfsdm1_channel1.Init.Offset = 0;
 hdfsdm1_channel1.Init.RightBitShift = 10;
 if (HAL_DFSDM_ChannelInit(&hdfsdm1_channel1) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_DFSDM_FilterConfigRegChannel(&hdfsdm1_filter0, DFSDM_CHANNEL_1, DFSDM_CONTINUOUS_CONV_ON) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DFSDM1_Init 2 */
 
 /* USER CODE END DFSDM1_Init 2 */
 
}
 
//HAL_DFSDM_FilterMspInit-----------------------------------------------------------------------------
void HAL_DFSDM_FilterMspInit(DFSDM_Filter_HandleTypeDef* hdfsdm_filter)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 if(DFSDM1_Init == 0)
 {
 /* USER CODE BEGIN DFSDM1_MspInit 0 */
 
 /* USER CODE END DFSDM1_MspInit 0 */
 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_DFSDM1;
 PeriphClkInitStruct.PLL2.PLL2M = 25;
 PeriphClkInitStruct.PLL2.PLL2N = 344;
 PeriphClkInitStruct.PLL2.PLL2P = 7;
 PeriphClkInitStruct.PLL2.PLL2Q = 2;
 PeriphClkInitStruct.PLL2.PLL2R = 2;
 PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
 PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
 PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
 PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
 PeriphClkInitStruct.Dfsdm1ClockSelection = RCC_DFSDM1CLKSOURCE_SYS;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 ...
}
 
//HAL_DFSDM_ChannelMspInit--------------------------------------------------------------------------------
void HAL_DFSDM_ChannelMspInit(DFSDM_Channel_HandleTypeDef* hdfsdm_channel)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 if(DFSDM1_Init == 0)
 {
 /* USER CODE BEGIN DFSDM1_MspInit 0 */
 
 /* USER CODE END DFSDM1_MspInit 0 */
 /** Initializes the peripherals clock
 */
 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_DFSDM1;
 PeriphClkInitStruct.PLL2.PLL2M = 25;
 PeriphClkInitStruct.PLL2.PLL2N = 344;
 PeriphClkInitStruct.PLL2.PLL2P = 7;
 PeriphClkInitStruct.PLL2.PLL2Q = 2;
 PeriphClkInitStruct.PLL2.PLL2R = 2;
 PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
 PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
 PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
 PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLL2;
 PeriphClkInitStruct.Dfsdm1ClockSelection = RCC_DFSDM1CLKSOURCE_SYS;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
 {
 Error_Handler();
 }
 ...
}

This topic has been closed for replies.

2 replies

Gabriel Melo
Associate II
May 17, 2021

Hey, so, first, some reference :

From the second link the formula (just for the PDM mic) is : Fs = decimation * PDM_clock

What I would try is changing the source from audio clock to system clock, because audio clock actually refers to another peripheral (independent from DFDSM - first link)

Technical Moderator
May 17, 2021

Hello @Community member​ and welcome to the STM32 Community,

Have a look at this section: "DFSDM peripheral configuration tutorial", in the DFSDM application note: AN4990 "Getting started with sigma-delta digital interface on applicable STM32 microcontrollers". This will help you on the DFSDM configuration.

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks