Revision 261
stuff
uart.c | ||
---|---|---|
61 | 61 |
|
62 | 62 |
/// LSR |
63 | 63 |
#define UART_RECEIVER_READY_POS 0 |
64 |
#define UART_OVERRUN_ERROR_POS 1 |
|
65 |
#define UART_PARITY_ERROR_POS 2 |
|
66 |
#define UART_FRAMING_ERROR_POS 3 |
|
64 | 67 |
#define UART_TRANSMITTER_EMPTY_POS 5 |
65 | 68 |
|
66 | 69 |
#define UART_RECEIVER_READY (BIT(0)) |
70 |
#define UART_OVERRUN_ERROR (BIT(1)) |
|
71 |
#define UART_PARITY_ERROR (BIT(2)) |
|
72 |
#define UART_FRAMING_ERROR (BIT(3)) |
|
67 | 73 |
#define UART_TRANSMITTER_EMPTY (BIT(5)) |
68 | 74 |
|
69 | 75 |
#define UART_GET_RECEIVER_READY(n) (((n)&UART_RECEIVER_READY )>>UART_RECEIVER_READY_POS ) |
76 |
#define UART_GET_OVERRUN_ERROR (((n)&UART_OVERRUN_ERROR )>>UART_OVERRUN_ERROR_POS ) |
|
77 |
#define UART_GET_PARITY_ERROR (((n)&UART_PARITY_ERROR )>>UART_PARITY_ERROR_POS ) |
|
78 |
#define UART_GET_FRAMING_ERROR (((n)&UART_FRAMING_ERROR )>>UART_FRAMING_ERROR_POS ) |
|
70 | 79 |
#define UART_GET_TRANSMITTER_EMPTY(n) (((n)&UART_TRANSMITTER_EMPTY )>>UART_TRANSMITTER_EMPTY_POS ) |
71 | 80 |
|
72 | 81 |
static void uart_parse_config(uart_config *config){ |
... | ... | |
241 | 250 |
return uart_set_ier(base_addr, ier); |
242 | 251 |
} |
243 | 252 |
|
244 |
int uart_get_char_poll(int base_addr, uint8_t *p){
|
|
253 |
static int uart_has_communication_error(int base_addr){
|
|
245 | 254 |
int ret; |
246 |
while(!uart_receiver_ready(base_addr)){} |
|
247 |
if((ret = uart_get_char(base_addr, p))) return ret; |
|
255 |
uint8_t lsr; |
|
256 |
if((ret = uart_get_lsr(base_addr, &lsr))) return 1; |
|
257 |
lsr &= (UART_OVERRUN_ERROR & |
|
258 |
UART_PARITY_ERROR & |
|
259 |
UART_FRAMING_ERROR); |
|
260 |
return (lsr ? 1 : 0); |
|
261 |
} |
|
262 |
|
|
263 |
#include "nctp.h" |
|
264 |
|
|
265 |
#define NCTP_START 0x80 |
|
266 |
#define NCTP_END 0xFF |
|
267 |
#define NCTP_TRIES 3 |
|
268 |
#define NCTP_OK 0xFF |
|
269 |
#define NCTP_NOK 0x00 |
|
270 |
#define NCTP_MAX_SIZE 1024 //in bytes |
|
271 |
|
|
272 |
int nctp_send_char_poll(int base_addr, uint8_t c){ |
|
273 |
for(int i = 0; i < NCTP_TRIES; ++i) |
|
274 |
if(uart_transmitter_empty(base_addr)) |
|
275 |
return uart_send_char(base_addr, c); |
|
276 |
return TIMEOUT_ERROR; |
|
277 |
} |
|
278 |
int nctp_get_char_poll (int base_addr, uint8_t *p){ |
|
279 |
for(int i = 0; i < NCTP_TRIES; ++i) |
|
280 |
if(uart_receiver_ready(base_addr)) |
|
281 |
return uart_get_char(base_addr, p); |
|
282 |
return TIMEOUT_ERROR; |
|
283 |
} |
|
284 |
|
|
285 |
int nctp_expect_ok(int base_addr){ |
|
286 |
int ret; |
|
287 |
uint8_t ok; |
|
288 |
if((ret = nctp_get_char_poll(base_addr, &ok))) return ret; |
|
289 |
int cnt = 0; |
|
290 |
while(ok){ |
|
291 |
cnt += ok&1; |
|
292 |
ok >>= 1; |
|
293 |
} |
|
294 |
if(cnt > 4) return SUCCESS; |
|
295 |
else return NOK; |
|
296 |
} |
|
297 |
|
|
298 |
int nctp_send_char_try(int base_addr, uint8_t c){ |
|
299 |
int ret; |
|
300 |
for(size_t k = 0; k < NCTP_TRIES; ++k){ |
|
301 |
if((ret = nctp_send_char_poll(base_addr, c))) return ret; |
|
302 |
if(nctp_expect_ok(base_addr) == SUCCESS) return SUCCESS; |
|
303 |
} |
|
304 |
return TRANS_FAILED; |
|
305 |
} |
|
306 |
int nctp_get_char_try (int base_addr, uint8_t *p){ |
|
307 |
int ret; |
|
308 |
for(size_t k = 0; k < NCTP_TRIES; ++k){ |
|
309 |
if((ret = nctp_get_char_poll (base_addr, p))) return ret; |
|
310 |
if(!uart_has_communication_error(base_addr)) |
|
311 |
return nctp_send_char_try(base_addr, NCTP_OK ); //If it does not have any errors |
|
312 |
} |
|
313 |
if((ret = nctp_send_char_poll(base_addr, NCTP_NOK))) return ret; |
|
314 |
return TRANS_FAILED; |
|
315 |
} |
|
316 |
|
|
317 |
int nctp_send(int port, size_t num, uint8_t* ptr[], size_t sz[]){ |
|
318 |
{ |
|
319 |
int cnt = 0; |
|
320 |
for(size_t i = 0; i < num; ++i){ |
|
321 |
cnt += sz[i]; |
|
322 |
if(cnt > NCTP_MAX_SIZE) return TRANS_REFUSED; |
|
323 |
} |
|
324 |
} |
|
325 |
|
|
326 |
int base_addr;{ |
|
327 |
switch(port){ |
|
328 |
case 1: base_addr = COM1_ADDR; break; |
|
329 |
case 2: base_addr = COM2_ADDR; break; |
|
330 |
default: return INVALID_ARG; |
|
331 |
} |
|
332 |
} |
|
333 |
|
|
334 |
int ret; |
|
335 |
|
|
336 |
if((ret = uart_disable_int_rx(base_addr))) return ret; |
|
337 |
if((ret = uart_disable_int_tx(base_addr))) return ret; |
|
338 |
|
|
339 |
if((ret = nctp_send_char_try(base_addr, NCTP_START))) return ret; |
|
340 |
for(size_t i = 0; i < num; ++i){ |
|
341 |
uint8_t *p = ptr[i]; size_t s = sz[i]; |
|
342 |
for(size_t j = 0; j < s; ++j, ++p) |
|
343 |
if((ret = nctp_send_char_try(base_addr, *p))) |
|
344 |
return ret; |
|
345 |
} |
|
346 |
if((ret = nctp_send_char_try(base_addr, NCTP_END))) return ret; |
|
347 |
|
|
248 | 348 |
return SUCCESS; |
249 | 349 |
} |
250 |
int uart_send_char_poll(int base_addr, uint8_t c){ |
|
350 |
int ntcp_get(int port, uint8_t *dest){ |
|
351 |
int base_addr;{ |
|
352 |
switch(port){ |
|
353 |
case 1: base_addr = COM1_ADDR; break; |
|
354 |
case 2: base_addr = COM2_ADDR; break; |
|
355 |
default: return INVALID_ARG; |
|
356 |
} |
|
357 |
} |
|
358 |
|
|
251 | 359 |
int ret; |
252 |
while(!uart_transmitter_empty(base_addr)){} |
|
253 |
if((ret = uart_send_char(base_addr, c))) return ret; |
|
360 |
free(dest); |
|
361 |
dest = malloc(NCTP_MAX_SIZE*sizeof(uint8_t)); size_t i = 0; |
|
362 |
if(dest == NULL) return NULL_PTR; |
|
363 |
uint8_t c; |
|
364 |
if((ret = nctp_get_char_try (base_addr, &c ))) return ret; |
|
365 |
while(true){ |
|
366 |
if(i >= NCTP_MAX_SIZE) return TRANS_REFUSED; |
|
367 |
if((ret = nctp_get_char_try (base_addr, &c))) return ret; |
|
368 |
if(c == NCTP_END) break; |
|
369 |
else dest[i] = c; |
|
370 |
++i; |
|
371 |
} |
|
254 | 372 |
return SUCCESS; |
255 | 373 |
} |
Also available in: Unified diff