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.

MSPM0G3507: MSPM0 Live Firmware Update (LFU) Bootloader Implementation Problem.

Part Number: MSPM0G3507


Tool/software:

Hi, TI expertise

I am kindly asking for help to solve this situation.

Chip model: MSPM0G3507SRHBR [VQFN]

SDK version: 1.00.01.03

I am trying to use an example from the "MSPM0 Live Firmware Update (LFU) Bootloader Implementation" guide. 

First, I flash the Bootloader code into the chip. Then, I used the Python-based PC software provided in the example files. But it cannot identify a UART signal from the chip. When I do test with the MSPM0G3507 launch pad, it works.

In the example bootloader code, UART 0 is defined like this,

/* Defines for UART_0 */
#define UART_0_INST                                                        UART0
#define UART_0_INST_IRQHandler                                  UART0_IRQHandler
#define UART_0_INST_INT_IRQN                                      UART0_INT_IRQn
#define GPIO_UART_0_RX_PORT                                                GPIOA
#define GPIO_UART_0_TX_PORT                                                GPIOA
#define GPIO_UART_0_RX_PIN                                        DL_GPIO_PIN_11
#define GPIO_UART_0_TX_PIN                                        DL_GPIO_PIN_10
#define GPIO_UART_0_IOMUX_RX                                     (IOMUX_PINCM22)
#define GPIO_UART_0_IOMUX_TX                                     (IOMUX_PINCM21)
#define GPIO_UART_0_IOMUX_RX_FUNC                      IOMUX_PINCM22_PF_UART0_RX
#define GPIO_UART_0_IOMUX_TX_FUNC                      IOMUX_PINCM21_PF_UART0_TX
#define UART_0_BAUD_RATE                                                  (9600)
#define UART_0_IBRD_32_MHZ_9600_BAUD                                       (208)
#define UART_0_FBRD_32_MHZ_9600_BAUD                                        (21)

But in our design, we use these pins for UART,

