/********************************************************************************************************* ** Function name : flash_write_sector ** Descriptions : Write flash memory , just in one page memory ** Input parameters : WAddr -- the start address to write ** Output parameters : buf -- the buffer to write the data ** RLength -- the length of the data to write ** Returned value : The operation result. 1 -- sucess, 0 -- false *********************************************************************************************************/ uint8_t flash_write_sector (uint32_t WAddr, uint8_t *buf, uint32_t WLength) { uint32_t i; if (WLength == 0) { return 0; } flash_write_enable(); /* Write enable */ SPI_FLASH_CS_LOW(); /* P0.2--0,CS = 0 选中SPI Flash */ Send_Byte(0x02); Send_Byte((WAddr & 0xFF0000) >> 16); Send_Byte((WAddr & 0x00FF00) >> 8); Send_Byte((WAddr & 0x0000FF)); for (i=0; i<WLength; i++) { Send_Byte(buf[i]); } SPI_FLASH_CS_HIGH(); /* P0.2--1,CS = 1 释放SPI Flash */ while (flash_read_status() & 0x01 != 0x00); return 1; }
/** **************************************************************************************** * @brief Erase n blocks of flash * @param[in] addr A23-A0 specified a valid 24bit address of a block. * @param[in] block_size flash a block content size * @param[in] n requirement erasing number blocks * @description * This function is used to erase serial flash block. ***************************************************************************************** */ void block_erase_flash(uint32_t addr, uint32_t block_size, uint32_t n) { while (n--) { flash_write_enable(); //set the Write Enable Latch bit sf_ctrl_SetCmdAddr(QN_SF_CTRL, __REV(addr | (g_flash_cmd[BE_CMD]<<24))); addr += block_size; } }
/** **************************************************************************************** * @brief Erase n sectors of flash * @param[in] addr A23-A0 specified a valid 24bit address of a sector * @param[in] n number of sector * @description * This function is used to erase serial flash sector. ***************************************************************************************** */ void sector_erase_flash(uint32_t addr, uint32_t n) { while (n--) { flash_write_enable(); //set the Write Enable Latch bit sf_ctrl_SetCmdAddr(QN_SF_CTRL, __REV((addr & 0xffffff) | (g_flash_cmd[SE_CMD]<<24))); addr += 4*1024; //all flash sector erase command erasing size is 4K } }
int flash_physical_erase(int offset, int size) { int rv = EC_SUCCESS; /* check protection */ if (all_protected) return EC_ERROR_ACCESS_DENIED; /* Lock physical flash operations */ flash_lock_mapped_storage(1); /* Disable tri-state */ TRISTATE_FLASH(0); /* Alignment has been checked in upper layer */ for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE, offset += CONFIG_FLASH_ERASE_SIZE) { /* check protection */ if (flash_check_prot_range(offset, CONFIG_FLASH_ERASE_SIZE)) { rv = EC_ERROR_ACCESS_DENIED; break; } /* * Reload the watchdog timer, so that erasing many flash pages * doesn't cause a watchdog reset. May not need this now that * we're using msleep() below. */ watchdog_reload(); /* Enable write */ rv = flash_write_enable(); if (rv) break; /* Set erase address */ flash_set_address(offset); /* Start erase */ flash_execute_cmd(CMD_SECTOR_ERASE, MASK_CMD_ADR); /* Wait erase completed */ rv = flash_wait_ready(FLASH_ABORT_TIMEOUT); if (rv) break; } /* Enable tri-state */ TRISTATE_FLASH(1); /* Unlock physical flash operations */ flash_lock_mapped_storage(0); return rv; }
/********************************************************************************************************* ** Terry: The function must be called once before progremme the SPI Flash ** ** Function name : flash_write_status ** Descriptions : Write the write state register in the flash memory ** Input parameters : none ** Output parameters : The value of the write state register ** Returned value : none *********************************************************************************************************/ void flash_write_status ( uint_16 Status ) { flash_write_enable(); Status|=0x01<<1; //Set SEL to 1 SPI_FLASH_CS_LOW(); /* P0.2--0,CS = 0 选中SPI Flash */ Send_Byte(0x01); Send_Byte((Status & 0x0000FF)); Send_Byte((Status & 0x00FF00) >> 8); SPI_FLASH_CS_HIGH(); /* P0.2--1,CS = 1 释放SPI Flash */ return; }
/********************************************************************************************************* ** Function name : flash_all_erase ** Descriptions : Erase the whole flash ** Input parameters : None ** Output parameters : None ** Returned value : The operation result. 1 -- sucess, 0 -- false *********************************************************************************************************/ uint8_t flash_whole_erase( void ) { flash_write_enable(); /* Write enable */ SPI_FLASH_CS_LOW(); /* P0.2--0,CS = 0 选中SPI Flash */ Send_Byte(0xC7); SPI_FLASH_CS_HIGH(); /* P0.2--1,CS = 1 释放SPI Flash */ while (flash_read_status() & 0x01 != 0x00); /* Wait for the flash free */ return 1; }
/** **************************************************************************************** * @brief Write data to flash * @param[in] addr flash address(3 bytes) * @param[in] pBuf pointer to write data address * @param[in] nByte write size, it must <= 256 and must be 4 integer times * @description * This function is used to write data to serial flash. * * @note * 1. The parameter "addr" note: * - When the address range is from 0x00 to 0x1000 (NVDS area), the address must be 4 * integer times. * - When the address range is greater than or equal to 0x1000 (Code area), the * address must be 256 integer times. (Encryption request) * 2. The parameter "nByte" note: * - When the address range is from 0x00 to 0x1000 (NVDS area), the size must be 4 * integer times and less than or equal to 256. * - When the address range is greater than or equal to 0x1000 (Code area), the * size must be 256 bytes. (Encryption request) ***************************************************************************************** */ void write_flash(uint32_t addr, const uint32_t *pBuf, uint32_t nByte) { addr += QN_FLASH_BASE; //get the data register address of flash control register sf_ctrl_SetDataLen(QN_SF_CTRL, nByte); flash_write_enable(); //set the Write Enable Latch bit nByte >>= 2; //nByte must is 4 integer time. while (nByte--) { *(uint32_t *)addr = *pBuf++; addr += 4; } }
int flash_chip_erase(void) { int ret; flash_write_enable(); flash_spi_select(); ret = flash_cmd(FLASH_BE); flash_spi_unselect(); if (ret == 0) { ret = flash_wait_until_done(FLASH_CHIP_ERASE_TIMEOUT_MS); } flash_write_disable(); return ret; }
/********************************************************************************************************* ** Function name : flash_sector_erase ** Descriptions : Sector erase ** Input parameters : addr -- sector address ** Output parameters : None ** Returned value : The operation result. 1 -- sucess, 0 -- false *********************************************************************************************************/ uint8_t flash_sector_erase (uint32_t addr) { flash_write_enable(); /* Write enable */ SPI_FLASH_CS_LOW(); /* P0.2--0,CS = 0 选中SPI Flash */ Send_Byte(0x20); Send_Byte((addr & 0xFF0000) >> 16); Send_Byte((addr & 0x00FF00) >> 8); Send_Byte(addr & 0x0000FF); SPI_FLASH_CS_HIGH(); /* P0.2--1,CS = 1 释放SPI Flash */ while (flash_read_status() & 0x01 != 0x00); /* Wait for the flash free */ return 1; }
//sector erase (4kB) only works for first 64kB int flash_sector_erase(uint32_t addr) { int ret; if (addr < FLASH_BLOCK_SIZE) { flash_write_enable(); flash_spi_select(); ret = flash_cmd_w_addr(FLASH_P4E, addr); flash_spi_unselect(); if (ret == 0) { ret = flash_wait_until_done(FLASH_BLOCK_64KB_ERASE_TIMEOUT_MS); } flash_write_disable(); return ret; } return -1; }
//Only valid if using 64kB block size int flash_block_erase(uint32_t addr) { int ret; flash_write_enable(); flash_spi_select(); ret = flash_cmd_w_addr(FLASH_SE, addr); flash_spi_unselect(); if (ret == 0) { if (addr < FLASH_BLOCK_SIZE) { ret = flash_wait_until_done(FLASH_BLOCK1_64KB_ERASE_TIMEOUT_MS); } else { ret = flash_wait_until_done(FLASH_BLOCK_64KB_ERASE_TIMEOUT_MS); } } flash_write_disable(); return ret; }
int flash_physical_erase(int offset, int size) { /* check protection */ if (all_protected) return EC_ERROR_ACCESS_DENIED; /* Disable tri-state */ TRISTATE_FLASH(0); /* Alignment has been checked in upper layer */ for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE, offset += CONFIG_FLASH_ERASE_SIZE) { /* Do nothing if already erased */ if (flash_is_erased(offset, CONFIG_FLASH_ERASE_SIZE)) continue; /* check protection */ if (flash_check_prot_range(offset, CONFIG_FLASH_ERASE_SIZE)) return EC_ERROR_ACCESS_DENIED; /* * Reload the watchdog timer, so that erasing many flash pages * doesn't cause a watchdog reset. May not need this now that * we're using msleep() below. */ watchdog_reload(); /* Enable write */ flash_write_enable(); /* Set erase address */ flash_set_address(offset); /* Start erase */ flash_execute_cmd(CMD_SECTOR_ERASE, MASK_CMD_ADR); /* Wait erase completed */ flash_wait_ready(); } /* Enable tri-state */ TRISTATE_FLASH(1); return EC_SUCCESS; }
int flash_set_status_for_prot(int reg1, int reg2) { /* Disable tri-state */ TRISTATE_FLASH(0); /* Enable write */ flash_write_enable(); NPCX_UMA_DB0 = reg1; NPCX_UMA_DB1 = reg2; /* Write status register 1/2 */ flash_execute_cmd(CMD_WRITE_STATUS_REG, MASK_CMD_WR_2BYTE); /* Enable tri-state */ TRISTATE_FLASH(1); reg_to_protect(reg1, reg2, &addr_prot_start, &addr_prot_length); return EC_SUCCESS; }
int flash_write_registers(uint8_t *sr1, uint8_t *cr, uint8_t *sr2) { int ret; int ret2; uint8_t cmd = FLASH_WRR; flash_write_enable(); flash_spi_select(); ret = flash_spi_send(&cmd, 1); //write one config register after the other, null pointer stops process if (ret == 0 && sr1) { ret = flash_spi_send(sr1, 1); if (ret == 0 && cr) { ret = flash_spi_send(cr, 1); if (ret == 0 && sr2) { ret = flash_spi_send(sr2, 1); } } } //this is required to start the procedure to write the registers. flash_spi_unselect(); ret2 = flash_wait_until_done(FLASH_REGISTER_PROGRAM_TIMEOUT_MS); flash_write_disable(); return ret == 0 ? ret2 : ret; }
void doFlash(){ uint32_t addr=0x0; uint32_t sw=0x1; uint8_t data[256]; uint8_t x=0; flashInit(); lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr(addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); lcdDisplay(); while(1){ TOGGLE(LED1); switch(getInput()){ case BTN_UP: /* addr-=sw; lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr((uint32_t)addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); lcdDisplay(); */ flash_write_enable(); lcdPrint("WE done."); lcdDisplay(); break; case BTN_DOWN: addr+=sw; lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr((uint32_t)addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); lcdDisplay(); break; case BTN_LEFT: /*sw<<=1; lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr((uint32_t)addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); lcdDisplay(); */ lcdPrint(IntToStr(flash_status1(),2,F_HEX)); lcdPrint(" "); lcdPrint(IntToStr(flash_status2(),2,F_HEX)); lcdNl();lcdDisplay(); break; case BTN_RIGHT: /*sw>>=1; lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr((uint32_t)addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); lcdDisplay(); */ data[0]=0xfe; data[1]=0xf8; flash_program(addr,0x2,data); lcdPrint("done."); lcdNl(); lcdDisplay(); break; case BTN_ENTER: lcdClear(0xff); lcdPrint("xxd @ "); lcdPrint(IntToStr(addr,8,F_HEX));lcdNl(); lcdPrint(" "); lcdPrint(IntToStr(sw,8,F_HEX));lcdNl(); flash_read(addr,0x100,data); int ctr; for (ctr=0x00;ctr<0x024;ctr++){ if (ctr%4==0){ lcdNl(); lcdPrint(IntToStr(ctr,2,F_HEX)); lcdPrint(":"); }; lcdPrint(" "); lcdPrint(IntToStr(data[ctr],2,F_HEX)); }; lcdNl(); lcdDisplay(); break; }; }; };