static FlashChipBase *DefaultFlashCtor(void) { DefaultFlash *impl = malloc(sizeof(DefaultFlash)); PCHECK(impl); memset(impl, 0, sizeof(DefaultFlash)); FLASH_DEBUG("create default chip"); impl->base.mPageSize = 256; impl->base.mSize = -1; impl->base.mMaxFreq = -1; impl->base.mMaxReadFreq = -1; /* impl->base.mEraseSizeSupport = FLASH_ERASE_64KB | FLASH_ERASE_CHIP; impl->base.mPageProgramSupport = FLASH_PAGEPROGRAM; impl->base.mReadStausSupport = FLASH_STATUS1; impl->base.mWriteStatusSupport = FLASH_STATUS1; impl->base.mReadSupport = FLASH_READ_NORMAL_MODE | FLASH_READ_FAST_MODE; */ impl->base.mEraseSizeSupport = FLASH_ERASE_4KB | FLASH_ERASE_32KB | FLASH_ERASE_64KB | FLASH_ERASE_CHIP; impl->base.mPageProgramSupport = FLASH_PAGEPROGRAM; impl->base.mReadStausSupport = FLASH_STATUS1; impl->base.mWriteStatusSupport = FLASH_STATUS1; impl->base.mReadSupport = FLASH_READ_NORMAL_MODE | FLASH_READ_FAST_MODE | FLASH_READ_DUAL_O_MODE; return &impl->base; }
/** * Flash ENV initialize. * * @param start_addr ENV start address in flash * @param total_size ENV section total size (@note must be word alignment) * @param erase_min_size the minimum size of flash erasure * @param default_env default ENV set for user * @param default_env_size default ENV set size * * @return result */ FlashErrCode flash_env_init(uint32_t start_addr, size_t total_size, size_t erase_min_size, flash_env const *default_env, size_t default_env_size) { FlashErrCode result = FLASH_NO_ERR; FLASH_ASSERT(start_addr); FLASH_ASSERT(total_size); FLASH_ASSERT(erase_min_size); FLASH_ASSERT(default_env); FLASH_ASSERT(default_env_size < FLASH_USER_SETTING_ENV_SIZE); /* must be word alignment for ENV */ FLASH_ASSERT(FLASH_USER_SETTING_ENV_SIZE % 4 == 0); FLASH_ASSERT(total_size % 4 == 0); env_start_addr = start_addr; env_total_size = total_size; flash_erase_min_size = erase_min_size; default_env_set = default_env; default_env_set_size = default_env_size; FLASH_DEBUG("Env start address is 0x%08X, size is %d bytes.\n", start_addr, total_size); flash_load_env(); return result; }
/** * Check the ENV CRC32 * * @return true is ok */ static bool_t env_crc_is_ok(void) { if (calc_env_crc() == env_cache[ENV_PARAM_PART_INDEX_DATA_CRC]) { FLASH_DEBUG("Verify Env CRC32 result is OK.\n"); return TRUE; } else { return FALSE; } }
/** * Calculate the cached ENV CRC32 value. * * @return CRC32 value */ static uint32_t calc_env_crc(void) { uint32_t crc32 = 0; extern uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size); /* Calculate the ENV end address and all ENV data CRC32. * The 4 is ENV end address bytes size. */ crc32 = calc_crc32(crc32, &env_cache[ENV_PARAM_PART_INDEX_END_ADDR], 4); crc32 = calc_crc32(crc32, &env_cache[ENV_PARAM_PART_WORD_SIZE], get_env_detail_size()); FLASH_DEBUG("Calculate Env CRC32 number is 0x%08X.\n", crc32); return crc32; }
FlashChipBase *FlashChipCreate(FlashDrvierBase *driver) { uint32_t list_size = sizeof(flashChipList) / sizeof(flashChipList[0]); uint32_t jedec = getJedecID(driver); FlashChipBase *base = NULL; FlashChipCtor *ctor = NULL; FLASH_DEBUG("jedec: 0x%x, list_size: %d", jedec, list_size); while (list_size--) { ctor = flashChipList[list_size]; if (ctor->mJedecId == jedec) break; } if (ctor == NULL) return NULL; base = ctor->create(jedec); /* base->writeEnable = defaultWriteEnable; base->writeDisable = defaultWriteDisable; base->readStatus = defaultReadStatus; base->erase = defaultErase; base->jedecID = defaultGetJedecID; base->pageProgram = defaultPageProgram; base->read = defaultRead; base->driverWrite = defaultDriverWrite; base->driverRead = defaultdriverRead; base->setFreq = defaultSetFreq; base->switchReadMode = defaultSwitchReadMode; base->enableXIP = defaultEnableXIP; base->disableXIP = defaultDisableXIP; base->isBusy = defaultIsBusy; base->control = defaultControl; base->minEraseSize = defaultGetMinEraseSize; base->writeStatus = NULL; base->suspendErasePageprogram = NULL; base->resumeErasePageprogram = NULL; base->powerDown = NULL; base->releasePowerDown = NULL; base->enableQPIMode = NULL; base->disableQPIMode = NULL; base->enableReset = NULL; base->reset = NULL; base->uniqueID = NULL;*/ ctor->init(base); base->mDriver = driver; return base; }
bool Flash_InfoDump(char *pFlashName){ bool bSuccess = FALSE; flash_region *regions, *nextreg; alt_flash_fd* fd; int number_of_regions; int ret_code; /* Set write_data to all 0xa */ FLASH_DEBUG(("Flash_InfoDump\r\n")); fd = alt_flash_open_dev(pFlashName); if (fd){ ret_code = alt_get_flash_info(fd,®ions,&number_of_regions); if (ret_code == 0){ int i; bSuccess = TRUE; nextreg = regions; FLASH_DEBUG(("number_of_regsion:%d\r\n", number_of_regions)); for(i=0;i<number_of_regions;i++){ FLASH_DEBUG(("regsion[%d]\r\n", i)); FLASH_DEBUG((" offset:%d\r\n", nextreg->offset)); FLASH_DEBUG((" region_size:%d\r\n", nextreg->region_size)); FLASH_DEBUG((" number_of_blocks:%d\r\n", nextreg->number_of_blocks)); FLASH_DEBUG((" block_size;:%d\r\n", nextreg->block_size)); nextreg++; } }else{ FLASH_DEBUG(("alt_get_flash_info error, ret_code:%d fail\r\n", ret_code)); } alt_flash_close_dev(fd); }else{ FLASH_DEBUG(("alt_flash_open_dev fail\r\n")); } if (!bSuccess) FLASH_DEBUG(("Flash_InfoDump fail\r\n")); return bSuccess; }
bool FlashStorage::write(uint32_t address, const void *data, uint32_t dataLength) { if ((uint32_t)FLASH_START + address < (uint32_t)&__flash_start__) { FLASH_DEBUG("Flash write address too low"); return false; } if ((uint32_t)FLASH_START + address + dataLength > (uint32_t)&__flash_end__) { FLASH_DEBUG("Flash write address too high"); return false; } if ((((uint32_t)FLASH_START + address) & 3) != 0) { FLASH_DEBUG("Flash start address must be on 4-byte boundary\n"); return false; } // The flash management code in the ASF is fragile and has a tendency to fail to return. Help it by disabling interrupts. efc_disable_frdy_interrupt(EFC); // should not be enabled already, but disable it just in case irqflags_t flags = cpu_irq_save(); // Unlock page uint32_t retCode = flash_unlock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Failed to unlock flash for write"); } else { // Write data retCode = flash_write((uint32_t)FLASH_START + address, data, dataLength, 1); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Flash write failed"); } else { // Lock page retCode = flash_lock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Failed to lock flash page"); } } } cpu_irq_restore(flags); return retCode == FLASH_RC_OK; }
static int EN25QHXXA_FlashInit(FlashChipBase * base) { PCHECK(base); EN25QHXXA_Flash *impl = __containerof(base, EN25QHXXA_Flash, base); impl->base.writeEnable = defaultWriteEnable; impl->base.writeDisable = defaultWriteDisable; impl->base.readStatus = EN25QHXXA_ReadStatus; impl->base.erase = defaultErase; impl->base.jedecID = defaultGetJedecID; impl->base.pageProgram = defaultPageProgram; impl->base.read = defaultRead; impl->base.driverWrite = defaultDriverWrite; impl->base.driverRead = defaultDriverRead; impl->base.xipDriverCfg = defaultXipDriverCfg; impl->base.setFreq = defaultSetFreq; impl->base.switchReadMode = defaultSwitchReadMode; impl->base.enableXIP = defaultEnableXIP; impl->base.disableXIP = defaultDisableXIP; impl->base.isBusy = defaultIsBusy; impl->base.control = defaultControl; impl->base.minEraseSize = defaultGetMinEraseSize; //impl->base.writeStatus = defaultWriteStatus; impl->base.writeStatus = EN25QHXXA_WriteStatus; impl->base.enableQPIMode = defaultEnableQPIMode; impl->base.disableQPIMode = defaultDisableQPIMode; // impl->base.enableReset = defaultEnableReset; impl->base.reset = defaultReset; impl->base.suspendErasePageprogram = NULL; impl->base.resumeErasePageprogram = NULL; impl->base.powerDown = NULL; impl->base.releasePowerDown = NULL; impl->base.uniqueID = NULL; /*TODO: a NULL interface for showing invalid interface*/ FLASH_DEBUG("EN25QHXXA_Flash chip inited"); return 0; }
int defaultDriverRead(FlashChipBase *base, InstructionField *cmd, InstructionField *addr, InstructionField *dummy, InstructionField *data) { if (base == NULL || cmd == NULL) return -1; if (!(base->mFlashStatus & FLASH_READ_QPI_MODE)) { cmd->len = 1; cmd->line = 1; //not in QPI if (addr != NULL) addr->len = 3; if (data != NULL && data->pdata == NULL && data->len <= 4) data->pdata = (uint8_t *)&data->data; } else /* in QPI mode */ { cmd->len = 1; cmd->line = 4; //not in QPI if (addr != NULL) { addr->len = 3; addr->line = 4; } if (dummy != NULL) dummy->line = 4; if (data != NULL) data->line = 4; if (data != NULL && data->pdata == NULL && data->len <= 4) data->pdata = (uint8_t *)&data->data; } if (base->mDriver == NULL || base->mDriver->read == NULL) return -1; FLASH_DEBUG("cmd: 0x%x", cmd->data); return base->mDriver->read(base->mDriver, cmd, addr, dummy, data); }
int defaultErase(FlashChipBase *base, FlashEraseMode mode, uint32_t eaddr) { PCHECK(base); INSTRUCT_ZCREATE(cmd, addr, dummy, data); if (!(mode & base->mEraseSizeSupport)) { FLASH_NOTSUPPORT(); return HAL_INVALID; } FLASH_DEBUG("mode: 0x%x; base->mEraseSizeSupport: 0x%x", mode, base->mEraseSizeSupport); if (mode == FLASH_ERASE_CHIP) { cmd.data = FLASH_INSTRUCTION_ERASE_CHIP; base->driverWrite(base, &cmd, NULL, NULL, NULL); return 0; } else if (mode == FLASH_ERASE_32KB) { cmd.data = FLASH_INSTRUCTION_ERASE_32KB; } else if (mode == FLASH_ERASE_64KB) { cmd.data = FLASH_INSTRUCTION_ERASE_64KB; } else if (mode == FLASH_ERASE_4KB) { cmd.data = FLASH_INSTRUCTION_ERASE_4KB; } else FLASH_NOWAY(); addr.data = eaddr; addr.line = 1; return base->driverWrite(base, &cmd, &addr, NULL, NULL); }
bool DueFlashStorage::write(uint32_t address, const void *data, uint32_t dataLength) { if ((uint32_t)FLASH_START + address < #if SAM4E IFLASH_ADDR #elif SAM4S IFLASH0_ADDR #else IFLASH1_ADDR #endif ) { FLASH_DEBUG("Flash write address too low"); return false; } if ((uint32_t)FLASH_START + address + dataLength > #if SAM4E IFLASH_ADDR + IFLASH_SIZE #elif SAM4S IFLASH0_ADDR + IFLASH0_SIZE #else IFLASH1_ADDR + IFLASH1_SIZE #endif ) { FLASH_DEBUG("Flash write address too high"); return false; } if ((((uint32_t)FLASH_START + address) & 3) != 0) { FLASH_DEBUG("Flash start address must be on 4-byte boundary\n"); return false; } // The flash management code in the ASF is fragile and has a tendency to fail to return. Help it by disabling interrupts. irqflags_t flags = cpu_irq_save(); // Unlock page uint32_t retCode = flash_unlock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Failed to unlock flash for write"); } else { // Write data retCode = flash_write((uint32_t)FLASH_START + address, data, dataLength, 1); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Flash write failed"); } else { // Lock page retCode = flash_lock((uint32_t)FLASH_START + address, (uint32_t)FLASH_START + address + dataLength - 1, NULL, NULL); if (retCode != FLASH_RC_OK) { FLASH_DEBUG("Failed to lock flash page"); } } } cpu_irq_restore(flags); return retCode == FLASH_RC_OK; }
bool Flash_Write(FLASH_HANDLE Handle, alt_u32 offset, alt_u8 *szData, alt_u32 size){ FLASH_INFO *pFlash = (FLASH_INFO *)Handle; bool bSuccess = TRUE; int error_code; if (!pFlash->fd_flash) return FALSE; //FLASH_DEBUG(("Flash_Write, offset=%d, size=%d\r\n", offset, size)); #if 0 error_code = alt_write_flash(fd_flash, offset, szData, size); // note. !!!! it will erase flash block content before write data if (error_code == 0){ bSuccess = TRUE; }else{ FLASH_DEBUG(("alt_write_flash fail, error_code=%d\r\n", error_code)); } #else int block_offset, block_size, write_count, this_write_size, r, i;//, first_offset; flash_region *nextreg = pFlash->regions_flash; block_offset = 0; write_count = 0; for(r=0;r<pFlash->number_of_regions_flash && bSuccess;r++){ for(i=0;i<nextreg->number_of_blocks && bSuccess;i++){ block_size = nextreg->block_size; // FLASH_DEBUG(("block_offset=%d, block_size=%d\r\n", block_offset, block_size)); // if ((offset >= block_offset) && ((offset+size) <= (block_offset + block_size))){ if (((offset+write_count) >= block_offset) && (write_count < size)){ // write this_write_size = size - write_count; if (write_count == 0){ // first block if (this_write_size > (block_offset + block_size - offset)) this_write_size = block_offset + block_size - offset; }else{ // block aligement if (this_write_size > block_size) this_write_size = block_size; } error_code = alt_write_flash_block(pFlash->fd_flash, block_offset, offset+write_count, szData+write_count, this_write_size); //FLASH_DEBUG(("alt_write_flash_block, block_offset:%d, offset:%d, len:%d, this block_size:%d\r\n", block_offset, offset+write_count, this_write_size, block_size)); if (error_code != 0){ bSuccess = FALSE; FLASH_DEBUG(("alt_write_flash_block fail, error_code=%d\r\n", error_code)); } write_count += this_write_size; } block_offset += block_size; } nextreg++; } #endif /* error_code = alt_write_flash(fd_flash, offset, szData, size); // it will erase flash block content before write data // error_code = alt_write_flash_block(fd_flash, offset, offset+size, szData, size); // it will preserve flash content if (error_code == 0) return TRUE; */ return bSuccess; }
int defaultRead(FlashChipBase *base, FlashReadMode mode, uint32_t raddr, uint8_t *rdata, uint32_t size) { PCHECK(base); INSTRUCT_ZCREATE(cmd, addr, dummy, data); if (!(mode & base->mReadSupport)) { FLASH_DEBUG("this flash chip not support read mode: %d", mode); FLASH_NOTSUPPORT(); return HAL_INVALID; } if ((raddr + size) > base->mSize) return -1; FLASH_DEBUG("size: %d; mode: %d", size, (uint32_t)mode); switch (mode) { /* !!! NOTICE: m7~m0 is count to dummy byte. !!! */ case FLASH_READ_NORMAL_MODE: cmd.data = FLASH_INSTRUCTION_READ; addr.line = 1; data.line = 1; dummy.len = 0; break; case FLASH_READ_FAST_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ; addr.line = 1; data.line = 1; dummy.len = 1; dummy.line = 1; break; case FLASH_READ_DUAL_O_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ_DO; addr.line = 1; data.line = 2; dummy.len = 1; dummy.line = 1; break; case FLASH_READ_DUAL_IO_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ_DIO; addr.line = 2; data.line = 2; dummy.len = 1; dummy.line = 2; break; case FLASH_READ_QUAD_O_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ_QO; addr.line = 1; data.line = 4; dummy.len = 1; dummy.line = 1; break; case FLASH_READ_QUAD_IO_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ_QIO; addr.line = 4; data.line = 4; dummy.len = 3; dummy.line = 4; break; case FLASH_READ_QPI_MODE: cmd.data = FLASH_INSTRUCTION_FAST_READ_QIO; cmd.line = 4; data.line = 4; dummy.len = base->mDummyCount; dummy.line = 4; break; default: return -1; } addr.data = raddr; data.pdata = rdata; data.len = size; return base->driverRead(base, &cmd, &addr, &dummy, &data); }