This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSPM0G3519: Firmware upgrade Procedure

Part Number: MSPM0G3519
Other Parts Discussed in Thread: MSPM0C1104, UNIFLASH, MSPM0G3518

Hello,

I am working on MSPM0G3519 Launchpad. I want to do OTA based firmware upgrade. I have 2 codes. 1st is bootloader code where i changed the flash region in linker.cmd file 

FLASH           (RX)  : origin = 0x00000000, length = 0x00008000.
 
in this bootloader code, I am receiving the .bin file through bluetooth and storing in location starting from 0x00008000. after completion i want to check whether application is valid or not and if valid i want to jump to application.
int is_application_valid(void)
{
    uint32_t stack = *(uint32_t*)APP_VECTOR_ADDRESS;
   // __BKPT(0);
   // if ((stack & 0xFFF00000) == 0x20200000)
    if ((stack & 0x2FFE0000) == 0x20200000){
        jump_flag = 1;
        result = 1;
    }
       
    else{

        result = 2;
    }
    return result;
}

void jump_to_application(void)
{
    uint32_t *vectorTable = (uint32_t *)APP_VECTOR_ADDRESS;

    uint32_t appStack = vectorTable[0];
    uint32_t appReset = vectorTable[1];

    __disable_irq();

    /* Disable all NVIC interrupts */
    for(int i = 0; i < 8; i++)
    {
        NVIC->ICER[i] = 0xFFFFFFFF;   // Disable
        NVIC->ICPR[i] = 0xFFFFFFFF;   // Clear pending
    }

    /* Disable SysTick */
    SysTick->CTRL = 0;

    SCB->VTOR = APP_VECTOR_ADDRESS;
    __set_MSP(appStack);

     void (*appEntry)(void) = (void (*)(void))appReset;
    appEntry();
}
 
In my application code linker.cmd file is as below.
MEMORY
{
    FLASH           (RX)  : origin = 0x00008000, length = 0x00078000
    SRAM_BANK0      (RWX) : origin = 0x20200000, length = 0x00010000
    SRAM_BANK1      (RWX) : origin = 0x20210000, length = 0x00010000
    BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x000000FF
    BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
    DATA            (R)   : origin = 0x41D00000, length = 0x00004000
}

SECTIONS
{
    .intvecs:  {}  > 0x00008000
    .text   : palign(8) {} > FLASH
    .const  : palign(8) {} > FLASH
    .cinit  : palign(8) {} > FLASH
    .pinit  : palign(8) {} > FLASH
    .rodata : palign(8) {} > FLASH
    .ARM.exidx    : palign(8) {} > FLASH
    .init_array   : palign(8) {} > FLASH
    .binit        : palign(8) {} > FLASH
    .TI.ramfunc   : load = FLASH, palign(8), run=SRAM_BANK0, table(BINIT)

    .vtable :   > SRAM_BANK0
    .args   :   > SRAM_BANK0
    .data   :   > SRAM_BANK0
    .bss    :   > SRAM_BANK0
    .sysmem :   > SRAM_BANK0
    .TrimTable :  > SRAM_BANK0
    .stack  :   > SRAM_BANK0 (HIGH)

    .BCRConfig  : {} > BCR_CONFIG
    .BSLConfig  : {} > BSL_CONFIG
    .DataBank   : {} > DATA
}
binfile_storing.pngbin_hex_convert.png
 
and in application code main() i have used 
SCB->VTOR = 0x00008000;
I build the project and generated the .bin file. I have attached the screenshots for the .bin file for after converting to hex view and another screenshot showing the memory view where this value has stored.  After storing when I am checking for is_application_valid(), in the if condition, it is entering into some default handler and I am not able to come out of the loop. what is happening I am not understanding. I am sharing the main() function too. 
int main(void)
{
    SYSCFG_DL_init();
    __enable_irq();

    DL_UART_Main_enable(UART_1_INST);
    NVIC_EnableIRQ(UART_1_INST_INT_IRQN);

    delay_ms(3000);

    /*if(is_application_valid())
    {
        __BKPT(0);
        jump_to_application();
    }*/

    // DO NOT ERASE HERE

    while(1)
    {
        delay_ms(1);
        lastReceiveTime++;

        if(lastReceiveTime > 2000)
        {
            if(rxIndex >= 8)
            {
                uint16_t fullBlocks = rxIndex / 8;

                for(int i = 0; i < fullBlocks * 8; i += 8)
                {
                    flash_write_block(&rxBuffer[i]);
                }

                rxIndex = 0;
            }
if(lastReceiveTime > 20000){
            __disable_irq();

            if(is_application_valid())
            {
                __BKPT(0);
                jump_to_application();
            }
}
        }
    }
}
 
