diff --git a/STM32F072xB.ld b/STM32F072xB.ld index 0e568f6..cf2d393 100644 --- a/STM32F072xB.ld +++ b/STM32F072xB.ld @@ -26,7 +26,7 @@ MEMORY flash4 : org = 0x00000000, len = 0 flash5 : org = 0x00000000, len = 0 flash6 : org = 0x00000000, len = 0 - flash7 : org = 0x0801ec00, len = 5k + flash7 : org = 0x08018800, len = 30k ram0 : org = 0x20000000, len = 16k ram1 : org = 0x00000000, len = 0 ram2 : org = 0x00000000, len = 0 diff --git a/flash.c b/flash.c index af9256e..6c9d3ae 100644 --- a/flash.c +++ b/flash.c @@ -38,15 +38,14 @@ void flash_program_half_word(uint32_t address, uint16_t data) FLASH->CR &= ~FLASH_CR_PG; } -void flash_unlock(void) { +void flash_unlock(void) +{ // unlock sequence FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; } -config_t cal_saved1 __attribute__ ((section(".calsave"))); - static uint32_t checksum(void *start, size_t len) { @@ -58,40 +57,64 @@ checksum(void *start, size_t len) return value; } +#define SAVEAREA_MAX 5 + +const uint32_t saveareas[] = + { 0x08018800, 0x0801a000, 0x0801b800, 0x0801d000, 0x0801e8000 }; + +#define FLASH_PAGESIZE 0x800 + + int -caldata_save(void) +caldata_save(int id) { uint16_t *src = (uint16_t*)¤t_config; - uint16_t *dst = (uint16_t*)&cal_saved1; - int count = sizeof current_config / sizeof(uint16_t); + uint16_t *dst; + int count = sizeof(config_t) / sizeof(uint16_t); + + if (id < 0 || id >= SAVEAREA_MAX) + return -1; + dst = (uint16_t*)saveareas[id]; current_config.magic = CONFIG_MAGIC; current_config.checksum = 0; current_config.checksum = checksum(¤t_config, sizeof current_config); flash_unlock(); - flash_erase_page(0x801e800); - flash_erase_page(0x801f000); - flash_erase_page(0x801f800); - flash_erase_page((uint32_t)dst); + void *p = dst; + void *tail = p + sizeof(config_t); + while (p < tail) { + flash_erase_page((uint32_t)p); + p += FLASH_PAGESIZE; + } while(count-- > 0) { flash_program_half_word((uint32_t)dst, *src++); dst++; } + + active = (config_t*)saveareas[id]; return 0; } int -caldata_recall(void) +caldata_recall(int id) { - void *src = &cal_saved1; + config_t *src; void *dst = ¤t_config; - if (cal_saved1.magic != CONFIG_MAGIC) + if (id < 0 || id >= SAVEAREA_MAX) + return -1; + src = (config_t*)saveareas[id]; + + if (src->magic != CONFIG_MAGIC) return -1; - if (checksum(&cal_saved1, sizeof cal_saved1) != 0) + if (checksum(src, sizeof(config_t)) != 0) return -1; - memcpy(dst, src, sizeof current_config); +#if 0 + memcpy(dst, src, sizeof(config_t)); +#else + active = src; +#endif return 0; } diff --git a/main.c b/main.c index a52c4d0..2f8e643 100644 --- a/main.c +++ b/main.c @@ -352,6 +352,15 @@ config_t current_config = { }; config_t *active = ¤t_config; +void +ensure_edit_config(void) +{ + if (active == ¤t_config) + return; + + memcpy(¤t_config, active, sizeof(config_t)); + active = ¤t_config; +} static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[]) @@ -455,6 +464,7 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[]) return; } if (argc >= 1) { + ensure_edit_config(); int32_t x = atoi(argv[0]); if (x < 300000) { chprintf(chp, "bad parameter\r\n"); @@ -661,33 +671,39 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) char *cmd = argv[0]; if (strcmp(cmd, "load") == 0) { + ensure_edit_config(); cal_status |= CALSTAT_LOAD; chMtxLock(&mutex); memcpy(cal_data[CAL_LOAD], measured[0], sizeof measured[0]); chMtxUnlock(&mutex); } else if (strcmp(cmd, "open") == 0) { + ensure_edit_config(); cal_status |= CALSTAT_OPEN; cal_status &= ~(CALSTAT_ES|CALSTAT_APPLY); chMtxLock(&mutex); memcpy(cal_data[CAL_OPEN], measured[0], sizeof measured[0]); chMtxUnlock(&mutex); } else if (strcmp(cmd, "short") == 0) { + ensure_edit_config(); cal_status |= CALSTAT_SHORT; cal_status &= ~(CALSTAT_ER|CALSTAT_APPLY); chMtxLock(&mutex); memcpy(cal_data[CAL_SHORT], measured[0], sizeof measured[0]); chMtxUnlock(&mutex); } else if (strcmp(cmd, "thru") == 0) { + ensure_edit_config(); cal_status |= CALSTAT_THRU; chMtxLock(&mutex); memcpy(cal_data[CAL_THRU], measured[1], sizeof measured[0]); chMtxUnlock(&mutex); } else if (strcmp(cmd, "isoln") == 0) { + ensure_edit_config(); cal_status |= CALSTAT_ISOLN; chMtxLock(&mutex); memcpy(cal_data[CAL_ISOLN], measured[1], sizeof measured[0]); chMtxUnlock(&mutex); } else if (strcmp(cmd, "done") == 0) { + ensure_edit_config(); if (!(cal_status & CALSTAT_LOAD)) eterm_set(ETERM_ED, 0.0, 0.0); //adjust_ed(); @@ -742,17 +758,41 @@ static void cmd_cal(BaseSequentialStream *chp, int argc, char *argv[]) static void cmd_save(BaseSequentialStream *chp, int argc, char *argv[]) { (void)chp; - (void)argc; - (void)argv; - caldata_save(); + + if (argc != 1) + goto usage; + + int id = atoi(argv[0]); + if (id < 0 || id >= SAVEAREA_MAX) + goto usage; + caldata_save(id); + return; + + usage: + chprintf(chp, "save {id}\r\n"); } static void cmd_recall(BaseSequentialStream *chp, int argc, char *argv[]) { (void)chp; - (void)argc; - (void)argv; - caldata_recall(); + if (argc != 1) + goto usage; + + int id = atoi(argv[0]); + if (id < 0 || id >= SAVEAREA_MAX) + goto usage; + + pause_sweep(); + if (caldata_recall(id) == 0) { + // success + set_sweep(freq_start, freq_stop); + } + + resume_sweep(); + return; + + usage: + chprintf(chp, "save {id}\r\n"); } @@ -1068,16 +1108,15 @@ int main(void) */ plot_init(); + /* initial frequencies */ + set_frequencies(); + /* restore config and calibration data from flash memory */ - caldata_recall(); + caldata_recall(0); set_sweep(freq_start, freq_stop); redraw(); - /* - */ - set_frequencies(); - /* * I2S Initialize */ diff --git a/nanovna.h b/nanovna.h index 6e9f546..e06feda 100644 --- a/nanovna.h +++ b/nanovna.h @@ -153,8 +153,11 @@ extern const uint32_t numfont20x24[][24]; #define CHAR_MICRO '\0x1d' #define CHAR_OHM '\0x1e' -int caldata_save(void); -int caldata_recall(void); +/* + * flash.c + */ + +#define SAVEAREA_MAX 5 typedef struct { int32_t magic; @@ -168,9 +171,6 @@ typedef struct { int32_t checksum; } config_t; -/* - * flash.c - */ #define CONFIG_MAGIC 0x436f4e45 /* 'CoNF' */ extern config_t *active; @@ -183,6 +183,12 @@ extern config_t current_config; #define frequencies active->_frequencies #define cal_data active->_cal_data +int caldata_save(int id); +int caldata_recall(int id); + + + + #define PULSE do { palClearPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);} while(0)