support lolo's board
[protos/xbee-avr.git] / uart_getconf.c
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2005)
3  * 
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.
8  *
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.
13  *
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
17  *
18  *  Revision : $Id: uart_getconf.c,v 1.1.2.3 2009-02-20 20:16:09 zer0 Exp $
19  *
20  */
21
22 /* Olivier MATZ, Droids-corp 2004 - 2007 */
23
24 #include <uart.h>
25 #include <uart_defs.h>
26 #include <uart_private.h>
27
28 #if UART_IS_USART
29
30 static inline uint8_t get_ucsrc(uint8_t num)
31 {
32 #ifdef URSEL
33         uint8_t tmp;
34         /* on some uC, reading UCSRxC is a bit tricky */
35         switch(num) {
36 #ifdef UART0_COMPILE
37                 case 0:
38                         tmp = UBRR0H;
39                         tmp = UCSR0C;
40                         break;
41 #endif
42 #ifdef UART1_COMPILE
43                 case 1:
44                         tmp = UBRR1H;
45                         tmp = UCSR1C;
46                         break;
47 #endif
48 #ifdef UART2_COMPILE
49                 case 2:
50                         tmp = UBRR2H;
51                         tmp = UCSR2C;
52                         break;
53 #endif
54 #ifdef UART3_COMPILE
55                 case 3:
56                         tmp = UBRR3H;
57                         tmp = UCSR3C;
58                         break;
59 #endif
60                 default:
61                         tmp = 0;
62                         break;
63         }
64         return tmp;
65 #else
66         return *uart_regs[num].ucsrc;
67 #endif /* URSEL */
68 }
69
70 /* return number of bits in current conf. Intr must be disabled. */
71 uint8_t uart_getconf_nbits(uint8_t num)
72 {
73         uint8_t nbits;
74
75         nbits = (get_ucsrc(num) >> UCSZ0) & 0x03;
76 #ifdef CONFIG_MODULE_UART_9BITS
77         if (*uart_regs[num].ucsrb & (1 << UCSZ2))
78                 nbits += 4;
79 #endif
80         nbits += 5;
81         return nbits;
82 }
83
84 #else /* UART_IS_USART */
85
86 /* return number of bits in current conf */
87 uint8_t uart_getconf_nbits(uint8_t num)
88 {
89 #ifdef CONFIG_MODULE_UART_9BITS
90         if (*uart_regs[num].ucsrb & (uint8_t)(1 << CHR9))
91                 return 8;
92         else
93                 return 9;
94 #else
95         return 8;
96 #endif
97 }
98
99 #endif /* UART_IS_USART */
100
101
102 #if UART_IS_USART
103
104 /* return number of bits in current conf */
105 static inline uint16_t uart_get_baudreg(uint8_t num)
106 {
107         return ((uint16_t)*uart_regs[num].ubrrh << 8) | 
108                 (uint16_t)*uart_regs[num].ubrrl;
109 }
110
111 #else /* UART_IS_USART */
112
113 /* return number of bits in current conf */
114 static inline uint16_t uart_get_baudreg(uint8_t num)
115 {
116         return (uint16_t)*uart_regs[num].ubrrl;
117 }
118
119 #endif /* UART_IS_USART */
120
121
122 /* get the running uart configurtion */
123 void uart_getconf(uint8_t num, struct uart_config *u)
124 {
125         uint8_t tmp;
126         uint8_t flags;
127
128         IRQ_LOCK(flags);
129
130         /* XXX */
131         /* enabled if RXEN is set */
132         if (*uart_regs[num].ucsrb & (1 << RXEN))
133                 u->enabled = 1;
134         else
135                 u->enabled = 0;
136
137         /* intrp enabled if RXCIE is set */
138         if (*uart_regs[num].ucsrb & (1 << RXCIE))
139                 u->intr_enabled = 1;
140         else
141                 u->intr_enabled = 0;
142
143         /* use double speed */
144         if (UART_HAS_U2X && (*uart_regs[num].ucsra & (1 << U2X)))
145                 u->use_double_speed = 1;
146         else
147                 u->use_double_speed = 0;
148
149
150         /* parity */
151         if (UART_IS_USART) {
152                 tmp = get_ucsrc(num) & ((1 << UPM1) | (1 << UPM0));
153                 if (tmp == ((1 << UPM1) | (1 << UPM0)))
154                         u->parity = UART_PARTITY_ODD;
155                 else if (tmp == (1 << UPM1))
156                         u->parity = UART_PARTITY_EVEN;
157                 else
158                         u->parity = UART_PARTITY_NONE;
159         }
160         else {
161                 u->parity = UART_PARTITY_NONE;
162         }
163
164         /* stop_bits */
165         if  (UART_IS_USART && (get_ucsrc(num) & (1 << USBS))) {
166                 u->stop_bits = UART_STOP_BITS_2;
167         }
168         else {
169                 u->stop_bits = UART_STOP_BITS_1;
170         }
171
172         /* nbits */
173         u->nbits = uart_getconf_nbits(num);
174         u->baudrate = (F_CPU / ((uart_get_baudreg(num)+1) * 16)) ;
175
176         IRQ_UNLOCK(flags);
177 }