refactor spi flash detection

This commit is contained in:
ANTodorov 2024-11-18 19:59:20 +02:00
commit f3fa732062
No known key found for this signature in database
GPG key ID: 318CC11D7ED4016B
6 changed files with 118 additions and 131 deletions

View file

@ -2748,11 +2748,11 @@ static void PacketReceived(PacketCommandNG *packet) {
break; break;
} }
if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k)) { if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p->p64k)) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xC); Flash_Erase4k(3, 0xC);
} else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k)) { } else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p->p64k)) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0x8); Flash_Erase4k(3, 0x8);
@ -2762,11 +2762,11 @@ static void PacketReceived(PacketCommandNG *packet) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xA); Flash_Erase4k(3, 0xA);
} else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p64k)) { } else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p->p64k)) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xB); Flash_Erase4k(3, 0xB);
} else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p64k)) { } else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p->p64k)) {
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xF); Flash_Erase4k(3, 0xF);
@ -2789,7 +2789,7 @@ static void PacketReceived(PacketCommandNG *packet) {
LED_B_OFF(); LED_B_OFF();
break; break;
} }
if (page < spi_flash_p64k-1) { if (page < spi_flash_p->p64k-1) {
isok = Flash_WipeMemoryPage(page); isok = Flash_WipeMemoryPage(page);
// let spiffs check and update its info post flash erase // let spiffs check and update its info post flash erase
rdv40_spiffs_check(); rdv40_spiffs_check();
@ -2836,7 +2836,7 @@ static void PacketReceived(PacketCommandNG *packet) {
LED_B_ON(); LED_B_ON();
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t)); rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p64k), info->signature, FLASH_MEM_SIGNATURE_LEN); bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p->p64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
if (FlashInit()) { if (FlashInit()) {
Flash_UniqueID(info->flashid); Flash_UniqueID(info->flashid);
@ -2856,11 +2856,11 @@ static void PacketReceived(PacketCommandNG *packet) {
if (FlashInit()) { if (FlashInit()) {
isok = true; isok = true;
if (g_dbglevel >= DBG_DEBUG) { if (g_dbglevel >= DBG_DEBUG) {
Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_p64k, spi_flash_p64k); Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_p->p64k, spi_flash_p->p64k);
} }
FlashStop(); FlashStop();
} }
reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_p64k, sizeof(uint8_t)); reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_p->p64k, sizeof(uint8_t));
LED_B_OFF(); LED_B_OFF();
break; break;

View file

@ -2148,7 +2148,7 @@ void T55xx_ChkPwds(uint8_t flags, bool ledcontrol) {
BigBuf_Clear_EM(); BigBuf_Clear_EM();
uint16_t isok = 0; uint16_t isok = 0;
uint8_t counter[2] = {0x00, 0x00}; uint8_t counter[2] = {0x00, 0x00};
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k), counter, sizeof(counter)); isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p->p64k), counter, sizeof(counter));
if (isok != sizeof(counter)) if (isok != sizeof(counter))
goto OUT; goto OUT;
@ -2164,7 +2164,7 @@ void T55xx_ChkPwds(uint8_t flags, bool ledcontrol) {
// adjust available pwd_count // adjust available pwd_count
pwd_count = pwd_size_available / 4; pwd_count = pwd_size_available / 4;
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k) + 2, pwds, pwd_size_available); isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p->p64k) + 2, pwds, pwd_size_available);
if (isok != pwd_size_available) if (isok != pwd_size_available)
goto OUT; goto OUT;

View file

@ -1789,7 +1789,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
BigBuf_free(); BigBuf_free();
uint16_t isok = 0; uint16_t isok = 0;
uint8_t size[2] = {0x00, 0x00}; uint8_t size[2] = {0x00, 0x00};
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k), size, 2); isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p->p64k), size, 2);
if (isok != 2) if (isok != 2)
goto OUT; goto OUT;
@ -1808,7 +1808,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
if (datain == NULL) if (datain == NULL)
goto OUT; goto OUT;
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k) + 2, datain, key_mem_available); isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p->p64k) + 2, datain, key_mem_available);
if (isok != key_mem_available) if (isok != key_mem_available)
goto OUT; goto OUT;

