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