From 3ab99e7747d85b12bbfd429966ec42ade02b2da1 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 28 Oct 2013 21:10:47 +0200 Subject: [PATCH] Expand the serial API and add an asynchronous mode This breaks any existing code using the API, since the callback macro isn't available anymore. --- common/serial.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++-- common/serial.h | 13 +++----- 2 files changed, 85 insertions(+), 10 deletions(-) diff --git a/common/serial.c b/common/serial.c index a5e5cae..8874c3e 100644 --- a/common/serial.c +++ b/common/serial.c @@ -1,8 +1,23 @@ +#include #include +#include "ringbuffer.h" #include "serial.h" #define BIT(n) (1<<(n)) +#ifndef SERIAL_BUFSIZE +#define SERIAL_BUFSIZE 16 +#endif + +#ifdef SERIAL_ASYNC +static RINGBUFFER(rx, SERIAL_BUFSIZE); +static RINGBUFFER(tx, SERIAL_BUFSIZE); +static uint8_t rx_overrun; +#define INTERRUPTS BIT(RXCIE0) +#else +#define INTERRUPTS 0 +#endif + void serial_init(uint16_t baud) { DDRD = (DDRD&~0x03) | 0x02; @@ -13,11 +28,74 @@ void serial_init(uint16_t baud) UBRR0L = baud; UCSR0A = 0; UCSR0C = BIT(UCSZ00) | BIT(UCSZ01); // 8N1 - UCSR0B = BIT(RXEN0) | BIT(TXEN0) | BIT(RXCIE0); + UCSR0B = BIT(RXEN0) | BIT(TXEN0) | INTERRUPTS; +} + +uint8_t serial_read() +{ +#ifdef SERIAL_ASYNC + return ringbuffer_blocking_pop(rx); +#else + while(!(UCSR0A&BIT(RXC0))) ; + return UDR0; +#endif +} + +uint8_t serial_read_available() +{ +#ifdef SERIAL_ASYNC + return ringbuffer_fill(rx); +#else + return (UCSR0A&BIT(RXC0))!=0; +#endif +} + +uint8_t serial_read_overrun() +{ +#ifdef SERIAL_ASYNC + uint8_t o = rx_overrun; + rx_overrun = 0; + return o; +#else + return (UCSR0A&BIT(DOR0))!=0; +#endif } void serial_write(uint8_t c) { - while(!(UCSR0A&(1< - -#define SERIAL_SET_CALLBACK(f) \ - ISR(USART_RX_vect) \ - { \ - char c = UDR0; \ - f(c); \ - } +#include void serial_init(uint16_t); +uint8_t serial_read(); +uint8_t serial_read_available(); +uint8_t serial_read_overrun(); void serial_write(uint8_t); +uint8_t serial_write_space(); #endif -- 2.45.2