Fix flash routine bugs, make it work

This commit is contained in:
true 2023-11-01 10:15:18 -07:00
parent b3c799d7e7
commit 6a2e8164d9
4 changed files with 62 additions and 22 deletions

View File

@ -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

View File

@ -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));

View File

@ -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
*/

View File

@ -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();
}
}