Project

General

Profile

Revision 249

implementing uart. done with basic functions, still planning protocol

View differences:

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
7
#define UART_BITRATE                            115200
8
#define UART_WAIT                               20 //microseconds
17 9

  
18
#define UART_DLL            0
19
#define UART_DLM            1
10
#define UART_RBR                                0
11
#define UART_THR                                0
12
#define UART_IER                                1
13
#define UART_IIR                                2
14
#define UART_FCR                                2
15
#define UART_LCR                                3
16
#define UART_MCR                                4
17
#define UART_LSR                                5
18
#define UART_MSR                                6
19
#define UART_SR                                 7
20 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
21
#define UART_DLL                                0
22
#define UART_DLM                                1
26 23

  
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))
24
/// LCR
25
#define UART_BITS_PER_CHAR_POS                  0
26
#define UART_STOP_BITS_POS                      2
27
#define UART_PARITY_POS                         3
28
#define UART_BREAK_CONTROL_POS                  6
29
#define UART_DLAB_POS                           7
32 30

  
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)
31
#define UART_BITS_PER_CHAR                      (BIT(0) | BIT(1))
32
#define UART_STOP_BITS                          (BIT(2))
33
#define UART_PARITY                             (BIT(3) | BIT(4) | BIT(5))
34
#define UART_BREAK_CONTROL                      (BIT(6))
35
#define UART_DLAB                               (BIT(7))
41 36

  
42
#define UART_RECEIVED_DATA_POS      0
43
#define UART_TRANSMITTER_EMPTY_POS  1
44
#define UART_RECEIVER_LINE_STAT_POS 2
45
#define UART_MODEM_STAT_POS         3
37
#define UART_GET_BITS_PER_CHAR(n)               (((n)&UART_BITS_PER_CHAR) + 5)
38
#define UART_GET_STOP_BITS(n)                   (((n)&UART_STOP_BITS)? 2 : 1)
39
#define UART_GET_PARITY(n)                      (((n)&UART_PARITY       )>>UART_PARITY_POS       )
40
#define UART_GET_BREAK_CONTROL(n)               (((n)&UART_BREAK_CONTROL)>>UART_BREAK_CONTROL_POS)
41
#define UART_GET_DLAB(n)                        (((n)&UART_DLAB         )>>UART_DLAB_POS         )
42
#define UART_GET_DIV_LATCH(m,l)                 ((m)<<8 | (l))
43
#define UART_GET_DLL(n)                         ((n)&0xFF)
44
#define UART_GET_DLM(n)                         (((n)>>8)&0xFF)
46 45

  
47
#define UART_RECEIVED_DATA          (BIT(0))
48
#define UART_TRANSMITTER_EMPTY      (BIT(1))
49
#define UART_RECEIVER_LINE_STAT     (BIT(2))
50
#define UART_MODEM_STAT             (BIT(3))
46
/// IER
47
#define UART_INT_EN_RECEIVED_DATA_POS           0
48
#define UART_INT_EN_TRANSMITTER_EMPTY_POS       1
49
#define UART_INT_EN_RECEIVER_LINE_STAT_POS      2
50
#define UART_INT_EN_MODEM_STAT_POS              3
51 51

  
52
#define UART_GET_RECEIVED_DATA(n)       (((n)&UART_RECEIVED_DATA     )>>UART_RECEIVED_DATA_POS     )
53
#define UART_GET_TRANSMITTER_EMPTY(n)   (((n)&UART_TRANSMITTER_EMPTY )>>UART_TRANSMITTER_EMPTY_POS )
54
#define UART_GET_RECEIVER_LINE_STAT(n)  (((n)&UART_RECEIVER_LINE_STAT)>>UART_RECEIVER_LINE_STAT_POS)
55
#define UART_GET_MODEM_STAT(n)          (((n)&UART_MODEM_STAT        )>>UART_MODEM_STAT_POS        )
52
#define UART_INT_EN_RECEIVED_DATA               (BIT(0))
53
#define UART_INT_EN_TRANSMITTER_EMPTY           (BIT(1))
54
#define UART_INT_EN_RECEIVER_LINE_STAT          (BIT(2))
55
#define UART_INT_EN_MODEM_STAT                  (BIT(3))
56 56

  
57
#define UART_INT_EN_GET_RECEIVED_DATA(n)        (((n)&UART_INT_EN_RECEIVED_DATA     )>>UART_INT_EN_RECEIVED_DATA_POS     )
58
#define UART_INT_EN_GET_TRANSMITTER_EMPTY(n)    (((n)&UART_INT_EN_TRANSMITTER_EMPTY )>>UART_INT_EN_TRANSMITTER_EMPTY_POS )
59
#define UART_INT_EN_GET_RECEIVER_LINE_STAT(n)   (((n)&UART_INT_EN_RECEIVER_LINE_STAT)>>UART_INT_EN_RECEIVER_LINE_STAT_POS)
60
#define UART_INT_EN_GET_MODEM_STAT(n)           (((n)&UART_INT_EN_MODEM_STAT        )>>UART_INT_EN_MODEM_STAT_POS        )
61

  
62
/// LSR
63
#define UART_RECEIVER_READY_POS                 0
64
#define UART_TRANSMITTER_EMPTY_POS              5
65

  
66
#define UART_RECEIVER_READY                     (BIT(0))
67
#define UART_TRANSMITTER_EMPTY                  (BIT(5))
68

  
69
#define UART_GET_RECEIVER_READY(n)              (((n)&UART_RECEIVER_READY           )>>UART_RECEIVER_READY_POS           )
70
#define UART_GET_TRANSMITTER_EMPTY(n)           (((n)&UART_TRANSMITTER_EMPTY        )>>UART_TRANSMITTER_EMPTY_POS        )
71

  
57 72
int uart_get_config(int base_addr, uart_config *config){
58 73
    int ret = SUCCESS;
59 74

  
......
75 90
    /// LCR
76 91
    config->bits_per_char          = UART_GET_BITS_PER_CHAR     (config->lcr);
77 92
    config->stop_bits              = UART_GET_STOP_BITS         (config->lcr);
78
    config->parity                 = UART_GET_PARITY            (config->lcr);
93
    config->parity                 = UART_GET_PARITY            (config->lcr); if((config->parity & BIT(0)) == 0) config->parity = uart_parity_none;
79 94
    config->break_control          = UART_GET_BREAK_CONTROL     (config->lcr);
80 95
    config->dlab                   = UART_GET_DLAB              (config->lcr);
81 96
    /// IER
82
    config->received_data_int      = UART_GET_RECEIVED_DATA     (config->ier);
83
    config->transmitter_empty_int  = UART_GET_TRANSMITTER_EMPTY (config->ier);
84
    config->receiver_line_stat_int = UART_GET_RECEIVER_LINE_STAT(config->ier);
85
    config->modem_stat_int         = UART_GET_MODEM_STAT        (config->ier);
97
    config->received_data_int      = UART_INT_EN_GET_RECEIVED_DATA     (config->ier);
98
    config->transmitter_empty_int  = UART_INT_EN_GET_TRANSMITTER_EMPTY (config->ier);
99
    config->receiver_line_stat_int = UART_INT_EN_GET_RECEIVER_LINE_STAT(config->ier);
100
    config->modem_stat_int         = UART_INT_EN_GET_MODEM_STAT        (config->ier);
86 101
    /// DIV LATCH
87 102
    config->divisor_latch          = UART_GET_DIV_LATCH(config->dlm, config->dll);
88 103
}
89 104
void uart_print_config(uart_config config){
90
    printf("Base address                                   : 0x%X\n", config.base_addr);
91
    printf("    LCR configuration                          : 0x%02X\n", config.lcr);
92
    printf("        Number of bits per char                : %d\n", config.bits_per_char);
93
    printf("        Number of stop bits                    : %d\n", config.stop_bits);
94
    printf("        Parity                                 : ");
95
    if((config.parity&1) == 0) printf("no parity\n");
105

  
106
    printf("%s configuration:\n", (config.base_addr == COM1_ADDR ? "COM1" : "COM2"));
107
    printf("\tLCR = 0x%X: %d bits per char\t %d stop bits\t", config.lcr, config.bits_per_char, config.stop_bits);
108
    if((config.parity&BIT(0)) == 0) printf("NO parity\n");
96 109
    else switch(config.parity){
97
        case uart_parity_odd : printf("odd parity\n"     ); break;
98
        case uart_parity_even: printf("even parity\n"    ); break;
110
        case uart_parity_odd : printf("ODD parity\n"     ); break;
111
        case uart_parity_even: printf("EVEN parity\n"    ); break;
99 112
        case uart_parity_par1: printf("parity bit is 1\n"); break;
100 113
        case uart_parity_par0: printf("parity bit is 0\n"); break;
101 114
        default              : printf("invalid\n"        ); break;
102 115
    }
103
    printf("    Break control                              : %d\n", config.break_control);
104
    printf("    DLAB                                       : %d\n", config.dlab);
105

  
106
    printf("    IER configuration                          : 0x%02X\n", config.ier);
107
    printf("        Received data interrupts enabled       : %d\n", config.received_data_int);
108
    printf("        Transmitter empty interrupts enabled   : %d\n", config.transmitter_empty_int);
109
    printf("        Receiver line status interrupts enabled: %d\n", config.receiver_line_stat_int);
110
    printf("        Modem status interrupts enabled        : %d\n", config.modem_stat_int);
111

  
112
    printf("    Divisor latch (DLM & DLL)                  : %d\n", config.divisor_latch);
113
    printf("        Bit rate                               : %d\n", UART_BITRATE/config.divisor_latch);
116
    printf("\tDLM = 0x%02X DLL=0x%02X: bitrate = %d bps\n", config.dlm, config.dll, UART_BITRATE/config.divisor_latch);
117
    printf("\tIER = 0x%02X: Rx interrupts: %s\tTx interrupts: %s\n", config.ier,
118
        (config.received_data_int     ? "ENABLED":"DISABLED"),
119
        (config.transmitter_empty_int ? "ENABLED":"DISABLED"));
114 120
}
115 121

  
116 122
int uart_enable_divisor_latch(int base_addr){
......
160 166
    if((ret = uart_enable_divisor_latch(base_addr))) return ret;
161 167
    if(sys_outb(base_addr+UART_DLL, dll)) return WRITE_ERROR;
162 168
    if(sys_outb(base_addr+UART_DLM, dlm)) return WRITE_ERROR;
163
    if((ret = util_sys_inb(base_addr+UART_DLM, &dlm))) return ret;
169
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
164 170
    return SUCCESS;
165 171
}
172

  
173
/// PRIVATE
174
int uart_get_lsr(int base_addr, uint8_t *p){
175
    return util_sys_inb(base_addr+UART_LSR, p);
176
}
177
/**
178
 * @brief Get char from RBR.
179
 */
