diff --git a/sw/controller/src/app.c b/sw/controller/src/app.c index a0cf63f..2568874 100644 --- a/sw/controller/src/app.c +++ b/sw/controller/src/app.c @@ -1,3 +1,4 @@ +#include #include "button.h" #include "cfg.h" #include "cic.h" @@ -6,6 +7,7 @@ #include "fpga.h" #include "hw.h" #include "isv.h" +#include "led.h" #include "rtc.h" #include "sd.h" #include "timer.h" @@ -28,17 +30,19 @@ void app (void) { dd_init(); flashram_init(); isv_init(); + led_init(); sd_init(); usb_init(); writeback_init(); - while (1) { + while (true) { button_process(); cfg_process(); cic_process(); dd_process(); flashram_process(); isv_process(); + led_process(); rtc_process(); sd_process(); usb_process(); diff --git a/sw/controller/src/cfg.c b/sw/controller/src/cfg.c index a2509b7..4a6e805 100644 --- a/sw/controller/src/cfg.c +++ b/sw/controller/src/cfg.c @@ -5,6 +5,7 @@ #include "flash.h" #include "fpga.h" #include "isv.h" +#include "led.h" #include "rtc.h" #include "sd.h" #include "usb.h" @@ -560,12 +561,16 @@ void cfg_process (void) { case SD_CARD_OP_DEINIT: sd_card_deinit(); break; - case SD_CARD_OP_INIT: - if (sd_card_init()) { + case SD_CARD_OP_INIT: { + led_activity_on(); + bool error = sd_card_init(); + led_activity_off(); + if (error) { cfg_set_error(CFG_ERROR_SD_CARD); return; } break; + } case SD_CARD_OP_GET_STATUS: args[1] = sd_card_get_status(); break; @@ -601,7 +606,7 @@ void cfg_process (void) { p.sd_card_sector = args[0]; break; - case 's': + case 's': { if (args[1] >= 0x800000) { cfg_set_error(CFG_ERROR_BAD_ARGUMENT); return; @@ -610,14 +615,18 @@ void cfg_process (void) { cfg_set_error(CFG_ERROR_BAD_ADDRESS); return; } - if (sd_read_sectors(args[0], p.sd_card_sector, args[1])) { + led_activity_on(); + bool error = sd_read_sectors(args[0], p.sd_card_sector, args[1]); + led_activity_off(); + if (error) { cfg_set_error(CFG_ERROR_SD_CARD); return; } p.sd_card_sector += args[1]; break; + } - case 'S': + case 'S': { if (args[1] >= 0x800000) { cfg_set_error(CFG_ERROR_BAD_ARGUMENT); return; @@ -626,12 +635,16 @@ void cfg_process (void) { cfg_set_error(CFG_ERROR_BAD_ADDRESS); return; } - if (sd_write_sectors(args[0], p.sd_card_sector, args[1])) { + led_activity_on(); + bool error = sd_write_sectors(args[0], p.sd_card_sector, args[1]); + led_activity_off(); + if (error) { cfg_set_error(CFG_ERROR_SD_CARD); return; } p.sd_card_sector += args[1]; break; + } case 'D': if (cfg_translate_address(&args[0], args[1], (SDRAM | BRAM))) { diff --git a/sw/controller/src/dd.c b/sw/controller/src/dd.c index d28babb..cafd82e 100644 --- a/sw/controller/src/dd.c +++ b/sw/controller/src/dd.c @@ -263,7 +263,7 @@ void dd_set_disk_mapping (uint32_t address, uint32_t length) { } void dd_handle_button (void) { - led_blink_act(); + led_activity_pulse(); if (dd_get_disk_state() == DD_DISK_STATE_EJECTED) { dd_set_disk_state(DD_DISK_STATE_INSERTED); } else { diff --git a/sw/controller/src/led.c b/sw/controller/src/led.c index ef4996f..076ec52 100644 --- a/sw/controller/src/led.c +++ b/sw/controller/src/led.c @@ -1,147 +1,147 @@ #include -// #include "hw.h" +#include "hw.h" #include "led.h" -// #include "rtc.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_REFRESH_PERIOD_MS (50) + +#define LED_PULSE_LENGTH_MS (500) + +#define ERROR_BLINK_PERIOD_MS (100) +#define ERROR_TOTAL_PERIOD_MS (1000) + +#define CIC_ERROR_BLINKS (1) +#define RTC_ERROR_BLINKS (2) -// 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 activity_pulse = false; +static int activity_pulse_timer = 0; -// static uint32_t act_timer = 0; -// static uint32_t current_act_counter = 0; -// static volatile uint32_t next_act_counter = 0; +static bool cic_error = false; +static bool rtc_error = false; +static bool error_active = false; +static int error_timer = 0; -// static void led_task_resume (void) { -// task_set_ready(TASK_ID_LED); -// } +void led_activity_on (void) { + rtc_settings_t *settings = rtc_get_settings(); + if (!activity_pulse && !error_active && settings->led_enabled) { + hw_gpio_set(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); -// } -// } +void led_activity_off (void) { + rtc_settings_t *settings = rtc_get_settings(); + if (!activity_pulse && !error_active && settings->led_enabled) { + 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_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); -// } -// } -// } -// } - -// 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); -// } -// } -// } +void led_activity_pulse (void) { + activity_pulse = true; + activity_pulse_timer = LED_PULSE_LENGTH_MS; +} 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; + } + + error_active = ( + cic_error | + rtc_error + ); } 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; + } + + error_active = ( + cic_error | + rtc_error + ); + + if (!error_active) { + activity_pulse = false; + activity_pulse_timer = 0; + error_timer = 0; + } } -void led_blink_act (void) { - // next_act_counter += 1; + +void led_init (void) { + timer_countdown_start(TIMER_ID_LED, LED_REFRESH_PERIOD_MS); } -// void led_task (void) { -// timer_init(); -// while (1) { -// hw_tim_setup(TIM_ID_LED, LED_MS_PER_TICK, led_task_resume); +void led_process (void) { + if (!timer_countdown_elapsed(TIMER_ID_LED)) { + return; + } -// led_update_error_mode(); + timer_countdown_start(TIMER_ID_LED, LED_REFRESH_PERIOD_MS); -// if (error_mode) { -// led_process_errors(); -// } else { -// led_process_act(); -// } + if (error_active) { + int blinks = 0; -// timer_update(); + if (cic_error) { + blinks = CIC_ERROR_BLINKS; + } else if (rtc_error) { + blinks = RTC_ERROR_BLINKS; + } -// task_yield(); -// } -// } + bool led_on = false; + + for (int i = 0; i < blinks; i++) { + bool lower_bound = (error_timer >= (ERROR_BLINK_PERIOD_MS * (i * 2))); + bool upper_bound = (error_timer < (ERROR_BLINK_PERIOD_MS * ((i * 2) + 1))); + if (lower_bound && upper_bound) { + led_on = true; + break; + } + } + + if (led_on) { + hw_gpio_set(GPIO_ID_LED); + } else { + hw_gpio_reset(GPIO_ID_LED); + } + + error_timer += LED_REFRESH_PERIOD_MS; + + if (error_timer >= ERROR_TOTAL_PERIOD_MS) { + error_timer = 0; + } + + return; + } + + if (activity_pulse) { + if (activity_pulse_timer > 0) { + hw_gpio_set(GPIO_ID_LED); + } else { + activity_pulse = false; + hw_gpio_reset(GPIO_ID_LED); + return; + } + + activity_pulse_timer -= LED_REFRESH_PERIOD_MS; + } +} diff --git a/sw/controller/src/led.h b/sw/controller/src/led.h index 4958d24..4a084a7 100644 --- a/sw/controller/src/led.h +++ b/sw/controller/src/led.h @@ -8,10 +8,16 @@ typedef enum { } led_error_t; +void led_activity_on (void); +void led_activity_off (void); +void led_activity_pulse (void); + 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_init (void); + +void led_process (void); #endif diff --git a/sw/controller/src/primer.c b/sw/controller/src/primer.c index 62bf8c8..b5083bb 100644 --- a/sw/controller/src/primer.c +++ b/sw/controller/src/primer.c @@ -19,7 +19,7 @@ static uint8_t primer_get_command (uint8_t *buffer, uint8_t *rx_length) { uint32_t received_crc32; uint8_t token[4]; - while (1) { + while (true) { hw_crc32_reset(); primer_get_and_calculate_crc32(token, 4, &calculated_crc32); diff --git a/sw/controller/src/sd.c b/sw/controller/src/sd.c index 3cae691..20498c4 100644 --- a/sw/controller/src/sd.c +++ b/sw/controller/src/sd.c @@ -1,6 +1,5 @@ #include "fpga.h" #include "hw.h" -#include "led.h" #include "sd.h" #include "timer.h" @@ -192,7 +191,6 @@ static dat_err_t sd_dat_wait (uint16_t 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))) { if (sd_dat & SD_DAT_ERROR) { sd_dat_abort(); @@ -222,8 +220,6 @@ bool sd_card_init (void) { p.card_initialized = true; p.rca = 0; - led_blink_act(); - sd_set_clock(CLOCK_400KHZ); sd_cmd(0, 0, RSP_NONE, NULL); @@ -389,7 +385,6 @@ bool sd_write_sectors (uint32_t address, uint32_t sector, uint32_t count) { while (count > 0) { uint32_t blocks = ((count > DAT_BLOCK_MAX_COUNT) ? DAT_BLOCK_MAX_COUNT : count); - led_blink_act(); if (sd_cmd(25, sector, RSP_R1, NULL)) { return true; } @@ -422,7 +417,6 @@ bool sd_read_sectors (uint32_t address, uint32_t sector, uint32_t count) { while (count > 0) { uint32_t blocks = ((count > DAT_BLOCK_MAX_COUNT) ? DAT_BLOCK_MAX_COUNT : count); - led_blink_act(); sd_dat_prepare(address, blocks, DAT_READ); if (sd_cmd(18, sector, RSP_R1, NULL)) { sd_dat_abort(); diff --git a/sw/controller/src/timer.c b/sw/controller/src/timer.c index f2b91ea..ee50a10 100644 --- a/sw/controller/src/timer.c +++ b/sw/controller/src/timer.c @@ -2,7 +2,7 @@ #include "timer.h" -#define TIMER_PERIOD_MS (50) +#define TIMER_PERIOD_MS (25) typedef struct { diff --git a/sw/controller/src/timer.h b/sw/controller/src/timer.h index fb5c72f..1adb086 100644 --- a/sw/controller/src/timer.h +++ b/sw/controller/src/timer.h @@ -8,6 +8,7 @@ typedef enum { TIMER_ID_DD, + TIMER_ID_LED, TIMER_ID_RTC, TIMER_ID_SD, TIMER_ID_USB,