Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
329 Kevin 1
#include <xc.h>
2
#include "defines.h"
3
#include "UART.h"
4
 
5
static UART_DATA *data_ptr;
6
 
7
void UART_Init(UART_DATA *data) {
8
    data_ptr = data;
9
 
10
    APFCON0bits.RXDTSEL = 1;    // Change RX from RB5 to RC5
11
    APFCON0bits.TXCKSEL = 1;    // Change TX from RB7 to RC4
12
    UART_RX_TRIS = 1;
13
    UART_TX_TRIS = 0;
14
 
15
    SPBRG = 16;                 // Set baud rate to 115200 @ 32MHz
16
    BAUDCONbits.BRG16 = 0;      // 8-bit baud rate generator
17
    TXSTAbits.BRGH = 1;         // High baud rate select
18
 
19
    TXSTAbits.SYNC = 0;         // Async operation
20
    RCSTAbits.CREN = 1;         // Enable reception module
21
    TXSTAbits.TXEN = 1;         // Enable transmission module
22
    RCSTAbits.SPEN = 1;         // Enable EUSART module
23
 
24
    PIE1bits.RCIE = 1;          // UART RX interrupt starts enabled
25
    PIE1bits.TXIE = 0;          // UART TX interrupt starts disabled
26
 
27
    // Initialize local variables
28
    data_ptr->buffer_in_read_ind = 0;
29
    data_ptr->buffer_in_write_ind = 0;
30
    data_ptr->buffer_in_len = 0;
31
    data_ptr->buffer_out_ind = 0;
32
    data_ptr->buffer_out_len = 0;
33
}
34
 
35
void UART_TX_Interrupt_Handler(void) {
36
    // Send more data when transmit buffer is empty
37
    if (data_ptr->buffer_out_ind != data_ptr->buffer_out_len) {
38
        TXREG = data_ptr->buffer_out[data_ptr->buffer_out_ind];
39
        data_ptr->buffer_out_ind++;
40
    } else {
41
        // Stop processing TX interrupts if there is no more data to send
42
        while (!TXSTAbits.TRMT);
43
        PIE1bits.TXIE = 0;
44
        data_ptr->buffer_out_ind = 0;
45
        data_ptr->buffer_out_len = 0;
46
    }
47
}
48
 
49
void UART_RX_Interrupt_Handler(void) {
50
    char c = RCREG;
51
 
52
    // Read received data into buffer
53
    data_ptr->buffer_in[data_ptr->buffer_in_write_ind] = c;
54
    if (data_ptr->buffer_in_write_ind == UART_BUFFER_SIZE - 1) {
55
        data_ptr->buffer_in_write_ind = 0;
56
    } else {
57
        data_ptr->buffer_in_write_ind++;
58
    }
59
 
60
    // Increment read counter to keep only the latest data
61
    if (data_ptr->buffer_in_len < UART_BUFFER_SIZE) {
62
        data_ptr->buffer_in_len++;
63
    } else {
64
        if (data_ptr->buffer_in_read_ind == UART_BUFFER_SIZE - 1) {
65
            data_ptr->buffer_in_read_ind = 0;
66
        } else {
67
            data_ptr->buffer_in_read_ind++;
68
        }
69
    }
70
 
71
    // Reset receiver module on overrun error
72
    if (RCSTAbits.OERR == 1) {
73
        RCSTAbits.CREN = 0;
74
        RCSTAbits.CREN = 1;
75
    }
76
}
77
 
78
void UART_Write(char *data, char length) {
79
    // Ensure that no transmission is currently running
80
    while (PIE1bits.TXIE);
81
 
82
    data_ptr->buffer_out_len = length;
83
    data_ptr->buffer_out_ind = 0;
84
    for (char i = 0; i < length; i++) {
85
        data_ptr->buffer_out[i] = data[i];
86
    }
87
 
88
    // Start transmission
89
    PIE1bits.TXIE = 1;
90
}
91
 
92
char UART_Read(char *buffer) {
93
    PIE1bits.RCIE = 0; // Disable receiver interrupt
94
    char length = data_ptr->buffer_in_len;
95
    for (char i = 0; i < length; i++) {
96
        buffer[i] = data_ptr->buffer_in[data_ptr->buffer_in_read_ind];
97
        if (data_ptr->buffer_in_read_ind == UART_BUFFER_SIZE - 1) {
98
            data_ptr->buffer_in_read_ind = 0;
99
        } else {
100
            data_ptr->buffer_in_read_ind++;
101
        }
102
    }
103
    data_ptr->buffer_in_len -= length;
104
    PIE1bits.RCIE = 1; // Re-enable receiver interrupt
105
    return length;
106
}