cancel
Showing results for 
Search instead for 
Did you mean: 

Stop iwdg in halt mode on STM8L051F3

PRasm.3
Associate II

Hey

I have tried to use the option byte to stop the iwdg when i enter halt.

I can see that i manage to set the WDG_HALTin option byte 3.

But the watchdog still resets the MCU after i enter halt.

Please help me, cant i do it? If so then how do i read that from the documentation.

If i can what am i doing wrong?

I can reproduce the problem with this code:

void halt_test(void) {
    // switch to 16MHz (default is 2MHz)
    sfr_CLK.CKDIVR.byte = 0x00;
 
    // Setup LED
    sfr_PORTB.DDR.DDR2 = 1; // input(=0) or output(=1)
    sfr_PORTB.CR1.C12 = 1;  // input: 0=float, 1=pull-up; output: 0=open-drain, 1=push-pull
 
    // Disable LED
    sfr_PORTB.ODR.ODR2 = 1;
 
    for (uint32_t i = 0; i < 600000; i++) {
        NOP();
    }
 
    // unlock w/e access to EEPROM & option bytes
    sfr_FLASH.DUKR.byte = 0xAE;
    sfr_FLASH.DUKR.byte = 0x56;
 
    // wait until access granted
    while (!(sfr_FLASH.IAPSR.DUL))
        ;
 
    // Enable write to option bytes
    sfr_FLASH.CR2.OPT = 1;
 
    // Set IWDG_HALT bit
    sfr_OPT.OPT3.byte = 0b10;
 
    // wait until end of programming
    while (!(sfr_FLASH.IAPSR.EOP))
        ;
 
    // Disable write to option bytes
    sfr_FLASH.CR2.OPT = 0;
 
    // lock EEPROM again against accidental erase/write
    sfr_FLASH.IAPSR.DUL = 0;
 
    // start IDWG (must be the first value written to this register, see UM)
    sfr_IWDG.KR.byte = (uint8_t)0xCC;
 
    // unlock write access to prescaler and reload registers
    sfr_IWDG.KR.byte = (uint8_t)0x55;
 
    sfr_IWDG.PR.PR = 6;
 
    // set timeout period 0xff = 1724.63ms according to RM0031
    sfr_IWDG.RLR.byte = 0xff;
 
    // start IDWG
    sfr_IWDG.KR.byte = (uint8_t)0xCC;
 
    // Enable LED
    sfr_PORTB.ODR.ODR2 = 0;
 
    ENTER_HALT();
}

15 REPLIES 15
Peter BENSCH
ST Employee

How did you reprogram WDG_HALT in option byte 3 (OPT3)?

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
PRasm.3
Associate II

i just added an example

Peter BENSCH
ST Employee

It looks like you are asking for the wrong bit to test in line 31.

Instead of EOP you should query HVOFF (see RM0031, section 3.6.2).

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
PRasm.3
Associate II

That didn't change the behavior.

Looking for

    while (!(sfr_FLASH.IAPSR.HVOFF))
        ;

didnt fix the issue

/Peter

Peter BENSCH
ST Employee

Have you checked the value of OPT3 after trying to program it?

You could extend the query in line 31 to WR_PG_DIS | HVOFF. 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
PRasm.3
Associate II

i read it back via stm8flash and saw that the bit was set.

But good point i will try to read it back runtime

PRasm.3
Associate II
void halt_test(void) {
    // switch to 16MHz (default is 2MHz)
    sfr_CLK.CKDIVR.byte = 0x00;
 
    // Setup LED
    sfr_PORTB.DDR.byte = 0xff; // input(=0) or output(=1)
    sfr_PORTB.CR1.byte = 0xff;  // input: 0=float, 1=pull-up; output: 0=open-drain, 1=push-pull
 
    // Disable LED
    sfr_PORTB.ODR.byte = 0xff;
 
    for (uint32_t i = 0; i < 600000; i++) {
        NOP();
    }
 
    // unlock w/e access to EEPROM & option bytes
    sfr_FLASH.DUKR.byte = 0xAE;
    sfr_FLASH.DUKR.byte = 0x56;
 
    // wait until access granted
    while (!(sfr_FLASH.IAPSR.DUL))
        ;
 
    // Enable write to option bytes
    sfr_FLASH.CR2.OPT = 1;
 
    // Set IWDG_HALT bit
    sfr_OPT.OPT3.byte = 0b10;
 
    // wait until end of programming
    while (!(sfr_FLASH.IAPSR.EOP))
        ;
 
    while ((sfr_FLASH.IAPSR.WR_PG_DIS))
        ;
 
    while (!(sfr_FLASH.IAPSR.HVOFF))
        ;
 
    // Disable write to option bytes
    sfr_FLASH.CR2.OPT = 0;
 
    // lock EEPROM again against accidental erase/write
    sfr_FLASH.IAPSR.DUL = 0;
 
    if (sfr_OPT.OPT3.byte == 0b10) {
        sfr_PORTB.ODR.ODR3 = 0; // LED5
    } else {
        sfr_PORTB.ODR.ODR7 = 0; // LED1
    }
 
    // start IDWG (must be the first value written to this register, see UM)
    sfr_IWDG.KR.byte = (uint8_t)0xCC;
 
    // unlock write access to prescaler and reload registers
    sfr_IWDG.KR.byte = (uint8_t)0x55;
 
    sfr_IWDG.PR.PR = 6;
 
    // set timeout period 0xff = 1724.63ms according to RM0031
    sfr_IWDG.RLR.byte = 0xff;
 
    // start IDWG
    sfr_IWDG.KR.byte = (uint8_t)0xCC;
 
    // Enable LED
    sfr_PORTB.ODR.ODR2 = 0;
 
    ENTER_HALT();
}

I have now tried to read OPT3 back runtime and from what i can see the correct bit is set.

PRasm.3
Associate II

Any updates @Peter BENSCH​ 

Unfortunately, I can only check it theoretically/from memory at the moment and not on a living object, as I don't have one at my place.

Maybe someone else can be found who has a board with the STM8L051 right now?

Regards

/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.