Browse Source

Teensy 2 - Serial1.write() - maybe bypass queue

Add same speedup from Arduino core, that on Serial1.write, check to see
if output queue is empty and data register empty, if so simply stuff the
character out in the output queue, without needing to use interrupt to
start transmission.  Helps speed up fast IO like 1MBS

Also, changed how UCSR1B is updated, to be like Arduino.  In particular
it turns on and off specific bit(s) instead of complete set of register.
Needed if you wish to emulate half duplex with this uart.
main
Kurt Eckhardt 8 years ago
parent
commit
a4a65a44ed
1 changed files with 16 additions and 2 deletions
  1. +16
    -2
      teensy/HardwareSerial.cpp

+ 16
- 2
teensy/HardwareSerial.cpp View File

#include <avr/interrupt.h> #include <avr/interrupt.h>
#include "core_pins.h" #include "core_pins.h"
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "wiring_private.h"


#define RX_BUFFER_SIZE 64 #define RX_BUFFER_SIZE 64
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
if (tx_enable_pin < 255 && !transmitting) { if (tx_enable_pin < 255 && !transmitting) {
digitalWrite(tx_enable_pin, HIGH); digitalWrite(tx_enable_pin, HIGH);
} }
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if (tx_buffer_head == tx_buffer_tail && bit_is_set(UCSR1A, UDRE1)) {
UDR1 = c;
transmitting = 1;
return 1;
}

i = tx_buffer_head + 1; i = tx_buffer_head + 1;
if (i >= TX_BUFFER_SIZE) i = 0; if (i >= TX_BUFFER_SIZE) i = 0;
while (tx_buffer_tail == i) ; // wait until space in buffer while (tx_buffer_tail == i) ; // wait until space in buffer
tx_buffer[i] = c; tx_buffer[i] = c;
transmitting = 1; transmitting = 1;
tx_buffer_head = i; tx_buffer_head = i;
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1) | (1<<UDRIE1);
//UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1) | (1<<UDRIE1);
sbi(UCSR1B, UDRIE1);

#if ARDUINO >= 100 #if ARDUINO >= 100
return 1; return 1;
#endif #endif


if (tx_buffer_head == tx_buffer_tail) { if (tx_buffer_head == tx_buffer_tail) {
// buffer is empty, disable transmit interrupt // buffer is empty, disable transmit interrupt
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
//UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
cbi(UCSR1B, UDRIE1);
} else { } else {
i = tx_buffer_tail + 1; i = tx_buffer_tail + 1;
if (i >= TX_BUFFER_SIZE) i = 0; if (i >= TX_BUFFER_SIZE) i = 0;

Loading…
Cancel
Save