View file

@ -236,7 +236,7 @@ typedef uint8_t u8_t;
// Instead of giving parameters in config struct, singleton build must // Instead of giving parameters in config struct, singleton build must
// give parameters in defines below. // give parameters in defines below.
#ifndef SPIFFS_CFG_PHYS_SZ #ifndef SPIFFS_CFG_PHYS_SZ
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024 * 64 * (spi_flash_p64k - 1)) #define SPIFFS_CFG_PHYS_SZ(ignore) (1024 * 64 * (spi_flash_p->p64k - 1))
#endif #endif
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ #ifndef SPIFFS_CFG_PHYS_ERASE_SZ
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024) #define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024)

View file

@ -43,7 +43,34 @@ static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
#ifndef AS_BOOTROM #ifndef AS_BOOTROM
uint8_t spi_flash_p64k = 0; const spi_flash_t SpiFlashTable[] = {
// first element is the default of 4 * 64kB pages (256kB)
{ 0x00, 0x00, 0x0000, 4, "unknown" }, // 256k
// Manufacturer: Puya
{ 0x85, 0x00, 0x6015, 32, "P25Q16H" }, // 2048k
/// Manufacturer: Renesas
{ 0x1F, 0x46, 0x0000, 32, "AT25XE161D" }, // 2048k
{ 0x1F, 0x47, 0x0000, 64, "AT25XE321D" }, // 4096k
// Manufacturer: Winbond
{ 0xEF, 0x00, 0x3012, 4, "W25X20BV" }, // 256k
{ 0xEF, 0x00, 0x3013, 8, "W25X40BV" }, // 512k
{ 0xEF, 0x00, 0x4013, 8, "W25Q40BV" }, // 512k
{ 0xEF, 0x00, 0x4014, 16, "W25Q80BV" }, // 1024k
{ 0xEF, 0x14, 0x4015, 32, "W25Q16BV" }, // 2048k
{ 0xEF, 0x15, 0x4016, 64, "W25Q32BV" }, // 4096k
{ 0xEF, 0x21, 0x7022, 4, "W25Q02JV" },
// identified by Manufacturer /Device ID
// { 0xEF, 0x05, 0x0000, 1, "Winbond!!!" },
{ 0xEF, 0x10, 0x0000, 2, "W25*10BV!!!" }, // 128k
{ 0xEF, 0x11, 0x0000, 4, "W25*20BV" }, // 256k
{ 0xEF, 0x12, 0x0000, 8, "W25*40BV" }, // 512k
{ 0xEF, 0x13, 0x0000, 16, "W25*80BV" } // 1024k
};
const spi_flash_t *spi_flash_p = SpiFlashTable;
spi_flash_t spi_flash_data = {0};
void FlashmemSetSpiBaudrate(uint32_t baudrate) { void FlashmemSetSpiBaudrate(uint32_t baudrate) {
FLASHMEM_SPIBAUDRATE = baudrate; FLASHMEM_SPIBAUDRATE = baudrate;
@ -60,9 +87,9 @@ bool Flash_ReadID(flash_device_type_t *result, bool read_jedec) {
// 0x9F JEDEC // 0x9F JEDEC
FlashSendByte(JEDECID); FlashSendByte(JEDECID);
result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF); result->mfr_id = (FlashSendByte(0xFF) & 0xFF);
result->device_id = (FlashSendByte(0xFF) & 0xFF); result->device_id = (FlashSendByte(0xFF) & 0xFF);
result->device_id2 = (FlashSendLastByte(0xFF) & 0xFF); result->device_id2 = (FlashSendLastByte(0xFF) & 0xFF);
} else { } else {
// 0x90 Manufacture ID / device ID // 0x90 Manufacture ID / device ID
FlashSendByte(ID); FlashSendByte(ID);
@ -70,8 +97,8 @@ bool Flash_ReadID(flash_device_type_t *result, bool read_jedec) {
FlashSendByte(0x00); FlashSendByte(0x00);
FlashSendByte(0x00); FlashSendByte(0x00);
result->manufacturer_id = (FlashSendByte(0xFF) & 0xFF); result->mfr_id = (FlashSendByte(0xFF) & 0xFF);
result->device_id = (FlashSendLastByte(0xFF) & 0xFF); result->device_id = (FlashSendLastByte(0xFF) & 0xFF);
} }
return true; return true;
@ -152,8 +179,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
} }
// out-of-range // out-of-range
if (((address >> 16) & 0xFF) > spi_flash_p64k) { if (((address >> 16) & 0xFF) > spi_flash_p->p64k) {
Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k); Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p->p64k);
FlashStop(); FlashStop();
return 0; return 0;
} }
@ -190,8 +217,8 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
return 0; return 0;
} }
if (((address >> 16) & 0xFF) > spi_flash_p64k) { if (((address >> 16) & 0xFF) > spi_flash_p->p64k) {
Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k); Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p->p64k);
return 0; return 0;
} }
@ -269,7 +296,7 @@ bool Flash_WipeMemory(void) {
// Each block is 64Kb. Four blocks // Each block is 64Kb. Four blocks
// one block erase takes 1s ( 1000ms ) // one block erase takes 1s ( 1000ms )
for (uint8_t i=0; i < spi_flash_p64k; i++) { for (uint8_t i=0; i < spi_flash_p->p64k; i++) {
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase64k(i); Flash_Erase64k(i);
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
@ -289,7 +316,7 @@ void Flash_WriteEnable(void) {
// execution time: 0.8ms / 800us // execution time: 0.8ms / 800us
bool Flash_Erase4k(uint8_t block, uint8_t sector) { bool Flash_Erase4k(uint8_t block, uint8_t sector) {
if (block > spi_flash_p64k || sector > MAX_SECTORS) return false; if (block > spi_flash_p->p64k || sector > MAX_SECTORS) return false;
FlashSendByte(SECTORERASE); FlashSendByte(SECTORERASE);
FlashSendByte(block); FlashSendByte(block);
@ -324,7 +351,7 @@ bool Flash_Erase32k(uint32_t address) {
// 0x03 00 00 -- 0x 03 FF FF == block 3 // 0x03 00 00 -- 0x 03 FF FF == block 3
bool Flash_Erase64k(uint8_t block) { bool Flash_Erase64k(uint8_t block) {
if (block > spi_flash_p64k) return false; if (block > spi_flash_p->p64k) return false;
FlashSendByte(BLOCK64ERASE); FlashSendByte(BLOCK64ERASE);
FlashSendByte(block); FlashSendByte(block);
@ -350,57 +377,22 @@ void Flashmem_print_status(void) {
} }
DbpString(" Init.................... " _GREEN_("ok")); DbpString(" Init.................... " _GREEN_("ok"));
// NOTE: It would likely be more useful to use JDEC ID command 9F, if (spi_flash_data.device_id > 0 ) {
// as it provides a third byte indicative of capacity. Dbprintf(" Mfr ID / Dev ID......... " _YELLOW_("%02X / %02X"),
flash_device_type_t device_type = {0}; spi_flash_data.mfr_id,
if (!Flash_ReadID(&device_type, false)) { spi_flash_data.device_id
DbpString(" Device ID............... " _RED_(" --> Not Found <--")); );
} else {
if (device_type.manufacturer_id == WINBOND_MANID) {
switch (device_type.device_id) {
case WINBOND_32MB_DEVID:
DbpString(" Memory size............. " _YELLOW_("32 mbits / 4 MB"));
break;
case WINBOND_16MB_DEVID:
DbpString(" Memory size............. " _YELLOW_("16 mbits / 2 MB"));
break;
case WINBOND_8MB_DEVID:
DbpString(" Memory size............. " _YELLOW_("8 mbits / 1 MB"));
break;
case WINBOND_4MB_DEVID:
DbpString(" Memory size............. " _YELLOW_("4 mbits / 512 kb"));
break;
case WINBOND_2MB_DEVID:
DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb"));
break;
case WINBOND_1MB_DEVID:
DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb"));
break;
case WINBOND_512KB_DEVID:
DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb"));
break;
default:
Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (Winbond)"),
device_type.manufacturer_id,
device_type.device_id
);
break;
}
} else {
Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"),
device_type.manufacturer_id,
device_type.device_id
);
}
if (Flash_ReadID(&device_type, true)) {
Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %02X%02X"),
device_type.manufacturer_id,
device_type.device_id,
device_type.device_id2
);
}
} }
Dbprintf(" Flash pages (64k)....... " _YELLOW_("0x%02x (%u)"), spi_flash_p64k, spi_flash_p64k);
if (spi_flash_data.jedec_id > 0) {
Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %04X"),
spi_flash_data.mfr_id,
spi_flash_data.jedec_id
);
}
Dbprintf(" Device.................. " _YELLOW_("%s"), spi_flash_p->desc);
Dbprintf(" Memory size............. " _YELLOW_("%d kB (%d pages * 64k)"), spi_flash_p->p64k * 64, spi_flash_p->p64k);
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
Flash_UniqueID(uid); Flash_UniqueID(uid);
@ -428,7 +420,7 @@ void Flashmem_print_info(void) {
uint16_t num; uint16_t num;
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2); uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p->p64k), keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
@ -436,7 +428,7 @@ void Flashmem_print_info(void) {
} }
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2); isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p->p64k), keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
@ -444,7 +436,7 @@ void Flashmem_print_info(void) {
} }
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2); isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p->p64k), keysum, 2);
if (isok == 2) { if (isok == 2) {
num = ((keysum[1] << 8) | keysum[0]); num = ((keysum[1] << 8) | keysum[0]);
if (num != 0xFFFF && num != 0x0) if (num != 0xFFFF && num != 0x0)
@ -454,26 +446,44 @@ void Flashmem_print_info(void) {
FlashStop(); FlashStop();
} }
//read spi flash JEDEC ID and fill the global variable spi_flash_p64k bool FlashDetect(const spi_flash_t **spi_flash_ptr) {
bool FlashDetect(void) { flash_device_type_t flash_data = {0};
flash_device_type_t flash_device = {0}; bool ret = false;
// read JEDEC
if (!Flash_ReadID(&flash_device, true)) { if (Flash_ReadID(&flash_data, true)) {
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed"); spi_flash_data.mfr_id = flash_data.mfr_id;
return false; spi_flash_data.jedec_id = (flash_data.device_id <<8) + flash_data.device_id2;
ret = true;
} else{
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading JEDEC (0x9F)");
} }
uint32_t identifier = (flash_device.manufacturer_id << 16) + (flash_device.device_id <<8 ) + flash_device.device_id2; if (Flash_ReadID(&flash_data, false)) {
int i = 0; if (spi_flash_data.mfr_id == 0) {
for (; i < ARRAYLEN(SpiFlashTable)-1; i++) { spi_flash_data.mfr_id = flash_data.mfr_id;
if (SpiFlashTable[i].identifier == identifier) { }
break; spi_flash_data.device_id = flash_data.device_id;
ret = true;
} else {
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading Mfr/Dev (0x90)");
}
if (ret) {
for (int i=0; i < ARRAYLEN(SpiFlashTable); i++) {
if (SpiFlashTable[i].mfr_id == spi_flash_data.mfr_id) {
if (SpiFlashTable[i].jedec_id == spi_flash_data.jedec_id) {
*spi_flash_ptr = *spi_flash_ptr + i;
break;
}
if (SpiFlashTable[i].device_id == spi_flash_data.device_id) {
*spi_flash_ptr = *spi_flash_ptr + i;
break;
}
}
} }
} }
spi_flash_p64k = SpiFlashTable[i].pages64; return ret;
return true;
} }
#endif // #ifndef AS_BOOTROM #endif // #ifndef AS_BOOTROM
@ -491,8 +501,8 @@ bool FlashInit(void) {
} }
#ifndef AS_BOOTROM #ifndef AS_BOOTROM
if (spi_flash_p64k == 0) { if (spi_flash_data.mfr_id == 0) {
if (!FlashDetect()) { if (!FlashDetect(&spi_flash_p)) {
return false; return false;
} }
} }