180
int uart_get_char(int base_addr, uint8_t *p){
181
    int ret;
182
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
183
    return util_sys_inb(base_addr+UART_RBR, p);
184
}
185
int uart_send_char(int base_addr, uint8_t c){
186
    int ret;
187
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
188
    if(sys_outb(base_addr, c)) return WRITE_ERROR;
189
    return SUCCESS;
190
}
191
int uart_receiver_ready(int base_addr){
192
    uint8_t lsr;
193
    if(uart_get_lsr(base_addr, &lsr)) return false;
194
    return UART_GET_RECEIVER_READY(lsr);
195
}
196
int uart_transmitter_empty(int base_addr){
197
    uint8_t lsr;
198
    if(uart_get_lsr(base_addr, &lsr)) return false;
199
    return UART_GET_TRANSMITTER_EMPTY(lsr);
200
}
201
///PUBLIC
202
int uart_get_char_poll(int base_addr, uint8_t *p){
203
    int ret;
204
    while(!uart_receiver_ready(base_addr)){}
205
    if((ret = uart_get_char(base_addr, p))) return ret;
206
    return SUCCESS;
207
}
208
int uart_send_char_poll(int base_addr, uint8_t  c){
209
    int ret;
210
    while(!uart_transmitter_empty(base_addr)){}
211
    if((ret = uart_send_char(base_addr, c))) return ret;
212
    return SUCCESS;
213
}
214
int uart_send_memory_poll(int base_addr, void *str, size_t n){
215
    int ret;
216
    uint8_t *p = str;
217
    for(size_t i = 0; i < n; ++i, ++p){
218
        if((ret = uart_send_char_poll(base_addr, *p))) return ret;
219
    }
220
    return SUCCESS;
221
}

Also available in: Unified diff