1 /* USART-Init beim ATmegaXX */
6 #include <avr/interrupt.h>
27 #define USART_UDRE_vect USART0_UDRE_vect
28 #define USART_RXC_vect USART0_RX_vect
43 void uart_insertc(char c);
45 #define uart_insertc uart_putc
46 #endif /* UART_INTERRUPT */
49 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16L)-1)
52 typedef enum{go=1,nogo=0} gonogo;
53 static gonogo txon=go;
54 static gonogo rxon=go;
58 volatile static char rxbuf[UART_RXBUFSIZE];
59 volatile static char txbuf[UART_TXBUFSIZE];
60 volatile static char *volatile rxhead, *volatile rxtail;
61 volatile static char *volatile txhead, *volatile txtail;
64 void (*uart_hook) (uint8_t) = (void*)0; /* this is a pointer to a function ;-) */
67 ISR(USART_UDRE_vect) {
72 if ( txhead == txtail ) {
73 UCSRB &= ~(1 << UDRIE); /* disable data register empty IRQ */
79 UDR = *txtail; /* schreibt das Zeichen x auf die Schnittstelle */
80 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
88 static volatile uint8_t hook_running=0;
105 diff = rxhead - rxtail;
106 if (diff < 0) diff += UART_RXBUFSIZE; /* diff is the amount of bytes in buffer */
107 if (diff < UART_RXBUFSIZE -1) {
110 if(!hook_running && uart_hook){
113 sei(); /* reenable interrupts, avoid recursion!!! */
116 } while(uart_getc_nb((char*)&t));
121 if (rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
126 if (rxhead == (rxbuf + UART_RXBUFSIZE))
130 //reads the buffer to clear the interrupt condition
133 if((diff > UART_XON_XOFF_THRESHOLD_1) && (rxon==go)){
137 if((diff < UART_XON_XOFF_THRESHOLD_2) && (rxon==nogo)){
144 #endif // UART_INTERRUPT
148 PORTD |= 0x01; //Pullup an RXD an
150 UCSRB |= (1<<TXEN); //UART TX einschalten
153 UCSRC = (3<<UCSZ0); //Asynchron 8N1
156 UCSRC |= (1<<URSEL)|(3<<UCSZ0); //Asynchron 8N1
158 UCSRB |= ( 1 << RXEN ); //Uart RX einschalten
160 UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
161 UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
163 #ifdef UART_INTERRUPT
165 rxhead = rxtail = rxbuf;
166 txhead = txtail = txbuf;
169 UCSRB |= _BV(RXCIE) | _BV(UDRIE);
172 // UCSRB |= _BV(UDRIE);
174 #endif // UART_INTERRUPT
177 #ifdef UART_INTERRUPT
180 void uart_insertc(char c){
183 diff = txhead - txtail;
184 if ( diff < 0 ) diff += UART_TXBUFSIZE;
185 } while ( diff >= UART_TXBUFSIZE -1 );
188 if (--txtail == (txbuf-1)) txtail += UART_TXBUFSIZE;
191 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
194 #endif /* UART_XON_XOFF */
195 void uart_putc(char c) {
200 diff = txhead - txtail;
201 if ( diff < 0 ) diff += UART_TXBUFSIZE;
202 } while ( diff >= UART_TXBUFSIZE -1 );
206 if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
208 UCSRB |= (1 << UDRIE); /* enable data register empty IRQ */
211 #else // WITHOUT INTERRUPT
212 void uart_putc(char c) {
213 while (!(UCSRA & (1<<UDRE))) /* warten bis Senden moeglich */
216 while (txon==nogo) /* warte bis XON empfangen */
219 UDR = c; /* schreibt das Zeichen x auf die Schnittstelle */
221 #endif // UART_INTERRUPT
224 void uart_putstr(char *str) {
230 void uart_putstr_P(PGM_P str) {
232 while((tmp = pgm_read_byte(str))) {
238 void uart_hexdump(void* buf, int len)
240 unsigned char table[]={'0','1','2','3','4','5','6','7',
241 '8','9','a','b','c','d','e','f'};
243 uart_putc(table[((*((char*)buf))>>4)&0xf]);
244 uart_putc(table[(*((char*)buf))&0xf]);
251 #ifdef UART_INTERRUPT
256 while(rxhead==rxtail)
261 if (rxtail == (rxbuf + UART_RXBUFSIZE))
266 #else // WITHOUT INTERRUPT
270 while (!(UCSRA & (1<<RXC)))
271 ; // warten bis Zeichen verfuegbar
275 if (t==XOFF) txon=nogo;
277 return t; // Zeichen aus UDR zurueckgeben
279 #endif // UART_INTERRUPT
281 // returns 1 on success
282 #ifdef UART_INTERRUPT
283 char uart_getc_nb(char *c)
285 if (rxhead==rxtail) return 0;
288 if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
292 #else // WITHOUT INTERRUPT
293 char uart_getc_nb(char *c)
295 if (UCSRA & (1<<RXC)) { // Zeichen verfuegbar
298 if (*c==XON) txon=go;
299 if (*c==XOFF) txon=nogo;
306 #endif // UART_INTERRUPT