mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
chg: wiping / reading / writing flashmem
This commit is contained in:
parent
409c7b1029
commit
f5718fb448
3 changed files with 109 additions and 53 deletions
|
@ -1121,7 +1121,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
@ -1137,8 +1136,40 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_UPLOAD_FLASH_MEM:
|
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;
|
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
|
#endif
|
||||||
case CMD_SET_LF_DIVISOR:
|
case CMD_SET_LF_DIVISOR:
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
|
@ -166,7 +166,7 @@ bool Flash_CheckBusy(uint16_t times){
|
||||||
// read ID out
|
// read ID out
|
||||||
uint8_t Flash_ReadID(void) {
|
uint8_t Flash_ReadID(void) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(1000)) return 0;
|
if (Flash_CheckBusy(100)) return 0;
|
||||||
|
|
||||||
// Manufacture ID / device ID
|
// Manufacture ID / device ID
|
||||||
FlashSendByte(ID);
|
FlashSendByte(ID);
|
||||||
|
@ -188,7 +188,7 @@ uint8_t Flash_ReadID(void) {
|
||||||
// read unique id for chip.
|
// read unique id for chip.
|
||||||
void Flash_UniqueID(uint8_t *uid) {
|
void Flash_UniqueID(uint8_t *uid) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(1000)) return;
|
if (Flash_CheckBusy(100)) return;
|
||||||
|
|
||||||
// reading unique serial number
|
// reading unique serial number
|
||||||
FlashSendByte(UNIQUE_ID);
|
FlashSendByte(UNIQUE_ID);
|
||||||
|
@ -214,7 +214,7 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
Flash_ReadStat1();
|
Flash_ReadStat1();
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len || Flash_CheckBusy(1000)) return 0;
|
if (!len || Flash_CheckBusy(100)) return 0;
|
||||||
|
|
||||||
FlashSendByte(READDATA);
|
FlashSendByte(READDATA);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
@ -231,15 +231,30 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
return 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) {
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len) {
|
if (!len)
|
||||||
Dbprintf("Flash_WriteData len is zero error");
|
return 0;
|
||||||
|
|
||||||
|
// Max 256 bytes write
|
||||||
|
if (((address & 255) + len) > 256) {
|
||||||
|
Dbprintf("Flash_WriteData 256 fail");
|
||||||
return 0;
|
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()) {
|
if (!FlashInit()) {
|
||||||
Dbprintf("Flash_WriteData init fail");
|
Dbprintf("Flash_WriteData init fail");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -249,27 +264,6 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
Flash_WriteEnable();
|
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();
|
|
||||||
|
|
||||||
FlashSendByte(PAGEPROG);
|
FlashSendByte(PAGEPROG);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
@ -285,6 +279,25 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 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
|
// enable the flash write
|
||||||
void Flash_WriteEnable() {
|
void Flash_WriteEnable() {
|
||||||
FlashSendLastByte(WRITEENABLE);
|
FlashSendLastByte(WRITEENABLE);
|
||||||
|
@ -292,20 +305,21 @@ void Flash_WriteEnable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// erase 4K at one time
|
// erase 4K at one time
|
||||||
bool Flash_Erase4k(uint32_t address) {
|
// execution time: 0.8ms / 800us
|
||||||
if (address & (4096 - 1)) {
|
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096");
|
|
||||||
return false;
|
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
|
||||||
}
|
|
||||||
|
|
||||||
FlashSendByte(SECTORERASE);
|
FlashSendByte(SECTORERASE);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte(block);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte(sector << 4);
|
||||||
FlashSendLastByte((address >> 0) & 0xFF);
|
FlashSendLastByte(00);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// erase 32K at one time
|
// erase 32K at one time
|
||||||
|
// execution time: 0,3s / 300ms
|
||||||
bool Flash_Erase32k(uint32_t address) {
|
bool Flash_Erase32k(uint32_t address) {
|
||||||
if (address & (32*1024 - 1)) {
|
if (address & (32*1024 - 1)) {
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096");
|
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);
|
FlashSendLastByte((address >> 0) & 0xFF);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// erase 64k at one time
|
// erase 64k at one time
|
||||||
bool Flash_Erase64k(uint32_t address) {
|
// since a block is 64kb, and there is four blocks.
|
||||||
if (address & (64*1024 - 1)) {
|
// we only need block number, as MSB
|
||||||
if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase64k : Address is not align at 4096");
|
// execution time: 1s / 1000ms
|
||||||
return false;
|
// 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(BLOCK64ERASE);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte(block);
|
||||||
FlashSendByte((address >> 8) & 0xFF);
|
FlashSendByte(0x00);
|
||||||
FlashSendLastByte((address >> 0) & 0xFF);
|
FlashSendLastByte(0x00);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +363,7 @@ bool FlashInit(void) {
|
||||||
|
|
||||||
StartTicks();
|
StartTicks();
|
||||||
|
|
||||||
if (Flash_CheckBusy(1000)) {
|
if (Flash_CheckBusy(100)) {
|
||||||
StopTicks();
|
StopTicks();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,8 +89,6 @@
|
||||||
#define NO_CONTINUE 0x00
|
#define NO_CONTINUE 0x00
|
||||||
#define PASS 0x01
|
#define PASS 0x01
|
||||||
#define FAIL 0x00
|
#define FAIL 0x00
|
||||||
#define arrayLen(x) (sizeof(x) / sizeof(*x))
|
|
||||||
#define lengthOf(x) (sizeof(x))/sizeof(byte)
|
|
||||||
#define maxAddress capacity
|
#define maxAddress capacity
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
|
@ -108,6 +106,11 @@
|
||||||
#define NOSUSPEND 0x09
|
#define NOSUSPEND 0x09
|
||||||
#define UNKNOWNERROR 0xFF
|
#define UNKNOWNERROR 0xFF
|
||||||
|
|
||||||
|
// List of blocks
|
||||||
|
#define MAX_BLOCKS 4
|
||||||
|
#define MAX_SECTORS 16
|
||||||
|
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
extern void Dbprintf(const char *fmt, ...);
|
extern void Dbprintf(const char *fmt, ...);
|
||||||
|
|
||||||
|
@ -119,9 +122,10 @@ uint8_t Flash_ReadStat2(void);
|
||||||
uint16_t FlashSendByte(uint32_t data);
|
uint16_t FlashSendByte(uint32_t data);
|
||||||
|
|
||||||
void Flash_WriteEnable();
|
void Flash_WriteEnable();
|
||||||
bool Flash_Erase4k(uint32_t address);
|
bool Flash_WipeMemory();
|
||||||
bool Flash_Erase32k(uint32_t address);
|
bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
||||||
bool Flash_Erase64k(uint32_t address);
|
//bool Flash_Erase32k(uint32_t address);
|
||||||
|
bool Flash_Erase64k(uint8_t block);
|
||||||
|
|
||||||
bool FlashInit();
|
bool FlashInit();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue