Added test firmware for zynq

Signed-off-by: Joppe Blondel <joppe@blondel.nl>
This commit is contained in:
2022-09-08 13:29:11 +02:00
parent 379bf1f689
commit 7c5351b9c3
11 changed files with 872 additions and 0 deletions

2
examples/zynq7000/SW/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build
DISASS

View File

@ -0,0 +1,67 @@
.SILENT:
TARGET := app.elf
BUILDDIR := build
SRCDIRS := src
SRCFILESC := $(shell find $(SRCDIRS) -type f -name "*.c")
OBJFILESC := $(SRCFILESC:%.c=$(BUILDDIR)/%.c.o) $(BUILDDIR)/src/ps7_init.o
DEPFILESC := $(SRCFILESC:%.c=$(BUILDDIR)/%.c.d)
SRCFILESA := $(shell find $(SRCDIRS) -type f -name "*.S")
OBJFILESA := $(SRCFILESA:%.S=$(BUILDDIR)/%.S.o)
DEPFILESA := $(SRCFILESA:%.S=$(BUILDDIR)/%.S.d)
SRCFILES := $(SRCFILESC) $(SRCFILESA)
OBJFILES := $(OBJFILESA) $(OBJFILESC)
DEPFILES := $(DEPFILESC) $(DEPFILESA)
FILESTOCLEAN := $(OBJFILES) $(DEPFILES) $(BUILDDIR)/$(TARGET)
CROSS_COMPILE ?= arm-none-eabi-
CC := $(CROSS_COMPILE)gcc
AS := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)gcc
CC_WARNING := -Wall -Wextra
CC_LIBS := -lgcc
CC_FLAGS := -nostdlib -fno-builtin -g -mcpu=cortex-a9
CC_INCLUDES := -I src -I ../OUT/ip/zynqps
LD_FLAGS := -Wl,-Tlinker.ld
.PHONY: $(TARGET) all clean
all: $(TARGET)
# PHONY RULES
# -----------
$(TARGET): $(BUILDDIR)/$(TARGET)
clean:
echo CLEAN FILES FOR $(TARGET)
-rm -r $(FILESTOCLEAN)
# SPECIFIC BUILD RULES
# --------------------
$(BUILDDIR)/$(TARGET): $(OBJFILES)
echo 'LD ' $@
$(LD) $(CC_FLAGS) $(LD_FLAGS) -o $(BUILDDIR)/$(TARGET) $(OBJFILES) $(CC_LIBS)
$(XILINX_BASE)/bin/$(CROSS_COMPILE)objdump -D $(BUILDDIR)/$(TARGET) > DISASS
$(BUILDDIR)/src/ps7_init.o : ../OUT/ip/zynqps/ps7_init.c ../OUT/ip/zynqps/ps7_init.h
echo 'CC ' $@
-mkdir -p $(shell dirname $@)
$(CC) $(CC_FLAGS) $(CC_WARNING) $(CC_INCLUDES) -MD -o $(BUILDDIR)/src/ps7_init.o -c ../OUT/ip/zynqps/ps7_init.c
$(OBJFILES): $(BUILDDIR)/%.c.o: %.c
echo 'CC ' $@
-mkdir -p $(shell dirname $@)
$(CC) $(CC_FLAGS) $(CC_WARNING) $(CC_INCLUDES) -MD -o $@ -c $<
$(OBJFILESA): $(BUILDDIR)/%.S.o: %.S
echo 'AS ' $@
-mkdir -p $(shell dirname $@)
$(CC) $(CC_FLAGS) $(CC_WARNING) $(CC_INCLUDES) -MD -o $@ -c $<
# Add DEPFILE dependencies
-include $(DEPFILES)

View File

