cancel
Showing results for 
Search instead for 
Did you mean: 

DFSDM change clock divider at runtime

WolframG
Associate II

Hello,

I am trying to change the clock divider of my DFSDM channel at runtime. What I try to achieve with this is starting my microphone in standard mode and then increasing the clock rate to go into performance mode. This procedure is recommended by the manufacturer.

The auto generated code to initialize the DFSDM first initializes the filters, then the channels, while setting all the parameters I defined in CubeIDE. Based on that I was trying to:

  1. Deinit the filter and channel.
  2. Change the clock divider
  3. Re-Init the filter and channel with the new settings.

My issue is that within the Msp methods HAL_DFSDM_FilterMspDeInit and HAL_DFSDM_ChannelMspDeInit some flags are used. When I deinitialize channel and filter the flag for DFSDM1_Init "underflows" and jumps to max value since its unsigned. Since all of the Msp init methods check for if(DFSDM1_Init == 0) they wont execute anymore afterwards. Therefore I am left without a clock. Is there a specific order?

I also tried setting the clock divider directly using:

__HAL_RCC_DFSDM1_CLK_DISABLE();
hdfsdm1_channel2.Init.OutputClock.Divider = 20;
hdfsdm1_channel2.Instance->CHCFGR1 |= (uint32_t)((hdfsdm1_channel2.Init.OutputClock.Divider - 1U) <<
DFSDM_CHCFGR1_CKOUTDIV_Pos);
__HAL_RCC_DFSDM1_CLK_ENABLE();

This deactivated my clock, changed the divider and re-enabled the clock. However, the clock I measured with the oscilloscope stayed unchanged. So the divider is not applied. What am I missing?

Any help in this is greatly appreciated.
Kind regards
Wolf

1 ACCEPTED SOLUTION

Accepted Solutions

from rm :

AScha3_0-1716201922863.png

So set ..try:

hdfsdm1_channel2.Instance->CHCFGR1 &= 0x7FFFFFFF ;  // dfs off
hdfsdm1_channel2.Instance->CHCFGR1 = (hdfsdm1_channel2.Instance->CHCFGR1 & 0xFF00FFFF)|0x00130000 ;
hdfsdm1_channel2.Instance->CHCFGR1 |= 0x80000000 ;  // dfs on
If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
AScha.3
Chief

Hi,

i didnt much with DFSDM1 ....

 

You OR your new value (20) to the old (is ? bigger ?) , so maybe still the bigger value stays there.

+

but did you try just to write your new clock setting to CHCFGR1 ?

about like this:

 

 

hdfsdm1_channel2.Instance->CHCFGR1 = (hdfsdm1_channel2.Instance->CHCFGR1 & 0xFF00FFFF)|0x00130000 ;

 

 

 

 

 

If you feel a post has answered your question, please click "Accept as Solution".

Thank you for your input.
I have tried your suggested way in setting the register. However, the clock remains unchanged.
Is there some way I need to restart it using the new values or are they constantly read from the register?

from rm :

AScha3_0-1716201922863.png

So set ..try:

hdfsdm1_channel2.Instance->CHCFGR1 &= 0x7FFFFFFF ;  // dfs off
hdfsdm1_channel2.Instance->CHCFGR1 = (hdfsdm1_channel2.Instance->CHCFGR1 & 0xFF00FFFF)|0x00130000 ;
hdfsdm1_channel2.Instance->CHCFGR1 |= 0x80000000 ;  // dfs on
If you feel a post has answered your question, please click "Accept as Solution".

This works! Thanks for the pointer to the documentation.
I realized that the CKOUTDIV is present only in the register of channel 0. I always tried setting it in the register of channel 2.
After changing it it works. Thank you so much! Much appreciated.

Hi, i'm currently struggling to de-init, reset, change configuration and re-init the DFSDM Peripheral. The DMA doesn't start to fill the array again.

Could you provide your working Code? That would help me a lot.

These are the 3 lines of code I have to disable, change clock divider, and re-enable the DFSDM.

// Set DFSDMEN = 0
hdfsdm1_channel0.Instance->CHCFGR1 &= 0x7FFFFFFF;
// Change clock divider CKOUTDIV. If target is 20, set to 20 - 1 = 19 as Hex, so 13 here:  ⤵⤵
hdfsdm1_channel0.Instance->CHCFGR1 = (hdfsdm1_channel0.Instance->CHCFGR1 & 0xFF00FFFF)|0x00130000;
// Set DFSDMEN = 1
hdfsdm1_channel0.Instance->CHCFGR1 |= 0x80000000;