2 * Copyright (c) 2015, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <ucg_avr_uart.h>
32 static void disable_tx_irq(struct ucg_uart *uart)
34 struct ucg_avr_uart *avr_uart = uart->driver_data;
35 *avr_uart->reg_ucsrb &= ~(1 << avr_uart->bit_udrie);
38 static void enable_tx_irq(struct ucg_uart *uart)
40 struct ucg_avr_uart *avr_uart = uart->driver_data;
41 *avr_uart->reg_ucsrb |= (1 << avr_uart->bit_udrie);
44 static uint8_t tx_ready(struct ucg_uart *uart)
46 struct ucg_avr_uart *avr_uart = uart->driver_data;
47 return !!(*avr_uart->reg_ucsra & (1 << avr_uart->bit_udre));
50 static uint8_t rx_ready(struct ucg_uart *uart)
52 struct ucg_avr_uart *avr_uart = uart->driver_data;
53 return !!(*avr_uart->reg_ucsra & (1 << avr_uart->bit_rxc));
56 static void set_udr(struct ucg_uart *uart, char c)
58 struct ucg_avr_uart *avr_uart = uart->driver_data;
59 *avr_uart->reg_udr = c;
62 static char get_udr(struct ucg_uart *uart)
64 struct ucg_avr_uart *avr_uart = uart->driver_data;
65 return *avr_uart->reg_udr;
68 static int set_conf(struct ucg_uart *uart, const struct ucg_uart_config *conf)
70 struct ucg_avr_uart *avr_uart = uart->driver_data;
73 uint8_t use_u2x = 1; /* always use double speed */
75 if (conf->enable == 0) {
76 *avr_uart->reg_ucsrb = 0;
81 baudreg = (F_CPU / (conf->baudrate * 8UL)) - 1;
83 baudreg = (F_CPU / (conf->baudrate * 16UL)) - 1;
85 lo = (uint8_t)baudreg;
86 hi = (uint8_t)((baudreg >> 8) & 0xF);
88 *avr_uart->reg_ubrrl = lo;
89 *avr_uart->reg_ubrrh = hi;
91 *avr_uart->reg_ucsra = (
92 (use_u2x << avr_uart->bit_u2x));
93 *avr_uart->reg_ucsrb = (
94 (1 << avr_uart->bit_txen) |
95 (1 << avr_uart->bit_rxen) |
96 (1 << avr_uart->bit_rxcie));
101 const struct ucg_uart_driver_ops avr_uart_ops = {
102 .disable_tx_irq = disable_tx_irq,
103 .enable_tx_irq = enable_tx_irq,
104 .tx_ready = tx_ready,
105 .rx_ready = rx_ready,
108 .set_conf = set_conf,