2025-12-29 4:19 AM - last edited on 2025-12-29 5:00 AM by Andrew Neil
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 2also 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.
2025-12-29 4:33 AM
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?
2025-12-29 4:40 AM
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.
2025-12-29 4:46 AM - edited 2025-12-29 4:49 AM
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!
2025-12-29 4:48 AM
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?
2025-12-29 5:06 AM
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..
2025-12-29 5:11 AM
@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?
2025-12-29 5:26 AM
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.
2025-12-29 5:31 AM
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.
2025-12-29 5:37 AM
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?