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-MSPM0L1306: LP-MSPM0L1306

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

Tool/software:

The following code stops transmitting after some time, I have tried to solve the problem but have been unable to. Need help regarding this.


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

uint8_t gWelcomeMsg[] = "\r\n==== MSPM0 Console Test ====\r\n";
uint8_t gTestingMsg[] = "> Testing...0\r\n";

volatile bool gConsoleTxTransmitted, gConsoleTxDMATransmitted, gTransmitReady;

void UART_Console_write(const uint8_t *data, uint16_t size)
{
    printf("Starting DMA transmission: %s\n", data);  // Debug log

    DL_DMA_disableChannel(DMA, DMA_CH0_CHAN_ID);

    DL_DMA_setSrcAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(data));
    DL_DMA_setDestAddr(DMA, DMA_CH0_CHAN_ID, (uint32_t)(&UART_0_INST->TXDATA));
    DL_DMA_setTransferSize(DMA, DMA_CH0_CHAN_ID, size);

    DL_SYSCTL_disableSleepOnExit();

    DL_DMA_enableChannel(DMA, DMA_CH0_CHAN_ID);

    while (false == gConsoleTxDMATransmitted) {
        printf("Waiting for DMA TX...\n");  // Debug log
    }

    while (false == gConsoleTxTransmitted) {
        printf("Waiting for UART TX...\n");  // Debug log
    }

printf("DMA transmission complete\n");  // Debug log

gConsoleTxTransmitted    = false;
gConsoleTxDMATransmitted = false;
   
}

int main(void)
{
    gTransmitReady           = false;
    gConsoleTxTransmitted    = false;
    gConsoleTxDMATransmitted = false;
    uint32_t increment       = 0;

    SYSCFG_DL_init();
    NVIC_EnableIRQ(UART_0_INST_INT_IRQN);
    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);


    /* Write welcome message */
    UART_Console_write(&gWelcomeMsg[0], sizeof(gWelcomeMsg));

    while (1) {
        if (gTransmitReady == true) {
            /* Will output "Testing...0", "Testing...1", etc. and loop after 9 */
            gTransmitReady  = false;
            gTestingMsg[12] = '0' + increment;
            increment       = (increment + 1) % 10;
            UART_Console_write(&gTestingMsg[0], sizeof(gTestingMsg));
        } else {
            __WFI();
        }
    }
}

void UART_0_INST_IRQHandler(void)
{

printf("UART IRQ: %d\n", DL_UART_Main_getPendingInterrupt(UART_0_INST));  // Debug log

    switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
        case DL_UART_MAIN_IIDX_EOT_DONE:
            gConsoleTxTransmitted = true;
            break;
        case DL_UART_MAIN_IIDX_DMA_DONE_TX:
            gConsoleTxDMATransmitted = true;
            break;
        case DL_UART_IIDX_OVERRUN_ERROR:  // Handle overrun errors
            printf("UART Overrun Error! Resetting...\n");
            break;
        case DL_UART_IIDX_NOISE_ERROR:  // Handle noise errors
            printf("UART Noise Error!\n");
            break;
        default:
            printf("Unexpected UART interrupt");
            break;
    }
}

void TIMER_0_INST_IRQHandler(void)
{
    switch (DL_Timer_getPendingInterrupt(TIMER_0_INST)) {
        case DL_TIMER_IIDX_ZERO:
            gTransmitReady = true;
            DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN | GPIO_LEDS_USER_TEST_PIN);
            printf("Timer interrupt\n");
            break;
        default:
            break;
    }
}


  • Hi Dheeraj,
    I would start by updating the software you are using to the latest CCS, M0SDK, and SYSCONFIG. If that doesn't help, I recommend tracking down where specifically your code gets stuck.
    Best Regards,
    Diego Abad

  • What are

    1) Your Timer_0 period?

    2) Your UART bit-rate?

    Your timer period should be fairly long (maybe 500ms) to accommodate all those printf() calls. You should not call printf()  in an ISR (though sometimes it sort of works).

    -------------------

    > printf("UART IRQ: %d\n", DL_UART_Main_getPendingInterrupt(UART_0_INST)); // Debug log
    > switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {

    Reading the IIDX register clears the interrupt, so if you call it twice you'll (in general) get different results. In this sequence you throw away the first interrupt -- in this case the DMA_DONE -- so your UART_Console_write function will never complete. Try instead something like:

    > uint32_t IIDX = DL_UART_Main_getPendingInterrupt(UART_0_INST);
    > printf("UART IRQ: %d\n", IIDX); // Debug log
    > switch (IIDX) {
    -------------------

    When I set UART0 for 9600bps, the timer period to 500ms, and made the change above, it works fine for me (~10 minutes so far).

  • Will definitely try it

  • Hi Dheeraj, 

    Let me know if you need further help in this thread.

    Best Regards,

    Diego Abad