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.

MSPM0G1507: Enabling GPIO Pin PA8 output hangs the application only when it is uploaded through bootloader

Part Number: MSPM0G1507


Tool/software:

Hi,

in my current project, I developed custom flashed based secondary bsl and using it to upload application via UART serial comms.

But my intention is to go into the bsl when the device is powered on so I located BSL at 0x00000000 of flash and located Application code at 0x00002000.

Inside the BSL application, PA8 is used as GPIO output and set HIGH so as to enable the "output" IC's UART function and upload the APP code. Once the uploading and verification  process have been done, the BSL will jump to the valid application start address.

But in the application code, I found out that the program "hangs" once this PA8 is initialized as GPIO output. To address the issue I disabled the PA8 digital output and upload the application code again and it worked as intended.

The strange issue is that I can enable PA8 digital output if I flash directly to the device without bootloader on another device, i.e. the application code starts at 0x00000000 as usual, and the application code works well again.

So the issue exists only if I upload the code through bootloader. 

What would be the reason? Is there something that I missed? Please advise and thanks so much in advance. Slight smilePray

  • Hi,

    What pin are you using to invoke the BSL?

    -Matthew

  • Hi Matthew, my apology for the late reply.
    I don't use GPIO to invoke the BSL. The BSL is at 0x00000000 so the BSL will be invoked whenever the power resets. I make it in this way so that BSL will be invoked even if the application is hanged and watchdog triggers the power reset. 

  • Could you describe what happens when the code hangs?

    Would you be able to share your code?

  • Hi Matthew, 

    sorry that I can't share the full application code,

    but this is the GPIO Init function (which I implemented in the application code instead of configuring in SysCfg order to find out the root cause.)

    void Appl_Output_GPIO_Init ()
    {
        DL_GPIO_initDigitalOutputFeatures(IOMUX_PINCM19,
    		 DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
    		 DL_GPIO_DRIVE_STRENGTH_HIGH, DL_GPIO_HIZ_DISABLE);
    
        DL_GPIO_initDigitalOutputFeatures(IOMUX_PINCM14,
    		 DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_NONE,
    		 DL_GPIO_DRIVE_STRENGTH_LOW, DL_GPIO_HIZ_ENABLE);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM19);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM1);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM10);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM8);
    
        DL_GPIO_initDigitalOutput(IOMUX_PINCM11);
    
        DL_GPIO_clearPins(GPIOA, DL_GPIO_PIN_8 |
        	DL_GPIO_PIN_7 |
    		DL_GPIO_PIN_0 |
    		DL_GPIO_PIN_5 |
    		DL_GPIO_PIN_3 |
    		DL_GPIO_PIN_6);
        DL_GPIO_setPins(GPIOA, DL_GPIO_PIN_7);
    
    
        DL_GPIO_enableOutput(GPIOA, //DL_GPIO_PIN_8 |
        	DL_GPIO_PIN_7 |
    		DL_GPIO_PIN_0 |
    		DL_GPIO_PIN_5 |
    		DL_GPIO_PIN_3 |
    		DL_GPIO_PIN_6);
    
    
    }

    As you see in the above function, If I comment out "enabling output" pin 8 as in line num 30 in the above code, the application runs successfully which means the device can shows the measured data on the OLED Monochrome Display continuously.

    But if I uncomment back this function, the device's OLED will show nothing.

    To verify this point, I added blinking led before this function is invoked and I can see the led blink.

    But if I put the blinking led function below this GPIO_Init , then I can't even see the blinking led when the device is powered up. 

  • Hi,

    Can you show me how you are jumping to your application code?

    -Matthew

  • Hi Matthew, 

    void CMD_API_startApplication(void)
    {
                //Check Marker Byte and Branch to app only it's correct
                if( (*(uint8_t*)(APP_UPDATE_MARKER_BYTE_ADDRESS))==APP_UPDATE_MARKER_BYTE)
                {
                    /* Start application */
                    DL_SYSCTL_resetDevice(SYSCTL_RESETLEVEL_LEVEL_BOOT);     
                    /* Wait until reset happens */
                    while (1)
                        ;
                }
    }

  • Make sure that your VTOR is pointing to the start of your application memory. Here is an example that shows how: 

    dev.ti.com/.../node

  • Hi Matthew, 

    thanks so much for the reply. 
    I actually copy and paste the startup file into the project directory, uncheck "Startup file Reference" in Syscfg file and this is what I added in the ResetHandler function in the startup .c file.

    /* Forward declaration of the default fault handlers. */
    /* This is the code that gets called when the processor first starts execution */
    /* following a reset event.  Only the absolutely necessary set is performed,   */
    /* after which the application supplied entry() routine is called.  Any fancy  */
    /* actions (such as making decisions based on the reset cause register, and    */
    /* resetting the bits in that register) are left solely in the hands of the    */
    /* application.                                                                */
    void Reset_Handler(void)
    {
        /* Jump to the ticlang C Initialization Routine. */
        SCB->VTOR = (volatile uint32_t) interruptVectors;
        __asm(
            "    .global _c_int00\n"
            "    b       _c_int00");
    }

    and this is the .cmd file I used for the application.

    /*****************************************************************************
    
      Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
    
      Redistribution and use in source and binary forms, with or without
      modification, are permitted provided that the following conditions
      are met:
    
       Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.
    
       Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the
       distribution.
    
       Neither the name of Texas Instruments Incorporated nor the names of
       its contributors may be used to endorse or promote products derived
       from this software without specific prior written permission.
    
      THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    
    *****************************************************************************/
    -uinterruptVectors
    --stack_size=512
    
    MEMORY
    {
        INT_VECS		(RX)  : origin = 0x00002000, length = 0x000000C0
        FLASH           (RX)  : origin = 0x000020C0, length = 0x0001DF40
        SRAM            (RWX) : origin = 0x20200000, length = 0x00008000
        BCR_CONFIG      (R)   : origin = 0x41C00000, length = 0x00000080
        BSL_CONFIG      (R)   : origin = 0x41C00100, length = 0x00000080
    
    }
    
    SECTIONS
    {
        .intvecs:   > INT_VECS
        .marker:  > 0x0001FFF0
        .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, table(BINIT)
    
        .vtable :   > SRAM
        .args   :   > SRAM
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM (HIGH)   
    
        .BCRConfig  : {} > BCR_CONFIG
        .BSLConfig  : {} > BSL_CONFIG
    }


    I locate the application interrupt vector at 0x00002000 in the cmd file which is where the correct application exists.

  • Has your issue been resolved? (I was out of office for some time, so my apologies for the delay)