Project

General

Profile

Revision 275

implementing transmission with queues

View differences:

uart.c
2 2

  
3 3
#include "uart.h"
4 4

  
5
#include "queue.h"
5 6
#include "errors.h"
6 7

  
7 8
#define UART_BITRATE                            115200
......
78 79
#define UART_GET_FRAMING_ERROR                  (((n)&UART_FRAMING_ERROR            )>>UART_FRAMING_ERROR_POS            )
79 80
#define UART_GET_TRANSMITTER_EMPTY(n)           (((n)&UART_TRANSMITTER_EMPTY        )>>UART_TRANSMITTER_EMPTY_POS        )
80 81

  
82
/// IIR
83
#define UART_GET_IF_INT_PEND(n)                 (!((n)&1))
84
#define UART_GET_INT_PEND(n)                    (((n)&0xE)>>1)
85
#define UART_INT_RX                             0x2 //0b010
86
#define UART_INT_TX                             0x1 //0b001
87

  
81 88
int (subscribe_uart_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
82 89
    if (interrupt_id == NULL) return 1;
83 90
    *interrupt_id = interrupt_bit;
......
110 117
static int uart_get_lsr(int base_addr, uint8_t *p){
111 118
    return util_sys_inb(base_addr+UART_LSR, p);
112 119
}
120
static int uart_get_iir(int base_addr, uint8_t *p){
121
    return util_sys_inb(base_addr+UART_IIR, p);
122
}
113 123

  
114 124
static int uart_enable_divisor_latch(int base_addr){
115 125
    int ret = SUCCESS;
......
256 266
    return uart_set_ier(base_addr, ier);
257 267
}
258 268

  
259
/*static*/ int uart_has_communication_error(int base_addr){
260
    int ret;
261
    uint8_t lsr;
262
    if((ret = uart_get_lsr(base_addr, &lsr))) return 1;
263
    lsr &= (UART_OVERRUN_ERROR &
264
            UART_PARITY_ERROR  &
265
            UART_FRAMING_ERROR);
266
    return (lsr ? 1 : 0);
267
}
268

  
269 269
#include "nctp.h"
270 270

  
271 271
#define NCTP_START      0x80
272 272
#define NCTP_END        0xFF
273
#define NCTP_TRIES      3
274 273
#define NCTP_OK         0xFF
275 274
#define NCTP_NOK        0x00
276 275
#define NCTP_MAX_SIZE   1024 //in bytes
277 276

  
278
int nctp_send_char_poll(int base_addr, uint8_t  c){
279
    for(int i = 0; i < NCTP_TRIES; ++i)
280
        if(uart_transmitter_empty(base_addr))
281
            return uart_send_char(base_addr, c);
282
    return TIMEOUT_ERROR;
283
}
284
int nctp_get_char_poll (int base_addr, uint8_t *p){
285
    for(int i = 0; i < NCTP_TRIES; ++i)
286
        if(uart_receiver_ready(base_addr))
287
            return uart_get_char(base_addr, p);
288
    return TIMEOUT_ERROR;
289
}
277
queue_t *out = NULL;
278
queue_t *in  = NULL;
290 279

  
291
int nctp_expect_ok(int base_addr){
292
    int ret;
293
    uint8_t ok;
294
    if((ret = nctp_get_char_poll(base_addr, &ok))) return ret;
295
    int cnt = 0;
296
    while(ok){
297
        cnt += ok&1;
298
        ok >>= 1;
299
    }
300
    if(cnt > 4) return SUCCESS;
301
    else        return NOK;
280
int nctp_init(void){
281
    out = queue_ctor(); if(out == NULL) return NULL_PTR;
282
    in  = queue_ctor(); if(in  == NULL) return NULL_PTR;
283
    return SUCCESS;
302 284
}
303

  
304
int nctp_send_char_try(int base_addr, uint8_t  c){
305
    int ret;
306
    for(size_t k = 0; k < NCTP_TRIES; ++k){
307
        if((ret = nctp_send_char_poll(base_addr, c))) return ret;
308
        return SUCCESS;
309
        //if(nctp_expect_ok(base_addr) == SUCCESS) return SUCCESS;
285
int nctp_free(void){
286
    while(!queue_empty(out)){
287
        free(queue_top(out));
288
        queue_pop(out);
310 289
    }
311
    return TRANS_FAILED;
312
}
313
int nctp_get_char_try (int base_addr, uint8_t *p){
314
    int ret;
315
    for(size_t k = 0; k < NCTP_TRIES; ++k){
316
        if((ret = nctp_get_char_poll (base_addr, p))) return ret;
317
        return SUCCESS;
318
        //if(!uart_has_communication_error(base_addr))
319
            //return nctp_send_char_try(base_addr, NCTP_OK ); //If it does not have any errors
290
    while(!queue_empty(in)){
291
        free(queue_top(in));
292
        queue_pop(in);
320 293
    }
321
    if((ret = nctp_send_char_poll(base_addr, NCTP_NOK))) return ret;
322
    return TRANS_FAILED;
294
    return SUCCESS;
323 295
}
324 296

  
325
static int nctp_send_inner(int base_addr, size_t num, uint8_t* ptr[], size_t sz[]){
297
int nctp_send(size_t num, uint8_t* ptr[], size_t sz[]){
326 298
    {
327 299
        int cnt = 0;
328 300
        for(size_t i = 0; i < num; ++i){
......
330 302
            if(cnt > NCTP_MAX_SIZE) return TRANS_REFUSED;
331 303
        }
332 304
    }
333

  
334 305
    int ret;
335

  
336
    if((ret = nctp_send_char_try(base_addr, NCTP_START))) return ret;
306
    uint8_t *tmp;
307
    tmp = malloc(sizeof(uint8_t)); *tmp = NCTP_START; queue_push(out, tmp);
337 308
    for(size_t i = 0; i < num; ++i){
338 309
        uint8_t *p = ptr[i]; size_t s = sz[i];
339
        for(size_t j = 0; j < s; ++j, ++p)
340
            if((ret = nctp_send_char_try(base_addr, *p)))
341
                return ret;
310
        for(size_t j = 0; j < s; ++j, ++p){
311
            tmp = malloc(sizeof(uint8_t)); *tmp = *p; queue_push(out, tmp);
312
        }
342 313
    }
343
    if((ret = nctp_send_char_try(base_addr, NCTP_END))) return ret;
344

  
314
    tmp = malloc(sizeof(uint8_t)); *tmp = NCTP_END; queue_push(out, tmp);
315
    if(uart_transmitter_empty(COM1_ADDR)){
316
        if((ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out)))) return ret;
317
        queue_pop(out);
318
    }
345 319
    return SUCCESS;
346 320
}
347
int nctp_send(int base_addr, size_t num, uint8_t* ptr[], size_t sz[]){
348
    int ret;
349
    if((ret = uart_disable_int_rx(base_addr))) return ret;
350
    if((ret = uart_disable_int_tx(base_addr))) return ret;
351
    int r = nctp_send_inner(base_addr, num, ptr, sz);
352
    if((ret = uart_enable_int_rx(base_addr))) return ret;
353
    if((ret = uart_disable_int_tx(base_addr))) return ret;
354
    return r;
321

  
322
static int nctp_transmit(void){
323
    if(!queue_empty(out)){
324
        int ret = uart_send_char(COM1_ADDR, *(uint8_t*)queue_top(out));
325
        queue_pop(out);
326
        return ret;
327
    }else return SUCCESS;
355 328
}
356

  
357
static int nctp_get_inner(int base_addr, uint8_t **dest){
329
static void process(){
330
    free(queue_top(in)); queue_pop(in);
331
    while(*(uint8_t*)queue_top(in) != NCTP_END){
332
        printf("%c", *(uint8_t*)queue_top(in));
333
        free(queue_top(in)); queue_pop(in);
334
    }
335
    free(queue_top(in)); queue_pop(in);
336
}
337
static int nctp_receive(void){
358 338
    int ret;
359
    free(*dest);
360
    *dest = malloc(NCTP_MAX_SIZE*sizeof(uint8_t)); size_t i = 0;
361
    if(*dest == NULL) return NULL_PTR;
362 339
    uint8_t c;
363
    if((ret = nctp_get_char_try (base_addr, &c     ))) return ret;
364
    while(true){
365
        if(i >= NCTP_MAX_SIZE) return TRANS_REFUSED;
366
        if((ret = nctp_get_char_try (base_addr, &c))) return ret;
367
        if(c == NCTP_END) return SUCCESS;
368
        else              (*dest)[i++] = c;
340
    while(uart_receiver_ready(COM1_ADDR)){
341
        if((ret = uart_get_char(COM1_ADDR, &c))) return ret;
342
        uint8_t *tmp = malloc(sizeof(uint8_t)); *tmp = c;
343
        queue_push(in, tmp);
344
        if(c == NCTP_END) process();
369 345
    }
346
    return SUCCESS;
370 347
}
371
int nctp_get(int base_addr, uint8_t **dest){
372
    int ret;
373
    if((ret = uart_disable_int_rx(base_addr))) return ret;
374
    if((ret = uart_disable_int_tx(base_addr))) return ret;
375
    int r = nctp_get_inner(base_addr, dest);
376
    if((ret = uart_enable_int_rx(base_addr))) return ret;
377
    if((ret = uart_disable_int_tx(base_addr))) return ret;
378
    return r;
348

  
349
int nctp_ih_err = SUCCESS;
350
void nctp_ih(void){
351
    uint8_t iir;
352
    if((nctp_ih_err = uart_get_iir(COM1_ADDR, &iir))) return;
353
    if(UART_GET_IF_INT_PEND(iir)){
354
        switch(UART_GET_INT_PEND(iir)){
355
            case UART_INT_RX: nctp_receive (); break;
356
            case UART_INT_TX: nctp_transmit(); break;
357
            default: break;
358
        }
359
    }
379 360
}
361

  
362
/// HLTP
363
int hltp_send_string(const char *p){
364
    uint8_t* ptr[1]; ptr[0] = (uint8_t*)p;
365
    size_t    sz[1]; sz[0] = strlen(p)+1;
366
    return nctp_send(1, ptr, sz);
367
}

Also available in: Unified diff