summaryrefslogtreecommitdiffstats
path: root/sw/programmer/avr/usart.c
blob: 8c2eb38457fd59b90967fb1a4d8ea398cd6ddb4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include "usart.h"

static uint16_t usart_baudrate;
static uint16_t usart_baud_prescale;

void usart_init(uint16_t baudrate)
{
    // enable RX and TX
    UCSR0B |= _BV(RXEN0) | _BV(TXEN0);
    
    // set 8 bit size char
    UCSR0C |= _BV(UCSZ01) | _BV(UCSZ00);

    // set baudrate 
    usart_baudrate = baudrate;
    usart_baud_prescale = (F_CPU / (usart_baudrate * 16)) -1;
    
    UBRR0L = usart_baud_prescale;
    UBRR0H = usart_baud_prescale >> 8;
}

void usart_send_byte(uint8_t data)
{
    while (!(UCSR0A & _BV(UDRE0)));
    UDR0 = data;
}

void usart_send(uint8_t *data, size_t len)
{
    uint8_t *p = data;

    while (len--) {
        usart_send_byte(*(p++));
    }
}

void usart_print(char *str)
{
    char *p = str;
    size_t len = 0;

    while (*p++ != '\0') {
        len++;
    }

    usart_send((uint8_t *) str, len);
}

int usart_read_byte(uint8_t *byte)
{
    uint16_t timeout = USART_TIMEOUT;

    do {
        if (UCSR0A & _BV(RXC0)) {
            *byte = UDR0;
            return 0;
        }
    } while (timeout--);

    return -1;
}

uint8_t usart_read_byte_nt(void)
{
    while ((UCSR0A & _BV(RXC0)) == 0);
    return UDR0;
}


size_t usart_read(uint8_t *buffer, size_t len)
{
    size_t read = 0;
    uint8_t *p = buffer;

    while (len--) {
        if (usart_read_byte(p)  == 0) {
            p++; 
            read++;
        }
    }

    return read;
}

int usart_read_line(uint8_t *buffer, size_t len)
{
    uint8_t ch;
    uint8_t *p = buffer;
    size_t read = 0;

    while (len--) {
        if (usart_read_byte(&ch) != 0)
            continue;
        else
            read++;

        if (ch == '\n')
            break;
        else
            *(p++) = ch;
    }

    if (ch != '\n')
        return -1;

    return 0;
}