View file

@ -54,15 +54,6 @@
// Flash busy timeout: 20ms is the strict minimum when writing 256kb // Flash busy timeout: 20ms is the strict minimum when writing 256kb
#define BUSY_TIMEOUT 200000L #define BUSY_TIMEOUT 200000L
#define WINBOND_MANID 0xEF
#define WINBOND_32MB_DEVID 0x15
#define WINBOND_16MB_DEVID 0x14
#define WINBOND_8MB_DEVID 0x13
#define WINBOND_4MB_DEVID 0x12
#define WINBOND_2MB_DEVID 0x11
#define WINBOND_1MB_DEVID 0x10
#define WINBOND_512KB_DEVID 0x05
#define PAGESIZE 0x100 #define PAGESIZE 0x100
#define WINBOND_WRITE_DELAY 0x02 #define WINBOND_WRITE_DELAY 0x02
@ -131,7 +122,7 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector);
bool Flash_Erase64k(uint8_t block); bool Flash_Erase64k(uint8_t block);
typedef struct { typedef struct {
uint8_t manufacturer_id; uint8_t mfr_id;
uint8_t device_id; uint8_t device_id;
uint8_t device_id2; uint8_t device_id2;
} flash_device_type_t; // extra device_id used for the JEDEC ID read via cmd 9F } flash_device_type_t; // extra device_id used for the JEDEC ID read via cmd 9F
@ -145,38 +136,24 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
void Flashmem_print_status(void); void Flashmem_print_status(void);
void Flashmem_print_info(void); void Flashmem_print_info(void);
typedef struct spi_flash_s { typedef struct {
const uint32_t identifier; uint8_t mfr_id;
const uint8_t pages64; uint8_t device_id;
const char *desc; uint16_t jedec_id;
} spi_flash_t; uint8_t p64k;
char *desc;
}spi_flash_t;
const static spi_flash_t SpiFlashTable[] = { extern const spi_flash_t spiFlashTable[];
// Manufacturer: Puya extern const spi_flash_t *spi_flash_p;
{ 0x856015, 32, "P25Q16H" }, extern spi_flash_t spi_flash_data;
// Manufacturer: Winbond
{ 0xEF3012, 4, "W25X20BV" },
{ 0xEF3013, 8, "W25X40BV" },
{ 0xEF4013, 8, "W25Q40BV" }, bool FlashDetect(const spi_flash_t **);
{ 0xEF4014, 16, "W25Q80BV" },
{ 0xEF4015, 32, "W25Q16BV" },
{ 0xEF4016, 64, "W25Q32BV" },
{ 0xEF7022, 4, "W25Q02JV" },
// (default) last record
{ 0x000000, 4, "Unknown!" }
};
#ifndef ARRAYLEN #ifndef ARRAYLEN
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) # define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
#endif #endif
extern uint8_t spi_flash_p64k;
bool FlashDetect(void);
#endif // #ifndef AS_BOOTROM #endif // #ifndef AS_BOOTROM
#endif #endif