2021-06-10 05:28 AM
Hi,
I guess there is a bug in manual clock switching (file: stm8s_clk.c function:CLK_ClockSwitchConfig:(
/* Wait until the target clock source is ready */
while((((CLK->SWCR & CLK_SWCR_SWIF) != 0 ) && (DownCounter != 0)))
{
DownCounter--;
}
Must be changed to:
/* Wait until the target clock source is ready */
while((((CLK->SWCR & CLK_SWCR_SWIF) == 0) && (DownCounter != 0)))
{
DownCounter--;
}
As stated in reference manual, SWIF becomes 1 when target clock source is ready, so we must loop on it till it becomes 1 or timeouts
2024-11-15 02:15 AM
I found a new bug: in auto mode, after give the SWR a new value, the SWBSY bit won't become 1 immediately, but it check this bit at once in the function CLK_ClockSwitchConfig(), so this function exit before the clock switch done, then i init the uart, it will get a wrong clk value, and then the baudrate is not correct
/* Automatic switch mode management */
if (CLK_SwitchMode == CLK_SWITCHMODE_AUTO)
{
/* Enables Clock switch */
CLK->SWCR |= CLK_SWCR_SWEN;
/* Enables or Disables Switch interrupt */
if (ITState != DISABLE)
{
CLK->SWCR |= CLK_SWCR_SWIEN;
}
else
{
CLK->SWCR &= (uint8_t)(~CLK_SWCR_SWIEN);
}
/* Selection of the target clock source */
CLK->SWR = (uint8_t)CLK_NewClock;
//here is the bug????????????????
/* Wait until the target clock source is ready */
while((((CLK->SWCR & CLK_SWCR_SWBSY) != 0 )&& (DownCounter != 0)))
{
DownCounter--;
}
if(DownCounter != 0)
{
Swif = SUCCESS;
}
else
{
Swif = ERROR;
}
}
2024-11-26 11:06 AM - edited 2024-11-26 01:38 PM
@Life_Cycle did you try to add a loop while it is 0 before the loop checking for it to go to 0? That is adding this where your bug comment is:
/* Wait until the target clock is switching */
while((((CLK->SWCR & CLK_SWCR_SWBSY) == 0 )&& (DownCounter != 0)))
{
DownCounter--;
}
Edit: It well could be that it only needs a few CPU cycles to go high so inserting a few NOPs might be all it takes to see the bit go high.
2024-12-12 10:48 PM
I do not want to edit the STM8S_StdPeriph_Driver, so I add the follow code after the function CLK_ClockSwitchConfig(), it work and my uart program also work in correct baudratio.
// switch clk to HSE without div, the fclk = HSE/1
CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE); // should not disable current clk for bug
// wait switch done(beacause there is a bug in fucntuion CLK_ClockSwitchConfig() when in auto mode)
while ((CLK->SWCR & CLK_SWCR_SWBSY) != 0);
2024-12-13 01:12 PM
Your program will hang if the processor cannot switch the clock. They included the DownCounter part for a good reason.