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
88 void uart_insertc(char c);
90 #define uart_insertc uart_putc
91 #endif /* UART_INTERRUPT */
94 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
97 typedef enum{go=1,nogo=0} gonogo;
98 static gonogo txon=go;
99 static gonogo rxon=go;
102 #ifdef UART_INTERRUPT
103 volatile static char rxbuf[UART_RXBUFSIZE];
104 volatile static char txbuf[UART_TXBUFSIZE];
105 volatile static char *volatile rxhead, *volatile rxtail;
106 volatile static char *volatile txhead, *volatile txtail;
109 void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
112 ISR(USART_UDRE_vect) {
117 if ( txhead == txtail ) {
118 UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
124 UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
125 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
129 ISR(USART_RXC_vect) {
133 static volatile uint8_t hook_running=0;
150 diff = rxhead - rxtail;
151 if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
152 if (diff < UART_RXBUFSIZE -1) {
155 if(!hook_running && uart_hook){
158 sei(); /* reenable interrupts, avoid recursion!!! */
161 } while(uart_getc_nb((char*)&t));
166 if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
171 if (rxhead == (rxbuf + UART_RXBUFSIZE))
175 //reads the buffer to clear the interrupt condition
178 if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
182 if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
189 #endif // UART_INTERRUPT
193 PORTD |= 0x01; //Pullup an RXD an
195 UCSRB |= (1<<TXEN); //UART TX einschalten
198 UCSRC = (3<<UCSZ0); //Asynchron 8N1
201 UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
203 UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
205 UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
206 UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
208 #ifdef UART_INTERRUPT
210 rxhead = rxtail = rxbuf;
211 txhead = txtail = txbuf;
214 UCSRB |= _BV(RXCIE) | _BV(UDRIE);
217 // UCSRB |= _BV(UDRIE);
219 #endif // UART_INTERRUPT
222 #ifdef UART_INTERRUPT
225 void uart_insertc(char c){
228 diff = txhead - txtail;
229 if ( diff < 0 ) diff += UART_TXBUFSIZE;
230 } while ( diff >= UART_TXBUFSIZE -1 );
233 if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
236 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
239 #endif /* UART_XON_XOFF */
240 void uart_putc(char c) {
245 diff = txhead - txtail;
246 if ( diff < 0 ) diff += UART_TXBUFSIZE;
247 } while ( diff >= UART_TXBUFSIZE -1 );
251 if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
253 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
256 #else // WITHOUT INTERRUPT
257 void uart_putc(char c) {
258 while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
261 while (txon==nogo) /* warte bis XON empfangen */
264 UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
266 #endif // UART_INTERRUPT
269 void uart_putstr(char *str) {
275 void uart_putstr_P(PGM_P str) {
277 while((tmp = pgm_read_byte(str))) {
283 void uart_hexdump(const void* buf, int len)
286 uart_putc(pgm_read_byte(hexdigit_tab_P + ((*((uint8_t*)buf))>>4)));
287 uart_putc(pgm_read_byte(hexdigit_tab_P + ((*((uint8_t*)buf))&0xf)));
294 #ifdef UART_INTERRUPT
299 while(rxhead==rxtail)
304 if (rxtail == (rxbuf + UART_RXBUFSIZE))
309 #else // WITHOUT INTERRUPT
313 while (!(UCSRA & (1<<RXC)))
314 ; // warten bis Zeichen verfuegbar
318 if (t==XOFF) txon=nogo;
320 return t; // Zeichen aus UDR zurueckgeben
322 #endif // UART_INTERRUPT
324 // returns 1 on success
325 #ifdef UART_INTERRUPT
326 char uart_getc_nb(char *c)
328 if (rxhead==rxtail) return 0;
331 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
335 #else // WITHOUT INTERRUPT
336 char uart_getc_nb(char *c)
338 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
341 if (*c==XON) txon=go;
342 if (*c==XOFF) txon=nogo;
349 #endif // UART_INTERRUPT