void storage_erase(void) {
    fd_log_initialize();
    chip_erase();
    fd_storage_initialize();
}
Example #2
0
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;
}