void storage_erase(void) { fd_log_initialize(); chip_erase(); fd_storage_initialize(); }
uint16_t flash_reprogram(uint16_t handle) { // Determine file size. uint32_t data_size = file_size(handle); // Check device ID. uint32_t id = read_device_id(); printf("ID: 0x%08lx\n", id); if (id != EXPECTED_DEVICE_ID) { return FLASH_PROGRAM_ID_MISMATCH; } // Erase enough sectors to fit the new configuration file. #if defined(DEBUG) printf_P(PSTR("Erasing chip\n")); #endif // defined (DEBUG) // Set write enable. write_enable(); // Start block erase. chip_erase(); // Make sure WIP bit is set. if (!(read_status_reg() & (1 << STATUS_REG_WIP))) { return FLASH_PROGRAM_ERASE_START_ERROR; } // Wait for WIP = 0. // TODO: add timeout. while (read_status_reg() & (1 << STATUS_REG_WIP)); // Write the new data to flash. char file_buf[PAGE_SIZE]; for (uint32_t offset = 0; offset < data_size; offset += PAGE_SIZE) { // Read the file. uint16_t size_read = file_read(handle, file_buf, PAGE_SIZE); if (size_read < PAGE_SIZE && size_read != offset - data_size) { return FLASH_PROGRAM_FILE_READ_ERROR; } bool page_empty = true; for (uint16_t page_offset = 0; page_offset < size_read; ++page_offset) { if (file_buf[page_offset] != UNINITIALIZED_MEMORY_VALUE) { page_empty = false; break; } } if (page_empty) { #if defined(DEBUG) printf_P(PSTR("No data at 0x%08lx\n"), offset); #endif // defined(DEBUG) continue; } // Obtain a 32-bit checksum. uint32_t checksum = get_checksum(file_buf, size_read); // Program a |PAGE_SIZE| page of the flash. write_enable(); #if defined(DEBUG) printf_P(PSTR("Programming data at 0x%08lx\n"), offset); #endif // defined(DEBUG) page_program(offset, file_buf, size_read); // Make sure WIP bit is set. if (!(read_status_reg() & (1 << STATUS_REG_WIP))) { return FLASH_PROGRAM_WRITE_START_ERROR; } // Wait for programming to finish. // TODO: add timeout. while (read_status_reg() & (1 << STATUS_REG_WIP)); // Read back and check the checksum. read_data(offset, file_buf, size_read); uint32_t new_checksum = get_checksum(file_buf, size_read); if (checksum != new_checksum) { return FLASH_PROGRAM_WRITE_VERIFY_ERROR; } } return FLASH_PROGRAM_SUCCESS; }