From 729f2a2c3ebfb2612d873caf453a1d7ca02180d9 Mon Sep 17 00:00:00 2001 From: dmlunar Date: Wed, 22 Jan 2025 16:47:21 +0200 Subject: varpa: initial public commit --- firmware/src/peripheral/uart.c | 239 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 firmware/src/peripheral/uart.c (limited to 'firmware/src/peripheral/uart.c') diff --git a/firmware/src/peripheral/uart.c b/firmware/src/peripheral/uart.c new file mode 100644 index 0000000..defcf54 --- /dev/null +++ b/firmware/src/peripheral/uart.c @@ -0,0 +1,239 @@ +/** + * + * Author: Dylan Muller + * Copyright (c) 2025 + * All rights reserved. + * + * - Commercial/IP use prohibited. + * - Attribution required. + * See License.txt + * + */ + +#include "setup.h" + +#include "peripheral/ring.h" +#include "peripheral/uart.h" + +#include "status.h" +#include "cmd.h" + +#include +#include +#include +#include + +extern t_system_status system_status; + +static int uart_putc( + char c, + FILE *stream +) +{ + (void)stream; + + if(uart_tx(c)) + return _FDEV_EOF; + + return c; +} + +static int uart_getc( + FILE *stream +) +{ + uint8_t c; + (void)stream; + + if(uart_rx(&c)) + return _FDEV_EOF; + + return c; +} + +FILE uart_out = FDEV_SETUP_STREAM(uart_putc, NULL, _FDEV_SETUP_WRITE); +FILE uart_in = FDEV_SETUP_STREAM(NULL, uart_getc, _FDEV_SETUP_READ); + +static volatile ring_t uart_tx_ring; +static volatile ring_t uart_rx_ring; + +static volatile uint8_t uart_tx_buf[UART_BUF_SIZE]; +static volatile uint8_t uart_rx_buf[UART_BUF_SIZE]; + +void uart_init(void) +{ + uart_tx_ring = ring_init((uint8_t*)uart_tx_buf, UART_BUF_SIZE - 1); + uart_rx_ring = ring_init((uint8_t*)uart_rx_buf, UART_BUF_SIZE - 1); + + UBRR0H = UBRRH_VALUE; + UBRR0L = UBRRL_VALUE; + UCSR0B |= (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); + UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); + + stdout = &uart_out; + stdin = &uart_in; +} + +bool uart_tx( + uint8_t data +) +{ + bool ret; + + while(ring_is_full(uart_tx_ring)); + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + ret = ring_push((ring_t*)&uart_tx_ring, data); + } + + if(!ret) + UCSR0B |= (1 << UDRIE0); + + return ret; +} + +bool uart_rx( + uint8_t* data +) +{ + bool ret; + + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) + { + ret = ring_pop((ring_t*)&uart_rx_ring, data); + } + + return ret; +} + +size_t uart_tx_burst( + uint8_t *data, + size_t size +) +{ + size_t i = 0; + + while(i= n-1) + { + s[i] = '\0'; + i = 0; + + return s; + } + } + + return NULL; +} + +ISR(USART_UDRE_vect) +{ + uint8_t c; + + if(!ring_pop((ring_t*)&uart_tx_ring, &c)) + UDR0 = c; + + else + UCSR0B &= ~(1 << UDRIE0); +} + +ISR(USART_RX_vect) +{ + if (system_status.status == SYSTEM_STATUS_BUSY) + { + // system busy.. lock now! + CMD_ERROR("SYSTEM BUSY"); + system_status.status = SYSTEM_STATUS_LOCKED; + } + + if (system_status.status != SYSTEM_STATUS_LOCKED) + { + #ifdef UART_OVERWRITE + ring_push_over((ring_t*)&uart_rx_ring, UDR0); + #else + ring_push((ring_t*)&uart_rx_ring, UDR0); + #endif + } + else{ + (uint8_t)UDR0; + } +} -- cgit v1.2.3-70-g09d2