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
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.
Just an addendum - if writing binary data to the UART, then it's normally better to directly make use of the UART than using any "stdout redirection" because different CRTL have different behaviour when processing received some "non-text" characters. So the single character representing newline (\n) can be replaced with the sequence \r\n as in Carriage Return + Line Feed, in the output stream. When using fopen(), the last parameter allows specifying text or binary mode - but with "stdout" you don't do any file open.
And, of course, 'C' string functions expect NUL to indicate the end of the string - so you can't use them for any binary data handling!
View all questions in Keil forum