cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F2 Change Clock while running: Problems with USB

christophschwarz9
Associate II
Posted on September 21, 2015 at 09:40

Hello,

I have a STM32F215 running as USB Device. With a specific command I implemented a function to change the core clock speed to 30/60/120 MHz. This is already working, but the USB Port has a strange behavior. After changing the clock speed the Controller doesn't send any data back to the PC, but the data which is sent to the controller is still correct. The clock changing is done like this:


RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);

if
(ret == 0)

{

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 8;

RCC_OscInitStruct.PLL.PLLN = 240;

RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;

RCC_OscInitStruct.PLL.PLLQ = 5;

ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);

if
(ret == HAL_OK)

{

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;

ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);

if
(ret == HAL_OK)

{

HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/8000);

ret = HAL_OK;

SysFreq = 60;

}

}

}

The USB is clocked with the PLL and for changing I have to switch off the PLL and switch on after reconfig it. I guess this is the reason why the USB connection has this strange behavior afterwards. Does any one know how to solve this problem? Regards, Chris #stm32f2 #pll #usb #stm32 #clock
2 REPLIES 2
Posted on September 21, 2015 at 15:00

Well the PLL has to be stopped to reconfigure it (even with the same values), so expect bad things to happen to synchronous devices that don't expect their clocks to be stopped, or glitched.

If you want to change the speed of the processor or buses, then just modify the AHB/APB prescalers (dividers), directly with the RCC registers. You can also select between the PLL, HSE, and HSI as a source, without turning the PLL off, or attempting to reconfigure it.

I would expect the HAL code to try to do everything, and that's probably not what you want. You want controlled and specific changes, where the consequences are narrow and predictable.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
christophschwarz9
Associate II
Posted on September 22, 2015 at 09:52

Hello,

you're right, its the better way. I implemented it once with the HAL library and once with a plain access to the config register, as seen inthe code section.

temp = RCC->CFGR;
temp &= 0xFFFF030F;
temp |= 0x0000B480;
RCC->CFGR = temp;
SysFreq = 60;

Weired is now that some commands over USB are answered and after 5 to 30 answers nothing is sent back on the USB port. Without changing the frequency this problem doesn't occur. I also disable all interrupts with __set_PRIMASK(1); when I change the clock to avoid interrupts while access the registers. Any ideas to this behavior? Regards, Chris