@ -0,0 +1,89 @@
OUTPUT_FORMAT ("elf32-littlearm")
MEMORY
{
SRAM_0 : ORIGIN = 0x00000000, LENGTH = 0x00030000 /* 192k */
SRAM_1 : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000 /* 64k */
DDR_PS : ORIGIN = 0x00100000, LENGTH = 0x0FF00000 /* 256M */
}
EXTERN(__stack_size);
ASSERT(__stack_size, "Must provide a non-zero stack size");
EXTERN(_start);
SECTIONS
{
.text :
{
__stext = .;
*(.vectortable) /* Vector table */
*(.text .text.*) /* Standard Code */
*(.rodata .rodata.*) /* Constants, strings, ... */
*(.glue_7) /* Glue ARM to thumb code */
*(.glue_7t) /* Glue thumb to ARM code */
__etext = .;
} >DDR_PS
.data :
{
. = ALIGN(4);
__sdata = .;
*(.data .data.*)
__edata = .;
} >DDR_PS
.bss (NOLOAD) :
{
. = ALIGN(4);
__bss_start__ = .; /* Used for zeroing bss on startup */
*(.bss .bss.*)
__bss_end__ = .;
} >DDR_PS
. = ALIGN(4);
end = .;
/* Place all stacks in SRAM_1 - need to avoid filling addresses */
/* 0xfffffe00 to 0xfffffff0 - proc1 is halted running code in this range */
/* TODO: assert stacks do not step on proc1's code out of reset */
.stack (NOLOAD) :
{
. += __stack_size;
__proc0_irq_stack = .;
. += __stack_size;
__proc0_fiq_stack = .;
. += __stack_size;
__proc0_svc_stack = .;
. += __stack_size;
__proc0_abt_stack = .;
. += __stack_size;
__proc0_und_stack = .;
. += __stack_size;
__proc0_sys_stack = .;
. += __stack_size;
__proc1_irq_stack = .;
. += __stack_size;
__proc1_fiq_stack = .;
. += __stack_size;
__proc1_svc_stack = .;
. += __stack_size;
__proc1_abt_stack = .;
. += __stack_size;
__proc1_und_stack = .;
. += __stack_size;
__proc1_sys_stack = .;
. += __stack_size;
} >SRAM_1
.data.ddr :
{
*(.data_in_ddr)
} >DDR_PS
.note.gnu.build-id : {
KEEP (*(.note.gnu.build-id))
} >DDR_PS
}

View File

@ -0,0 +1,87 @@
.syntax unified /* Use the unified instruction syntax */
.arm /* Assemble ARM instruction set, not thumb */
.equ PROC1_RESET_VECTOR_TABLE, 0xFFFFFFF0
.equ CPSR_MODE_USER, 0x10
.equ CPSR_MODE_FIQ, 0x11
.equ CPSR_MODE_IRQ, 0x12
.equ CPSR_MODE_SVC, 0x13
.equ CPSR_MODE_ABORT, 0x17
.equ CPSR_MODE_UNDEFINED, 0x8B
.equ CPSR_MODE_SYSTEM, 0x1F
.equ CPSR_IRQ, 0x80 /* disable IRQ interrupts */
.equ CPSR_FIQ, 0x40 /* disable FIQ interrupts */
.global __stack_size
.equ __stack_size, 0x1000
// ------------------
.section .vectortable
// ------------------
.global vectortable
vectortable:
/* Exception Processor Mode Event Return Sequence */
b reset_handler /* MODE_SVC System Reset n/a */
b undef_handler /* MODE_UNDEFINED Undefined Instruction MOVS PC, LR (if emulating) */
b SVC_handler /* MODE_SVC SVC instruction MOVS PC, LR */
b prefetch_abort_handler /* MODE_ABORT Invalid inst. address SUBS PC, LR, #4 */
b data_abort_handler /* MODE_ABORT R/W to invalid address SUBS PC, LR, #8 (to retry) */
b hypervisor_handler /* MODE_HYP Hypervisor entry ERET */
b IRQ_handler /* MODE_IRQ IRQ Input Asserted SUBS PC, LR, #4 */
b FIQ_handler /* MODE_FIQ FIQ Input Asserted SUBS PC, LR, #4 */
reset_handler:
b _start
undef_handler:
b .
SVC_handler:
b .
prefetch_abort_handler:
b .
data_abort_handler:
b .
hypervisor_handler:
b .
IRQ_handler:
b .
FIQ_handler:
b .
// -----------
.section .text
// -----------
.global _start
_start:
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_IRQ) /* switch to MODE_IRQ */
ldr sp, =__proc0_irq_stack /* load IRQ mode stack pointer */
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_FIQ) /* switch to MODE_FIQ */
ldr sp, =__proc0_fiq_stack /* load FIQ mode stack pointer */
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_ABORT) /* switch to MODE_ABT */
ldr sp, =__proc0_abt_stack /* load ABT mode stack pointer */
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_UNDEFINED) /* switch to MODE_UND */
ldr sp, =__proc0_und_stack /* load UND mode stack pointer */
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_SYSTEM) /* switch to MODE_SYS */
ldr sp, =__proc0_sys_stack /* load SYS mode stack pointer */
msr CPSR, #(CPSR_IRQ | CPSR_FIQ | CPSR_MODE_SVC) /* switch to MODE_SVC */
ldr sp, =__proc0_svc_stack /* load SVC mode stack pointer */
/* We are now in SVC mode */
/* Set vector table base address */
ldr r0, =vectortable
mcr p15, #0, r0, c12, c0, #0
b main
_hang:
b _hang
.end

