Transmitting uint8_t array via USART

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm dealing with a situation where I'm attempting to transmit a continuous stream of audio into a uint8_t array via USART so that it can be read into an encryption method (particularly tinyAES) that takes in said uint8_t array. I'm attempting to transmit the array in a per byte basis using UDR0 and storing each received byte into an array on my receiving micro controller. Particularly, I'm using this type of method to transmit data, which is fairly straightforward:

void transmit_part(unsigned char data) {
  while(!(UCSR0A & (1 << UDRE0)));

  UDR0 = data; 
}

I have the value from an index in the uint8_t array casted as unsigned char which I figured shouldn't be a problem since they seem to be essentially the same based off what I've looked up. And on the receiving micro controller, I have the following:

ISR(USART0_RX_vect){
  if (received_cnt != 64) {
    received = receive_data();
    received_block[received_cnt] = (uint8_t) received;
    received_cnt++;
  }
}

where receive_data() just returns UDR0 and I'm essentially casting the unsigned char from UDR0 back to uint8_t. Once the counter reaches 64, I pass off the block to the encryption functions. Is there a better way to set this up? I'm uncertain of how to efficiently transmit this data without creating a noticeable delay.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do you synchronise the data?

With any form of transmission, you have a transport delay. You decide if the delay is acceptable or not.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sublime wrote:

 I'm uncertain of how to efficiently transmit this data without creating a noticeable delay.

 

 Define `efficiently'. Do you want it simple in terms of HW connections? Or to have faster data rates? To consume less CPU cycles or energy?

 UART is byte-oriented and adds an overhead. You may wish to consider interrupt-driven architecture on either end, depending on application requirements.

 SPI is also byte-oriented but it does not send frame bits. Requires more HW lines than UART.

 


Qoitech AB, The Home of Otii Arc, an SMU for every developer

Check out Otii solution at www.qoitech.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The casting has no runtime overhead.

 

But:

    received = receive_data();
    received_block[received_cnt] = (uint8_t) received;

Why not just have receive_data() return uint8_t in the first place?

 

Note that the assignment to 'received'  is superfluous - but the compiler will probably optimise it out anyhow:

    received_block[received_cnt] = receive_data();

 

receive_data() just returns UDR0

So that adds a bit of overhead. Making it inline would help. 

 

But the big thing is:

via USART

Remember that USARTs are slow relative to CPU operation!

 

One thing that may help system performance is to have two buffers - so that you can be filling one while processing the other...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yabusame wrote:
SPI is also byte-oriented

SPI itself is not byte-oriented, thought the (unspecified) microcontroller's SPI peripheral might be ...

 

 

The fact that the microcontroller is unspecified, and this is posted under 'General Programming', raises the question of whether DMA may be available ... ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Yabusame wrote:
SPI is also byte-oriented

SPI itself is not byte-oriented, thought the (unspecified) microcontroller's SPI peripheral might be ...

 

 That's true.

 Anyway, if it's a non-streaming UART, then looping for UDRE on Tx end and interrupting on Rx is the most optimal approach. Implementation details will vary. As encryption operates on 64-byte blocks, DMA may become handy.

 


Qoitech AB, The Home of Otii Arc, an SMU for every developer

Check out Otii solution at www.qoitech.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yabusame wrote:
looping for UDRE on Tx end and interrupting on Rx is the most optimal approach

Why not interrupt-driven Tx ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

Yabusame wrote:
looping for UDRE on Tx end and interrupting on Rx is the most optimal approach

Why not interrupt-driven Tx ?

 

 Just a suggestion. I suppose that Tx side knows when it has at least 64 bytes ready to be sent and will send them one-by-one in a stream, without waiting for the next byte. UDRE loop, however, still can be interrupted by other tasks, eg when (64+n)th byte is ready. We can increase CPU speed to send at relatively high rate, then slow down and turn USART off until the next batch is ready.

 


Qoitech AB, The Home of Otii Arc, an SMU for every developer

Check out Otii solution at www.qoitech.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It was more than "just a suggestion" - you specifically said it was "the most optimal approach"

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

It was more than "just a suggestion" - you specifically said it was "the most optimal approach"

 

 The requirements were a suggestion.

 


Qoitech AB, The Home of Otii Arc, an SMU for every developer

Check out Otii solution at www.qoitech.com