#include "ti_msp_dl_config.h" #include #include #define APP_BASE 0x00008000 #define TEMP_BASE 0x00058000 #define MAX_APP_SIZE (300 * 1024) volatile bool upgrade_mode = false; volatile uint32_t write_address; volatile uint32_t received_size = 0; /* Forward declarations */ void jump_to_application(void); void enter_upgrade_mode(void); void erase_application_area(void); void erase_temp_area(void); void copy_temp_to_application(void); int main(void) { SYSCFG_DL_init(); NVIC_EnableIRQ(GPIO_SWITCHES_INT_IRQN); NVIC_EnableIRQ(UART_0_INST_INT_IRQN); if (upgrade_mode) { enter_upgrade_mode(); } jump_to_application(); while(1); } /* --------- Jump to Application ---------- */ void jump_to_application(void) { uint32_t sp = *(uint32_t *)APP_BASE; uint32_t reset = *(uint32_t *)(APP_BASE + 4); __disable_irq(); SCB->VTOR = APP_BASE; __set_MSP(sp); ((void (*)(void))reset)(); } /* --------- Enter Upgrade Mode ---------- */ void enter_upgrade_mode(void) { erase_temp_area(); write_address = TEMP_BASE; received_size = 0; while (received_size < MAX_APP_SIZE) { /* wait for UART interrupt to fill data */ } erase_application_area(); copy_temp_to_application(); NVIC_SystemReset(); } #define FLASH_WRITE_SIZE 8 uint8_t uart_buffer[FLASH_WRITE_SIZE]; uint32_t uart_index = 0; /* --------- UART Interrupt ---------- */ void UART_0_INST_IRQHandler(void) { if (DL_UART_Main_getPendingInterrupt(UART_0_INST) == DL_UART_MAIN_IIDX_RX) { uint8_t byte = DL_UART_Main_receiveData(UART_0_INST); uart_buffer[uart_index++] = byte; if (uart_index == 8) { __disable_irq(); DL_FlashCTL_programMemoryFromRAM( FLASHCTL, write_address, (uint32_t *)uart_buffer, 8, DL_FLASHCTL_REGION_SELECT_MAIN); __enable_irq(); write_address += 8; received_size += 8; uart_index = 0; } } } /* --------- Button Interrupt ---------- */ void GROUP1_IRQHandler(void) { if (DL_GPIO_getPendingInterrupt(GPIO_SWITCHES_PORT) == GPIO_SWITCHES_USER_SWITCH_1_IIDX) { upgrade_mode = true; } } #define FLASH_SECTOR_SIZE (8 * 1024) void erase_application_area(void) { for (uint32_t addr = APP_BASE; addr < TEMP_BASE; addr += FLASH_SECTOR_SIZE) { __disable_irq(); DL_FlashCTL_eraseMemory( FLASHCTL, addr, DL_FLASHCTL_COMMAND_SIZE_SECTOR); __enable_irq(); } } void erase_temp_area(void) { for (uint32_t addr = TEMP_BASE; addr < 0x00080000; addr += FLASH_SECTOR_SIZE) { __disable_irq(); DL_FlashCTL_eraseMemory( FLASHCTL, addr, DL_FLASHCTL_COMMAND_SIZE_SECTOR); __enable_irq(); } } /* --------- Copy TEMP → APP ---------- */ void copy_temp_to_application(void) { uint32_t offset = 0; uint8_t buffer[8]; while (offset < received_size) { for (uint32_t i = 0; i < 8; i++) { buffer[i] = *(uint8_t *)(TEMP_BASE + offset + i); } __disable_irq(); DL_FlashCTL_programMemoryFromRAM( FLASHCTL, APP_BASE + offset, (uint32_t *)buffer, 8, DL_FLASHCTL_REGION_SELECT_MAIN); __enable_irq(); offset += 8; } }