View File

@ -0,0 +1,15 @@
#include "ps7_init.h"
#include "zynq.h"
#include "uart.h"
#include "printf.h"
void main(){
cpu_disable_interrups();
// Initialize ZYNQ Processing System
ps7_init();
// Start UART
uart_setup();
printf("Hello World!\n");
}

View File

@ -0,0 +1,452 @@
#include "printf.h"
#include "uart.h"
#define NULL 0
extern int putchar(int c);
static void print_double_float(double val, unsigned int precision);
static void simple_outputchar(char **str, char c)
{
if (str) {
**str = c;
++(*str);
} else {
uart_send(c);
}
}
enum flags {
PAD_ZERO = 1,
PAD_RIGHT = 2,
};
static int prints(char **out, const char *string, int width, int flags)
{
int pc = 0, padchar = ' ';
if (width > 0) {
int len = 0;
const char *ptr;
for (ptr = string; *ptr; ++ptr) ++len;
if (len >= width) width = 0;
else width -= len;
if (flags & PAD_ZERO)
padchar = '0';
}
if (!(flags & PAD_RIGHT)) {
for ( ; width > 0; --width) {
simple_outputchar(out, padchar);
++pc;
}
}
for ( ; *string ; ++string) {
simple_outputchar(out, *string);
++pc;
}
for ( ; width > 0; --width) {
simple_outputchar(out, padchar);
++pc;
}
return pc;
}
#define PRINT_BUF_LEN 64
static int simple_outputi(char **out, long long i, int base, int sign, int width, int flags, int letbase)
{
char print_buf[PRINT_BUF_LEN];
char *s;
int t, neg = 0, pc = 0;
unsigned long long u = i;
if (i == 0) {
print_buf[0] = '0';
print_buf[1] = '\0';
return prints(out, print_buf, width, flags);
}
if (sign && base == 10 && i < 0) {
neg = 1;
u = -i;
}
s = print_buf + PRINT_BUF_LEN-1;
*s = '\0';
while (u) {
t = u % base;
if( t >= 10 )
t += letbase - '0' - 10;
*--s = t + '0';
u /= base;
}
if (neg) {
if( width && (flags & PAD_ZERO) ) {
simple_outputchar (out, '-');
++pc;
--width;
}
else {
*--s = '-';
}
}
return pc + prints (out, s, width, flags);
}
static int simple_vsprintf(char **out, char *format, va_list ap)
{
int width, flags;
int pc = 0;
char scr[2];
union {
char c;
char *s;
int i;
unsigned int u;
long li;
unsigned long lu;
long long lli;
unsigned long long llu;
short hi;
unsigned short hu;
signed char hhi;
unsigned char hhu;
void *p;
double d;
} u;
for (; *format != 0; ++format) {
if (*format == '%') {
++format;
width = flags = 0;
if (*format == '\0')
break;
if (*format == '%')
goto out;
if (*format == '-') {
++format;
flags = PAD_RIGHT;
}
while (*format == '0') {
++format;
flags |= PAD_ZERO;
}
if (*format == '*') {
width = va_arg(ap, int);
format++;
} else {
for ( ; *format >= '0' && *format <= '9'; ++format) {
width *= 10;
width += *format - '0';
}
}
switch (*format) {
case('d'):
u.i = va_arg(ap, int);
pc += simple_outputi(out, u.i, 10, 1, width, flags, 'a');
break;
case('u'):
u.u = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.u, 10, 0, width, flags, 'a');
break;
case('x'):
u.u = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.u, 16, 0, width, flags, 'a');
break;
case('X'):
u.u = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.u, 16, 0, width, flags, 'A');
break;
case('c'):
u.c = va_arg(ap, int);
scr[0] = u.c;
scr[1] = '\0';
pc += prints(out, scr, width, flags);
break;
case('f'):
u.d = va_arg(ap, double);
print_double_float(u.d, width);
break;
case('s'):
u.s = va_arg(ap, char *);
pc += prints(out, u.s ? u.s : "(null)", width, flags);
break;
case('l'):
++format;
switch (*format) {
case('d'):
u.li = va_arg(ap, long);
pc += simple_outputi(out, u.li, 10, 1, width, flags, 'a');
break;
case('u'):
u.lu = va_arg(ap, unsigned long);
pc += simple_outputi(out, u.lu, 10, 0, width, flags, 'a');
break;
case('x'):
u.lu = va_arg(ap, unsigned long);
pc += simple_outputi(out, u.lu, 16, 0, width, flags, 'a');
break;
case('X'):
u.lu = va_arg(ap, unsigned long);
pc += simple_outputi(out, u.lu, 16, 0, width, flags, 'A');
break;
case('l'):
++format;
switch (*format) {
case('d'):
u.lli = va_arg(ap, long long);
pc += simple_outputi(out, u.lli, 10, 1, width, flags, 'a');
break;
case('u'):
u.llu = va_arg(ap, unsigned long long);
pc += simple_outputi(out, u.llu, 10, 0, width, flags, 'a');
break;
case('x'):
u.llu = va_arg(ap, unsigned long long);
pc += simple_outputi(out, u.llu, 16, 0, width, flags, 'a');
break;
case('X'):
u.llu = va_arg(ap, unsigned long long);
pc += simple_outputi(out, u.llu, 16, 0, width, flags, 'A');
break;
default:
break;
}
break;
default:
break;
}
break;
case('h'):
++format;
switch (*format) {
case('d'):
u.hi = va_arg(ap, int);
pc += simple_outputi(out, u.hi, 10, 1, width, flags, 'a');
break;
case('u'):
u.hu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 10, 0, width, flags, 'a');
break;
case('x'):
u.hu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 16, 0, width, flags, 'a');
break;
case('X'):
u.hu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 16, 0, width, flags, 'A');
break;
case('h'):
++format;
switch (*format) {
case('d'):
u.hhi = va_arg(ap, int);
pc += simple_outputi(out, u.hhi, 10, 1, width, flags, 'a');
break;
case('u'):
u.hhu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 10, 0, width, flags, 'a');
break;
case('x'):
u.hhu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 16, 0, width, flags, 'a');
break;
case('X'):
u.hhu = va_arg(ap, unsigned int);
pc += simple_outputi(out, u.lli, 16, 0, width, flags, 'A');
break;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
}
}
else {
out:
simple_outputchar (out, *format);
++pc;
}
}
if (out) **out = '\0';
return pc;
}
int printf(char *fmt, ...)
{
va_list ap;
int r;
va_start(ap, fmt);
r = simple_vsprintf(NULL, fmt, ap);
va_end(ap);
return r;
}
int sprintf(char *buf, char *fmt, ...)
{
va_list ap;
int r;
va_start(ap, fmt);
r = simple_vsprintf(&buf, fmt, ap);
va_end(ap);
return r;
}
void hexDump (const char * desc, const void * addr, const int len) {
int i;
unsigned char buff[17];
const unsigned char * pc = (const unsigned char *)addr;
// Output description if given.
if (desc != NULL)
printf ("%s:\n", desc);
// Length checks.
if (len == 0) {
printf(" ZERO LENGTH\n");
return;
}
else if (len < 0) {
printf(" NEGATIVE LENGTH: %d\n", len);
return;
}
// Process every byte in the data.
for (i = 0; i < len; i++) {
// Multiple of 16 means new line (with line offset).
if ((i % 16) == 0) {
// Don't print ASCII buffer for the "zeroth" line.
if (i != 0)
printf (" %s\n", buff);
// Output the offset.
printf (" %04x ", i);
}
// Now the hex code for the specific character.
printf (" %02x", pc[i]);
// And buffer a printable ASCII character for later.
if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better.
buff[i % 16] = '.';
else
buff[i % 16] = pc[i];
buff[(i % 16) + 1] = '\0';
}
// Pad out last line if not exactly 16 characters.
while ((i % 16) != 0) {
printf (" ");
i++;
}
// And print the final ASCII buffer.
printf (" %s\n", buff);
}
#define MAX_PRECISION 50
#define IsNaN(n) (n != n)
// %f: double/single precision support (double or promoted float, 64-bits)
static void print_double_float(double val, unsigned int precision)
{
unsigned int cur_prec = 1;
if(precision==0)
precision = MAX_PRECISION;
// if the user-defined precision is out-of-bounds, normalize it
if(precision > MAX_PRECISION)
precision = MAX_PRECISION;
// if it's negative, show it!
if(val < 0)
{
printf("-");
// change to a positive value
val = -val;
}
// check to see if it is Not-a-Number
if(IsNaN(val))
{
printf("NaN");
return;
}
// print the integer part of the floating point
printf("%d", (int)val);
// if precision == 0, only print the integer part
if(!precision)
return;
// now on to the decimal potion
printf(".");
// remove the integer part
val -= (double)((int)val);
/* on every iteration, make sure there are still decimal places left that are non-zero,
and make sure we're still within the user-defined precision range. */
while(val > (double)((int)val) && cur_prec++ < precision+1)
{
// move the next decimal into the integer portion and print it
val *= 10;
printf("%d", (int)val);
/* if the value is == the floored value (integer portion),
then there are no more decimal places that are non-zero. */
if(val == (double)((int)val))
return;
// subtract the integer portion
val -= (double)((int)val);
}
}

