cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G070 software reset issue

aravindpv
Associate III

I was doing reset through SPI command and expected results are not happening.

 

this is the line i was expecting to reset the MCU

SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1 << NVIC_SYSRESETREQ));


where

#define NVIC_AIRCR_VECTKEY (0x05FA << 16)

#define NVIC_SYSRESETREQ    2

also my watchdog is running and expected to reset the system.
code snippet

 
FLASH_Unlock();
FLASH_ErasePage(0x08013000);
FLASH_ProgramWord(0x08013000, (uint64_t)0x0000000000000000ULL);
FLASH_Lock();

FLASH_Unlock();
FLASH_ErasePage(0x08013008);
FLASH_Lock();

SCB->AIRCR = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1 << NVIC_SYSRESETREQ));
__DSB();

while (1);

 


Edited to apply proper source code formatting - please see How to insert source code for future reference.

10 REPLIES 10
Andrew Neil
Super User

Please give some more details - see: How to write your question to maximize your chances to find a solution

 


@aravindpv wrote:

I was doing reset through SPI command and expected results are not happening..


So what, exactly, were you expecting to happen ?

What, exactly, is actually happening ?

What investigation/testing/debugging have you done to find the issue?

 


@aravindpv wrote:

this is the line i was expecting to reset the MCU.


Is that line ever executed?

Does it work without all the Flash stuff?

Without the SPI?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

i was running a bootloader + main app setup on mcu where i expecting a particular command over SPI to capture one of my else condition and which is properly triggering. And on that condition i have added a reset line like mentioned above which is not happening or code executing but stuck at somewhere that kind of result I am getting. Actually my plan was to reset the mcu and set to start from 0x08000000 were my bootloader lies.

mƎALLEm
ST Employee

Hello,

Why complicate things to yourself? and why simply you don't use HAL_NVIC_SystemReset() to reset your MCU? You're already using HAL with the flash based on your shared code!

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.

You didn't answer whether your reset line is ever getting executed?

 


@aravindpv wrote:

 i have added a reset line like mentioned above .


What do you mean, "like" ?

 

Why is that line doing a read-modify-write on SCB->AIRCR ?

Shouldn't it be just a write?

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
void Execute_write()
{
    for (uint8_t byteCounter = C_DATA_WR_OFFSET_BEGIN; byteCounter < C_DATA_ARRAY_LEN; byteCounter++)
    {
        uint8_t offset = byteCounter - C_DATA_WR_OFFSET_BEGIN;

        if (modified_app_data[offset] != 1)
            continue;

        uint8_t value = app_data[byteCounter];

        // RTC Write: set bits 0–5, and write if all are set
        if (byteCounter >= OFFSET_SET_TIME && byteCounter < OFFSET_SET_TIME + 6)
        {
            rtc_time_updated |= (1 << (byteCounter - OFFSET_SET_TIME));
            if (rtc_time_updated == 0x3F)
            {
                RTC_Write(&app_data[OFFSET_SET_TIME]);
                rtc_time_updated = 0;
            }
        }

        // PMIC Register Write
        else if (byteCounter >= OFFSET_PMIC_REG && byteCounter < OFFSET_PMIC_REG + 20)
        {
            PMIC_Write_Registers(byteCounter - OFFSET_PMIC_REG, value);
        }

        // Clear Tamper Data
        else if (byteCounter == OFFSET_CLR_TV_TAMPER_TIME)
        {
            Clear_DataArray(&app_data[OFFSET_LAST_TV_TAMPER_TIME], 6);
        }
        else if (byteCounter == OFFSET_CLR_CHASSIS_TAMPER_TIME)
        {
            Clear_DataArray(&app_data[OFFSET_LAST_CHASSIS_TAMPER_TIME], 6);
        }

        // Clear SOS Alarm
        else if (byteCounter == OFFSET_SOS_ALARM_CLR)
        {
            app_data[OFFSET_SOS_ALARM] = 0x00;
        }

        // Handle Buzzer Timings
        else if (byteCounter == OFFSET_BUZZ_DUR || byteCounter == OFFSET_BUZZ_DUR + 1)
        {
            uint16_t duration = (app_data[OFFSET_BUZZ_DUR + 1] << 8) | app_data[OFFSET_BUZZ_DUR];
            if (duration < 15000)
            {
                buzzer_systick_ctr = duration;
                turn_buzzer_off = 0;
            }
        }
        else if (byteCounter == OFFSET_BUZZ_ONTIME || byteCounter == OFFSET_BUZZ_ONTIME + 1)
        {
            uint16_t duration = (app_data[OFFSET_BUZZ_ONTIME + 1] << 8) | app_data[OFFSET_BUZZ_ONTIME];
            if (duration < 5000)
                buzzer_ontime_ctr = duration;
        }
        else if (byteCounter == OFFSET_BUZZ_OFFTIME || byteCounter == OFFSET_BUZZ_OFFTIME + 1)
        {
            uint16_t duration = (app_data[OFFSET_BUZZ_OFFTIME + 1] << 8) | app_data[OFFSET_BUZZ_OFFTIME];
            if (duration < 15000)
                buzzer_offtime_ctr = duration;
        }

        // LED Blink Durations
        else if (byteCounter == OFFSET_LED1_BLINK_DUR || byteCounter == OFFSET_LED1_BLINK_DUR + 1)
        {
            led1_duration = (app_data[OFFSET_LED1_BLINK_DUR + 1] << 8) | app_data[OFFSET_LED1_BLINK_DUR];
        }
        else if (byteCounter == OFFSET_LED2_BLINK_DUR || byteCounter == OFFSET_LED2_BLINK_DUR + 1)
        {
            led2_duration = (app_data[OFFSET_LED2_BLINK_DUR + 1] << 8) | app_data[OFFSET_LED2_BLINK_DUR];
        }
        else if (byteCounter == OFFSET_ENTER_OTA && value == 0x5E)
        {

            FLASH_Unlock();
            FLASH_ErasePage(C_PRG_FORCE_OTA); // newly added

            FLASH_ProgramWord(C_PRG_FORCE_OTA, (uint64_t)0x0000000000000000ULL);

            FLASH_Lock();
            FLASH_Unlock();
            FLASH_ErasePage(C_PRG_FORCE_RPI_POWER_CYCLE);
            FLASH_Lock();

            dbglog(0x2B);
            dbglog(0x2E);
//SCB->AIRCR = (0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;
//HAL_NVIC_SystemReset();
            SCB->AIRCR  = (NVIC_AIRCR_VECTKEY | (SCB->AIRCR & (0x700)) | (1 << NVIC_SYSRESETREQ));
            __DSB();
            while (1);
        }

        modified_app_data[offset] = 0;
    }
}

