fix pepper programs, store / retrieve user config from flash
fix issues with button handler. pepper programs are now selectable in sequence with the left pepper hat button.
This commit is contained in:
parent
a6966fc32f
commit
6f9444ab5c
|
@ -17,7 +17,13 @@ struct Btn btn[BTN_COUNT] = {0};
|
||||||
|
|
||||||
void btn_init()
|
void btn_init()
|
||||||
{
|
{
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
touch_init();
|
touch_init();
|
||||||
|
|
||||||
|
for (i = 0; i < BTN_COUNT; i++) {
|
||||||
|
btn[i]._mask = BTN_RELEASE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void btn_poll()
|
void btn_poll()
|
||||||
|
@ -29,16 +35,16 @@ void btn_poll()
|
||||||
ignore = btn[i]._mask & BTN_IGNORE;
|
ignore = btn[i]._mask & BTN_IGNORE;
|
||||||
|
|
||||||
if (touch_read_pushed(i)) {
|
if (touch_read_pushed(i)) {
|
||||||
// is pushed
|
|
||||||
if (btn[i]._count < BTN_DEBOUNCE) continue;
|
|
||||||
|
|
||||||
// hold counter
|
// hold counter
|
||||||
if (btn[i]._count < 0xffff) btn[i]._count++;
|
if (btn[i]._count < 0xffff) btn[i]._count++;
|
||||||
|
|
||||||
|
// pushed long enough?
|
||||||
|
if (btn[i]._count < BTN_DEBOUNCE) continue;
|
||||||
|
|
||||||
// first push?
|
// first push?
|
||||||
if (!btn[i]._mask & BTN_PUSH) {
|
if (!(btn[i]._mask & BTN_PUSH)) {
|
||||||
btn[i]._mask = BTN_PUSH;
|
btn[i]._mask = BTN_PUSH | ignore;
|
||||||
if (btn[i].cb_push) {
|
if (btn[i].cb_push && !ignore) {
|
||||||
btn[i].cb_push(i);
|
btn[i].cb_push(i);
|
||||||
btn[i]._mask |= (BTN_PUSH << 4);
|
btn[i]._mask |= (BTN_PUSH << 4);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +52,7 @@ void btn_poll()
|
||||||
// held to count limit
|
// held to count limit
|
||||||
|
|
||||||
// if button is not repeatable, do not retrigger
|
// if button is not repeatable, do not retrigger
|
||||||
if ((btn[i]._mask && BTN_HOLD) && !btn[i].repeat) continue;
|
if ((btn[i]._mask & BTN_HOLD) && !btn[i].repeat) continue;
|
||||||
|
|
||||||
btn[i]._mask |= BTN_HOLD;
|
btn[i]._mask |= BTN_HOLD;
|
||||||
// call callback only if not in ignore state
|
// call callback only if not in ignore state
|
||||||
|
@ -56,11 +62,14 @@ void btn_poll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply repeat rate to count
|
// apply repeat rate to count
|
||||||
btn[i]._count -= btn[i].repeat;
|
if (btn[i].repeat > btn[i]._count) {
|
||||||
|
btn[i]._count = 0;
|
||||||
|
} else btn[i]._count -= btn[i].repeat;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// is not pushed
|
// is not pushed
|
||||||
if (!btn[i]._mask & BTN_RELEASE) {
|
if (!(btn[i]._mask & BTN_RELEASE)) {
|
||||||
|
// note: release will remove ignore status
|
||||||
btn[i]._mask = BTN_RELEASE;
|
btn[i]._mask = BTN_RELEASE;
|
||||||
btn[i]._count = 0;
|
btn[i]._count = 0;
|
||||||
// call callback only if not in ignore state
|
// call callback only if not in ignore state
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* Author: true
|
* Author: true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <ch32v20x.h>
|
#include <ch32v20x.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -42,11 +43,13 @@ uint32_t chip_get_flash_size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t * calc_address()
|
static uint32_t calc_address()
|
||||||
{
|
{
|
||||||
return (uint32_t *)(FLASH_BASE + chip_get_flash_size()) - (CONF_FLASH_PAGE_SIZE * CONF_FLASH_PAGES);
|
uint32_t calc = (FLASH_BASE + chip_get_flash_size()) - (CONF_FLASH_PAGE_SIZE * CONF_FLASH_PAGES);
|
||||||
|
return calc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void read_page_from_flash(uint8_t page, uint32_t *data, uint16_t len)
|
static void read_page_from_flash(uint8_t page, uint32_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
uint32_t *addr = calc_address();
|
uint32_t *addr = calc_address();
|
||||||
|
@ -60,25 +63,26 @@ static void read_page_from_flash(uint8_t page, uint32_t *data, uint16_t len)
|
||||||
// read the data
|
// read the data
|
||||||
flash_read(addr, data, len);
|
flash_read(addr, data, len);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static void write_page_to_flash(uint8_t page, uint32_t *data, uint16_t len)
|
static void write_page_to_flash(uint8_t page, uint32_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
len = (uint16_t)len;
|
len = (uint16_t)len;
|
||||||
|
|
||||||
uint32_t *addr = calc_address() + (page * CONF_FLASH_PAGE_SIZE);
|
uint32_t addr = calc_address() + (page * CONF_FLASH_PAGE_SIZE);
|
||||||
|
|
||||||
// write the data
|
// write the data
|
||||||
// note we don't pass any length. we'll just read whatever garbage
|
// note we don't pass any length. we'll just read whatever garbage
|
||||||
// is in RAM after our config and write it to flash. lol
|
// is in RAM after our config and write it to flash. lol
|
||||||
flash_write256(addr, data);
|
flash_write256((uint32_t *)addr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t checksum()
|
static uint16_t checksum(struct UserConf *conf)
|
||||||
{
|
{
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint16_t sum = 0;
|
uint16_t sum = 0;
|
||||||
|
|
||||||
uint8_t *uc = (uint8_t *)&userconf;
|
uint8_t *uc = (uint8_t *)conf;
|
||||||
|
|
||||||
// calculate checksum
|
// calculate checksum
|
||||||
for (i = 0; i < sizeof(userconf) - 6; i++) {
|
for (i = 0; i < sizeof(userconf) - 6; i++) {
|
||||||
|
@ -90,30 +94,39 @@ static uint16_t checksum()
|
||||||
|
|
||||||
void userconf_load()
|
void userconf_load()
|
||||||
{
|
{
|
||||||
uint8_t valid = 0;
|
uint8_t i;
|
||||||
|
|
||||||
|
uint32_t ver_highest = 0;
|
||||||
|
|
||||||
uint8_t page = CONF_FLASH_PAGES;
|
uint8_t page = CONF_FLASH_PAGES;
|
||||||
|
uint32_t addr;
|
||||||
|
struct UserConf *flash;
|
||||||
|
|
||||||
// read pages backward until we get non-empty flash
|
// read pages and see if we can find our data
|
||||||
while (page) {
|
while (page--) {
|
||||||
read_page_from_flash(--page, (uint32_t *)&userconf, sizeof(userconf)/4);
|
addr = calc_address() + (page * CONF_FLASH_PAGE_SIZE);
|
||||||
if (userconf.checkval == CHECKVAL) {
|
flash = (struct UserConf *)addr;
|
||||||
if (userconf.checksum == checksum()) {
|
if (flash->checkval == CHECKVAL) {
|
||||||
// data appears to be valid... use it
|
if (flash->checksum == checksum(flash)) {
|
||||||
active_page = page;
|
if (ver_highest < flash->version) {
|
||||||
valid = 1;
|
ver_highest = flash->version;
|
||||||
|
active_page = page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!valid) {
|
if (!ver_highest) {
|
||||||
// config is invalid; reset to default
|
// config is invalid; reset to default
|
||||||
userconf.version = 0;
|
userconf.version = 0;
|
||||||
|
|
||||||
userconf.checksum = checksum();
|
// default program configs
|
||||||
userconf.checkval = CHECKVAL;
|
for (i = 0; i < 8; i++) {
|
||||||
|
userconf.pep_conf[i][0] = 0;
|
||||||
// default program connfigs
|
userconf.pep_conf[i][1] = 0;
|
||||||
|
userconf.pep_conf[i][2] = 0;
|
||||||
|
userconf.pep_conf[i][3] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// program 0: flashing
|
// program 0: flashing
|
||||||
userconf.pep_conf[0][0] = 0x80; // brightness
|
userconf.pep_conf[0][0] = 0x80; // brightness
|
||||||
|
@ -122,19 +135,25 @@ void userconf_load()
|
||||||
// program 2: loops
|
// program 2: loops
|
||||||
userconf.pep_conf[2][0] = 0xc0; // brightness
|
userconf.pep_conf[2][0] = 0xc0; // brightness
|
||||||
userconf.pep_conf[2][1] = 0; // looping rate
|
userconf.pep_conf[2][1] = 0; // looping rate
|
||||||
userconf.pep_conf[2][3] = 3; // decay rate
|
userconf.pep_conf[2][3] = 1; // decay rate
|
||||||
|
|
||||||
// program 4: alternating
|
// program 4: alternating
|
||||||
userconf.pep_conf[4][0] = 0x80; // brightness
|
userconf.pep_conf[4][0] = 0x80; // brightness
|
||||||
userconf.pep_conf[4][1] = 8; // flash rate
|
userconf.pep_conf[4][1] = 12; // flash rate
|
||||||
userconf.pep_conf[4][3] = 0x0b; // lower brightness on alternate
|
userconf.pep_conf[4][3] = 0x0b; // lower brightness on alternate
|
||||||
|
|
||||||
|
userconf.checksum = checksum(&userconf);
|
||||||
|
userconf.checkval = CHECKVAL;
|
||||||
|
} else {
|
||||||
|
memcpy(&userconf, (uint8_t *)(calc_address() + (active_page * 256)), sizeof(userconf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void userconf_save()
|
void userconf_save()
|
||||||
{
|
{
|
||||||
|
// we can only save ~4 billion times
|
||||||
userconf.version++;
|
userconf.version++;
|
||||||
userconf.checksum = checksum();
|
userconf.checksum = checksum(&userconf);
|
||||||
userconf.checkval = CHECKVAL;
|
userconf.checkval = CHECKVAL;
|
||||||
|
|
||||||
// determine page to write
|
// determine page to write
|
||||||
|
@ -145,6 +164,5 @@ void userconf_save()
|
||||||
// nothing is mentioned in the datasheet nor reference manual
|
// nothing is mentioned in the datasheet nor reference manual
|
||||||
// about repeated writes. so to be safe, each page gets
|
// about repeated writes. so to be safe, each page gets
|
||||||
// written to once per erase.
|
// written to once per erase.
|
||||||
|
|
||||||
write_page_to_flash(active_page, (uint32_t *)&userconf, sizeof(userconf)/4);
|
write_page_to_flash(active_page, (uint32_t *)&userconf, sizeof(userconf)/4);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,15 @@ void led_init()
|
||||||
TIM_TimeBaseInitTypeDef timer ={0};
|
TIM_TimeBaseInitTypeDef timer ={0};
|
||||||
TIM_OCInitTypeDef pwm = {0};
|
TIM_OCInitTypeDef pwm = {0};
|
||||||
|
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
|
||||||
|
// reset LED values
|
||||||
|
for (i = 0; i < FL3729_SW_COUNT * FL3729_CS_COUNT; i++) {
|
||||||
|
led.all[i] = 0;
|
||||||
|
}
|
||||||
|
rgb[0] = rgb[1] = rgb[2] = 0;
|
||||||
|
|
||||||
|
|
||||||
// configure matrix
|
// configure matrix
|
||||||
is31fl3729_init(FL3729_ADDR,
|
is31fl3729_init(FL3729_ADDR,
|
||||||
|
|
|
@ -195,17 +195,53 @@ static void pep_2_loops(uint8_t tick)
|
||||||
* segment, upper and lower, turns on
|
* segment, upper and lower, turns on
|
||||||
* after both segments are on the separator goes off
|
* after both segments are on the separator goes off
|
||||||
*/
|
*/
|
||||||
|
static uint8_t flicker_count[2];
|
||||||
|
static uint8_t flicker_delay[2];
|
||||||
|
static uint8_t flicker_timer[2];
|
||||||
|
|
||||||
static void pep_3_neon_sign(uint8_t tick)
|
static void pep_3_neon_sign(uint8_t tick)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
|
uint16_t rnd;
|
||||||
|
uint8_t target;
|
||||||
|
|
||||||
|
if (tick & 4) {
|
||||||
|
rnd = prng_get8();
|
||||||
|
if (rnd >= 0xfc) {
|
||||||
|
// do a flicker
|
||||||
|
target = rnd & 1;
|
||||||
|
|
||||||
|
flicker_count[target] = prng_scale16(1, 4) << 1;
|
||||||
|
flicker_delay[target] = prng_scale16(12, 240);
|
||||||
|
|
||||||
|
if (rnd & 2) {
|
||||||
|
flicker_count[target ^ 1] = flicker_count[target];
|
||||||
|
flicker_delay[target ^ 1] = flicker_delay[target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// todo: implement flickering on/off
|
// todo: implement flickering on/off
|
||||||
// like a flourescent tube warming up or failing
|
// like a flourescent tube warming up or failing
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
if (flicker_count[i]) {
|
||||||
|
if (flicker_timer[i]) {
|
||||||
|
flicker_timer[i]--;
|
||||||
|
} else {
|
||||||
|
flicker_count[i]--;
|
||||||
|
flicker_timer[i] = flicker_delay[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < LED_PEP_COUNT; i++) {
|
for (i = 0; i < LED_PEP_COUNT; i++) {
|
||||||
led.section.pep[i] = (tick & 2) ? 0x40 : 16;
|
led.section.pep[i] = flicker_count[0] & 1 ? 0 : 0x80;
|
||||||
}
|
}
|
||||||
for (i = 0; i < LED_HAT_COUNT; i++) {
|
for (i = 0; i < LED_HAT_COUNT; i++) {
|
||||||
led.section.hat[i] = (tick & 2) ? 0x80 : 24;
|
led.section.hat[i] = flicker_count[1] & 1 ? 0 : 0x60;
|
||||||
}
|
}
|
||||||
|
|
||||||
led_matrix_is_updated();
|
led_matrix_is_updated();
|
||||||
|
@ -257,9 +293,10 @@ static const uint8_t nom_map[5][2] = {
|
||||||
{14, 21},
|
{14, 21},
|
||||||
{12, 23},
|
{12, 23},
|
||||||
{ 9, 24},
|
{ 9, 24},
|
||||||
{ 5, 27},
|
{ 7, 27},
|
||||||
{ 2, 29}
|
{ 3, 28}
|
||||||
};
|
};
|
||||||
|
uint16_t nom_timeout = 0;
|
||||||
|
|
||||||
static void pep_5_nom(uint8_t tick)
|
static void pep_5_nom(uint8_t tick)
|
||||||
{
|
{
|
||||||
|
@ -269,13 +306,21 @@ static void pep_5_nom(uint8_t tick)
|
||||||
switch (pep_work[0]) {
|
switch (pep_work[0]) {
|
||||||
case 0:
|
case 0:
|
||||||
case 2: { // wait a while
|
case 2: { // wait a while
|
||||||
if (!pep_work[2]) {
|
if (!nom_timeout) {
|
||||||
// just got here; set a new random timeout
|
// just got here; set a new random timeout
|
||||||
pep_work[2] = 0xff - (prng_get8() >> 2);
|
nom_timeout = 0x3ff - prng_get8();
|
||||||
|
// also set the pepper to be on
|
||||||
|
for (i = LED_PEP_NOTOP; i < LED_PEP_COUNT; i++) {
|
||||||
|
led.section.pep[i] = 0x80;
|
||||||
|
}
|
||||||
|
for (i = 0; i < LED_HAT_COUNT; i++) {
|
||||||
|
led.section.hat[i] = 0x60;
|
||||||
|
}
|
||||||
|
led_matrix_is_updated();
|
||||||
} else {
|
} else {
|
||||||
// wait around for a little while
|
// wait around for a little while
|
||||||
pep_work[2]--;
|
nom_timeout--;
|
||||||
if (!pep_work[2]) {
|
if (!nom_timeout) {
|
||||||
// done here
|
// done here
|
||||||
pep_work[1] = 0;
|
pep_work[1] = 0;
|
||||||
pep_work[0]++;
|
pep_work[0]++;
|
||||||
|
@ -286,9 +331,28 @@ static void pep_5_nom(uint8_t tick)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1: { // eat the pepper
|
case 1: { // regen the pepper
|
||||||
|
if (led.section.pep[pep_work[1]] >= (0x80 - 4)) {
|
||||||
|
// next segment
|
||||||
|
pep_work[1]++;
|
||||||
|
if (pep_work[1] > (LED_PEP_NOTOP - pep_work[1])) {
|
||||||
|
// we're done regenerating
|
||||||
|
pep_work[0]++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
led.section.pep[pep_work[1]] += 4;
|
||||||
|
if (pep_work[1]) {
|
||||||
|
led.section.pep[LED_PEP_NOTOP - pep_work[1]] = led.section.pep[pep_work[1]];
|
||||||
|
}
|
||||||
|
led_matrix_is_updated();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3: { // eat the pepper
|
||||||
// eat at about one bite per second
|
// eat at about one bite per second
|
||||||
if ((tick & 0x3f) != 0) break;
|
if ((tick & 0x7f) != 0) break;
|
||||||
|
|
||||||
start = 0;
|
start = 0;
|
||||||
|
|
||||||
|
@ -321,26 +385,7 @@ static void pep_5_nom(uint8_t tick)
|
||||||
|
|
||||||
pep_work[1]++;
|
pep_work[1]++;
|
||||||
|
|
||||||
if (pep_work[1] > 6) pep_work[0]++;
|
if (pep_work[1] > 6) pep_work[0] = 0;
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3: { // regen the pepper
|
|
||||||
if (led.section.pep[pep_work[1]] >= (0x80 - 4)) {
|
|
||||||
// next segment
|
|
||||||
pep_work[1]++;
|
|
||||||
if (pep_work[1] > (LED_PEP_NOTOP - pep_work[1])) {
|
|
||||||
// we're done regenerating
|
|
||||||
pep_work[0] = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
led.section.pep[pep_work[1]] += 4;
|
|
||||||
if (pep_work[1]) {
|
|
||||||
led.section.pep[LED_PEP_NOTOP - pep_work[1]] = led.section.pep[pep_work[1]];
|
|
||||||
}
|
|
||||||
led_matrix_is_updated();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +458,7 @@ void ledprog_pep_init()
|
||||||
}
|
}
|
||||||
|
|
||||||
// per-program initialization
|
// per-program initialization
|
||||||
|
nom_timeout = 0;
|
||||||
|
|
||||||
// there is none on this badge
|
// there is none on this badge
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,18 @@ static uint16_t rgb_work[4];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void rgb_0_nothing(uint8_t tick)
|
||||||
|
{
|
||||||
|
rgb[0] = rgb[1] = rgb[2] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* rainbow puke
|
* rainbow puke
|
||||||
*/
|
*/
|
||||||
|
static void rgb_1_rainbow(uint8_t tick)
|
||||||
static void rgb_0_rainbow(uint8_t tick)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +34,7 @@ static void rgb_0_rainbow(uint8_t tick)
|
||||||
/*
|
/*
|
||||||
* static color with bright flickers
|
* static color with bright flickers
|
||||||
*/
|
*/
|
||||||
static void rgb_1_flicker(uint8_t tick)
|
static void rgb_2_candle(uint8_t tick)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,17 +42,18 @@ static void rgb_1_flicker(uint8_t tick)
|
||||||
/*
|
/*
|
||||||
* alternate between two colors
|
* alternate between two colors
|
||||||
*/
|
*/
|
||||||
static void rgb_2_alternate(uint8_t tick)
|
static void rgb_3_alternate(uint8_t tick)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const void (*ledprog_rgb[4])(uint8_t) = {
|
void (*ledprog_rgb[4])(uint8_t) = {
|
||||||
(const void (*)(uint8_t))rgb_0_rainbow,
|
rgb_0_nothing,
|
||||||
(const void (*)(uint8_t))rgb_1_flicker,
|
rgb_1_rainbow,
|
||||||
(const void (*)(uint8_t))rgb_2_alternate
|
rgb_2_candle,
|
||||||
|
rgb_3_alternate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern void (*ledprog_rgb[8])(uint8_t, uint8_t);
|
extern void (*ledprog_rgb[8])(uint8_t);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,11 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
#include "adc.h"
|
#include "adc.h"
|
||||||
#include "btn.h"
|
#include "btn.h"
|
||||||
|
#include "config.h"
|
||||||
#include "led.h"
|
#include "led.h"
|
||||||
#include "ledprog_pep.h"
|
#include "ledprog_pep.h"
|
||||||
#include "ledprog_rgb.h"
|
#include "ledprog_rgb.h"
|
||||||
|
@ -16,11 +19,13 @@
|
||||||
#define MODE_PROGRAM 1
|
#define MODE_PROGRAM 1
|
||||||
#define MODE_PARAMETER 2
|
#define MODE_PARAMETER 2
|
||||||
|
|
||||||
#define UI_CONF_SAVE_TIMEOUT 160
|
#define UI_CONF_SAVE_TIMEOUT 512
|
||||||
|
|
||||||
#define UI_PROG_RUNTIME_MIN (128*15) // 15 seconds
|
#define UI_PROG_RUNTIME_MIN (128*15) // 15 seconds
|
||||||
#define UI_PROG_RUNTIME_MAX (128*120) // 120 seconds
|
#define UI_PROG_RUNTIME_MAX (128*120) // 120 seconds
|
||||||
|
|
||||||
|
#define PROG_REPEAT 0x80
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const uint8_t led_gc_map[] = {
|
static const uint8_t led_gc_map[] = {
|
||||||
|
@ -35,6 +40,8 @@ static const uint8_t led_gc_map[] = {
|
||||||
static uint8_t mode = MODE_RUN;
|
static uint8_t mode = MODE_RUN;
|
||||||
static uint8_t tick = 0;
|
static uint8_t tick = 0;
|
||||||
|
|
||||||
|
static uint16_t save_delay = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ui_btn_push_cb(uint8_t idx)
|
void ui_btn_push_cb(uint8_t idx)
|
||||||
|
@ -44,33 +51,61 @@ void ui_btn_push_cb(uint8_t idx)
|
||||||
|
|
||||||
void ui_btn_hold_cb(uint8_t idx)
|
void ui_btn_hold_cb(uint8_t idx)
|
||||||
{
|
{
|
||||||
|
switch (idx) {
|
||||||
|
case 0: { // left pepper hat
|
||||||
|
userconf.pep_prog_ena_map ^= PROG_REPEAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: { // right pepper hat
|
||||||
|
userconf.rgb_prog_ena_map ^= PROG_REPEAT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_btn_release_cb(uint8_t idx)
|
void ui_btn_release_cb(uint8_t idx)
|
||||||
{
|
{
|
||||||
|
uint8_t update;
|
||||||
|
|
||||||
|
switch (idx) {
|
||||||
|
case 0: { // left pepper hat
|
||||||
|
update = userconf.pep_prog_ena_map & ~(PROG_REPEAT);
|
||||||
|
update++;
|
||||||
|
if (update > 5) update = 0;
|
||||||
|
userconf.pep_prog_ena_map = update | (userconf.pep_prog_ena_map & PROG_REPEAT);
|
||||||
|
ledprog_pep_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: { // right pepper hat
|
||||||
|
update = userconf.rgb_prog_ena_map & ~(PROG_REPEAT);
|
||||||
|
update++;
|
||||||
|
if (update > 3) update = 0;
|
||||||
|
userconf.rgb_prog_ena_map = update | (userconf.rgb_prog_ena_map & PROG_REPEAT);
|
||||||
|
ledprog_rgb_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
save_delay = UI_CONF_SAVE_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ui_init()
|
void ui_init()
|
||||||
{
|
{
|
||||||
btn[0].hold = 330 >> 1;
|
btn[0].hold = 1200 >> 1;
|
||||||
btn[0].repeat = 0; // (1000 / 20) >> 1;
|
btn[0].repeat = 0; // (1000 / 20) >> 1;
|
||||||
btn[0].cb_push = ui_btn_push_cb;
|
btn[0].cb_push = ui_btn_push_cb;
|
||||||
btn[0].cb_hold = ui_btn_hold_cb;
|
btn[0].cb_hold = ui_btn_hold_cb;
|
||||||
btn[0].cb_release = ui_btn_release_cb;
|
btn[0].cb_release = ui_btn_release_cb;
|
||||||
|
|
||||||
btn[1].hold = 330 >> 1;
|
btn[1].hold = 1200 >> 1;
|
||||||
btn[1].repeat = 0;
|
btn[1].repeat = 0;
|
||||||
btn[1].cb_push = ui_btn_push_cb;
|
btn[1].cb_push = ui_btn_push_cb;
|
||||||
btn[1].cb_hold = ui_btn_hold_cb;
|
btn[1].cb_hold = ui_btn_hold_cb;
|
||||||
btn[1].cb_release = ui_btn_release_cb;
|
btn[1].cb_release = ui_btn_release_cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t tmp;
|
|
||||||
volatile uint8_t prog_run = 5;
|
|
||||||
|
|
||||||
void ui_render()
|
void ui_render()
|
||||||
{
|
{
|
||||||
|
@ -78,8 +113,27 @@ void ui_render()
|
||||||
|
|
||||||
tick++;
|
tick++;
|
||||||
|
|
||||||
|
uint8_t prog_pep_idx = userconf.pep_prog_ena_map & ~(PROG_REPEAT);
|
||||||
|
uint8_t prog_rgb_idx = userconf.rgb_prog_ena_map & ~(PROG_REPEAT);
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case MODE_RUN: {
|
case MODE_RUN: {
|
||||||
|
// run programs
|
||||||
|
if (ledprog_pep[prog_pep_idx]) {
|
||||||
|
ledprog_pep[prog_pep_idx](tick);
|
||||||
|
}
|
||||||
|
if (ledprog_rgb[prog_rgb_idx]) {
|
||||||
|
ledprog_rgb[prog_rgb_idx](tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check flash save
|
||||||
|
if (save_delay) {
|
||||||
|
save_delay--;
|
||||||
|
if (!save_delay) {
|
||||||
|
userconf_save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +161,7 @@ void ui_render()
|
||||||
|
|
||||||
// temporary: testing
|
// temporary: testing
|
||||||
|
|
||||||
ledprog_pep[prog_run](tick);
|
// ledprog_pep[prog_run](tick);
|
||||||
/*
|
/*
|
||||||
if ((tick & 3) == 3) {
|
if ((tick & 3) == 3) {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue