71 lines
1.7 KiB
C
71 lines
1.7 KiB
C
/*
|
|
* Copyright 2017-2024 Oleg Borodin <onborodin@gmail.com>
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
#include <avr/io.h>
|
|
#include <util/delay.h>
|
|
#define BAUD 38400
|
|
#include <util/setbaud.h>
|
|
|
|
#include <tool.h>
|
|
#include <fifo.h>
|
|
#include <uart.h>
|
|
|
|
|
|
static uint8_t inbuf[FIFO_BUFFER_SIZE];
|
|
static uint8_t outbuf[FIFO_BUFFER_SIZE];
|
|
|
|
fifo_t uart_inbuf, uart_outbuf;
|
|
|
|
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
|
|
|
|
int uart_putchar(char c, FILE * stream) {
|
|
return fifo_putc(&uart_outbuf, c);
|
|
}
|
|
|
|
int uart_getchar(FILE * stream) {
|
|
return (int)fifo_getc(&uart_inbuf);
|
|
}
|
|
|
|
void uartio_init(void) {
|
|
fifo_init(&uart_inbuf, inbuf, sizeof(inbuf));
|
|
fifo_init(&uart_outbuf, outbuf, sizeof(outbuf));
|
|
stdout = &uart_stream;
|
|
stdin = &uart_stream;
|
|
stderr = &uart_stream;
|
|
}
|
|
|
|
void uart_init(void) {
|
|
/* Set port speed */
|
|
UBRR0H = UBRRH_VALUE;
|
|
UBRR0L = UBRRL_VALUE;
|
|
/* Disable double speed operation */
|
|
REG_SETDOWN_BIT(UCSR0A, U2X0);
|
|
/* Set character size to 8 bit */
|
|
REG_SETDOWN_BIT(UCSR0B, UCSZ02);
|
|
REG_SETUP_BIT(UCSR0C, UCSZ01);
|
|
REG_SETUP_BIT(UCSR0C, UCSZ00);
|
|
/* Set one stop bit, no parity */
|
|
REG_SETDOWN_BIT(UCSR0C, USBS0);
|
|
REG_SETDOWN_BIT(UCSR0C, UPM00);
|
|
REG_SETDOWN_BIT(UCSR0C, UPM01);
|
|
/* Enable TX and RX */
|
|
REG_SETUP_BIT(UCSR0B, TXEN0);
|
|
REG_SETUP_BIT(UCSR0B, RXEN0);
|
|
/* Disable receive & transmit interrupts */
|
|
REG_SETDOWN_BIT(UCSR0B, RXCIE0);
|
|
REG_SETDOWN_BIT(UCSR0B, UDRIE0);
|
|
_delay_ms(20);
|
|
}
|
|
|
|
void uart_handle(void) {
|
|
volatile uint8_t xchar;
|
|
while ((xchar = fifo_getc(&uart_outbuf)) > 0) {
|
|
while (!REG_BIT_ISUP(UCSR0A, UDRE0));
|
|
UDR0 = xchar;
|
|
}
|
|
}
|