diff --git a/bootloader/main.c b/bootloader/main.c index 35989a4..7c3bfb3 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -35,7 +35,6 @@ #include "rtc/max77620-rtc.h" #include "soc/hw_init.h" #include "soc/i2c.h" -#include "soc/pmc.h" #include "soc/t210.h" #include "soc/uart.h" #include "storage/sdmmc.h" @@ -191,56 +190,6 @@ void emmcsn_path_impl(char *path, char *sub_dir, char *filename, sdmmc_storage_t sdmmc_storage_end(&storage2); } -void panic(u32 val) -{ - // Set panic code. - PMC(APBDEV_PMC_SCRATCH200) = val; - //PMC(APBDEV_PMC_CRYPTO_OP) = 1; // Disable SE. - TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN; - TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN; - TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN; - TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; - while (1) - ; -} - -void reboot_normal() -{ - sd_unmount(); -#ifdef MENU_LOGO_ENABLE - free(Kc_MENU_LOGO); -#endif //MENU_LOGO_ENABLE - display_end(); - panic(0x21); // Bypass fuse programming in package1. -} - -void reboot_rcm() -{ - sd_unmount(); -#ifdef MENU_LOGO_ENABLE - free(Kc_MENU_LOGO); -#endif //MENU_LOGO_ENABLE - display_end(); - PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm. - PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST; - while (true) - usleep(1); -} - -void power_off() -{ - sd_unmount(); - - // Stop the alarm, in case we injected and powered off too fast. - max77620_rtc_stop_alarm(); - -#ifdef MENU_LOGO_ENABLE - free(Kc_MENU_LOGO); -#endif //MENU_LOGO_ENABLE - //TODO: we should probably make sure all regulators are powered off properly. - i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); -} - void check_power_off_from_hos() { // Power off on AutoRCM wakeup from HOS shutdown. For modchips/dongles. diff --git a/bootloader/utils/btn.c b/bootloader/utils/btn.c index 795ee93..9b383a4 100644 --- a/bootloader/utils/btn.c +++ b/bootloader/utils/btn.c @@ -22,9 +22,9 @@ #include "util.h" #include "../power/max77620.h" -u32 btn_read() +u8 btn_read() { - u32 res = 0; + u8 res = 0; if (!gpio_read(GPIO_PORT_X, GPIO_PIN_7)) res |= BTN_VOL_DOWN; if (!gpio_read(GPIO_PORT_X, GPIO_PIN_6)) @@ -34,9 +34,9 @@ u32 btn_read() return res; } -u32 btn_wait() +u8 btn_wait() { - u32 res = 0, btn = btn_read(); + u8 res = 0, btn = btn_read(); bool pwr = false; //Power button down, raise a filter. @@ -59,14 +59,16 @@ u32 btn_wait() return res; } -u32 btn_wait_timeout(u32 time_ms, u32 mask) +u8 btn_wait_timeout(u32 time_ms, u8 mask) { u32 timeout = get_tmr_ms() + time_ms; - u32 res = btn_read() & mask; + u8 res = btn_read() & mask; do { - if (!(res & mask)) + if (res == mask) + break; + else res = btn_read() & mask; } while (get_tmr_ms() < timeout); diff --git a/bootloader/utils/btn.h b/bootloader/utils/btn.h index ddc28bc..ede13ac 100644 --- a/bootloader/utils/btn.h +++ b/bootloader/utils/btn.h @@ -20,12 +20,12 @@ #include "types.h" -#define BTN_POWER 0x1 -#define BTN_VOL_DOWN 0x2 -#define BTN_VOL_UP 0x4 +#define BTN_POWER (1 << 0) +#define BTN_VOL_DOWN (1 << 1) +#define BTN_VOL_UP (1 << 2) -u32 btn_read(); -u32 btn_wait(); -u32 btn_wait_timeout(u32 time_ms, u32 mask); +u8 btn_read(); +u8 btn_wait(); +u8 btn_wait_timeout(u32 time_ms, u8 mask); #endif diff --git a/bootloader/utils/util.c b/bootloader/utils/util.c index ff5f59f..c34764a 100644 --- a/bootloader/utils/util.c +++ b/bootloader/utils/util.c @@ -16,8 +16,15 @@ */ #include "util.h" +#include "../gfx/di.h" +#include "../power/max77620.h" +#include "../rtc/max77620-rtc.h" +#include "../soc/i2c.h" +#include "../soc/pmc.h" #include "../soc/t210.h" +extern void sd_unmount(); + u32 get_tmr_s() { return RTC(APBDEV_RTC_SECONDS); @@ -56,6 +63,50 @@ void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops) base[ops[i].off] = ops[i].val; } +void panic(u32 val) +{ + // Set panic code. + PMC(APBDEV_PMC_SCRATCH200) = val; + //PMC(APBDEV_PMC_CRYPTO_OP) = PMC_CRYPTO_OP_SE_DISABLE; + TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN; + TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN; + TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | TIMER_PMCRESET_EN; + TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT; + while (1) + ; +} + +void reboot_normal() +{ + sd_unmount(); + display_end(); + + panic(0x21); // Bypass fuse programming in package1. +} + +void reboot_rcm() +{ + sd_unmount(); + display_end(); + + PMC(APBDEV_PMC_SCRATCH0) = 2; // Reboot into rcm. + PMC(APBDEV_PMC_CNTRL) |= PMC_CNTRL_MAIN_RST; + + while (true) + usleep(1); +} + +void power_off() +{ + sd_unmount(); + + // Stop the alarm, in case we injected and powered off too fast. + max77620_rtc_stop_alarm(); + + //TODO: we should probably make sure all regulators are powered off properly. + i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_ONOFFCNFG1, MAX77620_ONOFFCNFG1_PWR_OFF); +} + #define CRC32C_POLY 0x82F63B78 u32 crc32c(const void *buf, u32 len) { diff --git a/bootloader/utils/util.h b/bootloader/utils/util.h index e73913a..3b57703 100644 --- a/bootloader/utils/util.h +++ b/bootloader/utils/util.h @@ -34,6 +34,10 @@ u32 get_tmr_ms(); u32 get_tmr_s(); void usleep(u32 ticks); void msleep(u32 milliseconds); +void panic(u32 val); +void reboot_normal(); +void reboot_rcm(); +void power_off(); void exec_cfg(u32 *base, const cfg_op_t *ops, u32 num_ops); u32 crc32c(const void *buf, u32 len);