diff --git a/serial.cpp b/serial.cpp index 4c7cd5d..a848664 100644 --- a/serial.cpp +++ b/serial.cpp @@ -1,18 +1,27 @@ #include "serial.h" -#include "ringbuffer.h" - -volatile RingBuffer rxBuffer; - -bool stopped = false; ISR(USART_RX_vect) //I have seen worse interrupt sintax { - rxBuffer.write(UDR0); - if(serialFlowControl && !stopped && rxBuffer.remainingCapacity() < 32) + Serial* serial = Serial::getInstance(); + serial->rxBuffer.write(UDR0); + if(serialFlowControl && !serial->stopped && serial->rxBuffer.remainingCapacity() < 32) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = 0x13; - stopped = true; + serial->stopped = true; + } +} + +ISR(USART_TX_vect) +{ + Serial* serial = Serial::getInstance(); + if(!serial->txBuffer.isEmpty()) + { + UDR0 = serial->txBuffer.read(); + } + else + { + serial->transmitting = false; } } @@ -22,14 +31,38 @@ Serial::Serial() UBRR0L = UBRRL_VALUE; UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); UCSR0B = _BV(RXEN0) | _BV(TXEN0); //Enable RX and TX - UCSR0B |= (1 << RXCIE0); //Enable Rx interuppt + UCSR0B |= (1 << RXCIE0) | (1 << TXCIE0); //Enable Rx and TX interuppt sei(); } +Serial* Serial::getInstance() +{ + static Serial serial; + return &serial; +} + void Serial::putChar(const char c) { - loop_until_bit_is_set(UCSR0A, UDRE0); - UDR0 = c; + if(SREG & 1 << 7) + { + while(txBuffer.remainingCapacity() < 2 && transmitting); + + if(!transmitting) + { + loop_until_bit_is_set(UCSR0A, UDRE0); + transmitting = true; + UDR0 = c; + } + else + { + txBuffer.write(c); + } + } + else + { + loop_until_bit_is_set(UCSR0A, UDRE0); + UDR0 = c; + } } void Serial::write(const char* in, const unsigned int length) @@ -42,7 +75,7 @@ void Serial::write(const char* in, const unsigned int length) void Serial::write_p(const char in[]) { - cli(); + //cli(); char ch = pgm_read_byte(in); while (ch != '\0') { @@ -50,7 +83,7 @@ void Serial::write_p(const char in[]) in++; ch = pgm_read_byte(in); } - sei(); + //sei(); } void Serial::write(const char in[]) @@ -61,7 +94,6 @@ void Serial::write(const char in[]) } } - void Serial::write(int32_t in) { if(in == 0)