this is my code base. I already tried these all ways which didn't worked.

First, to answer whether the reset line is getting executed: yes, it reaches that SCB->AIRCR write (confirmed by toggling a GPIO just before it in debug). After the write + __DSB(), the code hits the while(1) and just hangs there – no actual reset happens. Removing the flash erase/program parts doesn't change anything, the reset still doesn't trigger.

Regarding the read-modify-write on AIRCR: I copied that pattern from older examples. But i also tried this HAL_NVIC_SystemReset() which also didnt helped.

 

observations: - The watchdog is running (IWDG), which was initially resetting the whole program due to less heap allocation which solved allocating enough Heap

Thanks..


@aravindpv wrote:

Regarding the read-modify-write on AIRCR: I copied that pattern from older examples. But i also tried this HAL_NVIC_SystemReset() which also didnt helped.


How did you know if the reset wasn't performed? Did you set a breakpoint at HAL_NVIC_SystemReset()?

Did you probe the NRST with an oscilloscope and check if the reset was/wasn't asserted?

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.

There are printf() calls very early in main() (e.g., "*****BOOTLOADER*****", some meta data's, etc.). - These are redirected via __io_putchar() to USART1 (custom low-level UART_Init()). - After software reset from the app (or even from bootloader itself), **no UART output appears**. - But on cold power-on (full power cycle), the printf logs show up fine.
also,

I2C not re-enumerating on Raspberry Pi: - Bootloader calls I2C_Init() (clock enable, reset via RCC, timing, OAR1 set to 0x30<<1, interrupts enabled). - But after reset, the RPi no longer sees the slave at 0x30 (i2cdetect shows nothing).
That's how I confirmed the control didn't reaching back to bootloader.

I suggest to check if there was a pulse on NRST pin after calling HAL_NVIC_SystemReset(). Frankly I don't rely on printf/traces..

Check if you really calling HAL_NVIC_SystemReset(), toggle a pin just before that call, and toggle another pin just at the beginning of your program to check if the reset has been performed.

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.
TDK
Super User

If HAL_NVIC_SystemReset doesn't reset the chip perhaps you have NRST tied high. Can't think of any other reason for it not working.

> But after reset, the RPi no longer sees the slave at 0x30

So it is resetting just not doing what you expect after reset?

If you feel a post has answered your question, please click "Accept as Solution".