0,0 → 1,137 |
#include <xc.h> |
#include "defines.h" |
#include "base_UART.h" |
|
static UART_DATA *uart_data_p; |
|
void UART_Init(UART_DATA *data) { |
uart_data_p = data; |
|
UART_TX_TRIS = 0; // Tx pin set to output |
#ifndef UART_TX_ONLY |
UART_RX_TRIS = 1; // Rx pin set to input |
#endif |
LATAbits.LATA0 = 1; // Keep the line high at start |
|
BAUDCONbits.BRG16 = 0; // 8-bit baud rate generator |
SPBRGL = 25; // Set UART speed to 38400 baud |
TXSTAbits.BRGH = 1; // High speed mode |
|
TXSTAbits.SYNC = 0; // Async mode |
RCSTAbits.SPEN = 1; // Serial port enable |
|
TXSTAbits.TX9 = 0; // 8 bit transmission |
|
TXSTAbits.TXEN = 1; // Transmission enabled |
|
PIE1bits.TXIE = 0; // Disable TX interrupt |
#ifndef UART_TX_ONLY |
RCSTAbits.RX9 = 0; // 8 bit reception |
RCSTAbits.CREN = 1; // Enables receiver |
PIE1bits.RCIE = 1; // Enable RX interrupt |
|
// Initialize the buffer that holds UART messages |
uart_data_p->buffer_in_read_ind = 0; |
uart_data_p->buffer_in_write_ind = 0; |
uart_data_p->buffer_in_len = 0; |
uart_data_p->buffer_in_len_tmp = 0; |
#else |
RCSTAbits.CREN = 0; |
#endif |
uart_data_p->buffer_out_ind = 0; |
uart_data_p->buffer_out_len = 0; |
} |
|
void UART_Send_Interrupt_Handler() { |
// Put remaining data in TSR for transmit |
if (uart_data_p->buffer_out_ind != uart_data_p->buffer_out_len) { |
TXREG = uart_data_p->buffer_out[uart_data_p->buffer_out_ind]; |
uart_data_p->buffer_out_ind++; |
} else { |
while (!TXSTAbits.TRMT); // Wait for last byte to finish sending |
PIE1bits.TXIE = 0; |
uart_data_p->buffer_out_ind = 0; |
uart_data_p->buffer_out_len = 0; |
} |
} |
|
void UART_Write(const char *string, char length) { |
while (PIE1bits.TXIE); // Wait for previous message to finish sending |
uart_data_p->buffer_out_len = length; |
uart_data_p->buffer_out_ind = 1; |
for (char i = 0; i < length; i++) { |
uart_data_p->buffer_out[i] = string[i]; |
} |
TXREG = uart_data_p->buffer_out[0]; // Put first byte in TSR |
PIE1bits.TXIE = 1; |
} |
|
void UART_WriteD(const char* string, char length) { |
PIE1bits.TXIE = 1; |
for (char i = 0; i < length; i++) { |
TXREG = string[i]; |
NOP(); |
while (!PIR1bits.TXIF); |
} |
PIE1bits.TXIE = 0; |
} |
|
#ifndef UART_TX_ONLY |
void UART_Recv_Interrupt_Handler() { |
if (PIR1bits.RCIF) { // Check if data receive flag is set |
char c = RCREG; |
|
// Save received data into buffer |
uart_data_p->buffer_in[uart_data_p->buffer_in_write_ind] = c; |
if (uart_data_p->buffer_in_write_ind == MAXUARTBUF - 1) { |
uart_data_p->buffer_in_write_ind = 0; |
} else { |
uart_data_p->buffer_in_write_ind++; |
} |
|
// Store the last MAXUARTBUF values entered |
if (uart_data_p->buffer_in_len_tmp < MAXUARTBUF) { |
uart_data_p->buffer_in_len_tmp++; |
} else { |
if (uart_data_p->buffer_in_read_ind == MAXUARTBUF - 1) { |
uart_data_p->buffer_in_read_ind = 0; |
} else { |
uart_data_p->buffer_in_read_ind++; |
} |
} |
|
// Update buffer size upon receiving newline (0x0D) |
if (c == UART_BREAK_CHAR) { |
uart_data_p->buffer_in_len = uart_data_p->buffer_in_len_tmp; |
uart_data_p->buffer_in_len_tmp = 0; |
} |
} |
|
if (RCSTAbits.OERR == 1) { |
// We've overrun the USART and must reset |
TXSTAbits.TXEN = 0; // Kill anything currently sending |
RCSTAbits.CREN = 0; // Reset UART1 |
RCSTAbits.CREN = 1; |
} |
} |
|
char UART_Buffer_Len() { |
return uart_data_p->buffer_in_len; |
} |
|
/* Reader interface to the UART buffer, returns the number of bytes read */ |
char UART_Read_Buffer(char *buffer) { |
char i = 0; |
while (uart_data_p->buffer_in_len != 0) { |
buffer[i] = uart_data_p->buffer_in[uart_data_p->buffer_in_read_ind]; |
i++; |
if (uart_data_p->buffer_in_read_ind == MAXUARTBUF - 1) { |
uart_data_p->buffer_in_read_ind = 0; |
} else { |
uart_data_p->buffer_in_read_ind++; |
} |
uart_data_p->buffer_in_len--; |
} |
return i; |
} |
#endif |