105 lines
3.9 KiB
C
105 lines
3.9 KiB
C
#include "uart.h"
|
|
#include "stdint.h"
|
|
|
|
#define XUARTPS_CR_TXRST 0x00000002U /**< TX logic reset */
|
|
#define XUARTPS_CR_RXRST 0x00000001U /**< RX logic reset */
|
|
|
|
#define XUARTPS_CR_OFFSET 0x0000U /**< Control Register [8:0] */
|
|
#define XUARTPS_MR_OFFSET 0x0004U /**< Mode Register [9:0] */
|
|
#define XUARTPS_BAUDGEN_OFFSET 0x0018U /**< Baud Rate Generator [15:0] */
|
|
#define XUARTPS_BAUDDIV_OFFSET 0x0034U /**< Baud Rate Divider [7:0] */
|
|
#define XUARTPS_FIFO_OFFSET 0x0030U /**< FIFO [7:0] */
|
|
#define XUARTPS_SR_OFFSET 0x002CU /**< Channel Status [14:0] */
|
|
#define XPS_UART1_BASEADDR 0xE0001000U
|
|
|
|
#define XUARTPS_MR_CHMODE_NORM 0x00000000U /**< Normal mode */
|
|
#define XUARTPS_MR_STOPMODE_1_BIT 0x00000000U /**< 1 stop bit */
|
|
#define XUARTPS_MR_PARITY_NONE 0x00000020U /**< No parity mode */
|
|
#define XUARTPS_MR_CHARLEN_8_BIT 0x00000000U /**< 8 bits data */
|
|
#define XUARTPS_MR_CLKSEL 0x00000001U /**< Input clock selection */
|
|
|
|
#define XUARTPS_SR_TNFUL 0x00004000U /**< TX FIFO Nearly Full Status */
|
|
#define XUARTPS_SR_TACTIVE 0x00000800U /**< TX active */
|
|
#define XUARTPS_SR_RXEMPTY 0x00000002U /**< RX FIFO empty */
|
|
|
|
#define XUARTPS_CR_TX_DIS 0x00000020U /**< TX disabled. */
|
|
#define XUARTPS_CR_TX_EN 0x00000010U /**< TX enabled */
|
|
#define XUARTPS_CR_RX_DIS 0x00000008U /**< RX disabled. */
|
|
#define XUARTPS_CR_RX_EN 0x00000004U /**< RX enabled */
|
|
|
|
#define POINTER_TO_REGISTER(REG) ( *((volatile uint32_t*)(REG)))
|
|
|
|
#define UART_BASE XPS_UART1_BASEADDR
|
|
#define UART_CTRL POINTER_TO_REGISTER(UART_BASE + XUARTPS_CR_OFFSET) // Control Register
|
|
#define UART_MODE POINTER_TO_REGISTER(UART_BASE + XUARTPS_MR_OFFSET) // Mode Register
|
|
|
|
#define UART_BAUD_GEN POINTER_TO_REGISTER(UART_BASE + XUARTPS_BAUDGEN_OFFSET) // Baud Rate Generator "CD"
|
|
#define UART_BAUD_DIV POINTER_TO_REGISTER(UART_BASE + XUARTPS_BAUDDIV_OFFSET) // Baud Rate Divider "BDIV"
|
|
#define UART_FIFO POINTER_TO_REGISTER(UART_BASE + XUARTPS_FIFO_OFFSET) // FIFO
|
|
#define UART_STATUS POINTER_TO_REGISTER(UART_BASE + XUARTPS_SR_OFFSET) // Channel Status
|
|
|
|
#define BUFLEN 127
|
|
|
|
static uint16_t end_ndx;
|
|
static char buf[BUFLEN+1];
|
|
#define buf_len ((end_ndx - start_ndx) % BUFLEN)
|
|
static inline int inc_ndx(int n) { return ((n + 1) % BUFLEN); }
|
|
static inline int dec_ndx(int n) { return (((n + BUFLEN) - 1) % BUFLEN); }
|
|
|
|
void uart_send(char c) {
|
|
while (UART_STATUS & XUARTPS_SR_TNFUL);
|
|
UART_FIFO = c;
|
|
while (UART_STATUS & XUARTPS_SR_TACTIVE);
|
|
}
|
|
|
|
char uart_recv() {
|
|
if ((UART_STATUS & XUARTPS_SR_RXEMPTY) == XUARTPS_SR_RXEMPTY)
|
|
return 0;
|
|
|
|
return UART_FIFO;
|
|
}
|
|
|
|
char uart_recv_blocking() {
|
|
while ((UART_STATUS & XUARTPS_SR_RXEMPTY) == XUARTPS_SR_RXEMPTY);
|
|
return UART_FIFO;
|
|
}
|
|
|
|
void uart_setup(void) {
|
|
uint32_t r = 0; // Temporary value variable
|
|
r = UART_CTRL;
|
|
r &= ~(XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN); // Clear Tx & Rx Enable
|
|
r |= XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS; // Tx & Rx Disable
|
|
UART_CTRL = r;
|
|
|
|
UART_MODE = 0;
|
|
UART_MODE &= ~XUARTPS_MR_CLKSEL; // Clear "Input clock selection" - 0: clock source is uart_ref_clk
|
|
UART_MODE |= XUARTPS_MR_CHARLEN_8_BIT; // Set "8 bits data"
|
|
UART_MODE |= XUARTPS_MR_PARITY_NONE; // Set "No parity mode"
|
|
UART_MODE |= XUARTPS_MR_STOPMODE_1_BIT; // Set "1 stop bit"
|
|
UART_MODE |= XUARTPS_MR_CHMODE_NORM; // Set "Normal mode"
|
|
|
|
// baud_rate = sel_clk / (CD * (BDIV + 1) (ref: UG585 - TRM - Ch. 19 UART)
|
|
UART_BAUD_DIV = 6; // ("BDIV")
|
|
UART_BAUD_GEN = 124; // ("CD")
|
|
// Baud Rate = 100Mhz / (124 * (6 + 1)) = 115200 bps
|
|
|
|
UART_CTRL |= (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST); // TX & RX logic reset
|
|
|
|
r = UART_CTRL;
|
|
r |= XUARTPS_CR_RX_EN | XUARTPS_CR_TX_EN; // Set TX & RX enabled
|
|
r &= ~(XUARTPS_CR_RX_DIS | XUARTPS_CR_TX_DIS); // Clear TX & RX disabled
|
|
UART_CTRL = r;
|
|
}
|
|
|
|
void uart_back_up(void){
|
|
end_ndx = dec_ndx(end_ndx);
|
|
uart_send('\010');
|
|
uart_send(' ');
|
|
uart_send('\010');
|
|
}
|
|
|
|
void uart_puts(char * s){
|
|
while(*s){
|
|
uart_send(*(s++));
|
|
}
|
|
} |