flash_err_t flash_erase_sector(const void *addr) { sector_info_t sinfo; if (false == get_sector_info((uint32_t)addr, &sinfo)) { return FLASH_ERR_INVALID; } return flash_erase_sectorinfo(&sinfo); }
size_t flash_sector_size(const void *addr) { sector_info_t sinfo; if (false == get_sector_info((uint32_t)addr, &sinfo)) { return 0; } return sinfo.sectorSize; }
static sector_descriptor_t *check_free_space_in_sector(flash_entry_header_t *pf, size_t new_size) { sector_descriptor_t *sm = get_sector_info(pf); uint8_t *psector_first = (uint8_t *) sm->address; uint8_t *psector_last = psector_first + sm->size - 1; uint8_t *pnext_end = (uint8_t *)(valid_magic((h_magic_t *)pf) ? next_entry(pf) : pf) + new_size; if (pnext_end >= psector_first && pnext_end <= psector_last) { sm = 0; } return sm; }
flash_err_t // TODO rename _range flash_erase(const void *base_block_addr, unsigned int size_in_bytes) { uint32_t addr = (uint32_t)base_block_addr; uint32_t end_addr = (uint32_t)base_block_addr + size_in_bytes; sector_info_t sinfo; if (0 == size_in_bytes) { return FLASH_ERR_INVALID; // FIXME why? if we want to erase a whole sector it is convenient... } while (addr < end_addr) { if (false == get_sector_info(addr, &sinfo)) { return FLASH_ERR_INVALID; } if (FLASH_ERR_OK != flash_erase_sectorinfo(&sinfo)) { return FLASH_ERR_INVALID; } addr = sinfo.sectorStartAddress + sinfo.sectorSize; } return FLASH_ERR_OK; }
flash_err_t flash_init(void) { flash_err_t rv; _coreDisableFlashEcc_(); // allowed by myself #if 0 //Fapi_initializeFlashBanks(ROUNDUPCAST(HCLK_FREQ)); //while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { // ////vTaskDelay(15 / portTICK_RATE_MS); //} #endif // this will call Fapi_initializeFlashBanks() rv = flash_init_nvram(); if (RV_SUCCESS == rv) { (void)get_sector_info((uint32_t)&flash_init, &api_bank); } return rv == RV_SUCCESS ? FLASH_ERR_OK : FLASH_ERR_HWR; }
/* takes a file handle, file position should be at the start of the Anadisk dump data. reads the info for each sector and builds it into a list of sides. each side holds a list of tracks, and each track a list of sectors */ struct disk_side *parse_image(FILE *fp) { struct sect_info si; struct disk_side *sides = NULL; struct disk_side *curr_side, *new_side; struct disk_track *curr_track, *new_track; struct disk_sector *curr_sector, *new_sector; while (get_sector_info(fp, &si)) { curr_side = find_side(sides, si.phy_side); if (curr_side == NULL) { new_side = make_side(si.phy_side); if (sides == NULL) sides = new_side; else { for (curr_side = sides; curr_side->next != NULL; curr_side = curr_side->next) ; curr_side->next = new_side; } max_sides++; curr_side = new_side; } curr_track = find_track(curr_side->tracks, si.phy_cylinder); if (curr_track == NULL) { new_track = make_track(si.phy_cylinder, si.phy_side); if (curr_side->tracks == NULL) curr_side->tracks = new_track; else { for (curr_track = curr_side->tracks; curr_track->next != NULL; curr_track = curr_track->next) ; curr_track->next = new_track; } curr_side->track_count++; if (curr_side->track_count > max_tracks) max_tracks = curr_side->track_count; curr_track = new_track; } new_sector = make_sector(si.log_sector, si.log_cylinder, si.log_side, si.size, ftell(fp)); if (si.size > sector_size) sector_size = si.size; if (curr_track->sectors == NULL) curr_track->sectors = new_sector; else { for (curr_sector = curr_track->sectors; curr_sector->next != NULL; curr_sector = curr_sector->next) ; curr_sector->next = new_sector; } curr_track->sector_count++; if (curr_track->sector_count > max_sectors) max_sectors = curr_track->sector_count; skip_sector(fp, &si); } return sides; }
static flash_err_t flash_write_sector_locked(const void *addr, const void *data, int len_in_bytes) // TODO arg: err_addr { Fapi_StatusType status; uint32_t fsm_status; sector_info_t p, *sinfo = &p; int bytes; uint32_t *paddr = (uint32_t *)addr; // TODO align? uint8_t *pdata = (uint8_t *)data; #if 0 if (!(((uint32_t)addr) & ~3)) { return FLASH_ERR_INVALID; // FIXME necessary? } #endif if (false == get_sector_info((uint32_t)addr, &p)) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR unknown sector (addr:0x%08x)\n", (uint32_t)addr); return FLASH_ERR_INVALID; } if (api_bank.bankId == sinfo->bankId) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR api_bank.bankId=%d\n", api_bank.bankId); return FLASH_ERR_PROTECT; } //while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { // ////vTaskDelay(15 / portTICK_RATE_MS); //} if (currentBankId != sinfo->bankId) { status = Fapi_setActiveFlashBank(sinfo->bankId); if (Fapi_Status_Success != status) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR Fapi_setActiveFlashBank(bankId:%d) status=%d\n", sinfo->bankId, status); return FLASH_ERR_INVALID; } currentBankId = sinfo->bankId; } if (Fapi_FLEE == sinfo->bankTech) { status = Fapi_enableEepromBankSectors(1 << sinfo->sectorId, 0); } else { status = Fapi_enableMainBankSectors(1 << sinfo->sectorId); } if (Fapi_Status_Success != status) { log_report_fmt(LOG_FLASH, "flash_write_sector ERROR Fapi_enable*BankSectors(sectorId:%d) status=%d\n", sinfo->sectorId, status); return FLASH_ERR_INVALID; } while (Fapi_Status_FsmReady != FAPI_CHECK_FSM_READY_BUSY) { ////vTaskDelay(15 / portTICK_RATE_MS); } // -- status = Fapi_issueAsyncCommand(Fapi_ClearStatus); if (Fapi_Status_Success != status) { return FLASH_ERR_INVALID; } /* Wait for FSM to finish */ while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { //vTaskDelay(15 / portTICK_RATE_MS); } /* Check the FSM Status to see if there were no errors */ fsm_status = FAPI_GET_FSM_STATUS; // // -- log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, 0x%06x, src=0x%08x) Programming...\r\n", (uint32_t)addr, len_in_bytes, (uint32_t)data); vPortEnterCritical(); while (len_in_bytes > 0) { if (len_in_bytes > WORDSIZE) { bytes = WORDSIZE; } else { bytes = len_in_bytes; } status = Fapi_issueProgrammingCommand(paddr, pdata, bytes, NULL, 0, Fapi_DataOnly); if (Fapi_Status_Success != status) { vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR1 Program Fapi_Status:%d\r\n", (uint32_t)paddr, len_in_bytes, status); return FLASH_ERR_INVALID; } /* Wait for FSM to finish */ while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { //vTaskDelay(15 / portTICK_RATE_MS); } /* Check the FSM Status to see if there were no errors */ fsm_status = FAPI_GET_FSM_STATUS; if (fsm_status) { // see FMSTAT_BITS //if INVDAT: status = Fapi_issueAsyncCommand(Fapi_ClearStatus); if (Fapi_Status_Success != status) { vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR2 fsm_status:%d Fapi_Status:%d\r\n", (uint32_t)paddr, len_in_bytes, fsm_status, status); return FLASH_ERR_INVALID; } /* Wait for FSM to finish */ while (Fapi_Status_FsmBusy == FAPI_CHECK_FSM_READY_BUSY) { //vTaskDelay(15 / portTICK_RATE_MS); } /* Check the FSM Status to see if there were no errors */ fsm_status = FAPI_GET_FSM_STATUS; vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, still:0x%06x) ERROR3 fsm_status:%d\r\n", (uint32_t)paddr, len_in_bytes, fsm_status); return FLASH_ERR_PROTOCOL; } len_in_bytes -= bytes; pdata += bytes; paddr++; } Fapi_flushPipeline(); vPortExitCritical(); log_report_fmt(LOG_FLASH, "flash_write_sector(0x%08x, src=0x%08x) Done.\r\n", (uint32_t)addr, (uint32_t)data); return FLASH_ERR_OK; }