0% found this document useful (0 votes)
8 views9 pages

Uart

The document is a C source code file for UART (Universal Asynchronous Receiver-Transmitter) communication, detailing the configuration and functions for transmitting and receiving data. It includes definitions for various baud rates based on different oscillator frequencies, as well as functions for enabling transmission, checking parity, and handling interrupts. The code also manages the UART mode settings and initializes the UART hardware for communication.

Uploaded by

technosanky
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views9 pages

Uart

The document is a C source code file for UART (Universal Asynchronous Receiver-Transmitter) communication, detailing the configuration and functions for transmitting and receiving data. It includes definitions for various baud rates based on different oscillator frequencies, as well as functions for enabling transmission, checking parity, and handling interrupts. The code also manages the UART mode settings and initializes the UART hardware for communication.

Uploaded by

technosanky
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 9

/*

* File: uart.c
* Author: Sanket
*/

#include "uart.h"
#include "interrupt.h"

#define UART_0_TX_DIR (TRISCbits.TRISC6)


#define UART_0_TX_PIN (PORTCbits.RC6)
#define UART_0_TX_ON() ((UART_0_TX_PIN) = (BIT_SET))
#define UART_0_TX_OFF() ((UART_0_TX_PIN) = (BIT_CLR))
#define UART_0_TX_CHK() (PORTCbits.RC6)

#define UART_0_RX_DIR (TRISCbits.TRISC7)


#define UART_0_RX_PIN (PORTCbits.RC7)
#define UART_0_RX_ON() ((UART_0_RX_PIN) = (BIT_SET))
#define UART_0_RX_OFF() ((UART_0_RX_PIN) = (BIT_CLR))
#define UART_0_RX_CHK() (PORTCbits.RC7)

#define MB_TX_DIR (TRISCbits.TRISC4)


#define MB_TX_PIN (PORTCbits.RC4)
#define MB_TX_ON() ((MB_TX_PIN) =
(BIT_SET))
#define MB_TX_OFF() ((MB_TX_PIN) =
(BIT_CLR))
#define MB_TX_CHK() (PORTCbits.RC4)

