From 8b4c7855cca0a77af0365e8ab4c24f72a3104e3a Mon Sep 17 00:00:00 2001 From: imi415 Date: Sun, 31 May 2020 15:49:49 +0800 Subject: [PATCH] Refactored structure, implemented UARTLite and GPIO driver. --- Makefile | 19 +++++++---- include/ibex_system.h | 7 ++++ include/main.h | 9 +++++ include/soc_peripherals.h | 34 +++++++++++++++++++ include/system_defs.h | 13 ++++++++ include/xilinx_gpio.h | 23 +++++++++++++ include/xilinx_timer.h | 16 +++++++++ include/xilinx_uartlite.h | 21 ++++++++++++ linker.ld | 7 ++-- src/drivers/xilinx_gpio.c | 35 ++++++++++++++++++++ src/drivers/xilinx_timer.c | 2 ++ src/drivers/xilinx_uartlite.c | 25 ++++++++++++++ system_handlers.c => src/ibex_it.c | 3 +- src/ibex_system.c | 9 +++++ main.c => src/main.c | 15 ++++++--- src/soc_peripherals.c | 5 +++ src/syscalls.c | 29 ++++++++++++++++ system_init.c => src/system_init.c | 11 +++++-- startup.s | 4 +-- syscalls.c | 20 ----------- system_peripherals.c | 5 --- xilinx_ip_defs.h | 53 ------------------------------ 22 files changed, 268 insertions(+), 97 deletions(-) create mode 100644 include/ibex_system.h create mode 100644 include/main.h create mode 100644 include/soc_peripherals.h create mode 100644 include/system_defs.h create mode 100644 include/xilinx_gpio.h create mode 100644 include/xilinx_timer.h create mode 100644 include/xilinx_uartlite.h create mode 100644 src/drivers/xilinx_gpio.c create mode 100644 src/drivers/xilinx_timer.c create mode 100644 src/drivers/xilinx_uartlite.c rename system_handlers.c => src/ibex_it.c (80%) create mode 100644 src/ibex_system.c rename main.c => src/main.c (79%) create mode 100644 src/soc_peripherals.c create mode 100644 src/syscalls.c rename system_init.c => src/system_init.c (75%) delete mode 100644 syscalls.c delete mode 100644 system_peripherals.c delete mode 100644 xilinx_ip_defs.h diff --git a/Makefile b/Makefile index 43bbe6d..56e088f 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,18 @@ BUILD_DIR = build C_SOURCES = \ -system_handlers.c \ -system_peripherals.c \ -system_init.c \ -syscalls.c \ -main.c +src/drivers/xilinx_gpio.c \ +src/drivers/xilinx_uartlite.c \ +src/drivers/xilinx_timer.c \ +src/ibex_it.c \ +src/ibex_system.c \ +src/soc_peripherals.c \ +src/system_init.c \ +src/syscalls.c \ +src/main.c + +INCLUDES = \ +-Iinclude ASM_SOURCES = \ startup.s @@ -22,7 +29,7 @@ SZ = /home/imi415/Softwares/Arch/RISC-V/toolchains/rv32imc/bin/riscv32-unknown-e HEX = $(CP) -O ihex BIN = $(CP) -O binary -CFLAGS += -mabi=ilp32 -march=rv32imc -g +CFLAGS += -mabi=ilp32 -march=rv32imc -g $(INCLUDES) ASFLAGS += -mabi=ilp32 -march=rv32imc -g LDFLAGS += -nostartfiles -specs=nano.specs -lc -lm -lnosys diff --git a/include/ibex_system.h b/include/ibex_system.h new file mode 100644 index 0000000..d3146f2 --- /dev/null +++ b/include/ibex_system.h @@ -0,0 +1,7 @@ +#ifndef __IBEX_SYSTEM_H +#define __IBEX_SYSTEM_H + +void __enable_irqs(void); +void __disable_irqs(void); + +#endif \ No newline at end of file diff --git a/include/main.h b/include/main.h new file mode 100644 index 0000000..59a1307 --- /dev/null +++ b/include/main.h @@ -0,0 +1,9 @@ +#ifndef __MAIN_H +#define __MAIN_H + +#include "soc_peripherals.h" + +extern xilinx_uartlite_handle_t soc_uart; +extern xilinx_gpio_handle_t soc_gpio; + +#endif \ No newline at end of file diff --git a/include/soc_peripherals.h b/include/soc_peripherals.h new file mode 100644 index 0000000..ae6daa6 --- /dev/null +++ b/include/soc_peripherals.h @@ -0,0 +1,34 @@ +#ifndef __SOC_PERIPHERALS_H +#define __SOC_PERIPHERALS_H + +#include "xilinx_uartlite.h" +#include "xilinx_gpio.h" +#include "xilinx_timer.h" + +// Peripheral defines +#define UART0_BASE 0x40010000 +#define GPIO0_BASE 0x40000000 +#define TIMER0_BASE 0x40020000 + + +// SoC config +#define SYS_CLK_FREQ 48000000 +#define SYS_TICK_RATE 1000 + +// Peripherals +extern __IO xilinx_uartlite_t *UART0; +extern __IO xilinx_gpio_t *GPIO0; +extern __IO xilinx_timer_t *TIMER0; + +// SysTick +extern volatile uint32_t SysTick; + +static inline uint32_t GetTick() { + return SysTick; +} + +static inline uint32_t GetCoreClock() { + return SYS_CLK_FREQ; +} + +#endif \ No newline at end of file diff --git a/include/system_defs.h b/include/system_defs.h new file mode 100644 index 0000000..aba2e10 --- /dev/null +++ b/include/system_defs.h @@ -0,0 +1,13 @@ +#ifndef __XILINX_IP_DEFS_H +#define __XILINX_IP_DEFS_H + +#include + +#define __IO volatile + +#define RET_OK 0 +#define RET_ERR 1 + +typedef int sys_ret_t; + +#endif \ No newline at end of file diff --git a/include/xilinx_gpio.h b/include/xilinx_gpio.h new file mode 100644 index 0000000..409fd7c --- /dev/null +++ b/include/xilinx_gpio.h @@ -0,0 +1,23 @@ +#ifndef __XILINX_GPIO_H +#define __XILINX_GPIO_H + +#include "system_defs.h" + +typedef struct { + __IO uint32_t DATA; + __IO uint32_t TRI; + __IO uint32_t DATA2; + __IO uint32_t TRI2; +} xilinx_gpio_t; + +typedef struct { + __IO xilinx_gpio_t *instance; +} xilinx_gpio_handle_t; + +sys_ret_t xilinx_gpio_init(xilinx_gpio_handle_t *handle); +sys_ret_t xilinx_gpio_pinmode(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t output); +sys_ret_t xilinx_gpio_write(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t value); +uint8_t xilinx_gpio_read(xilinx_gpio_handle_t *handle, uint32_t pin); +sys_ret_t xilinx_gpio_toggle(xilinx_gpio_handle_t *handle, uint32_t pin); + +#endif \ No newline at end of file diff --git a/include/xilinx_timer.h b/include/xilinx_timer.h new file mode 100644 index 0000000..306b1e0 --- /dev/null +++ b/include/xilinx_timer.h @@ -0,0 +1,16 @@ +#ifndef __XILINX_TIMER_H +#define __XILINX_TIMER_H + +#include "system_defs.h" + +typedef struct { + __IO uint32_t TCSR0; + __IO uint32_t TLR0; + __IO uint32_t TCR0; + __IO uint32_t RSVD; + __IO uint32_t TCSR1; + __IO uint32_t TLR1; + __IO uint32_t TCR1; +} xilinx_timer_t; + +#endif \ No newline at end of file diff --git a/include/xilinx_uartlite.h b/include/xilinx_uartlite.h new file mode 100644 index 0000000..d525261 --- /dev/null +++ b/include/xilinx_uartlite.h @@ -0,0 +1,21 @@ +#ifndef __XILINX_UARTLITE_H +#define __XILINX_UARTLITE_H + +#include "system_defs.h" + +typedef struct { + __IO uint32_t RX_FIFO; + __IO uint32_t TX_FIFO; + __IO uint32_t STAT; + __IO uint32_t CTRL; +} xilinx_uartlite_t; + +typedef struct { + __IO xilinx_uartlite_t *instance; +} xilinx_uartlite_handle_t; + +sys_ret_t xilinx_uartlite_init(xilinx_uartlite_handle_t *handle); +sys_ret_t xilinx_uartlite_send(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len); +sys_ret_t xilinx_uartlite_receive(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len); + +#endif \ No newline at end of file diff --git a/linker.ld b/linker.ld index c9595b6..98ff253 100644 --- a/linker.ld +++ b/linker.ld @@ -64,6 +64,8 @@ SECTIONS _bss_start = _sbss; *(.bss) *(.bss*) + *(.sbss) + *(.sbss*) *(COMMON) . = ALIGN(4); _ebss = .; @@ -73,9 +75,10 @@ SECTIONS ._heap_stack_space : { . = ALIGN(8); - PROVIDE(end = .); - PROVIDE(_end = .); + _heap_start = .; . = . + _minimum_heap_size; + _heap_end = .; + . = ALIGN(8); . = . + _minimum_stack_size; . = ALIGN(8); } >RW_DATA diff --git a/src/drivers/xilinx_gpio.c b/src/drivers/xilinx_gpio.c new file mode 100644 index 0000000..0fec481 --- /dev/null +++ b/src/drivers/xilinx_gpio.c @@ -0,0 +1,35 @@ +#include "xilinx_gpio.h" + +sys_ret_t xilinx_gpio_init(xilinx_gpio_handle_t *handle) { + handle->instance->TRI = 0xFFFFFFFF; + return RET_OK; +} + +sys_ret_t xilinx_gpio_pinmode(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t output) { + if(output) { + handle->instance->TRI &= ~(1U << pin); + } + else { + handle->instance->TRI |= (1U << pin); + } + return RET_OK; +} + +sys_ret_t xilinx_gpio_write(xilinx_gpio_handle_t *handle, uint32_t pin, uint8_t value) { + if(value) { + handle->instance->DATA |= (1U << pin); + } + else { + handle->instance->DATA &= ~(1U << pin); + } + return RET_OK; +} + +uint8_t xilinx_gpio_read(xilinx_gpio_handle_t *handle, uint32_t pin) { + return (handle->instance->DATA & (1U << pin)) ? 1 : 0; +} + +sys_ret_t xilinx_gpio_toggle(xilinx_gpio_handle_t *handle, uint32_t pin) { + handle->instance->DATA ^= (1U << pin); + return RET_OK; +} \ No newline at end of file diff --git a/src/drivers/xilinx_timer.c b/src/drivers/xilinx_timer.c new file mode 100644 index 0000000..4ec13a3 --- /dev/null +++ b/src/drivers/xilinx_timer.c @@ -0,0 +1,2 @@ +#include "xilinx_timer.h" + diff --git a/src/drivers/xilinx_uartlite.c b/src/drivers/xilinx_uartlite.c new file mode 100644 index 0000000..15b1639 --- /dev/null +++ b/src/drivers/xilinx_uartlite.c @@ -0,0 +1,25 @@ +#include "xilinx_uartlite.h" + +sys_ret_t xilinx_uartlite_init(xilinx_uartlite_handle_t *handle) { + handle->instance->CTRL |= 0x03; // Reset FIFO +} + +sys_ret_t xilinx_uartlite_send(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len) { + for(uint32_t i = 0; i < len; i++) { + while(handle->instance->STAT & (1U << 0x03) || !(handle->instance->STAT & (1U << 0x02))) { // Check if TX FIFO is full + // TODO: Unless we figure out where systick should be. + } + handle->instance->TX_FIFO = data[i]; + } + return RET_OK; +} + +sys_ret_t xilinx_uartlite_receive(xilinx_uartlite_handle_t *handle, uint8_t *data, uint32_t len) { + for(uint32_t i = 0; i < len; i++) { + while(handle->instance->STAT & 0x01U == 0) { // Check if RX FIFO is empty + // TODO: Unless we figure out where our systick should be. + } + data[i] = handle->instance->RX_FIFO & 0xFF; + } + return RET_OK; +} \ No newline at end of file diff --git a/system_handlers.c b/src/ibex_it.c similarity index 80% rename from system_handlers.c rename to src/ibex_it.c index b3d8acb..fba769a 100644 --- a/system_handlers.c +++ b/src/ibex_it.c @@ -1,7 +1,8 @@ #include #include -#include "xilinx_ip_defs.h" +#include "soc_peripherals.h" +#include "xilinx_timer.h" void Generic_ExceptionCallback(void) { for(;;) { diff --git a/src/ibex_system.c b/src/ibex_system.c new file mode 100644 index 0000000..c984df0 --- /dev/null +++ b/src/ibex_system.c @@ -0,0 +1,9 @@ +#include "ibex_system.h" + +void __attribute__((naked)) __enable_irqs(void) { + asm volatile("csrs mstatus, %0\n" : : "r"(0x8)); +} + +void __attribute__((naked)) __disable_irqs(void) { + asm volatile("csrc mstatus, %0\n" : : "r"(0x08)); +} \ No newline at end of file diff --git a/main.c b/src/main.c similarity index 79% rename from main.c rename to src/main.c index dd811cf..50e9fe7 100644 --- a/main.c +++ b/src/main.c @@ -1,14 +1,16 @@ #include #include -#include "xilinx_ip_defs.h" + +#include "main.h" #define DDR_BASE 0x1FC00000 #define DDR_LENGTH 0x100 +xilinx_uartlite_handle_t soc_uart; +xilinx_gpio_handle_t soc_gpio; + int main(int argc, char *argv[]) { - GPIO0->TRI = 0xFFFFFFFD; - GPIO0->DATA = 0x00; printf("Dumping first 256 bytes of DDR memory...\r\n"); for(uint32_t i = DDR_BASE; i < DDR_BASE + DDR_LENGTH; i++) { printf("%02x ", *(uint8_t *)i); @@ -31,10 +33,13 @@ int main(int argc, char *argv[]) { uint32_t previous_tick = GetTick(); + xilinx_gpio_pinmode(&soc_gpio, 1, 1); + xilinx_gpio_write(&soc_gpio, 1, 0); + while(1) { if(GetTick() - previous_tick >= 500) { - previous_tick = SysTick; - GPIO0->DATA ^= 0x02; + previous_tick = GetTick(); + xilinx_gpio_toggle(&soc_gpio, 1); printf("SysTick: %lu\r\n", GetTick()); } } diff --git a/src/soc_peripherals.c b/src/soc_peripherals.c new file mode 100644 index 0000000..654e117 --- /dev/null +++ b/src/soc_peripherals.c @@ -0,0 +1,5 @@ +#include "soc_peripherals.h" + +__IO xilinx_uartlite_t *UART0 = (xilinx_uartlite_t *) UART0_BASE; +__IO xilinx_gpio_t *GPIO0 = (xilinx_gpio_t *) GPIO0_BASE; +__IO xilinx_timer_t *TIMER0 = (xilinx_timer_t *) TIMER0_BASE; \ No newline at end of file diff --git a/src/syscalls.c b/src/syscalls.c new file mode 100644 index 0000000..f6a6b62 --- /dev/null +++ b/src/syscalls.c @@ -0,0 +1,29 @@ +#include +#include + +#include "main.h" + +extern int _heap_start; +extern int _heap_end; +static void *_old_heap = &_heap_start; + +int _write(int handle, char *data, int size) { + int count; + handle = handle; + xilinx_uartlite_send(&soc_uart, data, size); + return size; +} + +void *_sbrk(int nbytes) { + char *_old = _old_heap; + if(&_heap_start == &_heap_end) { + errno = -ENOMEM; + return (void *)-1; + } + if((_old + nbytes) < (char *)&_heap_end) { + _old += nbytes; + } else { + errno = -ENOMEM; + return (void *)-1; + } +} \ No newline at end of file diff --git a/system_init.c b/src/system_init.c similarity index 75% rename from system_init.c rename to src/system_init.c index 3d430af..95c1382 100644 --- a/system_init.c +++ b/src/system_init.c @@ -1,10 +1,15 @@ -#include "xilinx_ip_defs.h" +#include "xilinx_timer.h" + +#include "main.h" __IO uint32_t SysTick; void System_Init(void) { - // Clear UARTLite FIFOs - UART0->CTRL = 0x03; + soc_uart.instance = UART0; + xilinx_uartlite_init(&soc_uart); + + soc_gpio.instance = GPIO0; + xilinx_gpio_init(&soc_gpio); SysTick = 0; diff --git a/startup.s b/startup.s index c4c78d5..a34c81a 100644 --- a/startup.s +++ b/startup.s @@ -54,7 +54,7 @@ copy_data: addi x25, x25, 4 addi x26, x26, 4 - ble x26, x27, copy_data + blt x26, x27, copy_data copy_data_end: @@ -67,7 +67,7 @@ copy_data_end: zero_bss: sw x0, 0(x26) addi x26, x26, 4 - ble x26, x27, zero_bss + blt x26, x27, zero_bss zero_bss_end: jal x1, System_Init diff --git a/syscalls.c b/syscalls.c deleted file mode 100644 index 5c52ace..0000000 --- a/syscalls.c +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include "xilinx_ip_defs.h" - - -void _putchar(char ch) -{ - while(((UART0->STAT & 0x04) == 0) || UART0->STAT & 0x08) { - // Waits for TX FIFO empty. - } - UART0->TX_FIFO = ch; -} - -int _write(int handle, char *data, int size ) { - int count; - handle = handle; - for( count = 0; count < size; count++) { - _putchar(data[count]); - } - return count; -} \ No newline at end of file diff --git a/system_peripherals.c b/system_peripherals.c deleted file mode 100644 index 5f7147f..0000000 --- a/system_peripherals.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "xilinx_ip_defs.h" - -__IO UartLite_TypeDef *UART0 = (UartLite_TypeDef *)UART0_BASE; -__IO GPIO_TypeDef *GPIO0 = (GPIO_TypeDef *)GPIO0_BASE; -__IO Timer_TypeDef *TIMER0 = (Timer_TypeDef *)TIMER0_BASE; \ No newline at end of file diff --git a/xilinx_ip_defs.h b/xilinx_ip_defs.h deleted file mode 100644 index c697cb8..0000000 --- a/xilinx_ip_defs.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __XILINX_IP_DEFS_H -#define __XILINX_IP_DEFS_H - -#include - -#define __IO volatile - -typedef struct { - __IO uint32_t RX_FIFO; - __IO uint32_t TX_FIFO; - __IO uint32_t STAT; - __IO uint32_t CTRL; -} UartLite_TypeDef; - -typedef struct { - __IO uint32_t DATA; - __IO uint32_t TRI; - __IO uint32_t DATA2; - __IO uint32_t TRI2; -} GPIO_TypeDef; - -typedef struct { - __IO uint32_t TCSR0; - __IO uint32_t TLR0; - __IO uint32_t TCR0; - __IO uint32_t RSVD; - __IO uint32_t TCSR1; - __IO uint32_t TLR1; - __IO uint32_t TCR1; -} Timer_TypeDef; - -#define UART0_BASE 0x40010000 -#define GPIO0_BASE 0x40000000 -#define TIMER0_BASE 0x40020000 - -#define SYS_CLK_FREQ 48000000 -#define SYS_TICK_RATE 1000 - -extern __IO UartLite_TypeDef *UART0; -extern __IO GPIO_TypeDef *GPIO0; -extern __IO Timer_TypeDef *TIMER0; - -extern __IO uint32_t SysTick; - -static inline uint32_t GetTick() { - return SysTick; -} - -static inline uint32_t GetCoreClock() { - return SYS_CLK_FREQ; -} - -#endif \ No newline at end of file