diff --git a/nametag8_CH592/user/hw/aw20xxx.c b/nametag8_CH592/user/hw/aw20xxx.c index 3e17440..d11b041 100644 --- a/nametag8_CH592/user/hw/aw20xxx.c +++ b/nametag8_CH592/user/hw/aw20xxx.c @@ -69,27 +69,28 @@ void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint aw->config = imax & AW20X_CONF_IMAX_MASK; // wake up (and set page to config page) - aw20x_sleep(aw, 0); + aw20x_set_sleep(aw, 0); // enabled columns aw_buf[0] = cols - 1; + while (AW20X_I2C_busy()); AW20X_I2C_writereg(aw->addr, AW20X_REG_SIZE, aw_buf, 1); // general config aw_buf[0] = imax & AW20X_CONF_IMAX_MASK; - AW20X_I2C_writereg(aw->addr, AW20X_REG_GCCR, aw_buf, 1); while (AW20X_I2C_busy()); + AW20X_I2C_writereg(aw->addr, AW20X_REG_GCCR, aw_buf, 1); } -void aw20x_sleep(struct AW20x *aw, uint8_t sleep) +void aw20x_set_sleep(struct AW20x *aw, uint8_t sleep) { // make sure we're on the config page AW20X_SET_PAGE(AW20X_PAGE0_CONFIG); - // don't touch the buffer until we are allowed - while (AW20X_I2C_busy()); + + aw_buf[0] = sleep ? AW20X_SLPCR_SLEEP : 0; // send sleep bit - aw_buf[0] = sleep ? AW20X_SLPCR_SLEEP : 0; + while (AW20X_I2C_busy()); AW20X_I2C_writereg(aw->addr, AW20X_REG_SLPCR, aw_buf, 1); // set state @@ -102,9 +103,16 @@ void aw20x_sleep(struct AW20x *aw, uint8_t sleep) void aw20x_set_imax(struct AW20x *aw, uint8_t imax) { + // make sure we're on the config page AW20X_SET_PAGE(AW20X_PAGE0_CONFIG); - // todo: implement + aw_buf[0] = imax & AW20X_CONF_IMAX_MASK; + + // send imax + while (AW20X_I2C_busy()); + AW20X_I2C_writereg(aw->addr, AW20X_REG_GCCR, aw_buf, 1); + + aw->config = imax & AW20X_CONF_IMAX_MASK; } /* diff --git a/nametag8_CH592/user/hw/aw20xxx.h b/nametag8_CH592/user/hw/aw20xxx.h index e180e71..e9b1468 100644 --- a/nametag8_CH592/user/hw/aw20xxx.h +++ b/nametag8_CH592/user/hw/aw20xxx.h @@ -181,7 +181,8 @@ typedef struct AW20x { void aw20x_init(struct AW20x *aw, uint8_t addr, uint8_t cols, uint8_t rows, uint8_t imax); -void aw20x_sleep(struct AW20x *aw, uint8_t sleep); +void aw20x_set_sleep(struct AW20x *aw, uint8_t sleep); +void aw20x_set_imax(struct AW20x *aw, uint8_t imax); void aw20x_set_fade(struct AW20x *aw); void aw20x_set_dim_global(struct AW20x *aw, uint8_t dim); diff --git a/nametag8_CH592/user/led/rgbled.c b/nametag8_CH592/user/led/rgbled.c index 7c99220..bfff413 100644 --- a/nametag8_CH592/user/led/rgbled.c +++ b/nametag8_CH592/user/led/rgbled.c @@ -159,3 +159,13 @@ void rgbled_runprog(uint8_t tick_ctr) led_matrix_needs_update = 1; } } + +void rgbled_set_imax_normal() +{ + aw20x_set_imax(&awled, RGBLED_BRT_STANDARD); +} + +void rgbled_set_imax_dim() +{ + aw20x_set_imax(&awled, RGBLED_BRT_DIMMED); +} diff --git a/nametag8_CH592/user/led/rgbled.h b/nametag8_CH592/user/led/rgbled.h index 073ecb6..ecd8aa4 100644 --- a/nametag8_CH592/user/led/rgbled.h +++ b/nametag8_CH592/user/led/rgbled.h @@ -22,11 +22,8 @@ #define RGBLED_COUNT 12 -#define RGB_STR_UNUSED rgb_str_unused -#define RGB_STR_RESERVED rgb_str_reserved -#define RGB_STR_INCREMENT rgb_str_increment -#define RGB_STR_DELAY rgb_str_delay -#define RGB_STR_BRIGHTNESS rgb_str_brightness +#define RGBLED_BRT_STANDARD AW20X_IMAX_13_3MA +#define RGBLED_BRT_DIMMED AW20X_IMAX_3_3MA @@ -38,12 +35,20 @@ typedef struct LedProgram { +#define RGB_STR_UNUSED rgb_str_unused +#define RGB_STR_RESERVED rgb_str_reserved +#define RGB_STR_INCREMENT rgb_str_increment +#define RGB_STR_DELAY rgb_str_delay +#define RGB_STR_BRIGHTNESS rgb_str_brightness + extern const uint8_t rgb_str_unused[]; extern const uint8_t rgb_str_reserved[]; extern const uint8_t rgb_str_increment[]; extern const uint8_t rgb_str_delay[]; extern const uint8_t rgb_str_brightness[]; + + extern const uint8_t rgb_map[RGBLED_COUNT]; extern const LedProgram rgb_pgm[6]; @@ -56,6 +61,9 @@ void rgbled_init(); void rgbled_send(); void rgbled_runprog(uint8_t tick_ctr); +void rgbled_set_imax_normal(); +void rgbled_set_imax_dim(); + #endif /* USER_LED_RGBLED_H_ */ diff --git a/nametag8_CH592/user/main.c b/nametag8_CH592/user/main.c index 0d87106..464a623 100644 --- a/nametag8_CH592/user/main.c +++ b/nametag8_CH592/user/main.c @@ -19,6 +19,9 @@ * - implementing USB interface (once I get time) * - implementing BLE (maybe) * + * todo: + * - decouple oled render routine from interrupt off time. not an issue for now... + * */ #include @@ -55,6 +58,14 @@ #define PROG_TICK_RATE ((32768-8192-4096) / 256) // not sure why this value can't be 32768/256 // this was checked with a stopwatch and is close enough // this value IS FRAMERATE DEPENDENT for some reason... figure it out later +#define IDLE_SLEEP_START (1 << 0) +#define IDLE_MENU_START (1 << 1) +#define IDLE_DIM_START (1 << 2) +#define IDLE_SLEEP_READY (1 << 4) +#define IDLE_MENU_READY (1 << 5) +#define IDLE_DIM_READY (1 << 6) + + const uint8_t vers[] = "241026b"; @@ -68,9 +79,8 @@ uint16_t uptime_hour; uint8_t uptime_min; uint8_t uptime_sec; -uint32_t idle_time_menu; -uint32_t idle_time_still; -uint8_t idle_go_sleep; +uint32_t idle_time = 0; +uint8_t idle_flags; static volatile uint8_t flags_lo = 0; @@ -136,6 +146,25 @@ void systick_init(void) SysTick->CTLR = SysTick_CTLR_STCLK | SysTick_CTLR_STE; // enable counter in /1 mode } + +static void idle_clear() +{ + if (idle_flags & IDLE_SLEEP_READY) { + // wake up things + ssd1306_set_display(1); + + uconf.flags &= ~UCONF_FLAGS_LEDS_DISABLE; + rgbled_send(); + } + + if (idle_flags & IDLE_DIM_READY) { + rgbled_set_imax_normal(); + } + + idle_flags = 0; + idle_time = 0; +} + __HIGH_CODE void oled_update_done() { @@ -180,15 +209,19 @@ 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; + idle_clear(); } // 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; + if (uconf.sleep_timeout && (idle_time == uconf.sleep_timeout)) { + idle_flags |= IDLE_SLEEP_START; + } + if (uconf.menu_timeout && (idle_time == uconf.menu_timeout)) { + idle_flags |= IDLE_MENU_START; + } + if (uconf.dim_timeout && (idle_time == uconf.dim_timeout)) { + rgbled_set_imax_dim(); + idle_flags |= IDLE_DIM_START | IDLE_DIM_READY; } @@ -239,7 +272,25 @@ void lowprio_task() { // todo: implement proper sleep mode that saves power // and wakes up on interrupt, instead of this - if (!idle_go_sleep) { + if (idle_flags & IDLE_SLEEP_START) { + if (!(idle_flags & IDLE_SLEEP_READY)) { + idle_flags |= IDLE_SLEEP_READY; + + // just entered the mode? then turn things off + ssd1306_set_display(0); + + uconf.flags |= UCONF_FLAGS_LEDS_DISABLE; + rgbled_send(); + } else { + // check to see if we should wake + if (accel_get_movement() > 3) { + idle_clear(); + } + } + } + + // run normal program + else { // temporary: re-send sub interrupts, sub button holds, enable rgb_hwen if (flags_lo & FLAG_CH32V_RESEND_CONF) { flags_lo &= ~FLAG_CH32V_RESEND_CONF; @@ -301,36 +352,6 @@ void lowprio_task() { // 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 @@ -405,8 +426,7 @@ void RTC_IRQHandler(void) flags_lo |= FLAG_CH32V_RESEND_CONF; } - idle_time_still++; - idle_time_menu++; + idle_time++; } oled_tick++;