Rev 772 | Rev 800 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
685 | cascade | 1 | /**************************************************************************** |
728 | cascade | 2 | * Copyright (C) 2009-2010 by Claas Anders "CaScAdE" Rathje * |
685 | cascade | 3 | * admiralcascade@gmail.com * |
4 | * Project-URL: http://www.mylifesucks.de/oss/c-osd/ * |
||
5 | * * |
||
6 | * This program is free software; you can redistribute it and/or modify * |
||
7 | * it under the terms of the GNU General Public License as published by * |
||
8 | * the Free Software Foundation; either version 2 of the License. * |
||
9 | * * |
||
10 | * This program is distributed in the hope that it will be useful, * |
||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
||
13 | * GNU General Public License for more details. * |
||
14 | * * |
||
15 | * You should have received a copy of the GNU General Public License * |
||
16 | * along with this program; if not, write to the * |
||
17 | * Free Software Foundation, Inc., * |
||
18 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
||
19 | ****************************************************************************/ |
||
20 | |||
21 | #include <avr/io.h> |
||
22 | #include <avr/interrupt.h> |
||
23 | #include <util/delay.h> |
||
24 | #include "main.h" |
||
25 | #include "usart1.h" |
||
26 | |||
27 | #if !(ALLCHARSDEBUG|(WRITECHARS != -1)) |
||
28 | |||
29 | volatile uint8_t rxd_buffer_locked = 0; |
||
30 | volatile uint8_t rxd_buffer[RXD_BUFFER_LEN]; |
||
783 | - | 31 | //volatile uint8_t txd_buffer[TXD_BUFFER_LEN]; |
685 | cascade | 32 | volatile uint8_t ReceivedBytes = 0; |
33 | volatile uint8_t *pRxData = 0; |
||
34 | volatile uint8_t RxDataLen = 0; |
||
35 | |||
36 | /* ########################################################################## |
||
772 | - | 37 | * USART1 stuff |
685 | cascade | 38 | * ##########################################################################*/ |
39 | |||
40 | /** |
||
41 | * init usart1 |
||
42 | */ |
||
43 | void usart1_init() { |
||
44 | UBRR1H = ((F_CPU / (16UL * baud)) - 1) >> 8; |
||
45 | UBRR1L = (F_CPU / (16UL * baud)) - 1; |
||
46 | |||
47 | // Enable receiver and transmitter; enable RX interrupt |
||
48 | UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1); |
||
49 | |||
50 | //asynchronous 8N1 |
||
51 | UCSR1C = (1 << URSEL1) | (3 << UCSZ10); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * disable the txd pin of usart1 |
||
56 | */ |
||
57 | void usart1_DisableTXD(void) { |
||
58 | UCSR1B &= ~(1 << TXCIE1); // disable TX-Interrupt |
||
59 | UCSR1B &= ~(1 << TXEN1); // disable TX in USART |
||
60 | DDRB &= ~(1 << DDB3); // set TXD pin as input |
||
61 | PORTB &= ~(1 << PORTB3); // disable pullup on TXD pin |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * enable the txd pin of usart1 |
||
66 | */ |
||
67 | void usart1_EnableTXD(void) { |
||
68 | DDRB |= (1 << DDB3); // set TXD pin as output |
||
69 | PORTB &= ~(1 << PORTB3); // disable pullup on TXD pin |
||
70 | UCSR1B |= (1 << TXEN1); // enable TX in USART |
||
71 | UCSR1B |= (1 << TXCIE1); // enable TX-Interrupt |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * send a single <character> through usart1 |
||
76 | */ |
||
77 | void usart1_putc(unsigned char character) { |
||
78 | // wait until UDR ready |
||
79 | while (!(UCSR1A & (1 << UDRE1))); |
||
80 | UDR1 = character; |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * send a <string> throught usart1 |
||
85 | */ |
||
738 | cascade | 86 | /*void usart1_puts(char *s) { |
685 | cascade | 87 | while (*s) { |
88 | usart1_putc(*s); |
||
89 | s++; |
||
90 | } |
||
738 | cascade | 91 | }*/ |
685 | cascade | 92 | |
93 | /** |
||
761 | - | 94 | * send a PGM<string> throught usart1 |
95 | */ |
||
96 | void usart1_puts_pgm(const char* string) { |
||
97 | while (pgm_read_byte(string) != 0x00) |
||
98 | usart1_putc(pgm_read_byte(string++)); |
||
99 | } |
||
100 | |||
101 | /** |
||
685 | cascade | 102 | * transmit interrupt handler |
103 | * unused |
||
104 | */ |
||
105 | ISR(SIG_USART1_DATA) { |
||
106 | } |
||
107 | |||
108 | /* |
||
109 | * receive data through usart1 |
||
110 | * portions taken and adapted from |
||
111 | * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Fbranches%2FV0.72p+Code+Redesign+killagreg%2Fuart0.c |
||
112 | */ |
||
113 | ISR(SIG_USART1_RECV) { |
||
114 | uint8_t c; |
||
115 | // catch the received byte |
||
116 | c = UDR1; |
||
117 | if (rxd_buffer_locked) return; // if rxd buffer is locked immediately return |
||
118 | static uint16_t crc; |
||
119 | static uint8_t ptr_rxd_buffer = 0; |
||
120 | static uint8_t c1 = 0; |
||
121 | static uint8_t c2 = 0; |
||
122 | static uint8_t usart_rx_ok = 0; |
||
123 | uint8_t crc1, crc2; |
||
124 | // the rxd buffer is unlocked |
||
761 | - | 125 | if (usart_rx_ok == 0) { |
126 | // if ((c2 == '#') && (c1 == 'b' || c1 == 'c') && (c == 'D' || c == 'V' || c == 'O')) { |
||
127 | |||
128 | if ((c2 == '#') && (c1 == 'b' || c1 == 'c') && |
||
129 | #if FCONLY |
||
783 | - | 130 | (c == 'V' || c == 'D' || c == 'Q')) { // version, debug, settings |
761 | - | 131 | #else |
783 | - | 132 | (c == 'V' || c == 'O' || c == 'Q')) { // version, OSD, settings |
761 | - | 133 | #endif |
134 | usart_rx_ok = 1; |
||
135 | rxd_buffer[ptr_rxd_buffer++] = c2; |
||
136 | crc = c2; |
||
137 | rxd_buffer[ptr_rxd_buffer++] = c1; |
||
138 | crc += c1; |
||
139 | rxd_buffer[ptr_rxd_buffer++] = c; |
||
140 | crc += c; |
||
141 | c2 = 0; |
||
142 | c1 = 0; |
||
143 | LED1_ON |
||
144 | LED2_OFF |
||
145 | } else { |
||
685 | cascade | 146 | c2 = c1; |
147 | c1 = c; |
||
148 | } |
||
149 | } else if (ptr_rxd_buffer < RXD_BUFFER_LEN) { // collect incomming bytes |
||
150 | if (c != '\r') { // no termination character |
||
151 | rxd_buffer[ptr_rxd_buffer++] = c; // copy byte to rxd buffer |
||
152 | crc += c; // update crc |
||
153 | } else { // termination character was received |
||
154 | // the last 2 bytes are no subject for checksum calculation |
||
155 | // they are the checksum itself |
||
156 | crc -= rxd_buffer[ptr_rxd_buffer - 2]; |
||
157 | crc -= rxd_buffer[ptr_rxd_buffer - 1]; |
||
158 | // calculate checksum from transmitted data |
||
159 | crc %= 4096; |
||
160 | crc1 = '=' + crc / 64; |
||
161 | crc2 = '=' + crc % 64; |
||
162 | // compare checksum to transmitted checksum bytes |
||
163 | if ((crc1 == rxd_buffer[ptr_rxd_buffer - 2]) && (crc2 == rxd_buffer[ptr_rxd_buffer - 1])) { // checksum valid |
||
164 | rxd_buffer[ptr_rxd_buffer] = '\r'; // set termination character |
||
165 | ReceivedBytes = ptr_rxd_buffer + 1; // store number of received bytes |
||
166 | rxd_buffer_locked = 1; // lock the rxd buffer |
||
167 | LED1_OFF |
||
168 | } else { // checksum invalid |
||
169 | rxd_buffer_locked = 0; // unlock rxd buffer |
||
170 | LED2_ON |
||
171 | } |
||
172 | ptr_rxd_buffer = 0; // reset rxd buffer pointer |
||
173 | usart_rx_ok = 0; |
||
174 | } |
||
175 | } else { // rxd buffer overrun |
||
176 | ptr_rxd_buffer = 0; // reset rxd buffer |
||
177 | rxd_buffer_locked = 0; // unlock rxd buffer |
||
178 | usart_rx_ok = 0; |
||
179 | LED2_ON |
||
180 | } |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Decode the recevied Buffer |
||
185 | * portions taken and adapted from |
||
186 | * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Ftags%2FV0.72p%2Fuart.c |
||
187 | */ |
||
188 | void Decode64(void) { |
||
189 | uint8_t a, b, c, d; |
||
190 | uint8_t x, y, z; |
||
191 | uint8_t ptrIn = 3; |
||
192 | uint8_t ptrOut = 3; |
||
193 | uint8_t len = ReceivedBytes - 6; |
||
194 | |||
195 | while (len) { |
||
196 | a = rxd_buffer[ptrIn++] - '='; |
||
197 | b = rxd_buffer[ptrIn++] - '='; |
||
198 | c = rxd_buffer[ptrIn++] - '='; |
||
199 | d = rxd_buffer[ptrIn++] - '='; |
||
200 | |||
201 | x = (a << 2) | (b >> 4); |
||
202 | y = ((b & 0x0f) << 4) | (c >> 2); |
||
203 | z = ((c & 0x03) << 6) | d; |
||
204 | |||
205 | if (len--) rxd_buffer[ptrOut++] = x; |
||
206 | else break; |
||
207 | if (len--) rxd_buffer[ptrOut++] = y; |
||
208 | else break; |
||
209 | if (len--) rxd_buffer[ptrOut++] = z; |
||
210 | else break; |
||
211 | } |
||
212 | pRxData = &rxd_buffer[3]; |
||
213 | RxDataLen = ptrOut - 3; |
||
783 | - | 214 | } |
215 | |||
216 | |||
217 | /** |
||
218 | * Request Data through usart1 until a answer is received |
||
219 | */ |
||
220 | void usart1_request_blocking(unsigned char answer, const char* message) { |
||
221 | rxd_buffer[2] = answer + 1; |
||
222 | while (rxd_buffer[2] != answer) { |
||
223 | rxd_buffer_locked = 0; |
||
224 | usart1_EnableTXD(); |
||
225 | usart1_puts_pgm(message); |
||
226 | usart1_DisableTXD(); |
||
227 | static uint8_t wait = 0; |
||
228 | wait = 0; |
||
229 | while (rxd_buffer_locked == 0 && wait < 150) { |
||
230 | wait++; |
||
231 | _delay_ms(10); |
||
232 | } |
||
233 | } |
||
234 | Decode64(); |
||
685 | cascade | 235 | } |
783 | - | 236 | |
237 | /** |
||
238 | * Request UART Redirect from NC to itself |
||
239 | */ |
||
240 | void usart1_request_nc_uart(void) { |
||
241 | usart1_EnableTXD(); |
||
242 | usart1_putc(0x1B); |
||
243 | usart1_putc(0x1B); |
||
244 | usart1_putc(0x55); |
||
245 | usart1_putc(0xAA); |
||
246 | usart1_putc(0x00); |
||
247 | usart1_DisableTXD(); |
||
248 | } |
||
249 | |||
685 | cascade | 250 | |
251 | /** |
||
252 | * request Data through USART in special MK format by adding checksum and |
||
253 | * encode data in modified Base64 |
||
254 | * portions taken and adapted from |
||
255 | * http://svn.mikrokopter.de/mikrowebsvn/filedetails.php?repname=FlightCtrl&path=%2Ftags%2FV0.72p%2Fuart.c |
||
256 | */ |
||
738 | cascade | 257 | /*void sendMKData(unsigned char cmd, unsigned char addr, unsigned char *snd, unsigned char len) { |
685 | cascade | 258 | unsigned int pt = 0; |
259 | unsigned char a, b, c; |
||
260 | unsigned char ptr = 0; |
||
261 | |||
262 | txd_buffer[pt++] = '#'; // Start-Byte |
||
263 | txd_buffer[pt++] = 'a' + addr; // Adress |
||
264 | txd_buffer[pt++] = cmd; // Command |
||
265 | while (len) { |
||
266 | if (len) { |
||
267 | a = snd[ptr++]; |
||
268 | len--; |
||
269 | } else a = 0; |
||
270 | if (len) { |
||
271 | b = snd[ptr++]; |
||
272 | len--; |
||
273 | } else b = 0; |
||
274 | if (len) { |
||
275 | c = snd[ptr++]; |
||
276 | len--; |
||
277 | } else c = 0; |
||
278 | txd_buffer[pt++] = '=' + (a >> 2); |
||
279 | txd_buffer[pt++] = '=' + (((a & 0x03) << 4) | ((b & 0xf0) >> 4)); |
||
280 | txd_buffer[pt++] = '=' + (((b & 0x0f) << 2) | ((c & 0xc0) >> 6)); |
||
281 | txd_buffer[pt++] = '=' + (c & 0x3f); |
||
282 | } |
||
283 | |||
284 | // add crc |
||
285 | unsigned int tmpCRC = 0, i; |
||
286 | for (i = 0; i < pt; i++) { |
||
287 | tmpCRC += txd_buffer[i]; |
||
288 | } |
||
289 | tmpCRC %= 4096; |
||
290 | txd_buffer[i++] = '=' + tmpCRC / 64; |
||
291 | txd_buffer[i++] = '=' + tmpCRC % 64; |
||
292 | txd_buffer[i++] = '\r'; |
||
293 | |||
294 | usart1_puts((char*) txd_buffer); |
||
738 | cascade | 295 | }*/ |
685 | cascade | 296 | |
297 | /** |
||
298 | * short script to directly send a request thorugh usart including en- and disabling it |
||
299 | * where <address> is the address of the receipient, <label> is which data set to request |
||
300 | * and <ms> represents the milliseconds delay between data |
||
301 | */ |
||
738 | cascade | 302 | /*void usart1_request_mk_data(uint8_t address, char label, uint8_t ms) { |
685 | cascade | 303 | // re-enable TXD pin |
304 | usart1_EnableTXD(); |
||
305 | |||
306 | unsigned char mstenth = ms / 10; |
||
307 | sendMKData(label, address, &mstenth, 1); |
||
308 | // wait until UDR ready |
||
309 | while (!(UCSR1A & (1 << UDRE1))); |
||
310 | // disable TXD pin again |
||
311 | usart1_DisableTXD(); |
||
738 | cascade | 312 | }*/ |
685 | cascade | 313 | |
314 | #endif |