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.

LP-MSPM0G3507: UART DMA TX can' work.

Part Number: LP-MSPM0G3507
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

 The source code of this issue as below:

#include "ti_msp_dl_config.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

volatile bool gCheckUART = false;
volatile bool gDMADone = false;
#define LOG_MAX_LENGTH 128

void UART_Console_Write(const char *data, ...)
{
    char log_buf[LOG_MAX_LENGTH] = { 0 };
    va_list args;
    va_start(args, data);
    vsnprintf(log_buf, LOG_MAX_LENGTH, data, args);
    va_end(args);

    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(log_buf));
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA));
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, strlen(log_buf));

    DL_SYSCTL_disableSleepOnExit();

    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    DL_UART_Main_enableDMATransmitEvent(UART_0_INST);

    while (false == gDMADone) {
        __WFE();
    }

    DL_UART_Main_disableDMATransmitEvent(UART_0_INST);

    while (false == gCheckUART) {
        __WFE();
    }

    gCheckUART = false;
    gDMADone = false;
}

int main(void)
{
    SYSCFG_DL_init();
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    DL_SYSCTL_disableSleepOnExit();
   
    UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);

    while (1) {
        ;
    }
}

void UART_0_INST_IRQHandler(void)
{
    switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
        case DL_UART_MAIN_IIDX_EOT_DONE:
            gCheckUART = true;
            break;
        case DL_UART_MAIN_IIDX_DMA_DONE_TX:
            gDMADone = true;
            break;
        default:
            break;
    }
}
But after add red words as below in main(), MCU and UART work normal.
int main(void)
{
    SYSCFG_DL_init();
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    DL_SYSCTL_disableSleepOnExit();
   
    UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
    UART_Console_Write("%s: %s %s\r\n", __FUNCTION__, __DATE__, __TIME__);

    while (1) {
        ;
    }
}
There are many cases to cause this issue. I found out SEGMENT ALLOCATION MAP in .map will become as below when this issue is happened
If this issue isn't happened SEGMENT ALLOCATION MAP in .map will be as blow:
Please help to fix this issue. Thank you!
  • This demo with single UART_Console_Write works fine from my side.

    I am using CCS 20.1.1.8

    Dependencies is

    SDK 2.4.0.6

    Sysconfig 1.22.0

    Compiler TI Clang 4.0.2 LTS

    uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.zip

    This may relates to compiler issue, you can try set optimization level to None in your dependencies environment, and test again.

    Or try my environment.

  • My environment:

    CCS: 20.1.1.8__1.7.1

    SDK: 2.4.0.06

    SysConfig is 1.22.0

    Compiler: TI Clang 4.0.2 LTS

    I had tried to set optimization level to 0 but the issue is still happened.

    Please modify main() as below:

    After build the segment allocation map will become as below:

    load .bin instead of .out file

  • What result do you see in the failure case?

    -----

    The extra line you see in the .map is a section alignment artifact, and is not significant.

    ------

    > DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    > DL_UART_Main_enableDMATransmitEvent(UART_0_INST);

    Try reversing these two lines (i.e. opposite order).

    -----

    Also, either (a) increase your stack size or (b) make log_buf[] a global/static.

  • > DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    > DL_UART_Main_enableDMATransmitEvent(UART_0_INST);

    Reverse these two lines is not work.

    Increase stack size or make log_buf[] a global/static is also not work.

    When this issue is happened no message is shown on the console.

    I2C is also used in our project. This problem also causes I2C to not work properly.

    Below video is to show this issue. 


  • Do you see any differences between Helic's project and yours? I'm supposing Helic started with the same C code, so sysconfig would be a place to look.

  • I used Helic's project directly.

    I only add two lines code in main() as below:

    Below is test results

    One Line is ok

        UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
    Two Lines is ok
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
    Three Lines is not ok
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
    Four Lines is not ok
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
    Five Lines is ok
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
    Six Lines is not ok
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s%s\r\n", __FUNCTION__, __TIMESTAMP__);
        UART_Console_Write("%s: %s\r\n", __FUNCTION__, __TIMESTAMP__);
    This issue can be reproduced without rules.
  • There are two potential point will cause this issue, compiler and event.

    Event:

    Please remove the UART Tx DMA event disable and enable function here:

    void UART_Console_Write(const char *data, ...)
    {
        char log_buf[LOG_MAX_LENGTH] = { 0 };
        va_list args;
    
        va_start(args, data);
        vsnprintf(log_buf, LOG_MAX_LENGTH, data, args);
        va_end(args);
    
        DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(log_buf));
        DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA));
        DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, strlen(log_buf));
    
        DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);
    
        while (false == gDMADone) {
            __WFE();
        }
    
        while (false == gCheckUART) {
            __WFE();
        }
    
        gCheckUART = false;
        gDMADone = false;
    }

    In this project, I test UART_Console_Write from 1 ~ 6 times, all works fine.

    1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.zip

    For compiler, I am using O2 in default

    I had tried to set optimization level to 0 but the issue is still happened.

    OK, fine.

    Please try to use a gcc version M0 project.

    You can import a gcc project and copy the source file and syscfg to gcc project.

  • This issue is still happened after remove the UART Tx DMA event disable and enable function.

    This time the issue is happened when UART_Console_Write() is executed 1, 2, and 5 times.

    Before remove the UART Tx DMA event disable and enable function, the issue is happened when UART_Console_Write() is executed 3, 4, and 6 times.

    I think you can't see this issue because you use .out file to load.

    You have to use .bin file to load if you want to see this issue.

    The project in the video is your project provided by you just now.

    This video shows the issue is happened when UART_Console_Write() is executed 1 time.

    Below video shows work well when UART_Console_Write() is executed 3 time.

    Both .bin and .out files work fine.

  • Let me ask compiler team for help.

    As the same time, please try this

    You can import a gcc project and copy the source file and syscfg to gcc project.
  • The issue is not happened on gcc project after I test UART_Console_Write() 1~15 times.

    Compiler: GNU v9.2.1

  • Great to hear this.

    Please use gcc.

    And waiting for some compiler team comments at the same time.

  • I can't use gcc because of some reasons.

    I think I need your compiler team to fix it.

    Thank you.

  • Let's waiting for the reply~

  • Please rebuild the entire project.  Then save the contents of a the Output View to a text file.  Attach that text file to your next post.

    Thanks and regards,

    -George

  • The file you requested is attached.

    [0]**** Clean-only build of configuration Debug for project uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang ****
    [1]"C:\\ti\\ccs2010\\ccs\\utils\\bin\\gmake" -k -j 12 clean -O 
     
    [2]DEL /F  "device.cmd.genlibs" "ti_msp_dl_config.h" "Event.dot"  "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.bin"  "device_linker.cmd" "device.opt" "ti_msp_dl_config.c"  "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" 
    [3]DEL /F "uart_tx_multibyte_fifo_dma_interrupts.o" "ti_msp_dl_config.o" "startup_mspm0g350x_ticlang.o" 
    [4]DEL /F "uart_tx_multibyte_fifo_dma_interrupts.d" "ti_msp_dl_config.d" "startup_mspm0g350x_ticlang.d" 
    [5]Finished clean
     
    [6]**** Build Finished ****
    
    [7]**** Build of configuration Debug for project uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang ****
    [8]"C:\\ti\\ccs2010\\ccs\\utils\\bin\\gmake" -k -j 12 all -O 
     
    [9]Building file: "../uart_tx_multibyte_fifo_dma_interrupts.syscfg"
    [10]Invoking: SysConfig
    [11]"C:/ti/sysconfig_1.22.0/sysconfig_cli.bat" --script "C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_tx_multibyte_fifo_dma_interrupts.syscfg" -o "." -s "C:/ti/mspm0_sdk_2_04_00_06/.metadata/product.json" --compiler ticlang
    [12]Running script...
    [13]Validating...
    [14]info: UART_0(/ti/driverlib/UART) DMA_CHANNEL_TX.channelID: Currently using a Full Channel.
    [15]Generating Code (uart_tx_multibyte_fifo_dma_interrupts.syscfg)...
    [16]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\device_linker.cmd...
    [17]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\device.opt...
    [18]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\device.cmd.genlibs...
    [19]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\ti_msp_dl_config.c...
    [20]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\ti_msp_dl_config.h...
    [21]Writing C:\_Tmp\Test\1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang\Debug\Event.dot...
    [22]Finished building: "../uart_tx_multibyte_fifo_dma_interrupts.syscfg"
     
    [23]Building file: "C:/ti/mspm0_sdk_2_04_00_06/source/ti/devices/msp/m0p/startup_system_files/ticlang/startup_mspm0g350x_ticlang.c"
    [24]Invoking: Arm Compiler
    [25]"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/bin/tiarmclang.exe" -c @"device.opt"  -march=thumbv6m -mcpu=cortex-m0plus -mfloat-abi=soft -mlittle-endian -mthumb -O2 -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang" -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/Debug" -I"C:/ti/mspm0_sdk_2_04_00_06/source/third_party/CMSIS/Core/Include" -I"C:/ti/mspm0_sdk_2_04_00_06/source" -gdwarf-3 -MMD -MP -MF"startup_mspm0g350x_ticlang.d_raw" -MT"startup_mspm0g350x_ticlang.o"  @"./device.opt"  -o"startup_mspm0g350x_ticlang.o" "C:/ti/mspm0_sdk_2_04_00_06/source/ti/devices/msp/m0p/startup_system_files/ticlang/startup_mspm0g350x_ticlang.c"
    [26]Finished building: "C:/ti/mspm0_sdk_2_04_00_06/source/ti/devices/msp/m0p/startup_system_files/ticlang/startup_mspm0g350x_ticlang.c"
     
    [27]Building file: "ti_msp_dl_config.c"
    [28]Invoking: Arm Compiler
    [29]"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/bin/tiarmclang.exe" -c @"device.opt"  -march=thumbv6m -mcpu=cortex-m0plus -mfloat-abi=soft -mlittle-endian -mthumb -O2 -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang" -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/Debug" -I"C:/ti/mspm0_sdk_2_04_00_06/source/third_party/CMSIS/Core/Include" -I"C:/ti/mspm0_sdk_2_04_00_06/source" -gdwarf-3 -MMD -MP -MF"ti_msp_dl_config.d_raw" -MT"ti_msp_dl_config.o"  @"./device.opt"  -o"ti_msp_dl_config.o" "ti_msp_dl_config.c"
    [30]Finished building: "ti_msp_dl_config.c"
     
    [31]Building file: "../uart_tx_multibyte_fifo_dma_interrupts.c"
    [32]Invoking: Arm Compiler
    [33]"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/bin/tiarmclang.exe" -c @"device.opt"  -march=thumbv6m -mcpu=cortex-m0plus -mfloat-abi=soft -mlittle-endian -mthumb -O2 -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang" -I"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/Debug" -I"C:/ti/mspm0_sdk_2_04_00_06/source/third_party/CMSIS/Core/Include" -I"C:/ti/mspm0_sdk_2_04_00_06/source" -gdwarf-3 -MMD -MP -MF"uart_tx_multibyte_fifo_dma_interrupts.d_raw" -MT"uart_tx_multibyte_fifo_dma_interrupts.o"  @"./device.opt"  -o"uart_tx_multibyte_fifo_dma_interrupts.o" "../uart_tx_multibyte_fifo_dma_interrupts.c"
    [34]Finished building: "../uart_tx_multibyte_fifo_dma_interrupts.c"
     
    [35]Building target: "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out"
    [36]Invoking: Arm Linker
    [37]"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/bin/tiarmclang.exe" @"device.opt"  -march=thumbv6m -mcpu=cortex-m0plus -mfloat-abi=soft -mlittle-endian -mthumb -O2 -gdwarf-3 -Wl,-m"uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.map" -Wl,-i"C:/ti/mspm0_sdk_2_04_00_06/source" -Wl,-i"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang" -Wl,-i"C:/_Tmp/Test/1212.uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang/Debug/syscfg" -Wl,-i"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/lib" -Wl,--diag_wrap=off -Wl,--display_error_number -Wl,--warn_sections -Wl,--xml_link_info="uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang_linkInfo.xml" -Wl,--rom_model -o "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" "./uart_tx_multibyte_fifo_dma_interrupts.o" "./ti_msp_dl_config.o" "./startup_mspm0g350x_ticlang.o" -Wl,-l"./device_linker.cmd"  -Wl,-ldevice.cmd.genlibs -Wl,-llibc.a 
    [38]Finished building target: "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out"
     
    [39]Building secondary target: "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.bin"
    [40]Invoking: Arm Hex Utility
    [41]"C:/ti/ccs2010/ccs/tools/compiler/ti-cgt-armllvm_4.0.2.LTS/bin/tiarmhex.exe" --diag_wrap=off --binary -o "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.bin"  "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" 
    [42]Translating to Binary format...
    [43]   "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" .intvecs ==&gt; .intvecs
    [44]   "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" .text ==&gt; .text
    [45]   "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" .rodata ==&gt; .rodata
    [46]   "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.out" .cinit ==&gt; .cinit
    [47]Finished building secondary target: "uart_log_tx_dmaInt_LP_MSPM0G3507_nortos_ticlang.bin"
     
    [48]**** Build Finished ****
    

  • Please do not use the hex utility to create the binary file.  Use tiarmobjcopy instead.  Here is a sample command:

    tiarmobjcopy -O binary executable_file.out binary_file.bin

    Thanks and regards,

    -George

  • Thank you for replying.

    I do know how to use this command because I am a beginner.

    I try to change the setting shown as figure.

    I think it is the same as this command because the issue will not be happened after .bin file is loaded  

    However, I have to check the bin file created by Arm Objcopy Utility can be used in our application because we planned a section of FLASH space to store data.

    In addition, in our application we will use the information in the .map file therefore I still have questions.

    When the issue is happened, the content of the .map file as below figure.

    Why length of 1 (0x22d0) is different with 2(0x22c0+0x18 = 0x22d8) in below figure? Which one is correct?

    Why the size of .bin file created by Arm Hex Utility is value 1 (0x22d0) but the size of .bin file created by Arm Objcopy utility is value 2(0x22d8)?

    When the issue is not happened, the content of the .map file shown as below figure.

    Obviously, value 1(0x22e8) and 2(0x22d0+0x18  = 0x22e8) are the same

    Why can't use Arm Hex Utility to create binary file? Is the issue is caused by Arm Hex Utility?

    Is it a workaround solution to use tiarmobjcopy  to create the binary file?

  • Your configuration of tiarmobjcopy is correct.

    Please read the article An Introduction to Binary Files.  Focus on the part titled Holes in a Binary File.  By default, tiarmhex ignores holes when creating a binary file.  There is a way to change this behavior.  But it is better to use tiarmobjcopy instead, which fills holes with zero.  In your case, I cannot identify the location of the holes from what you have shown so far.  But I'm confident one or more holes is present.

    Thanks and regards,

    -George

**Attention** This is a public forum