Subversion Repositories Code-Repo

Rev

Rev 147 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "defines.h"
#include "uart.h"
#include "xbee.h"
#include <string.h>
#include <stdio.h>

#pragma udata UART1_BUFFER
static UART_DATA uart_1_data;
#pragma udata
static UART_DATA *uart_1_data_p = &uart_1_data;

void UART1_Init() {
    // Configure the hardware USART device
    // UART1 TX RC6
    // UART1 RX RC7

    UART1_TX_TRIS = 0; // Tx pin set to output
    UART1_RX_TRIS = 1; // Rx pin set to input

    BAUDCON1bits.BRG16 = 0; // 8-bit baud rate generator
    SPBRG1 = 25; // Set UART speed to 115200 baud
    TXSTA1bits.BRGH = 1; // High speed mode
    TXSTA1bits.SYNC = 0; // Async mode
    RCSTA1bits.SPEN = 1; // Serial port enable
    TXSTA1bits.TX9 = 0; // 8 bit transmission
    RCSTA1bits.RX9 = 0; // 8 bit reception
    RCSTA1bits.CREN = 1; // Continuous receive mode

#ifdef _DEBUG // In debug mode we want to have TXEN constantly enabled
    TXSTA1bits.TXEN = 1; // TX is always enabled
    PIE1bits.TX1IE = 0; // Disable TX interrupt
#else
    TXSTA1bits.TXEN = 0; // Enable transmission
    PIE1bits.TX1IE = 1; // Enable TX interrupt
#endif

    PIE1bits.RC1IE = 1; // Enable RX interrupt

    // Initialize the buffer that holds UART messages
    uart_1_data_p->buffer_in_read_ind = 0;
    uart_1_data_p->buffer_in_write_ind = 0;
    uart_1_data_p->buffer_in_len = 0;
    uart_1_data_p->buffer_in_len_tmp = 0;
}

//void uart_2_init() {
//    // Configure the PPS USART ports
//
//    // UART2 RX Pin RP5
//    RPINR16 = PPS_UART2_RX;    // 5 is PPS RP5
//    // UART2 TX Pin RP6
//    PPS_UART2_TX = 6;  // 6 is TX2/CK2 (EUSART2 Asynchronous Transmit/Asynchronous Clock Output)
//
//    Open2USART(USART_TX_INT_OFF &   // Interrupt on TX off
//            USART_RX_INT_ON &      // Interrupt on RX on
//            USART_ASYNCH_MODE &     // Operate in async mode
//            USART_EIGHT_BIT &       // Operate in 8-bit mode
//            USART_CONT_RX &         // Continuously recieve messages
//            USART_BRGH_HIGH, 25);  // Set UART speed to 115200 baud
//}

void UART1_Recv_Interrupt_Handler() {
    unsigned char c;
    if (PIR1bits.RC1IF) { // Check if data receive flag is set
        c = RCREG1;
#ifdef UART1_RX_TO_BUFFER
        // Save received data into buffer
        uart_1_data_p->buffer_in[uart_1_data_p->buffer_in_write_ind] = c;
        if (uart_1_data_p->buffer_in_write_ind == MAXUARTBUF - 1) {
            uart_1_data_p->buffer_in_write_ind = 0;
        } else {
            uart_1_data_p->buffer_in_write_ind++;
        }

        // Store the last MAXUARTBUF values entered
        if (uart_1_data_p->buffer_in_len_tmp < MAXUARTBUF) {
            uart_1_data_p->buffer_in_len_tmp++;
        } else {
            if (uart_1_data_p->buffer_in_read_ind == MAXUARTBUF - 1) {
                uart_1_data_p->buffer_in_read_ind = 0;
            } else {
                uart_1_data_p->buffer_in_read_ind++;
            }
        }

        // Update buffer size upon receiving newline (0x0D)
        if (c == UART1_BREAK_CHAR) {
            uart_1_data_p->buffer_in_len = uart_1_data_p->buffer_in_len_tmp;
            uart_1_data_p->buffer_in_len_tmp = 0;
        }
#endif
#ifdef UART1_RX_TO_XBEE
        XBee_Serial_In(c);
#endif
    }

    if (RCSTA1bits.OERR == 1) {
        // We've overrun the USART and must reset
        RCSTA1bits.CREN = 0; // Reset UART1
        RCSTA1bits.CREN = 1;
        DBG_PRINT_UART("UART1: (ERROR) overrun\r\n");
        TXSTA1bits.TXEN = 0; // Kill anything currently sending
    }
}

//void uart_2_recv_interrupt_handler() {
//    if (DataRdy2USART()) {
////        xbee_read_serial(Read2USART());
//    }
//
//    if (USART2_Status.OVERRUN_ERROR == 1) {
//        // We've overrun the USART and must reset
//        RCSTA2bits.CREN = 0;    // Reset UART2
//        RCSTA2bits.CREN = 1;
//    }
//}

