0,0 → 1,105 |
#include "defines.h" |
#include "UART1.h" |
|
static UART1_DATA *uart_data_ptr; |
|
/* Note: BRGH values are different from PIC18! |
* |
* Baud Rate Calculation (BRGH = 0): |
* Baud Rate = PerfBusFreq / (16 * (BRG + 1)) |
* BRG = PerfBusFreq / (16 * Baud Rate) - 1 |
* |
* Baud Rate Calculation (BRGH = 1): |
* Baud Rate = PerfBusFreq / (4 * (BRG + 1)) |
* BRG = PerfBusFreq / (4 * Baud Rate) - 1 |
*/ |
|
void UART1_Init(UART1_DATA *data, void (*rx_callback)(uint8_t)) { |
uart_data_ptr = data; |
uart_data_ptr->rx_callback = rx_callback; |
uart_data_ptr->buffer_out_len = 0; |
uart_data_ptr->buffer_out_ind = 0; |
|
INTDisableInterrupts(); |
|
IEC0CLR = 0x1C000000; // Disable all UART1 interrupts |
IFS0CLR = 0x1C000000; // Clear any existing events |
IPC6SET = 0x00000009; // Set Priority = 2, Subpriority = 1 |
|
U1MODE = 0x00008008; // UART enabled, BRGH = 1 |
U1STA = 0x00009400; // TX interrupt on buffer empty, RX interrupt on buffer not empty |
|
// U1BRG = 173; // Set baud rate to 115200 @ 80MHz (0.22% error) |
U1BRG = 86; // Set baud rate to 230400 @ 80MHz (0.22% error) |
// U1BRG = 77; // Set baud rate to 256000 @ 80MHz (0.12% error) |
// U1BRG = 42; // Set baud rate to 460800 @ 80MHz (0.94% error) |
// U1BRG = 21; // Set baud rate to 921600 @ 80MHz (1.36% error) |
|
IEC0SET = 0x0C000000; // Enable the RX and Error interrupts |
|
INTEnableInterrupts(); |
} |
|
uint8_t UART1_Write(uint8_t *string, uint32_t length) { |
if (length > UART1_BUFFER_SIZE) |
return 0; |
if (uart_data_ptr->buffer_out_len != 0) |
return 0; |
|
// Put the data to send into the outbound buffer |
uart_data_ptr->buffer_out_len = length; |
uart_data_ptr->buffer_out_ind = 0; |
uint8_t i; |
for (i = 0; i < length; i++) { |
uart_data_ptr->buffer_out[i] = string[i]; |
} |
IEC0SET = 0x10000000; // Enable TX interrupt |
return 1; |
} |
|
void __ISR(_UART_1_VECTOR, ipl2) __UART_1_Interrupt_Handler(void) { |
// Process UART1 error flag |
if (IFS0bits.U1EIF) { |
if (U1STAbits.PERR) { // Process parity error |
|
} |
if (U1STAbits.FERR) { // Process frame error |
|
} |
if (U1STAbits.OERR) { // Process receive buffer overrun error |
U1STAbits.OERR = 0; // Clear the overrun error if set |
} |
IFS0CLR = 0x04000000; // Clear the error flag |
} |
|
// Process UART1 recieve flag |
if (IFS0bits.U1RXIF) { |
// Read the data received from the last transfer |
while (U1STAbits.URXDA) { |
uint8_t c = U1RXREG; |
// Call the RX callback function on each received data |
if (uart_data_ptr->rx_callback != NULL) { |
(*uart_data_ptr->rx_callback)(c); |
} |
} |
IFS0CLR = 0x08000000; // Clear the recieve flag |
} |
|
// Process UART1 transmit flag |
if (IFS0bits.U1TXIF && IEC0bits.U1TXIE) { |
// Disable the transmit interrupt if all data has been sent |
if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len) { |
IEC0CLR = 0x10000000; |
uart_data_ptr->buffer_out_len = 0; |
} else { |
// Start filling the transmit buffer |
while (!U1STAbits.UTXBF) { |
U1TXREG = uart_data_ptr->buffer_out[uart_data_ptr->buffer_out_ind]; |
uart_data_ptr->buffer_out_ind++; |
if (uart_data_ptr->buffer_out_ind == uart_data_ptr->buffer_out_len) |
break; |
} |
} |
IFS0CLR = 0x10000000; // Clear the transmit flag |
} |
} |