Revision 241
implementing uart
uart.c | ||
---|---|---|
4 | 4 |
|
5 | 5 |
#include "errors.h" |
6 | 6 |
|
7 |
#define UART_RBR 0 |
|
8 |
#define UART_THR 0 |
|
9 |
#define UART_IER 1 |
|
10 |
#define UART_IIR 2 |
|
11 |
#define UART_FCR 2 |
|
12 |
#define UART_LCR 3 |
|
13 |
#define UART_MCR 4 |
|
14 |
#define UART_LSR 5 |
|
15 |
#define UART_MSR 6 |
|
16 |
#define UART_SR 7 |
|
17 |
|
|
18 |
#define UART_DLL 0 |
|
19 |
#define UART_DLM 1 |
|
20 |
|
|
21 |
#define UART_BITS_PER_CHAR_POS 0 |
|
22 |
#define UART_STOP_BITS_POS 2 |
|
23 |
#define UART_PARITY_POS 3 |
|
24 |
#define UART_BREAK_CONTROL_POS 6 |
|
25 |
#define UART_DLAB_POS 7 |
|
26 |
|
|
27 |
#define UART_BITS_PER_CHAR (BIT(0) | BIT(1)) |
|
28 |
#define UART_STOP_BITS (BIT(2)) |
|
29 |
#define UART_PARITY (BIT(3) | BIT(4) | BIT(5)) |
|
30 |
#define UART_BREAK_CONTROL (BIT(6)) |
|
31 |
#define UART_DLAB (BIT(7)) |
|
32 |
|
|
33 |
#define UART_GET_BITS_PER_CHAR(n) (((n)&UART_BITS_PER_CHAR) + 5) |
|
34 |
#define UART_GET_STOP_BITS(n) (((n)&UART_STOP_BITS)? 2 : 1) |
|
35 |
#define UART_GET_PARITY(n) (((n)&UART_PARITY )>>UART_PARITY_POS ) |
|
36 |
#define UART_GET_BREAK_CONTROL(n) (((n)&UART_BREAK_CONTROL)>>UART_BREAK_CONTROL_POS) |
|
37 |
#define UART_GET_DLAB(n) (((n)&UART_DLAB )>>UART_DLAB_POS ) |
|
38 |
#define UART_GET_DIV_LATCH(m,l) ((m)<<8 | (l)) |
|
39 |
#define UART_GET_DLL(n) ((n)&0xFF) |
|
40 |
#define UART_GET_DLM(n) (((n)>>8)&0xFF) |
|
41 |
|
|
7 | 42 |
int uart_get_config(int base_addr, uart_config *config){ |
8 | 43 |
int ret = SUCCESS; |
9 | 44 |
|
... | ... | |
23 | 58 |
config->stop_bits = UART_GET_STOP_BITS (config->config); |
24 | 59 |
config->parity = UART_GET_PARITY (config->config); |
25 | 60 |
config->break_control = UART_GET_BREAK_CONTROL(config->config); |
26 |
config->divisor_latch = config->dlm<<8 | config->dll; |
|
61 |
config->dlab = UART_GET_DLAB (config->config); |
|
62 |
config->divisor_latch = UART_GET_DIV_LATCH (config->dlm, config->dll); |
|
27 | 63 |
} |
28 | 64 |
void uart_print_config(uart_config config){ |
29 | 65 |
printf("Base address: 0x%X\n", config.base_addr); |
... | ... | |
41 | 77 |
} |
42 | 78 |
printf("Break control: %d\n", config.break_control); |
43 | 79 |
printf("Divisor latch: %d\n", config.divisor_latch); |
44 |
printf("Bit rate (x1000): %d\n", 1000*(uint32_t)UART_BITRATE/config.divisor_latch);
|
|
80 |
printf("Bit rate: %d\n", UART_BITRATE/config.divisor_latch);
|
|
45 | 81 |
} |
46 | 82 |
|
47 | 83 |
int uart_enable_divisor_latch(int base_addr){ |
... | ... | |
56 | 92 |
} |
57 | 93 |
|
58 | 94 |
int uart_write_config(int base_addr, uint8_t config){ |
59 |
printf("WRITING CONFIG 0x%02X TO 0x%X\n", config, base_addr); |
|
60 | 95 |
if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR; |
61 | 96 |
return SUCCESS; |
62 | 97 |
} |
... | ... | |
84 | 119 |
conf = (conf & (~UART_PARITY)) | parity; |
85 | 120 |
return uart_write_config(base_addr, conf); |
86 | 121 |
} |
87 |
int uart_set_bit_rate(int base_addr, float bit_rate){ printf("%s, L82\n", __func__);
|
|
122 |
int uart_set_bit_rate(int base_addr, float bit_rate){ |
|
88 | 123 |
int ret = SUCCESS; |
89 | 124 |
uint16_t latch = UART_BITRATE/bit_rate; |
90 |
uint8_t dll = latch&0xFF;
|
|
91 |
uint8_t dlm = (latch>>8)&0xFF;
|
|
125 |
uint8_t dll = UART_GET_DLL(latch);
|
|
126 |
uint8_t dlm = UART_GET_DLM(latch);
|
|
92 | 127 |
if((ret = uart_enable_divisor_latch(base_addr))) return ret; |
93 |
printf("dlm,dll=0x%02X%02X\n", dlm, dll); |
|
94 | 128 |
if(sys_outb(base_addr+UART_DLL, dll)) return WRITE_ERROR; |
95 | 129 |
if(sys_outb(base_addr+UART_DLM, dlm)) return WRITE_ERROR; |
96 | 130 |
if((ret = util_sys_inb(base_addr+UART_DLM, &dlm))) return ret; |
97 |
printf("dlm=0x%02X\n", dlm); |
|
98 |
printf("%s, L91\n", __func__); |
|
99 | 131 |
return SUCCESS; |
100 | 132 |
} |
Also available in: Unified diff