Uart
Uart
* File: uart.c
* Author: Sanket
*/
#include "uart.h"
#include "interrupt.h"
/*
SPBRG = (FOSC / (BR x 4)) - 1
*/
#if _XTAL_FREQ == 32000000UL
#define UART_0_BR_1200_VAL (6666)
#define UART_0_BR_2400_VAL (3332)
#define UART_0_BR_4800_VAL (1666)
#define UART_0_BR_9600_VAL (832)
#define UART_0_BR_19200_VAL (416)
#define UART_0_BR_115200_VAL (68)
#endif
/*
* Global variables
*/
static union {
uint8_t value;
struct {
uint8_t BIT_0 : 1; // LSB (bit 0)
uint8_t BIT_1 : 1;
uint8_t BIT_2 : 1;
uint8_t BIT_3 : 1;
uint8_t BIT_4 : 1;
uint8_t BIT_5 : 1;
uint8_t BIT_6 : 1;
uint8_t BIT_7 : 1; // MSB (bit 7)
} x;
struct {
uint8_t:
7; // LSB (bit 0 to 6)
uint8_t PARITY : 1; // MSB (bit 7)
} y;
} tx_0_data;
static union {
uint8_t value;
struct {
uint8_t BIT_0 : 1; // LSB (bit 0)
uint8_t BIT_1 : 1;
uint8_t BIT_2 : 1;
uint8_t BIT_3 : 1;
uint8_t BIT_4 : 1;
uint8_t BIT_5 : 1;
uint8_t BIT_6 : 1;
uint8_t BIT_7 : 1; // MSB (bit 7)
} x;
struct {
uint8_t:
7; // LSB (bit 0 to 6)
uint8_t PARITY : 1; // MSB (bit 7)
} y;
} rx_0_data;
uint8_t is_query_received;
uint8_t rx_buffer[UART_0_MAX_BUFFER_LEN];
/*
* Private function prototypes
*/
/*
* Function definitions
*/
static void uart_0_calculate_parity(void) {
uint8_t parity = 0;
if (tx_0_data.x.BIT_0) {
parity++;
}
if (tx_0_data.x.BIT_1) {
parity++;
}
if (tx_0_data.x.BIT_2) {
parity++;
}
if (tx_0_data.x.BIT_3) {
parity++;
}
if (tx_0_data.x.BIT_4) {
parity++;
}
if (tx_0_data.x.BIT_5) {
parity++;
}
if (tx_0_data.x.BIT_6) {
parity++;
}
if (uart_0_mode == UART_0_7_O_1) {
tx_0_data.y.PARITY = parity & 1 ? BIT_CLR : BIT_SET;
return;
}
else if (uart_0_mode == UART_0_7_E_1) {
tx_0_data.y.PARITY = parity & 1 ? BIT_SET : BIT_CLR;
return;
}
if (tx_0_data.x.BIT_7) {
parity++;
}
if (uart_0_mode == UART_0_8_O_1) {
TXSTAbits.TX9D = parity & 1 ? BIT_CLR : BIT_SET;
}
else if (uart_0_mode == UART_0_8_E_1) {
TXSTAbits.TX9D = parity & 1 ? BIT_SET : BIT_CLR;
}
}
rx_0_data.value = data_byte;
if (rx_0_data.x.BIT_0) {
parity++;
}
if (rx_0_data.x.BIT_1) {
parity++;
}
if (rx_0_data.x.BIT_2) {
parity++;
}
if (rx_0_data.x.BIT_3) {
parity++;
}
if (rx_0_data.x.BIT_4) {
parity++;
}
if (rx_0_data.x.BIT_5) {
parity++;
}
if (rx_0_data.x.BIT_6) {
parity++;
}
if (uart_0_mode == UART_0_7_O_1) {
return (rx_0_data.y.PARITY != (parity & 1)) ? SUCCESS : FAILURE;
}
else if (uart_0_mode == UART_0_7_E_1) {
return (rx_0_data.y.PARITY == (parity & 1)) ? SUCCESS : FAILURE;
}
if (rx_0_data.x.BIT_7) {
parity++;
}
if (uart_0_mode == UART_0_8_O_1) {
return (RCSTAbits.RX9D != (parity & 1)) ? SUCCESS : FAILURE;
}
else if (uart_0_mode == UART_0_8_E_1) {
return (RCSTAbits.RX9D == (parity & 1)) ? SUCCESS : FAILURE;
}
return FAILURE;
}
void uart_0_tx_en(void) {
// Enable the transmitter.
TXSTAbits.TXEN = BIT_SET;
}
void uart_0_tx_ds(void) {
// Wait till transmit buffer gets empty.
while (!TXSTAbits.TRMT);
// Disable uart 0.
RCSTAbits.SPEN = BIT_CLR;
// Disable receiver.
RCSTAbits.CREN = BIT_CLR;
// Disable transmitter.
uart_0_tx_ds();
if (mode == UART_0_INVALID) {
return;
}
MB_TX_DIR = DIR_OP;
MB_TX_OFF();
// Asynchronous modes.
TXSTAbits.SYNC = BIT_CLR;
switch (baudrate) {
case UART_0_1200:
SPBRG = UART_0_BR_1200_VAL & 0xFF;
SPBRGH = (UART_0_BR_1200_VAL >> 8) & 0xFF;
break;
case UART_0_2400:
SPBRG = UART_0_BR_2400_VAL & 0xFF;
SPBRGH = (UART_0_BR_2400_VAL >> 8) & 0xFF;
break;
case UART_0_4800:
SPBRG = UART_0_BR_4800_VAL & 0xFF;
SPBRGH = (UART_0_BR_4800_VAL >> 8) & 0xFF;
break;
case UART_0_9600:
SPBRG = UART_0_BR_9600_VAL & 0xFF;
SPBRGH = (UART_0_BR_9600_VAL >> 8) & 0xFF;
break;
case UART_0_19200:
SPBRG = UART_0_BR_19200_VAL & 0xFF;
SPBRGH = (UART_0_BR_19200_VAL >> 8) & 0xFF;
break;
default:
break;
}
// Enable transmitter.
//uart_0_tx_en();
// Enable receiver.
RCSTAbits.CREN = BIT_SET;
// Enable uart 0.
RCSTAbits.SPEN = BIT_SET;
}
void uart_0_tx_character(const uint8_t data_byte,
const
uart_0_tx_mode_t tx_mode) {
tx_0_data.value = data_byte;
TXREG = tx_0_data.value;
if (tx_mode == UART_0_POLL_BASED) {
// Wait till buffer empty.
while (!TXSTAbits.TRMT || !INTR_UART_0_TX_CHK());
}
}
void uart_0_tx_isr(void) {
if (is_query_received) {
return;
}
if (!did_find_new_msg) {
if (rx_byte != *(new_msg_cmd + data_len)) {
data_len = 0;
}
if (rx_byte == *(new_msg_cmd + data_len)) {
data_len++;
}
if (data_len == NEW_MSG_CMD_LEN) {
did_find_new_msg = BIT_SET;
rx_buffer_len = 1;
rx_buffer[0] = 0;
data_len = 0;
}
}
else {
if (rx_byte != *(eol_cmd + data_len)) {
data_len = 0;
}
if (rx_byte == *(eol_cmd + data_len)) {
data_len++;
}
rx_buffer[rx_buffer_len] = rx_byte;
rx_buffer[0] = rx_buffer_len;
if (rx_buffer_len < (UART_0_MAX_BUFFER_LEN - 1)) {
rx_buffer_len++;
}
if (data_len == EOL_CMD_LEN) {
rx_buffer[0] -= EOL_CMD_LEN;
did_find_new_msg = BIT_CLR;
is_query_received = BIT_SET;
}
}
}