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.

MSP430F5659: Seeking Help with UART Interrupt Mode for Transmitting and Receiving Large Data Sets

Part Number: MSP430F5659
Other Parts Discussed in Thread: MSPM0G3507

Hello TI community,

I am currently working on a project that involves implementing UART communication in interrupt mode on a TI platform. I am using MSP430 microcontroller and need assistance in handling both the transmission and reception of data, particularly when dealing with data sets of up to 256 bytes.

Here are the key points of my inquiry:

  1. Initialization and Configuration: I would like guidance on the correct initialization and configuration steps for setting up UART communication in interrupt mode.

  2. Interrupt Service Routine (ISR): How should I structure the ISR for both transmitting and receiving data? Are there any best practices or specific considerations when working with large data sets (up to 256 bytes)?

  3. Buffer Management: What is the recommended approach for managing data buffers, considering the potential size of up to 256 bytes? Should I implement circular buffers, and if so, what size would be optimal?

  4. Error Handling: Are there specific error-handling techniques I should implement, especially when dealing with long data transmissions and receptions?

I appreciate any insights, code snippets, or references to relevant documentation that can help me tackle this challenge effectively.

Thank you in advance for your assistance.

Baseer

  • Have you looked at the examples in resource explorer? They can get you started.

    While not TI, this is a good reference:

    http://www.simplyembedded.org/tutorials/msp430-uart/

    As for buffer size, that is up to your application, and how quickly you are expecting the data. Same with errors.

  • Thanks for your kind response. I expect to send a larger set of data approx 112640 bytes and in minimum possible time, same with reception.

  • The question is how quickly you can deal with the data. If the bytes come in once per second, the MCU can deal with them even without a buffer. If they come in at at 4 Megabytes per second, the MCU might not be able to keep up with or without a buffer.

  • Well I need to communicate with the software through UART when I get request from software. So its not a mission critical system, I just need to send the data to software in minimum possible time. If I send data byte by byte it will take more time. So I might need to send chunk wise keeping in mind the error maybe I need to send CRC to verify the validity of data. So the if the data is 112640 bytes and I send byte by byte it will take much more time, so my question is can I send data in chunk of lets say 256 bytes etc. Did you got my point? 

  • If you queue it up right, sending data "byte by byte" should take no more time than sending 256 byte chunks, though you can set things up to send the chunks automagically. Here is my string sending routine:

    The kick starter:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void StartSerialTX(char *str) {
    while (TXChar != -1) {
    // wait for previous tx to finish
    Delay(10);
    }
    strcpy(TXData, str);
    TXChar = 0;
    DL_UART_Main_transmitData(UART_0_INST, TXData[TXChar++]);
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    And the interrupt:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    void UART_0_INST_IRQHandler(void) {
    switch (DL_UART_Main_getPendingInterrupt(UART_0_INST)) {
    case DL_UART_MAIN_IIDX_RX:
    RXdata = DL_UART_Main_receiveData(UART_0_INST);
    // DL_UART_Main_transmitData(UART_0_INST, RXdata);
    break;
    case DL_UART_MAIN_IIDX_TX:
    if (TXData[TXChar] != '\0') {
    DL_UART_Main_transmitData(UART_0_INST, TXData[TXChar++]);
    } else {
    TXChar = -1;
    }
    break;
    default:
    break;
    }
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Where TXChar is the index into the string (-1 and 0 are sentinal values, too) and TXData is the data array.

    This is for an MSPM0G3507, but you would do something similar for any MSP, look at the example for your device.

  • It is theoretically possible to run the UART at full speed using software (byte-by-byte) but it's not easy. I think what you want is the DMA, which uses hardware to service the TXBUF and RXBUF quickly. The DMA can transfer up to 64KB (DMASZ register) in a block, but with only 64KB SRAM you won't achieve that.

    The Tx side is straightforward: Put the bytes in memory, set DMAEN=1, then recognize the completion in an ISR.

    The Rx side may require a little more work since the DMA wants to operate in fixed-size blocks. If your Rx blocks vary in size (or if you allow for bytes to get lost) you need to implement a timeout to deal with short blocks. There's also no reason you couldn't do Tx with the DMA and Rx byte-by-byte.

    You can get some idea of the mechanics from TI Example msp430f665x_dma_02.c, here:

    https://dev.ti.com/tirex/explore/node?node=A__AOA7HJs5vP6JteXGeExmkQ__msp430ware__IOGqZri__LATEST

    This example uses a timer to meter out the bytes (4 per second), which isn't the usual way one would do this, but you can see what registers are involved.

**Attention** This is a public forum