2021-11-18 19:34:41 +01:00
/*
* UART . c
*
2021-12-04 23:11:51 +01:00
* Created : 25 / 11 / 2021 16 : 26 : 10
2021-11-18 19:34:41 +01:00
* Author : n0x
*/
# include "UART.h"
2022-01-26 21:17:40 +01:00
/* create structs for TX and TX buffer */
2022-01-20 17:22:50 +01:00
CircularBuffer TxBuffer ;
CircularBuffer * pTxBuffer = & TxBuffer ;
CircularBuffer RxBuffer ;
CircularBuffer * pRxBuffer = & RxBuffer ;
2021-11-18 19:34:41 +01:00
2021-12-04 23:11:51 +01:00
volatile uint8_t TxActive ;
2021-11-18 19:34:41 +01:00
void
2022-01-26 21:17:40 +01:00
uart_init ( void ) {
2021-12-04 23:11:51 +01:00
UBRR0 = 103 ; /* set BAUD rate to 9600 */
2021-11-18 19:34:41 +01:00
2021-12-04 23:11:51 +01:00
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 */
2021-11-18 19:34:41 +01:00
2022-01-26 21:17:40 +01:00
/* Initiate read- and write-pointers */
2022-01-20 17:22:50 +01:00
pTxBuffer - > Readpointer = 0 ;
pTxBuffer - > Writepointer = 0 ;
pRxBuffer - > Readpointer = 0 ;
pRxBuffer - > Writepointer = 0 ;
2021-11-18 19:34:41 +01:00
}
2022-01-26 21:17:40 +01:00
/********Sending Data********/
2021-11-18 19:34:41 +01:00
2021-12-04 23:11:51 +01:00
void
2022-01-26 21:17:40 +01:00
uart_send_string ( char * string ) {
/* Take a whole string and transmit every char from it */
2021-12-04 23:11:51 +01:00
int i = 0 ;
while ( string [ i ] ! = ' \0 ' ) {
uart_send_byte ( string [ i ] ) ;
i + + ;
2021-11-18 19:34:41 +01:00
}
}
2021-12-04 23:11:51 +01:00
void
2022-01-26 21:17:40 +01:00
uart_send_byte ( char c ) {
/* Disable the TX Interrupt to prevent issues while writing to the send buffer*/
2022-01-20 17:22:50 +01:00
UCSR0B & = ~ ( 1 < < TXCIE0 ) ;
2021-11-18 19:34:41 +01:00
2022-01-26 21:17:40 +01:00
/* Check if a transmit is in progress
if yes - > write the byte to the buffer
if no - > write the byte to the UDR0 register and enable the transmit in progress flag
*/
2021-12-04 23:11:51 +01:00
if ( TxActive ) {
2022-01-20 17:22:50 +01:00
pTxBuffer - > data [ pTxBuffer - > Writepointer + + ] = c ;
if ( pTxBuffer - > Writepointer > = SIZE_BUFFER ) {
pTxBuffer - > Writepointer = 0 ;
2021-12-04 23:11:51 +01:00
}
} else {
TxActive = 1 ;
UDR0 = c ;
}
2022-01-20 17:22:50 +01:00
/* Enable the TX Interrupt again*/
2021-12-04 23:11:51 +01:00
UCSR0B | = ( 1 < < TXCIE0 ) ;
}
2022-01-26 21:17:40 +01:00
/* when data (a data frame) is to be send */
ISR ( USART0_TX_vect ) {
/* check if the read and write pointer of the send buffer are not aligned
if not aligned - > read the next byte and write it to UDR0 register
if aligned - > no more data to send , disable the send in progress flag */
2022-01-20 17:22:50 +01:00
if ( pTxBuffer - > Readpointer ! = pTxBuffer - > Writepointer )
2021-12-04 23:11:51 +01:00
{
2022-01-26 21:17:40 +01:00
/* writing data to the register withing the interrupt will cause a new interrupt which then will repeat till no more data is to be read from the send buffer */
2022-01-20 17:22:50 +01:00
UDR0 = pTxBuffer - > data [ pTxBuffer - > Readpointer + + ] ;
2021-12-04 23:11:51 +01:00
2022-01-20 17:22:50 +01:00
if ( pTxBuffer - > Readpointer > = SIZE_BUFFER ) {
pTxBuffer - > Readpointer = 0 ;
2021-12-04 23:11:51 +01:00
}
} else {
TxActive = 0 ;
}
2021-11-18 19:34:41 +01:00
}
2022-01-26 21:17:40 +01:00
/*******Receiving Data*******/
2021-12-04 23:11:51 +01:00
uint8_t
2022-01-26 21:17:40 +01:00
uart_data_available ( void ) {
2021-12-04 23:11:51 +01:00
uint8_t dataAvailabel = 0 ;
2022-01-26 21:17:40 +01:00
/* Disable the RX Interrupt to prevent issues when checking if data is available */
2021-12-04 23:11:51 +01:00
UCSR0B & = ~ ( 1 < < RXCIE0 ) ;
2022-01-26 21:17:40 +01:00
/* check if read and write pointer are at different locations
if yes - > data is available and can be read */
2022-01-20 17:22:50 +01:00
if ( pRxBuffer - > Readpointer ! = pRxBuffer - > Writepointer ) {
2021-12-04 23:11:51 +01:00
dataAvailabel = 1 ;
}
2022-01-26 21:17:40 +01:00
/* Enable the RX Interrupt again*/
2021-12-04 23:11:51 +01:00
UCSR0B | = ( 1 < < RXCIE0 ) ;
return dataAvailabel ;
}
char
2022-01-26 21:17:40 +01:00
uart_get_data ( void ) {
2021-12-04 23:11:51 +01:00
char data = 0 ;
2022-01-26 21:17:40 +01:00
/* Disable the RX Interrupt to prevent issues when reading out a char from the buffer */
2021-12-04 23:11:51 +01:00
UCSR0B & = ~ ( 1 < < RXCIE0 ) ;
2022-01-26 21:17:40 +01:00
/* check if read and write pointer are at different locations
if yes - > data is available and can be read */
2022-01-20 17:22:50 +01:00
if ( pRxBuffer - > Readpointer ! = pRxBuffer - > Writepointer )
2021-12-04 23:11:51 +01:00
{
2022-01-26 21:17:40 +01:00
/* read a char from the buffer and increment the readpointer */
2022-01-20 17:22:50 +01:00
data = pRxBuffer - > data [ pRxBuffer - > Readpointer + + ] ;
if ( pRxBuffer - > Readpointer > = SIZE_BUFFER ) {
pRxBuffer - > Readpointer = 0 ;
2021-11-18 19:34:41 +01:00
}
}
2022-01-26 21:17:40 +01:00
/* Enable the RX Interrupt again*/
2021-12-04 23:11:51 +01:00
UCSR0B | = ( 1 < < RXCIE0 ) ;
2022-01-26 21:17:40 +01:00
/* give back the read in character */
2021-12-04 23:11:51 +01:00
return data ;
2021-11-18 19:34:41 +01:00
}
2022-01-26 21:17:40 +01:00
/* when data (a data frame) is received */
ISR ( USART0_RX_vect ) {
2021-12-04 23:11:51 +01:00
uint8_t status = UCSR0A ;
uint8_t data = UDR0 ;
2022-01-26 21:17:40 +01:00
/* check status flags if data is correctly accessible */
if ( ( status & ( ( 1 < < DOR0 ) | ( 1 < < FE0 ) ) ) = = 0 ) {
/* Save data to buffer and increment the write pointer */
2022-01-20 17:22:50 +01:00
pRxBuffer - > data [ pRxBuffer - > Writepointer + + ] = data ;
if ( pRxBuffer - > Writepointer > = SIZE_BUFFER ) {
pRxBuffer - > Writepointer = 0 ;
2021-12-04 23:11:51 +01:00
}
}
2021-11-18 19:34:41 +01:00
}