From dc67b5d7c9301cef64ee2286887243fcc34384c4 Mon Sep 17 00:00:00 2001 From: Chris Date: Sun, 23 Sep 2018 05:29:55 +0200 Subject: [PATCH] chg: revert fpga_major mode in LF. chg: 'lf t55xx deviceconfig' - persistence to flashmem is now option with param P --- armsrc/appmain.c | 2 +- armsrc/apps.h | 2 +- armsrc/flashmem.c | 48 +++++++++++++++++++++++++++++++++-------- armsrc/flashmem.h | 1 + armsrc/lfops.c | 52 ++++++++++++++++++++++++++++----------------- client/cmdlft55xx.c | 14 +++++++----- client/util.c | 4 ++-- common/i2c.c | 10 ++++----- common/protocols.h | 1 + include/common.h | 32 ++++++++++++++++++++++------ 10 files changed, 117 insertions(+), 49 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 8a63f72e4..a84a33d48 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -633,7 +633,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { switch(c->cmd) { #ifdef WITH_LF case CMD_SET_LF_T55XX_CONFIG: - setT55xxConfig((t55xx_config *) c->d.asBytes); + setT55xxConfig( c->arg[0], (t55xx_config *) c->d.asBytes); break; case CMD_SET_LF_SAMPLING_CONFIG: setSamplingConfig((sample_config *) c->d.asBytes); diff --git a/armsrc/apps.h b/armsrc/apps.h index 81a073904..1e8524d57 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -108,7 +108,7 @@ void TurnReadLFOn(uint32_t delay); void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd); void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd); void Cotag(uint32_t arg0); -void setT55xxConfig(t55xx_config *c); +void setT55xxConfig(uint8_t arg0, t55xx_config *c); t55xx_config * getT55xxConfig(void); void printT55xxConfig(void); void loadT55xxConfig(void); diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 3007ffbc1..3a46500ba 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -13,7 +13,6 @@ uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; - void FlashmemSetSpiBaudrate(uint32_t baudrate){ FLASHMEM_SPIBAUDRATE = baudrate; Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000); @@ -316,7 +315,6 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { //////////////////////////////////////// - // 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) { @@ -361,25 +359,25 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { return len; } + +// length should never be zero +// Max 256 bytes write +// out-of-range uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) { - // length should never be zero if (!len) return 0; - // Max 256 bytes write if (((address & 0xFF) + len) > 256) { - Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); + Dbprintf("Flash_WriteDataCont 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len ); return 0; } - // out-of-range if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) { - Dbprintf("Flash_WriteData, block out-of-range"); + Dbprintf("Flash_WriteDataCont, block out-of-range"); return 0; } - FlashSendByte(PAGEPROG); FlashSendByte((address >> 16) & 0xFF); FlashSendByte((address >> 8) & 0xFF); @@ -390,10 +388,42 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) { FlashSendByte(in[i]); FlashSendLastByte(in[i]); - return len; } +// assumes valid start 256 based 00 address +// +uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) { + + bool isok; + uint16_t res, bytes_sent = 0, bytes_remaining = len; + uint8_t buf[FLASH_MEM_BLOCK_SIZE]; + while (bytes_remaining > 0) { + + Flash_CheckBusy(BUSY_TIMEOUT); + Flash_WriteEnable(); + + uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); + + memcpy(buf, in + bytes_sent, bytes_in_packet); + + res = Flash_WriteDataCont(address + bytes_sent, buf, bytes_in_packet); + + bytes_remaining -= bytes_in_packet; + bytes_sent += bytes_in_packet; + + isok = (res == bytes_in_packet); + + if (!isok) + goto out; + } + +out: + FlashStop(); + return len; +} + + bool Flash_WipeMemoryPage(uint8_t page) { if (!FlashInit()) { if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index ae10ea388..da81363c0 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -144,6 +144,7 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len); +uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len); uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len); uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len); void Flashmem_print_status(void); diff --git a/armsrc/lfops.c b/armsrc/lfops.c index ce161d6dd..18e178c1f 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -70,7 +70,7 @@ void printT55xxConfig(void) { Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap/8, t_config.read_gap); } -void setT55xxConfig(t55xx_config *c) { +void setT55xxConfig(uint8_t arg0, t55xx_config *c) { if (c->start_gap != 0) t_config.start_gap = c->start_gap; if (c->write_gap != 0) t_config.write_gap = c->write_gap; @@ -81,24 +81,36 @@ void setT55xxConfig(t55xx_config *c) { printT55xxConfig(); #if WITH_FLASH + // shall persist to flashmem + if (arg0 == 0) { + return; + } + if (!FlashInit()) { return; } - uint8_t buf[T55XX_CONFIG_LEN]; + uint8_t *buf = BigBuf_malloc(4096); + Flash_CheckBusy(BUSY_TIMEOUT); + uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, 4096); + if ( res == 0) { + FlashStop(); + BigBuf_free(); + return; + } + memcpy(buf, &t_config, T55XX_CONFIG_LEN); Flash_CheckBusy(BUSY_TIMEOUT); - Flash_WriteEnable(); - uint16_t isok = Flash_WriteDataCont(T55XX_CONFIG_OFFSET, buf, sizeof(buf)); - FlashStop(); + Flash_WriteEnable(); + Flash_Erase4k(3, 0xD); + res = Flash_Write(T55XX_CONFIG_OFFSET, buf, 4096); - if ( isok == T55XX_CONFIG_LEN) { - if (MF_DBGLEVEL > 1) { - DbpString("T55XX Config save success"); - Dbhexdump(sizeof(buf), buf, false); - } + if ( res == 4096 && MF_DBGLEVEL > 1) { + DbpString("T55XX Config save success"); } + + BigBuf_free(); #endif } @@ -139,7 +151,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint // Make sure the tag is reset FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitMS(500); // clear read buffer @@ -180,7 +192,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint if (command[counter] == '0') { // if field already off leave alone (affects timing otherwise) if (off == false) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); off = true; } @@ -207,7 +219,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint TurnReadLFOn(period_1); LED_D_OFF(); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(delay_off); } @@ -1328,7 +1340,7 @@ void TurnReadLFOn(uint32_t delay) { WaitUS(delay); } void TurnReadLF_off(uint32_t delay) { - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(delay); } @@ -1338,7 +1350,7 @@ void T55xxWriteBit(int bit) { TurnReadLFOn(t_config.write_0); else TurnReadLFOn(t_config.write_1); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.write_gap); } @@ -1356,7 +1368,7 @@ void T55xxResetRead(void) { WaitMS(4); // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); // reset tag - op code 00 @@ -1390,7 +1402,7 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) // make sure tag is fully powered up... WaitMS(4); // Trigger T55x7 in mode. - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); if (testMode) Dbprintf("TestMODE"); @@ -1475,7 +1487,7 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { // make sure tag is fully powered up... WaitMS(4); // Trigger T55x7 Direct Access Mode with start gap - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); // Opcode 1[page] @@ -1522,7 +1534,7 @@ void T55xxWakeUp(uint32_t Pwd){ WaitMS(4); // Trigger T55x7 Direct Access Mode - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(t_config.start_gap); // Opcode 10 @@ -1962,7 +1974,7 @@ This triggers a COTAG tag to response */ void Cotag(uint32_t arg0) { #ifndef OFF -# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF_LF); WaitUS(2035); } +# define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } #endif #ifndef ON # define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c index 71a26ddd3..743d2db9c 100644 --- a/client/cmdlft55xx.c +++ b/client/cmdlft55xx.c @@ -189,7 +189,7 @@ int usage_t55xx_recoverpw(){ } int usage_lf_deviceconfig(){ PrintAndLogEx(NORMAL, "Sets t55x7 timings for direkt commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); - PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a b c d e "); + PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a b c d e p"); PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, " h - This help"); PrintAndLogEx(NORMAL, " a <8..255> - Set start gap"); @@ -197,9 +197,9 @@ int usage_lf_deviceconfig(){ PrintAndLogEx(NORMAL, " c <8..255> - Set write ZERO gap"); PrintAndLogEx(NORMAL, " d <8..255> - Set write ONE gap"); PrintAndLogEx(NORMAL, " e <8..255> - Set read gap"); + PrintAndLogEx(NORMAL, " p - persist to flashmemory"); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 31 - start gap 31*8"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 29 b 17 c 15 d 47 e 15 - default T55XX"); PrintAndLogEx(NORMAL, " lf t55xx deviceconfig a 55 b 14 c 21 d 30 - default EM4305"); PrintAndLogEx(NORMAL, ""); @@ -1903,7 +1903,7 @@ int CmdT55xxDetectPage1(const char *Cmd){ int CmdT55xxSetDeviceConfig(const char *Cmd){ uint8_t startgap = 0, writegap = 0; uint8_t write0 = 0, write1 = 0, readgap = 0; - bool errors = false; + bool errors = false, shall_persist = false; uint8_t cmdp = 0; while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch (tolower(param_getchar(Cmd, cmdp))) { @@ -1928,7 +1928,11 @@ int CmdT55xxSetDeviceConfig(const char *Cmd){ case 'e': errors |= param_getdec(Cmd, cmdp+1, &readgap); cmdp += 2; - break; + break; + case 'p': + shall_persist = true; + cmdp++; + break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = 1; @@ -1941,7 +1945,7 @@ int CmdT55xxSetDeviceConfig(const char *Cmd){ t55xx_config config = { startgap*8, writegap*8, write0*8, write1*8, readgap*8 }; - UsbCommand c = {CMD_SET_LF_T55XX_CONFIG, {0,0,0} }; + UsbCommand c = {CMD_SET_LF_T55XX_CONFIG, {shall_persist,0,0} }; memcpy(c.d.asBytes, &config, sizeof(t55xx_config)); clearCommandBuffer(); SendCommand(&c); diff --git a/client/util.c b/client/util.c index 4a256e0b2..6ed6201fa 100644 --- a/client/util.c +++ b/client/util.c @@ -110,8 +110,8 @@ void FillFileNameByUID(char *filenamePrefix, uint8_t *uid, const char *ext, int return; } - int len=0; - len=strlen(filenamePrefix); + int len = 0; + len = strlen(filenamePrefix); //memset(fn, 0x00, FILE_PATH_SIZE); for (int j = 0; j < uidlen; j++) diff --git a/common/i2c.c b/common/i2c.c index 159efcad2..262fd832a 100644 --- a/common/i2c.c +++ b/common/i2c.c @@ -88,11 +88,11 @@ void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { // Reset the SIM_Adapter, then enter the main program // Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter. void I2C_Reset_EnterMainProgram(void) { - I2C_SetResetStatus(0, 0, 0); // 拉低复位线 + I2C_SetResetStatus(0, 0, 0); SpinDelay(30); - I2C_SetResetStatus(1, 0, 0); // 解除复位 + I2C_SetResetStatus(1, 0, 0); SpinDelay(30); - I2C_SetResetStatus(1, 1, 1); // 拉高数据线 + I2C_SetResetStatus(1, 1, 1); SpinDelay(10); } @@ -100,9 +100,9 @@ void I2C_Reset_EnterMainProgram(void) { // Reset the SIM_Adapter, then enter the bootloader program // Reserve:For firmware update. void I2C_Reset_EnterBootloader(void) { - I2C_SetResetStatus(0, 1, 1); // 拉低复位线 + I2C_SetResetStatus(0, 1, 1); SpinDelay(100); - I2C_SetResetStatus(1, 1, 1); // 解除复位 + I2C_SetResetStatus(1, 1, 1); SpinDelay(10); } diff --git a/common/protocols.h b/common/protocols.h index 82cea74ad..0f3ef3407 100644 --- a/common/protocols.h +++ b/common/protocols.h @@ -304,6 +304,7 @@ ISO 7816-4 Basic interindustry commands. For command APDU's. #define ISO7816_GET_CHALLENGE 0xB4 #define ISO7816_MANAGE_CHANNEL 0x70 +#define ISO7816_GETSTATUS 0xC0 // ISO7816-4 For response APDU's #define ISO7816_OK 0x9000 // 6x xx = ERROR diff --git a/include/common.h b/include/common.h index 24e085699..90394448c 100644 --- a/include/common.h +++ b/include/common.h @@ -50,6 +50,13 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; #define RAMFUNC __attribute((long_call, section(".ramfunc"))) // RDV40 Section +// 256kb divided into 4k sectors. +// +// last 4k sector = signature +// second last 4k sector = settings +// third last 4k sector = default MF keys dictionary +// forth last 4k sector = default LF keys dictionary + #ifndef FLASH_MEM_BLOCK_SIZE # define FLASH_MEM_BLOCK_SIZE 256 #endif @@ -58,6 +65,11 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; # define FLASH_MEM_MAX_SIZE 0x3FFFF // (262143) #endif +#ifndef FLASH_MEM_MAX_4K_SECTOR +# define FLASH_MEM_MAX_4K_SECTOR 0x3F000 +#endif + + #ifndef FLASH_MEM_ID_LEN # define FLASH_MEM_ID_LEN 8 #endif @@ -71,13 +83,21 @@ extern uint32_t FLASHMEM_SPIBAUDRATE; #endif #if WITH_FLASH -#ifndef T55XX_CONFIG_LEN -# define T55XX_CONFIG_LEN sizeof( t55xx_config ) -#endif + #ifndef T55XX_CONFIG_LEN + # define T55XX_CONFIG_LEN sizeof( t55xx_config ) + #endif -#ifndef T55XX_CONFIG_OFFSET -#define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_SIZE - FLASH_MEM_SIGNATURE_LEN - T55XX_CONFIG_LEN) -#endif + #ifndef T55XX_CONFIG_OFFSET + # define T55XX_CONFIG_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x2000) + #endif + + #ifndef DEFAULT_MF_KEYS_OFFSET + # define DEFAULT_MF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x3000) + #endif + + #ifndef DEFAULT_LF_KEYS_OFFSET + # define DEFAULT_LF_KEYS_OFFSET (FLASH_MEM_MAX_4K_SECTOR - 0x4000) + #endif #endif // RDV40, validation structure to help identifying that client/firmware is talking with RDV40