Other Parts Discussed in Thread: MSPM0G3507, MSPM0-SDK
Tool/software:
Hello,
I am working with custom bootloader of MSPM0G3507. This bootloader implemented using UART and doing crc nd version check before writing new hex to flash.
In my bootloader application upon reset bootloader runs first then checks for the application at desired location presented or not if present then jump to that app if not then runs normal bootloader code.
At last if full crc of received code and calculated local crc match then it will make a jump to new application which is flashed but the issue was when i make a jump through my jump function,interrupts of jumped application not worked, it will reset the uc and start from the bootloader app at 0. as i mentioned it will check and jump to the app again.
so the main error is my interrupt handler never get executed and never wrtie bootcmd(1 at flash loc 0x0001F058 ). it wil repeat every time when interrupt i give gpio interrupt.
so can anybody help me with this beacause i am not able to find this issue and this was my first bootloader code. i attach the jump function and irq handler also linker file.
Linker Command File
#include "ti_msp_dl_config.h"
#include "string.h"
#include "stdio.h"
#include "core_cm0plus.h"
#define BOOTLOADER_VECTOR_TABLE_ADDRESS 0x00000000
#define BOOTLOADER_INT_LOCATION 0x0001F058 /* At this location flag set by applicant who wish to turn on boot mode to flesh nex hex */
#define VTOR_OFFSET (uint32_t *)0x00003E80
#define NO_ERROR 0
#define ERROR_WRITE_32_BIT 6
void jump_to_app(uint32_t);
uint8_t BootCmdWrite(uint32_t);
volatile uint8_t gErrorType = NO_ERROR;
volatile DL_FLASHCTL_COMMAND_STATUS gCmdStatus;
uint32_t gCmd32 = 0x00000001;
uint32_t gCmdTemp;
int main(void) {
//early_irq_enable();
SYSCFG_DL_init();
SCB->VTOR = (uint32_t)VTOR_OFFSET;
__enable_irq();
NVIC_ClearPendingIRQ(USR_BOOT_INT_IRQN);
NVIC_EnableIRQ(USR_BOOT_INT_IRQN);
while (1) {
DL_GPIO_togglePins(USER_LED_PORT, USER_LED_RED_LED_PIN);
delay_cycles(16000000);
}
}
void GROUP1_IRQHandler(void)
{
switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
case USR_BOOT_INT_IIDX:
/* If SW is high, turn the LED off */
if (DL_GPIO_readPins(USR_BOOT_PORT, USR_BOOT_BT_PIN_PIN)) {
BootCmdWrite(gCmd32);
DL_GPIO_togglePins(RGB_PORT, RGB_GREEN_LED_PIN);
delay_cycles(64000000);
jump_to_app(BOOTLOADER_VECTOR_TABLE_ADDRESS);
// NVIC_SystemReset();
}
break;
default :
break;
}
}
uint8_t BootCmdWrite(uint32_t cmd) {
if (gErrorType == NO_ERROR) {
DL_FlashCTL_unprotectSector(FLASHCTL, BOOTLOADER_INT_LOCATION, DL_FLASHCTL_REGION_SELECT_MAIN);
// gCmdStatus = DL_FlashCTL_programMemoryFromRAM64WithECCGenerated(
// FLASHCTL, BOOTLOADER_INT_LOCATION, &cmd32[0]);
DL_FlashCTL_programMemoryFromRAM32WithECCGenerated(
FLASHCTL, BOOTLOADER_INT_LOCATION, &cmd);
// Ensure write is fully committed
__DSB(); // Data Synchronization Barrier
__ISB(); // Instruction Synchronization Barrier
if (gCmdStatus == DL_FLASHCTL_COMMAND_STATUS_FAILED)
{
/* If command was not successful, set error flag */
gErrorType = ERROR_WRITE_32_BIT;
}
DL_FlashCTL_protectSector(FLASHCTL, BOOTLOADER_INT_LOCATION, DL_FLASHCTL_REGION_SELECT_MAIN);
gCmdTemp = *(uint32_t *)BOOTLOADER_INT_LOCATION;
}
return gErrorType;
}
void HardFault_Handler(void)
{
// Debug indicator - blink LED or breakpoint
while (1)
{
DL_GPIO_togglePins(RGB_PORT, RGB_GREEN_LED_PIN);
for (volatile int i = 0; i < 100000; i++); // Simple delay
}
}
void jump_to_app(uint32_t app_addr) {
__disable_irq();
// Disable and clear all interrupts
for (uint32_t i = 0; i < 8; i++) {
NVIC->ICER[i] = 0xFFFFFFFF; // Disable IRQs
NVIC->ICPR[i] = 0xFFFFFFFF; // Clear pending IRQs
}
__DSB();
__ISB();
// Reset SysTick just in case
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
uint32_t sp = *((uint32_t *)app_addr); // Stack pointer
uint32_t reset = *((uint32_t *)(app_addr + 4)); // Reset handler
__set_MSP(sp);
SCB->VTOR = app_addr; // If needed
((void (*)(void))reset)(); // Jump to reset handler
}