diff --git a/software/boards/hydrausb3/Makefile b/software/boards/hydrausb3/Makefile new file mode 100644 index 0000000..83611a8 --- /dev/null +++ b/software/boards/hydrausb3/Makefile @@ -0,0 +1,150 @@ +RM := rm -rf + +# Check and choose riscv compiler either closed source from MounRiver Studio riscv-none-embed" or open source one GCC riscv-none-elf +# For open source GCC riscv-none-elf see https://github.com/hydrausb3/riscv-none-elf-gcc-xpack/releases/ +COMPILER_PREFIX := $(shell command -v riscv-none-embed-gcc >/dev/null 2>&1 && echo "riscv-none-embed" || true) +COMPILER_PREFIX := $(if $(COMPILER_PREFIX),$(COMPILER_PREFIX),$(shell command -v riscv-none-elf-gcc >/dev/null 2>&1 && echo "riscv-none-elf" || true)) + +ifeq ($(COMPILER_PREFIX),riscv-none-embed) + MARCH_OPT := -march=rv32imac +else ifeq ($(COMPILER_PREFIX),riscv-none-elf) + MARCH_OPT := -march=rv32imac_zicsr +else + $(error Unknown COMPILER_PREFIX: $(COMPILER_PREFIX)) +endif + +# Define option(s) defined in pre-processor compiler option(s) +DEFINE_OPTS = -DDEBUG=1 +# Optimisation option(s) +OPTIM_OPTS = -O3 +# Debug option(s) +DEBUG = -g + +BUILD_DIR = ./build + +PROJECT = $(BUILD_DIR)/sucrela_fw +BSP_DIR = ../../../wch-ch56x-bsp + +RVMSIS_DIR = $(BSP_DIR)/rvmsis +RVMSIS_SRCS = $(wildcard $(RVMSIS_DIR)/*.c) +OBJS += $(patsubst $(RVMSIS_DIR)/%.c,$(BUILD_DIR)/%.o,$(RVMSIS_SRCS)) + +DRV_DIR = $(BSP_DIR)/drv +DRV_SRCS = $(wildcard $(DRV_DIR)/*.c) +OBJS += $(patsubst $(DRV_DIR)/%.c,$(BUILD_DIR)/%.o,$(DRV_SRCS)) + +BOARD_DIR = $(BSP_DIR)/board +BOARD_SRCS = $(BOARD_DIR)/hydrausb3_v1.c +OBJS += $(patsubst $(BOARD_DIR)/%.c,$(BUILD_DIR)/%.o,$(BOARD_SRCS)) + +USER_DIR = ./ +USER_SRCS = $(wildcard $(USER_DIR)/*.c) +OBJS += $(patsubst $(USER_DIR)/%.c,$(BUILD_DIR)/%.o,$(USER_SRCS)) + +# All of the sources participating in the build are defined here +OBJS += $(BUILD_DIR)/startup_CH56x.o +DEPS = $(subst .o,.d,$(OBJS)) +LIBS = + +UARTBONE_DIR = ../../libuartbone +UARTBONE_SRCS = $(UARTBONE_DIR)/uartbone.c +OBJS += $(patsubst $(UARTBONE_DIR)/%.c,$(BUILD_DIR)/%.o,$(UARTBONE_SRCS)) + +BASE_OPTS = $(MARCH_OPT) -mabi=ilp32 -msmall-data-limit=8 $(OPTIM_OPTS) -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections +C_OPTS = $(BASE_OPTS) $(DEBUG) $(DEFINE_OPTS)\ + $(INCLUDES) -std=gnu99 -MMD -MP -MT"$(@)" +LD_OPTS = -T "$(BSP_DIR)/ld/.ld" -nostartfiles -Xlinker --gc-sections -Xlinker --print-memory-usage -Wl,-Map,"$(PROJECT).map" --specs=nano.specs --specs=nosys.specs + +INCLUDES = \ + -I"$(RVMSIS_DIR)" \ + -I"$(DRV_DIR)" \ + -I"$(BOARD_DIR)" \ + -I"$(USER_DIR)" \ + -I"$(UARTBONE_DIR)" + +# Add inputs and outputs from these tool invocations to the build variables +SECONDARY_FLASH += $(PROJECT).hex $(PROJECT).bin +SECONDARY_LIST += $(PROJECT).lst +SECONDARY_SIZE += $(PROJECT).siz +SECONDARY_MAP += $(PROJECT).map + +SECONDARY_OUTPUTS = $(SECONDARY_FLASH) $(SECONDARY_LIST) $(SECONDARY_SIZE) $(SECONDARY_MAP) +secondary-outputs: $(SECONDARY_OUTPUTS) + +# All Target +all: $(PROJECT).elf secondary-outputs + +.PRECIOUS: $(BUILD_DIR)/. $(BUILD_DIR)%/. + +$(BUILD_DIR)/.: + mkdir -p $@ + +$(BUILD_DIR)%/.: + mkdir -p $@ + +.SECONDEXPANSION: + +$(BUILD_DIR)/startup_CH56x.o: $(BSP_DIR)/startup/startup_CH56x.S | $$(@D)/. + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -x assembler -c -o "$@" "$<" + @echo ' ' + +$(BUILD_DIR)/%.o: $(USER_DIR)/%.c | $$(@D)/. + @echo $(OBJS) + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<" + @echo ' ' + +$(BUILD_DIR)/%.o: $(UARTBONE_DIR)/%.c | $$(@D)/. + @echo $(OBJS) + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<" + @echo ' ' + +$(BUILD_DIR)/%.o: $(RVMSIS_DIR)/%.c | $$(@D)/. + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<" + @echo ' ' + +$(BUILD_DIR)/%.o: $(DRV_DIR)/%.c | $$(@D)/. + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<" + @echo ' ' + +$(BUILD_DIR)/%.o: $(BOARD_DIR)/%.c | $$(@D)/. + @echo 'Building file: $<' + $(COMPILER_PREFIX)-gcc $(C_OPTS) -c -o "$@" "$<" + @echo ' ' + +# Tool invocations +$(PROJECT).elf: $(OBJS) + @echo 'Invoking: GNU RISC-V Cross C Linker' + $(COMPILER_PREFIX)-gcc $(BASE_OPTS) $(LD_OPTS) -o "$(PROJECT).elf" $(OBJS) $(LIBS) + @echo ' ' + +$(PROJECT).hex: $(PROJECT).elf + @echo 'Invoking: GNU RISC-V Cross Create Flash Image' + $(COMPILER_PREFIX)-objcopy -O ihex "$(PROJECT).elf" "$(PROJECT).hex" + @echo ' ' + +$(PROJECT).bin: $(PROJECT).elf + -@echo 'Create Flash Image BIN' + -$(COMPILER_PREFIX)-objcopy -O binary "$(PROJECT).elf" "$(PROJECT).bin" + -@echo ' ' + +$(PROJECT).lst: $(PROJECT).elf + @echo 'Invoking: GNU RISC-V Cross Create Listing' + $(COMPILER_PREFIX)-objdump --source --all-headers --demangle --line-numbers --wide "$(PROJECT).elf" > "$(PROJECT).lst" + @echo ' ' + +$(PROJECT).siz: $(PROJECT).elf + @echo 'Invoking: GNU RISC-V Cross Print Size' + $(COMPILER_PREFIX)-size --format=berkeley "$(PROJECT).elf" + @echo ' ' + +# Other Targets +clean: + -$(RM) $(OBJS) $(DEPS) $(SECONDARY_OUTPUTS) $(PROJECT).elf + -@echo ' ' + +.PHONY: all clean dependents diff --git a/software/boards/hydrausb3/main.c b/software/boards/hydrausb3/main.c new file mode 100644 index 0000000..05d42db --- /dev/null +++ b/software/boards/hydrausb3/main.c @@ -0,0 +1,61 @@ +#include +#include +#include + +#include "core_riscv.h" +#include "CH56x_bsp.h" +#include "CH56x_uart.h" + +#include "uartbone.h" + +/* System clock and HSPI freq : 15 MHz */ +#define FREQ_SYS (15000000) + +/* UARTs settings */ +#define UART1_BAUD 115200 +#define UART3_BAUD 115200 + +/* HSPI Data width : 8 bits */ +#define HSPI_DATA_WIDTH 0 + +//DMA_Addr0 +#define TX_DMA_Addr0 0x20020000 +#define RX_DMA_Addr0 0x20020000 + +//DMA_Addr1 +#define TX_DMA_Addr1 0x20020000 + DMA_Tx_Len0 +#define RX_DMA_Addr1 0x20020000 + DMA_Tx_Len1 + +void uartbone_ch56x_init(struct uartbone_ctx *ctx, int uart_num, int baudrate, int addr_width); + +int main(void) { + struct uartbone_ctx ctx; + char ident_str[256]; + int i = 0; + char c; + uint32_t ident_addr = 0x00002000; /* we should find a way to embed this at build time from the soc.csv */ + + bsp_gpio_init(); + + UART1_init(UART1_BAUD, FREQ_SYS); + UART3_init(UART3_BAUD, FREQ_SYS); + + printf("\n\r"); + printf("###########################\n\r"); + printf("# SucreLA fw starting up! #\n\r"); + printf("###########################\n\r\n\r"); + + printf("board: hydrausb3\n\r"); + uartbone_ch56x_init(&ctx, 3, 115200, 4); + printf("uartbone: initialized on UART3\n\r"); + + printf("Identifying FPGA SoC...\n\r"); + memset(ident_str, '\0', sizeof(ident_str)); + do { + c = uartbone_read(&ctx, ident_addr+i*4); + ident_str[i++] = c; + } while (c); + printf("FPGA SoC ident: %s\n", ident_str); + + return 0; +} diff --git a/software/boards/hydrausb3/uartbone_ch569_backend.c b/software/boards/hydrausb3/uartbone_ch569_backend.c new file mode 100644 index 0000000..77d74f4 --- /dev/null +++ b/software/boards/hydrausb3/uartbone_ch569_backend.c @@ -0,0 +1,76 @@ +#include +#include + +#include "uartbone.h" +#include "CH56x_uart.h" + +static void ch56x_uart_writeb(struct uartbone_ctx *ctx, uint8_t data) { + //printf("sending byte 0x%02x to uart %d\n\r", data, ctx->fd); + switch (ctx->fd) { + case 0: { + UART0_SendByte(data); + break; + } + case 1: { + UART1_SendByte(data); + break; + } + case 2: { + UART2_SendByte(data); + break; + } + case 3: { + UART3_SendByte(data); + break; + } + default: { + printf("Only valid UARTs are 0/1/2/3\n"); + abort(); + } + } +} + +static int ch56x_uart_readb(struct uartbone_ctx *ctx, uint8_t *data) { + switch (ctx->fd) { + case 0: { + while (!(R8_UART0_LSR & RB_LSR_DATA_RDY)); // wait for FIFO not empty + *data = UART0_RecvByte(); + break; + } + case 1: { + while (!(R8_UART1_LSR & RB_LSR_DATA_RDY)); // wait for FIFO not empty + *data = UART1_RecvByte(); + break; + } + case 2: { + while (!(R8_UART2_LSR & RB_LSR_DATA_RDY)); // wait for FIFO not empty + *data = UART2_RecvByte(); + break; + } + case 3: { + while (!(R8_UART3_LSR & RB_LSR_DATA_RDY)); // wait for FIFO not empty + *data = UART3_RecvByte(); + break; + } + default: { + printf("Only valid UARTs are 0/1/2/3\n"); + abort(); + } + } + return 0; +} + +struct uart_backend ch56x_uart_backend = { + .type = CH569_UART, + .readb = ch56x_uart_readb, + .writeb = ch56x_uart_writeb +}; + +void uartbone_ch56x_init(struct uartbone_ctx *ctx, int uart_num, int baudrate, int addr_width) { + ctx->addr_width = addr_width; + ctx->baudrate = baudrate; + ctx->fd = uart_num; + ctx->open = true; + ctx->error = 0; + ctx->uart = &ch56x_uart_backend; +}