From 6a2e8164d9ef44fcf7c750ad376646712d371449 Mon Sep 17 00:00:00 2001 From: true Date: Wed, 1 Nov 2023 10:15:18 -0700 Subject: [PATCH] Fix flash routine bugs, make it work --- include/flash.h | 2 +- src/flash.c | 53 ++++++++++++++++++++++++++++++++++++++----------- src/main.c | 2 ++ src/probe.c | 27 ++++++++++++++++--------- 4 files changed, 62 insertions(+), 22 deletions(-) diff --git a/include/flash.h b/include/flash.h index 2db7bd6..a74b1cc 100644 --- a/include/flash.h +++ b/include/flash.h @@ -34,7 +34,7 @@ typedef struct UConf { uint16_t diode_shorted; // unused, unneeded uint32_t rsvd_1[4]; uint32_t rsvd_2[8]; - uint32_t vctr; // increment every update of config + uint32_t update_cntr; // increment every update of config uint32_t crc32; // CRC of preceding 60 bytes } UConf; // 64 bytes diff --git a/src/flash.c b/src/flash.c index 373b3d4..d00f48c 100644 --- a/src/flash.c +++ b/src/flash.c @@ -274,21 +274,14 @@ void flash_commit_conf() } } - // if all pages are occupied, erase the first page + // if all pages are occupied, we'll erase all the pages if (i == UCONF_COUNT) { flash_full = 1; } - // copy flash page from ROM to the write buffer, - // as our data (64 bytes) is smaller than the page write size (128 bytes) - f32 = (uint32_t *)fconf; - u32 = (uint32_t *)write; - for (i = 0; i < (FLASH_PAGE_SIZE / 4); i++) { - *u32++ = *f32++; - } - - // ensure config header is correct, and calculate CRC + // ensure live config header is correct, and calculate CRC conf.conf_key = UCONF_KEY; + conf.update_cntr++; u32 = (uint32_t *)&conf; CRC->CR = CRC_CR_RESET; @@ -298,14 +291,50 @@ void flash_commit_conf() CRC->DR = u32[i]; } u32[(UCONF_SIZE / 4) - 1] = CRC->DR; + + // do we need to actually update data? + // check checksum of our data against checksum of prior entry + if (flash_idx) { + fconf = (struct UConf *)(UCONF_FLASH_START + (UCONF_SIZE * (flash_idx - 1))); + if (fconf->crc32 == conf.crc32) { + // nothing to update; we can break out + return; + } + } + + // set empty write buffer to 0xff + for (i = 0; i < 32; i++) { + write[i] = 0xffffffff; + } + + // set write buffer + u32 = (uint32_t *)write; + + // if this is the second entry in a flash page, + // copy first half of flash page from ROM to the write buffer, + // as our config size (64 bytes) is smaller than the page write size (128 bytes) + if (flash_idx & 1) { + f32 = (uint32_t *)fconf; + for (i = 0; i < (UCONF_SIZE / 4); i++) { + *u32++ = *f32++; + } + } + + // correct flash_idx if it is out of bounds + // (we will usually have 1-8, only getting 0 on the very first write) + if (flash_idx == UCONF_COUNT) { + flash_idx = 0; + } // copy user config from RAM to write buffer at the appropriate offset f32 = (uint32_t *)&conf; - u32 = (uint32_t *)write; - for (i = (flash_idx ? UCONF_SIZE : 0); i < (UCONF_SIZE / 4); i++) { + for (i = 0; i < (UCONF_SIZE / 4); i++) { *u32++ = *f32++; } + // we now need the flash page boundary, so remove lowest bit from flash_idx + flash_idx &= ~1; + // erase this page flash_erase_page(UCONF_FLASH_START + (UCONF_SIZE * flash_idx)); diff --git a/src/main.c b/src/main.c index d346238..b067fdd 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,8 @@ * main.c: test-o continuity and diode tester * * your robot addon badge buddy for testing all the things + * + * version 0.0.1 * * file creation: 20231015 0021 */ diff --git a/src/probe.c b/src/probe.c index 862554a..22cd925 100644 --- a/src/probe.c +++ b/src/probe.c @@ -207,7 +207,7 @@ void probe_measure() switch (mode) { case MODE_CONT: probe_measure_cont(); break; - case MODE_FUN: break; // todo: run RGBLED program + case MODE_FUN: break; // LED program is run elsewhere case MODE_DIODE: probe_measure_diode(); break; } } @@ -218,13 +218,22 @@ void probe_measure() */ void probe_mode_switch(uint8_t mode) { - if (mode == MODE_CONT) { - // set LED to buzzer mode, set PROBESEL low - led_mode_buzzer(); - PROBESEL_PORT->BRR = (1 << PROBESEL_PIN); - } else { - // set LED to dual RGB mode, set PROBESEL high - led_mode_rgb(); - PROBESEL_PORT->BSRR = (1 << PROBESEL_PIN); + switch (mode) { + case MODE_CONT: { + // set LED to buzzer mode, set PROBESEL low + led_mode_buzzer(); + PROBESEL_PORT->BRR = (1 << PROBESEL_PIN); + break; + } + default: { + // set LED to dual RGB mode, set PROBESEL high + led_mode_rgb(); + PROBESEL_PORT->BSRR = (1 << PROBESEL_PIN); + } + } + + // save config if moving into LED mode + if (mode == MODE_FUN) { + flash_commit_conf(); } } \ No newline at end of file