root / proj / src / uart.c @ 237
History | View | Annotate | Download (4.04 KB)
1 |
#include <lcom/lcf.h> |
---|---|
2 |
|
3 |
#include "uart.h" |
4 |
|
5 |
#include "errors.h" |
6 |
|
7 |
int uart_get_config(int base_addr, uart_config *config){ |
8 |
int ret = SUCCESS;
|
9 |
|
10 |
config->base_addr = base_addr; |
11 |
|
12 |
if((ret = util_sys_inb(base_addr+UART_LCR, &config->config))) return ret; |
13 |
|
14 |
if((ret = uart_enable_divisor_latch(base_addr))) return ret; |
15 |
if((ret = util_sys_inb(base_addr+UART_DLL, &config->dll ))) return ret; |
16 |
if((ret = util_sys_inb(base_addr+UART_DLM, &config->dlm ))) return ret; |
17 |
|
18 |
uart_parse_config(config); |
19 |
return ret;
|
20 |
} |
21 |
void uart_parse_config(uart_config *config){
|
22 |
config->bits_per_char = UART_GET_BITS_PER_CHAR(config->config); |
23 |
config->stop_bits = UART_GET_STOP_BITS (config->config); |
24 |
config->parity = UART_GET_PARITY (config->config); |
25 |
config->break_control = UART_GET_BREAK_CONTROL(config->config); |
26 |
config->divisor_latch = config->dlm<<8 | config->dll;
|
27 |
} |
28 |
void uart_print_config(uart_config config){
|
29 |
printf("Base address: 0x%X\n", config.base_addr);
|
30 |
printf("Configuration: 0x%02X\n", config.config);
|
31 |
printf("Number of bits per char: %d\n", config.bits_per_char);
|
32 |
printf("Number of stop bits: %d\n", config.stop_bits);
|
33 |
printf("Parity: ");
|
34 |
if((config.parity&1) == 0) printf("no parity\n"); |
35 |
else switch(config.parity){ |
36 |
case uart_parity_odd : printf("odd parity\n" ); break; |
37 |
case uart_parity_even: printf("even parity\n" ); break; |
38 |
case uart_parity_par1: printf("parity bit is 1\n"); break; |
39 |
case uart_parity_par0: printf("parity bit is 0\n"); break; |
40 |
default : printf("invalid\n" ); break; |
41 |
} |
42 |
printf("Break control: %d\n", config.break_control);
|
43 |
printf("Divisor latch: %d\n", config.divisor_latch);
|
44 |
printf("Bit rate (x1000): %d\n", 1000*(uint32_t)UART_BITRATE/config.divisor_latch); |
45 |
} |
46 |
|
47 |
int uart_enable_divisor_latch(int base_addr){ |
48 |
int ret = SUCCESS;
|
49 |
uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret; |
50 |
return uart_write_config(base_addr, conf | UART_DLAB);
|
51 |
} |
52 |
int uart_disable_divisor_latch(int base_addr){ |
53 |
int ret = SUCCESS;
|
54 |
uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret; |
55 |
return uart_write_config(base_addr, conf & (~UART_DLAB));
|
56 |
} |
57 |
|
58 |
int uart_write_config(int base_addr, uint8_t config){ |
59 |
printf("WRITING CONFIG 0x%02X TO 0x%X\n", config, base_addr);
|
60 |
if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR; |
61 |
return SUCCESS;
|
62 |
} |
63 |
int uart_set_bits_per_character(int base_addr, uint8_t bits_per_char){ |
64 |
if(bits_per_char < 5 || bits_per_char > 8) return INVALID_ARG; |
65 |
int ret = SUCCESS;
|
66 |
bits_per_char = (bits_per_char-5)&0x3; |
67 |
uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret; |
68 |
conf = (conf & (~UART_BITS_PER_CHAR)) | bits_per_char; |
69 |
return uart_write_config(base_addr, conf);
|
70 |
} |
71 |
int uart_set_stop_bits(int base_addr, uint8_t stop){ |
72 |
if(stop != 1 && stop != 2) return INVALID_ARG; |
73 |
int ret = SUCCESS;
|
74 |
stop -= 1;
|
75 |
stop = (stop&1)<<2; |
76 |
uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret; |
77 |
conf = (conf & (~UART_STOP_BITS)) | stop; |
78 |
return uart_write_config(base_addr, conf);
|
79 |
} |
80 |
int uart_set_parity(int base_addr, uart_parity par){ |
81 |
int ret = SUCCESS;
|
82 |
uint8_t parity = par << 3;
|
83 |
uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret; |
84 |
conf = (conf & (~UART_PARITY)) | parity; |
85 |
return uart_write_config(base_addr, conf);
|
86 |
} |
87 |
int uart_set_bit_rate(int base_addr, float bit_rate){ printf("%s, L82\n", __func__); |
88 |
int ret = SUCCESS;
|
89 |
uint16_t latch = UART_BITRATE/bit_rate; |
90 |
uint8_t dll = latch&0xFF;
|
91 |
uint8_t dlm = (latch>>8)&0xFF; |
92 |
if((ret = uart_enable_divisor_latch(base_addr))) return ret; |
93 |
printf("dlm,dll=0x%02X%02X\n", dlm, dll);
|
94 |
if(sys_outb(base_addr+UART_DLL, dll)) return WRITE_ERROR; |
95 |
if(sys_outb(base_addr+UART_DLM, dlm)) return WRITE_ERROR; |
96 |
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 |
return SUCCESS;
|
100 |
} |