2015-09-21 12:40 AM
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
2015-09-21 06:00 AM
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.2015-09-22 12:52 AM
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