Skip to content

Commit

Permalink
Add basic fw for hydrausb3
Browse files Browse the repository at this point in the history
HydraUSB3 board is used to prototype SucreLA
Eventually a board featuring an ECP5 FPGA and a WCH569
microcontroller will be designed.

For now, let's use OrangeCrab FPGA board connected to
HydraUSB3.

Signed-off-by: Yann Sionneau <[email protected]>
  • Loading branch information
fallen committed Mar 3, 2024
1 parent c4f9d41 commit 6662498
Show file tree
Hide file tree
Showing 3 changed files with 287 additions and 0 deletions.
150 changes: 150 additions & 0 deletions software/boards/hydrausb3/Makefile
Original file line number Diff line number Diff line change
@@ -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
61 changes: 61 additions & 0 deletions software/boards/hydrausb3/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#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;
}
76 changes: 76 additions & 0 deletions software/boards/hydrausb3/uartbone_ch569_backend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <stdio.h>
#include <stdlib.h>

#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;
}

0 comments on commit 6662498

Please sign in to comment.