/* BuffSerial.cpp v.01 - serial with transmit buffer library for Wiring Created by Kochetkov Aleksey, 03.07.2009 */ #include #include "BuffSerial.h" // serial init void BuffSerial::begin(long speed) { #if defined(__AVR_ATmega8__) UCSRB = _BV(RXCIE) | _BV(RXEN) | _BV(TXCIE) | _BV(TXEN); // enable rx, tx inerrputs UBRRH = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8; // usart speed UBRRL = ((F_CPU / 16 + speed / 2) / speed - 1); #else UCSR0B = (_BV(RXCIE0) | _BV(RXEN0) | _BV(TXCIE0) | _BV(TXEN0)); // enable rx, tx inerrputs UBRR0H = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8; // usart speed UBRR0L = ((F_CPU / 16 + speed / 2) / speed - 1); #endif rxBegin = rxEnd = 0; txBegin = txEnd = txOverflow = 0; txFull = 0; } //USART Rx Complete #if defined(__AVR_ATmega8__) SIGNAL(SIG_UART_RECV) #else SIGNAL(USART_RX_vect) #endif { #if defined(__AVR_ATmega8__) bSerial.rxBuffer[bSerial.rxEnd] = UDR; #else bSerial.rxBuffer[bSerial.rxEnd] = UDR0; #endif if (bSerial.rxEnd < RX_BUFF_SIZE) bSerial.rxEnd++; } //USART Tx Complete #if defined(__AVR_ATmega8__) SIGNAL(SIG_UART_TRANS) #else SIGNAL(USART_TX_vect) #endif { if (bSerial.txEnd != bSerial.txBegin || bSerial.txFull != 0) { #if defined(__AVR_ATmega8__) UDR = bSerial.txBuffer[bSerial.txBegin]; // Send buffer #else UDR0 = bSerial.txBuffer[bSerial.txBegin]; // Send buffer #endif bSerial.txFull = 0; bSerial.txBegin++; if (bSerial.txBegin == TX_BUFF_SIZE) bSerial.txBegin = 0; } } // send byte to serial or buffer if bisy void BuffSerial::sendByte(uint8_t data) { if (txFull) { txOverflow++; } else { uint8_t oldSREG = SREG; cli(); #if defined(__AVR_ATmega8__) if (txEnd != txBegin || (UCSRA & _BV(UDRE)) == 0) { #else if (txEnd != txBegin || (UCSR0A & _BV(UDRE0)) == 0) { #endif txBuffer[txEnd] = data; txEnd++; if (txEnd == TX_BUFF_SIZE) txEnd = 0; if (txEnd == txBegin) txFull = 1; // buffer overflow } else { #if defined(__AVR_ATmega8__) UDR = data; #else UDR0 = data; #endif } SREG = oldSREG; } } // print string void BuffSerial::print(const char *pBuf) { while (*pBuf) { sendByte(*pBuf++); } } void BuffSerial::print(const char pBuf) { sendByte(pBuf); } void BuffSerial::println(const char *pBuf) { print(pBuf); println(); } void BuffSerial::println(const char pBuf) { print(pBuf); println(); } void BuffSerial::println(void) { print("\r\n"); } void BuffSerial::printHex4(uint8_t data) { uint8_t c = data & 0x0f; c += c < 10 ? '0' : 'A' - 10 ; sendByte(c); } void BuffSerial::printHex8(uint8_t data) { printHex4(data >> 4); printHex4(data); } void BuffSerial::printDec(uint8_t data) { uint8_t buf[3]; uint8_t i = 0; if (data == 0) { sendByte('0'); return; } while (data > 0) { buf[i++] = data % 10; data /= 10; } for (; i > 0; i--) sendByte((buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10)); } // check rx buffer not empty bool BuffSerial::rxEnabled(void) { return rxEnd; } uint8_t BuffSerial::rxRead(void) { #if defined(__AVR_ATmega8__) cbi(UCSRB, RXCIE); // disable RX complete interrupt #else cbi(UCSR0B, RXCIE0); // disable RX complete interrupt #endif uint8_t readkey = rxBuffer[rxBegin]; // read begin of received Buffer rxBegin++; if (rxBegin == rxEnd) rxBegin = rxEnd = 0; // if Buffer is empty reset Buffer #if defined(__AVR_ATmega8__) sbi(UCSRB, RXCIE); // enable RX complete interrupt #else sbi(UCSR0B, RXCIE0); // enable RX complete interrupt #endif return readkey; } BuffSerial bSerial;