This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Tiva TM4C123G UART transmission

Hello everybody, I am currently programming a Tiva C series, TM4C123GH6PM Evaluation Board from TI.

I need to send a relatively large amount of data to the virtual com of the PC. This board has an integrated virtual com feature (as soon as you plug the usb, and install the drivers, a virtual COM is generated).

I've configured the UART0 peripheral, and used the UARTprintf command, and it works properly.

But, as far as I know, this is only for strings/chars types. I need to send an array of 300 elements, made by 16-bit registers.

I've read about the UART, and the uDMA feature. I don't know if activating the DMA is necessary in this type of transfers, or if it's enough with a while loop. I've seen a lot of code-examples, and read the TI forum, but I'vve found nothing like what I need. In every example I saw, they just use the UART to echo what you sent from the PC.

Can anybody give me a hint on where to start?
I'm not asking for anybody to solve this for me, only perhaps to point me in the right direction.
Thanks a lot for taking the time to read this.
Kind regards

Martín

Parents
  • The UART doesn't care what you send. It will try to send anything you put into the transmit register.

    But the transmit register is small, and you have a limited number of data bits you can program the UART to send.

    So you would normally settle for "standard" 8N1 format, i.e. 8 data bits, no parity and one stop bit.

    So sending raw data?

    You either convert to ASCII:

    #define NELEM(a) (sizeof(a)/sizeof(*(a)))
    ...
    uint16_t array[400] = { ... };
    ...
    printf("start-uint16-array:\n");
    for (unsigned i = 0; i < NELEM(array); ++i) {
        printf("%u\n",array[i]);
    }
    printf("\n");
    

    Or you make up some fancy binary protocol, and then send the data as binary, and then convert all your binary data into 8-bit bytes that you send one-by-one. Using DMA or feeding multiple bytes at a time using a UART with FIFO or feeding a single byte at a time directly to the transmit register doesn't matter.

    Let's say that putc(int) will redirect to your UART.

    Then you could do:

    void send_u16(uint16_t n) {
        putc(n&0xff);
        putc((n >> 8) & 0xff);
    }
    void send_u32(uint32_t n) {
        putc(n&0xff);
        putc((n >> 8) & 0xff),
        putc((n >> 16) & 0xff);
        putc((n >> 24) & 0xff);
    }
    ...
    

    But it's normally way easier to go with ASCII and then use sscanf(), atoi() etc to restore to binary format on the receiving end. Then normal line breaks works well for framing of the data.

    Another issue here is that if you want to send floating point data, then the sending side and the receiving side might use different binary storage methods for the same number in which case it isn't enough to just split a float into four bytes or a double into 8 bytes. And strictly speaking - the same is true for int types too even if the huge majority of all of todays processors uses the traditional two-complement format for signed integers, and make them 8, 16, 32, 64 bit large so you "only" need to care about byte order - which is trivial to handle if you pre-define a transmission order instead of sending in "memcpy()" order.

Reply
  • The UART doesn't care what you send. It will try to send anything you put into the transmit register.

    But the transmit register is small, and you have a limited number of data bits you can program the UART to send.

    So you would normally settle for "standard" 8N1 format, i.e. 8 data bits, no parity and one stop bit.

    So sending raw data?

    You either convert to ASCII:

    #define NELEM(a) (sizeof(a)/sizeof(*(a)))
    ...
    uint16_t array[400] = { ... };
    ...
    printf("start-uint16-array:\n");
    for (unsigned i = 0; i < NELEM(array); ++i) {
        printf("%u\n",array[i]);
    }
    printf("\n");
    

    Or you make up some fancy binary protocol, and then send the data as binary, and then convert all your binary data into 8-bit bytes that you send one-by-one. Using DMA or feeding multiple bytes at a time using a UART with FIFO or feeding a single byte at a time directly to the transmit register doesn't matter.

    Let's say that putc(int) will redirect to your UART.

    Then you could do:

    void send_u16(uint16_t n) {
        putc(n&0xff);
        putc((n >> 8) & 0xff);
    }
    void send_u32(uint32_t n) {
        putc(n&0xff);
        putc((n >> 8) & 0xff),
        putc((n >> 16) & 0xff);
        putc((n >> 24) & 0xff);
    }
    ...
    

    But it's normally way easier to go with ASCII and then use sscanf(), atoi() etc to restore to binary format on the receiving end. Then normal line breaks works well for framing of the data.

    Another issue here is that if you want to send floating point data, then the sending side and the receiving side might use different binary storage methods for the same number in which case it isn't enough to just split a float into four bytes or a double into 8 bytes. And strictly speaking - the same is true for int types too even if the huge majority of all of todays processors uses the traditional two-complement format for signed integers, and make them 8, 16, 32, 64 bit large so you "only" need to care about byte order - which is trivial to handle if you pre-define a transmission order instead of sending in "memcpy()" order.

Children