implement factory reset, fix eeprom write routine

This commit is contained in:
true 2024-10-27 04:14:37 -07:00
parent 36e091a949
commit ea3f6ae9e0
9 changed files with 114 additions and 29 deletions

View File

@ -22,9 +22,9 @@
* - there is no ack on address. code always assumes slave is responding.
*/
#define i2c_init() i2cm_init()
#define i2c_start() SetSysClock(SYSCLK_FREQ_USEI2C); i2cm_start()
#define i2c_start() { SetSysClock(SYSCLK_FREQ_USEI2C); i2cm_start(); }
#define i2c_restart() i2cm_restart()
#define i2c_stop() SetSysClock(SYSCLK_FREQ_NORMAL); i2cm_stop()
#define i2c_stop() { i2cm_stop(); SetSysClock(SYSCLK_FREQ_NORMAL); }
#define i2c_rd(ack) i2cm_rd(ack)
#define i2c_wr(dat) i2cm_wr(dat)
#define i2c_addr(a, w) i2c_start(); i2cm_addr(a, w)

View File

@ -184,8 +184,9 @@ uint8_t i2cm_wr(uint8_t dat)
SCL_OUTLO(); bit_delay_lo();
}
SDA_IN_HI();
SDA_IN_HI(); __nop(); // slave will now try to ack
SCL_IN_HI(); bit_delay_hi();
while (!SCL_GET()); // nothing should stretch here, but...
ack = SDA_GET();

View File

@ -58,7 +58,7 @@ uint8_t eep16_is_ready()
uint8_t ack;
i2c_start();
ack = i2c_wr(EEPROM_I2C_ADDR | 1);
ack = i2c_wr(EEPROM_I2C_ADDR | 0);
i2c_stop();
if (ack) return 0;

View File

@ -85,6 +85,21 @@ void btn_commit_hold()
ch32sub_write(REG_BTN1_REPEAT_HI, val, sizeof(val));
}
int8_t btn_get_idx(uint8_t map_idx)
{
uint8_t *map;
if (map_idx >= BTN_COUNT) return -1;
if (sysflags & SYS_OLED_ROTATE_X) {
map = btn_map_rot;
} else {
map = btn_map_upr;
}
return map[map_idx] & 0x7f;
}
__HIGH_CODE
void btn_intr()

View File

@ -39,6 +39,8 @@ extern uint8_t btn_held;
void btn_intr();
void btn_commit_hold();
int8_t btn_get_idx(uint8_t map_idx);
#endif /* USER_UI_BTN_H_ */

View File

@ -101,20 +101,47 @@ void menu_5_disp(uint8_t idx)
break;
}
case LI_FACTORY_RESET: {
uint32_t iter;
// todo: implement manual button checking here after getting button orientation code working
// yes, this means reset speed depends on framerate lol
if (btn_pushed & (1 << 2)) {
factory_reset++;
} else factory_reset = 0;
if (factory_reset >= 32) {
// do the factory reset
iter = uconf.iter;
uconf_defaults();
// todo: reboot?
// we do store the old iteration value so long as it isn't
// too high in order to keep track of nvmem writes.
// if the value is unnaturally high, we'll reset to zero.
// if it's corrupt in any way, enjoy your false write count.
if (iter < 0xffffff) {
uconf.iter = iter;
}
uconf_clear();
// while it isn't necesasry to write an initial config
// as the code will determine there is no valid config
// and load defaults if the nvmem is empty,
// we're doing it to write the iter value.
uconf_write();
// aaaand it's gone
SYS_ResetExecute();
while (1);
}
ssd1306fb_draw_str(font_table[0].font, "Hold Set to Factory Reset...", 0);
txt[0] = 0;
ssd1306fb_draw_rect(50, 18, 86, 31);
for (w = 0; w < (factory_reset >> 1); w++) {
ssd1306fb_draw_vline(50 + w, 18, 31);
ssd1306fb_draw_rect(52, 18, 52 + 31, 31);
for (w = 0; w < factory_reset; w++) {
ssd1306fb_draw_vline(53 + w, 18, 31);
}
break;
}

View File

@ -260,16 +260,16 @@ void menu_6_disp(uint8_t idx)
ssd1306fb_set_cursor(10, -1);
ssd1306fb_draw_str(font_Dialog_plain_8, "Light: ", 1);
oled.cursor_x = 39;
sprintf(txt, "%d lo, %02d + %d", lsens_get_dark_threshold(), lsens_get_coarse(), lsens_get_fine());
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
//sprintf(txt, "%d lo, %02d + %d", lsens_get_dark_threshold(), lsens_get_coarse(), lsens_get_fine());
//ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
ssd1306fb_draw_str(font_Dialog_plain_8, "not yet implemented", 0);
ssd1306fb_set_cursor(10, 7);
ssd1306fb_draw_str(font_Dialog_plain_8, "Temp: Batt:", 1);
ssd1306fb_draw_str(font_Dialog_plain_8, "Temp:", 1);
oled.cursor_x = 42;
// todo: implement temperature sensing
// sprintf(txt, "%d.%dC", temp_degc, temp_degc_decimal);
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
ssd1306fb_draw_str(font_Dialog_plain_8, "not yet implemented", 0);
oled.cursor_x = 98;
// battery reading support is not supported on this target
@ -278,14 +278,14 @@ void menu_6_disp(uint8_t idx)
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
ssd1306fb_set_cursor(10, 16);
ssd1306fb_draw_str(font_Dialog_plain_8, "Flash Conf Writes: ", 0);
ssd1306fb_draw_str(font_Dialog_plain_8, "EEPROM Conf Writes: ", 0);
sprintf(txt, "%lu", uconf.iter);
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
ssd1306fb_set_cursor(10, 24);
ssd1306fb_draw_str(font_Dialog_plain_8, "MCU: ", 1);
sprintf(txt, "%dK / %dK", MCU_FLASH, MCU_SRAM);
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 1);
ssd1306fb_draw_str(font_Dialog_plain_8, "CH592 ", 0);
sprintf(txt, "F%dK / R%dK", MCU_FLASH, MCU_SRAM);
ssd1306fb_draw_str(font_Dialog_plain_8, txt, 0);
break;
}