I think this is the problem with UART communication. Help me to change this pin mux configuration. But this example project does not have a "System Configuration" to set up or change any configuration.

  • Hi Kaushika,

    The LFU is used with ROM based BSL, so the pinmux of MSPM0 and baud rate is fixed.

    If want to use differernt pin, then you need modify the NONMAIN of MSPM0.

    If want to use different baud rate, you can either use flash UART pulgin interface, or use BSL command to dynamically modify the UART baud rate.

    Directly change the LFU code doesn't work, we should configure both to take effect.

    B.R.

    Sal

  • I resolved the above problem, successfully changed the UART pins.

    I also changed the LEDs to RGB in the application code for the MSPM0 launchpad and turned off the Red LED blink. But the Red LED blinking of the bootloader code is still working. I think the bootloader is still working in parallel with the application code. 

    I also need to use UART communication in the application. How to do it while the bootloader is also looking for UART receive.

    I have uncommented these lines and modified the application as below. Then I can use UART for the application code. But I cannot wake the bootloader again.

    SCB->VTOR = APP_AREA_1_START_ADDR;

    SCB->VTOR = APP_AREA_2_START_ADDR;

    void main_tasks_create(void)
    {
        /* Create the queue. */
        xQueue = xQueueCreate(mainQUEUE_LENGTH, sizeof(uint32_t));
    
        if (xQueue != NULL) {
            /*
             * Start the two tasks as described in the comments at the top of this
             * file.
             */
            xTaskCreate(
                    prvBootloader_Task, /* The function that implements the task. */
                    "BSL", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
                    configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
                    NULL, /* The parameter passed to the task - just to check the functionality. */
                    mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
                    &Bootloader_Handler); /* The task handle is not required, so NULL is passed. */
    
            xTaskCreate(
                    prvRTOS_LED0_Toggle_Task,
                    "LED",
                    configMINIMAL_STACK_SIZE,
                    (void *) mainQUEUE_SEND_PARAMETER,
                    mainQUEUE_SEND_TASK_PRIORITY,
                    &RTOS_LED_Toggle_Handler);
    //        BSL_PI_sendByte(0xBB);
            app_area_flag = TI_MSPBoot_AppMgr_AppisValid();
    //        app_area_flag = 1;
            BSL_PI_sendByte(app_area_flag);
            switch (app_area_flag)
            {
                case 1:
                    xTaskCreate(
                            (TaskFunction_t)(*(uint32_t *)(APP_AREA_1_START_ADDR + 4)),
    //                        prvRTOS_LED0_Toggle_Task2,
                            "App",
                            config_test_STACK_SIZE,
                            NULL,
                            mainQUEUE_SEND_TASK_PRIORITY,
                            &App_Handler);
                    vTaskSuspend(Bootloader_Handler);
                    SCB->VTOR = APP_AREA_1_START_ADDR;
    //                BSL_PI_sendByte(0x11);
                    break;
                case 2:
                    xTaskCreate(
                            (TaskFunction_t)(*(uint32_t *)(APP_AREA_2_START_ADDR + 4)),
                            "App",
                            config_test_STACK_SIZE,
                            NULL,
                            mainQUEUE_SEND_TASK_PRIORITY,
                            &App_Handler);
                    vTaskSuspend(Bootloader_Handler);
                    SCB->VTOR = APP_AREA_2_START_ADDR;
                    break;
                default:
                    break;
            }
     //       BSL_PI_sendByte(0x22);
            /* Start the tasks. */
            vTaskStartScheduler();
        }
    
        /*
         * If all is well, the scheduler will now be running, and the following
         * line will never be reached.  If the following line does execute, then
         * there was insufficient FreeRTOS heap memory available for the idle
         * and/or timer tasks to be created.  See the memory management section on
         * the FreeRTOS web site for more details.
         */
        for (;;)
            ;
    }

    Below is the modified application code. Its UART echo is working, but the LED blinking is not working. LEDs are working without the UART functions.

    #include "ti_msp_dl_config.h"
    
    #define APP_AREA_1_START_ADDR       0x4000
    
    volatile uint8_t gEchoData = 0;
    
    void Delay_for_tasks_switch(uint32_t delay_ms);
    
    int main(void)
    {
        SYSCFG_DL_init();
    
        SCB->VTOR = APP_AREA_1_START_ADDR;
    
        NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
    
        DL_TimerG_startCounter(TIMER_0_INST);
    
        /*  UART Initializing */
            // RX interrupt is enabled
            DL_UART_Main_enableInterrupt(UART_0_INST, DL_UART_MAIN_INTERRUPT_RX);
            NVIC_ClearPendingIRQ(UART_0_INST_INT_IRQN);
            NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
            delay_cycles(160000);
    
        while (1) {
            Delay_for_tasks_switch(1000);//must be call for tasks switch.
    
            DL_GPIO_togglePins(GPIO_GRP_0_PORT, GPIO_GRP_0_RGB_B_PIN);
            delay_cycles(16000000);
            DL_GPIO_togglePins(GPIO_GRP_0_PORT, GPIO_GRP_0_RGB_R_PIN);
            delay_cycles(16000000);
        }
    }
    
    
    void Delay_for_tasks_switch(uint32_t delay_ms)
    {
        ((void (* )(uint32_t xTicksToDelay))(*(uint32_t *)(0x3FF0)))(delay_ms);
    }
    
    
    void UART_0_INST_IRQHandler(void)
    {
        uint32_t intSource = DL_UART_Main_getPendingInterrupt(UART_0_INST);
    
        switch (intSource) {
            case DL_UART_MAIN_IIDX_RX:
                gEchoData = DL_UART_Main_receiveData(UART_0_INST);
    
                // Echo back the character
                DL_UART_Main_transmitData(UART_0_INST, gEchoData);
    
                break;
            default:
                break;
    
        }
    }

    How to suspend the bootloader while running application codes, and wake when needed to update firmware.

    I also tried to create a new application code with .syscfg. Also added necessary things. It was downloaded properly through the GUI. But did not work. 

    Please help resolve this.

  • Hi Kaushika,

    How to suspend the bootloader while running application codes, and wake when needed to update firmware.

    I checked the documents of LFU, it will automatically suspend the bootloader when execute app.

    And if it wrong to execute the app, I recommned you check the app you loaded (read it by debugger) and check whether it has any issues.

    The basic principle is that:

    boot will check the app status, and enable the avaiable app. After the app start to execute, boot will be suspended.

    I also need to use UART communication in the application. How to do it while the bootloader is also looking for UART receive.

    The reference project does not support use the same peripheral in boot and app both.

    B.R.

    Sal