diff --git a/nametag8_CH592/user/main.c b/nametag8_CH592/user/main.c index 551b5f5..d054ddb 100644 --- a/nametag8_CH592/user/main.c +++ b/nametag8_CH592/user/main.c @@ -167,7 +167,18 @@ void oled_update_done() } // power saving + // todo: don't hardcode the movement values + if (accel_get_movement() > 3) { + idle_go_sleep = 0; + idle_time_still = 0; + idle_time_menu = 0; + } + + // start going to sleep if the option is enabled and if we've been still for enough time + if (uconf.sleep_timeout && (idle_time_still > uconf.sleep_timeout)) { + idle_go_sleep = 1; + } #ifdef MENU_TIMEOUT_TO_NAMETAG @@ -210,68 +221,104 @@ void lowprio_task() { // can corrupt transactions SYS_DisableAllIrq(&interrupt_flags); - // temporary: re-send sub interrupts, sub button holds, enable rgb_hwen - if (flags_lo & FLAG_CH32V_RESEND_CONF) { - flags_lo &= ~FLAG_CH32V_RESEND_CONF; - ch32sub_intr_defaults(); - btn_commit_hold(); - ch32sub_rgb_hwen(1); - } - - // process sub MCU interrupt, if pending - ch32sub_process(); - - if (flags_lo & FLAG_RGBLED_SEND) { - flags_lo &= ~FLAG_RGBLED_SEND; - rgbled_send(); - } - if (flags_lo & FLAG_ACCEL_POLL) { flags_lo &= ~FLAG_ACCEL_POLL; accel_poll(); } - // send the last oled frame data - if (flags_lo & FLAG_OLED_UPDATE) { - flags_lo &= ~FLAG_OLED_UPDATE; - - /*** oled ***/ - if (oled.callback && !(oled.state & SSD1306_STATE_BUSY)) { - if (ssd1306_cb_get()) { - oled.callback(); - } + // todo: implement proper sleep mode that saves power + // and wakes up on interrupt, instead of this + if (!idle_go_sleep) { + // temporary: re-send sub interrupts, sub button holds, enable rgb_hwen + if (flags_lo & FLAG_CH32V_RESEND_CONF) { + flags_lo &= ~FLAG_CH32V_RESEND_CONF; + ch32sub_intr_defaults(); + btn_commit_hold(); + ch32sub_rgb_hwen(1); } - // update - // only update this frame if we're not in the middle of starting up - if (uptime) { - // process other tasks - if (oled.state & SSD1306_STATE_INITIALIZED) { - oled.callback = oled_update_done; - } - ssd1306_update(); + // process sub MCU interrupt, if pending + ch32sub_process(); + + if (flags_lo & FLAG_RGBLED_SEND) { + flags_lo &= ~FLAG_RGBLED_SEND; + rgbled_send(); } - cpu_use = SysTick->CNT; + // send the last oled frame data + if (flags_lo & FLAG_OLED_UPDATE) { + flags_lo &= ~FLAG_OLED_UPDATE; + + if (oled.callback && !(oled.state & SSD1306_STATE_BUSY)) { + if (ssd1306_cb_get()) { + oled.callback(); + } + } + + // update + // only update this frame if we're not in the middle of starting up + if (uptime) { + // process other tasks + if (oled.state & SSD1306_STATE_INITIALIZED) { + oled.callback = oled_update_done; + } + ssd1306_update(); + } + + cpu_use = SysTick->CNT; + } + + // re-enable IRQs + SYS_RecoverIrq(interrupt_flags); + + // render new rgbled frame + // this is not included in cpu calcs :/ + if (flags_lo & FLAG_RGBLED_RUN) { + flags_lo &= ~FLAG_RGBLED_RUN; + + // make sure a valid program is selected + if (uconf.ledprog_rgb_idx > (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]))) { + uconf.ledprog_rgb_idx = 0; + } + + // now run a program + rgbled_runprog(st_tick >> 2); + } + } else { + switch (idle_go_sleep) { + case 1: { + idle_go_sleep++; + + // just entered the mode? then turn things off + ssd1306_set_display(0); + + uconf.flags |= UCONF_FLAGS_LEDS_DISABLE; + rgbled_send(); + + break; + } + default: { + // check to see if we should wake + if (accel_get_movement() > 3) { + idle_go_sleep = 0; + + idle_time_still = 0; + idle_time_menu = 0; + + // wake up things + ssd1306_set_display(1); + + uconf.flags &= ~UCONF_FLAGS_LEDS_DISABLE; + rgbled_send(); + } + break; + } + } } // re-enable IRQs SYS_RecoverIrq(interrupt_flags); - // render new rgbled frame - // this is not included in cpu calcs :/ - if (flags_lo & FLAG_RGBLED_RUN) { - flags_lo &= ~FLAG_RGBLED_RUN; - - // make sure a valid program is selected - if (uconf.ledprog_rgb_idx > (sizeof(rgb_pgm) / sizeof(rgb_pgm[0]))) { - uconf.ledprog_rgb_idx = 0; - } - - // now run a program - rgbled_runprog(st_tick >> 2); - } - // drop into lower clock rate SetSysClock(SYSCLK_FREQ_IDLE); } @@ -342,6 +389,7 @@ void RTC_IRQHandler(void) } idle_time_still++; + idle_time_menu++; } oled_tick++; diff --git a/nametag8_CH592/user/misc/accel.c b/nametag8_CH592/user/misc/accel.c index ad0e758..240d255 100644 --- a/nametag8_CH592/user/misc/accel.c +++ b/nametag8_CH592/user/misc/accel.c @@ -13,6 +13,7 @@ #include "misc/i8atan2.h" #include +#include @@ -20,8 +21,11 @@ AccelData accel; uint8_t accel_found = 0; -int16_t movement; -uint16_t movement_worst; + +uint8_t movement_idx; // index into "read" register +int16_t movement_read[4]; // last read movement value +int16_t movement; // last calculated movement value +uint16_t movement_worst; // worst seen movement value // hardware @@ -29,7 +33,6 @@ static stmdev_ctx_t dev_ctx; - int32_t accel_i2c_write(void *handle, uint8_t reg, const uint8_t *bufp, uint16_t len) { (void)(handle); @@ -96,6 +99,7 @@ void accel_init() } } +__HIGH_CODE void accel_poll() { uint8_t reg = 1; @@ -111,13 +115,30 @@ void accel_poll() // read acceleration data memset(xyz, 0x00, 3 * sizeof(int16_t)); lis2dw12_acceleration_raw_get(&dev_ctx, xyz); + accel.x = xyz[0] >>= 8; accel.y = xyz[1] >>= 8; accel.z = xyz[2] >>= 8; + + // compute our shitty "movement" thing + // awful way to detect being still + reg = sizeof(movement_read) / sizeof(movement_read[0]); + + movement_idx++; + if (movement_idx == reg) { + movement_idx = 0; + movement = abs(movement_read[3] - movement_read[0]); + if (movement > movement_worst) { + movement_worst = movement; + } + } + + movement_read[movement_idx] = abs(accel.x) + abs(accel.y); } } } +__HIGH_CODE int8_t accel_get_rotation(struct AccelData *a) { int8_t nx, ny, ret; diff --git a/nametag8_CH592/user/misc/accel.h b/nametag8_CH592/user/misc/accel.h index 738db03..e79b520 100644 --- a/nametag8_CH592/user/misc/accel.h +++ b/nametag8_CH592/user/misc/accel.h @@ -27,8 +27,8 @@ typedef struct AccelData { extern AccelData accel; - extern uint8_t accel_found; + extern uint16_t movement_worst; diff --git a/nametag8_CH592/user/ui/menu_entry_6.c b/nametag8_CH592/user/ui/menu_entry_6.c index 2fb9f49..1b35292 100644 --- a/nametag8_CH592/user/ui/menu_entry_6.c +++ b/nametag8_CH592/user/ui/menu_entry_6.c @@ -217,7 +217,7 @@ void menu_6_disp(uint8_t idx) sprintf(txt, "m%i", abs(accel_get_movement())); ssd1306fb_set_cursor(104, 10); ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0); - sprintf(txt, "w%d", 0); // todo: fix this: movement_worst); + sprintf(txt, "w%d", movement_worst); ssd1306fb_set_cursor(106, 17); ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0); diff --git a/nametag8_CH592/user/user_config.c b/nametag8_CH592/user/user_config.c index 420fea1..c4bdd5f 100644 --- a/nametag8_CH592/user/user_config.c +++ b/nametag8_CH592/user/user_config.c @@ -32,34 +32,34 @@ static const uint8_t uconf_edge_defaults[8][8] = { -static void uconf_defaults() +void uconf_defaults() { int i; - uconf.ver = UCONF_VER; - uconf.flags = UCONF_FLAGS_LEDS_ENABLE; - uconf.framemod = UCONF_FRAMERATE_FULL; - uconf.nameconf = UCONF_NAME_DISP_DEMOWAVE1 | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT; + uconf.ver = UCONF_VER; + uconf.flags = UCONF_FLAGS_LEDS_ENABLE; + uconf.framemod = UCONF_FRAMERATE_FULL; + uconf.nameconf = UCONF_NAME_DISP_DEMOWAVE1 | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT; // UCONF_NAME_DISP_DEMOWAVES1 | UCONF_NAME_MODE_AUTOROTATE | UCONF_NAME_MODE_COLOR_INVERT; if (uconf_flash_offset == 0xf0) { - uconf.iter = 0; + uconf.iter = 0; } - uconf.font_idx = 4; - uconf.char_spacing = 2; - uconf.y_offset = 0; + uconf.font_idx = 4; + uconf.char_spacing = 2; + uconf.y_offset = 0; // todo: add LUT strcpy(uconf.name, "Supercon"); - uconf.favcolor_hue = 170; - uconf.favcolor_sat = 240; - uconf.favcolor_val = 32; + uconf.favcolor_hue = 170; + uconf.favcolor_sat = 240; + uconf.favcolor_val = 32; - uconf.altcolor_hue = 0; - uconf.altcolor_sat = 240; - uconf.altcolor_val = 32; + uconf.altcolor_hue = 0; + uconf.altcolor_sat = 240; + uconf.altcolor_val = 32; - uconf.ledprog_rgb_idx = 4; + uconf.ledprog_rgb_idx = 4; for (i = 0; i < 8; i++) { uconf.ledprog_rgb[i] = 0; @@ -67,10 +67,11 @@ static void uconf_defaults() memcpy(uconf.ledprog_rgb_data, uconf_edge_defaults, sizeof(uconf_edge_defaults)); - uconf.lsens_dark_thresh = 0x6a0; // todo: figure out what this should be by testing - uconf.sleep_timeout = 20 * 60; + uconf.lsens_dark_thresh = 0x6a0; // todo: figure out what this should be by testing + uconf.menu_timeout = 5 * 60; + uconf.sleep_timeout = 20 * 60; - uconf.checksum = checksum_gen((uint8_t *)&uconf, sizeof(uconf) - 2); + uconf.checksum = checksum_gen((uint8_t *)&uconf, sizeof(uconf) - 2); } static int8_t uconf_validate() diff --git a/nametag8_CH592/user/user_config.h b/nametag8_CH592/user/user_config.h index c28c92e..8301c53 100644 --- a/nametag8_CH592/user/user_config.h +++ b/nametag8_CH592/user/user_config.h @@ -83,8 +83,9 @@ typedef struct UserConf { uint8_t padding0; // 52 uint8_t ledprog_rgb[16]; // 68 uint8_t ledprog_rgb_data[16][8]; // 196 - uint8_t padding1[52]; // 248 - uint16_t lsens_dark_thresh; // 250 + uint8_t padding1[50]; // 246 + uint16_t lsens_dark_thresh; // 248 + uint16_t menu_timeout; // 250 uint16_t sleep_timeout; // 252 uint16_t tempcx10_offset; // 253-254 uint16_t checksum; // 255-256 @@ -106,6 +107,8 @@ extern uint8_t temp_degc_decimal; void uconf_load(); void uconf_write(); +void uconf_defaults(); + #endif /* USER_CONFIG_H_ */