3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
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 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 /* USART-Init beim ATmegaXX */
24 #include <avr/interrupt.h>
36 #define USART_UDRE_vect USART0_UDRE_vect
37 #define USART_RXC_vect USART0_RX_vect
48 #define USART_UDRE_vect USART0_UDRE_vect
49 #define USART_RXC_vect USART0_RX_vect
68 #define USART_UDRE_vect USART1_UDRE_vect
69 #define USART_RXC_vect USART1_RX_vect
85 void uart_insertc(char c);
87 #define uart_insertc uart_putc
88 #endif /* UART_INTERRUPT */
91 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
94 typedef enum{go=1,nogo=0} gonogo;
95 static gonogo txon=go;
96 static gonogo rxon=go;
100 volatile static char rxbuf[UART_RXBUFSIZE];
101 volatile static char txbuf[UART_TXBUFSIZE];
102 volatile static char *volatile rxhead, *volatile rxtail;
103 volatile static char *volatile txhead, *volatile txtail;
106 void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
109 ISR(USART_UDRE_vect) {
114 if ( txhead == txtail ) {
115 UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
121 UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
122 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
126 ISR(USART_RXC_vect) {
130 static volatile uint8_t hook_running=0;
147 diff = rxhead - rxtail;
148 if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
149 if (diff < UART_RXBUFSIZE -1) {
152 if(!hook_running && uart_hook){
155 sei(); /* reenable interrupts, avoid recursion!!! */
158 } while(uart_getc_nb((char*)&t));
163 if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
168 if (rxhead == (rxbuf + UART_RXBUFSIZE))
172 //reads the buffer to clear the interrupt condition
175 if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
179 if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
186 #endif // UART_INTERRUPT
190 PORTD |= 0x01; //Pullup an RXD an
192 UCSRB |= (1<<TXEN); //UART TX einschalten
195 UCSRC = (3<<UCSZ0); //Asynchron 8N1
198 UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
200 UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
202 UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
203 UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
205 #ifdef UART_INTERRUPT
207 rxhead = rxtail = rxbuf;
208 txhead = txtail = txbuf;
211 UCSRB |= _BV(RXCIE) | _BV(UDRIE);
214 // UCSRB |= _BV(UDRIE);
216 #endif // UART_INTERRUPT
219 #ifdef UART_INTERRUPT
222 void uart_insertc(char c){
225 diff = txhead - txtail;
226 if ( diff < 0 ) diff += UART_TXBUFSIZE;
227 } while ( diff >= UART_TXBUFSIZE -1 );
230 if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
233 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
236 #endif /* UART_XON_XOFF */
237 void uart_putc(char c) {
242 diff = txhead - txtail;
243 if ( diff < 0 ) diff += UART_TXBUFSIZE;
244 } while ( diff >= UART_TXBUFSIZE -1 );
248 if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
250 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
253 #else // WITHOUT INTERRUPT
254 void uart_putc(char c) {
255 while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
258 while (txon==nogo) /* warte bis XON empfangen */
261 UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
263 #endif // UART_INTERRUPT
266 void uart_putstr(char *str) {
272 void uart_putstr_P(PGM_P str) {
274 while((tmp = pgm_read_byte(str))) {
280 void uart_hexdump(const void* buf, int len)
282 unsigned char table[]={'0','1','2','3','4','5','6','7',
283 '8','9','a','b','c','d','e','f'};
285 uart_putc(table[((*((char*)buf))>>4)&0xf]);
286 uart_putc(table[(*((char*)buf))&0xf]);
293 #ifdef UART_INTERRUPT
298 while(rxhead==rxtail)
303 if (rxtail == (rxbuf + UART_RXBUFSIZE))
308 #else // WITHOUT INTERRUPT
312 while (!(UCSRA & (1<<RXC)))
313 ; // warten bis Zeichen verfuegbar
317 if (t==XOFF) txon=nogo;
319 return t; // Zeichen aus UDR zurueckgeben
321 #endif // UART_INTERRUPT
323 // returns 1 on success
324 #ifdef UART_INTERRUPT
325 char uart_getc_nb(char *c)
327 if (rxhead==rxtail) return 0;
330 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
334 #else // WITHOUT INTERRUPT
335 char uart_getc_nb(char *c)
337 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
340 if (*c==XON) txon=go;
341 if (*c==XOFF) txon=nogo;
348 #endif // UART_INTERRUPT