Implement ring buffer and auxiliary functions

This commit is contained in:
2024-08-27 03:45:51 +02:00
parent 382b4770b0
commit 9638d10830
3 changed files with 58 additions and 56 deletions

View File

@@ -1,22 +1,12 @@
#include "common.h" #include "common.h"
#include "serial.h" #include "serial.h"
#include <stdio.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#define MAX_CMDBUF 256
int main(void) int main(void)
{ {
unsigned long i; unsigned long i;
char buf[128]; char ch;
char *cmd;
// UART command buffer
cmd = malloc(MAX_CMDBUF);
if (cmd == NULL) {
return 1;
}
// Handle USART_RXC interrupt // Handle USART_RXC interrupt
UCSRB |= (1 << RXCIE); UCSRB |= (1 << RXCIE);
@@ -27,13 +17,10 @@ int main(void)
for (i = 1;; i++) { for (i = 1;; i++) {
if (i >= 99999) i = 1; if (i >= 99999) i = 1;
sprintf(buf, "[CORE] Fetching sensors #%05lu...\r\n", i); ch = USART_GetChar();
USART_Write(buf); USART_Printf("[CORE] Fetching sensors #%05lu...\r\n", i);
USART_Update(); USART_Printf("[CORE] USART_GetChar() = '%c'\r\n",
(ch) ? ch : ' ');
// USART_Read(&cmd, MAX_CMDBUF);
// sprintf(buf, "[CORE] Checking cmdbuf=\"%s\"\r\n", cmd);
// USART_Write(buf);
Sleep(3000); Sleep(3000);
} }

View File

@@ -1,62 +1,77 @@
#include "common.h"
#include "serial.h" #include "serial.h"
#include "common.h"
#include <stdio.h>
#include <stdarg.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdio.h>
#define USART_BUFSIZE 512
#define USART_BAUDRATE 9600 #define USART_BAUDRATE 9600
#define USART_RXBUF_MASK (USART_BUFSIZE - 1)
#define USART_BAUD_PRESCALE ((((F_CPU / 16) + \
(USART_BAUDRATE / 2)) / (USART_BAUDRATE)) - 1)
// TODO: Use ring buffer! https://stackoverflow.com/a/1771607 static unsigned char rxbuf[USART_BUFSIZE];
static unsigned char rxhead, rxtail;
// 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 size_t cmdlen;
static char cmdbuf[256];
void USART_Init(void) void USART_Init(void)
{ {
rxhead = 0;
rxtail = 0;
UCSRB |= BIT(RXEN) | BIT(TXEN); // Enable rx and tx circuitry UCSRB |= BIT(RXEN) | BIT(TXEN); // Enable rx and tx circuitry
UCSRC |= BIT(URSEL) | BIT(UCSZ0) | BIT(UCSZ1); // 8-bit chars UCSRC |= BIT(URSEL) | BIT(UCSZ0) | BIT(UCSZ1); // 8-bit chars
UBRRH = (BAUD_PRESCALE >> 8); // Baud Rate upper byte UBRRH = (USART_BAUD_PRESCALE >> 8); // Baud Rate upper byte
UBRRL = BAUD_PRESCALE; // Baud rate lower byte UBRRL = USART_BAUD_PRESCALE; // Baud rate lower byte
} }
void USART_Update(void) char USART_GetChar(void)
{ {
char buf[512]; unsigned char newtail;
sprintf(buf, "[CORE] CMDBUF='%s'\r\n", cmdbuf);
USART_Write(buf); if (rxhead == rxtail) {
return '\0'; // Non-blocking
} }
void USART_Write(const char *buf) newtail = (rxtail + 1) & USART_RXBUF_MASK;
{ rxtail = newtail;
int n = 0;
while (buf[n] != '\0') { return rxbuf[newtail];
}
void USART_PutChar(const char ch)
{
// Wait until UDR can receive data // Wait until UDR can receive data
while ((UCSRA & BIT(UDRE)) == 0); while ((UCSRA & BIT(UDRE)) == 0);
UDR = buf[n++]; UDR = ch;
}
void USART_Printf(const char *fmt, ...)
{
char buf[256], *ptr;
va_list args;
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
ptr = buf;
while (*ptr != '\0') {
USART_PutChar(*ptr++);
} }
} }
// USART RX Interrupt // Interrupt Handler
ISR(USART_RXC_vect) ISR(USART_RXC_vect)
{ {
char ch; unsigned char newhead;
ch = UDR; newhead = (rxhead + 1) & USART_RXBUF_MASK;
if (newhead == rxtail) {
// Exceeded buffer capacity? // TODO: Handle overflow
if (cmdlen >= sizeof(cmdbuf)) { } else {
if (ch == '\n') { rxhead = newhead;
cmdlen = 0; rxbuf[newhead] = UDR;
} }
return;
}
cmdbuf[cmdlen++] = ch;
} }

View File

@@ -2,8 +2,8 @@
#define MAD_SERIAL_H #define MAD_SERIAL_H
void USART_Init(void); void USART_Init(void);
void USART_Update(void); char USART_GetChar(void);
//void USART_Read(char **buf, int size); void USART_PutChar(const char ch);
void USART_Write(const char *buf); void USART_Printf(const char *fmt, ...);
#endif // MAD_SERIAL_H #endif // MAD_SERIAL_H