3 This file is part of the Crypto-avr-lib/microcrypt-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>
45 #define USART_UDRE_vect USART0_UDRE_vect
46 #define USART_RXC_vect USART0_RX_vect
61 void uart_insertc(char c);
63 #define uart_insertc uart_putc
64 #endif /* UART_INTERRUPT */
67 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
70 typedef enum{go=1,nogo=0} gonogo;
71 static gonogo txon=go;
72 static gonogo rxon=go;
76 volatile static char rxbuf[UART_RXBUFSIZE];
77 volatile static char txbuf[UART_TXBUFSIZE];
78 volatile static char *volatile rxhead, *volatile rxtail;
79 volatile static char *volatile txhead, *volatile txtail;
82 void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
85 ISR(USART_UDRE_vect) {
90 if ( txhead == txtail ) {
91 UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
97 UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
98 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
102 ISR(USART_RXC_vect) {
106 static volatile uint8_t hook_running=0;
123 diff = rxhead - rxtail;
124 if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
125 if (diff < UART_RXBUFSIZE -1) {
128 if(!hook_running && uart_hook){
131 sei(); /* reenable interrupts, avoid recursion!!! */
134 } while(uart_getc_nb((char*)&t));
139 if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
144 if (rxhead == (rxbuf + UART_RXBUFSIZE))
148 //reads the buffer to clear the interrupt condition
151 if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
155 if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
162 #endif // UART_INTERRUPT
166 PORTD |= 0x01; //Pullup an RXD an
168 UCSRB |= (1<<TXEN); //UART TX einschalten
171 UCSRC = (3<<UCSZ0); //Asynchron 8N1
174 UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
176 UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
178 UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
179 UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
181 #ifdef UART_INTERRUPT
183 rxhead = rxtail = rxbuf;
184 txhead = txtail = txbuf;
187 UCSRB |= _BV(RXCIE) | _BV(UDRIE);
190 // UCSRB |= _BV(UDRIE);
192 #endif // UART_INTERRUPT
195 #ifdef UART_INTERRUPT
198 void uart_insertc(char c){
201 diff = txhead - txtail;
202 if ( diff < 0 ) diff += UART_TXBUFSIZE;
203 } while ( diff >= UART_TXBUFSIZE -1 );
206 if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
209 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
212 #endif /* UART_XON_XOFF */
213 void uart_putc(char c) {
218 diff = txhead - txtail;
219 if ( diff < 0 ) diff += UART_TXBUFSIZE;
220 } while ( diff >= UART_TXBUFSIZE -1 );
224 if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
226 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
229 #else // WITHOUT INTERRUPT
230 void uart_putc(char c) {
231 while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
234 while (txon==nogo) /* warte bis XON empfangen */
237 UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
239 #endif // UART_INTERRUPT
242 void uart_putstr(char *str) {
248 void uart_putstr_P(PGM_P str) {
250 while((tmp = pgm_read_byte(str))) {
256 void uart_hexdump(const void* buf, int len)
258 unsigned char table[]={'0','1','2','3','4','5','6','7',
259 '8','9','a','b','c','d','e','f'};
261 uart_putc(table[((*((char*)buf))>>4)&0xf]);
262 uart_putc(table[(*((char*)buf))&0xf]);
269 #ifdef UART_INTERRUPT
274 while(rxhead==rxtail)
279 if (rxtail == (rxbuf + UART_RXBUFSIZE))
284 #else // WITHOUT INTERRUPT
288 while (!(UCSRA & (1<<RXC)))
289 ; // warten bis Zeichen verfuegbar
293 if (t==XOFF) txon=nogo;
295 return t; // Zeichen aus UDR zurueckgeben
297 #endif // UART_INTERRUPT
299 // returns 1 on success
300 #ifdef UART_INTERRUPT
301 char uart_getc_nb(char *c)
303 if (rxhead==rxtail) return 0;
306 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
310 #else // WITHOUT INTERRUPT
311 char uart_getc_nb(char *c)
313 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
316 if (*c==XON) txon=go;
317 if (*c==XOFF) txon=nogo;
324 #endif // UART_INTERRUPT