This commit is contained in:
Polprzewodnikowy 2021-09-25 12:23:10 +02:00
parent 281137f9f1
commit 1e98c669bd
11 changed files with 57 additions and 49 deletions

View File

@ -19,7 +19,7 @@
# #
# Quartus Prime # Quartus Prime
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition # Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
# Date created = 00:28:50 September 07, 2021 # Date created = 21:23:28 September 18, 2021
# #
# -------------------------------------------------------------------------- # # -------------------------------------------------------------------------- #
# #
@ -191,7 +191,7 @@ set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON
# Compiler Assignments # Compiler Assignments
# ==================== # ====================
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" set_global_assignment -name OPTIMIZATION_MODE BALANCED
# Analysis & Synthesis Assignments # Analysis & Synthesis Assignments
# ================================ # ================================

View File

@ -3,7 +3,7 @@ CC = $(TOOLCHAIN)gcc
OBJCOPY = $(TOOLCHAIN)objcopy OBJCOPY = $(TOOLCHAIN)objcopy
SIZE = $(TOOLCHAIN)size SIZE = $(TOOLCHAIN)size
FLAGS = -mabi=ilp32 -march=rv32i FLAGS = -mabi=ilp32 -march=rv32i $(USER_FLAGS)
CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP
LDFLAGS = -nostartfiles -Wl,--gc-sections LDFLAGS = -nostartfiles -Wl,--gc-sections
@ -17,7 +17,9 @@ DEPS = $(OBJS:.o=.d)
VPATH = $(SRC_DIR) VPATH = $(SRC_DIR)
all: make_output_dir $(BOOTLOADER_DIR)/cpu_bootloader.sv $(BUILD_DIR)/controller.rom $(@info $(shell mkdir -p ./$(BUILD_DIR) &> /dev/null))
all: $(BOOTLOADER_DIR)/cpu_bootloader.sv $(BUILD_DIR)/controller.rom
$(BUILD_DIR)/%.o: %.c $(BUILD_DIR)/%.o: %.c
$(CC) $(FLAGS) $(CFLAGS) -c $< -o $@ $(CC) $(FLAGS) $(CFLAGS) -c $< -o $@
@ -32,21 +34,18 @@ $(BUILD_DIR)/controller.rom: $(BUILD_DIR)/uc.elf
@echo 'Size of controller modules:' @echo 'Size of controller modules:'
@$(SIZE) -B -t --common $(OBJS) @$(SIZE) -B -t --common $(OBJS)
@echo 'Size of controller:' @echo 'Size of controller:'
@$(SIZE) -B build/controller.elf @$(SIZE) -B $(BUILD_DIR)/controller.elf
$(BOOTLOADER_DIR)/cpu_bootloader.sv: $(BUILD_DIR)/uc.elf $(BOOTLOADER_DIR)/cpu_bootloader.sv: $(BUILD_DIR)/uc.elf
$(OBJCOPY) -j .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/bootloader.elf $(OBJCOPY) -j .bootloader $(BUILD_DIR)/uc.elf $(BUILD_DIR)/bootloader.elf
$(OBJCOPY) -O binary $(BUILD_DIR)/bootloader.elf $(BUILD_DIR)/bootloader.bin $(OBJCOPY) -O binary $(BUILD_DIR)/bootloader.elf $(BUILD_DIR)/bootloader.bin
python3 tools/bin2sv.py tools/cpu_bootloader_template.sv $@ < $(BUILD_DIR)/bootloader.bin python3 tools/bin2sv.py tools/cpu_bootloader_template.sv $@ < $(BUILD_DIR)/bootloader.bin
@echo 'Size of bootloader:' @echo 'Size of bootloader:'
@$(SIZE) -B build/bootloader.elf @$(SIZE) -B $(BUILD_DIR)/bootloader.elf
make_output_dir:
@$(shell mkdir ./$(BUILD_DIR) 2> /dev/null)
clean: clean:
rm -rf build rm -rf ./$(BUILD_DIR)/*
.PHONY: all make_output_dir clean .PHONY: all clean
-include $(DEPS) -include $(DEPS)

View File

@ -89,6 +89,7 @@ static void set_save_type (enum save_type save_type) {
change_scr_bits(CFG_SCR_FLASHRAM_EN, true); change_scr_bits(CFG_SCR_FLASHRAM_EN, true);
break; break;
default: default:
save_type = SAVE_TYPE_NONE;
break; break;
} }
@ -113,13 +114,13 @@ void cfg_update (uint32_t *args) {
change_scr_bits(CFG_SCR_DD_EN, args[1]); change_scr_bits(CFG_SCR_DD_EN, args[1]);
break; break;
case CFG_ID_SAVE_TYPE: case CFG_ID_SAVE_TYPE:
set_save_type((enum save_type)(args[1])); set_save_type((enum save_type) (args[1]));
break; break;
case CFG_ID_CIC_SEED: case CFG_ID_CIC_SEED:
p.cic_seed = (uint16_t)(args[1] & 0xFFFF); p.cic_seed = (uint16_t) (args[1] & 0xFFFF);
break; break;
case CFG_ID_TV_TYPE: case CFG_ID_TV_TYPE:
p.tv_type = (uint8_t)(args[1] & 0x03); p.tv_type = (uint8_t) (args[1] & 0x03);
break; break;
case CFG_ID_SAVE_OFFEST: case CFG_ID_SAVE_OFFEST:
CFG->SAVE_OFFSET = args[1]; CFG->SAVE_OFFSET = args[1];
@ -148,13 +149,13 @@ void cfg_query (uint32_t *args) {
args[1] = CFG->SCR & CFG_SCR_DD_EN; args[1] = CFG->SCR & CFG_SCR_DD_EN;
break; break;
case CFG_ID_SAVE_TYPE: case CFG_ID_SAVE_TYPE:
args[1] = (uint32_t)(p.save_type); args[1] = (uint32_t) (p.save_type);
break; break;
case CFG_ID_CIC_SEED: case CFG_ID_CIC_SEED:
args[1] = (uint32_t)(p.cic_seed); args[1] = (uint32_t) (p.cic_seed);
break; break;
case CFG_ID_TV_TYPE: case CFG_ID_TV_TYPE:
args[1] = (uint32_t)(p.tv_type); args[1] = (uint32_t) (p.tv_type);
break; break;
case CFG_ID_SAVE_OFFEST: case CFG_ID_SAVE_OFFEST:
args[1] = CFG->SAVE_OFFSET; args[1] = CFG->SAVE_OFFSET;
@ -171,8 +172,10 @@ void cfg_query (uint32_t *args) {
void cfg_init (void) { void cfg_init (void) {
set_save_type(SAVE_TYPE_NONE); set_save_type(SAVE_TYPE_NONE);
CFG->DD_OFFSET = DEFAULT_DD_OFFSET; CFG->DD_OFFSET = DEFAULT_DD_OFFSET;
CFG->SCR = CFG_SCR_CPU_READY | CFG_SCR_SDRAM_SWITCH; CFG->SCR = CFG_SCR_CPU_READY | CFG_SCR_SDRAM_SWITCH;
p.cic_seed = 0xFFFF; p.cic_seed = 0xFFFF;
p.tv_type = 0x03; p.tv_type = 0x03;
} }

View File

@ -54,7 +54,7 @@ void process_flashram (void) {
if (op != OP_NONE) { if (op != OP_NONE) {
length = get_operation_length(op); length = get_operation_length(op);
save_data = (io32_t *)(SDRAM_BASE + CFG->SAVE_OFFSET + ((FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE)); save_data = (io32_t *) (SDRAM_BASE + CFG->SAVE_OFFSET + ((FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE));
for (uint32_t i = 0; i < (length / 4); i++) { for (uint32_t i = 0; i < (length / 4); i++) {
if (op == OP_WRITE_PAGE) { if (op == OP_WRITE_PAGE) {

View File

@ -34,8 +34,8 @@ __attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
#endif #endif
if (length == 0) { if (length == 0) {
__asm__ volatile ( __asm__ volatile (
"la t0, app_handler\n" "la t0, app_handler \n"
"jalr zero, t0\n" "jalr zero, t0 \n"
); );
} }
} }
@ -44,8 +44,8 @@ __attribute__ ((naked, section(".bootloader"))) void reset_handler (void) {
__attribute__ ((naked)) void app_handler (void) { __attribute__ ((naked)) void app_handler (void) {
__asm__ volatile ( __asm__ volatile (
"la sp, __stack_pointer\n" "la sp, __stack_pointer \n"
"la gp, __global_pointer\n" "la gp, __global_pointer \n"
"jal zero, main\n" "jal zero, main \n"
); );
} }

View File

@ -31,15 +31,15 @@
static void joybus_rx (uint8_t *data) { static void joybus_rx (uint8_t *data) {
uint32_t rx_length = (JOYBUS->SCR & JOYBUS_SCR_RX_LENGTH_MASK) >> JOYBUS_SCR_RX_LENGTH_BIT; size_t rx_length = (JOYBUS->SCR & JOYBUS_SCR_RX_LENGTH_MASK) >> JOYBUS_SCR_RX_LENGTH_BIT;
for (size_t i = 0; i < rx_length; i++) { for (size_t i = 0; i < rx_length; i++) {
data[i] = ((uint8_t *) JOYBUS->DATA)[(10 - rx_length) + i]; data[i] = ((uint8_t *) (JOYBUS->DATA))[(10 - rx_length) + i];
} }
} }
static void joybus_tx (uint8_t *data, size_t length) { static void joybus_tx (uint8_t *data, size_t length) {
for (size_t i = 0; i < ((length + 3) / 4); i++) { for (size_t i = 0; i < ((length + 3) / 4); i++) {
JOYBUS->DATA[i] = ((uint32_t *) data)[i]; JOYBUS->DATA[i] = ((uint32_t *) (data))[i];
} }
JOYBUS->SCR = ((length * 8) << JOYBUS_SCR_TX_LENGTH_BIT) | JOYBUS_SCR_TX_START; JOYBUS->SCR = ((length * 8) << JOYBUS_SCR_TX_LENGTH_BIT) | JOYBUS_SCR_TX_START;
} }
@ -61,6 +61,7 @@ void joybus_set_eeprom (enum eeprom_type eeprom_type) {
void joybus_init (void) { void joybus_init (void) {
JOYBUS->SCR = JOYBUS_SCR_TX_RESET | JOYBUS_SCR_RX_RESET; JOYBUS->SCR = JOYBUS_SCR_TX_RESET | JOYBUS_SCR_RX_RESET;
p.eeprom_type = EEPROM_NONE; p.eeprom_type = EEPROM_NONE;
p.rtc_running = true; p.rtc_running = true;
p.rtc_write_protect = RTC_WP_MASK; p.rtc_write_protect = RTC_WP_MASK;
@ -120,9 +121,9 @@ void process_joybus (void) {
} }
} else if (rx_data[1] == RTC_BLOCK_TIME) { } else if (rx_data[1] == RTC_BLOCK_TIME) {
rtc_time_t *rtc_time = rtc_get_time(); rtc_time_t *rtc_time = rtc_get_time();
tx_data[0] = rtc_time->seconds; tx_data[0] = rtc_time->second;
tx_data[1] = rtc_time->minutes; tx_data[1] = rtc_time->minute;
tx_data[2] = rtc_time->hours | 0x80; tx_data[2] = rtc_time->hour | 0x80;
tx_data[4] = rtc_time->weekday - 1; tx_data[4] = rtc_time->weekday - 1;
tx_data[3] = rtc_time->day; tx_data[3] = rtc_time->day;
tx_data[5] = rtc_time->month; tx_data[5] = rtc_time->month;
@ -139,9 +140,9 @@ void process_joybus (void) {
p.rtc_running = (!(rx_data[3] & RTC_ST)); p.rtc_running = (!(rx_data[3] & RTC_ST));
} else if (rx_data[1] == RTC_BLOCK_TIME && (!(p.rtc_write_protect & RTC_WP_TIME))) { } else if (rx_data[1] == RTC_BLOCK_TIME && (!(p.rtc_write_protect & RTC_WP_TIME))) {
rtc_time_t rtc_time; rtc_time_t rtc_time;
rtc_time.seconds = rx_data[2]; rtc_time.second = rx_data[2];
rtc_time.minutes = rx_data[3]; rtc_time.minute = rx_data[3];
rtc_time.hours = rx_data[4] & 0x7F; rtc_time.hour = rx_data[4] & 0x7F;
rtc_time.weekday = rx_data[6] + 1; rtc_time.weekday = rx_data[6] + 1;
rtc_time.day = rx_data[5]; rtc_time.day = rx_data[5];
rtc_time.month = rx_data[7]; rtc_time.month = rx_data[7];

View File

@ -121,9 +121,9 @@ void process_rtc (void) {
} else if (p.time_valid) { } else if (p.time_valid) {
p.running = p.data[RTCSEC] & RTCSEC_ST; p.running = p.data[RTCSEC] & RTCSEC_ST;
sanitize_time(p.data); sanitize_time(p.data);
p.time.seconds = p.data[RTCSEC]; p.time.second = p.data[RTCSEC];
p.time.minutes = p.data[RTCMIN]; p.time.minute = p.data[RTCMIN];
p.time.hours = p.data[RTCHOUR]; p.time.hour = p.data[RTCHOUR];
p.time.weekday = p.data[RTCWKDAY]; p.time.weekday = p.data[RTCWKDAY];
p.time.day = p.data[RTCDATE]; p.time.day = p.data[RTCDATE];
p.time.month = p.data[RTCMTH]; p.time.month = p.data[RTCMTH];
@ -162,8 +162,8 @@ void process_rtc (void) {
p.i2c_write = true; p.i2c_write = true;
p.i2c_length = 7; p.i2c_length = 7;
p.data[0] = RTCMIN; p.data[0] = RTCMIN;
p.data[1] = p.time.minutes; p.data[1] = p.time.minute;
p.data[2] = p.time.hours; p.data[2] = p.time.hour;
p.data[3] = p.time.weekday | RTCWKDAY_VBAT; p.data[3] = p.time.weekday | RTCWKDAY_VBAT;
p.data[4] = p.time.day; p.data[4] = p.time.day;
p.data[5] = p.time.month; p.data[5] = p.time.month;
@ -177,7 +177,7 @@ void process_rtc (void) {
p.i2c_length = 2; p.i2c_length = 2;
p.i2c_first_read_done = false; p.i2c_first_read_done = false;
p.data[0] = RTCSEC; p.data[0] = RTCSEC;
p.data[1] = p.time.seconds | RTCSEC_ST; p.data[1] = p.time.second | RTCSEC_ST;
p.rtc_phase = RTC_PHASE_WAIT_START; p.rtc_phase = RTC_PHASE_WAIT_START;
break; break;

View File

@ -6,9 +6,9 @@
typedef struct { typedef struct {
uint8_t seconds; uint8_t second;
uint8_t minutes; uint8_t minute;
uint8_t hours; uint8_t hour;
uint8_t weekday; uint8_t weekday;
uint8_t day; uint8_t day;
uint8_t month; uint8_t month;

View File

@ -7,9 +7,6 @@
#include <stdbool.h> #include <stdbool.h>
#define DEBUG_ENABLED
typedef volatile uint8_t io8_t; typedef volatile uint8_t io8_t;
typedef volatile uint32_t io32_t; typedef volatile uint32_t io32_t;

View File

@ -1,43 +1,50 @@
#include "uart.h" #include "uart.h"
#include "rtc.h" #include "rtc.h"
#ifdef DEBUG_ENABLED
#ifdef DEBUG
static const char hex_char_map[16] = { static const char hex_char_map[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
}; };
#endif
void uart_print (const char *text) { void uart_print (const char *text) {
#ifdef DEBUG
while (*text != '\0') { while (*text != '\0') {
while (!(UART->SCR & UART_SCR_TXE)); while (!(UART->SCR & UART_SCR_TXE));
UART->DR = *text++; UART->DR = *text++;
} }
#endif
} }
void uart_print_02hex (uint8_t number) { void uart_print_02hex (uint8_t number) {
#ifdef DEBUG
char buffer[3]; char buffer[3];
buffer[0] = hex_char_map[(number >> 4) & 0x0F]; buffer[0] = hex_char_map[(number >> 4) & 0x0F];
buffer[1] = hex_char_map[number & 0x0F]; buffer[1] = hex_char_map[number & 0x0F];
buffer[2] = '\0'; buffer[2] = '\0';
uart_print(buffer); uart_print(buffer);
#endif
} }
void uart_print_08hex (uint32_t number) { void uart_print_08hex (uint32_t number) {
#ifdef DEBUG
uart_print_02hex((number >> 24) & 0xFF); uart_print_02hex((number >> 24) & 0xFF);
uart_print_02hex((number >> 16) & 0xFF); uart_print_02hex((number >> 16) & 0xFF);
uart_print_02hex((number >> 8) & 0xFF); uart_print_02hex((number >> 8) & 0xFF);
uart_print_02hex((number >> 0) & 0xFF); uart_print_02hex((number >> 0) & 0xFF);
}
#endif #endif
}
void uart_init (void) { void uart_init (void) {
#ifdef DEBUG_ENABLED #ifdef DEBUG
uart_print("App ready!\n"); uart_print("App ready!\n");
#endif #endif
} }
void process_uart (void) { void process_uart (void) {
#ifdef DEBUG_ENABLED #ifdef DEBUG
rtc_time_t *time; rtc_time_t *time;
if (UART->SCR & USB_SCR_RXNE) { if (UART->SCR & USB_SCR_RXNE) {
@ -62,7 +69,7 @@ void process_uart (void) {
uart_print("(valid) "); uart_print("(valid) ");
} }
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
uart_print_02hex(((uint8_t *)(time))[i]); uart_print_02hex(((uint8_t *) (time))[i]);
uart_print(" "); uart_print(" ");
} }
uart_print("\r\n"); uart_print("\r\n");

View File

@ -83,6 +83,7 @@ static struct process p;
void usb_init (void) { void usb_init (void) {
USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX; USB->SCR = USB_SCR_FLUSH_TX | USB_SCR_FLUSH_RX;
p.state = STATE_IDLE; p.state = STATE_IDLE;
} }