Project

General

Profile

Revision 252

made some more changes to uart

View differences:

uart.c
44 44
#define UART_GET_DLM(n)                         (((n)>>8)&0xFF)
45 45

  
46 46
/// IER
47
#define UART_INT_EN_RECEIVED_DATA_POS           0
48
#define UART_INT_EN_TRANSMITTER_EMPTY_POS       1
47
#define UART_INT_EN_RX_POS                      0
48
#define UART_INT_EN_TX_POS                      1
49 49
#define UART_INT_EN_RECEIVER_LINE_STAT_POS      2
50 50
#define UART_INT_EN_MODEM_STAT_POS              3
51 51

  
52
#define UART_INT_EN_RECEIVED_DATA               (BIT(0))
53
#define UART_INT_EN_TRANSMITTER_EMPTY           (BIT(1))
52
#define UART_INT_EN_RX                          (BIT(0))
53
#define UART_INT_EN_TX                          (BIT(1))
54 54
#define UART_INT_EN_RECEIVER_LINE_STAT          (BIT(2))
55 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        )
57
#define UART_GET_INT_EN_RX(n)                   (((n)&UART_INT_EN_RX                )>>UART_INT_EN_RX_POS                )
58
#define UART_GET_INT_EN_TX(n)                   (((n)&UART_INT_EN_TX                )>>UART_INT_EN_TX_POS                )
59
#define UART_GET_INT_EN_RECEIVER_LINE_STAT(n)   (((n)&UART_INT_EN_RECEIVER_LINE_STAT)>>UART_INT_EN_RECEIVER_LINE_STAT_POS)
60
#define UART_GET_INT_EN_MODEM_STAT(n)           (((n)&UART_INT_EN_MODEM_STAT        )>>UART_INT_EN_MODEM_STAT_POS        )
61 61

  
62 62
/// LSR
63 63
#define UART_RECEIVER_READY_POS                 0
......
69 69
#define UART_GET_RECEIVER_READY(n)              (((n)&UART_RECEIVER_READY           )>>UART_RECEIVER_READY_POS           )
70 70
#define UART_GET_TRANSMITTER_EMPTY(n)           (((n)&UART_TRANSMITTER_EMPTY        )>>UART_TRANSMITTER_EMPTY_POS        )
71 71

  
72
static void uart_parse_config(uart_config *config){
73
    /// LCR
74
    config->bits_per_char          = UART_GET_BITS_PER_CHAR     (config->lcr);
75
    config->stop_bits              = UART_GET_STOP_BITS         (config->lcr);
76
    config->parity                 = UART_GET_PARITY            (config->lcr); if((config->parity & BIT(0)) == 0) config->parity = uart_parity_none;
77
    config->break_control          = UART_GET_BREAK_CONTROL     (config->lcr);
78
    config->dlab                   = UART_GET_DLAB              (config->lcr);
79
    /// IER
80
    config->received_data_int      = UART_GET_INT_EN_RX                (config->ier);
81
    config->transmitter_empty_int  = UART_GET_INT_EN_TX                (config->ier);
82
    config->receiver_line_stat_int = UART_GET_INT_EN_RECEIVER_LINE_STAT(config->ier);
83
    config->modem_stat_int         = UART_GET_INT_EN_MODEM_STAT        (config->ier);
84
    /// DIV LATCH
85
    config->divisor_latch          = UART_GET_DIV_LATCH(config->dlm, config->dll);
86
}
87

  
88
static int uart_get_lcr(int base_addr, uint8_t *p){
89
    return util_sys_inb(base_addr+UART_LCR, p);
90
}
91
static int uart_set_lcr(int base_addr, uint8_t config){
92
    if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR;
93
    return SUCCESS;
94
}
95
static int uart_get_lsr(int base_addr, uint8_t *p){
96
    return util_sys_inb(base_addr+UART_LSR, p);
97
}
98

  
99
static int uart_enable_divisor_latch(int base_addr){
100
    int ret = SUCCESS;
101
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
102
    return uart_set_lcr(base_addr, conf | UART_DLAB);
103
}
104
static int uart_disable_divisor_latch(int base_addr){
105
    int ret = SUCCESS;
106
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
107
    return uart_set_lcr(base_addr, conf & (~UART_DLAB));
108
}
109

  
110
static int uart_get_ier(int base_addr, uint8_t *p){
111
    int ret;
112
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
113
    return util_sys_inb(base_addr+UART_IER, p);
114
}
115
static int uart_set_ier(int base_addr, uint8_t n){
116
    int ret;
117
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
118
    if(sys_outb(base_addr+UART_IER, n)) return WRITE_ERROR;
119
    return SUCCESS;
120
}
121

  
72 122
int uart_get_config(int base_addr, uart_config *config){
73 123
    int ret = SUCCESS;
74 124

  
75 125
    config->base_addr = base_addr;
76 126

  
77
    if((ret = util_sys_inb(base_addr+UART_LCR, &config->lcr))) return ret;
127
    if((ret = uart_get_lcr(base_addr, &config->lcr))) return ret;
78 128

  
79
    if((ret = util_sys_inb(base_addr+UART_IER, &config->ier))) return ret;
129
    if((ret = uart_get_ier(base_addr, &config->ier))) return ret;
80 130

  
81 131
    if((ret = uart_enable_divisor_latch (base_addr))) return ret;
82 132
    if((ret = util_sys_inb(base_addr+UART_DLL, &config->dll   ))) return ret;
......
86 136
    uart_parse_config(config);
87 137
    return ret;
88 138
}
89
void uart_parse_config(uart_config *config){
90
    /// LCR
91
    config->bits_per_char          = UART_GET_BITS_PER_CHAR     (config->lcr);
92
    config->stop_bits              = UART_GET_STOP_BITS         (config->lcr);
93
    config->parity                 = UART_GET_PARITY            (config->lcr); if((config->parity & BIT(0)) == 0) config->parity = uart_parity_none;
94
    config->break_control          = UART_GET_BREAK_CONTROL     (config->lcr);
95
    config->dlab                   = UART_GET_DLAB              (config->lcr);
96
    /// 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);
101
    /// DIV LATCH
102
    config->divisor_latch          = UART_GET_DIV_LATCH(config->dlm, config->dll);
103
}
104 139
void uart_print_config(uart_config config){
105 140

  
106 141
    printf("%s configuration:\n", (config.base_addr == COM1_ADDR ? "COM1" : "COM2"));
......
119 154
        (config.transmitter_empty_int ? "ENABLED":"DISABLED"));