View File

@ -0,0 +1,11 @@
#ifndef __H_KPRINTF
#define __H_KPRINTF 1
#include <stdarg.h>
int printf(char * fmt, ...);
int sprintf(char * buf, char * fmt, ...);
void hexDump (const char * desc, const void * addr, const int len);
#endif

View File

@ -0,0 +1,105 @@
#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++));
}
}

View File

@ -0,0 +1,11 @@
#ifndef __H_UART
#define __H_UART 1
void uart_send(char c);
char uart_recv();
char uart_recv_blocking();
void uart_setup(void);
void uart_back_up(void);
void uart_puts(char * s);
#endif

View File

View File

@ -0,0 +1,33 @@
#ifndef __H_ZYNQ
#define __H_ZYNQ 1
#define ZYNQ_PERIPH_PHY_BASE 0xF8000000
#define ZYNQ_PERIPH_TTC0_BASE (ZYNQ_PERIPH_PHY_BASE + 0x1000)
#define ZYNQ_PRI_PERIPH_PHYS_BASE 0xF8F00000
#define ZYNQ_PERIPH_SIZE 0x2000
#define ZYNQ_SCU_PHYS_BASE (ZYNQ_PRI_PERIPH_PHYS_BASE + 0)
#define ZYNQ_SCU_SIZE 0x0100
#define ZYNQ_GIC_CPU_PHYS_BASE (ZYNQ_PRI_PERIPH_PHYS_BASE + 0x100)
#define ZYNQ_GIC_CPU_SIZE 0x0100
#define ZYNQ_GTIMER_PHYS_BASE (ZYNQ_PRI_PERIPH_PHYS_BASE + 0x200)
#define ZYNQ_GTIMER_SIZE 0x0100
#define ZYNQ_PTIMER_WDT_PHYS_BASE (ZYNQ_PRI_PERIPH_PHYS_BASE + 0x600)
#define ZYNQ_PTIMER_WDT_SIZE 0x0100
#define ZYNQ_GIC_DIST_PHYS_BASE (ZYNQ_PRI_PERIPH_PHYS_BASE + 0x1000)
#define ZYNQ_GIC_DIST_SIZE 0x1000
#define WRITE32(_reg, _val) (*(volatile uint32_t*)&_reg = _val)
#define WRITE16(_reg, _val) (*(volatile uint16_t*)&_reg = _val)
#define WRITE8(_reg, _val) (*(volatile uint8_t*)&_reg = _val)
#define cpu_disable_interrups() asm ("cpsid if")
#define cpu_enable_interrups() asm ("cpsie if")
#endif