Files
remotesyn/examples/zynq7000/SW/src/uart.c
2022-09-08 13:29:11 +02:00

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++));
}
}