Subversion Repositories Code-Repo

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
212 Kevin 1
#include <xc.h>
2
#include <plib.h>
3
#include "defines.h"
4
#include "UART1.h"
5
 
6
static UART1_DATA *uart_data_ptr;
7
 
215 Kevin 8
/* Note: BRGH values are different from PIC18!
9
 *
10
 * Baud Rate Calculation (BRGH = 0):
11
 * Baud Rate = PerfBusFreq / (16 * (BRG + 1))
12
 * BRG = PerfBusFreq / (16 * Baud Rate) - 1
13
 *
14
 * Baud Rate Calculation (BRGH = 1):
15
 * Baud Rate = PerfBusFreq / (4 * (BRG + 1))
16
 * BRG = PerfBusFreq / (4 * Baud Rate) - 1
17
 */
18
 
212 Kevin 19
void UART1_Init(UART1_DATA *data, void (*rx_callback)(char)) {
20
    uart_data_ptr = data;
21
    uart_data_ptr->rx_callback = rx_callback;
22
    uart_data_ptr->buffer_out_len = 0;
23
    uart_data_ptr->buffer_out_ind = 0;
24
 
25
    INTDisableInterrupts();
26
 
27
    IEC0CLR   = 0x1C000000; // Disable all UART1 interrupts
28
    IFS0CLR   = 0x1C000000; // Clear any existing events
29
    IPC6SET   = 0x00000009; // Set Priority = 2, Subpriority = 1
30
 
31
    U1MODE    = 0x00008000; // UART enabled, BRGH = 0
32
    U1STA     = 0x00009400; // TX interrupt on buffer empty, RX interrupt on buffer not empty
215 Kevin 33
    U1BRG     = 42;         // Set baud rate to 115200 @ 80MHz
212 Kevin 34
    IEC0SET   = 0x0C000000; // Enable the RX and Error interrupts
35
 
36
    INTEnableInterrupts();
37
 
38
    TRISDbits.TRISD14 = 0;
39
    PORTDbits.RD14 = 0;
40
}
41
 
42
int UART1_Write(char *string, int length) {
43
    if (length > UART1_BUFFER_SIZE)
44
        return 0;
45
    if (uart_data_ptr->buffer_out_len != 0)
46
        return 0;
47
 
48
    // Put the data to send into the outbound buffer
49
    uart_data_ptr->buffer_out_len = length;
50
    uart_data_ptr->buffer_out_ind = 0;
51
    int i;
52
    for (i = 0; i < length; i++) {
53
        uart_data_ptr->buffer_out[i] = string[i];
54
    }
55
    IEC0SET = 0x10000000; // Enable TX interrupt
56
    return 1;
57
}
58
 
59
void __ISR(_UART_1_VECTOR, ipl2) __UART_1_Interrupt_Handler(void) {
60
    PORTDbits.RD14 = 1;
61
    // Process UART1 error flag
62
    if (IFS0bits.U1EIF) {
63
        if (U1STAbits.PERR) { // Process parity error
64
 
65
        }
66
        if (U1STAbits.FERR) { // Process frame error
67
 
68
        }
69
        if (U1STAbits.OERR) { // Process receive buffer overrun error
70
            U1STAbits.OERR = 0; // Clear the overrun error if set
71
        }
72
        IFS0CLR = 0x04000000; // Clear the error flag
73
    }
74
 
75
    // Process UART1 recieve flag
76
    if (IFS0bits.U1RXIF) {
77
        // Read the data received from the last transfer
78
        while (U1STAbits.URXDA) {
79
            char c = U1RXREG;
80
            // Call the RX callback function on each received data
81
            if (uart_data_ptr->rx_callback != NULL) {
82
                (*uart_data_ptr->rx_callback)(c);
83
            }
84
        }
85
        IFS0CLR = 0x08000000; // Clear the recieve flag
86
    }
87
 
88
    // Process UART1 transmit flag
215 Kevin 89
    if (IFS0bits.U1TXIF && IEC0bits.U1TXIE) {
212 Kevin 90
        // Disable the transmit interrupt if all data has been sent
91
        if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len) {
92
            IEC0CLR = 0x10000000;
93
            uart_data_ptr->buffer_out_len = 0;
94
        } else {
95
            // Start filling the transmit buffer
96
            while (!U1STAbits.UTXBF) {
97
                U1TXREG = uart_data_ptr->buffer_out[uart_data_ptr->buffer_out_ind];
98
                uart_data_ptr->buffer_out_ind++;
99
                if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len)
100
                    break;
101
            }
102
        }
103
        IFS0CLR = 0x10000000; // Clear the transmit flag
104
    }
105
    PORTDbits.RD14 = 0;
106
}