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>
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
64 void uart_insertc(char c);
66 #define uart_insertc uart_putc
67 #endif /* UART_INTERRUPT */
70 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
73 typedef enum{go=1,nogo=0} gonogo;
74 static gonogo txon=go;
75 static gonogo rxon=go;
79 volatile static char rxbuf[UART_RXBUFSIZE];
80 volatile static char txbuf[UART_TXBUFSIZE];
81 volatile static char *volatile rxhead, *volatile rxtail;
82 volatile static char *volatile txhead, *volatile txtail;
85 void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
88 ISR(USART_UDRE_vect) {
93 if ( txhead == txtail ) {
94 UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
100 UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
101 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
105 ISR(USART_RXC_vect) {
109 static volatile uint8_t hook_running=0;
126 diff = rxhead - rxtail;
127 if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
128 if (diff < UART_RXBUFSIZE -1) {
131 if(!hook_running && uart_hook){
134 sei(); /* reenable interrupts, avoid recursion!!! */
137 } while(uart_getc_nb((char*)&t));
142 if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
147 if (rxhead == (rxbuf + UART_RXBUFSIZE))
151 //reads the buffer to clear the interrupt condition
154 if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
158 if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
165 #endif // UART_INTERRUPT
169 PORTD |= 0x01; //Pullup an RXD an
171 UCSRB |= (1<<TXEN); //UART TX einschalten
174 UCSRC = (3<<UCSZ0); //Asynchron 8N1
177 UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
179 UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
181 UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
182 UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
184 #ifdef UART_INTERRUPT
186 rxhead = rxtail = rxbuf;
187 txhead = txtail = txbuf;
190 UCSRB |= _BV(RXCIE) | _BV(UDRIE);
193 // UCSRB |= _BV(UDRIE);
195 #endif // UART_INTERRUPT
198 #ifdef UART_INTERRUPT
201 void uart_insertc(char c){
204 diff = txhead - txtail;
205 if ( diff < 0 ) diff += UART_TXBUFSIZE;
206 } while ( diff >= UART_TXBUFSIZE -1 );
209 if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
212 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
215 #endif /* UART_XON_XOFF */
216 void uart_putc(char c) {
221 diff = txhead - txtail;
222 if ( diff < 0 ) diff += UART_TXBUFSIZE;
223 } while ( diff >= UART_TXBUFSIZE -1 );
227 if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
229 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
232 #else // WITHOUT INTERRUPT
233 void uart_putc(char c) {
234 while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
237 while (txon==nogo) /* warte bis XON empfangen */
240 UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
242 #endif // UART_INTERRUPT
245 void uart_putstr(char *str) {
251 void uart_putstr_P(PGM_P str) {
253 while((tmp = pgm_read_byte(str))) {
259 void uart_hexdump(const void* buf, int len)
261 unsigned char table[]={'0','1','2','3','4','5','6','7',
262 '8','9','a','b','c','d','e','f'};
264 uart_putc(table[((*((char*)buf))>>4)&0xf]);
265 uart_putc(table[(*((char*)buf))&0xf]);
272 #ifdef UART_INTERRUPT
277 while(rxhead==rxtail)
282 if (rxtail == (rxbuf + UART_RXBUFSIZE))
287 #else // WITHOUT INTERRUPT
291 while (!(UCSRA & (1<<RXC)))
292 ; // warten bis Zeichen verfuegbar
296 if (t==XOFF) txon=nogo;
298 return t; // Zeichen aus UDR zurueckgeben
300 #endif // UART_INTERRUPT
302 // returns 1 on success
303 #ifdef UART_INTERRUPT
304 char uart_getc_nb(char *c)
306 if (rxhead==rxtail) return 0;
309 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
313 #else // WITHOUT INTERRUPT
314 char uart_getc_nb(char *c)
316 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
319 if (*c==XON) txon=go;
320 if (*c==XOFF) txon=nogo;
327 #endif // UART_INTERRUPT