View File

@ -11,6 +11,7 @@
#include "led/rgbled.h"
#include <string.h>
#include <stdio.h>
@ -36,14 +37,14 @@ void uconf_defaults()
{
int i;
memset(&uconf, 0x00, sizeof(uconf));
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.font_idx = 5;
uconf.char_spacing = 2;
uconf.y_offset = 0;
@ -74,6 +75,7 @@ void uconf_defaults()
uconf.checksum = checksum_gen((uint8_t *)&uconf, sizeof(uconf) - 2);
}
// returns 0 if valid
static int8_t uconf_validate()
{
// blank check
@ -98,21 +100,56 @@ static int8_t uconf_validate()
void uconf_load()
{
uint8_t i;
uint32_t iter = 0;
uconf_flash_offset = FLASH_RSVD_PAGES;
for (i = 0; i < FLASH_RSVD_PAGES; i++) {
// find last page of valid config from flash
uconf_flash_offset = (FLASH_RSVD_PAGES - 1) - i;
eep16_read(uconf_flash_offset * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
// search nv data for latest user config
eep16_read(i * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
if (!uconf_validate()) {
// valid data
return;
if (uconf.iter > iter) {
// this page has the highest iter value, so is the latest we've found so far
uconf_flash_offset = i;
iter = uconf.iter;
}
}
}
// flash has no valid data whatsoever
// don't worry about flash setup; that is done during writing
uconf_flash_offset = 0xf0;
uconf_defaults();
if (uconf_flash_offset >= FLASH_RSVD_PAGES) {
// flash has no valid data whatsoever
// load some defaults into RAM and ignore flash for now
uconf_defaults();
} else {
// reload the latest save data found
eep16_read(uconf_flash_offset * FLASH_UCONF_BYTES, (uint8_t *)&uconf, FLASH_UCONF_BYTES);
}
}
void uconf_clear()
{
uint8_t i;
uint8_t c[128];
uint16_t fsize;
uint16_t faddr;
memset(&c, 0xff, sizeof(c));
uconf_flash_offset = FLASH_RSVD_PAGES;
for (i = 0; i < FLASH_RSVD_PAGES; i++) {
// write config data
fsize = FLASH_UCONF_BYTES;
faddr = i * FLASH_UCONF_BYTES;
while (fsize) {
while (!eep16_is_ready());
eep16_write(faddr, c, (fsize > 128) ? 128 : fsize);
if (fsize <= 128) break;
fsize -= 128;
faddr += 128;
}
}
}
void uconf_write()

View File

@ -106,9 +106,12 @@ extern uint8_t temp_degc_decimal;
// non-volatile functions
void uconf_load();
void uconf_write();
void uconf_clear();
// volatile functions
void uconf_defaults();