diff --git a/src/main.c b/src/main.c index 016fa6d..34bac94 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include "serial.h" #include +#include #define MAX_CMDBUF 256 @@ -17,6 +18,10 @@ int main(void) return 1; } + // Handle USART_RXC interrupt + UCSRB |= (1 << RXCIE); + sei(); + USART_Init(); for (i = 1;; i++) { @@ -24,6 +29,7 @@ int main(void) sprintf(buf, "[CORE] Fetching sensors #%05lu...\r\n", i); USART_Write(buf); + USART_Update(); // USART_Read(&cmd, MAX_CMDBUF); // sprintf(buf, "[CORE] Checking cmdbuf=\"%s\"\r\n", cmd); diff --git a/src/serial.c b/src/serial.c index 84cb57a..9c0acb6 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,18 +1,21 @@ #include "common.h" #include "serial.h" -#include +#include +#include #include #define USART_BAUDRATE 9600 +// TODO: Use ring buffer! https://stackoverflow.com/a/1771607 + // Ensure closest fit for target baudrate //#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1) #define BAUD_PRESCALE ((((F_CPU / 16) + (USART_BAUDRATE / 2)) \ / (USART_BAUDRATE)) - 1) -static char USART_Rx(void); -static void USART_Tx(char ch); +static size_t cmdlen; +static char cmdbuf[256]; void USART_Init(void) { @@ -22,31 +25,11 @@ void USART_Init(void) UBRRL = BAUD_PRESCALE; // Baud rate lower byte } -void USART_Read(char **buf, int size) +void USART_Update(void) { - int n = 0; - char *p = *buf; - char ch; - - if ((UCSRA & BIT(RXC)) == 0) { - p = '\0'; - return; - } - - do { - // Discard messages exceeding - // given size limit quietly - if (n == size) { - p = '\0'; - while (USART_Rx()); - return; - } - - ch = USART_Rx(); - p[n] = ch; - n++; - - } while (ch != '\0'); + char buf[512]; + sprintf(buf, "[CORE] CMDBUF='%s'\r\n", cmdbuf); + USART_Write(buf); } void USART_Write(const char *buf) @@ -54,23 +37,26 @@ void USART_Write(const char *buf) int n = 0; while (buf[n] != '\0') { - USART_Tx(buf[n++]); + // Wait until UDR can receive data + while ((UCSRA & BIT(UDRE)) == 0); + UDR = buf[n++]; } } -static char USART_Rx(void) +// USART RX Interrupt +ISR(USART_RXC_vect) { - // Anything to read from UDR? - if ((UCSRA & BIT(RXC)) == 0) - return '\0'; + char ch; - return UDR; -} - -static void USART_Tx(char ch) -{ - // Wait until UDR can receive data - while ((UCSRA & BIT(UDRE)) == 0); - - UDR = ch; + ch = UDR; + + // Exceeded buffer capacity? + if (cmdlen >= sizeof(cmdbuf)) { + if (ch == '\n') { + cmdlen = 0; + } + return; + } + + cmdbuf[cmdlen++] = ch; } diff --git a/src/serial.h b/src/serial.h index fe74d29..cf19b41 100644 --- a/src/serial.h +++ b/src/serial.h @@ -2,7 +2,8 @@ #define MAD_SERIAL_H void USART_Init(void); -void USART_Read(char **buf, int size); +void USART_Update(void); +//void USART_Read(char **buf, int size); void USART_Write(const char *buf); #endif // MAD_SERIAL_H