chg: wiping / reading / writing flashmem

This commit is contained in:
iceman1001 2018-04-20 16:11:10 +02:00
commit f5718fb448
3 changed files with 109 additions and 53 deletions

View file

@ -1121,7 +1121,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
break;
}
}
// Trigger a finish downloading signal with an ACK frame
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
LED_B_OFF();
break;
@ -1137,8 +1136,40 @@ void UsbPacketReceived(uint8_t *packet, int len) {
break;
}
case CMD_UPLOAD_FLASH_MEM:
case CMD_DOWNLOAND_FLASH_MEM:
LED_B_ON();
cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
LED_B_OFF();
break;
case CMD_DOWNLOAND_FLASH_MEM: {
LED_B_ON();
uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE);
bool isok = false;
size_t len = 0;
uint32_t startidx = c->arg[0];
uint32_t numofbytes = c->arg[1];
// arg0 = startindex
// arg1 = length bytes to transfer
// arg2 = RFU
//Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]);
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
isok = Flash_ReadData(startidx + i, mem, len);
if (!isok )
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
if (!isok)
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
}
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
LED_B_OFF();
break;
}
#endif
case CMD_SET_LF_DIVISOR:
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);

View file

@ -146,7 +146,7 @@ uint8_t Flash_ReadStat2(void) {
}
// determine whether FLASHMEM is busy
bool Flash_CheckBusy(uint16_t times){
bool Flash_CheckBusy(uint16_t times) {
bool ret = (Flash_ReadStat1() & BUSY);
if (!ret || !times || !(times--))
@ -166,7 +166,7 @@ bool Flash_CheckBusy(uint16_t times){
// read ID out
uint8_t Flash_ReadID(void) {
if (Flash_CheckBusy(1000)) return 0;
if (Flash_CheckBusy(100)) return 0;
// Manufacture ID / device ID
FlashSendByte(ID);
@ -188,7 +188,7 @@ uint8_t Flash_ReadID(void) {
// read unique id for chip.
void Flash_UniqueID(uint8_t *uid) {
if (Flash_CheckBusy(1000)) return;
if (Flash_CheckBusy(100)) return;
// reading unique serial number
FlashSendByte(UNIQUE_ID);
@ -214,7 +214,7 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
Flash_ReadStat1();
// length should never be zero
if (!len || Flash_CheckBusy(1000)) return 0;
if (!len || Flash_CheckBusy(100)) return 0;
FlashSendByte(READDATA);
FlashSendByte((address >> 16) & 0xFF);
@ -231,42 +231,36 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
return len;
}
// Write data
// Write data can only program one page. A page has 256 bytes.
// if len > 256, it might wrap around and overwrite pos 0.
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
// length should never be zero
if (!len) {
Dbprintf("Flash_WriteData len is zero error");
if (!len)
return 0;
// Max 256 bytes write
if (((address & 255) + len) > 256) {
Dbprintf("Flash_WriteData 256 fail");
return 0;
}
// out-of-range
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
Dbprintf("Flash_WriteData, block out-of-range");
return 0;
}
// if 256b, empty out lower index.
if (len == 256)
address &= 0xFFFF00;
if (!FlashInit()) {
Dbprintf("Flash_WriteData init fail");
return 0;
}
Flash_ReadStat1();
Flash_WriteEnable();
if ( len < 0x1000 )
Flash_Erase4k(0x00);
else if ( len >= 0x1000 && len < 0x7FFF )
Flash_Erase32k(0x00);
else
Flash_Erase64k(0x00);
// busy after erasing
if (Flash_CheckBusy(1000)) {
Dbprintf("Flash_WriteData check busy");
return 0;
}
// ²»ÄÜ¿çÔ½ 256 ×ֽڱ߽ç
if (((address & 255) + len) > 256) {
Dbprintf("Flash_WriteData 256 fail");
return 0;
}
Flash_WriteEnable();
@ -285,6 +279,25 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
return len;
}
// Wipes flash memory completely, fills with 0xFF
bool Flash_WipeMemory() {
if (!FlashInit()) {
Dbprintf("Flash_WriteData init fail");
return false;
}
Flash_ReadStat1();
// Each block is 64Kb. Four blocks
// one block erase takes 1s ( 1000ms )
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(1000);
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(1000);
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(1000);
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(1000);
FlashStop();
return true;
}
// enable the flash write
void Flash_WriteEnable() {
FlashSendLastByte(WRITEENABLE);
@ -292,20 +305,21 @@ void Flash_WriteEnable() {
}
// erase 4K at one time
bool Flash_Erase4k(uint32_t address) {
if (address & (4096 - 1)) {
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096");
return false;
}
// execution time: 0.8ms / 800us
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
FlashSendByte(SECTORERASE);
FlashSendByte((address >> 16) & 0xFF);
FlashSendByte((address >> 8) & 0xFF);
FlashSendLastByte((address >> 0) & 0xFF);
FlashSendByte(block);
FlashSendByte(sector << 4);
FlashSendLastByte(00);
return true;
}
/*
// erase 32K at one time
// execution time: 0,3s / 300ms
bool Flash_Erase32k(uint32_t address) {
if (address & (32*1024 - 1)) {
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
@ -317,17 +331,24 @@ bool Flash_Erase32k(uint32_t address) {
FlashSendLastByte((address >> 0) & 0xFF);
return true;
}
*/
// erase 64k at one time
bool Flash_Erase64k(uint32_t address) {
if (address & (64*1024 - 1)) {
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase64k : Address is not align at 4096");
return false;
}
// erase 64k at one time
// since a block is 64kb, and there is four blocks.
// we only need block number, as MSB
// execution time: 1s / 1000ms
// 0x00 00 00 -- 0x 00 FF FF == block 0
// 0x01 00 00 -- 0x 01 FF FF == block 1
// 0x02 00 00 -- 0x 02 FF FF == block 2
// 0x03 00 00 -- 0x 03 FF FF == block 3
bool Flash_Erase64k(uint8_t block) {
if (block > MAX_BLOCKS) return false;
FlashSendByte(BLOCK64ERASE);
FlashSendByte((address >> 16) & 0xFF);
FlashSendByte((address >> 8) & 0xFF);
FlashSendLastByte((address >> 0) & 0xFF);
FlashSendByte(block);
FlashSendByte(0x00);
FlashSendLastByte(0x00);
return true;
}
@ -342,7 +363,7 @@ bool FlashInit(void) {
StartTicks();
if (Flash_CheckBusy(1000)) {
if (Flash_CheckBusy(100)) {
StopTicks();
return false;
}

View file

@ -89,8 +89,6 @@
#define NO_CONTINUE 0x00
#define PASS 0x01
#define FAIL 0x00
#define arrayLen(x) (sizeof(x) / sizeof(*x))
#define lengthOf(x) (sizeof(x))/sizeof(byte)
#define maxAddress capacity
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
@ -108,6 +106,11 @@
#define NOSUSPEND 0x09
#define UNKNOWNERROR 0xFF
// List of blocks
#define MAX_BLOCKS 4
#define MAX_SECTORS 16
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
extern void Dbprintf(const char *fmt, ...);
@ -119,9 +122,10 @@ uint8_t Flash_ReadStat2(void);
uint16_t FlashSendByte(uint32_t data);
void Flash_WriteEnable();
bool Flash_Erase4k(uint32_t address);
bool Flash_Erase32k(uint32_t address);
bool Flash_Erase64k(uint32_t address);
bool Flash_WipeMemory();
bool Flash_Erase4k(uint8_t block, uint8_t sector);
//bool Flash_Erase32k(uint32_t address);
bool Flash_Erase64k(uint8_t block);
bool FlashInit();