-
Notifications
You must be signed in to change notification settings - Fork 0
/
miniserial.cpp
83 lines (78 loc) · 3.04 KB
/
miniserial.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "miniserial.h"
#ifdef SERIALACTIVE
volatile FIFO FifoRx;
//------------------------------------------------------------------------------
ISR(USART_RX_vect) {
if((FifoRx.tail + 1) % FIFO_SIZE != FifoRx.head)
FifoRx.buff[FifoRx.tail = ++FifoRx.tail % FIFO_SIZE] = UDR0;
}
//------------------------------------------------------------------------------
uint32_t pow_bwl(uint32_t base, uint8_t expo) {
return (expo?base*pow_bwl(base,expo-1):1);
}
//------------------------------------------------------------------------------
void MiniSerial_data_(uint32_t val, uint8_t bwl, uint8_t base=DEC, uint8_t zero=false) {
uint8_t len;
switch (base) {
case BIN : len=bwl?(--bwl?32:16):8; break;
case OCT : len=bwl?(--bwl?11: 6):3; break;
case DEC : len=bwl?(--bwl?10: 5):3; break;
case HEX : len=bwl?(--bwl? 8: 4):2; break;
default : return;
}
while (len--) {
uint32_t tmp2 = pow_bwl(base, len);
uint8_t tmp = (val/tmp2);
val -= tmp*tmp2;
if(zero=(zero) | (tmp) | !(len)) {
MiniSerial_write(tmp+(tmp<10?'0':'A'-10));
}
}
}
//------------------------------------------------------------------------------
void MiniSerial_print_(const __FlashStringHelper *ifsh) {
const char * __attribute__((progmem)) p = (const char * ) ifsh;
while (unsigned char c = pgm_read_byte(p++)) {
MiniSerial_write(c);
}
}
//------------------------------------------------------------------------------
void MiniSerial_write_(uint8_t b) {
while (((1 << UDRIE0) & UCSR0B) || !(UCSR0A & (1 << UDRE0))) {}
UDR0 = b;
}
//------------------------------------------------------------------------------
uint8_t MiniSerial_read_() {
if(FifoRx.tail == FifoRx.head) return 0;
uint8_t data = FifoRx.buff[FifoRx.head];
FifoRx.head = ++FifoRx.head % FIFO_SIZE;
return data;
}
//------------------------------------------------------------------------------
uint8_t MiniSerial_available_() {
return ((FifoRx.tail - FifoRx.head + FIFO_SIZE) % FIFO_SIZE);
}
//------------------------------------------------------------------------------
void MiniSerial_begin_(uint32_t baud) {
FifoRx.head = FifoRx.tail = 0;
uint16_t baud_setting;
// don't worry, the compiler will squeeze out F_CPU != 16000000UL
if ((F_CPU != 16000000UL || baud != 57600) && baud > (F_CPU/(4*(2*0XFFF + 1)) + 1)) {
// Double the USART Transmission Speed
UCSR0A = 1 << U2X0;
baud_setting = (F_CPU / 4 / baud - 1) / 2;
} else {
// hardcoded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560.
UCSR0A = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting
UBRR0H = baud_setting >> 8;
UBRR0L = baud_setting;
// Enable Transmitter | Receiver | Rx Complete Interrupt
UCSR0B |= (1 << TXEN0) | (1 << RXEN0) | (1 << RXCIE0);
}
//------------------------------------------------------------------------------
#endif SERIALACTIVE