#include "serial.h" char rxBuffer[BUFFER_SIZE]; volatile uint32_t interruptIndex = 0; volatile uint32_t _rxIndex = 0; bool stopped = false; ISR (USART_RX_vect) //I have seen worse interrupt sintax { rxBuffer[interruptIndex % BUFFER_SIZE] = UDR0; if (interruptIndex - BUFFER_SIZE > 0 && _rxIndex - BUFFER_SIZE > 0) { interruptIndex -= BUFFER_SIZE; _rxIndex -= BUFFER_SIZE; } if(serialFlowControl && !stopped && interruptIndex - _rxIndex > BUFFER_SIZE - 64) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = 0x13; stopped = true; } if(interruptIndex - _rxIndex < BUFFER_SIZE )interruptIndex++; } Serial::Serial() { UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); UCSR0B = _BV(RXEN0) | _BV(TXEN0); //Enable RX and TX UCSR0B |= (1 << RXCIE0); //Enable Rx interuppt } void Serial::putChar(const char c) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = c; } void Serial::write(const char* in, const unsigned int length) { for(unsigned int i = 0; i < length && in[i] != '\0'; i++) { putChar(in[i]); } } void Serial::write(const char in[]) { for(unsigned int i = 0; i < strlen(in); i++) { putChar(in[i]); } } void Serial::write(int32_t in) { if(in == 0) { putChar('0'); } else { bool flag = false; char str[64] = { 0 }; int16_t i = 62; if (in < 0) { flag = true; in = abs(in); } while (in != 0 && i > 0) { str[i--] = (in % 10) + '0'; in /= 10; } if (flag) str[i--] = '-'; write(str + i + 1, 64-(i+1)); } } bool Serial::dataIsWaiting() { return (interruptIndex > _rxIndex); } char Serial::getChar() { if(dataIsWaiting()) { _rxIndex++; if(serialFlowControl && stopped && interruptIndex - _rxIndex < 64) { loop_until_bit_is_set(UCSR0A, UDRE0); UDR0 = 0x11; stopped = false; } return rxBuffer[(_rxIndex -1) % BUFFER_SIZE]; } else return '\0'; } unsigned int Serial::getString(char* buffer, const int bufferLength) { unsigned int i = 0; for(; i <= (interruptIndex-_rxIndex) && i <= BUFFER_SIZE && rxBuffer[(_rxIndex+i) % BUFFER_SIZE] != _terminator; i++); if( i < (interruptIndex-_rxIndex) && i > 0) { unsigned int j = 0; for(; j < i && j < bufferLength-1 ; j++) { buffer[j] = getChar(); } buffer[j+1]='\0'; _rxIndex++; } else i = 0; if (rxBuffer[(_rxIndex+i) % BUFFER_SIZE] == _terminator) _rxIndex++; return i; } void Serial::flush() { _rxIndex = 0; interruptIndex = 0; for(int i = 0; i < BUFFER_SIZE; i++) rxBuffer[i] = ' '; } void Serial::setTerminator(char terminator){_terminator = terminator;}