cancel
Showing results for 
Search instead for 
Did you mean: 

Need help setting up and enabling Spread Spectrum Clock on STM32F405

Cristea.Catalin
Associate III
Posted on August 14, 2017 at 23:13

I need help setting up and enabling (and disabling) the  Spread Spectrum Clock on STM32F405.

AN4850 is not enough, as it has no code example; says nothing about what to do with MODPER and INCSTEP once calculated.

I see file 'stm32f4xx.h' defines some related types/constants but I don't see anything anywhere on how to do it.

Thanks,

Cat
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on August 15, 2017 at 02:58

Add the Spread Spectrum enabling code into system_stm32f4xx.c where you currently enable the PLL

ie

...

/* Select regulator voltage output Scale 1 mode */

RCC->APB1ENR |= RCC_APB1ENR_PWREN;

PWR->CR |= PWR_CR_VOS;

/* HCLK = SYSCLK / 1*/

RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK / 2*/

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

/* PCLK1 = HCLK / 4*/

RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

/* Configure the main PLL */

RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

/* Enable/Configure Spread Spectrum, when PLL isn't running */

RCC->SSCGR = (1 << 31) | // Enable

(0 << 30) | // Center

(INCSTEP << 13) |

(MODPER << 0);

/* Enable the main PLL */

RCC->CR |= RCC_CR_PLLON;

/* Wait till the main PLL is ready */

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}

...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

6 REPLIES 6
Posted on August 15, 2017 at 02:58

Add the Spread Spectrum enabling code into system_stm32f4xx.c where you currently enable the PLL

ie

...

/* Select regulator voltage output Scale 1 mode */

RCC->APB1ENR |= RCC_APB1ENR_PWREN;

PWR->CR |= PWR_CR_VOS;

/* HCLK = SYSCLK / 1*/

RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK / 2*/

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

/* PCLK1 = HCLK / 4*/

RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

/* Configure the main PLL */

RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

/* Enable/Configure Spread Spectrum, when PLL isn't running */

RCC->SSCGR = (1 << 31) | // Enable

(0 << 30) | // Center

(INCSTEP << 13) |

(MODPER << 0);

/* Enable the main PLL */

RCC->CR |= RCC_CR_PLLON;

/* Wait till the main PLL is ready */

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}

...

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Cristea.Catalin
Associate III
Posted on August 15, 2017 at 16:39

Thank you Clive; I'll try this.

I do have a few more questions, if you can, while I try this:

- Is there any way to do this while running some program?  Even if I need to disable PLL, change SSCGR and re-enable PLL?

- Can I DIS-able spread spectrum while running some program? Just clear bit 31 or do the whole PLL thing?

- Can you confirm that USB will stop working if I go SS > 0.25% or something around that?

Thanks again,

Cat
Posted on August 15, 2017 at 16:49

You'll need to switch to an alternate clock source, turn off the PLL, adjust the SS settings, turn on the PLL, wait for it to lock, and switch back to it. This is likely to be quite disruptive to the peripherals, etc.

I'm not looking to confirm/validate this, not my use case, you can read the documentation, and you can experiment. I would imaging USB has a limited tolerance to jitter and modulation.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 15, 2017 at 17:14

Would this work to select HSI as the alternate clock source?

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= RCC_CFGR_SW_HSI;

Is the HSI always on, or do Ineed to enable it and wait for it?

Thanks,

Cat
Posted on August 15, 2017 at 17:34

I would do it as a single operation. Change the source and wait for it to sync. Any running source would suffice

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Cristea.Catalin
Associate III
Posted on August 16, 2017 at 22:25

If anybody cares, this is what I ended up with.  Thank you Clive One

void vSSCG_Init (void)

{

//Switch to HSI clock source

    while((RCC->CR & RCC_CR_HSIRDY) == 0){    }                // Wait till HSI is ready

    MODIFY_REG( RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI);

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_HSI)    {    }//Wait till the HSI is used as system clock source

    RCC->CR &= ~RCC_CR_PLLON;    //Turn PLL Off

    RCC->SSCGR = (RCC_SSCGR_MODPER    & ui32_myMODPER )

               | (RCC_SSCGR_INCSTEP    & ui32_myINCSTEP)

 //              | RCC_SSCGR_SPREADSEL // remove this line to use center spread mode rather than down spread mode

               | RCC_SSCGR_SSCGEN;

               

    RCC->CR |= RCC_CR_PLLON;    //Turn PLL On

//Switch to PLL clock source

    while((RCC->CR & RCC_CR_PLLRDY) == 0)    {    }    //Wait till the main PLL is ready

    MODIFY_REG( RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL);

     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL)    {    }

}