From 7d6e2bc5ee8628b272fc3d6c06a0868034c2c156 Mon Sep 17 00:00:00 2001 From: Mateusz Faderewski Date: Sat, 13 Jan 2024 07:48:42 +0100 Subject: [PATCH] removed task subsystem + huge cleanup --- fw/rtl/n64/n64_si.sv | 2 +- sw/controller/app.ld | 2 +- sw/controller/app.mk | 2 - sw/controller/loader.ld | 2 +- sw/controller/primer.ld | 2 +- sw/controller/src/app.c | 64 ++-- sw/controller/src/app.h | 11 - sw/controller/src/button.c | 7 + sw/controller/src/button.h | 2 + sw/controller/src/cfg.c | 12 +- sw/controller/src/cfg.h | 2 + sw/controller/src/cic.c | 77 ++-- sw/controller/src/cic.h | 2 + sw/controller/src/dd.c | 23 +- sw/controller/src/dd.h | 2 + sw/controller/src/flashram.c | 7 +- sw/controller/src/flashram.h | 1 + sw/controller/src/fpga.c | 40 +-- sw/controller/src/gvr.c | 39 -- sw/controller/src/gvr.h | 8 - sw/controller/src/hw.c | 660 ++++++++++++---------------------- sw/controller/src/hw.h | 62 ++-- sw/controller/src/isv.c | 2 + sw/controller/src/isv.h | 2 + sw/controller/src/lcmxo2.c | 4 +- sw/controller/src/led.c | 233 ++++++------ sw/controller/src/led.h | 2 +- sw/controller/src/loader.c | 1 + sw/controller/src/primer.c | 5 +- sw/controller/src/rtc.c | 270 ++++++-------- sw/controller/src/rtc.h | 27 +- sw/controller/src/sd.c | 73 ++-- sw/controller/src/sd.h | 5 + sw/controller/src/task.c | 135 ------- sw/controller/src/task.h | 23 -- sw/controller/src/timer.c | 62 +++- sw/controller/src/timer.h | 11 +- sw/controller/src/update.c | 6 +- sw/controller/src/usb.c | 27 +- sw/controller/src/usb.h | 17 +- sw/controller/src/writeback.c | 35 +- sw/controller/src/writeback.h | 5 +- 42 files changed, 781 insertions(+), 1193 deletions(-) delete mode 100644 sw/controller/src/app.h delete mode 100644 sw/controller/src/gvr.c delete mode 100644 sw/controller/src/gvr.h delete mode 100644 sw/controller/src/task.c delete mode 100644 sw/controller/src/task.h diff --git a/fw/rtl/n64/n64_si.sv b/fw/rtl/n64/n64_si.sv index cbc7482..045211d 100644 --- a/fw/rtl/n64/n64_si.sv +++ b/fw/rtl/n64/n64_si.sv @@ -382,7 +382,7 @@ module n64_si ( 4'd1: {rtc_time_wp, rtc_backup_wp} <= rx_byte_data[1:0]; 4'd2: begin rtc_stopped <= rx_byte_data[2:1]; - if (rx_byte_data[2:1] == 2'b00) begin + if ((|rtc_stopped) && (rx_byte_data[2:1] == 2'b00)) begin n64_scb.rtc_pending <= 1'b1; end end diff --git a/sw/controller/app.ld b/sw/controller/app.ld index dbcb537..660776c 100644 --- a/sw/controller/app.ld +++ b/sw/controller/app.ld @@ -24,7 +24,7 @@ SECTIONS { .text : { . = ALIGN(4); *(.text) - *(.text*) + *(.text*) *(.glue_7) *(.glue_7t) . = ALIGN(4); diff --git a/sw/controller/app.mk b/sw/controller/app.mk index f3ae8b6..946da5a 100644 --- a/sw/controller/app.mk +++ b/sw/controller/app.mk @@ -14,14 +14,12 @@ SRC_FILES = \ flash.c \ flashram.c \ fpga.c \ - gvr.c \ hw.c \ isv.c \ lcmxo2.c \ led.c \ rtc.c \ sd.c \ - task.c \ timer.c \ update.c \ usb.c \ diff --git a/sw/controller/loader.ld b/sw/controller/loader.ld index 97f2f37..ffc1f64 100644 --- a/sw/controller/loader.ld +++ b/sw/controller/loader.ld @@ -23,7 +23,7 @@ SECTIONS { . = ALIGN(4); _stext = .; *(.text) - *(.text*) + *(.text*) *(.glue_7) *(.glue_7t) . = ALIGN(4); diff --git a/sw/controller/primer.ld b/sw/controller/primer.ld index 7225e46..98f7caf 100644 --- a/sw/controller/primer.ld +++ b/sw/controller/primer.ld @@ -16,7 +16,7 @@ SECTIONS { .text : { . = ALIGN(4); *(.text) - *(.text*) + *(.text*) *(.glue_7) *(.glue_7t) . = ALIGN(4); diff --git a/sw/controller/src/app.c b/sw/controller/src/app.c index 16be2f7..7f871f2 100644 --- a/sw/controller/src/app.c +++ b/sw/controller/src/app.c @@ -1,34 +1,46 @@ -#include "app.h" -#include "gvr.h" +#include "button.h" +#include "cfg.h" +#include "cic.h" +#include "dd.h" +#include "flashram.h" +#include "fpga.h" #include "hw.h" -#include "led.h" +#include "isv.h" #include "rtc.h" -#include "task.h" +#include "sd.h" +#include "timer.h" +#include "usb.h" +#include "writeback.h" -#define RTC_STACK_SIZE (256) -#define LED_STACK_SIZE (256) -#define GVR_STACK_SIZE (2048) - - -uint8_t rtc_stack[RTC_STACK_SIZE] __attribute__((aligned(8))); -uint8_t led_stack[LED_STACK_SIZE] __attribute__((aligned(8))); -uint8_t gvr_stack[GVR_STACK_SIZE] __attribute__((aligned(8))); - - -void app_get_stack_usage (uint32_t *usage) { - *usage++ = 0; - *usage++ = task_get_stack_usage(rtc_stack, RTC_STACK_SIZE); - *usage++ = task_get_stack_usage(led_stack, LED_STACK_SIZE); - *usage++ = task_get_stack_usage(gvr_stack, GVR_STACK_SIZE); -} - void app (void) { - hw_init(); + hw_app_init(); - task_create(TASK_ID_RTC, rtc_task, rtc_stack, RTC_STACK_SIZE); - task_create(TASK_ID_LED, led_task, led_stack, LED_STACK_SIZE); - task_create(TASK_ID_GVR, gvr_task, gvr_stack, GVR_STACK_SIZE); + timer_init(); + rtc_init(); - task_scheduler_start(); + while (fpga_id_get() != FPGA_ID); + + button_init(); + cfg_init(); + cic_init(); + dd_init(); + flashram_init(); + isv_init(); + sd_init(); + usb_init(); + writeback_init(); + + while (1) { + button_process(); + cfg_process(); + cic_process(); + dd_process(); + flashram_process(); + isv_process(); + rtc_process(); + sd_process(); + usb_process(); + writeback_process(); + } } diff --git a/sw/controller/src/app.h b/sw/controller/src/app.h deleted file mode 100644 index e0d24ca..0000000 --- a/sw/controller/src/app.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef APP_H__ -#define APP_H__ - - -#include - - -void app_get_stack_usage (uint32_t *usage); - - -#endif diff --git a/sw/controller/src/button.c b/sw/controller/src/button.c index 1c10b30..26f811f 100644 --- a/sw/controller/src/button.c +++ b/sw/controller/src/button.c @@ -39,6 +39,7 @@ button_mode_t button_get_mode (void) { return p.mode; } + void button_init (void) { p.counter = 0; p.state = false; @@ -46,9 +47,12 @@ void button_init (void) { p.trigger = false; } + void button_process (void) { usb_tx_info_t packet_info; + uint32_t status = fpga_reg_get(REG_CFG_SCR); + if (status & CFG_SCR_BUTTON_STATE) { if (p.counter < BUTTON_COUNTER_TRIGGER_ON) { p.counter += 1; @@ -58,13 +62,16 @@ void button_process (void) { p.counter -= 1; } } + if (!p.state && p.counter == BUTTON_COUNTER_TRIGGER_ON) { p.state = true; p.trigger = true; } + if (p.state && p.counter == BUTTON_COUNTER_TRIGGER_OFF) { p.state = false; } + if (p.trigger) { switch (p.mode) { case BUTTON_MODE_N64_IRQ: diff --git a/sw/controller/src/button.h b/sw/controller/src/button.h index 3c41913..69cb575 100644 --- a/sw/controller/src/button.h +++ b/sw/controller/src/button.h @@ -16,7 +16,9 @@ typedef enum { bool button_get_state (void); bool button_set_mode (button_mode_t mode); button_mode_t button_get_mode (void); + void button_init (void); + void button_process (void); diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index a962982..a2509b7 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -373,11 +373,11 @@ bool cfg_update (uint32_t *args) { } bool cfg_query_setting (uint32_t *args) { - rtc_settings_t settings = (*rtc_get_settings()); + rtc_settings_t *settings = rtc_get_settings(); switch (args[0]) { case SETTING_ID_LED_ENABLE: - args[1] = settings.led_enabled; + args[1] = settings->led_enabled; break; default: return true; @@ -387,17 +387,17 @@ bool cfg_query_setting (uint32_t *args) { } bool cfg_update_setting (uint32_t *args) { - rtc_settings_t settings = (*rtc_get_settings()); + rtc_settings_t *settings = rtc_get_settings(); switch (args[0]) { case SETTING_ID_LED_ENABLE: - settings.led_enabled = args[1]; + settings->led_enabled = args[1]; break; default: return true; } - rtc_set_settings(&settings); + rtc_save_settings(); return false; } @@ -450,12 +450,14 @@ void cfg_reset_state (void) { p.boot_mode = BOOT_MODE_MENU; } + void cfg_init (void) { fpga_reg_set(REG_CFG_SCR, CFG_SCR_BOOTLOADER_ENABLED); cfg_reset_state(); p.usb_output_ready = true; } + void cfg_process (void) { uint32_t reg; uint32_t args[2]; diff --git a/sw/controller/src/cfg.h b/sw/controller/src/cfg.h index bc3611c..82038c5 100644 --- a/sw/controller/src/cfg.h +++ b/sw/controller/src/cfg.h @@ -27,7 +27,9 @@ save_type_t cfg_get_save_type (void); void cfg_get_time (uint32_t *args); void cfg_set_time (uint32_t *args); void cfg_reset_state (void); + void cfg_init (void); + void cfg_process (void); diff --git a/sw/controller/src/cic.c b/sw/controller/src/cic.c index d67ac5d..a184485 100644 --- a/sw/controller/src/cic.c +++ b/sw/controller/src/cic.c @@ -12,12 +12,7 @@ typedef enum { } cic_region_t; -static bool cic_initialized = false; - - -static void cic_irq_reset_falling (void) { - led_clear_error(LED_ERROR_CIC); -} +static bool cic_error_active = false; void cic_reset_parameters (void) { @@ -26,72 +21,70 @@ void cic_reset_parameters (void) { const uint8_t default_seed = 0x3F; const uint64_t default_checksum = 0xA536C0F1D859ULL; - uint32_t cic_config_0 = (default_seed << CIC_SEED_BIT) | ((default_checksum >> 32) & 0xFFFF); - uint32_t cic_config_1 = (default_checksum & 0xFFFFFFFFUL); + uint32_t cfg[2] = { + (default_seed << CIC_SEED_BIT) | ((default_checksum >> 32) & 0xFFFF), + (default_checksum & 0xFFFFFFFFUL) + }; if (region == REGION_PAL) { - cic_config_0 |= CIC_REGION; + cfg[0] |= CIC_REGION; } - - fpga_reg_set(REG_CIC_0, cic_config_0); - fpga_reg_set(REG_CIC_1, cic_config_1); + + fpga_reg_set(REG_CIC_0, cfg[0]); + fpga_reg_set(REG_CIC_1, cfg[1]); } void cic_set_parameters (uint32_t *args) { - uint32_t cic_config_0 = args[0] & (0x00FFFFFF); - uint32_t cic_config_1 = args[1]; + uint32_t cfg[2] = { + args[0] & (0x00FFFFFF), + args[1] + }; - cic_config_0 |= fpga_reg_get(REG_CIC_0) & (CIC_64DD_MODE | CIC_REGION); + cfg[0] |= fpga_reg_get(REG_CIC_0) & (CIC_64DD_MODE | CIC_REGION); if (args[0] & (1 << 24)) { - cic_config_0 |= CIC_DISABLED; + cfg[0] |= CIC_DISABLED; } - fpga_reg_set(REG_CIC_0, cic_config_0); - fpga_reg_set(REG_CIC_1, cic_config_1); + fpga_reg_set(REG_CIC_0, cfg[0]); + fpga_reg_set(REG_CIC_1, cfg[1]); } void cic_set_dd_mode (bool enabled) { - uint32_t cic_config_0 = fpga_reg_get(REG_CIC_0); + uint32_t cfg = fpga_reg_get(REG_CIC_0); if (enabled) { - cic_config_0 |= CIC_64DD_MODE; + cfg |= CIC_64DD_MODE; } else { - cic_config_0 &= ~(CIC_64DD_MODE); + cfg &= ~(CIC_64DD_MODE); } - fpga_reg_set(REG_CIC_0, cic_config_0); + fpga_reg_set(REG_CIC_0, cfg); } void cic_init (void) { - hw_gpio_irq_setup(GPIO_ID_N64_RESET, GPIO_IRQ_FALLING, cic_irq_reset_falling); + cic_reset_parameters(); } void cic_process (void) { - if (!cic_initialized) { - if (rtc_is_initialized()) { - cic_reset_parameters(); - cic_initialized = true; - } else { - return; - } - } + uint32_t cfg = fpga_reg_get(REG_CIC_0); - uint32_t cic_config_0 = fpga_reg_get(REG_CIC_0); + if (cfg & CIC_INVALID_REGION_DETECTED) { + cfg ^= CIC_REGION; + cfg |= CIC_INVALID_REGION_RESET; + fpga_reg_set(REG_CIC_0, cfg); - if (cic_config_0 & CIC_INVALID_REGION_DETECTED) { - cic_config_0 ^= CIC_REGION; - cic_config_0 |= CIC_INVALID_REGION_RESET; - fpga_reg_set(REG_CIC_0, cic_config_0); - - if (cic_config_0 & CIC_REGION) { - rtc_set_region(REGION_PAL); - } else { - rtc_set_region(REGION_NTSC); - } + cic_region_t region = (cfg & CIC_REGION) ? REGION_PAL : REGION_NTSC; + rtc_set_region(region); + cic_error_active = true; led_blink_error(LED_ERROR_CIC); } + + if (cic_error_active && (!hw_gpio_get(GPIO_ID_N64_RESET))) { + cic_error_active = false; + led_clear_error(LED_ERROR_CIC); + } } diff --git a/sw/controller/src/cic.h b/sw/controller/src/cic.h index 56f006e..6702560 100644 --- a/sw/controller/src/cic.h +++ b/sw/controller/src/cic.h @@ -9,7 +9,9 @@ void cic_reset_parameters (void); void cic_set_parameters (uint32_t *args); void cic_set_dd_mode (bool enabled); + void cic_init (void); + void cic_process (void); diff --git a/sw/controller/src/dd.c b/sw/controller/src/dd.c index 9db7bb3..d28babb 100644 --- a/sw/controller/src/dd.c +++ b/sw/controller/src/dd.c @@ -1,10 +1,9 @@ -#include #include "dd.h" #include "fpga.h" -#include "hw.h" #include "led.h" #include "rtc.h" #include "sd.h" +#include "timer.h" #include "usb.h" @@ -20,7 +19,7 @@ #define DD_DRIVE_ID_DEVELOPMENT (0x0004) #define DD_VERSION_RETAIL (0x0114) -#define DD_SPIN_UP_TIME (2000) +#define DD_SPIN_UP_TIME_MS (2000) #define DD_THB_UNMAPPED (0xFFFFFFFF) #define DD_THB_WRITABLE_FLAG (1 << 31) @@ -75,7 +74,6 @@ struct process { rtc_time_t time; bool disk_spinning; bool cmd_response_delayed; - bool cmd_response_ready; bool bm_running; bool transfer_mode; bool full_track_transfer; @@ -178,10 +176,6 @@ static bool dd_block_write_request (void) { return true; } -static void dd_set_cmd_response_ready (void) { - p.cmd_response_ready = true; -} - void dd_set_block_ready (bool valid) { p.block_ready = true; @@ -284,13 +278,13 @@ void dd_handle_button (void) { } } + void dd_init (void) { fpga_reg_set(REG_DD_SCR, 0); fpga_reg_set(REG_DD_HEAD_TRACK, 0); fpga_reg_set(REG_DD_DRIVE_ID, DD_DRIVE_ID_RETAIL); p.state = STATE_IDLE; p.cmd_response_delayed = false; - p.cmd_response_ready = false; p.disk_spinning = false; p.bm_running = false; p.drive_type = DD_DRIVE_TYPE_RETAIL; @@ -299,6 +293,7 @@ void dd_init (void) { dd_set_disk_mapping(0, 0); } + void dd_process (void) { uint32_t starting_scr = fpga_reg_get(REG_DD_SCR); uint32_t scr = starting_scr; @@ -306,7 +301,6 @@ void dd_process (void) { if (scr & DD_SCR_HARD_RESET) { p.state = STATE_IDLE; p.cmd_response_delayed = false; - p.cmd_response_ready = false; p.disk_spinning = false; p.bm_running = false; p.head_track = 0; @@ -319,19 +313,16 @@ void dd_process (void) { uint16_t data = cmd_data & 0xFFFF; if (p.cmd_response_delayed) { - if (p.cmd_response_ready) { + if (timer_countdown_elapsed(TIMER_ID_DD)) { p.cmd_response_delayed = false; fpga_reg_set(REG_DD_HEAD_TRACK, DD_HEAD_TRACK_INDEX_LOCK | data); scr |= DD_SCR_CMD_READY; } } else if ((cmd == DD_CMD_SEEK_READ) || (cmd == DD_CMD_SEEK_WRITE)) { p.cmd_response_delayed = true; - p.cmd_response_ready = false; if (!p.disk_spinning) { p.disk_spinning = true; - hw_tim_setup(TIM_ID_DD, DD_SPIN_UP_TIME, dd_set_cmd_response_ready); - } else { - p.cmd_response_ready = true; + timer_countdown_start(TIMER_ID_DD, DD_SPIN_UP_TIME_MS); } fpga_reg_set(REG_DD_HEAD_TRACK, p.head_track & ~(DD_HEAD_TRACK_INDEX_LOCK)); p.head_track = data & DD_HEAD_TRACK_MASK; @@ -397,7 +388,7 @@ void dd_process (void) { fpga_reg_set(REG_DD_CMD_DATA, data); scr |= DD_SCR_CMD_READY; } - } + } if (scr & DD_SCR_BM_STOP) { scr |= DD_SCR_BM_STOP_CLEAR; diff --git a/sw/controller/src/dd.h b/sw/controller/src/dd.h index cdd84fd..4c8b1b0 100644 --- a/sw/controller/src/dd.h +++ b/sw/controller/src/dd.h @@ -27,7 +27,9 @@ bool dd_get_sd_mode (void); void dd_set_sd_mode (bool value); void dd_set_disk_mapping (uint32_t address, uint32_t length); void dd_handle_button (void); + void dd_init (void); + void dd_process (void); diff --git a/sw/controller/src/flashram.c b/sw/controller/src/flashram.c index 4869a44..50acd79 100644 --- a/sw/controller/src/flashram.c +++ b/sw/controller/src/flashram.c @@ -40,10 +40,11 @@ void flashram_init (void) { } } + void flashram_process (void) { uint32_t scr = fpga_reg_get(REG_FLASHRAM_SCR); enum operation op = flashram_operation_type(scr); - uint8_t read_buffer[FLASHRAM_PAGE_SIZE]; + uint8_t page_buffer[FLASHRAM_PAGE_SIZE]; uint8_t write_buffer[FLASHRAM_PAGE_SIZE]; uint32_t address = FLASHRAM_ADDRESS; uint32_t erase_size = (op == OP_ERASE_SECTOR) ? FLASHRAM_SECTOR_SIZE : FLASHRAM_SIZE; @@ -63,10 +64,10 @@ void flashram_process (void) { break; case OP_WRITE_PAGE: - fpga_mem_read(FLASHRAM_BUFFER_ADDRESS, FLASHRAM_PAGE_SIZE, read_buffer); + fpga_mem_read(FLASHRAM_BUFFER_ADDRESS, FLASHRAM_PAGE_SIZE, page_buffer); fpga_mem_read(address, FLASHRAM_PAGE_SIZE, write_buffer); for (int i = 0; i < FLASHRAM_PAGE_SIZE; i++) { - write_buffer[i] &= read_buffer[i]; + write_buffer[i] &= page_buffer[i]; } fpga_mem_write(address, FLASHRAM_PAGE_SIZE, write_buffer); fpga_reg_set(REG_FLASHRAM_SCR, FLASHRAM_SCR_DONE); diff --git a/sw/controller/src/flashram.h b/sw/controller/src/flashram.h index 4fdb24d..d1dbfe0 100644 --- a/sw/controller/src/flashram.h +++ b/sw/controller/src/flashram.h @@ -3,6 +3,7 @@ void flashram_init (void); + void flashram_process (void); diff --git a/sw/controller/src/fpga.c b/sw/controller/src/fpga.c index 9edf7c6..2dc0671 100644 --- a/sw/controller/src/fpga.c +++ b/sw/controller/src/fpga.c @@ -7,8 +7,8 @@ uint8_t fpga_id_get (void) { uint8_t id; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&id, 1, SPI_RX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_rx(&id, 1); hw_spi_stop(); return id; @@ -19,9 +19,9 @@ uint32_t fpga_reg_get (fpga_reg_t reg) { uint32_t value; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(®, 1, SPI_TX); - hw_spi_trx((uint8_t *) (&value), 4, SPI_RX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_tx(®, 1); + hw_spi_rx((uint8_t *) (&value), 4); hw_spi_stop(); return value; @@ -31,9 +31,9 @@ void fpga_reg_set (fpga_reg_t reg, uint32_t value) { fpga_cmd_t cmd = CMD_REG_WRITE; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(®, 1, SPI_TX); - hw_spi_trx((uint8_t *) (&value), 4, SPI_TX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_tx(®, 1); + hw_spi_tx((uint8_t *) (&value), 4); hw_spi_stop(); } @@ -50,9 +50,9 @@ void fpga_mem_read (uint32_t address, size_t length, uint8_t *buffer) { while (fpga_reg_get(REG_MEM_SCR) & MEM_SCR_BUSY); hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&buffer_address, 1, SPI_TX); - hw_spi_trx(buffer, length, SPI_RX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_tx(&buffer_address, 1); + hw_spi_rx(buffer, length); hw_spi_stop(); } @@ -65,9 +65,9 @@ void fpga_mem_write (uint32_t address, size_t length, uint8_t *buffer) { } hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&buffer_address, 1, SPI_TX); - hw_spi_trx(buffer, length, SPI_TX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_tx(&buffer_address, 1); + hw_spi_tx(buffer, length); hw_spi_stop(); fpga_reg_set(REG_MEM_ADDRESS, address); @@ -95,8 +95,8 @@ uint8_t fpga_usb_status_get (void) { uint8_t status; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&status, 1, SPI_RX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_rx(&status, 1); hw_spi_stop(); return status; @@ -107,8 +107,8 @@ uint8_t fpga_usb_pop (void) { uint8_t data; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&data, 1, SPI_RX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_rx(&data, 1); hw_spi_stop(); return data; @@ -118,7 +118,7 @@ void fpga_usb_push (uint8_t data) { fpga_cmd_t cmd = CMD_USB_WRITE; hw_spi_start(); - hw_spi_trx((uint8_t *) (&cmd), 1, SPI_TX); - hw_spi_trx(&data, 1, SPI_TX); + hw_spi_tx((uint8_t *) (&cmd), 1); + hw_spi_tx(&data, 1); hw_spi_stop(); } diff --git a/sw/controller/src/gvr.c b/sw/controller/src/gvr.c deleted file mode 100644 index 70c7909..0000000 --- a/sw/controller/src/gvr.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "button.h" -#include "cfg.h" -#include "cic.h" -#include "dd.h" -#include "flashram.h" -#include "fpga.h" -#include "isv.h" -#include "rtc.h" -#include "sd.h" -#include "usb.h" -#include "writeback.h" - - -void gvr_task (void) { - while (fpga_id_get() != FPGA_ID); - - button_init(); - cfg_init(); - cic_init(); - dd_init(); - flashram_init(); - isv_init(); - sd_init(); - usb_init(); - writeback_init(); - - while (1) { - button_process(); - cfg_process(); - cic_process(); - dd_process(); - flashram_process(); - isv_process(); - rtc_process(); - sd_process(); - usb_process(); - writeback_process(); - } -} diff --git a/sw/controller/src/gvr.h b/sw/controller/src/gvr.h deleted file mode 100644 index 2a782d1..0000000 --- a/sw/controller/src/gvr.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef GVR_H__ -#define GVR_H__ - - -void gvr_task (void); - - -#endif diff --git a/sw/controller/src/hw.c b/sw/controller/src/hw.c index 6b7af28..b9adcf8 100644 --- a/sw/controller/src/hw.c +++ b/sw/controller/src/hw.c @@ -3,7 +3,70 @@ #include "hw.h" -#define UART_BAUD (115200) +#define CPU_FREQ (64000000UL) +#define UART_BAUD (115200UL) + + +void hw_set_vector_table (uint32_t offset) { + SCB->VTOR = (__IOM uint32_t) (offset); +} + + +void hw_enter_critical (void) { + __disable_irq(); +} + +void hw_exit_critical (void) { + __enable_irq(); +} + + +static void hw_clock_init (void) { + FLASH->ACR |= (FLASH_ACR_PRFTEN | (2 << FLASH_ACR_LATENCY_Pos)); + while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != (2 << FLASH_ACR_LATENCY_Pos)); + + RCC->PLLCFGR = ( + ((2 - 1) << RCC_PLLCFGR_PLLR_Pos) + | RCC_PLLCFGR_PLLREN + | (16 << RCC_PLLCFGR_PLLN_Pos) + | ((2 - 1) << RCC_PLLCFGR_PLLM_Pos) + | RCC_PLLCFGR_PLLSRC_HSI + ); + + RCC->CR |= RCC_CR_PLLON; + while ((RCC->CR & RCC_CR_PLLRDY_Msk) != RCC_CR_PLLRDY); + + RCC->CFGR = RCC_CFGR_SW_1; + while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1); +} + + +static void hw_delay_init (void) { + SysTick->LOAD = (((CPU_FREQ / 1000)) - 1); + SysTick->VAL = 0; + SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk); +} + +void hw_delay_ms (uint32_t ms) { + SysTick->VAL = 0; + for (uint32_t i = 0; i < ms; i++) { + while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + } +} + + +static void (*systick_callback) (void) = NULL; + +void hw_systick_config (uint32_t period_ms, void (*callback) (void)) { + SysTick_Config((CPU_FREQ / 1000) * period_ms); + systick_callback = callback; +} + +void SysTick_Handler (void) { + if (systick_callback) { + systick_callback(); + } +} typedef enum { @@ -42,22 +105,7 @@ typedef enum { GPIO_AF_7 = 0x07 } gpio_af_t; - -typedef struct { - void (*volatile falling)(void); - void (*volatile rising)(void); -} gpio_irq_callback_t; - - static const GPIO_TypeDef *gpios[] = { GPIOA, GPIOB, 0, 0, 0, 0, 0, 0 }; -static gpio_irq_callback_t gpio_irq_callbacks[16]; -static volatile uint8_t *i2c_data_txptr; -static volatile uint8_t *i2c_data_rxptr; -static volatile uint32_t i2c_next_cr2; -static void (*volatile i2c_callback)(void); -static const TIM_TypeDef *tims[] = { TIM14, TIM16, TIM17, TIM3, TIM1 }; -static void (*volatile tim_callbacks[5])(void); - static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_ospeed_t ospeed, gpio_pupd_t pupd, gpio_af_t af, int value) { GPIO_TypeDef tmp; @@ -65,6 +113,8 @@ static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_osp uint8_t pin = (id & 0x0F); uint8_t afr = ((pin < 8) ? 0 : 1); + RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN; + tmp.MODER = (gpio->MODER & ~(GPIO_MODER_MODE0_Msk << (pin * 2))); tmp.OTYPER = (gpio->OTYPER & ~(GPIO_OTYPER_OT0_Msk << pin)); tmp.OSPEEDR = (gpio->OSPEEDR & ~(GPIO_OSPEEDR_OSPEED0_Msk << (pin * 2))); @@ -80,22 +130,6 @@ static void hw_gpio_init (gpio_id_t id, gpio_mode_t mode, gpio_ot_t ot, gpio_osp gpio->MODER = (tmp.MODER | (mode << (pin * 2))); } -void hw_gpio_irq_setup (gpio_id_t id, gpio_irq_t irq, void (*callback)(void)) { - uint8_t port = ((id >> 4) & 0x07); - uint8_t pin = (id & 0x0F); - __disable_irq(); - if (irq == GPIO_IRQ_FALLING) { - EXTI->FTSR1 |= (EXTI_FTSR1_FT0 << pin); - gpio_irq_callbacks[pin].falling = callback; - } else { - EXTI->RTSR1 |= (EXTI_RTSR1_RT0 << pin); - gpio_irq_callbacks[pin].rising = callback; - } - EXTI->EXTICR[pin / 4] |= (port << (8 * (pin % 4))); - EXTI->IMR1 |= (EXTI_IMR1_IM0 << pin); - __enable_irq(); -} - uint32_t hw_gpio_get (gpio_id_t id) { GPIO_TypeDef *gpio = ((GPIO_TypeDef *) (gpios[(id >> 4) & 0x07])); uint8_t pin = (id & 0x0F); @@ -114,6 +148,20 @@ void hw_gpio_reset (gpio_id_t id) { gpio->BSRR = (GPIO_BSRR_BR0 << pin); } + +static void hw_uart_init (void) { + RCC->APBENR2 |= (RCC_APBENR2_USART1EN | RCC_APBENR2_SYSCFGEN); + + SYSCFG->CFGR1 |= (SYSCFG_CFGR1_PA12_RMP | SYSCFG_CFGR1_PA11_RMP); + + hw_gpio_init(GPIO_ID_UART_TX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_UP, GPIO_AF_1, 0); + hw_gpio_init(GPIO_ID_UART_RX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_UP, GPIO_AF_1, 0); + + USART1->BRR = CPU_FREQ / UART_BAUD; + USART1->RQR = USART_RQR_TXFRQ | USART_RQR_RXFRQ; + USART1->CR1 = USART_CR1_FIFOEN | USART_CR1_M0 | USART_CR1_PCE | USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; +} + void hw_uart_read (uint8_t *data, int length) { for (int i = 0; i < length; i++) { while (!(USART1->ISR & USART_ISR_RXNE_RXFNE)); @@ -128,10 +176,42 @@ void hw_uart_write (uint8_t *data, int length) { } } -void hw_uart_wait_busy (void) { +void hw_uart_write_wait_busy (void) { while (!(USART1->ISR & USART_ISR_TC)); } + +static void hw_spi_init (void) { + RCC->AHBENR |= RCC_AHBENR_DMA1EN; + RCC->APBENR2 |= RCC_APBENR2_SPI1EN; + + DMAMUX1_Channel0->CCR = (16 << DMAMUX_CxCR_DMAREQ_ID_Pos); + DMAMUX1_Channel1->CCR = (17 << DMAMUX_CxCR_DMAREQ_ID_Pos); + + DMA1_Channel1->CPAR = (uint32_t) (&SPI1->DR); + DMA1_Channel2->CPAR = (uint32_t) (&SPI1->DR); + + SPI1->CR2 = ( + SPI_CR2_FRXTH | + (8 - 1) << SPI_CR2_DS_Pos | + SPI_CR2_TXDMAEN | + SPI_CR2_RXDMAEN + ); + SPI1->CR1 = ( + SPI_CR1_SSM | + SPI_CR1_SSI | + SPI_CR1_BR_1 | + SPI_CR1_SPE | + SPI_CR1_MSTR | + SPI_CR1_CPHA + ); + + hw_gpio_init(GPIO_ID_SPI_CS, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 1); + hw_gpio_init(GPIO_ID_SPI_CLK, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0); + hw_gpio_init(GPIO_ID_SPI_MOSI, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0); + hw_gpio_init(GPIO_ID_SPI_MISO, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_DOWN, GPIO_AF_0, 0); +} + void hw_spi_start (void) { hw_gpio_reset(GPIO_ID_SPI_CS); } @@ -141,83 +221,87 @@ void hw_spi_stop (void) { hw_gpio_set(GPIO_ID_SPI_CS); } -void hw_spi_trx (uint8_t *data, int length, spi_direction_t direction) { +void hw_spi_rx (uint8_t *data, int length) { + volatile uint8_t dummy = 0x00; + + DMA1_Channel1->CNDTR = length; + DMA1_Channel2->CNDTR = length; + + DMA1_Channel1->CMAR = (uint32_t) (data); + DMA1_Channel1->CCR = (DMA_CCR_MINC | DMA_CCR_EN); + + DMA1_Channel2->CMAR = (uint32_t) (&dummy); + DMA1_Channel2->CCR = (DMA_CCR_DIR | DMA_CCR_EN); + + while (DMA1_Channel1->CNDTR || DMA1_Channel2->CNDTR); + + DMA1_Channel1->CCR = 0; + DMA1_Channel2->CCR = 0; +} + +void hw_spi_tx (uint8_t *data, int length) { volatile uint8_t dummy __attribute__((unused)); DMA1_Channel1->CNDTR = length; DMA1_Channel2->CNDTR = length; - if (direction == SPI_TX) { - DMA1_Channel1->CMAR = (uint32_t) (&dummy); - DMA1_Channel1->CCR = DMA_CCR_EN; + DMA1_Channel1->CMAR = (uint32_t) (&dummy); + DMA1_Channel1->CCR = DMA_CCR_EN; - DMA1_Channel2->CMAR = (uint32_t) (data); - DMA1_Channel2->CCR = (DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_EN); - } else { - DMA1_Channel1->CMAR = (uint32_t) (data); - DMA1_Channel1->CCR = (DMA_CCR_MINC | DMA_CCR_EN); - - DMA1_Channel2->CMAR = (uint32_t) (&dummy); - DMA1_Channel2->CCR = (DMA_CCR_DIR | DMA_CCR_EN); - } + DMA1_Channel2->CMAR = (uint32_t) (data); + DMA1_Channel2->CCR = (DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_EN); while (DMA1_Channel1->CNDTR || DMA1_Channel2->CNDTR); - DMA1_Channel1->CCR = 0; + DMA1_Channel1->CCR = 0; DMA1_Channel2->CCR = 0; } -void hw_i2c_read (uint8_t i2c_address, uint8_t address, uint8_t *data, uint8_t length, void (*callback)(void)) { - i2c_data_rxptr = data; - i2c_callback = callback; - I2C1->TXDR = address; - i2c_next_cr2 = ( - I2C_CR2_AUTOEND | - (length << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | - I2C_CR2_RD_WRN | - (i2c_address << I2C_CR2_SADD_Pos) - ); - I2C1->CR2 = ( - (1 << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | - (i2c_address << I2C_CR2_SADD_Pos) - ); + +static void hw_i2c_init (void) { + RCC->APBENR1 |= RCC_APBENR1_I2C1EN; + + I2C1->CR1 &= ~(I2C_CR1_PE); + I2C1->TIMINGR = 0x10901032UL; + I2C1->CR1 |= I2C_CR1_PE; + + hw_gpio_init(GPIO_ID_I2C_SCL, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0); + hw_gpio_init(GPIO_ID_I2C_SDA, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0); } -void hw_i2c_write (uint8_t i2c_address, uint8_t address, uint8_t *data, uint8_t length, void (*callback)(void)) { - i2c_data_txptr = data; - i2c_callback = callback; - I2C1->TXDR = address; - I2C1->CR2 = ( - I2C_CR2_AUTOEND | - ((length + 1) << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | - (i2c_address << I2C_CR2_SADD_Pos) - ); -} - -uint32_t hw_i2c_get_error (void) { - return (I2C1->ISR & I2C_ISR_NACKF); -} - -void hw_i2c_raw (uint8_t i2c_address, uint8_t *tx_data, uint8_t tx_length, uint8_t *rx_data, uint8_t rx_length) { +i2c_err_t hw_i2c_trx (uint8_t address, uint8_t *tx_data, uint8_t tx_length, uint8_t *rx_data, uint8_t rx_length) { while (I2C1->ISR & I2C_ISR_BUSY); if (tx_length > 0) { I2C1->ICR = I2C_ICR_NACKCF; I2C1->CR2 = ( - ((rx_length == 0) ? I2C_CR2_AUTOEND : 0) | + ((rx_length > 0) ? 0 : I2C_CR2_AUTOEND) | (tx_length << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | - (i2c_address << I2C_CR2_SADD_Pos) + (address << I2C_CR2_SADD_Pos) ); - for (int i = 0; i < tx_length; i++) { - while (!(I2C1->ISR & I2C_ISR_TXIS)); - I2C1->TXDR = *tx_data++; + I2C1->CR2 |= I2C_CR2_START; + + uint8_t left = tx_length; + + while (left > 0) { + uint32_t isr = I2C1->ISR; + + if (isr & I2C_ISR_TXIS) { + I2C1->TXDR = *tx_data++; + left -= 1; + } + + if (isr & I2C_ISR_NACKF) { + return I2C_ERR_NACK; + } } - if (!(I2C1->CR2 & I2C_CR2_AUTOEND)) { - while (!(I2C1->ISR & (I2C_ISR_NACKF | I2C_ISR_TC))); + + if (rx_length == 0) { + return I2C_OK; + } + + if (left == 0) { + while (!(I2C1->ISR & I2C_ISR_TC)); } } @@ -225,102 +309,31 @@ void hw_i2c_raw (uint8_t i2c_address, uint8_t *tx_data, uint8_t tx_length, uint8 I2C1->CR2 = ( I2C_CR2_AUTOEND | (rx_length << I2C_CR2_NBYTES_Pos) | - I2C_CR2_START | I2C_CR2_RD_WRN | - (i2c_address << I2C_CR2_SADD_Pos) + (address << I2C_CR2_SADD_Pos) ); - for (int i = 0; i < rx_length; i++) { - while (!(I2C1->ISR & I2C_ISR_RXNE)); - *rx_data++ = I2C1->RXDR; + I2C1->CR2 |= I2C_CR2_START; + + uint8_t left = rx_length; + + while (left > 0) { + uint32_t isr = I2C1->ISR; + + if (isr & I2C_ISR_RXNE) { + *rx_data++ = I2C1->RXDR; + left -= 1; + } } } - if ((tx_length > 0) || (rx_length > 0)) { - while (!(I2C1->ISR & I2C_ISR_STOPF)); - } + return I2C_OK; } -void hw_i2c_disable_irq (void) { - NVIC_DisableIRQ(I2C1_IRQn); -} -void hw_i2c_enable_irq (void) { - NVIC_EnableIRQ(I2C1_IRQn); -} +static void hw_crc32_init (void) { + RCC->AHBENR |= RCC_AHBENR_CRCEN; -void hw_tim_setup (tim_id_t id, uint16_t delay, void (*callback)(void)) { - if (delay == 0) { - if (callback) { - callback(); - } - return; - } - TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id])); - tim->CR1 = (TIM_CR1_OPM | TIM_CR1_URS); - tim->PSC = (64000 - 1); - tim->ARR = delay; - tim->DIER = TIM_DIER_UIE; - tim->EGR = TIM_EGR_UG; - tim->SR = 0; - tim->CR1 |= TIM_CR1_CEN; - tim_callbacks[id] = callback; -} - -void hw_tim_stop (tim_id_t id) { - TIM_TypeDef *tim = ((TIM_TypeDef *) (tims[id])); - tim->CR1 &= ~(TIM_CR1_CEN); - tim_callbacks[id] = 0; -} - -void hw_tim_disable_irq (tim_id_t id) { - switch (id) { - case TIM_ID_CIC: - NVIC_DisableIRQ(TIM14_IRQn); - break; - case TIM_ID_RTC: - NVIC_DisableIRQ(TIM16_IRQn); - break; - case TIM_ID_SD: - NVIC_DisableIRQ(TIM17_IRQn); - break; - case TIM_ID_DD: - NVIC_DisableIRQ(TIM3_IRQn); - break; - case TIM_ID_LED: - NVIC_DisableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); - break; - default: - break; - } -} - -void hw_tim_enable_irq (tim_id_t id) { - switch (id) { - case TIM_ID_CIC: - NVIC_EnableIRQ(TIM14_IRQn); - break; - case TIM_ID_RTC: - NVIC_EnableIRQ(TIM16_IRQn); - break; - case TIM_ID_SD: - NVIC_EnableIRQ(TIM17_IRQn); - break; - case TIM_ID_DD: - NVIC_EnableIRQ(TIM3_IRQn); - break; - case TIM_ID_LED: - NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); - break; - default: - break; - } -} - -void hw_delay_ms (uint32_t ms) { - SysTick->VAL = 0; - for (uint32_t i = 0; i < ms; i++) { - while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); - } + CRC->CR = (CRC_CR_REV_OUT | CRC_CR_REV_IN_0); } void hw_crc32_reset (void) { @@ -334,10 +347,15 @@ uint32_t hw_crc32_calculate (uint8_t *data, uint32_t length) { return (CRC->DR ^ 0xFFFFFFFF); } + uint32_t hw_flash_size (void) { return FLASH_SIZE; } +hw_flash_t hw_flash_read (uint32_t offset) { + return *(uint64_t *) (FLASH_BASE + offset); +} + static void hw_flash_unlock (void) { while (FLASH->SR & FLASH_SR_BSY1); if (FLASH->CR & FLASH_CR_LOCK) { @@ -363,9 +381,6 @@ void hw_flash_program (uint32_t offset, hw_flash_t value) { FLASH->CR &= ~(FLASH_CR_PG); } -hw_flash_t hw_flash_read (uint32_t offset) { - return *(uint64_t *) (FLASH_BASE + offset); -} void hw_reset (loader_parameters_t *parameters) { if (parameters != NULL) { @@ -382,6 +397,7 @@ void hw_reset (loader_parameters_t *parameters) { NVIC_SystemReset(); } + void hw_loader_get_parameters (loader_parameters_t *parameters) { RCC->APBENR1 |= RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN; parameters->magic = TAMP->BKP0R; @@ -399,280 +415,44 @@ void hw_loader_get_parameters (loader_parameters_t *parameters) { RCC->APBENR1 &= ~(RCC_APBENR1_PWREN | RCC_APBENR1_RTCAPBEN); } -static void hw_init_mcu (void) { - FLASH->ACR |= (FLASH_ACR_PRFTEN | (2 << FLASH_ACR_LATENCY_Pos)); - while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != (2 << FLASH_ACR_LATENCY_Pos)); - - RCC->PLLCFGR = ( - ((2 - 1) << RCC_PLLCFGR_PLLR_Pos) - | RCC_PLLCFGR_PLLREN - | (16 << RCC_PLLCFGR_PLLN_Pos) - | ((2 - 1) << RCC_PLLCFGR_PLLM_Pos) - | RCC_PLLCFGR_PLLSRC_HSI - ); - - RCC->CR |= RCC_CR_PLLON; - while ((RCC->CR & RCC_CR_PLLRDY_Msk) != RCC_CR_PLLRDY); - - RCC->CFGR = RCC_CFGR_SW_1; - while ((RCC->CFGR & RCC_CFGR_SWS_Msk) != RCC_CFGR_SWS_1); - - RCC->IOPENR |= RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN; - - SysTick->LOAD = (((64000000 / 1000)) - 1); - SysTick->VAL = 0; - SysTick->CTRL = (SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk); +static void hw_led_init (void) { hw_gpio_init(GPIO_ID_LED, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_0, 0); } -static void hw_init_spi (void) { - RCC->AHBENR |= RCC_AHBENR_DMA1EN; - RCC->APBENR2 |= RCC_APBENR2_SPI1EN; - DMAMUX1_Channel0->CCR = (16 << DMAMUX_CxCR_DMAREQ_ID_Pos); - DMAMUX1_Channel1->CCR = (17 << DMAMUX_CxCR_DMAREQ_ID_Pos); - - DMA1_Channel1->CPAR = (uint32_t) (&SPI1->DR); - DMA1_Channel2->CPAR = (uint32_t) (&SPI1->DR); - - SPI1->CR2 = ( - SPI_CR2_FRXTH | - (8 - 1) << SPI_CR2_DS_Pos | - SPI_CR2_TXDMAEN | - SPI_CR2_RXDMAEN - ); - SPI1->CR1 = ( - SPI_CR1_SSM | - SPI_CR1_SSI | - SPI_CR1_BR_1 | - SPI_CR1_SPE | - SPI_CR1_MSTR | - SPI_CR1_CPHA - ); - - hw_gpio_init(GPIO_ID_SPI_CS, GPIO_OUTPUT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 1); - hw_gpio_init(GPIO_ID_SPI_CLK, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0); - hw_gpio_init(GPIO_ID_SPI_MISO, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_DOWN, GPIO_AF_0, 0); - hw_gpio_init(GPIO_ID_SPI_MOSI, GPIO_ALT, GPIO_PP, GPIO_SPEED_HIGH, GPIO_PULL_NONE, GPIO_AF_0, 0); -} - -static void hw_init_i2c (void) { - RCC->APBENR1 |= RCC_APBENR1_I2C1EN; - - I2C1->TIMINGR = 0x80821B20UL; - I2C1->CR1 |= (I2C_CR1_TCIE | I2C_CR1_STOPIE | I2C_CR1_RXIE | I2C_CR1_TXIE | I2C_CR1_PE); - - hw_gpio_init(GPIO_ID_I2C_SCL, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0); - hw_gpio_init(GPIO_ID_I2C_SDA, GPIO_ALT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_NONE, GPIO_AF_6, 0); -} - -static void hw_init_uart (void) { - RCC->APBENR2 |= (RCC_APBENR2_USART1EN | RCC_APBENR2_SYSCFGEN); - - SYSCFG->CFGR1 |= (SYSCFG_CFGR1_PA12_RMP | SYSCFG_CFGR1_PA11_RMP); - - hw_gpio_init(GPIO_ID_UART_TX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_UP, GPIO_AF_1, 0); - hw_gpio_init(GPIO_ID_UART_RX, GPIO_ALT, GPIO_PP, GPIO_SPEED_LOW, GPIO_PULL_UP, GPIO_AF_1, 0); - - USART1->BRR = (64000000UL) / UART_BAUD; - USART1->RQR = USART_RQR_TXFRQ | USART_RQR_RXFRQ; - USART1->CR1 = USART_CR1_FIFOEN | USART_CR1_M0 | USART_CR1_PCE | USART_CR1_TE | USART_CR1_RE | USART_CR1_UE; -} - -static void hw_init_tim (void) { - RCC->APBENR1 |= ( - RCC_APBENR1_DBGEN | - RCC_APBENR1_TIM3EN - ); - RCC->APBENR2 |= ( - RCC_APBENR2_TIM17EN | - RCC_APBENR2_TIM16EN | - RCC_APBENR2_TIM14EN | - RCC_APBENR2_USART1EN | - RCC_APBENR2_TIM1EN - ); - - DBG->APBFZ1 |= DBG_APB_FZ1_DBG_TIM3_STOP; - DBG->APBFZ2 |= ( - DBG_APB_FZ2_DBG_TIM17_STOP | - DBG_APB_FZ2_DBG_TIM16_STOP | - DBG_APB_FZ2_DBG_TIM14_STOP | - DBG_APB_FZ2_DBG_TIM1_STOP - ); -} - -static void hw_init_crc (void) { - RCC->AHBENR |= RCC_AHBENR_CRCEN; - - CRC->CR = (CRC_CR_REV_OUT | CRC_CR_REV_IN_0); -} - -static void hw_init_misc (void) { - hw_gpio_init(GPIO_ID_N64_RESET, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_DOWN, GPIO_AF_0, 0); - hw_gpio_init(GPIO_ID_N64_CIC_CLK, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); +static void hw_misc_init (void) { + hw_gpio_init(GPIO_ID_N64_RESET, GPIO_INPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_DOWN, GPIO_AF_0, 0); + hw_gpio_init(GPIO_ID_N64_CIC_CLK, GPIO_INPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); hw_gpio_init(GPIO_ID_N64_CIC_DQ, GPIO_INPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 1); - hw_gpio_init(GPIO_ID_FPGA_INT, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); - hw_gpio_init(GPIO_ID_RTC_MFP, GPIO_INPUT, GPIO_PP, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); + hw_gpio_init(GPIO_ID_FPGA_INT, GPIO_INPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); + hw_gpio_init(GPIO_ID_RTC_MFP, GPIO_INPUT, GPIO_OD, GPIO_SPEED_VLOW, GPIO_PULL_UP, GPIO_AF_0, 0); } -void hw_set_vector_table (uint32_t offset) { - SCB->VTOR = (__IOM uint32_t) (offset); -} -void hw_init (void) { - hw_init_mcu(); - hw_init_spi(); - hw_init_i2c(); - hw_init_uart(); - hw_init_tim(); - hw_init_crc(); - hw_init_misc(); - - NVIC_SetPriority(EXTI0_1_IRQn, 0); - NVIC_SetPriority(EXTI2_3_IRQn, 0); - NVIC_SetPriority(EXTI4_15_IRQn, 0); - NVIC_SetPriority(I2C1_IRQn, 0); - NVIC_SetPriority(TIM14_IRQn, 0); - NVIC_SetPriority(TIM16_IRQn, 0); - NVIC_SetPriority(TIM17_IRQn, 0); - NVIC_SetPriority(TIM3_IRQn, 0); - NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0); - - NVIC_EnableIRQ(EXTI0_1_IRQn); - NVIC_EnableIRQ(EXTI2_3_IRQn); - NVIC_EnableIRQ(EXTI4_15_IRQn); - NVIC_EnableIRQ(I2C1_IRQn); - NVIC_EnableIRQ(TIM14_IRQn); - NVIC_EnableIRQ(TIM16_IRQn); - NVIC_EnableIRQ(TIM17_IRQn); - NVIC_EnableIRQ(TIM3_IRQn); - NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); +void hw_primer_init (void) { + hw_clock_init(); + hw_delay_init(); + hw_led_init(); + hw_uart_init(); + hw_spi_init(); + hw_i2c_init(); + hw_crc32_init(); } void hw_loader_init (void) { - hw_init_mcu(); - hw_init_spi(); + hw_clock_init(); + hw_delay_init(); + hw_led_init(); + hw_spi_init(); } -void hw_primer_init (void) { - hw_init_mcu(); - hw_init_spi(); - hw_init_i2c(); - hw_init_uart(); - hw_init_crc(); -} - - -void EXTI0_1_IRQHandler (void) { - for (int i = 0; i <= 1; i++) { - if (EXTI->FPR1 & (EXTI_FPR1_FPIF0 << i)) { - EXTI->FPR1 = (EXTI_FPR1_FPIF0 << i); - if (gpio_irq_callbacks[i].falling) { - gpio_irq_callbacks[i].falling(); - } - } - if (EXTI->RPR1 & (EXTI_RPR1_RPIF0 << i)) { - EXTI->RPR1 = (EXTI_RPR1_RPIF0 << i); - if (gpio_irq_callbacks[i].rising) { - gpio_irq_callbacks[i].rising(); - } - } - } -} - -void EXTI2_3_IRQHandler (void) { - for (int i = 2; i <= 3; i++) { - if (EXTI->FPR1 & (EXTI_FPR1_FPIF0 << i)) { - EXTI->FPR1 = (EXTI_FPR1_FPIF0 << i); - if (gpio_irq_callbacks[i].falling) { - gpio_irq_callbacks[i].falling(); - } - } - if (EXTI->RPR1 & (EXTI_RPR1_RPIF0 << i)) { - EXTI->RPR1 = (EXTI_RPR1_RPIF0 << i); - if (gpio_irq_callbacks[i].rising) { - gpio_irq_callbacks[i].rising(); - } - } - } -} - -void EXTI4_15_IRQHandler (void) { - for (int i = 4; i <= 15; i++) { - if (EXTI->FPR1 & (EXTI_FPR1_FPIF0 << i)) { - EXTI->FPR1 = (EXTI_FPR1_FPIF0 << i); - if (gpio_irq_callbacks[i].falling) { - gpio_irq_callbacks[i].falling(); - } - } - if (EXTI->RPR1 & (EXTI_RPR1_RPIF0 << i)) { - EXTI->RPR1 = (EXTI_RPR1_RPIF0 << i); - if (gpio_irq_callbacks[i].rising) { - gpio_irq_callbacks[i].rising(); - } - } - } -} - -void I2C1_IRQHandler (void) { - if (I2C1->ISR & I2C_ISR_TXIS) { - I2C1->TXDR = *i2c_data_txptr++; - } - - if (I2C1->ISR & I2C_ISR_RXNE) { - *i2c_data_rxptr++ = I2C1->RXDR; - } - - if (I2C1->ISR & I2C_ISR_TC) { - I2C1->CR2 = i2c_next_cr2; - } - - if (I2C1->ISR & I2C_ISR_STOPF) { - I2C1->ICR = I2C_ICR_STOPCF; - if (i2c_callback) { - i2c_callback(); - i2c_callback = 0; - } - } -} - -void TIM14_IRQHandler (void) { - TIM14->SR &= ~(TIM_SR_UIF); - if (tim_callbacks[0]) { - tim_callbacks[0](); - tim_callbacks[0] = 0; - } -} - -void TIM16_IRQHandler (void) { - TIM16->SR &= ~(TIM_SR_UIF); - if (tim_callbacks[1]) { - tim_callbacks[1](); - tim_callbacks[1] = 0; - } -} - -void TIM17_IRQHandler (void) { - TIM17->SR &= ~(TIM_SR_UIF); - if (tim_callbacks[2]) { - tim_callbacks[2](); - tim_callbacks[2] = 0; - } -} - -void TIM3_IRQHandler (void) { - TIM3->SR &= ~(TIM_SR_UIF); - if (tim_callbacks[3]) { - tim_callbacks[3](); - tim_callbacks[3] = 0; - } -} - -void TIM1_BRK_UP_TRG_COM_IRQHandler (void) { - TIM1->SR &= ~(TIM_SR_UIF); - if (tim_callbacks[4]) { - tim_callbacks[4](); - tim_callbacks[4] = 0; - } +void hw_app_init (void) { + hw_clock_init(); + hw_led_init(); + hw_uart_init(); + hw_spi_init(); + hw_i2c_init(); + hw_crc32_init(); + hw_misc_init(); } diff --git a/sw/controller/src/hw.h b/sw/controller/src/hw.h index 6daaaea..22b03b8 100644 --- a/sw/controller/src/hw.h +++ b/sw/controller/src/hw.h @@ -7,6 +7,7 @@ #define GPIO_PORT_PIN(p, n) ((((p) & 0x07) << 4) | ((n) & 0x0F)) + typedef enum { GPIO_ID_N64_RESET = GPIO_PORT_PIN(0, 0), GPIO_ID_N64_CIC_CLK = GPIO_PORT_PIN(0, 1), @@ -25,22 +26,9 @@ typedef enum { } gpio_id_t; typedef enum { - GPIO_IRQ_FALLING = 0b01, - GPIO_IRQ_RISING = 0b10, -} gpio_irq_t; - -typedef enum { - TIM_ID_CIC = 0, - TIM_ID_RTC = 1, - TIM_ID_SD = 2, - TIM_ID_DD = 3, - TIM_ID_LED = 4, -} tim_id_t; - -typedef enum { - SPI_TX, - SPI_RX, -} spi_direction_t; + I2C_OK, + I2C_ERR_NACK, +} i2c_err_t; typedef uint64_t hw_flash_t; @@ -59,39 +47,45 @@ typedef struct { } loader_parameters_t; -void hw_gpio_irq_setup (gpio_id_t id, gpio_irq_t irq, void (*callback)(void)); +void hw_set_vector_table (uint32_t offset); + +void hw_enter_critical (void); +void hw_exit_critical (void); + +void hw_delay_ms (uint32_t ms); + +void hw_systick_config (uint32_t period_ms, void (*callback) (void)); + uint32_t hw_gpio_get (gpio_id_t id); void hw_gpio_set (gpio_id_t id); void hw_gpio_reset (gpio_id_t id); + void hw_uart_read (uint8_t *data, int length); void hw_uart_write (uint8_t *data, int length); -void hw_uart_wait_busy (void); +void hw_uart_write_wait_busy (void); + void hw_spi_start (void); void hw_spi_stop (void); -void hw_spi_trx (uint8_t *data, int length, spi_direction_t direction); -void hw_i2c_read (uint8_t i2c_address, uint8_t address, uint8_t *data, uint8_t length, void (*callback)(void)); -void hw_i2c_write (uint8_t i2c_address, uint8_t address, uint8_t *data, uint8_t length, void (*callback)(void)); -uint32_t hw_i2c_get_error (void); -void hw_i2c_raw (uint8_t i2c_address, uint8_t *tx_data, uint8_t tx_length, uint8_t *rx_data, uint8_t rx_length); -void hw_i2c_disable_irq (void); -void hw_i2c_enable_irq (void); -void hw_tim_setup (tim_id_t id, uint16_t delay, void (*callback)(void)); -void hw_tim_stop (tim_id_t id); -void hw_tim_disable_irq (tim_id_t id); -void hw_tim_enable_irq (tim_id_t id); -void hw_delay_ms (uint32_t ms); +void hw_spi_rx (uint8_t *data, int length); +void hw_spi_tx (uint8_t *data, int length); + +i2c_err_t hw_i2c_trx (uint8_t i2c_address, uint8_t *tx_data, uint8_t tx_length, uint8_t *rx_data, uint8_t rx_length); + void hw_crc32_reset (void); uint32_t hw_crc32_calculate (uint8_t *data, uint32_t length); + uint32_t hw_flash_size (void); +hw_flash_t hw_flash_read (uint32_t offset); void hw_flash_erase (void); void hw_flash_program (uint32_t offset, hw_flash_t value); -hw_flash_t hw_flash_read (uint32_t offset); + void hw_reset (loader_parameters_t *parameters); + void hw_loader_get_parameters (loader_parameters_t *parameters); -void hw_set_vector_table (uint32_t offset); -void hw_init (void); -void hw_loader_init (void); + void hw_primer_init (void); +void hw_loader_init (void); +void hw_app_init (void); #endif diff --git a/sw/controller/src/isv.c b/sw/controller/src/isv.c index 4dbcee5..af3e25d 100644 --- a/sw/controller/src/isv.c +++ b/sw/controller/src/isv.c @@ -57,11 +57,13 @@ uint32_t isv_get_address (void) { return p.address; } + void isv_init (void) { p.address = 0; p.ready = true; } + void isv_process (void) { if ((p.address != 0) && p.ready) { if (isv_get_value(ISV_SETUP_TOKEN_ADDRESS) == ISV_TOKEN) { diff --git a/sw/controller/src/isv.h b/sw/controller/src/isv.h index 04ae2de..639b6f6 100644 --- a/sw/controller/src/isv.h +++ b/sw/controller/src/isv.h @@ -8,7 +8,9 @@ bool isv_set_address (uint32_t address); uint32_t isv_get_address (void); + void isv_init (void); + void isv_process (void); diff --git a/sw/controller/src/lcmxo2.c b/sw/controller/src/lcmxo2.c index de8535c..d5db5d2 100644 --- a/sw/controller/src/lcmxo2.c +++ b/sw/controller/src/lcmxo2.c @@ -114,7 +114,7 @@ static void lcmxo2_write_data (uint8_t *buffer, uint32_t length) { static void lcmxo2_reset_bus (void) { #ifdef LCMXO2_I2C uint8_t reset_data = 0; - hw_i2c_raw(LCMXO2_I2C_ADDR_RESET, &reset_data, sizeof(reset_data), NULL, 0); + hw_i2c_trx(LCMXO2_I2C_ADDR_RESET, &reset_data, sizeof(reset_data), NULL, 0); #else lcmxo2_reg_set(LCMXO2_CFGCR, CFGCR_RSTE); lcmxo2_reg_set(LCMXO2_CFGCR, 0); @@ -131,7 +131,7 @@ static void lcmxo2_execute_cmd (uint8_t cmd, uint32_t arg, cmd_type_t type, uint } packet_length += length; } - hw_i2c_raw(LCMXO2_I2C_ADDR_CFG, packet, packet_length, buffer, (write ? 0 : length)); + hw_i2c_trx(LCMXO2_I2C_ADDR_CFG, packet, packet_length, buffer, (write ? 0 : length)); #else uint32_t data = (cmd << 24) | (arg & 0x00FFFFFF); lcmxo2_reg_set(LCMXO2_CFGCR, CFGCR_WBCE); diff --git a/sw/controller/src/led.c b/sw/controller/src/led.c index 2cefc03..ef4996f 100644 --- a/sw/controller/src/led.c +++ b/sw/controller/src/led.c @@ -1,148 +1,147 @@ #include -#include "hw.h" +// #include "hw.h" #include "led.h" -#include "rtc.h" -#include "task.h" -#include "timer.h" +// #include "rtc.h" +// #include "timer.h" -#define LED_MS_PER_TICK (10) -#define LED_ERROR_TICKS_PERIOD (50) -#define LED_ERROR_TICKS_ON (25) -#define LED_ACT_TICKS_PERIOD (15) -#define LED_ACT_TICKS_ON (6) +// #define LED_MS_PER_TICK (10) +// #define LED_ERROR_TICKS_PERIOD (50) +// #define LED_ERROR_TICKS_ON (25) +// #define LED_ACT_TICKS_PERIOD (15) +// #define LED_ACT_TICKS_ON (6) -static bool error_mode = false; -static uint32_t error_timer = 0; -static volatile bool cic_error = false; -static volatile bool rtc_error = false; +// static bool error_mode = false; +// static uint32_t error_timer = 0; +// static volatile bool cic_error = false; +// static volatile bool rtc_error = false; -static uint32_t act_timer = 0; -static uint32_t current_act_counter = 0; -static volatile uint32_t next_act_counter = 0; +// static uint32_t act_timer = 0; +// static uint32_t current_act_counter = 0; +// static volatile uint32_t next_act_counter = 0; -static void led_task_resume (void) { - task_set_ready(TASK_ID_LED); -} +// static void led_task_resume (void) { +// task_set_ready(TASK_ID_LED); +// } -static void led_set_state (bool state, bool force) { - rtc_settings_t *settings = rtc_get_settings(); - if (settings->led_enabled || force) { - if (state) { - hw_gpio_set(GPIO_ID_LED); - } else { - hw_gpio_reset(GPIO_ID_LED); - } - } else { - hw_gpio_reset(GPIO_ID_LED); - } -} +// static void led_set_state (bool state, bool force) { +// rtc_settings_t *settings = rtc_get_settings(); +// if (settings->led_enabled || force) { +// if (state) { +// hw_gpio_set(GPIO_ID_LED); +// } else { +// hw_gpio_reset(GPIO_ID_LED); +// } +// } else { +// hw_gpio_reset(GPIO_ID_LED); +// } +// } -static void led_update_error_mode (void) { - if (error_mode) { - if (!(cic_error || rtc_error)) { - led_set_state(false, true); - error_mode = false; - act_timer = 0; - } - } else { - if (cic_error || rtc_error) { - led_set_state(false, true); - error_mode = true; - error_timer = 0; - } - } -} +// static void led_update_error_mode (void) { +// if (error_mode) { +// if (!(cic_error || rtc_error)) { +// led_set_state(false, true); +// error_mode = false; +// act_timer = 0; +// } +// } else { +// if (cic_error || rtc_error) { +// led_set_state(false, true); +// error_mode = true; +// error_timer = 0; +// } +// } +// } -static void led_process_errors (void) { - if (error_timer == 0) { - error_timer = LED_ERROR_TICKS_PERIOD; - if (cic_error) { - error_timer *= 1; - } else if (rtc_error) { - error_timer *= 2; - } - error_timer += LED_ERROR_TICKS_PERIOD; - } +// static void led_process_errors (void) { +// if (error_timer == 0) { +// error_timer = LED_ERROR_TICKS_PERIOD; +// if (cic_error) { +// error_timer *= 1; +// } else if (rtc_error) { +// error_timer *= 2; +// } +// error_timer += LED_ERROR_TICKS_PERIOD; +// } - if (error_timer > 0) { - error_timer -= 1; - if (error_timer >= LED_ERROR_TICKS_PERIOD) { - uint32_t error_cycle = (error_timer % LED_ERROR_TICKS_PERIOD); - if (error_cycle == LED_ERROR_TICKS_ON) { - led_set_state(true, true); - } - if (error_cycle == 0) { - led_set_state(false, true); - } - } - } -} +// if (error_timer > 0) { +// error_timer -= 1; +// if (error_timer >= LED_ERROR_TICKS_PERIOD) { +// uint32_t error_cycle = (error_timer % LED_ERROR_TICKS_PERIOD); +// if (error_cycle == LED_ERROR_TICKS_ON) { +// led_set_state(true, true); +// } +// if (error_cycle == 0) { +// led_set_state(false, true); +// } +// } +// } +// } -static void led_process_act (void) { - if (act_timer == 0) { - if (current_act_counter != next_act_counter) { - current_act_counter = next_act_counter; - act_timer = LED_ACT_TICKS_PERIOD; - } - } +// static void led_process_act (void) { +// if (act_timer == 0) { +// if (current_act_counter != next_act_counter) { +// current_act_counter = next_act_counter; +// act_timer = LED_ACT_TICKS_PERIOD; +// } +// } - if (act_timer > 0) { - act_timer -= 1; - if (act_timer == LED_ACT_TICKS_ON) { - led_set_state(true, false); - } - if (act_timer == 0) { - led_set_state(false, false); - } - } -} +// if (act_timer > 0) { +// act_timer -= 1; +// if (act_timer == LED_ACT_TICKS_ON) { +// led_set_state(true, false); +// } +// if (act_timer == 0) { +// led_set_state(false, false); +// } +// } +// } void led_blink_error (led_error_t error) { - switch (error) { - case LED_ERROR_CIC: - cic_error = true; - break; - case LED_ERROR_RTC: - rtc_error = true; - break; - } + // switch (error) { + // case LED_ERROR_CIC: + // cic_error = true; + // break; + // case LED_ERROR_RTC: + // rtc_error = true; + // break; + // } } void led_clear_error (led_error_t error) { - switch (error) { - case LED_ERROR_CIC: - cic_error = false; - break; - case LED_ERROR_RTC: - rtc_error = false; - break; - } + // switch (error) { + // case LED_ERROR_CIC: + // cic_error = false; + // break; + // case LED_ERROR_RTC: + // rtc_error = false; + // break; + // } } void led_blink_act (void) { - next_act_counter += 1; + // next_act_counter += 1; } -void led_task (void) { - timer_init(); +// void led_task (void) { +// timer_init(); - while (1) { - hw_tim_setup(TIM_ID_LED, LED_MS_PER_TICK, led_task_resume); +// while (1) { +// hw_tim_setup(TIM_ID_LED, LED_MS_PER_TICK, led_task_resume); - led_update_error_mode(); +// led_update_error_mode(); - if (error_mode) { - led_process_errors(); - } else { - led_process_act(); - } +// if (error_mode) { +// led_process_errors(); +// } else { +// led_process_act(); +// } - timer_update(); +// timer_update(); - task_yield(); - } -} +// task_yield(); +// } +// } diff --git a/sw/controller/src/led.h b/sw/controller/src/led.h index 1ae724d..4958d24 100644 --- a/sw/controller/src/led.h +++ b/sw/controller/src/led.h @@ -11,7 +11,7 @@ typedef enum { void led_blink_error (led_error_t error); void led_clear_error (led_error_t error); void led_blink_act (void); -void led_task (void); +// void led_task (void); #endif diff --git a/sw/controller/src/loader.c b/sw/controller/src/loader.c index be5e67f..e7a8e6a 100644 --- a/sw/controller/src/loader.c +++ b/sw/controller/src/loader.c @@ -9,6 +9,7 @@ void no_valid_image (void) { hw_gpio_set(GPIO_ID_LED); } + void loader (void) { if (update_check()) { hw_loader_init(); diff --git a/sw/controller/src/primer.c b/sw/controller/src/primer.c index 94e22a3..62bf8c8 100644 --- a/sw/controller/src/primer.c +++ b/sw/controller/src/primer.c @@ -69,7 +69,10 @@ static void primer_send_response (uint8_t cmd, uint8_t *buffer, uint8_t tx_lengt void primer (void) { hw_primer_init(); + vendor_initial_configuration(primer_get_command, primer_send_response); - hw_uart_wait_busy(); + + hw_uart_write_wait_busy(); + hw_reset(NULL); } diff --git a/sw/controller/src/rtc.c b/sw/controller/src/rtc.c index 827ea6f..a346c46 100644 --- a/sw/controller/src/rtc.c +++ b/sw/controller/src/rtc.c @@ -1,8 +1,9 @@ +#include #include "fpga.h" #include "hw.h" #include "led.h" #include "rtc.h" -#include "task.h" +#include "timer.h" #define RTC_I2C_ADDRESS (0xDE) @@ -28,6 +29,8 @@ #define RTC_SETTINGS_VERSION (1) +#define RTC_TIME_REFRESH_PERIOD_MS (500) + static rtc_time_t rtc_time = { .second = 0x00, @@ -38,17 +41,15 @@ static rtc_time_t rtc_time = { .month = 0x03, .year = 0x22 }; -static bool rtc_time_valid = false; -static volatile bool rtc_time_pending = false; +static bool rtc_time_pending = false; static uint8_t rtc_region = 0xFF; -static volatile bool rtc_region_pending = false; +static bool rtc_region_pending = false; static rtc_settings_t rtc_settings = { .led_enabled = true, }; -static volatile bool rtc_settings_pending = false; -static volatile bool rtc_initialized = false; +static bool rtc_settings_pending = false; static const uint8_t rtc_regs_bit_mask[7] = { 0b01111111, @@ -61,29 +62,21 @@ static const uint8_t rtc_regs_bit_mask[7] = { }; -static void rtc_task_resume (void) { - task_set_ready(TASK_ID_RTC); -} - -static void rtc_on_error (void) { - rtc_time_valid = false; - led_blink_error(LED_ERROR_RTC); - task_yield(); -} - static void rtc_read (uint8_t address, uint8_t *data, uint8_t length) { - hw_i2c_read(RTC_I2C_ADDRESS, address, data, length, rtc_task_resume); - task_yield(); - if (hw_i2c_get_error()) { - rtc_on_error(); + uint8_t tmp = address; + if (hw_i2c_trx(RTC_I2C_ADDRESS, &tmp, 1, data, length) != I2C_OK) { + led_blink_error(LED_ERROR_RTC); } } static void rtc_write (uint8_t address, uint8_t *data, uint8_t length) { - hw_i2c_write(RTC_I2C_ADDRESS, address, data, length, rtc_task_resume); - task_yield(); - if (hw_i2c_get_error()) { - rtc_on_error(); + uint8_t tmp[16]; + tmp[0] = address; + for (int i = 0; i < length; i++) { + tmp[i + 1] = data[i]; + } + if (hw_i2c_trx(RTC_I2C_ADDRESS, tmp, length + 1, NULL, 0) != I2C_OK) { + led_blink_error(LED_ERROR_RTC); } } @@ -110,17 +103,13 @@ static void rtc_read_time (void) { rtc_sanitize_time(regs); - if (!rtc_time_pending) { - rtc_time.second = regs[0]; - rtc_time.minute = regs[1]; - rtc_time.hour = regs[2]; - rtc_time.weekday = regs[3]; - rtc_time.day = regs[4]; - rtc_time.month = regs[5]; - rtc_time.year = regs[6]; - - rtc_time_valid = true; - } + rtc_time.second = regs[0]; + rtc_time.minute = regs[1]; + rtc_time.hour = regs[2]; + rtc_time.weekday = regs[3]; + rtc_time.day = regs[4]; + rtc_time.month = regs[5]; + rtc_time.year = regs[6]; } static void rtc_write_time (void) { @@ -161,12 +150,55 @@ static void rtc_write_settings (void) { rtc_write(RTC_ADDRESS_SRAM_SETTINGS, (uint8_t *) (&rtc_settings), sizeof(rtc_settings)); } -static void rtc_init (void) { + +void rtc_get_time (rtc_time_t *time) { + time->second = rtc_time.second; + time->minute = rtc_time.minute; + time->hour = rtc_time.hour; + time->weekday = rtc_time.weekday; + time->day = rtc_time.day; + time->month = rtc_time.month; + time->year = rtc_time.year; +} + +void rtc_set_time (rtc_time_t *time) { + rtc_time.second = time->second; + rtc_time.minute = time->minute; + rtc_time.hour = time->hour; + rtc_time.weekday = time->weekday; + rtc_time.day = time->day; + rtc_time.month = time->month; + rtc_time.year = time->year; + rtc_time_pending = true; +} + + +uint8_t rtc_get_region (void) { + return rtc_region; +} + +void rtc_set_region (uint8_t region) { + rtc_region = region; + rtc_region_pending = true; +} + + +rtc_settings_t *rtc_get_settings (void) { + return (&rtc_settings); +} + +void rtc_save_settings (void) { + rtc_settings_pending = true; +} + + +void rtc_init (void) { bool uninitialized = false; const char *magic = "SC64"; uint8_t buffer[4]; uint32_t settings_version; + memset(buffer, 0, 4); rtc_read(RTC_ADDRESS_SRAM_MAGIC, buffer, 4); for (int i = 0; i < 4; i++) { @@ -192,143 +224,73 @@ static void rtc_init (void) { rtc_write(RTC_ADDRESS_SRAM_VERSION, (uint8_t *) (&settings_version), 4); rtc_write_settings(); } -} - - -bool rtc_is_initialized (void) { - return rtc_initialized; -} - -bool rtc_get_time (rtc_time_t *time) { - bool vaild; - - hw_i2c_disable_irq(); - hw_tim_disable_irq(TIM_ID_RTC); - - time->second = rtc_time.second; - time->minute = rtc_time.minute; - time->hour = rtc_time.hour; - time->weekday = rtc_time.weekday; - time->day = rtc_time.day; - time->month = rtc_time.month; - time->year = rtc_time.year; - vaild = rtc_time_valid; - - hw_tim_enable_irq(TIM_ID_RTC); - hw_i2c_enable_irq(); - - return vaild; -} - -void rtc_set_time (rtc_time_t *time) { - hw_i2c_disable_irq(); - hw_tim_disable_irq(TIM_ID_RTC); - - rtc_time.second = time->second; - rtc_time.minute = time->minute; - rtc_time.hour = time->hour; - rtc_time.weekday = time->weekday; - rtc_time.day = time->day; - rtc_time.month = time->month; - rtc_time.year = time->year; - rtc_time_pending = true; - - hw_tim_enable_irq(TIM_ID_RTC); - hw_i2c_enable_irq(); -} - -uint8_t rtc_get_region (void) { - return rtc_region; -} - -void rtc_set_region (uint8_t region) { - rtc_region = region; - rtc_region_pending = true; -} - -rtc_settings_t *rtc_get_settings (void) { - return (&rtc_settings); -} - -void rtc_set_settings (rtc_settings_t *settings) { - hw_tim_disable_irq(TIM_ID_LED); - - rtc_settings = *settings; - rtc_settings_pending = true; - - hw_tim_enable_irq(TIM_ID_LED); -} - -void rtc_task (void) { - rtc_init(); + rtc_read_time(); rtc_read_region(); rtc_read_settings(); - rtc_initialized = true; - - while (1) { - if (rtc_time_pending) { - rtc_time_pending = false; - rtc_write_time(); - } - - if (rtc_region_pending) { - rtc_region_pending = false; - rtc_write_region(); - } - - if (rtc_settings_pending) { - rtc_settings_pending = false; - rtc_write_settings(); - } - - rtc_read_time(); - - hw_tim_setup(TIM_ID_RTC, 50, rtc_task_resume); - - task_yield(); - } + timer_countdown_start(TIMER_ID_RTC, RTC_TIME_REFRESH_PERIOD_MS); } + void rtc_process (void) { - rtc_time_t time; - uint32_t data[2]; uint32_t scr = fpga_reg_get(REG_RTC_SCR); if ((scr & RTC_SCR_PENDING) && ((scr & RTC_SCR_MAGIC_MASK) == RTC_SCR_MAGIC)) { + uint32_t data[2]; + data[0] = fpga_reg_get(REG_RTC_TIME_0); data[1] = fpga_reg_get(REG_RTC_TIME_1); - time.weekday = ((data[0] >> 24) & 0xFF) + 1; - time.hour = ((data[0] >> 16) & 0xFF); - time.minute = ((data[0] >> 8) & 0xFF); - time.second = ((data[0] >> 0) & 0xFF); - time.year = ((data[1] >> 16) & 0xFF); - time.month = ((data[1] >> 8) & 0xFF); - time.day = ((data[1] >> 0) & 0xFF); - - rtc_set_time(&time); + rtc_time.weekday = ((data[0] >> 24) & 0xFF) + 1; + rtc_time.hour = ((data[0] >> 16) & 0xFF); + rtc_time.minute = ((data[0] >> 8) & 0xFF); + rtc_time.second = ((data[0] >> 0) & 0xFF); + rtc_time.year = ((data[1] >> 16) & 0xFF); + rtc_time.month = ((data[1] >> 8) & 0xFF); + rtc_time.day = ((data[1] >> 0) & 0xFF); + rtc_time_pending = true; fpga_reg_set(REG_RTC_TIME_0, data[0]); fpga_reg_set(REG_RTC_TIME_1, data[1]); fpga_reg_set(REG_RTC_SCR, RTC_SCR_DONE); } - rtc_get_time(&time); + if (rtc_time_pending) { + rtc_time_pending = false; + rtc_write_time(); + } - data[0] = ( - ((time.weekday - 1) << 24) | - (time.hour << 16) | - (time.minute << 8) | - (time.second << 0) - ); - data[1] = ( - (time.year << 16) | - (time.month << 8) | - (time.day << 0) - ); + if (rtc_region_pending) { + rtc_region_pending = false; + rtc_write_region(); + } - fpga_reg_set(REG_RTC_TIME_0, data[0]); - fpga_reg_set(REG_RTC_TIME_1, data[1]); + if (rtc_settings_pending) { + rtc_settings_pending = false; + rtc_write_settings(); + } + + if (timer_countdown_elapsed(TIMER_ID_RTC)) { + timer_countdown_start(TIMER_ID_RTC, RTC_TIME_REFRESH_PERIOD_MS); + + rtc_read_time(); + + uint32_t data[2]; + + data[0] = ( + ((rtc_time.weekday - 1) << 24) | + (rtc_time.hour << 16) | + (rtc_time.minute << 8) | + (rtc_time.second << 0) + ); + data[1] = ( + (rtc_time.year << 16) | + (rtc_time.month << 8) | + (rtc_time.day << 0) + ); + + fpga_reg_set(REG_RTC_TIME_0, data[0]); + fpga_reg_set(REG_RTC_TIME_1, data[1]); + } } diff --git a/sw/controller/src/rtc.h b/sw/controller/src/rtc.h index be7dc8a..a8714d9 100644 --- a/sw/controller/src/rtc.h +++ b/sw/controller/src/rtc.h @@ -7,28 +7,31 @@ typedef struct { - volatile uint8_t second; - volatile uint8_t minute; - volatile uint8_t hour; - volatile uint8_t weekday; - volatile uint8_t day; - volatile uint8_t month; - volatile uint8_t year; + uint8_t second; + uint8_t minute; + uint8_t hour; + uint8_t weekday; + uint8_t day; + uint8_t month; + uint8_t year; } rtc_time_t; typedef struct { - volatile bool led_enabled; + bool led_enabled; } rtc_settings_t; -bool rtc_is_initialized (void); -bool rtc_get_time (rtc_time_t *time); +void rtc_get_time (rtc_time_t *time); void rtc_set_time (rtc_time_t *time); + uint8_t rtc_get_region (void); void rtc_set_region (uint8_t region); + rtc_settings_t *rtc_get_settings (void); -void rtc_set_settings (rtc_settings_t *settings); -void rtc_task (void); +void rtc_save_settings (void); + +void rtc_init (void); + void rtc_process (void); diff --git a/sw/controller/src/sd.c b/sw/controller/src/sd.c index a07917c..3cae691 100644 --- a/sw/controller/src/sd.c +++ b/sw/controller/src/sd.c @@ -1,9 +1,8 @@ -#include -#include #include "fpga.h" #include "hw.h" #include "led.h" #include "sd.h" +#include "timer.h" #define SD_INIT_BUFFER_ADDRESS (0x05002800UL) @@ -33,6 +32,8 @@ #define SWITCH_FUNCTION_GROUP_1 (SD_INIT_BUFFER_ADDRESS + 12) #define SWITCH_FUNCTION_GROUP_1_HS (1 << 1) +#define TIMEOUT_INIT_MS (1000) + #define DAT_BLOCK_MAX_COUNT (256) #define DAT_TIMEOUT_INIT_MS (2000) #define DAT_TIMEOUT_DATA_MS (5000) @@ -60,6 +61,12 @@ typedef enum { DAT_WRITE, } dat_mode_t; +typedef enum { + DAT_OK, + DAT_ERR_IO, + DAT_ERR_TIMEOUT, +} dat_err_t; + struct process { bool card_initialized; @@ -67,7 +74,6 @@ struct process { uint32_t rca; uint8_t csd[16]; uint8_t cid[16]; - volatile bool timeout; bool byte_swap; }; @@ -75,24 +81,6 @@ struct process { static struct process p; -static void sd_trigger_timeout (void) { - p.timeout = true; -} - -static void sd_prepare_timeout (uint16_t value) { - p.timeout = false; - hw_tim_setup(TIM_ID_SD, value, sd_trigger_timeout); -} - -static bool sd_did_timeout (void) { - return p.timeout; -} - -static void sd_clear_timeout (void) { - hw_tim_stop(TIM_ID_SD); - p.timeout = false; -} - static void sd_set_clock (sd_clock_t mode) { fpga_reg_set(REG_SD_SCR, SD_SCR_CLOCK_MODE_OFF); @@ -198,22 +186,25 @@ static void sd_dat_abort (void) { fpga_reg_set(REG_SD_DAT, SD_DAT_STOP | SD_DAT_FIFO_FLUSH); } -static bool sd_dat_wait (uint16_t timeout) { - sd_prepare_timeout(timeout); +static dat_err_t sd_dat_wait (uint16_t timeout_ms) { + timer_countdown_start(TIMER_ID_SD, timeout_ms); do { uint32_t sd_dat = fpga_reg_get(REG_SD_DAT); uint32_t sd_dma_scr = fpga_reg_get(REG_SD_DMA_SCR); led_blink_act(); if ((!(sd_dat & SD_DAT_BUSY)) && (!(sd_dma_scr & DMA_SCR_BUSY))) { - sd_clear_timeout(); - return (sd_dat & SD_DAT_ERROR); + if (sd_dat & SD_DAT_ERROR) { + sd_dat_abort(); + return DAT_ERR_IO; + } + return DAT_OK; } - } while (!sd_did_timeout()); + } while (!timer_countdown_elapsed(TIMER_ID_SD)); sd_dat_abort(); - return true; + return DAT_ERR_TIMEOUT; } @@ -248,11 +239,11 @@ bool sd_card_init (void) { arg = (ACMD41_ARG_HCS | ACMD41_ARG_OCR); } - sd_prepare_timeout(1000); + timer_countdown_start(TIMER_ID_SD, TIMEOUT_INIT_MS); do { - if (sd_did_timeout()) { + if (timer_countdown_elapsed(TIMER_ID_SD)) { sd_card_deinit(); - return true; + return true; } if (sd_acmd(41, arg, RSP_R3, &rsp)) { sd_card_deinit(); @@ -266,8 +257,7 @@ bool sd_card_init (void) { p.card_type_block = (rsp & R3_CCS); break; } - } while (1); - sd_clear_timeout(); + } while (true); if (sd_cmd(2, 0, RSP_R2, NULL)) { sd_card_deinit(); @@ -308,8 +298,7 @@ bool sd_card_init (void) { sd_card_deinit(); return true; } - sd_dat_wait(DAT_TIMEOUT_INIT_MS); - if (sd_did_timeout()) { + if (sd_dat_wait(DAT_TIMEOUT_INIT_MS) == DAT_ERR_TIMEOUT) { sd_card_deinit(); return true; } @@ -326,8 +315,7 @@ bool sd_card_init (void) { sd_card_deinit(); return true; } - sd_dat_wait(DAT_TIMEOUT_INIT_MS); - if (sd_did_timeout()) { + if (sd_dat_wait(DAT_TIMEOUT_INIT_MS) == DAT_ERR_TIMEOUT) { sd_card_deinit(); return true; } @@ -389,6 +377,7 @@ bool sd_set_byte_swap (bool enabled) { return false; } + bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { if (!p.card_initialized || (count == 0)) { return true; @@ -405,8 +394,7 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { return true; } sd_dat_prepare(address, blocks, DAT_WRITE); - if (sd_dat_wait(DAT_TIMEOUT_DATA_MS)) { - sd_dat_abort(); + if (sd_dat_wait(DAT_TIMEOUT_DATA_MS) != DAT_OK) { sd_cmd(12, 0, RSP_R1b, NULL); return true; } @@ -440,10 +428,8 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { sd_dat_abort(); return true; } - if (sd_dat_wait(DAT_TIMEOUT_DATA_MS)) { - if (sd_did_timeout()) { - sd_cmd(12, 0, RSP_R1b, NULL); - } + if (sd_dat_wait(DAT_TIMEOUT_DATA_MS) != DAT_OK) { + sd_cmd(12, 0, RSP_R1b, NULL); return true; } sd_cmd(12, 0, RSP_R1b, NULL); @@ -455,6 +441,7 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { return false; } + bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors) { uint32_t starting_sector = 0; uint32_t sectors_to_process = 0; @@ -483,12 +470,14 @@ bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t cou return false; } + void sd_init (void) { p.card_initialized = false; p.byte_swap = false; sd_set_clock(CLOCK_STOP); } + void sd_process (void) { if (p.card_initialized && !sd_card_is_inserted()) { sd_card_deinit(); diff --git a/sw/controller/src/sd.h b/sw/controller/src/sd.h index 9094df4..e530af5 100644 --- a/sw/controller/src/sd.h +++ b/sw/controller/src/sd.h @@ -3,6 +3,7 @@ #include +#include #define SD_SECTOR_SIZE (512) @@ -18,10 +19,14 @@ bool sd_card_is_inserted (void); uint32_t sd_card_get_status (void); bool sd_card_get_info (uint32_t address); bool sd_set_byte_swap (bool enabled); + bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count); bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count); + bool sd_optimize_sectors (uint32_t address, uint32_t *sector_table, uint32_t count, sd_process_sectors_t sd_process_sectors); + void sd_init (void); + void sd_process (void); diff --git a/sw/controller/src/task.c b/sw/controller/src/task.c deleted file mode 100644 index 8240aa4..0000000 --- a/sw/controller/src/task.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include -#include -#include "task.h" - - -#define TASK_INITIAL_XPSR (0x21000000UL) -#define TASK_CONTEXT_SWITCH() { SCB->ICSR = (1 << SCB_ICSR_PENDSVSET_Pos); } -#define TASK_STACK_FILL_VALUE (0xDEADBEEF) - - -typedef struct { - volatile uint32_t sp; - volatile bool ready; -} task_t; - - -static task_t task_table[__TASK_ID_MAX]; -static volatile task_id_t task_current = 0; - - -static void task_exit (void) { - while (1) { - task_yield(); - } -} - -static uint32_t task_switch_context (uint32_t sp) { - task_table[task_current].sp = sp; - - for (task_id_t id = 0; id < __TASK_ID_MAX; id++) { - if (task_table[id].ready) { - task_current = id; - break; - } - } - - return task_table[task_current].sp; -} - - -void task_create (task_id_t id, void (*code)(void), void *stack, size_t stack_size) { - if (id < __TASK_ID_MAX) { - for (size_t i = 0; i < stack_size; i += sizeof(uint32_t)) { - (*(uint32_t *) (stack + i)) = TASK_STACK_FILL_VALUE; - } - uint32_t *sp = ((uint32_t *) ((uint32_t) (stack) + stack_size)); - *--sp = TASK_INITIAL_XPSR; - *--sp = (uint32_t) (code); - *--sp = ((uint32_t) (task_exit)); - for (int i = 0; i < 13; i++) { - *--sp = 0; - } - task_t *task = &task_table[id]; - task->sp = ((uint32_t) (sp)); - task->ready = true; - } -} - -void task_yield (void) { - __disable_irq(); - task_table[task_current].ready = false; - __enable_irq(); - TASK_CONTEXT_SWITCH(); -} - -void task_set_ready (task_id_t id) { - __disable_irq(); - task_table[id].ready = true; - __enable_irq(); - TASK_CONTEXT_SWITCH(); -} - -size_t task_get_stack_usage (void *stack, size_t stack_size) { - for (size_t i = 0; i < stack_size; i += sizeof(uint32_t)) { - if ((*(uint32_t *) (stack + i)) != TASK_STACK_FILL_VALUE) { - return (stack_size - i); - } - } - return 0; -} - -__attribute__((naked)) void task_scheduler_start (void) { - uint32_t sp = task_table[task_current].sp; - - NVIC_SetPriority(PendSV_IRQn, 3); - - asm volatile ( - "add %[sp], #32 \n" - "msr psp, %[sp] \n" - "movs r0, #2 \n" - "msr CONTROL, r0 \n" - "isb \n" - "pop {r0-r5} \n" - "mov lr, r5 \n" - "pop {r3} \n" - "pop {r2} \n" - "cpsie i \n" - "bx r3 \n" - :: [sp] "r" (sp) - ); - - while (1); -} - - -__attribute__((naked)) void PendSV_Handler (void) { - asm volatile ( - "mrs r1, psp \n" - "sub r1, r1, #32 \n" - "mov r0, r1 \n" - "stmia r1!, {r4-r7} \n" - "mov r4, r8 \n" - "mov r5, r9 \n" - "mov r6, r10 \n" - "mov r7, r11 \n" - "stmia r1!, {r4-r7} \n" - "push {lr} \n" - "cpsid i \n" - "blx %[task_switch_context] \n" - "cpsie i \n" - "pop {r2} \n" - "add r0, #16 \n" - "ldmia r0!, {r4-r7} \n" - "mov r8, r4 \n" - "mov r9, r5 \n" - "mov r10, r6 \n" - "mov r11, r7 \n" - "msr psp, r0 \n" - "sub r0, #32 \n" - "ldmia r0!, {r4-r7} \n" - "bx r2 \n" - :: [task_switch_context] "r" (task_switch_context) - ); -} diff --git a/sw/controller/src/task.h b/sw/controller/src/task.h deleted file mode 100644 index 71ad4e3..0000000 --- a/sw/controller/src/task.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TASK_H__ -#define TASK_H__ - - -#include - - -typedef enum { - TASK_ID_RTC, - TASK_ID_LED, - TASK_ID_GVR, - __TASK_ID_MAX -} task_id_t; - - -void task_create (task_id_t id, void (*code)(void), void *stack, size_t stack_size); -void task_yield (void); -void task_set_ready (task_id_t id); -size_t task_get_stack_usage (void *stack, size_t stack_size); -void task_scheduler_start (void); - - -#endif diff --git a/sw/controller/src/timer.c b/sw/controller/src/timer.c index 03d44a5..f2b91ea 100644 --- a/sw/controller/src/timer.c +++ b/sw/controller/src/timer.c @@ -2,29 +2,55 @@ #include "timer.h" -static volatile uint32_t timer[__TIMER_ID_COUNT]; +#define TIMER_PERIOD_MS (50) -uint32_t timer_get (timer_id_t id) { - return (uint32_t) (timer[id]); -} +typedef struct { + volatile bool pending; + volatile bool running; + volatile uint32_t value; +} timer_t; -void timer_set (timer_id_t id, uint32_t ticks) { - hw_tim_disable_irq(TIM_ID_LED); - timer[id] = ticks; - hw_tim_enable_irq(TIM_ID_LED); -} +static timer_t timer[__TIMER_ID_COUNT]; -void timer_init (void) { + +static void timer_update (void) { for (timer_id_t id = 0; id < __TIMER_ID_COUNT; id++) { - timer[id] = 0; - } -} - -void timer_update (void) { - for (timer_id_t id = 0; id < __TIMER_ID_COUNT; id++) { - if (timer[id] > 0) { - timer[id] -= 1; + if (timer[id].value > 0) { + timer[id].value -= 1; + } + if (timer[id].pending) { + timer[id].pending = false; + } else if(timer[id].value == 0) { + timer[id].running = false; } } } + + +void timer_countdown_start (timer_id_t id, uint32_t value_ms) { + hw_enter_critical(); + if (value_ms > 0) { + timer[id].pending = true; + timer[id].running = true; + timer[id].value = ((value_ms + (TIMER_PERIOD_MS - 1)) / TIMER_PERIOD_MS); + } + hw_exit_critical(); +} + +void timer_countdown_abort (timer_id_t id) { + hw_enter_critical(); + timer[id].pending = false; + timer[id].running = false; + timer[id].value = 0; + hw_exit_critical(); +} + +bool timer_countdown_elapsed (timer_id_t id) { + return (!timer[id].running); +} + + +void timer_init (void) { + hw_systick_config(TIMER_PERIOD_MS, timer_update); +} diff --git a/sw/controller/src/timer.h b/sw/controller/src/timer.h index 916b524..fb5c72f 100644 --- a/sw/controller/src/timer.h +++ b/sw/controller/src/timer.h @@ -2,20 +2,25 @@ #define TIMER_H__ +#include #include typedef enum { + TIMER_ID_DD, + TIMER_ID_RTC, + TIMER_ID_SD, TIMER_ID_USB, TIMER_ID_WRITEBACK, __TIMER_ID_COUNT } timer_id_t; -uint32_t timer_get (timer_id_t id); -void timer_set (timer_id_t id, uint32_t ticks); +void timer_countdown_start (timer_id_t id, uint32_t value_ms); +void timer_countdown_abort (timer_id_t id); +bool timer_countdown_elapsed (timer_id_t id); + void timer_init (void); -void timer_update (void); #endif diff --git a/sw/controller/src/update.c b/sw/controller/src/update.c index 521e6a3..44b4d5e 100644 --- a/sw/controller/src/update.c +++ b/sw/controller/src/update.c @@ -312,7 +312,7 @@ void update_perform (void) { fpga_mem_read(parameters.mcu_address - 4, sizeof(length), (uint8_t *) (&length)); if (mcu_update(parameters.mcu_address, length)) { update_status_notify(UPDATE_STATUS_ERROR); - while (1); + while (true); } } @@ -321,7 +321,7 @@ void update_perform (void) { fpga_mem_read(parameters.fpga_address - 4, sizeof(length), (uint8_t *) (&length)); if (vendor_update(parameters.fpga_address, length) != VENDOR_OK) { update_status_notify(UPDATE_STATUS_ERROR); - while (1); + while (true); } } @@ -330,7 +330,7 @@ void update_perform (void) { fpga_mem_read(parameters.bootloader_address - 4, sizeof(length), (uint8_t *) (&length)); if (bootloader_update(parameters.bootloader_address, length)) { update_status_notify(UPDATE_STATUS_ERROR); - while (1); + while (true); } } diff --git a/sw/controller/src/usb.c b/sw/controller/src/usb.c index 6e2dd97..882e3aa 100644 --- a/sw/controller/src/usb.c +++ b/sw/controller/src/usb.c @@ -1,4 +1,3 @@ -#include "app.h" #include "cfg.h" #include "cic.h" #include "dd.h" @@ -12,15 +11,15 @@ #include "writeback.h" -#define BOOTLOADER_ADDRESS (0x04E00000UL) -#define BOOTLOADER_LENGTH (1920 * 1024) +#define BOOTLOADER_ADDRESS (0x04E00000UL) +#define BOOTLOADER_LENGTH (1920 * 1024) -#define MEMORY_LENGTH (0x05002980UL) +#define MEMORY_LENGTH (0x05002980UL) -#define RX_FLUSH_ADDRESS (0x07F00000UL) -#define RX_FLUSH_LENGTH (1 * 1024 * 1024) +#define RX_FLUSH_ADDRESS (0x07F00000UL) +#define RX_FLUSH_LENGTH (1 * 1024 * 1024) -#define DEBUG_WRITE_TIMEOUT_TICKS (100) +#define DEBUG_WRITE_TIMEOUT_MS (1000) enum rx_state { @@ -175,7 +174,7 @@ static void usb_rx_process (void) { p.response_info.dma_length = 0; p.response_info.done_callback = NULL; if (p.rx_cmd == 'U') { - timer_set(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_TICKS); + timer_countdown_start(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_MS); } } } @@ -311,9 +310,9 @@ static void usb_rx_process (void) { p.read_length -= length; p.read_address += length; p.read_ready = true; - timer_set(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_TICKS); + timer_countdown_start(TIMER_ID_USB, DEBUG_WRITE_TIMEOUT_MS); } - } else if (timer_get(TIMER_ID_USB) == 0) { + } else if (timer_countdown_elapsed(TIMER_ID_USB)) { p.rx_state = RX_STATE_FLUSH; p.flush_packet = true; } @@ -386,7 +385,10 @@ static void usb_rx_process (void) { p.rx_state = RX_STATE_IDLE; p.response_pending = true; p.response_info.data_length = 16; - app_get_stack_usage(p.response_info.data); + p.response_info.data[0] = 0; + p.response_info.data[1] = 0; + p.response_info.data[2] = 0; + p.response_info.data[3] = 0; break; default: @@ -521,6 +523,7 @@ bool usb_enqueue_packet (usb_tx_info_t *info) { return true; } + bool usb_prepare_read (uint32_t *args) { if (!p.read_ready) { return false; @@ -543,6 +546,7 @@ void usb_get_read_info (uint32_t *args) { args[0] |= (scr & USB_SCR_PWRSAV) ? (1 << 29) : 0; } + void usb_init (void) { fpga_reg_set(REG_USB_DMA_SCR, DMA_SCR_STOP); fpga_reg_set(REG_USB_SCR, USB_SCR_FIFO_FLUSH); @@ -563,6 +567,7 @@ void usb_init (void) { usb_rx_cmd_counter = 0; } + void usb_process (void) { uint32_t scr = fpga_reg_get(REG_USB_SCR); if (scr & (USB_SCR_PWRSAV | USB_SCR_RESET_STATE | USB_SCR_RESET_PENDING)) { diff --git a/sw/controller/src/usb.h b/sw/controller/src/usb.h index beafc04..3447e9a 100644 --- a/sw/controller/src/usb.h +++ b/sw/controller/src/usb.h @@ -7,13 +7,13 @@ typedef enum packet_cmd { - PACKET_CMD_BUTTON_TRIGGER = 'B', - PACKET_CMD_DATA_FLUSHED = 'G', - PACKET_CMD_DEBUG_OUTPUT = 'U', - PACKET_CMD_DD_REQUEST = 'D', - PACKET_CMD_ISV_OUTPUT = 'I', - PACKET_CMD_SAVE_WRITEBACK = 'S', - PACKET_CMD_UPDATE_STATUS = 'F', + PACKET_CMD_BUTTON_TRIGGER = 'B', + PACKET_CMD_DATA_FLUSHED = 'G', + PACKET_CMD_DEBUG_OUTPUT = 'U', + PACKET_CMD_DD_REQUEST = 'D', + PACKET_CMD_ISV_OUTPUT = 'I', + PACKET_CMD_SAVE_WRITEBACK = 'S', + PACKET_CMD_UPDATE_STATUS = 'F', } usb_packet_cmd_e; @@ -29,9 +29,12 @@ typedef struct usb_tx_info { void usb_create_packet (usb_tx_info_t *info, usb_packet_cmd_e cmd); bool usb_enqueue_packet (usb_tx_info_t *info); + bool usb_prepare_read (uint32_t *args); void usb_get_read_info (uint32_t *args); + void usb_init (void); + void usb_process (void); diff --git a/sw/controller/src/writeback.c b/sw/controller/src/writeback.c index 8e65f05..5d8870e 100644 --- a/sw/controller/src/writeback.c +++ b/sw/controller/src/writeback.c @@ -6,16 +6,19 @@ #include "writeback.h" -#define SAVE_MAX_SECTOR_COUNT (256) -#define EEPROM_ADDRESS (0x05002000) -#define SRAM_FLASHRAM_ADDRESS (0x03FE0000) -#define EEPROM_4K_LENGTH (512) -#define EEPROM_16K_LENGTH (2048) -#define SRAM_LENGTH (32 * 1024) -#define FLASHRAM_LENGTH (128 * 1024) -#define SRAM_BANKED_LENGTH (3 * 32 * 1024) -#define SRAM_1M_LENGTH (128 * 1024) -#define WRITEBACK_DELAY_TICKS (100) +#define SAVE_MAX_SECTOR_COUNT (256) + +#define EEPROM_ADDRESS (0x05002000) +#define SRAM_FLASHRAM_ADDRESS (0x03FE0000) + +#define EEPROM_4K_LENGTH (512) +#define EEPROM_16K_LENGTH (2048) +#define SRAM_LENGTH (32 * 1024) +#define FLASHRAM_LENGTH (128 * 1024) +#define SRAM_BANKED_LENGTH (3 * 32 * 1024) +#define SRAM_1M_LENGTH (128 * 1024) + +#define WRITEBACK_DELAY_MS (1000) struct process { @@ -111,6 +114,7 @@ void writeback_load_sector_table (uint32_t address) { } } + void writeback_enable (writeback_mode_t mode) { p.enabled = true; p.pending = false; @@ -121,13 +125,14 @@ void writeback_enable (writeback_mode_t mode) { void writeback_disable (void) { p.enabled = false; p.pending = false; - timer_set(TIMER_ID_WRITEBACK, 0); + timer_countdown_abort(TIMER_ID_WRITEBACK); } bool writeback_pending (void) { return p.enabled && p.pending; } + void writeback_init (void) { p.enabled = false; p.pending = false; @@ -137,6 +142,7 @@ void writeback_init (void) { } } + void writeback_process (void) { if (p.enabled && (p.mode == WRITEBACK_SD) && !sd_card_is_inserted()) { writeback_disable(); @@ -144,24 +150,27 @@ void writeback_process (void) { if (p.enabled) { uint16_t save_count = fpga_reg_get(REG_SAVE_COUNT); + if (save_count != p.last_save_count) { p.pending = true; p.last_save_count = save_count; - timer_set(TIMER_ID_WRITEBACK, WRITEBACK_DELAY_TICKS); + timer_countdown_start(TIMER_ID_WRITEBACK, WRITEBACK_DELAY_MS); } } - if (p.pending && (timer_get(TIMER_ID_WRITEBACK) == 0)) { + if (p.pending && timer_countdown_elapsed(TIMER_ID_WRITEBACK)) { switch (p.mode) { case WRITEBACK_SD: writeback_save_to_sd(); p.pending = false; break; + case WRITEBACK_USB: if (writeback_save_to_usb()) { p.pending = false; } break; + default: writeback_disable(); break; diff --git a/sw/controller/src/writeback.h b/sw/controller/src/writeback.h index 8e10b45..2e6a5cc 100644 --- a/sw/controller/src/writeback.h +++ b/sw/controller/src/writeback.h @@ -6,7 +6,7 @@ #include -#define WRITEBACK_SECTOR_TABLE_SIZE (1024) +#define WRITEBACK_SECTOR_TABLE_SIZE (1024) typedef enum { @@ -16,10 +16,13 @@ typedef enum { void writeback_load_sector_table (uint32_t address); + void writeback_enable (writeback_mode_t mode); void writeback_disable (void); bool writeback_pending (void); + void writeback_init (void); + void writeback_process (void);