]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/uart_i.c
forgotten uart files
[avr-crypto-lib.git] / test_src / uart_i.c
1 /* uart_i.c */
2 /*
3     This file is part of the AVR-uart_i.
4     Copyright (C) 2009  Daniel Otte (daniel.otte@rub.de)
5
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.
10
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.
15
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/>.
18 */
19 /**
20  * \file     uart_i.c
21  * \email    daniel.otte@rub.de
22  * \author   Daniel Otte 
23  * \date     2009-07-24
24  * \license  GPLv3 or later
25  * \ingroup  uart_i
26  * \brief    implementation of interrupt based uart
27  */
28
29 #include <stdlib.h>
30 #include <avr/interrupt.h>
31 #include "config.h"
32 #include "uart.h"
33
34 #define XON_VALUE  0x11
35 #define XOFF_VALUE 0x13
36
37 #if UART0_I
38
39 #ifndef UART0_PARATY
40 # warning "UART0: using default paraty: 'none'"
41 # define UART0_PARATY UART_PARATY_NONE
42 #endif
43
44 #ifndef UART0_STOPBITS
45 # warning "UART0: using default ammount of stop bits: '1'"
46 # define UART0_STOPBITS UART_STOPBITS_1
47 #endif
48
49 #ifndef UART0_DATABITS
50 # warning "UART0: using default ammount of data bits: '8'"
51 # define UART0_DATABITS UART_DATABITS_8
52 #endif
53
54 #if UART0_DATABITS == UART_DATABITS_9
55 # error "UART0: data bits==9 not supported"
56 #endif
57
58
59 #ifdef UDR
60 # define OLD_UART
61 # ifdef UDR0
62 #  error "can not decide which registernames to use, UDR and UDR0 are defined"
63 # endif
64 #endif
65
66 #ifdef OLD_UART
67 # define UCSR0A UCSRA
68 # define UCSR0B UCSRB
69 # define UCSR0C UCSRC
70 # define UBRR0H UBRRH
71 # define UBRR0L UBRRL
72 # define UDR0   UDR
73 # define TXEN0  TXEN
74 # define RXEN0  RXEN
75 # define UDRE0  UDRE
76 # define RXC0   RXC
77 # define TXB80  TXB8
78 # define RXB80  RXB8
79 #endif
80
81 uart0_ctx_t uart0_ctx;
82 uint8_t uart0_rxbuffer[UART0_RXBUFFER_SIZE];
83 uint8_t uart0_txbuffer[UART0_TXBUFFER_SIZE];
84
85 void uart0_init(void){
86         circularbytebuffer_init2(UART0_RXBUFFER_SIZE, &(uart0_ctx.rxb), uart0_rxbuffer);
87         circularbytebuffer_init2(UART0_TXBUFFER_SIZE, &(uart0_ctx.txb), uart0_txbuffer);
88 #if UART0_HOOK
89         uart0_ctx.hook = NULL;
90         uart0_ctx.hook_running = 0;
91 #endif
92 #if UART0_SWFLOWCTRL
93         uart0_ctx.txon = 1;
94         uart0_ctx.rxon = 1;
95 #endif
96         #define BAUD UART0_BAUD_RATE
97         #include <util/setbaud.h>       
98         UBRR0H = UBRRH_VALUE;
99         UBRR0L = UBRRL_VALUE;
100         #if USE_2X
101         UCSR0A |= _BV(U2X0);
102         #else
103         UCSR0A &= ~_BV(U2X0);
104         #endif
105         UCSR0C = (UART0_PARATY<<4)|(UART0_STOPBITS<<3)|((UART0_DATABITS&3)<<1);
106         UCSR0B = _BV(RXCIE0) | _BV(UDRIE0) | _BV(RXEN0) | _BV(TXEN0) ; /* enable TX and RX and interrupts */
107         sei();
108 }
109
110 ISR(USART0_UDRE_vect){
111         uint16_t x;
112         x = circularbytebuffer_get_fifo(&(uart0_ctx.txb));
113         if(x==0xffff){
114                 /* the transmit buffer is empty, disable interrupt */
115                 UCSR0B &= (uint8_t)~_BV(UDRIE0);
116                 return;
117         }
118 #if UART0_SWFLOWCTRL
119         while(!uart0_ctx.txon)
120                 ;
121 #endif          
122         UDR0 = x;
123 }
124
125 void uart0_putc (uint16_t c){
126 #if UART0_SWFLOWCTRL
127         while(!uart0_ctx.txon)
128                 ;
129 #endif  
130         while(circularbytebuffer_cnt(&(uart0_ctx.txb))==UART0_TXBUFFER_SIZE)
131                 ;
132         cli();          
133         circularbytebuffer_append((uint8_t)c, &(uart0_ctx.txb));
134         sei();
135         UCSR0B |= (uint8_t)_BV(UDRIE0);
136 }
137
138 ISR(USART0_RX_vect){
139         uint16_t c;
140         c = UDR0;
141 #if UART0_SWFLOWCTRL
142         if(c==XON_VALUE){
143                 uart0_ctx.txon = 1;
144                 return;
145         }
146         if(c==XOFF_VALUE){
147                 uart0_ctx.txon = 0;
148                 return;
149         }
150 #endif          
151 #if     UART0_HOOK
152         if((!uart0_ctx.hook_running) && uart0_ctx.hook){
153                 uart0_ctx.hook_running=1;
154                 sei();
155                 do{
156                         uart0_ctx.hook(c);
157                 }while((c=circularbytebuffer_get_fifo(&(uart0_ctx.rxb)))!=0xffff);
158                 uart0_ctx.hook_running=0;
159                 return;
160         }
161 #endif
162         if(circularbytebuffer_cnt(&(uart0_ctx.rxb))==UART0_RXBUFFER_SIZE)
163                 return;
164         circularbytebuffer_append(c, &(uart0_ctx.rxb));
165 #if UART0_SWFLOWCTRL
166         if(circularbytebuffer_cnt(&(uart0_ctx.rxb))>UART0_THRESH_HIGH && uart0_ctx.rxon){
167                 uart0_ctx.rxon = 0;
168                 circularbytebuffer_push(XOFF_VALUE, &(uart0_ctx.txb));
169                 UCSR0B |= (uint8_t)_BV(UDRIE0);
170         }
171         if(circularbytebuffer_cnt(&(uart0_ctx.rxb))<UART0_THRESH_LOW && !uart0_ctx.rxon){
172                 uart0_ctx.rxon = 1;
173                 circularbytebuffer_push(XON_VALUE, &(uart0_ctx.txb));
174                 UCSR0B |= (uint8_t)_BV(UDRIE0);
175         }
176 #endif          
177 }
178
179 uint16_t uart0_getc(void){
180         uint8_t ret;
181         while(circularbytebuffer_cnt(&(uart0_ctx.rxb))==0)
182                 ;
183         cli();  
184         ret = circularbytebuffer_get_fifo(&(uart0_ctx.rxb));
185         sei();
186         return  ret;
187 }
188
189 uint8_t uart0_dataavail(void){
190         return circularbytebuffer_cnt(&(uart0_ctx.rxb));
191 }
192
193 #if     UART0_HOOK
194 void uart0_sethook(void(*fpt)(uint8_t)){
195         uart0_ctx.hook = fpt;
196 }
197 #endif
198
199 #endif /* UART0_I */