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_setconf.c,v 1.1.2.3 2009-01-03 16:24:50 zer0 Exp $
22 /* Olivier MATZ, Droids-corp 2004 - 2009 */
25 #include <uart_defs.h>
26 #include <uart_private.h>
28 /** The emission fifo of uart */
30 char g_tx0_buf[UART0_TX_FIFO_SIZE];
31 char g_rx0_buf[UART0_RX_FIFO_SIZE];
34 char g_tx1_buf[UART1_TX_FIFO_SIZE];
35 char g_rx1_buf[UART1_RX_FIFO_SIZE];
38 char g_tx2_buf[UART2_TX_FIFO_SIZE];
39 char g_rx2_buf[UART2_RX_FIFO_SIZE];
42 char g_tx3_buf[UART3_TX_FIFO_SIZE];
43 char g_rx3_buf[UART3_RX_FIFO_SIZE];
48 static int8_t uart_set_nbits_parity(uint8_t num, struct uart_config * u)
52 /* number of bit in the frame */
53 #ifdef CONFIG_MODULE_UART_9BITS
54 if (u->nbits < 5 || u->nbits > 9) {
58 if (u->nbits < 5 || u->nbits > 8) {
63 ucsrc |= ( ((u->nbits - 5) & 0x03) << UCSZ0 );
64 #ifdef CONFIG_MODULE_UART_9BITS
66 *uart_regs[num].ucsrb |= (1 << UCSZ2);
69 *uart_regs[num].ucsrb &= ~(1 << UCSZ2);
72 if (u->parity == UART_PARTITY_ODD)
73 ucsrc |= ((1 << UPM0) | (1 << UPM1));
74 else if (u->parity == UART_PARTITY_EVEN)
76 else if (u->parity != UART_PARTITY_NONE) {
81 if (u->stop_bits == UART_STOP_BITS_2)
83 else if (u->stop_bits != UART_STOP_BITS_1)
87 /* some uC use a special bit URSEL to access to UCSRC */
90 *uart_regs[num].ucsrc = ucsrc;
95 #else /* UART_IS_USART */
97 static int8_t uart_set_nbits_parity(int8_t num, struct uart_config * u)
99 /* number of bit in the frame */
101 *uart_regs[num].ucsrb &= ~(1 << CHR9);
102 #ifdef CONFIG_MODULE_UART_9BITS
103 else if (u->nbits == 9)
104 *uart_regs[num].ucsrb |= (1 << CHR9);
109 /* parity and stop */
110 if (u->parity != UART_PARTITY_NONE ||
111 u->stop_bits != UART_STOP_BITS_1) {
117 #endif /* UART_IS_USART */
122 static int8_t uart_set_baudreg(uint8_t num, uint16_t baudreg)
126 /* set msb bit of hi to 0 (useful fot uC with URSEL, and not
127 * important for the others because the baudreg will never be
129 lo = (uint8_t)baudreg;
130 hi = (uint8_t)(baudreg>>8) & 0x7F;
132 *uart_regs[num].ubrrl = lo;
133 *uart_regs[num].ubrrh = hi;
138 #else /* UART_IS_USART */
140 static int8_t uart_set_baudreg(uint8_t num, uint16_t baudreg)
145 hi=(uint8_t)(baudreg>>8);
149 *uart_regs[num].ubrrl = lo;
153 #endif /* UART_IS_USART */
155 /* configuration from uart_config.h */
156 #define UART_SET_STATICCONF(x) \
157 u->enabled = UART##x##_ENABLED; \
158 u->intr_enabled = UART##x##_INTERRUPT_ENABLED; \
159 u->use_double_speed = UART##x##_USE_DOUBLE_SPEED; \
160 u->parity = UART##x##_PARITY; \
161 u->stop_bits = UART##x##_STOP_BIT; \
162 u->nbits = UART##x##_NBITS; \
163 u->baudrate = UART##x##_BAUDRATE; \
166 int8_t uart_setconf(uint8_t num, struct uart_config *u)
168 uint8_t ret = ESUCCESS;
169 uint16_t baudrate_reg;
170 struct uart_config static_conf;
175 /* static configuration */
181 UART_SET_STATICCONF(0);
185 UART_SET_STATICCONF(1);
189 UART_SET_STATICCONF(2);
193 UART_SET_STATICCONF(3);
201 /* wait xmit finished (UDRE = 1) */
202 while( !(*uart_regs[num].ucsra & (1<<UDRE)) );
207 cirbuf_init(&g_tx_fifo[0], g_tx0_buf, 0, UART0_TX_FIFO_SIZE);
208 cirbuf_init(&g_rx_fifo[0], g_rx0_buf, 0, UART0_RX_FIFO_SIZE);
213 cirbuf_init(&g_tx_fifo[1], g_tx1_buf, 0, UART1_TX_FIFO_SIZE);
214 cirbuf_init(&g_rx_fifo[1], g_rx1_buf, 0, UART1_RX_FIFO_SIZE);
219 cirbuf_init(&g_tx_fifo[2], g_tx2_buf, 0, UART2_TX_FIFO_SIZE);
220 cirbuf_init(&g_rx_fifo[2], g_rx2_buf, 0, UART2_RX_FIFO_SIZE);
225 cirbuf_init(&g_tx_fifo[3], g_tx3_buf, 0, UART3_TX_FIFO_SIZE);
226 cirbuf_init(&g_rx_fifo[3], g_rx3_buf, 0, UART3_RX_FIFO_SIZE);
233 *uart_regs[num].ucsra = 0;
236 *uart_regs[num].ucsrb = ((1 << TXEN) | (1 << RXEN));
238 *uart_regs[num].ucsrb = 0;
239 goto out; /* no more conf */
242 /* we only enable recv interrupt, the xmit intrpt will be
243 * enabled in the xmit function */
245 *uart_regs[num].ucsrb |= (1 << RXCIE);
247 if (UART_HAS_U2X) { /* if u2x is supported */
248 if (u->use_double_speed) /* u2x is enabled */
249 *uart_regs[num].ucsra |= (1 << U2X);
251 *uart_regs[num].ucsra &= ~(1 << U2X);
253 else if (u->use_double_speed) {
258 uart_set_nbits_parity(num, u);
261 if(u->use_double_speed)
262 baudrate_reg = (F_CPU / (u->baudrate*8l)) - 1;
264 baudrate_reg = (F_CPU / (u->baudrate*16l)) - 1;
266 uart_set_baudreg(num, baudrate_reg);