uartp.c 1.64 KB
Newer Older
1 2 3
#include <stdint.h>
#include "uartp.h"

4 5
extern void uart_wbyte(uint8_t x);
extern uint8_t uart_rbyte();
6 7 8 9 10 11 12 13 14 15

// Simple serial protocol with packets and checksum
const uint8_t AMUX_TAG = 0xf9;
const uint8_t AMUX_END = 0xf3;
const uint8_t AMUX_EXT = 0x80;

void uartp_send(const void *src, uint16_t len) {
    uint8_t len_ind_0, len_ind_1, fcs, info;
    const uint8_t *buf = (const uint8_t *) src;

16
    uart_wbyte(AMUX_TAG);
17 18 19
    len_ind_0 = (uint8_t) (0xff & len);
    len_ind_1 = (uint8_t) (0xff & (len >> 7));
    if (len < 128) {
20
        uart_wbyte(len_ind_0);
21
    } else {
22 23
        uart_wbyte(len_ind_0 | AMUX_EXT);
        uart_wbyte(len_ind_1);
24 25 26 27 28
    }
    fcs = 0;
    for (uint16_t i = 0; i < len; i++) {
        info = buf[i];
        fcs += info;
29
        uart_wbyte(buf[i]);
30 31
    }
    fcs = 255 - fcs;
32 33
    uart_wbyte(fcs);
    uart_wbyte(AMUX_END);
34 35 36 37 38
}


uint16_t uartp_recv(void *dst, uint16_t buf_len) {
    uint8_t *buf = (uint8_t *) dst;
Enrico Pozzobon committed
39
    uint8_t tag, info, cs;
40 41 42 43 44 45
    uint16_t len;

    tag = AMUX_END;
    while (1) {

        do {
46
            tag = uart_rbyte();
Enrico Pozzobon committed
47
        } while(tag != AMUX_TAG);
48

49
        len = (uint16_t) uart_rbyte();
50 51
        if (len & AMUX_EXT) {
            len &= (~AMUX_EXT);
52
            len |= (uint16_t) (uart_rbyte() << 7);
53 54 55 56 57 58 59 60
        }
        if (len > buf_len) {
            return len;
        }

        uint16_t i = 0;
        cs = 0;
        for (i = 0; i < len; i++) {
61
            info = uart_rbyte();
62 63 64
            buf[i] = info;
            cs += info;
        }
65 66
        cs += uart_rbyte();
        tag = uart_rbyte();
67 68 69 70 71 72 73 74 75
        if (0xff == cs) {
            if (AMUX_END == tag) {
                return len;
            }
        }

    }
}