Skip to main content
Visitor II
June 10, 2021
Question

STM8 Manual Clock Switching Bug

  • June 10, 2021
  • 2 replies
  • 1676 views

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

    This topic has been closed for replies.

    2 replies

    Visitor II
    November 15, 2024

    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;
     }
     }
    Graduate II
    November 26, 2024

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

     

    Visitor II
    December 13, 2024

    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);
    Graduate II
    December 13, 2024

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