diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e139959..87968ef48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] +- Changed SPI flash detection to calculate the size instead of table lookup, updated spi_flash_decode.py script with more ICs (@ANTodorov) - Add option to set and get maximum read/write block number using `hf_mf_ultimatecard` script (@piotrva) - Added JEDEC information for SPI flash W25Q64JV (@ANTodorov) - Added special iclass legacy config cards in `hf iclass configcard` (@antiklesys) diff --git a/client/pyscripts/spi_flash_decode.py b/client/pyscripts/spi_flash_decode.py index 0f125844b..2a89f57af 100644 --- a/client/pyscripts/spi_flash_decode.py +++ b/client/pyscripts/spi_flash_decode.py @@ -12,62 +12,118 @@ except ModuleNotFoundError: return str(s) spi = { + 0x68:{ + "manufacturer": "Boya", + "jedec" : { + 0x40: { + 0x15: { + "part": "BY25Q16BS", + "size": "16mbits", + "sizeB": "2MB", + }, + }, + }, + }, 0x85:{ "manufacturer": "Puya", - 0x60: { - 0x15: { - "part": "P25Q16H", - "size": "16mbits", - "sizeB": "2MB", + "jedec" : { + 0x60: { + 0x15: { + "part": "P25Q16H", + "size": "16mbits", + "sizeB": "2MB", + }, + 0x16: { + "part": "P25Q32H", + "size": "32mbits", + "sizeB": "4MB", + }, + 0x17: { + "part": "P25Q64H", + "size": "64mbits", + "sizeB": "8MB", + }, }, }, }, 0xEF:{ "manufacturer": "Winbond", - 0x30: { - 0x11: { - "part": "W25X10BV", - "size": "1mbits", - "sizeB": "128KB", + "jedec" : { + 0x30: { + 0x11: { + "part": "W25X10BV", + "size": "1mbits", + "sizeB": "128KB", + }, + 0x12: { + "part": "W25X20BV", + "size": "2mbits", + "sizeB": "256KB", + }, + 0x13: { + "part": "W25X40BV", + "size": "4mbits", + "sizeB": "512KB", + }, }, - 0x12: { - "part": "W25X20BV", - "size": "2mbits", - "sizeB": "256KB", + 0x40: { + 0x12: { + "part": "W25Q20BV", + "size": "2mbits", + "sizeB": "256KB", + }, + 0x13: { + "part": "W25Q40BV", + "size": "4mbits", + "sizeB": "512KB", + }, + 0x14: { + "part": "W25Q80BV", + "size": "8mbits", + "sizeB": "1MB", + }, + 0x15: { + "part": "W25Q16BV", + "size": "16mbits", + "sizeB": "2MB", + }, + 0x16: { + "part": "W25Q32BV", + "size": "32mbits", + "sizeB": "4MB", + }, + 0x17: { + "part": "W25Q64BV", + "size": "64mbits", + "sizeB": "8MB", + }, }, - 0x13: { - "part": "W25X40BV", - "size": "4mbits", - "sizeB": "512KB", - }, - }, - 0x40: { - 0x13: { - "part": "W25Q40BV", - "size": "4mbits", - "sizeB": "512KB", - }, - 0x14: { - "part": "W25Q80BV", - "size": "8mbits", - "sizeB": "1MB", - }, - 0x15: { - "part": "W25Q16BV", - "size": "16mbits", - "sizeB": "2MB", - }, - 0x16: { - "part": "W25Q32BV", - "size": "32mbits", - "sizeB": "4MB", - }, - }, - 0x70: { - 0x22: { - "part": "W25Q02JV-IM", - "size": "2mbits", - "sizeB": "256KB", + 0x70: { + 0x14: { + "part": "W25Q80JV", + "size": "8mbits", + "sizeB": "1MB", + }, + 0x15: { + "part": "W25Q16JV", + "size": "16mbits", + "sizeB": "2MB", + }, + 0x16: { + "part": "W25Q32JV", + "size": "32mbits", + "sizeB": "4MB", + }, + 0x17: { + "part": "W25Q64JV", + "size": "64mbits", + "sizeB": "8MB", + }, + 0x22: { + "part": "W25Q02JV-IM", + "size": "2mbits", + "sizeB": "256KB", + }, }, }, }, @@ -90,16 +146,16 @@ for line in p.grabbed_output.split('\n'): did_h = did >> 8 did_l = did & 0xff t = None - + print(f"\n JEDEC ID....... 0x{mid:X} / 0x{did:X}") if mid in spi: mfr = spi[mid]['manufacturer'] - if did_h in spi[mid]: + if did_h in spi[mid]['jedec']: - if did_l in spi[mid][did_h]: + if did_l in spi[mid]['jedec'][did_h]: - t = spi[mid][did_h][did_l] + t = spi[mid]['jedec'][did_h][did_l] print("\n Manufacturer... " + color(f"{mfr}", fg="green") + "\n Device......... " + color(f"{t['part']}", fg="green") + "\n Size........... " + color(f"{t['size']} ({t['sizeB']})", fg="yellow") diff --git a/common_arm/flashmem.c b/common_arm/flashmem.c index 5aa88b0eb..76b475e9c 100644 --- a/common_arm/flashmem.c +++ b/common_arm/flashmem.c @@ -366,7 +366,6 @@ void Flashmem_print_status(void) { ); } - Dbprintf(" Device.................. " _YELLOW_("%s"), spi_flash_data.device); Dbprintf(" Memory size............. " _YELLOW_("%d kB (%d pages * 64k)"), spi_flash_pages64k * 64, spi_flash_pages64k); uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; @@ -442,21 +441,13 @@ bool FlashDetect(void) { } else { if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading Mfr/Dev (0x90)"); } - // default device is 'unknown' - spi_flash_data.device = SpiFlashTable[0].device; - + // Check JEDEC data is valid, compare the reported device types and then calculate the number of pages + // It is covering the most (known) cases of devices but probably there are vendors with different data + // They will be handled when there is such cases if (ret) { - for (int i = 0; i < ARRAYLEN(SpiFlashTable); i++) { - if (SpiFlashTable[i].manufacturer_id == spi_flash_data.manufacturer_id) { - if (SpiFlashTable[i].jedec_id == spi_flash_data.jedec_id) { - spi_flash_pages64k = SpiFlashTable[i].pages64k; - spi_flash_data.device = SpiFlashTable[i].device; - break; - } - if (SpiFlashTable[i].device_id == spi_flash_data.device_id) { - spi_flash_data.device = SpiFlashTable[i].device; - break; - } + if (spi_flash_data.jedec_id > 0 && spi_flash_data.jedec_id < 0xFFFF) { + if (((spi_flash_data.device_id + 1) & 0x0F) == (spi_flash_data.jedec_id & 0x000F)) { + spi_flash_pages64k = 1 << (spi_flash_data.jedec_id & 0x000F); } } } diff --git a/common_arm/flashmem.h b/common_arm/flashmem.h index 616575e49..f20dd0bff 100644 --- a/common_arm/flashmem.h +++ b/common_arm/flashmem.h @@ -140,41 +140,8 @@ typedef struct { uint8_t manufacturer_id; uint8_t device_id; uint16_t jedec_id; - uint8_t pages64k; - char *device; } spi_flash_t; -static const spi_flash_t SpiFlashTable[] = { - // first element is the default of 4 * 64kB pages (256kB) - { 0x00, 0x00, 0x0000, 4, "unknown" }, // 256k - // Manufacturer: Puya - { 0x85, 0x14, 0x6015, 32, "P25Q16H" }, // 2048k - // 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, 0x16, 0x7017, 128, "W25Q64JV" }, // 8192k - { 0xEF, 0x21, 0x7022, 4, "W25Q02JV" }, - - // identified by Manufacturer /Device ID only - /// Manufacturer: Renesas - { 0x1F, 0x46, 0x0000, 32, "AT25XE161D" }, // 2048k - { 0x1F, 0x47, 0x0000, 64, "AT25XE321D" }, // 4096k -// { 0xEF, 0x05, 0x0000, 1, "Winbond!!!" }, // 64k (too small !!!) - { 0xEF, 0x10, 0x0000, 2, "W25*10BV!" }, // 128k (small !!!) - { 0xEF, 0x11, 0x0000, 4, "W25*20BV" }, // 256k - { 0xEF, 0x12, 0x0000, 8, "W25*40BV" }, // 512k - { 0xEF, 0x13, 0x0000, 16, "W25*80BV" }, // 1024k - { 0xEF, 0x14, 0x0000, 32, "W25*16*" }, // 2048k - { 0xEF, 0x15, 0x0000, 64, "W25*32*" }, // 4096k - { 0xEF, 0x16, 0x0000, 128, "W25*64*" } // 8192k -}; - extern uint8_t spi_flash_pages64k; bool FlashDetect(void);