3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
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.
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.
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/>.
23 #include "hw_uart_regs.h"
24 #include "uart_defines.h"
26 void calc_baud_values(uint32_t baudrate, uint16_t* intdivider, uint8_t* fracdivider, uint8_t* highspeed){
29 uart_freq = sysclk_get_freq();
30 *highspeed = (baudrate*16>uart_freq)?1:0;
31 tmp = (uint64_t)uart_freq*128/((*highspeed?8:16)*baudrate);
34 *fracdivider = (uint8_t)(tmp&0x3f);
39 uint32_t uart_base[] = { UART0_BASE, UART1_BASE, UART2_BASE };
42 uint32_t gpio_base[] =
43 { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE,
44 GPIOE_BASE, GPIOF_BASE, GPIOG_BASE, GPIOH_BASE,
49 uint8_t uart_tx_gpio[] = { GPIOA, GPIOD, GPIOG };
51 uint8_t uart_rx_gpio[] = { GPIOA, GPIOD, GPIOG };
53 uint8_t uart_tx_pin[] = { 1, 1, 1 };
55 uint8_t uart_rx_pin[] = { 0, 0, 0 };
57 uint8_t uart_tx_pctl[] = {1, 5, 1};
59 uint8_t uart_rx_pctl[] = {1, 5, 1};
61 uint8_t uart_init(uint8_t uartno, uint32_t baudrate, uint8_t databits, uint8_t paraty, uint8_t stopbits){
67 return UART_ERROR_WRONG_UART;
69 if(databits>UART_DATABITS_8){
70 return UART_ERROR_WRONG_DATABITS;
72 if(paraty>UART_PARATY_SPACE){
73 return UART_ERROR_WRONG_PARATY;
75 if(stopbits>UART_STOPBITS_TWO){
76 return UART_ERROR_WRONG_STOPBITS;
78 /* enable clock for uart */
79 HW_REG(SYSCTL_BASE+RCGC1_OFFSET) |= _BV(uartno);
80 /* enable clock for gpio*/
81 HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= _BV(uart_rx_gpio[uartno]) | _BV(uart_tx_gpio[uartno]);
82 HW_REG(SYSCTL_BASE+RCGC2_OFFSET) |= 1;
84 HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* open drain */
85 HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_ODR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* open drain */
86 HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-up */
87 HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PUR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-up */
88 HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_rx_pin[uartno]); /* pull-down*/
89 HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_PDR_OFFSET) &= ~_BV(uart_tx_pin[uartno]); /* pull-down*/
90 HW_REG(gpio_base[uart_rx_gpio[uartno]] + GPIO_DEN_OFFSET) |= _BV(uart_rx_pin[uartno]); /* digital enable */
91 HW_REG(gpio_base[uart_tx_gpio[uartno]] + GPIO_DEN_OFFSET) |= _BV(uart_tx_pin[uartno]); /* digital enable */
93 /* switch to alternate function for rx */
94 HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_rx_pin[uartno]);
95 /* switch to alternate function for tx */
96 HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_AFSEL_OFFSET) |= _BV(uart_tx_pin[uartno]);
97 /* switch multiplexer to uart for rx */
98 HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_rx_pin[uartno]*4));
99 HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_rx_pctl[uartno])<<(uart_rx_pin[uartno]*4));
100 /* switch multiplexer to uart for tx */
101 HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) &= ~(0x0f<<(uart_tx_pin[uartno]*4));
102 HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_PCTL_OFFSET) |= ((uart_tx_pctl[uartno])<<(uart_tx_pin[uartno]*4));
103 /* set pins to be 2mA */
104 HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_rx_pin[uartno]);
105 HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DR2R_OFFSET) |= _BV(uart_tx_pin[uartno]);
106 /* configure rx pin as input */
107 HW_REG(gpio_base[uart_rx_gpio[uartno]]+GPIO_DIR_OFFSET) &= ~_BV(uart_rx_pin[uartno]);
108 /* configure tx pin as output */
109 HW_REG(gpio_base[uart_tx_gpio[uartno]]+GPIO_DIR_OFFSET) |= _BV(uart_tx_pin[uartno]);
112 HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UARTEN);
113 /* set baudrate parameters */
115 calc_baud_values(baudrate,
116 (uint16_t*)&HW_REG(uart_base[uartno]+UARTIBRD_OFFSET),
117 (uint8_t*)&HW_REG(uart_base[uartno]+UARTFBRD_OFFSET),
119 /* wait until uart is no longer busy */
120 while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_BUSY))
123 HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) &= ~_BV(UART_FEN);
124 /* set line parameters (bits, paraty, stopbits*/
125 tmp = HW_REG(uart_base[uartno]+UARTLCRH_OFFSET);
127 tmp |= (paraty==UART_PARATY_MARK||paraty==UART_PARATY_SPACE)?_BV(7):0; /* set flag for mark or space paraty*/
129 tmp |= _BV(UART_FEN); /* enable FIFOs */
130 tmp |= (stopbits==UART_STOPBITS_TWO)?_BV(3):0;
131 tmp |= (paraty==UART_PARATY_EVEN || paraty==UART_PARATY_MARK)?_BV(2):0;
132 tmp |= (paraty!=UART_PARATY_NONE)?_BV(1):0;
133 HW_REG(uart_base[uartno]+UARTLCRH_OFFSET) = tmp;
134 /* set the highspeed bit accordingly */
136 HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_HSE);
138 HW_REG(uart_base[uartno]+UARTCTL_OFFSET) &= ~_BV(UART_HSE);
140 HW_REG(uart_base[uartno]+UARTFR_OFFSET) = 0;
141 HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UART_RXE) | _BV(UART_TXE);
142 HW_REG(uart_base[uartno]+UARTCTL_OFFSET) |= _BV(UARTEN);
144 return UART_ERROR_OK;
148 void uart_putc(uint8_t uartno, uint8_t byte){
152 /* wait while the FIFO is full */
153 while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_TXFF))
155 HW_REG(uart_base[uartno]+UARTDR_OFFSET) = (uint32_t)byte;
158 uint16_t uart_getc(uint8_t uartno){
162 /* wait while the FIFO is empty */
163 while(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))
165 return (uint16_t)HW_REG(uart_base[uartno]+UARTDR_OFFSET);
168 uint32_t uart_dataavail(uint8_t uartno){
172 /* wait while the FIFO is empty */
173 return(HW_REG(uart_base[uartno]+UARTFR_OFFSET)&_BV(UART_RXFE))?0:1;