cancel
Showing results for 
Search instead for 
Did you mean: 

STM8 Manual Clock Switching Bug

Mehran Memarnejad
Associate III

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

4 REPLIES 4
Life_Cycle
Associate

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; } }
View more
BillAinCT
Associate II

@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.

 

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);

Your program will hang if the processor cannot switch the clock. They included the DownCounter part for a good reason.