1
0
mirror of https://github.com/Oleg-Stepanenko-owo/IEBUS synced 2025-06-14 11:26:31 +00:00
2016-03-12 21:17:29 +02:00

164 lines
3.7 KiB
C++

/*
BuffSerial.cpp v.01 - serial with transmit buffer library for Wiring
Created by Kochetkov Aleksey, 03.07.2009
*/
#include <stdio.h>
#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;