]> git.cryptolib.org Git - avr-crypto-lib.git/blob - uart.c
new, derived from old avr/crypto + cast5
[avr-crypto-lib.git] / uart.c
1 /* USART-Init beim ATmegaXX */
2
3 #include "config.h"
4
5 #include <avr/io.h>
6 //#include <avr/signal.h>
7 #include <avr/interrupt.h>
8 #include <stdlib.h>
9
10 #include "uart.h"
11
12 #ifdef ATMEGA128
13 #define UCSRB UCSR0B
14 #define UCSRC UCSR0C
15 #define UDR UDR0
16 #define UBRRH UBRR0H
17 #define UBRRL UBRR0L
18 #define URSEL UMSEL
19 #endif
20
21
22 #define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_CPU)/((UART_BAUD_RATE)*16L)-1)
23
24
25 #ifdef UART_INTERRUPT
26 volatile static char rxbuf[UART_RXBUFSIZE];
27 volatile static char txbuf[UART_TXBUFSIZE];
28 volatile static char *volatile rxhead, *volatile rxtail;
29 volatile static char *volatile txhead, *volatile txtail;
30
31
32 SIGNAL(SIG_UART_DATA) {
33 #ifdef UART_LEDS        
34         PORTC ^= 0x01;
35 #endif
36         
37         if ( txhead == txtail ) {
38                 UCSRB &= ~(1 << UDRIE);         /* disable data register empty IRQ */
39         } else {
40                 UDR = *txtail;                  /* schreibt das Zeichen x auf die Schnittstelle */
41                 if (++txtail == (txbuf + UART_TXBUFSIZE)) txtail = txbuf;
42         }
43 }
44
45 SIGNAL(SIG_UART_RECV) {
46         int diff; 
47
48 #ifdef UART_LEDS
49         PORTC ^= 0x02;
50 #endif
51         
52         /* buffer full? */
53         diff = rxhead - rxtail;
54         if ( diff < 0 ) diff += UART_RXBUFSIZE;
55         if (diff < UART_RXBUFSIZE -1) {
56                 // buffer NOT full
57                 *rxhead = UDR;
58                 if (++rxhead == (rxbuf + UART_RXBUFSIZE)) rxhead = rxbuf;
59         } else {
60                 UDR;                            //reads the buffer to clear the interrupt condition
61         }
62 }
63
64 #endif // UART_INTERRUPT
65
66
67 void uart_init(void) {
68         PORTD |= 0x01;                          //Pullup an RXD an
69
70         UCSRB |= (1<<TXEN);                     //UART TX einschalten
71         UCSRC |= (1<<URSEL)|(3<<UCSZ0);         //Asynchron 8N1
72
73         UCSRB |= ( 1 << RXEN );                 //Uart RX einschalten
74
75         UBRRH=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU)>>8);
76         UBRRL=(uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_CPU));
77
78 #ifdef UART_INTERRUPT
79         // init buffers
80         rxhead = rxtail = rxbuf;
81         txhead = txtail = txbuf;
82
83         // activate rx IRQ
84         UCSRB |= (1 << RXCIE);
85 #endif // UART_INTERRUPT
86 }
87
88 #ifdef UART_INTERRUPT
89 void uart_putc(char c) {
90         volatile int diff;
91
92         /* buffer full? */
93         do {
94                 diff = txhead - txtail;
95                 if ( diff < 0 ) diff += UART_TXBUFSIZE;
96         } while ( diff >= UART_TXBUFSIZE -1 );
97
98         cli();
99         *txhead = c;
100         if (++txhead == (txbuf + UART_TXBUFSIZE)) txhead = txbuf;
101
102         UCSRB |= (1 << UDRIE);          /* enable data register empty IRQ */
103         sei();
104 }
105 #else  // WITHOUT INTERRUPT
106 void uart_putc(char c) {
107         while (!(UCSRA & (1<<UDRE))); /* warten bis Senden moeglich                   */
108         UDR = c;                      /* schreibt das Zeichen x auf die Schnittstelle */
109 }
110 #endif // UART_INTERRUPT
111
112
113 void uart_putstr(char *str) {
114         while(*str) {
115                 uart_putc(*str++);
116         }
117 }
118
119 void uart_putstr_P(PGM_P str) {
120         char tmp;
121         while((tmp = pgm_read_byte(str))) {
122                 uart_putc(tmp);
123                 str++;
124         }
125 }
126
127 void uart_hexdump(void* buf, int len)
128 {
129         unsigned char table[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
130         
131         while(len--){
132                 uart_putc(table[((*((char*)buf))>>4)&0xf]);
133                 uart_putc(table[(*((char*)buf))&0xf]);
134                 uart_putc(' ');
135                 ++buf;
136         }
137 }
138
139
140 #ifdef UART_INTERRUPT
141 char uart_getc(void)
142 {
143         char val;
144
145         while(rxhead==rxtail) ;
146
147         val = *rxtail;
148         if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
149
150         return val;
151 }
152 #else  // WITHOUT INTERRUPT
153 char uart_getc(void)
154 {
155         while (!(UCSRA & (1<<RXC)));    // warten bis Zeichen verfuegbar
156         return UDR;                     // Zeichen aus UDR zurueckgeben
157 }
158 #endif // UART_INTERRUPT
159
160 // returns 1 on success
161 #ifdef UART_INTERRUPT
162 char uart_getc_nb(char *c)
163 {
164         if (rxhead==rxtail) return 0;
165
166         *c = *rxtail;
167         if (++rxtail == (rxbuf + UART_RXBUFSIZE)) rxtail = rxbuf;
168
169         return 1;
170 }
171 #else  // WITHOUT INTERRUPT
172 char uart_getc_nb(char *c)
173 {
174         if (UCSRA & (1<<RXC)) {         // Zeichen verfuegbar
175                 *c = UDR;
176                 return 1;
177         }
178
179         return 0;
180 }
181 #endif // UART_INTERRUPT