You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
2.3 KiB
C

/*
* UART.c
*
* Created: 25/11/2021 16:26:10
* Author: n0x
*/
#include "UART.h"
#define SIZE_BUFFER 500
struct CircularBuffer{
volatile char data[SIZE_BUFFER];
volatile uint16_t Readpointer;
volatile uint16_t Writepointer;
};
struct CircularBuffer TxBuffer;
struct CircularBuffer RxBuffer;
volatile uint8_t TxActive;
void
uart_init(void)
{
UBRR0 = 103; /* set BAUD rate to 9600 */
UCSR0C |=
(0<<UMSEL00)|(0<<UMSEL01)| /* Async UART */
(0<<UPM00)|(0<<UPM01)| /* Disable Parity */
(1<<UCSZ00)|(1<<UCSZ01)| /* 8 Bit */
(0<<USBS0); /* 1 Stopbit */
UCSR0B |=
(1<<TXEN0)|(1<<RXEN0)| /* enable send and receive */
(1<<RXCIE0); /* enable Receive interrupts */
TxBuffer.Readpointer = 0;
TxBuffer.Writepointer = 0;
RxBuffer.Readpointer = 0;
RxBuffer.Writepointer = 0;
}
/* ------------------------ */
/* Sending Data */
/* ------------------------ */
void
uart_send_string(char* string)
{
int i = 0;
while(string[i] != '\0'){
uart_send_byte(string[i]);
i++;
}
}
void
uart_send_byte(char c)
{
UCSR0B&=~(1<<TXCIE0);
if(TxActive){
TxBuffer.data[TxBuffer.Writepointer++] = c;
if (TxBuffer.Writepointer>=SIZE_BUFFER){
TxBuffer.Writepointer = 0;
}
} else {
TxActive = 1;
UDR0 = c;
}
UCSR0B |= (1<<TXCIE0);
}
ISR(USART0_TX_vect)
{
if(TxBuffer.Readpointer != TxBuffer.Writepointer)
{
UDR0 = TxBuffer.data[TxBuffer.Readpointer++];
if(TxBuffer.Readpointer >= SIZE_BUFFER){
TxBuffer.Readpointer = 0;
}
} else {
TxActive = 0;
}
}
/* ------------------------ */
/* Receiving Data */
/* ------------------------ */
uint8_t
uart_data_available(void)
{
uint8_t dataAvailabel = 0;
UCSR0B &= ~(1<<RXCIE0);
if(RxBuffer.Readpointer != RxBuffer.Writepointer){
dataAvailabel = 1;
}
UCSR0B |= (1<<RXCIE0);
return dataAvailabel;
}
char
uart_get_data(void)
{
char data = 0;
UCSR0B &= ~(1<<RXCIE0);
if(RxBuffer.Readpointer != RxBuffer.Writepointer)
{
data = RxBuffer.data[RxBuffer.Readpointer++];
if(RxBuffer.Readpointer >= SIZE_BUFFER){
RxBuffer.Readpointer = 0;
}
}
UCSR0B |= (1<<RXCIE0);
return data;
}
ISR(USART0_RX_vect)
{
uint8_t status = UCSR0A;
uint8_t data = UDR0;
if((status & ((1<<DOR0) | (1>>FE0))) == 0){
RxBuffer.data[RxBuffer.Writepointer++] = data;
if(RxBuffer.Writepointer >= SIZE_BUFFER) {
RxBuffer.Writepointer = 0;
}
}
}