diff --git a/fw/rtl/cpu/cpu_soc.sv b/fw/rtl/cpu/cpu_soc.sv index 567759b..14e82bd 100644 --- a/fw/rtl/cpu/cpu_soc.sv +++ b/fw/rtl/cpu/cpu_soc.sv @@ -72,12 +72,16 @@ module cpu_soc ( .usb_pwren(usb_pwren) ); - cpu_uart cpu_uart_inst ( - .sys(sys), - .bus(bus.at[sc64::ID_CPU_UART].device), - .uart_rxd(uart_rxd), - .uart_txd(uart_txd) - ); + generate + if (sc64::CPU_HAS_UART) begin + cpu_uart cpu_uart_inst ( + .sys(sys), + .bus(bus.at[sc64::ID_CPU_UART].device), + .uart_rxd(uart_rxd), + .uart_txd(uart_txd) + ); + end + endgenerate cpu_dma cpu_dma_inst ( .sys(sys), diff --git a/fw/rtl/system/sc64.sv b/fw/rtl/system/sc64.sv index 4a839ca..56f5aae 100644 --- a/fw/rtl/system/sc64.sv +++ b/fw/rtl/system/sc64.sv @@ -34,6 +34,8 @@ package sc64; parameter int CLOCK_FREQUENCY = 32'd100_000_000; + parameter bit CPU_HAS_UART = 1'b0; + parameter int UART_BAUD_RATE = 32'd1_000_000; endpackage diff --git a/sw/riscv/src/dma.c b/sw/riscv/src/dma.c index 3015753..243a558 100644 --- a/sw/riscv/src/dma.c +++ b/sw/riscv/src/dma.c @@ -19,8 +19,3 @@ void dma_stop (void) { void dma_init (void) { dma_stop(); } - - -void process_dma (void) { - -} diff --git a/sw/riscv/src/dma.h b/sw/riscv/src/dma.h index e259cbb..75462a7 100644 --- a/sw/riscv/src/dma.h +++ b/sw/riscv/src/dma.h @@ -20,7 +20,6 @@ bool dma_busy (void); void dma_start (uint32_t memory_address, size_t length, enum dma_id id, enum dma_dir dir); void dma_stop (void); void dma_init (void); -void process_dma (void); #endif diff --git a/sw/riscv/src/flashram.c b/sw/riscv/src/flashram.c index b850472..02c5b5a 100644 --- a/sw/riscv/src/flashram.c +++ b/sw/riscv/src/flashram.c @@ -14,6 +14,17 @@ enum operation { }; +struct process { + bool save_in_progress; + enum operation op; + io32_t *save_pointer; + uint32_t num_words; + uint32_t current_word; +}; + +static struct process p; + + static enum operation get_operation_type (void) { uint32_t scr = FLASHRAM->SCR; @@ -44,26 +55,38 @@ static size_t get_operation_length (enum operation op) { void flashram_init (void) { FLASHRAM->SCR = FLASHRAM_OPERATION_DONE; + + p.save_in_progress = false; } void process_flashram (void) { - enum operation op = get_operation_type(); - size_t length; - io32_t *save_data; + if (!p.save_in_progress) { + p.op = get_operation_type(); - if (op != OP_NONE) { - length = get_operation_length(op); - save_data = (io32_t *) (SDRAM_BASE + CFG->SAVE_OFFSET + ((FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE)); + if (p.op != OP_NONE) { + uint32_t sdram_address = SDRAM_BASE + CFG->SAVE_OFFSET; - for (uint32_t i = 0; i < (length / 4); i++) { - if (op == OP_WRITE_PAGE) { - *save_data++ &= FLASHRAM->BUFFER[i]; - } else { - *save_data++ = FLASHRAM_ERASE_VALUE; + p.save_in_progress = true; + if (p.op != OP_ERASE_ALL) { + sdram_address += (FLASHRAM->SCR >> FLASHRAM_PAGE_BIT) * FLASHRAM_PAGE_SIZE; } + p.save_pointer = (io32_t *) (sdram_address); + p.num_words = get_operation_length(p.op) / sizeof(uint32_t); + p.current_word = 0; + } + } else { + if (p.op == OP_WRITE_PAGE) { + *p.save_pointer++ &= FLASHRAM->BUFFER[p.current_word]; + } else { + *p.save_pointer++ = FLASHRAM_ERASE_VALUE; } - FLASHRAM->SCR = FLASHRAM_OPERATION_DONE; + p.current_word += 1; + + if (p.current_word >= p.num_words) { + p.save_in_progress = false; + FLASHRAM->SCR = FLASHRAM_OPERATION_DONE; + } } } diff --git a/sw/riscv/src/process.c b/sw/riscv/src/process.c index 093ded3..4f7c2e3 100644 --- a/sw/riscv/src/process.c +++ b/sw/riscv/src/process.c @@ -9,7 +9,20 @@ #include "uart.h" -void process_init (void) { +static const void (*process_table[])(void) = { + process_usb, + process_cfg, + process_rtc, + process_i2c, + process_flashram, + process_uart, + NULL, +}; + + +__attribute__((naked)) void process_loop (void) { + void (**process_func)(void) = process_table; + usb_init(); cfg_init(); dma_init(); @@ -18,18 +31,12 @@ void process_init (void) { i2c_init(); flashram_init(); uart_init(); -} - -void process_loop (void) { while (1) { - process_usb(); - process_cfg(); - process_dma(); process_joybus(); - process_rtc(); - process_i2c(); - process_flashram(); - process_uart(); + (*process_func++)(); + if (*process_func == NULL) { + process_func = process_table; + } } } diff --git a/sw/riscv/src/startup.S b/sw/riscv/src/startup.S index 581e106..0eb3670 100644 --- a/sw/riscv/src/startup.S +++ b/sw/riscv/src/startup.S @@ -32,12 +32,9 @@ init_bss: blt a0, a1, 1b 2: -run: - call process_init - call process_loop - -loop: - j loop +run_in_ram: + la ra, process_loop + jalr zero, 0(ra) copy_section: bge a1, a2, 2f diff --git a/sw/riscv/src/sys.h b/sw/riscv/src/sys.h index c8f62e1..9b7db5b 100644 --- a/sw/riscv/src/sys.h +++ b/sw/riscv/src/sys.h @@ -185,8 +185,4 @@ typedef volatile struct joybus_regs { #define JOYBUS_SCR_TX_LENGTH_BIT (16) -void reset_handler (void); -void app_handler (void); - - #endif