I want to know Is this the correct way to do firmware upgrade? or Is there any other way to do this?
I need guidance on this. It's very urgent. I got stuck on it.
 
  • Hi,

    The method looks good from my side.

    •  is_application_valid(): Which code will cause you enter into default_hanlder? Please check if CPU can jump to this code line. And read the stack value to check if it is = 0x20210000
    • Please define the hard_fault and NMI handler in your bootloader code to check which specifically cause MCU enter into default_handler.
    • The main() function you shared is application project or bootloader project? 

    Regards,

    Zoey

  • Hi Zoey,

    I am coming to is_application_valid(), I am getting stack = 0x20210000. So, as per me If condition should true and it should return result =1, but I am not entering into the loop, by keeping break point i checked, after If condition, when I stepped into it is entering into some while loop in default_handler. 

    The main() function I shared is of bootloader.

  • It is so odd. Does every time you call this function, it will enter into default handler? 

  • Yes, can You suggest any other better way? Because I am not able to solve this problem. I am expecting to help me out

  • Hi,

    You can find demo code in ...\ti\mspm0_sdk_2_09_00_01\examples\nortos\LP_MSPM0C1104\bsl\flash_bsl  --- flashBSL_invocation.c

    This is what we always use:
    blInvocationState_t blInvocation_checkBlankDevice(void)
    {
        // Check if Application Reset vector exists
        if ((*((uint32_t *) (MAIN_APP_RESET_VECTOR_ADDR))) == BLANK_VALUE) {
            return BL_INVOCATION_BLANK_DEVICE;
        } else {
            return BL_INVOCATION_FALSE;
        }
    }
  • okay, thanks. I will go through this and will let you know. let the thread open.

  • Hi Zoey, 

    This is not for MSPM0G3519. Can you suggest some better way? Is it possible to store the .bin file in emulated eeprom and at poweron can it able to boot from the eeprom stored value?

  • Hi,

    You can migrate it to M0G3519. 

    .bin file is too large to store as the emulated eeprom. Can you refer to secondary BSL code in our SDK(C1104 demo code I shared will also include blank check and G3519 demo code will have blank check in boot code and only need bootloader project in flash).

    Regards,

    Zoey 

  • okay. There are many bsl codes for G3519. Which one I should check for? please suggest. I am sharing the list of codes over here. Please suggest one. 

    My setup is like, I am using MSPM0G3519 Launch pad and I have connected the JDY-25M Bluetooth Module to the UART1. I am using serial  bluetooth terminal in mobile for transfering .bin/.hex file of the gpio toggle code.

  • Hi, 

    i tried to use bsl_software_invoke_app_demo_uart code, I flashed the code, one blue led starts blinking, i pressed S2, then green led blinked and stopped, now i started flashing gpio_toggle_output code i.e. .hex file . it programmed successfully, as per me now I am expecting the gpio_toggle code to run, but its not running. even after reconnecting the borad also no code is running. Board is getting corrupted. I need to reset the board before programming again.

    please help me on this.

  • Hi,

    You mean you succeed to flash the MCU?? How your confirmed this? Is your bootloader protocol same as our ROM BSL?

     bsl_software_invoke_app_demo_uart is using our ROM bootloader. If you have your own protocol, please refer to  . And modify the demo code like UART pin, protocol, and so on. I have also attached the BSL user guide for your reference:

    https://www.ti.com/lit/pdf/slau887

    https://www.ti.com/lit/pdf/slaae88

     

  • in uniflash it's showing program completed successfully. I didnot change any code in my side, simply i am using the launchpad and testing the demo code. That's it. My expectation is the demo code should work. As its TI provided uniflash so it should work correctly. I am not sending any BSL protocol.

  • OK, Please check if you application code start address at 0x0000

  • yes, it is starting at 0x0000. the application code also same demo code provided i.e. gpio_toggle_output. individually when I am running this code, it is working fine.

  • Can you generate the .bin or .txt file and upload to uniflash to have a try? There is some issue for CCS to generate the hex file

  • Thanks a lot Zoey. .bin file is working fine. So, now I want to do in the same way the firmware upgrade but not using uniflash. I have a bluetooth module connected to UART1 of the launchpad. I want to receive the .bin file over bluetooth and want to flash it. How can I achieve this, please give the steps or give me some idea.

  • i have 1 doubt, if you can clear it. 

    Rightnow i can't implement the app in android to get bsl protocol, what I can do is, by removing the bluetooth module i can connect a cable where i can open the docklight and can send the frame formats. or else 2nd method is i should receive the .bin file , store it in emulated eeprom and from there can i send it to bsl by converting it into proper bsl frame formats. just for testing i am using a small size file, so i think it won't be a problem.

    I will be waiting for your response

  • Hi,

    Sorry for the late reply. I am not familiar with your host system. But I would say if you send the .bin file based on our BSL protocol to the MCU, then MSPM0 can be updated successfully. So you can send the .bin file to your host maybe by bluetooth or EEPROM stored directly, than, host send this data array to the MCU.

    And just would like to let you know that we do have host demo code in our SDK: Not sure whether this can help you. 

  • Hi,

    Now I am able to do firmware upgrade. I am sending BSL Packets using docklight. I have 1 doubt. ROM BSL is accepting packets on UART0. Can I change the configuration to any other UART? One more thing, let say while upgrading, there is any disturbance happened, then the board is not working. I want, even if it won't upgrade to new firmware but my old firmware should run. As I am erasing before sending the new firmware, so I don't have anything in the flash , so nothing works. How to deal with this?

  • Hi, 

    Now I am trying to work with secondary bsl. But this code is not flashing on the board. what is this code? and how to test this code. Will this code able to solve the problem I am facing in firmware upgrade? I am getting following error while flashing the code.

    Flash Programmer: Invalid mass erase command
    File Loader: Memory write failed: Flash Programmer: Error, Attempting NONMAIN write without erasing!
    GEL: File: C:\Users\dibyarekha\workspace_ccstheia\secondary_bsl_uart\Debug\secondary_bsl_uart.out: Load failed.

  • Hi,

    Sorry for the late reply. I just back to the office after my personal leave.

    ROM BSL is accepting packets on UART0. Can I change the configuration to any other UART?

    You're correct. ROM BSL only support UART0. If you would like to other UATR, please use secondary BSL or BSL plugin

    As I am erasing before sending the new firmware, so I don't have anything in the flash , so nothing works. How to deal with this?

    MSPM0G3519 supports dual bank. You can only upgrade the only bank. And reserve your old firmware in the other bank. And in your secondary BSL, you can add timeout function. And if host is stuck, then target can jump into old version to run.

  • Hi,

    Secondary BSL is not staring from 0x0000. So you can try to read the address, and see if 0x2000 have the related code.

    And why failed to load again:

    In this demo code, the static flash protected is enabled. In that case, normal flash (mass erase) cannot work and change the related flash. You should do factory reset 7674.Factory reset_Auto.pdf

  • Hi, 

    I tried to do like this, but I am getting error in debugging. Please check the attached files.

    Error: (Error -1001 @ 0x0) Requested operation is not supported on this device. (Emulation package 20.4.0.3835)
    Trouble Halting Target CPU: Device Connection Error. This could be caused by the device having gone to low power mode. Try forcing an external reset pressing the 'Force Reset' button. If the error persists, try: 1) Invoking BSL, 2) Calling a DSSM Mass erase, or, 3) Calling a DSSM Factory Reset. Check device FAQs for more information.
    Breakpoint Manager: Remove job failed: Register/memory write failure[22005]

    #include "ti_msp_dl_config.h"
    #include <stdint.h>
    #include <stdbool.h>
    
    #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;
        }
    }

  • I tried to do like this, but I am getting error in debugging.

    Could you help to clarify what do you do and where you get such error?

  • Hi, 

    I want to upgrade the firmware. I am able to do it using ROM BSL. But in ROM BSL 1 problem is that, if there is power OFF during firmware upgrade, at power ON the board become dead, that's why my requirement is, board should not dead, even if there is problem in firmware upgrade, atleast the board should run the previous firmware. 

    I am trying to use the custom bootloader concept. 

    I am doing in the following way

    Bootloader : 0x00000000 → 0x00007FFF
    Application: 0x00008000 → onward
    Temp area : 0x00058000 → onward

    Power ON

    Bootloader starts

    Press switch

    upgrade_mode = true

    enter_upgrade_mode()

    UART receives firmware

    Firmware stored in TEMP flash

    Docklight sends 5A5A5A5A

    upgrade_complete = 1

    copy TEMP → APP

    NVIC_SystemReset()

    New firmware runs

    I have 1 bootloader code, following is the linker.cmd

    uinterruptVectors
    --stack_size=256

    /* Note: SRAM is partitioned into two separate sections SRAM_BANK0 and SRAM_BANK1
     * to account for SRAM_BANK1 being wiped out upon the device entering any low-power
     * mode stronger than SLEEP. Thus, it is up to the end-user to enable SRAM_BANK1 for
     * applications where the memory is considered lost outside of RUN and SLEEP Modes.
     */

    MEMORY
    {
        FLASH           (RX)  : origin = 0x00000000, length = 0x00080000
        SRAM_BANK0      (RWX) : origin = 0x20200000, length = 0x00010000
        SRAM_BANK1      (RWX) : origin = 0x20210000, length = 0x00010000
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x000000FF
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
        DATA            (R)   : origin = 0x41D00000, length = 0x00004000
    }

    SECTIONS
    {
        .intvecs:   > 0x00000000
        .text   : palign(8) {} > FLASH
        .const  : palign(8) {} > FLASH
        .cinit  : palign(8) {} > FLASH
        .pinit  : palign(8) {} > FLASH
        .rodata : palign(8) {} > FLASH
        .ARM.exidx    : palign(8) {} > FLASH
        .init_array   : palign(8) {} > FLASH
        .binit        : palign(8) {} > FLASH
        .TI.ramfunc   : load = FLASH, palign(8), run=SRAM_BANK0, table(BINIT)

        .vtable :   > SRAM_BANK0
        .args   :   > SRAM_BANK0
        .data   :   > SRAM_BANK0
        .bss    :   > SRAM_BANK0
        .sysmem :   > SRAM_BANK0
        .TrimTable :  > SRAM_BANK0
        .stack  :   > SRAM_BANK0 (HIGH)

        .BCRConfig  : {} > BCR_CONFIG
        .BSLConfig  : {} > BSL_CONFIG
        .DataBank   : {} > DATA
    }
     
    Another is the new firmware where I am taking the gpio_toggle_output code provided by TI where I modified the linker.cmd file as follows
    -uinterruptVectors
    --stack_size=256

    /* Note: SRAM is partitioned into two separate sections SRAM_BANK0 and SRAM_BANK1
     * to account for SRAM_BANK1 being wiped out upon the device entering any low-power
     * mode stronger than SLEEP. Thus, it is up to the end-user to enable SRAM_BANK1 for
     * applications where the memory is considered lost outside of RUN and SLEEP Modes.
     */

    MEMORY
    {
        FLASH           (RX)  : origin = 0x00008000, length = 0x00078000
        SRAM_BANK0      (RWX) : origin = 0x20200000, length = 0x00010000
        SRAM_BANK1      (RWX) : origin = 0x20210000, length = 0x00010000
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x000000FF
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
        DATA            (R)   : origin = 0x41D00000, length = 0x00004000
    }

    SECTIONS
    {
        .intvecs:   > 0x00008000
        .text   : palign(8) {} > FLASH
        .const  : palign(8) {} > FLASH
        .cinit  : palign(8) {} > FLASH
        .pinit  : palign(8) {} > FLASH
        .rodata : palign(8) {} > FLASH
        .ARM.exidx    : palign(8) {} > FLASH
        .init_array   : palign(8) {} > FLASH
        .binit        : palign(8) {} > FLASH
        .TI.ramfunc   : load = FLASH, palign(8), run=SRAM_BANK0, table(BINIT)

        .vtable :   > SRAM_BANK0
        .args   :   > SRAM_BANK0
        .data   :   > SRAM_BANK0
        .bss    :   > SRAM_BANK0
        .sysmem :   > SRAM_BANK0
        .TrimTable :  > SRAM_BANK0
        .stack  :   > SRAM_BANK0 (HIGH)

        .BCRConfig  : {} > BCR_CONFIG
        .BSLConfig  : {} > BSL_CONFIG
        .DataBank   : {} > DATA
    }
    The generated .bin file has hex view as
    I am sending each 16bytes using docklight receiving and storing these bytes in memory location 0x00058000 onwards which is happening in my code properly,
    Here with I am sharing the code with you.
    #include "ti_msp_dl_config.h"
    #include <stdint.h>
    #include <stdbool.h>

    #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;

    #define FLASH_WRITE_SIZE    8
    #define UART_PACKET_SIZE    16
    volatile uint8_t upgrade_complete = 0;
    volatile uint32_t uart_index = 0;
    volatile uint8_t uart_buffer[UART_PACKET_SIZE];
    volatile bool uart_packet_ready = false;

    /* 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);
    void process_uart_packet();

    int main(void)
    {
        SYSCFG_DL_init();

        NVIC_EnableIRQ(GPIO_SWITCHES_INT_IRQN);
        NVIC_EnableIRQ(UART_0_INST_INT_IRQN);

        /* Check if application exists */
        uint32_t app_sp = *(uint32_t *)APP_BASE;

        while (1)
        {
            if (upgrade_mode)
            {
                enter_upgrade_mode();
                upgrade_mode = false;
            }

            if (upgrade_complete)
            {
                upgrade_complete = 0;
                erase_application_area();
                copy_temp_to_application();
                NVIC_SystemReset();
            }
            process_uart_packet();
        }
    }
    /* --------- 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 storage area */
        erase_temp_area();

        write_address = TEMP_BASE;
        received_size = 0;
        uart_index = 0;
        upgrade_complete = 0;
       
    }
    /* --------- UART Interrupt ---------- */

    volatile uint32_t end_pattern = 0;
    void UART_0_INST_IRQHandler(void)
    {
        uint32_t pending = DL_UART_Main_getPendingInterrupt(UART_0_INST);

        if (pending == DL_UART_MAIN_IIDX_RX)
        {
            while (DL_UART_Main_isRXFIFOEmpty(UART_0_INST) == false)
            {
                uint8_t byte = DL_UART_Main_receiveData(UART_0_INST);

                uart_buffer[uart_index++] = byte;

                if (uart_index == 16)
                {
                   
                   uart_packet_ready = true;
                   uart_index = 0;
                   
                }
                  /* Shift previous bytes and add new byte */
            end_pattern = (end_pattern << 8) | byte;

            if (end_pattern == 0x5A5A5A5A)
            {
                upgrade_complete = true;
            }
            }
        }
    }



    void process_uart_packet(void)
    {
        if (uart_packet_ready)
        {
            uart_packet_ready = false;

            uint32_t data64[2];

            /* First 8 bytes */
            data64[0] = (uart_buffer[3] << 24) |
                        (uart_buffer[2] << 16) |
                        (uart_buffer[1] << 8)  |
                        uart_buffer[0];

            data64[1] = (uart_buffer[7] << 24) |
                        (uart_buffer[6] << 16) |
                        (uart_buffer[5] << 8)  |
                        uart_buffer[4];
            __disable_irq();

           DL_FlashCTL_unprotectSector(
        FLASHCTL,
        write_address,
        DL_FLASHCTL_REGION_SELECT_MAIN
    );

            DL_FlashCTL_programMemoryFromRAM64(
                FLASHCTL,
                write_address,
                data64);

            __enable_irq();
            write_address += 8;

            /* Next 8 bytes */
            data64[0] = (uart_buffer[11] << 24) |
                        (uart_buffer[10] << 16) |
                        (uart_buffer[9] << 8)   |
                        uart_buffer[8];

            data64[1] = (uart_buffer[15] << 24) |
                        (uart_buffer[14] << 16) |
                        (uart_buffer[13] << 8)  |
                        uart_buffer[12];

            __disable_irq();

            DL_FlashCTL_unprotectSector(
        FLASHCTL,
        write_address,
        DL_FLASHCTL_REGION_SELECT_MAIN
    );
            DL_FlashCTL_programMemoryFromRAM64(
                FLASHCTL,
                write_address,
                data64);
            __enable_irq();
            write_address += 8;
            received_size += 16;
        }
    }
    /* --------- Button Interrupt ---------- */
    void GROUP1_IRQHandler(void)
    {
        if (DL_GPIO_getPendingInterrupt(GPIO_SWITCHES_PORT) ==
            GPIO_SWITCHES_USER_SWITCH_1_IIDX)
        {
            upgrade_mode = true;
           // enter_upgrade_mode();
        }
       
    }

    #define FLASH_SECTOR_SIZE   2048

    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 ---------- */
    #define RAMFUNC __attribute__((section(".ramfunc")))
    #if 1
    RAMFUNC void copy_temp_to_application(void)
    {
        uint32_t offset = 0;
        uint32_t buffer[2];
        uint32_t current_sector = 0xFFFFFFFF;

        while (offset < received_size)
        {
            uint32_t app_addr = APP_BASE + offset;

            /* Unprotect sector only once per sector */
            uint32_t sector = app_addr / FLASH_SECTOR_SIZE;
            __disable_irq();
             /* Wait for flash controller */
            //while (DL_FlashCTL_getStatus(FLASHCTL) & DL_FLASHCTL_STATUS_BUSY);
            if (sector != current_sector)
            {
                current_sector = sector;

                DL_FlashCTL_unprotectSector(
                    FLASHCTL,
                    app_addr,
                    DL_FLASHCTL_REGION_SELECT_MAIN);
            }

            /* Read 8 bytes from TEMP area */
            buffer[0] = *(uint32_t *)(TEMP_BASE + offset);
            buffer[1] = *(uint32_t *)(TEMP_BASE + offset + 4);

           
    //while (DL_FlashCTL_isBusy(FLASHCTL));
            /* Program 8 bytes to application area */
            /*DL_FlashCTL_programMemoryFromRAM(
                FLASHCTL,
                app_addr,
                buffer,
                8,
                DL_FLASHCTL_REGION_SELECT_MAIN);*/
                DL_FlashCTL_programMemoryFromRAM64(
                FLASHCTL,
                app_addr,
                buffer);

            offset += 8;
        }
        __enable_irq();
    }
    #endif
    when I am trying to read 0x00058000, then buffer[0] = *(uint32_t *)(TEMP_BASE + offset); this line is entering into default_handler , I am not understanding the reason.
    I tried to use secondary bsl, but i couldnot wunderstand how to test the code, whether secondary_bsl code is help in my project or  not?

    Please help me in finding where I am going wrong.
  • at power ON the board become dead,

    If the device go into bootloader mode after reset if the previous update is failed, dose it accept for you?

    That means if the firmware update failed last time, you can use reset to make the device go into bootloader mode.

  • Hi,

    Board to need to reset again. If I am writing the 0x00 memory location atlast, then if before writing 0x00 power goes OFF, then at power ON it is staying at BSL only. But thing is, in this case, I don't want to stay in BSL. At power ON I want to run the previous firmware.

  • could you please help me on this. I really got stuck and unable to move ahead. need your help.

  • when I am trying to read 0x00058000, then buffer[0] = *(uint32_t *)(TEMP_BASE + offset); this line is entering into default_handler , I am not understanding the reason.

    Few thing you can to check here

    1. you need to take care is when you use the uint32_t pointer to read data, the address TEMP_BASE + offset should be 4 bytes aligned. 

    2. Make sure the TEMP_BASE + offset  not exceed the maximum address of MSPM0G3519 that 0x0007FFFF

    3. you can try to add HardFault_Handler to see if due to this cause the default handler

    I also try run the code below with MSPM0G3519 with no issue on myside, so the code format should no issue.

     

  • Hi,

    Same thing, I checked at my side by giving direct memory location, still it's entering into defaulthandler. Is there any problem in my workspace? I have taken the project of bsl only, In that i am editing and doing.

  • You can try this project

    adc12_max_freq_dma_LP_MSPM0G3519_nortos_ticlang.zip

    Make sure your device is MSPM0G3519 not MSPM0G3518.

  • Okay, I will check it, But what I observe is, in general if I am reading any memory then it is not entering into default handler, Only when I am writing into that memory after that I am reading, then only it's entering into default handler

  • I checked this. In this you didnot wrote anything into memory 0x00058000. Could you please write something and after that read it back.whether It's working or not please let me know

  • Hi, I solved this. Now I am able to read from 0x00058000 and write into 0x0008000. after that I am doing system reset and expecting it to run the new firmware. but its not working. what else need to do

    please help

  • after copying the data from 0x00058000 to 0x00008000, reset is not working, as well as I am doing 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)();
    }.
    In this function at the 1st line itself it's entering into the default handler. After getting the firmware , how to start? i used 
    NVIC_SystemReset(). still its not working
  • Do you know at which line it trigged default handler?

    Few comments about out jump to application code:

    1.  __set_MSP(sp) can be removed

    2. SCB->VTOR = APP_BASE; can move to start of application code 

  • Hi,

    I solved the problem. I did yesterday mistake only. writing into 0x00008000 using 

    DL_FlashCTL_programMemoryFromRAM64WithECCGenerated solved the problem. Now my sp = 0x20210000 and reset value = 0x000081DD
    but when I am entering into 
    ((void (*)(void))reset)(); this line I am not understanding what is happening, I am expecting the board should reset and it should run the new firmware. But That's not happening. 
    What to do next? How to run the new firmware available at 0x00008000. 
    ...
  • this line I am not understanding what is happening,

    For this line will go into application's reset handler and then jump to main function. You can pull up a GPIO into application code to show it start work.

  • Hi,

    I found my mistake. Now it's working.

  • Hi,

    Thanks a lot for your help. I was completely new to this chip. Now I understood somehow. Still I am doing this project. I need some more modifications. For Further queries I need your help.

    Hope you will help me.

    Thanks

  • No problem, please create a new thread if any other questioned you get.

  • Here I more thing, I need your help, I am converting the .bin file into hex and sending hex bytes over uart using docklight.

    My goal is to send the file using bluetooth. Now in this launchpad for sending hex bytes over docklight, uart0 I have used. But I have connected the bluetooth to UART1. So, will it work If I will do the same with uart1?

    2nd doubt

    How can I send the .bin file over bluetooth?

    weather bluetooth will send the .bin file as hex bytes or do I need an external software for converting the .bin to hex bytes and transmit over bluetooth?

  • I am converting the .bin file into hex and sending hex bytes over uart using docklight.

    The CCS can generate HEX or TI-TXT format directly that can easy to handle. 

    My goal is to send the file using bluetooth. Now in this launchpad for sending hex bytes over docklight, uart0 I have used. But I have connected the bluetooth to UART1. So, will it work If I will do the same with uart1?

    Do you mean you use MSPM0's UART1 to send the firmware to the bluetooth device?

    How can I send the .bin file over bluetooth?

    You refer to this https://www.ti.com/lit/an/slaa721e/slaa721e.pdf that using sub 1G.

    weather bluetooth will send the .bin file as hex bytes or do I need an external software for converting the .bin to hex bytes and transmit over bluetooth?

    In our demo code is use CCS generate TI-TXT format firmware and then convert it to header file that can be called by C code. We provide the python scripts to convert the firmware to the header file.

  • I mean, is it mandatory to use uart0 to send hex bytes, Or can I use uart1 also?

    My bluetooth is connected to uart1

    .hex file i tried to flash using uniflash but it didnot work.

    .txt I never used

  • I mean, is it mandatory to use uart0 to send hex bytes, Or can I use uart1 also?

    It's never mind. UART1 also OK.

    .hex file i tried to flash using uniflash but it didnot work.

    Try this way to generate the hex

    generate_hex file with CCS.pdf

  • Okay, Thanks. I will go through it and I will try to do.

  • Hi,

    I faced one more problem.

    Till now my code is working fine with uart0. When I eneabled uart1 and flashed code, then also with uart1 it's working fine. But when I remove the power cable and again reconnect it, whatever is there in flash it is not running. I need to flash the code again. What is happening I am not understanding

  • if i am pressing the reset button, then the code is running. is there any problem? Is there any connection in the launchpad , for which i need to press the reset button after adding uart1