Rev 1144 Rev 1858
1   1  
2 /* 2 /*
3 * Copyright (c) 2006-2007 by Roland Riegel <feedback@roland-riegel.de> 3 * Copyright (c) 2006-2007 by Roland Riegel <feedback@roland-riegel.de>
4 * 4 *
5 * This file is free software; you can redistribute it and/or modify 5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9   9  
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <avr/interrupt.h> 11 #include <avr/interrupt.h>
12 #include <avr/io.h> 12 #include <avr/io.h>
13 #include <avr/pgmspace.h> 13 #include <avr/pgmspace.h>
14 #include <avr/sfr_defs.h> 14 #include <avr/sfr_defs.h>
15 #include <avr/sleep.h> 15 #include <avr/sleep.h>
16   16  
17 #include "uart.h" 17 #include "uart.h"
18   18  
19 /* some mcus have multiple uarts */ 19 /* some mcus have multiple uarts */
20 #ifdef UDR0 20 #ifdef UDR0
21 #define UBRRH UBRR0H 21 #define UBRRH UBRR0H
22 #define UBRRL UBRR0L 22 #define UBRRL UBRR0L
23 #define UDR UDR0 23 #define UDR UDR0
24   24  
25 #define UCSRA UCSR0A 25 #define UCSRA UCSR0A
26 #define UDRE UDRE0 26 #define UDRE UDRE0
27 #define RXC RXC0 27 #define RXC RXC0
28   28  
29 #define UCSRB UCSR0B 29 #define UCSRB UCSR0B
30 #define RXEN RXEN0 30 #define RXEN RXEN0
31 #define TXEN TXEN0 31 #define TXEN TXEN0
32 #define RXCIE RXCIE0 32 #define RXCIE RXCIE0
33   33  
34 #define UCSRC UCSR0C 34 #define UCSRC UCSR0C
35 #define URSEL 35 #define URSEL
36 #define UCSZ0 UCSZ00 36 #define UCSZ0 UCSZ00
37 #define UCSZ1 UCSZ01 37 #define UCSZ1 UCSZ01
38 #define UCSRC_SELECT 0 38 #define UCSRC_SELECT 0
39 #else 39 #else
40 #define UCSRC_SELECT (1 << URSEL) 40 #define UCSRC_SELECT (1 << URSEL)
41 #endif 41 #endif
42   42  
43 #ifndef USART_RXC_vect 43 #ifndef USART_RXC_vect
44 #if defined(UART0_RX_vect) 44 #if defined(UART0_RX_vect)
45 #define USART_RXC_vect UART0_RX_vect 45 #define USART_RXC_vect UART0_RX_vect
46 #elif defined(UART_RX_vect) 46 #elif defined(UART_RX_vect)
47 #define USART_RXC_vect UART_RX_vect 47 #define USART_RXC_vect UART_RX_vect
48 #elif defined(USART0_RX_vect) 48 #elif defined(USART0_RX_vect)
49 #define USART_RXC_vect USART0_RX_vect 49 #define USART_RXC_vect USART0_RX_vect
50 #elif defined(USART_RX_vect) 50 #elif defined(USART_RX_vect)
51 #define USART_RXC_vect USART_RX_vect 51 #define USART_RXC_vect USART_RX_vect
52 #elif defined(USART0_RXC_vect) 52 #elif defined(USART0_RXC_vect)
53 #define USART_RXC_vect USART0_RXC_vect 53 #define USART_RXC_vect USART0_RXC_vect
54 #elif defined(USART_RXC_vect) 54 #elif defined(USART_RXC_vect)
55 #define USART_RXC_vect USART_RXC_vect 55 #define USART_RXC_vect USART_RXC_vect
56 #else 56 #else
57 #error "Uart receive complete interrupt not defined!" 57 #error "Uart receive complete interrupt not defined!"
58 #endif 58 #endif
59 #endif 59 #endif
60   60  
61 #define BAUD 9600UL 61 #define BAUD 9600UL
62 #define UBRRVAL (F_CPU/(BAUD*16)-1) 62 #define UBRRVAL (F_CPU/(BAUD*16)-1)
63 #define USE_SLEEP 1 63 #define USE_SLEEP 1
64   64  
65 void uart_init() 65 void uart_init()
66 { 66 {
67 /* set baud rate */ 67 /* set baud rate */
68 UBRRH = UBRRVAL >> 8; 68 UBRRH = UBRRVAL >> 8;
69 UBRRL = UBRRVAL & 0xff; 69 UBRRL = UBRRVAL & 0xff;
70 /* set frame format: 8 bit, no parity, 1 bit */ 70 /* set frame format: 8 bit, no parity, 1 bit */
71 UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0); 71 UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
72 /* enable serial receiver and transmitter */ 72 /* enable serial receiver and transmitter */
73 #if !USE_SLEEP 73 #if !USE_SLEEP
74 UCSRB = (1 << RXEN) | (1 << TXEN); 74 UCSRB = (1 << RXEN) | (1 << TXEN);
75 #else 75 #else
76 UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); 76 UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
77 #endif 77 #endif
78 } 78 }
79   79  
80 void uart_putc(uint8_t c) 80 void uart_putc(uint8_t c)
81 { 81 {
82 if(c == '\n') 82 if(c == '\n')
83 uart_putc('\r'); 83 uart_putc('\r');
84   84  
85 /* wait until transmit buffer is empty */ 85 /* wait until transmit buffer is empty */
86 while(!(UCSRA & (1 << UDRE))); 86 while(!(UCSRA & (1 << UDRE)));
87   87  
88 /* send next byte */ 88 /* send next byte */
89 UDR = c; 89 UDR = c;
90 } 90 }
91   91  
92 void uart_putc_hex(uint8_t b) 92 void uart_putc_hex(uint8_t b)
93 { 93 {
94 /* upper nibble */ 94 /* upper nibble */
95 if((b >> 4) < 0x0a) 95 if((b >> 4) < 0x0a)
96 uart_putc((b >> 4) + '0'); 96 uart_putc((b >> 4) + '0');
97 else 97 else
98 uart_putc((b >> 4) - 0x0a + 'a'); 98 uart_putc((b >> 4) - 0x0a + 'a');
99   99  
100 /* lower nibble */ 100 /* lower nibble */
101 if((b & 0x0f) < 0x0a) 101 if((b & 0x0f) < 0x0a)
102 uart_putc((b & 0x0f) + '0'); 102 uart_putc((b & 0x0f) + '0');
103 else 103 else
104 uart_putc((b & 0x0f) - 0x0a + 'a'); 104 uart_putc((b & 0x0f) - 0x0a + 'a');
105 } 105 }
106   106  
107 void uart_putw_hex(uint16_t w) 107 void uart_putw_hex(uint16_t w)
108 { 108 {
109 uart_putc_hex((uint8_t) (w >> 8)); 109 uart_putc_hex((uint8_t) (w >> 8));
110 uart_putc_hex((uint8_t) (w & 0xff)); 110 uart_putc_hex((uint8_t) (w & 0xff));
111 } 111 }
112   112  
113 void uart_putdw_hex(uint32_t dw) 113 void uart_putdw_hex(uint32_t dw)
114 { 114 {
115 uart_putw_hex((uint16_t) (dw >> 16)); 115 uart_putw_hex((uint16_t) (dw >> 16));
116 uart_putw_hex((uint16_t) (dw & 0xffff)); 116 uart_putw_hex((uint16_t) (dw & 0xffff));
117 } 117 }
118   118  
119 void uart_putw_dec(uint16_t w) 119 void uart_putw_dec(uint16_t w)
120 { 120 {
121 uint16_t num = 10000; 121 uint16_t num = 10000;
122 uint8_t started = 0; 122 uint8_t started = 0;
123   123  
124 while(num > 0) 124 while(num > 0)
125 { 125 {
126 uint8_t b = w / num; 126 uint8_t b = w / num;
127 if(b > 0 || started || num == 1) 127 if(b > 0 || started || num == 1)
128 { 128 {
129 uart_putc('0' + b); 129 uart_putc('0' + b);
130 started = 1; 130 started = 1;
131 } 131 }
132 w -= b * num; 132 w -= b * num;
133   133  
134 num /= 10; 134 num /= 10;
135 } 135 }
136 } 136 }
137   137  
138 void uart_putdw_dec(uint32_t dw) 138 void uart_putdw_dec(uint32_t dw)
139 { 139 {
140 uint32_t num = 1000000000; 140 uint32_t num = 1000000000;
141 uint8_t started = 0; 141 uint8_t started = 0;
142   142  
143 while(num > 0) 143 while(num > 0)
144 { 144 {
145 uint8_t b = dw / num; 145 uint8_t b = dw / num;
146 if(b > 0 || started || num == 1) 146 if(b > 0 || started || num == 1)
147 { 147 {
148 uart_putc('0' + b); 148 uart_putc('0' + b);
149 started = 1; 149 started = 1;
150 } 150 }
151 dw -= b * num; 151 dw -= b * num;
152   152  
153 num /= 10; 153 num /= 10;
154 } 154 }
155 } 155 }
156   156  
157 void uart_puts(const char* str) 157 void uart_puts(const char* str)
158 { 158 {
159 while(*str) 159 while(*str)
160 uart_putc(*str++); 160 uart_putc(*str++);
161 } 161 }
162   162  
163 void uart_puts_p(PGM_P str) 163 void uart_puts_p(PGM_P str)
164 { 164 {
165 while(1) 165 while(1)
166 { 166 {
167 uint8_t b = pgm_read_byte_near(str++); 167 uint8_t b = pgm_read_byte_near(str++);
168 if(!b) 168 if(!b)
169 break; 169 break;
170   170  
171 uart_putc(b); 171 uart_putc(b);
172 } 172 }
173 } 173 }
174   174  
175 uint8_t uart_getc() 175 uint8_t uart_getc()
176 { 176 {
177 /* wait until receive buffer is full */ 177 /* wait until receive buffer is full */
178 #if USE_SLEEP 178 #if USE_SLEEP
179 uint8_t sreg = SREG; 179 uint8_t sreg = SREG;
180 sei(); 180 sei();
181   181  
182 while(!(UCSRA & (1 << RXC))) 182 while(!(UCSRA & (1 << RXC)))
183 sleep_mode(); 183 sleep_mode();
184   184  
185 SREG = sreg; 185 SREG = sreg;
186 #else 186 #else
187 while(!(UCSRA & (1 << RXC))); 187 while(!(UCSRA & (1 << RXC)));
188 #endif 188 #endif
189   189  
190 uint8_t b = UDR; 190 uint8_t b = UDR;
191 if(b == '\r') 191 if(b == '\r')
192 b = '\n'; 192 b = '\n';
193   193  
194 return b; 194 return b;
195 } 195 }
196   196  
197 EMPTY_INTERRUPT(USART_RXC_vect) 197 EMPTY_INTERRUPT(USART_RXC_vect)
198   198