diff --git a/flash.c b/flash.c index 3ac53fb..a24f6c2 100644 --- a/flash.c +++ b/flash.c @@ -22,7 +22,8 @@ #include "nanovna.h" #include -int16_t lastsaveid = 0; +uint16_t lastsaveid = 0; +static uint32_t checksum_ok = 0; static int flash_wait_for_last_operation(void) { @@ -42,80 +43,71 @@ static void flash_erase_page0(uint32_t page_address) FLASH->CR &= ~FLASH_CR_PER; } -int flash_erase_page(uint32_t page_address) +static void flash_erase_page(uint32_t page_address) { chSysLock(); flash_erase_page0(page_address); chSysUnlock(); - return 0; } -void flash_program_half_word(uint32_t address, uint16_t data) -{ - flash_wait_for_last_operation(); - FLASH->CR |= FLASH_CR_PG; - *(__IO uint16_t*)address = data; - flash_wait_for_last_operation(); - FLASH->CR &= ~FLASH_CR_PG; -} - -void flash_unlock(void) +static inline void flash_unlock(void) { // unlock sequence FLASH->KEYR = 0x45670123; FLASH->KEYR = 0xCDEF89AB; } +static void flash_program_half_word_buffer(uint16_t* dst, uint16_t *data, uint16_t size) +{ + uint32_t i; + flash_unlock(); + // erase flash pages for buffer (aligned to FLASH_PAGESIZE) + for (i = 0; i < size; i+=FLASH_PAGESIZE) + flash_erase_page((uint32_t)dst + i); + // Save buffer + __IO uint16_t* p = dst; + for (i = 0; i < size/sizeof(uint16_t); i++){ + flash_wait_for_last_operation(); + FLASH->CR |= FLASH_CR_PG; + p[i] = data[i]; + flash_wait_for_last_operation(); + FLASH->CR &= ~FLASH_CR_PG; + } +} + static uint32_t checksum(const void *start, size_t len) { uint32_t *p = (uint32_t*)start; - uint32_t *tail = (uint32_t*)(start + len); uint32_t value = 0; - while (p < tail) + // align by sizeof(uint32_t) + len = (len + sizeof(uint32_t)-1)/sizeof(uint32_t); + while (len-- > 0) value = __ROR(value, 31) + *p++; return value; } -const uint32_t save_config_area = SAVE_CONFIG_ADDR; - int config_save(void) { - uint16_t *src = (uint16_t*)&config; - uint16_t *dst = (uint16_t*)save_config_area; - int count = sizeof(config_t) / sizeof(uint16_t); - + // Apply magic word and calculate checksum config.magic = CONFIG_MAGIC; config.checksum = checksum(&config, sizeof config - sizeof config.checksum); - flash_unlock(); - - /* erase flash pages */ - flash_erase_page((uint32_t)dst); - - /* write to flahs */ - while (count-- > 0) { - flash_program_half_word((uint32_t)dst, *src++); - dst++; - } - + // write to flash + flash_program_half_word_buffer((uint16_t*)SAVE_CONFIG_ADDR, (uint16_t*)&config, sizeof(config_t)); return 0; } int config_recall(void) { - const config_t *src = (const config_t*)save_config_area; - void *dst = &config; + const config_t *src = (const config_t*)SAVE_CONFIG_ADDR; - if (src->magic != CONFIG_MAGIC) + if (src->magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return -1; - if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) - return -1; - - /* duplicated saved data onto sram to be able to modify marker/trace */ - memcpy(dst, src, sizeof(config_t)); + // duplicated saved data onto sram to be able to modify marker/trace + memcpy(&config, src, sizeof(config_t)); return 0; } @@ -124,33 +116,16 @@ caldata_save(uint32_t id) { if (id >= SAVEAREA_MAX) return -1; - uint16_t *src = (uint16_t*)¤t_props; - uint16_t *dst; - int count = sizeof(properties_t) / sizeof(uint16_t); - - dst = (uint16_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); + // Apply magic word and calculate checksum current_props.magic = CONFIG_MAGIC; - current_props.checksum = checksum( - ¤t_props, sizeof current_props - sizeof current_props.checksum); + current_props.checksum = checksum(¤t_props, sizeof current_props - sizeof current_props.checksum); - flash_unlock(); + // write to flash + uint16_t *dst = (uint16_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); + flash_program_half_word_buffer(dst, (uint16_t*)¤t_props, sizeof(properties_t)); - /* erase flash pages */ - void *p = dst; - void *tail = p + sizeof(properties_t); - while (p < tail) { - flash_erase_page((uint32_t)p); - p += FLASH_PAGESIZE; - } - - /* write to flahs */ - while (count-- > 0) { - flash_program_half_word((uint32_t)dst, *src++); - dst++; - } - - /* after saving data, make active configuration points to flash */ + // after saving data, make active configuration points to flash active_props = (properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); lastsaveid = id; @@ -162,56 +137,50 @@ caldata_recall(uint32_t id) { if (id >= SAVEAREA_MAX) return -1; - properties_t *src; - void *dst = ¤t_props; - // point to saved area on the flash memory - src = (properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); + properties_t *src = (properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); - if (src->magic != CONFIG_MAGIC) - goto load_default; - if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) + if (src->magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) goto load_default; - /* active configuration points to save data on flash memory */ + // active configuration points to save data on flash memory active_props = src; lastsaveid = id; - /* duplicated saved data onto sram to be able to modify marker/trace */ - memcpy(dst, src, sizeof(properties_t)); + // duplicated saved data onto sram to be able to modify marker/trace + memcpy(¤t_props, src, sizeof(properties_t)); return 0; load_default: load_default_properties(); - return -1; + return lastsaveid; } +// Used in interpolate const properties_t * -caldata_ref(uint32_t id) +caldata_reference(void) { - if (id >= SAVEAREA_MAX) + if (lastsaveid >= SAVEAREA_MAX) return NULL; const properties_t *src; - src = (const properties_t*)(SAVE_PROP_CONFIG_ADDR + id * SAVE_PROP_CONFIG_SIZE); - - if (src->magic != CONFIG_MAGIC) - return NULL; - if (checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) + src = (const properties_t*)(SAVE_PROP_CONFIG_ADDR + lastsaveid * SAVE_PROP_CONFIG_SIZE); + // Check crc cache mask (made it only 1 time) + if (checksum_ok&(1<magic != CONFIG_MAGIC || checksum(src, sizeof *src - sizeof src->checksum) != src->checksum) return NULL; + checksum_ok|=1<