void UART1_Send_Interrupt_Handler() {
    // Put remaining data in TSR for transmit
    if (uart_1_data_p->buffer_out_ind != uart_1_data_p->buffer_out_len) {
        TXREG1 = uart_1_data_p->buffer_out[uart_1_data_p->buffer_out_ind];
        uart_1_data_p->buffer_out_ind++;
    } else {
        while (!TXSTA1bits.TRMT); // Wait for last byte to finish sending
        TXSTA1bits.TXEN = 0; // End transmission and disable TX interrupt
        uart_1_data_p->buffer_out_ind = 0;
        uart_1_data_p->buffer_out_len = 0;
    }
}

void UART1_WriteS(const rom char *fmt, ...) {
#ifdef _DEBUG
    unsigned char i;
    va_list args;
    va_start(args, fmt);
    vsprintf((char *) uart_1_data_p->buffer_out, fmt, args);
    va_end(args);
    uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
    uart_1_data_p->buffer_out_ind = 1;
    for (i = 0; i < uart_1_data_p->buffer_out_len; i++) {
        TXREG1 = uart_1_data_p->buffer_out[i];
        Nop();
        while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
    }
#else
    va_list args;
    while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
    va_start(args, fmt);
    vsprintf((char *) uart_1_data_p->buffer_out, fmt, args);
    va_end(args);
    uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
    uart_1_data_p->buffer_out_ind = 1;
    TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
    TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}

void UART1_WriteF(float f, unsigned char m) {
    long whole = 0;
    unsigned long decimal = 0;
    unsigned int multiplier = 1;
    unsigned char i;

    for (i = 0; i < m; i++)
        multiplier *= 10;

    whole = (long)((float)f);
    decimal = (long)((float)f*multiplier) - whole*multiplier;
    // Round up if necessary
    if ((long)((float)f*multiplier*10) % 10 >= 5)
        decimal += 1;
#ifdef _DEBUG
    sprintf((char *) uart_1_data_p->buffer_out, "%ld.%ld", whole, decimal);
    uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
    uart_1_data_p->buffer_out_ind = 1;
    for (i = 0; i < uart_1_data_p->buffer_out_len; i++) {
        TXREG1 = uart_1_data_p->buffer_out[i];
        Nop();
        while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
    }
#else
    while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
    sprintf((char *) uart_1_data_p->buffer_out, "%ld.%ld", whole, decimal);
    uart_1_data_p->buffer_out_len = strlen((char *) uart_1_data_p->buffer_out);
    uart_1_data_p->buffer_out_ind = 1;
    TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
    TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}

void UART1_WriteB(const char *msg, unsigned char length) {
    unsigned char i;
#ifdef _DEBUG
    for (i = 0; i < length; i++) {
        TXREG1 = msg[i];
        Nop();
        while (!PIR1bits.TX1IF); // Wait for byte to be transmitted
    }
#else
    while (TXSTA1bits.TXEN); // Wait for previous message to finish sending
    uart_1_data_p->buffer_out_len = length;
    uart_1_data_p->buffer_out_ind = 1;
    for (i = 0; i < length; i++) {
        uart_1_data_p->buffer_out[i] = msg[i];
    }
    TXREG1 = uart_1_data_p->buffer_out[0]; // Put first byte in TSR
    TXSTA1bits.TXEN = 1; // Begin transmission
#endif
}

void UART1_WriteC(const unsigned char c) {
#ifdef _DEBUG
    TXREG1 = c;
    Nop();
    while (!PIR1bits.TX1IF);
#else
    while (TXSTA1bits.TXEN);
    uart_1_data_p->buffer_out_len = 1;
    uart_1_data_p->buffer_out_ind = 1;
    TXREG1 = c;
    TXSTA1bits.TXEN = 1;
#endif

}

unsigned char UART1_Buffer_Len() {
    return uart_1_data_p->buffer_in_len;
}

/* Reader interface to the UART buffer, returns the number of bytes read */
unsigned char UART1_Read_Buffer(unsigned char *buffer) {
    unsigned char i = 0;
    while (uart_1_data_p->buffer_in_len != 0) {
        buffer[i] = uart_1_data_p->buffer_in[uart_1_data_p->buffer_in_read_ind];
        i++;
        if (uart_1_data_p->buffer_in_read_ind == MAXUARTBUF - 1) {
            uart_1_data_p->buffer_in_read_ind = 0;
        } else {
            uart_1_data_p->buffer_in_read_ind++;
        }
        uart_1_data_p->buffer_in_len--;
    }
    return i;
}