void storage_commit(void) { int i; uint32_t *w; // backup meta memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN); flash_clear_status_flags(); flash_unlock(); // erase storage for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { flash_erase_sector(i, FLASH_CR_PROGRAM_X32); } // modify storage memcpy(meta_backup + FLASH_META_DESC_LEN, "stor", 4); memcpy(meta_backup + FLASH_META_DESC_LEN + 4, storage_uuid, sizeof(storage_uuid)); memcpy(meta_backup + FLASH_META_DESC_LEN + 4 + sizeof(storage_uuid), &storage, sizeof(Storage)); // copy it back for (i = 0; i < FLASH_META_LEN / 4; i++) { w = (uint32_t *)(meta_backup + i * 4); flash_program_word(FLASH_META_START + i * 4, *w); } flash_lock(); // flash operation failed if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) { layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Storage failure", "detected.", NULL, "Please unplug", "the device.", NULL); for (;;) { } } }
/* * storage_commit() - Write content of configuration in shadow memory to * storage partion in flash * * INPUT * none * OUTPUT * none */ void storage_commit(void) { uint32_t shadow_ram_crc32, shadow_flash_crc32, retries; memcpy((void *)&shadow_config, STORAGE_MAGIC_STR, STORAGE_MAGIC_LEN); for(retries = 0; retries < STORAGE_RETRIES; retries++) { /* Capture CRC for verification at restore */ shadow_ram_crc32 = calc_crc32((uint32_t *)&shadow_config, sizeof(shadow_config) / sizeof(uint32_t)); if(shadow_ram_crc32 == 0) { continue; /* Retry */ } /* Make sure flash is in good state before proceeding */ if(!flash_chk_status()) { flash_clear_status_flags(); continue; /* Retry */ } /* Make sure storage sector is valid before proceeding */ if(storage_location < FLASH_STORAGE1 && storage_location > FLASH_STORAGE3) { /* Let it exhaust the retries and error out */ continue; } flash_unlock(); flash_erase_word(storage_location); wear_leveling_shift(); flash_erase_word(storage_location); /* Load storage data first before loading storage magic */ if(flash_write_word(storage_location, STORAGE_MAGIC_LEN, sizeof(shadow_config) - STORAGE_MAGIC_LEN, (uint8_t *)&shadow_config + STORAGE_MAGIC_LEN)) { if(!flash_write_word(storage_location, 0, STORAGE_MAGIC_LEN, (uint8_t *)&shadow_config)) { continue; /* Retry */ } } else { continue; /* Retry */ } /* Flash write completed successfully. Verify CRC */ shadow_flash_crc32 = calc_crc32((uint32_t *)flash_write_helper( storage_location), sizeof(shadow_config) / sizeof(uint32_t)); if(shadow_flash_crc32 == shadow_ram_crc32) { /* Commit successful, break to exit */ break; } else { continue; /* Retry */ } } flash_lock(); if(retries >= STORAGE_RETRIES) { layout_warning_static("Error Detected. Reboot Device!"); system_halt(); } }
static void svhandler_flash_unlock(void) { flash_wait_for_last_operation(); flash_clear_status_flags(); flash_unlock(); }