1 | /*
|
2 | * Copyright (c) 2006-2009 by Roland Riegel <feedback@roland-riegel.de>
|
3 | *
|
4 | * This file is free software; you can redistribute it and/or modify
|
5 | * it under the terms of the GNU General Public License version 2 as
|
6 | * published by the Free Software Foundation.
|
7 | */
|
8 |
|
9 | #include <stdio.h>
|
10 | #include <avr/interrupt.h>
|
11 | #include <avr/io.h>
|
12 | #include <avr/pgmspace.h>
|
13 | #include <avr/sfr_defs.h>
|
14 | #include <avr/sleep.h>
|
15 |
|
16 | #include "uart.h"
|
17 | #include "globals.h"
|
18 |
|
19 | /* some mcus have multiple uarts */
|
20 | #ifdef UDR1
|
21 | #define UBRRH UBRR1H
|
22 | #define UBRRL UBRR1L
|
23 | #define UDR UDR1
|
24 |
|
25 | #define UCSRA UCSR1A
|
26 | //#define UDRE UDRE1
|
27 |
|
28 |
|
29 | #define UCSRB UCSR1B
|
30 |
|
31 | #define UCSRC UCSR1C
|
32 | #define URSEL
|
33 |
|
34 | #define UCSRC_SELECT 0
|
35 | #else
|
36 | #define UCSRC_SELECT (1 << URSEL)
|
37 | #endif
|
38 |
|
39 | #ifndef USART_RXC_vect
|
40 |
|
41 | #if defined(UART1_RX_vect)
|
42 | #define USART_RXC_vect UART1_RX_vect
|
43 |
|
44 | #elif defined(UART_RX_vect)
|
45 | #define USART_RXC_vect UART1_RX_vect
|
46 |
|
47 | #elif defined(USART1_RX_vect)
|
48 | #define USART_RXC_vect USART1_RX_vect
|
49 |
|
50 | #elif defined(USART_RX_vect)
|
51 | #define USART_RXC_vect USART1_RX_vect
|
52 |
|
53 | #elif defined(USART1_RXC_vect)
|
54 | #define USART_RXC_vect USART1_RXC_vect
|
55 |
|
56 | #elif defined(USART_RXC_vect)
|
57 | #define USART_RXC_vect USART1_RXC_vect
|
58 | #else
|
59 | #error "Uart receive complete interrupt not defined!"
|
60 | #endif
|
61 | #endif
|
62 |
|
63 | #define BAUD 19200UL // Default 57600UL
|
64 | #define UBRRVAL (F_CPU/(BAUD*16)-1)
|
65 | #define USE_SLEEP 1
|
66 |
|
67 | void uart_init()
|
68 | {
|
69 | // Setze Baudrate
|
70 | UBRRH = UBRRVAL >> 8;
|
71 | UBRRL = UBRRVAL & 0xFF;
|
72 |
|
73 | // set frame format: 8 bit, no parity, 1 bit
|
74 | UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
|
75 |
|
76 | // Receiver und Transmitter einschalten UND (Transmitt) und Receive Interrupts einschalten
|
77 | // UCSRB = (1 << RXEN) | (1 << TXEN);// | (1 << RXCIE); // | (1 << TXCIE);
|
78 |
|
79 | // enable serial receiver and transmitter
|
80 | #if !USE_SLEEP
|
81 | UCSRB = (1 << RXEN) | (1 << TXEN);
|
82 | #else
|
83 | UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
|
84 | #endif
|
85 |
|
86 | }
|
87 |
|
88 |
|
89 | void uart_deak()
|
90 | {
|
91 | //UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
|
92 | UCSRA=0x00;
|
93 | UCSRB=0x00;
|
94 | UCSRC=0x00;
|
95 | }
|
96 |
|
97 | void uart_putc(uint8_t c)
|
98 | {
|
99 | if (c == '\n')
|
100 | uart_putc('\r');
|
101 |
|
102 | /* wait until transmit buffer is empty */
|
103 | while (!(UCSR1A & (1 << UDRE1)))
|
104 | ;
|
105 |
|
106 | /* send next byte */
|
107 | UDR = c;
|
108 | }
|
109 |
|
110 | void uart_putc_hex(uint8_t b)
|
111 | {
|
112 | /* upper nibble */
|
113 | if ((b >> 4) < 0x0a)
|
114 | uart_putc((b >> 4) + '0');
|
115 | else
|
116 | uart_putc((b >> 4) - 0x0a + 'a');
|
117 |
|
118 | /* lower nibble */
|
119 | if ((b & 0x0f) < 0x0a)
|
120 | uart_putc((b & 0x0f) + '0');
|
121 | else
|
122 | uart_putc((b & 0x0f) - 0x0a + 'a');
|
123 | }
|
124 |
|
125 | void uart_putw_hex(uint16_t w)
|
126 | {
|
127 | uart_putc_hex((uint8_t) (w >> 8));
|
128 | uart_putc_hex((uint8_t) (w & 0xff));
|
129 | }
|
130 |
|
131 | void uart_putdw_hex(uint32_t dw)
|
132 | {
|
133 | uart_putw_hex((uint16_t) (dw >> 16));
|
134 | uart_putw_hex((uint16_t) (dw & 0xffff));
|
135 | }
|
136 |
|
137 | void uart_putw_dec(uint16_t w)
|
138 | {
|
139 | uint16_t num = 10000;
|
140 | uint8_t started = 0;
|
141 |
|
142 | while (num > 0)
|
143 | {
|
144 | uint8_t b = w / num;
|
145 | if (b > 0 || started || num == 1)
|
146 | {
|
147 | uart_putc('0' + b);
|
148 | started = 1;
|
149 | }
|
150 | w -= b * num;
|
151 |
|
152 | num /= 10;
|
153 | }
|
154 | }
|
155 |
|
156 | void uart_putdw_dec(uint32_t dw)
|
157 | {
|
158 | uint32_t num = 1000000000;
|
159 | uint8_t started = 0;
|
160 |
|
161 | while (num > 0)
|
162 | {
|
163 | uint8_t b = dw / num;
|
164 | if (b > 0 || started || num == 1)
|
165 | {
|
166 | uart_putc('0' + b);
|
167 | started = 1;
|
168 | }
|
169 | dw -= b * num;
|
170 |
|
171 | num /= 10;
|
172 | }
|
173 | }
|
174 |
|
175 | void uart_puts(const char* str)
|
176 | {
|
177 | while (*str)
|
178 | uart_putc(*str++);
|
179 | }
|
180 |
|
181 | void uart_puts_p(PGM_P str)
|
182 | {
|
183 | while (1)
|
184 | {
|
185 | uint8_t b = pgm_read_byte_near(str++);
|
186 | if (!b)
|
187 | break;
|
188 |
|
189 | uart_putc(b);
|
190 | }
|
191 | }
|
192 |
|
193 | uint8_t uart_getc()
|
194 | {
|
195 | /* wait until receive buffer is full */
|
196 | #if USE_SLEEP
|
197 | uint8_t sreg = SREG;
|
198 | sei();
|
199 |
|
200 | while (!(UCSRA & (1 << RXC)))
|
201 | // sleep_mode();
|
202 |
|
203 | SREG = sreg;
|
204 | #else
|
205 | while(!(UCSRA & (1 << RXC)));
|
206 | #endif
|
207 |
|
208 | uint8_t b = UDR;
|
209 | if (b == '\r')
|
210 | b = '\n';
|
211 |
|
212 | return b;
|
213 | }
|
214 |
|
215 | void uart_gets(char* Buffer, uint8_t MaxLen)
|
216 | {
|
217 | uint8_t NextChar;
|
218 | uint8_t StringLen = 0;
|
219 |
|
220 | NextChar = uart_getc(); // Warte auf und empfange das nächste Zeichen
|
221 |
|
222 | // Sammle solange Zeichen, bis:
|
223 | // * entweder das String Ende Zeichen kam
|
224 | // * oder das aufnehmende Array voll ist
|
225 | while (NextChar != '\n' && StringLen < MaxLen - 1)
|
226 | {
|
227 | *Buffer++ = NextChar;
|
228 | StringLen++;
|
229 | NextChar = uart_getc();
|
230 | }
|
231 |
|
232 | // Noch ein '\0' anhängen um einen Standard
|
233 | // C-String daraus zu machen
|
234 | *Buffer = '\0';
|
235 | }
|
236 |
|
237 | //EMPTY_INTERRUPT(USART_RXC_vect)
|
238 |
|
239 | ISR (USART1_RXC_vect) // UART1
|
240 | {
|
241 | PORTA = ~PORTA;
|
242 | // sync_flag=1;
|
243 | // UCSRA &= ~(1 << RXC);
|
244 |
|
245 | //U8 u = UDR;
|
246 | }
|