-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart.cpp
132 lines (106 loc) · 1.79 KB
/
uart.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <avr/io.h>
#include <avr/interrupt.h>
#include "config.h"
#include "uart.h"
#include "portAccess.h"
#include "utils.h"
#ifndef F_CPU
#error F_CPU not defined
#endif
UART uart0(HOST_UART,HOST_BAUDRATE);
namespace {
uint16_t calcUBRR(uint16_t baud)
{
return F_CPU/16/baud-1;
}
UART* uartInstance[NUM_UARTS];
}
#if defined(__AVR_ATmega1280__) //mega
volatile uint8_t* portUDR[NUM_UARTS] = {
&UDR0,
&UDR1,
&UDR2,
&UDR3
};
volatile uint8_t* portDDR[NUM_UARTS] = {
&DDRE,
&DDRD,
&DDRH,
&DDRJ
};
uint8_t portTxPin[NUM_UARTS] = {
_BV(PE1),
_BV(PD3),
_BV(PH1),
_BV(PJ1)
};
#elif defined(__AVR_ATmega644P__) //sanguino
volatile uint8_t* portUDR[NUM_UARTS] = {
&UDR0,
&UDR1,
};
volatile uint8_t* portDDR[NUM_UARTS] = {
&DDRD,
&DDRD,
};
uint8_t portTxPin[NUM_UARTS] = {
_BV(PD1),
_BV(PD3),
};
#else
#error UART doesnt support current cpu
#endif
ISR(USART0_RX_vect)
{
uartInstance[0]->isrCallback();
}
#if NUM_UARTS > 1
ISR(USART1_RX_vect)
{
uartInstance[1]->isrCallback();
}
#endif
#if NUM_UARTS > 2
ISR(USART2_RX_vect)
{
uartInstance[2]->isrCallback();
}
#endif
#if NUM_UARTS > 3
ISR(USART3_RX_vect)
{
uartInstance[3]->isrCallback();
}
#endif
UART::UART(uint8_t uartNum,uint16_t baudRate)
: mRingBuffer(mBuffer,UART_RECEIVE_BUFFER_SIZE),
mUartNum(uartNum),
mBaudrate(baudRate)
{
uartInstance[uartNum] = this;
uint16_t ubrr = calcUBRR(mBaudrate);
UBRRnH = ubrr>>8;
UBRRnL = ubrr;
UCSRnB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
UCSRnC = _BV(UCSZ1) | _BV(UCSZ0);
}
void UART::send(uint8_t b)
{
WAIT_SEND;
UDRn = b;
}
void UART::send(const uint8_t* b,uint8_t size)
{
while(size--)
{
send(*b++);
}
}
uint8_t UART::receive()
{
return mRingBuffer.get();
}
void UART::isrCallback()
{
mRingBuffer.put(UDRn);
}