2 * Copyright Droids Corporation, Microb Technology, Eirbot (2005)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: uart.c,v 1.33.4.7 2009-01-23 23:08:42 zer0 Exp $
22 /* Olivier MATZ, Droids-corp 2004 - 2009 */
25 #include <aversive/list.h>
28 #include <uart_defs.h>
29 #include <uart_private.h>
31 struct cirbuf g_tx_fifo[UART_HW_NUM];
32 struct cirbuf g_rx_fifo[UART_HW_NUM];
34 /* global vars are initialized to 0 (NULL) */
35 event *rx_event[UART_HW_NUM];
36 event *tx_event[UART_HW_NUM];
38 const struct regs uart_regs[UART_HW_NUM] = {
82 * This is the interruption function which occurs when the entire
83 * frame in the transmit shift register has been shifted out and
84 * there is no new data in the transmit buffer.
87 #ifndef USART0_UDRE_vect
88 #if defined(USART_UDRE_vect)
89 #define USART0_UDRE_vect USART_UDRE_vect
90 #elif defined(SIG_USART0_DATA)
91 #define USART0_UDRE_vect SIG_USART0_DATA
92 #elif defined(SIG_UART0_DATA)
93 #define USART0_UDRE_vect SIG_UART0_DATA
96 SIGNAL(USART0_UDRE_vect)
98 uart_send_next_char(0);
102 #ifndef USART1_UDRE_vect
103 #if defined(SIG_USART1_DATA)
104 #define USART1_UDRE_vect SIG_USART1_DATA
105 #elif defined(SIG_UART1_DATA)
106 #define USART1_UDRE_vect SIG_UART1_DATA
109 SIGNAL(USART1_UDRE_vect)
111 uart_send_next_char(1);
115 #ifndef USART2_UDRE_vect
116 #if defined(SIG_USART2_DATA)
117 #define USART2_UDRE_vect SIG_USART2_DATA
118 #elif defined(SIG_UART2_DATA)
119 #define USART2_UDRE_vect SIG_UART2_DATA
122 SIGNAL(USART2_UDRE_vect)
124 uart_send_next_char(2);
128 #ifndef USART3_UDRE_vect
129 #if defined(SIG_USART3_DATA)
130 #define USART3_UDRE_vect SIG_USART3_DATA
131 #elif defined(SIG_UART3_DATA)
132 #define USART3_UDRE_vect SIG_UART3_DATA
135 SIGNAL(USART3_UDRE_vect)
137 uart_send_next_char(3);
141 static void uart_recv_next_char(uint8_t num);
144 * This is the interruption function which occurs when there is
145 * a new unread data in the reception buffer.
148 #ifndef USART0_RXC_vect
149 #if defined(USART_RXC_vect)
150 #define USART0_RXC_vect USART_RXC_vect
151 #elif defined(USART_RX_vect)
152 #define USART0_RXC_vect USART_RX_vect
153 #elif defined(USART0_RX_vect)
154 #define USART0_RXC_vect USART0_RX_vect
156 #if defined(SIG_USART0_RECV)
157 #define USART0_RXC_vect SIG_USART0_RECV
158 #elif defined(SIG_UART0_RECV)
159 #define USART0_RXC_vect SIG_UART0_RECV
163 SIGNAL(USART0_RXC_vect)
165 uart_recv_next_char(0);
169 #ifndef USART1_RXC_vect
170 #if defined(USART1_RX_vect)
171 #define USART1_RXC_vect USART1_RX_vect
173 #if defined(SIG_USART1_RECV)
174 #define USART1_RXC_vect SIG_USART1_RECV
175 #elif defined(SIG_UART1_RECV)
176 #define USART1_RXC_vect SIG_UART1_RECV
180 SIGNAL(USART1_RXC_vect)
182 uart_recv_next_char(1);
186 #ifndef USART2_RXC_vect
187 #if defined(USART2_RX_vect)
188 #define USART2_RXC_vect USART2_RX_vect
190 #if defined(SIG_USART2_RECV)
191 #define USART2_RXC_vect SIG_USART2_RECV
192 #elif defined(SIG_UART2_RECV)
193 #define USART2_RXC_vect SIG_UART2_RECV
197 SIGNAL(USART2_RXC_vect)
199 uart_recv_next_char(2);
203 #ifndef USART3_RXC_vect
204 #if defined(USART3_RX_vect)
205 #define USART3_RXC_vect USART3_RX_vect
207 #if defined(SIG_USART3_RECV)
208 #define USART3_RX_vect SIG_USART3_RECV
209 #elif defined(SIG_UART3_RECV)
210 #define USART3_RX_vect SIG_UART3_RECV
214 SIGNAL(USART3_RXC_vect)
216 uart_recv_next_char(3);
222 * transmit next character of fifo if any, and call the event function.
223 * This function is executed with intr locked.
225 void uart_send_next_char(uint8_t num)
227 #ifdef CONFIG_MODULE_UART_9BITS
228 if (uart_getconf_nbits(num) == 9) {
231 /* for 9 bits, it uses 2 places in the fifo */
232 if (CIRBUF_GET_LEN(&g_tx_fifo[num]) < 2) {
233 cbi(*uart_regs[num].ucsrb, UDRIE);
237 cirbuf_get_buf_tail(&g_tx_fifo[num], (char *)&elt, 2);
238 cirbuf_del_buf_tail(&g_tx_fifo[num], 2);
240 uart_set_udr_9bits(num, elt);
241 sbi(*uart_regs[num].ucsrb, UDRIE);
243 else /* 5, 6, 7 or 8 bits */
244 #endif /* CONFIG_MODULE_UART_9BITS */
248 if (CIRBUF_IS_EMPTY(&g_tx_fifo[num])) {
249 cbi(*uart_regs[num].ucsrb, UDRIE);
253 elt = cirbuf_get_tail(&g_tx_fifo[num]);
254 cirbuf_del_tail(&g_tx_fifo[num]);
255 uart_set_udr(num, elt);
256 sbi(*uart_regs[num].ucsrb, UDRIE);
263 static void uart_recv_next_char(uint8_t num)
265 #ifdef CONFIG_MODULE_UART_9BITS
266 if (uart_getconf_nbits() == 9) {
269 elt = uart_get_udr_9bits(num);
270 if (CIRBUF_GET_FREELEN(&g_rx_fifo[num]) >= 2) {
271 cirbuf_add_buf_head(&g_rx_fifo[num], (char *)&elt, 2);
275 ((event_9bits *)rx_event[num])(elt);
278 #endif /* CONFIG_MODULE_UART_9BITS */
282 elt = uart_get_udr(num);
283 if (!CIRBUF_IS_FULL(&g_rx_fifo[num])) {
284 cirbuf_add_head(&g_rx_fifo[num], elt);
295 #if (defined UDR0) && (defined UART0_COMPILE)
296 uart_setconf(0, NULL);
299 #if (defined UDR1) && (defined UART1_COMPILE)
300 uart_setconf(1, NULL);
303 #if (defined UDR2) && (defined UART2_COMPILE)
304 uart_setconf(2, NULL);
307 #if (defined UDR3) && (defined UART3_COMPILE)
308 uart_setconf(3, NULL);