Subversion Repositories Code-Repo

Rev

Blame | Last modification | View Log | RSS feed

#include "DEFINES.h"
#include "EUSART.h"
#include "INTERRUPTS.h"

static volatile uint8_t txBuffer[UART_TX_BUFFER_SIZE];
static volatile uint8_t txBufferSize = 0;
static volatile uint8_t txBufferIndex = 0;

static volatile uint8_t rxBuffer[UART_RX_BUFFER_SIZE];
static volatile uint8_t rxBufferSize = 0;
static volatile uint8_t rxBufferIndex = 0;

void UART_Init() {
    UART_TX_TRIS = 0;
    UART_RX_TRIS = 1;

    BAUDCONbits.BRG16 = 0;      // 8-bit baud rate generation
    SPBRG = 64;                 // Baud rate of 19.2k
    TXSTAbits.BRGH = 1;         // High speed mode

    TXSTAbits.SYNC = 0;         // Async mode
    RCSTAbits.SPEN = 1;         // Serial port enable

    TXSTAbits.TX9 = 0;          // 8 bit transmission
    RCSTAbits.RX9 = 0;          // 8 bit reception

    TXSTAbits.TXEN = 1;         // Transmission enabled
    RCSTAbits.CREN = 1;         // Reception enabled

    PIE1bits.TXIE = 0;          // TX interrupt starts disabled
    PIE1bits.RCIE = 1;          // RX interrupt starts enabled
}

void UART_Write(uint8_t *msg, uint8_t length) {
    // Check to make sure there is enough space in buffer for message
    length = (length > UART_TX_BUFFER_SIZE) ? UART_TX_BUFFER_SIZE : length;
    
    // Wait for previous message to finish sending
    while (PIE1bits.TXIE);

    txBufferSize = length;
    txBufferIndex = 1;
    for (uint8_t i = 0; i < length; i++) {
        txBuffer[i] = msg[i];
    }
    TXREG = txBuffer[0];
    PIE1bits.TXIE = 1;
}

void UART_TX_Interrupt_Handler() {
    if (txBufferIndex != txBufferSize) {
        // Transmit next byte in the buffer
        TXREG = txBuffer[txBufferIndex];
        txBufferIndex++;
    } else {
        // Wait for last byte to finish sending
        while (!TXSTAbits.TRMT);
        PIE1bits.TXIE = 0;
        txBufferSize = 0;
        txBufferIndex = 0;
    }
}

void UART_RX_Interrupt_Handler() {
    if (PIR1bits.RCIF) {
        uint8_t c = RCREG;

        // Store received byte into buffer and increment write location
        rxBuffer[rxBufferIndex] = c;
        if (rxBufferIndex == UART_RX_BUFFER_SIZE - 1) {
            rxBufferIndex = 0;
        } else {
            rxBufferIndex++;
        }

        // Increment received byte count
        if (rxBufferSize < UART_RX_BUFFER_SIZE) {
            rxBufferSize++;
        }
    }

    // If UART overrun is detected, reset module
    if (RCSTAbits.OERR) {
        TXSTAbits.TXEN = 0;
        RCSTAbits.CREN = 0;
        RCSTAbits.CREN = 1;
    }
}

uint8_t UART_Read(uint8_t *buffer) {
    // Return values in RX buffer
    uint8_t size = rxBufferSize;
    for (uint8_t i = 0; i < size; i++) {
        buffer[i] = rxBuffer[i];
    }

    return size;
}

void UART_Reset_RX() {
    rxBufferIndex = 0;
    rxBufferSize = 0;
}