120 155
}
121 156

  
122
int uart_enable_divisor_latch(int base_addr){
123
    int ret = SUCCESS;
124
    uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret;
125
    return uart_write_config(base_addr, conf | UART_DLAB);
126
}
127
int uart_disable_divisor_latch(int base_addr){
128
    int ret = SUCCESS;
129
    uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret;
130
    return uart_write_config(base_addr, conf & (~UART_DLAB));
131
}
132

  
133
int uart_write_config(int base_addr, uint8_t config){
134
    if(sys_outb(base_addr+UART_LCR, config)) return WRITE_ERROR;
135
    return SUCCESS;
136
}
137 157
int uart_set_bits_per_character(int base_addr, uint8_t bits_per_char){
138 158
    if(bits_per_char < 5 || bits_per_char > 8) return INVALID_ARG;
139 159
    int ret = SUCCESS;
140 160
    bits_per_char = (bits_per_char-5)&0x3;
141
    uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret;
161
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
142 162
    conf = (conf & (~UART_BITS_PER_CHAR)) | bits_per_char;
143
    return uart_write_config(base_addr, conf);
163
    return uart_set_lcr(base_addr, conf);
144 164
}
145 165
int uart_set_stop_bits(int base_addr, uint8_t stop){
146 166
    if(stop != 1 && stop != 2) return INVALID_ARG;
147 167
    int ret = SUCCESS;
148 168
    stop -= 1;
149 169
    stop = (stop&1)<<2;
150
    uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret;
170
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
151 171
    conf = (conf & (~UART_STOP_BITS)) | stop;
152
    return uart_write_config(base_addr, conf);
172
    return uart_set_lcr(base_addr, conf);
153 173
}
154 174
int uart_set_parity(int base_addr, uart_parity par){
155 175
    int ret = SUCCESS;
156 176
    uint8_t parity = par << 3;
157
    uint8_t conf; if((ret = util_sys_inb(base_addr+UART_LCR, &conf))) return ret;
177
    uint8_t conf; if((ret = uart_get_lcr(base_addr, &conf))) return ret;
158 178
    conf = (conf & (~UART_PARITY)) | parity;
159
    return uart_write_config(base_addr, conf);
179
    return uart_set_lcr(base_addr, conf);
160 180
}
161 181
int uart_set_bit_rate(int base_addr, float bit_rate){
162 182
    int ret = SUCCESS;
......
170 190
    return SUCCESS;
171 191
}
172 192

  
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){
193
static int uart_get_char(int base_addr, uint8_t *p){
181 194
    int ret;
182 195
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
183 196
    return util_sys_inb(base_addr+UART_RBR, p);
184 197
}
185
int uart_send_char(int base_addr, uint8_t c){
198
static int uart_send_char(int base_addr, uint8_t c){
186 199
    int ret;
187 200
    if((ret = uart_disable_divisor_latch(base_addr))) return ret;
188
    if(sys_outb(base_addr, c)) return WRITE_ERROR;
201
    if(sys_outb(base_addr+UART_THR, c)) return WRITE_ERROR;
189 202
    return SUCCESS;
190 203
}
191
int uart_receiver_ready(int base_addr){
204
static int uart_receiver_ready(int base_addr){
192 205
    uint8_t lsr;
193 206
    if(uart_get_lsr(base_addr, &lsr)) return false;
194 207
    return UART_GET_RECEIVER_READY(lsr);
195 208
}
196
int uart_transmitter_empty(int base_addr){
209
static int uart_transmitter_empty(int base_addr){
197 210
    uint8_t lsr;
198 211
    if(uart_get_lsr(base_addr, &lsr)) return false;
199 212
    return UART_GET_TRANSMITTER_EMPTY(lsr);
200 213
}
201
///PUBLIC
214

  
215
int uart_enable_int_rx(int base_addr){
216
    int ret;
217
    uint8_t ier;
218
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
219
    ier |= UART_INT_EN_RX;
220
    return uart_set_ier(base_addr, ier);
221
}
222
int uart_disable_int_rx(int base_addr){
223
    int ret;
224
    uint8_t ier;
225
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
226
    ier &= ~UART_INT_EN_RX;
227
    return uart_set_ier(base_addr, ier);
228
}
229
int uart_enable_int_tx(int base_addr){
230
    int ret;
231
    uint8_t ier;
232
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
233
    ier |= UART_INT_EN_TX;
234
    return uart_set_ier(base_addr, ier);
235
}
236
int uart_disable_int_tx(int base_addr){
237
    int ret;
238
    uint8_t ier;
239
    if((ret = uart_get_ier(base_addr, &ier))) return ret;
240
    ier &= ~UART_INT_EN_TX;
241
    return uart_set_ier(base_addr, ier);
242
}
243

  
202 244
int uart_get_char_poll(int base_addr, uint8_t *p){
203 245
    int ret;
204 246
    while(!uart_receiver_ready(base_addr)){}
......
211 253
    if((ret = uart_send_char(base_addr, c))) return ret;
212 254
    return SUCCESS;
213 255
}
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