Files
HendiControlFirmware/Control/firmware/uart_echo/uart.c
T
2019-03-29 21:33:32 +00:00

105 lines
1.5 KiB
C

/*
* uart.c
*
* Created: 20.02.2019 20:50:13
* Author: jens
*/
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "uart.h"
#include "message.h"
static Fifo *g_pFifo = NULL;
ISR(USART_UDRE_vect)
{
}
ISR(USART_TX_vect)
{
}
ISR(USART_RX_vect)
{
uint8_t status = UCSR0A;
if (status & (1 << RXC0))
{
uint8_t rx_data = UDR0;
Msg_t msg =
{
.code = Uart,
.m.uart.data = rx_data
};
fifo_push(g_pFifo, &msg);
}
}
void uart_init(Fifo *pFifo, uint32_t baudrate)
{
g_pFifo = pFifo;
uint16_t prescale8 = UART_PRESCALE(baudrate, 8UL);
uint16_t prescale16 = UART_PRESCALE(baudrate, 16UL);
uint32_t baud8 = ((prescale8+1) * 8);
uint32_t baud16 = ((prescale16+1) * 16);
uint32_t err8 = abs(baudrate - baud8);
uint32_t err16 = abs(baudrate - baud16);
uint16_t prescale = prescale16;
if (err8 < err16)
{
prescale = prescale8;
// Double UART speed
UCSR0A |= 1 << U2X0;
}
// Set baud rate
UBRR0L = (uint8_t)prescale;
UBRR0H = (uint8_t)(prescale >> 8);
// Enable receiver and transmitter
UCSR0B = (1<<TXEN0)|(1<<RXEN0);
// Enable RX interrupt
UCSR0B |= (1<<RXCIE0);
}
void uart_putc(char c)
{
while((UCSR0A & (1<<UDRE0)) == 0)
{
}
UDR0 = c;
}
int uart_putchar(char c, FILE *stream)
{
uart_putc(c);
if (c == 0x0A)
{
uart_putc(0x0D);
}
return 0;
}
void uart_puts(char const *str)
{
while(*str)
{
char c = *(str++);
uart_putc(c);
if (c == 0x0A)
{
uart_putc(0x0D);
}
}
}