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>
26 #include "hexdigit_tab.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)
283 uart_putc(pgm_read_byte(hexdigit_tab_P + ((*((uint8_t*)buf))>>4)));
284 uart_putc(pgm_read_byte(hexdigit_tab_P + ((*((uint8_t*)buf))&0xf)));
291 #ifdef UART_INTERRUPT
296 while(rxhead==rxtail)
301 if (rxtail == (rxbuf + UART_RXBUFSIZE))
306 #else // WITHOUT INTERRUPT
310 while (!(UCSRA & (1<<RXC)))
311 ; // warten bis Zeichen verfuegbar
315 if (t==XOFF) txon=nogo;
317 return t; // Zeichen aus UDR zurueckgeben
319 #endif // UART_INTERRUPT
321 // returns 1 on success
322 #ifdef UART_INTERRUPT
323 char uart_getc_nb(char *c)
325 if (rxhead==rxtail) return 0;
328 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
332 #else // WITHOUT INTERRUPT
333 char uart_getc_nb(char *c)
335 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
338 if (*c==XON) txon=go;
339 if (*c==XOFF) txon=nogo;
346 #endif // UART_INTERRUPT