/*
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)

#elif _XTAL_FREQ == 24000000UL


#define UART_0_BR_1200_VAL (4999)
#define UART_0_BR_2400_VAL (2499)
#define UART_0_BR_4800_VAL (1249)
#define UART_0_BR_9600_VAL (624)
#define UART_0_BR_19200_VAL (312)
#define UART_0_BR_115200_VAL (51)

#elif _XTAL_FREQ == 20000000UL


#define UART_0_BR_1200_VAL (4166)
#define UART_0_BR_2400_VAL (2082)
#define UART_0_BR_4800_VAL (1041)
#define UART_0_BR_9600_VAL (520)
#define UART_0_BR_19200_VAL (259)
#define UART_0_BR_115200_VAL (42)

#elif _XTAL_FREQ == 16000000UL


#define UART_0_BR_1200_VAL (3332)
#define UART_0_BR_2400_VAL (1666)
#define UART_0_BR_4800_VAL (832)
#define UART_0_BR_9600_VAL (416)
#define UART_0_BR_19200_VAL (207)
#define UART_0_BR_115200_VAL (34)

#elif _XTAL_FREQ == 12000000UL


#define UART_0_BR_1200_VAL (2499)
#define UART_0_BR_2400_VAL (1249)
#define UART_0_BR_4800_VAL (624)
#define UART_0_BR_9600_VAL (312)
#define UART_0_BR_19200_VAL (155)
#define UART_0_BR_115200_VAL (25)

#elif _XTAL_FREQ == 11059200UL


#define UART_0_BR_1200_VAL (2303)
#define UART_0_BR_2400_VAL (1151)
#define UART_0_BR_4800_VAL (575)
#define UART_0_BR_9600_VAL (287)
#define UART_0_BR_19200_VAL (143)
#define UART_0_BR_115200_VAL (23)

#elif _XTAL_FREQ == 8000000UL


#define UART_0_BR_1200_VAL (1666)
#define UART_0_BR_2400_VAL (832)
#define UART_0_BR_4800_VAL (416)
#define UART_0_BR_9600_VAL (207)
#define UART_0_BR_19200_VAL (103)
#define UART_0_BR_115200_VAL (16)

#elif _XTAL_FREQ == 4000000UL


#define UART_0_BR_1200_VAL (832)
#define UART_0_BR_2400_VAL (416)
#define UART_0_BR_4800_VAL (207)
#define UART_0_BR_9600_VAL (103)
#define UART_0_BR_19200_VAL (51)
#define UART_0_BR_115200_VAL (8)

#endif

#define NEW_MSG_CMD_LEN (1)


#define EOL_CMD_LEN (1)

/*
* 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;

static uart_0_mode_t uart_0_mode;


static const uint8_t *new_msg_cmd = (uint8_t *) "*";
static const uint8_t *eol_cmd = (uint8_t *) "#";

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;
}
}

int8_t uart_0_parity_chk(const uint8_t data_byte) {


uint8_t parity = 0;

if (uart_0_mode == UART_0_7_N_2 || uart_0_mode == UART_0_8_N_1 ||


uart_0_mode == UART_0_8_N_2) {
return SUCCESS;
}

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 the transmitter.


TXSTAbits.TXEN = BIT_CLR;
}

void init_uart_0(const uart_0_baudrate_t baudrate, const uart_0_mode_t mode) {


// Disable uart 0 RX interrupt.
INTR_UART_0_RX_DS();

// Disable uart 0 TX interrupt.


INTR_UART_0_TX_DS();

// Disable uart 0.
RCSTAbits.SPEN = BIT_CLR;

// Disable receiver.
RCSTAbits.CREN = BIT_CLR;
// Disable transmitter.
uart_0_tx_ds();

// Save uart 0 configuration.


uart_0_mode = mode;

if (mode == UART_0_INVALID) {
return;
}

// Initialize all digital I/O pins declared.


UART_0_TX_DIR = DIR_OP;
UART_0_RX_DIR = DIR_IP;

MB_TX_DIR = DIR_OP;
MB_TX_OFF();

// Initialize initial states of output pins.


// When uart enabled, pins will be auto configured. Hence no change here.

// Asynchronous modes.
TXSTAbits.SYNC = BIT_CLR;

// Transmit non-inverted data to the TX/CK pin.


BAUDCTLbits.SCKP = BIT_CLR;

// Sync Break transmission completed.


TXSTAbits.SENDB = BIT_CLR;

if (uart_0_mode == UART_0_7_E_1 || uart_0_mode == UART_0_7_O_1 ||


uart_0_mode == UART_0_7_N_2 || uart_0_mode == UART_0_8_N_1) {
// Selects 8-bit transmission.
TXSTAbits.TX9 = BIT_CLR;

// Selects 8-bit reception.


RCSTAbits.RX9 = BIT_CLR;
}
else {
// Selects 9-bit transmission.
TXSTAbits.TX9 = BIT_SET;

// Selects 9-bit reception.


RCSTAbits.RX9 = BIT_SET;

// Disable address detection.


// Ninth bit used as either parity bit or an extra stop bit (7-E/O-2).
RCSTAbits.ADDEN = BIT_CLR;
}

// Clear Framing Error. Not required as it is readonly.


//UART_0_FRAME_ERR_CLR();

// Clear uart 0 data.


tx_0_data.value = 0;

if (uart_0_mode == UART_0_7_E_1 || uart_0_mode == UART_0_7_O_1) {


// Calculate parity to be used at bit 7.
uart_0_calculate_parity();
}
else if (uart_0_mode == UART_0_7_N_2) {
// Use parity bit (bit 7) as an extra stop bit. Stop bit is always 1.
tx_0_data.y.PARITY = BIT_SET;
}
else if (uart_0_mode == UART_0_8_N_2) {
// Use parity bit (bit 8) as an extra stop bit. Stop bit is always 1.
TXSTAbits.TX9D = BIT_SET;
}
else if (uart_0_mode == UART_0_8_E_1 || uart_0_mode == UART_0_8_O_1) {
// Calculate parity to be used at bit 8.
uart_0_calculate_parity();
}

// High speed baudrate.


TXSTAbits.BRGH = BIT_SET;

// 16-bit baudrate generator is used.


BAUDCTLbits.BRG16 = BIT_SET;

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;

if (((uint8_t) uart_0_mode) & 1) {


uart_0_calculate_parity();
}
else if (uart_0_mode == UART_0_7_N_2) {
// Use parity bit (bit 7) as an extra stop bit. Stop bit is always 1.
tx_0_data.y.PARITY = BIT_SET;
}

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_string(const uint8_t *p_str) {


// Send data.
while (*p_str) {
uart_0_tx_character(*p_str++, UART_0_POLL_BASED);
}
}

void uart_0_tx_isr(void) {

void uart_0_rx_isr(const uint8_t rx_byte) {


static uint8_t data_len = 0, rx_buffer_len = 0;
static uint8_t did_find_new_msg = BIT_CLR;

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;
}
}
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy