-
Notifications
You must be signed in to change notification settings - Fork 1
/
Serial_USART.cpp
164 lines (120 loc) · 2.57 KB
/
Serial_USART.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
* Serial_USART.cpp
*
* Created: 10/18/2014 11:45:25 PM
* Author: jpagel
*/
#include <avr/io.h>
#include "Serial_USART.h"
#include "ProgMemData.h"
#include <util/setbaud.h>
#ifndef F_CPU
#error You Must declare F_CPU
#endif
#ifndef BAUD
#error You must define BAUD to your desired BAUDrate
#endif
int main(void)
{
}
#if defined(__AVR_ATXMEGA128D3__) || defined(__AVR_ATXMEGA64A1U__) //Really any XMEGA Since they are all pretty much much compatible minus USB variations.
void Serial::sendChar(char c)
{
while( !(USARTC0_STATUS & USART_DREIF_bm) ); //Wait until DATA buffer is empty
USARTC0_DATA = c;
}
void Serial::sendString(char *text)
{
while(*text)
{
sendChar(*text++);
}
}
char Serial::receiveByte() //Blocking
{
while( !(USARTC0_STATUS & USART_RXCIF_bm) ); //Interesting DRIF didn't work.
return USARTC0_DATA;
}
void Serial::SerialBeginXMEGA(baud_t baud)
{
//baud_t temp = baud;
int16_t scaler = baud.Scaler;
int32_t bsel = baud.Bsel;
int16_t doubleSpeed = baud.DoubleSpeed;
USARTC0_BAUDCTRLB = USARTC0.BAUDCTRLB = 0| (bsel >> 8) | (scaler << USART_BSCALE0_bp);
USARTC0_BAUDCTRLA = bsel;
//Disable interrupts, just for safety
USARTC0_CTRLA = 0;
//8 data bits, no parity and 1 stop bit
USARTC0_CTRLC = USART_CHSIZE_8BIT_gc;
//Enable receive and transmit
if(doubleSpeed)
{
USARTC0_CTRLB = USART_TXEN_bm | USART_RXEN_bm | USART_CLK2X_bm;
}
else
{
USARTC0_CTRLB = USART_TXEN_bm | USART_RXEN_bm | ~USART_CLK2X_bm;
}
}
#endif
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega8A__) || defined(__AVR_ATmega168P)
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168P__)
#undef UDR
#undef UCSRA
#undef UCSRB
#undef UDRE
#undef UBRRH
#undef UBRRL
#undef U2X
#undef RXEN
#undef TXEN
#undef TXC
#undef RXC
#define UDR UDR0
#define UCSRA UCSR0A
#define UCSRB UCSR0B
#define UDRE UDRE0
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define U2X U2X0
#define RXEN RXEN0
#define TXEN TXEN0
#define TXC TXC0
#define RXC RXC0
#endif
void configureSerial()
{
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
#if USE_2X
UCSRA |= (1<<U2X);
#else
UCSRA &= ~(1<<U2X);
#endif
}
void startSerial()
{
UCSRB |= (1<<RXEN) | (1<<TXEN);
}
void Serial::sendChar(char c) {
UDR = c;
loop_until_bit_is_set(UCSRA, TXC); /* Wait until transmission ready. */
}
void Serial::sendString(char *text)
{
while(*text)
{
sendChar(*text++) ;
}
}
char receiveByte() {
loop_until_bit_is_set(UCSRA, RXC); /* Wait until data exists. */
return UDR;
}
void Serial::SerialBegin()
{
configureSerial();
startSerial();
}
#endif