chg: 't55' - adapting to codestyle, added some colors to message outputs, change comments

This commit is contained in:
iceman1001 2019-07-27 09:36:16 +02:00
commit a597382530
2 changed files with 178 additions and 141 deletions

View file

@ -107,7 +107,7 @@ void T55xxResetRead(uint8_t flags);
void T55xxWriteBlock(uint8_t *data); void T55xxWriteBlock(uint8_t *data);
// void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags); // void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags);
void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode); void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode);
void T55xxWakeUp(uint32_t Pwd, uint8_t flags); void T55xxWakeUp(uint32_t pwd, uint8_t flags);
void T55xx_ChkPwds(uint8_t flags); void T55xx_ChkPwds(uint8_t flags);
void TurnReadLFOn(uint32_t delay); void TurnReadLFOn(uint32_t delay);

View file

@ -20,15 +20,16 @@
#include "usb_cdc.h" // for usb_poll_validate_length #include "usb_cdc.h" // for usb_poll_validate_length
#include "common.h" #include "common.h"
#include "pmflash.h" #include "pmflash.h"
#include "flashmem.h" // persistence on mem #include "flashmem.h" // persistence on flash
/*
Notes about EM4xxx timings.
The timing values differs between cards, we got EM410x, EM43x5, EM445x etc.
We are trying to unify and enable the Proxmark to easily detect and select correct timings automatic.
The measures from datasheets doesn't always match correct the hardware features of RDV4 antenans and we still wanted to let other devices with other custom antennas
still benefit from this repo. This is why its configurable and we use to set these dynamic settings in device external flash memory.
//#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
//#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
//#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
//#define WRITE_1 47*8 // 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (56fc) 432 for T55x7; 448 for E5550
//#define READ_GAP 15*8
// VALUES TAKEN FROM EM4x function: SendForward // VALUES TAKEN FROM EM4x function: SendForward
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) // START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
@ -38,24 +39,34 @@
// These timings work for 4469/4269/4305 (with the 55*8 above) // These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 // WRITE_0 = 23*8 , 9*8
// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK) Not about ARM TIMERS
// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz Short note about timers on Proxmark device ARM. They are a bit differently implemented and gives decent correctness.
// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
// T0 = TIMER_CLOCK1 / 125000 = 192 SAM7S has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
// 1 Cycle = 8 microseconds(us) == 1 field clock TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
New timer implemenation in ticks.c, which is used in LFOPS.c
1us = 1.5ticks
1fc = 8us = 12ticks
Terms you find in different datasheets and how they match.
1 Cycle = 8 microseconds(us) == 1 field clock (fc)
Note about HITAG timing
Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
T0 = TIMER_CLOCK1 / 125000 = 192
// new timer:
// = 1us = 1.5ticks
// 1fc = 8us = 12ticks
/*
========================================================================================================== ==========================================================================================================
T55x7 Timing T55x7 Timing
========================================================================================================== ==========================================================================================================
// t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ;
ATA5577 Downlink Protocol Timings. ATA5577 Downlink Protocol Timings.
Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz) Note: All absolute times assume TC = 1 / fC = 8 μs (fC = 125 kHz)
Note: These timings are from the datasheet and doesn't map the best to the features of the RVD4 LF antenna.
RDV4 LF antenna has high voltage and the drop of power when turning off the rf field takes about 1-2 TC longer.
----------------------------------------------------------------------- -----------------------------------------------------------------------
Fixed-bit-length Protocol | Normal Downlink | Fast Downlink | Fixed-bit-length Protocol | Normal Downlink | Fast Downlink |
------------------------------+-----------------------------------+-----------------------------------+------ ------------------------------+-----------------------------------+-----------------------------------+------
@ -110,21 +121,23 @@
| |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc | | |10 data | d10 | dref + 25 | dref + 32 | dref + 40 | dref + 13 | dref + 16 | dref + 20 | Tc |
| |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc | | |11 data | d11 | dref + 41 | dref + 48 | dref + 56 | dref + 21 | dref + 24 | dref + 28 | Tc |
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
*/
// Initial values if not in flash Initial values if not in flash
/*
// Note: Moved * 8 to apply when used. Saving 28 bytes here (- the *8) and 28 bytes flash. SG = Start gap
// StartGap WriteGap Bit 0/00 Bit 1/01 Bit 10 Bit 11 ReadGap WG = Write gap
t55xx_config T55xx_Timing = {{ RG = Read gap
Explainations for array T55xx_Timing below
SG WG Bit 0/00 Bit 1/01 Bit 10 Bit 11 RG
--------------------------------------------------------------------
{ 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed { 29 , 17 , 15 , 47 , 0 , 0 , 15 }, // Default Fixed
{ 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref. { 31 , 20 , 18 , 50 , 0 , 0 , 15 }, // Long Leading Ref.
{ 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0 { 31 , 20 , 18 , 40 , 0 , 0 , 15 }, // Leading 0
{ 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4 { 29 , 17 , 15 , 31 , 47 , 63 , 15 } // 1 of 4
}
};
*/ */
// StartGap WriteGap Bit 0/00 Bit 1/01 ReadGap Bit 10 Bit 11 t55xx_config T55xx_Timing = {
t55xx_config T55xx_Timing = {{ {
{ 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8, 0, 0 }, // Default Fixed
{ 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref. { 31 * 8, 20 * 8, 18 * 8, 50 * 8, 15 * 8, 0, 0 }, // Long Leading Ref.
{ 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0 { 31 * 8, 20 * 8, 18 * 8, 40 * 8, 15 * 8, 0, 0 }, // Leading 0
@ -134,61 +147,68 @@ t55xx_config T55xx_Timing = {{
// Some defines for readability // Some defines for readability
#define T55xx_DLMode_Fixed 0 // Default Mode #define T55XX_DLMODE_FIXED 0 // Default Mode
#define T55xx_DLMode_LLR 1 // Long Leading Reference #define T55XX_DLMODE_LLR 1 // Long Leading Reference
#define T55xx_DLMode_Leading0 2 // Leading Zero #define T55XX_DLMODE_LEADING_ZERO 2 // Leading Zero
#define T55xx_DLMode_1of4 3 // 1 of 4 #define T55XX_DLMODE_1OF4 3 // 1 of 4
#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference #define T55XX_LONGLEADINGREFERENCE 4 // Value to tell Write Bit to send long reference
void printT55xxConfig(void) { void printT55xxConfig(void) {
int DLMode;
DbpString(_BLUE_("LF T55XX config")); DbpString(_BLUE_("LF T55XX config"));
for (DLMode = 0; DLMode < 4; DLMode++) { for (uint8_t i = 0; i < 4; i++) {
switch (DLMode) { switch (i) {
case T55xx_DLMode_Fixed : case T55XX_DLMODE_FIXED :
Dbprintf("r 0 fixed bit length (default)"); Dbprintf(_YELLOW_("fixed bit length (default)"));
break; break;
case T55xx_DLMode_LLR : case T55XX_DLMODE_LLR :
Dbprintf("r 1 long leading reference"); Dbprintf(_YELLOW_("long leading reference"));
break; break;
case T55xx_DLMode_Leading0 : case T55XX_DLMODE_LEADING_ZERO :
Dbprintf("r 2 leading zero"); Dbprintf(_YELLOW_("leading zero"));
break; break;
case T55xx_DLMode_1of4 : case T55XX_DLMODE_1OF4 :
Dbprintf("r 3 1 of 4 coding reference"); Dbprintf(_YELLOW_("1 of 4 coding reference"));
break; break;
} }
Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[DLMode].start_gap / 8, T55xx_Timing.m[DLMode].start_gap); Dbprintf(" [a] startgap............%d*8 (%d)", T55xx_Timing.m[i].start_gap / 8, T55xx_Timing.m[i].start_gap);
Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[DLMode].write_gap / 8, T55xx_Timing.m[DLMode].write_gap); Dbprintf(" [b] writegap............%d*8 (%d)", T55xx_Timing.m[i].write_gap / 8, T55xx_Timing.m[i].write_gap);
Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_0 / 8, T55xx_Timing.m[DLMode].write_0); Dbprintf(" [c] write_0.............%d*8 (%d)", T55xx_Timing.m[i].write_0 / 8, T55xx_Timing.m[i].write_0);
Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_1 / 8, T55xx_Timing.m[DLMode].write_1); Dbprintf(" [d] write_1.............%d*8 (%d)", T55xx_Timing.m[i].write_1 / 8, T55xx_Timing.m[i].write_1);
Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[DLMode].read_gap / 8, T55xx_Timing.m[DLMode].read_gap); Dbprintf(" [e] readgap.............%d*8 (%d)", T55xx_Timing.m[i].read_gap / 8, T55xx_Timing.m[i].read_gap);
if (DLMode == T55xx_DLMode_1of4) { if (i == T55XX_DLMODE_1OF4) {
Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_2 / 8, T55xx_Timing.m[DLMode].write_2); Dbprintf(" [f] write_2.............%d*8 (%d)", T55xx_Timing.m[i].write_2 / 8, T55xx_Timing.m[i].write_2);
Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[DLMode].write_3 / 8, T55xx_Timing.m[DLMode].write_3); Dbprintf(" [g] write_3.............%d*8 (%d)", T55xx_Timing.m[i].write_3 / 8, T55xx_Timing.m[i].write_3);
} }
} }
} }
void setT55xxConfig(uint8_t arg0, t55xx_config *c) { void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
uint8_t DLMode; for (uint8_t i = 0; i < 4; i++) {
// uint8_t ClearT55Settings = c->m[0].start_gap & 0xffff; // all values will be ffff if clear requested if (c->m[i].start_gap != 0)
T55xx_Timing.m[i].start_gap = c->m[i].start_gap;
if (c->m[i].write_gap != 0)
T55xx_Timing.m[i].write_gap = c->m[i].write_gap;
if (c->m[i].write_0 != 0)
T55xx_Timing.m[i].write_0 = c->m[i].write_0;
if (c->m[i].write_1 != 0)
T55xx_Timing.m[i].write_1 = c->m[i].write_1;
if (i == T55XX_DLMODE_1OF4) {
if (c->m[i].write_2 != 0)
T55xx_Timing.m[i].write_2 = c->m[i].write_2;
if (c->m[i].write_3 != 0)
T55xx_Timing.m[i].write_3 = c->m[i].write_3;
for (DLMode = 0; DLMode < 4; DLMode++) {
if (c->m[DLMode].start_gap != 0) T55xx_Timing.m[DLMode].start_gap = c->m[DLMode].start_gap;// * 8;
if (c->m[DLMode].write_gap != 0) T55xx_Timing.m[DLMode].write_gap = c->m[DLMode].write_gap;// * 8;
if (c->m[DLMode].write_0 != 0) T55xx_Timing.m[DLMode].write_0 = c->m[DLMode].write_0 ;// * 8;
if (c->m[DLMode].write_1 != 0) T55xx_Timing.m[DLMode].write_1 = c->m[DLMode].write_1 ;// * 8;
if (DLMode == T55xx_DLMode_1of4) {
if (c->m[DLMode].write_2 != 0) T55xx_Timing.m[DLMode].write_2 = c->m[DLMode].write_2;// * 8;
if (c->m[DLMode].write_3 != 0) T55xx_Timing.m[DLMode].write_3 = c->m[DLMode].write_3;// * 8 ;
} else { } else {
T55xx_Timing.m[DLMode].write_2 = 0x00; T55xx_Timing.m[i].write_2 = 0x00;
T55xx_Timing.m[DLMode].write_3 = 0x00; T55xx_Timing.m[i].write_3 = 0x00;
} }
if (c->m[DLMode].read_gap != 0) T55xx_Timing.m[DLMode].read_gap = c->m[DLMode].read_gap;//* 8; if (c->m[i].read_gap != 0)
T55xx_Timing.m[i].read_gap = c->m[i].read_gap;
} }
printT55xxConfig(); printT55xxConfig();
@ -203,7 +223,6 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
return; return;
} }
uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN); uint8_t *buf = BigBuf_malloc(T55XX_CONFIG_LEN);
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); uint16_t res = Flash_ReadDataCont(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
@ -215,14 +234,16 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN); memcpy(buf, &T55xx_Timing, T55XX_CONFIG_LEN);
// delete old configuration
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
Flash_Erase4k(3, 0xD); Flash_Erase4k(3, 0xD);
// write new
res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN); res = Flash_Write(T55XX_CONFIG_OFFSET, buf, T55XX_CONFIG_LEN);
if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) { if (res == T55XX_CONFIG_LEN && DBGLEVEL > 1) {
DbpString("T55XX Config save success"); DbpString("T55XX Config save " _GREEN_("success") );
} }
BigBuf_free(); BigBuf_free();
@ -1478,37 +1499,35 @@ void TurnReadLF_off(uint32_t delay) {
} }
// Macro for code readability // Macro for code readability
#define BitStream_Byte(X) ((X) >> 3) #define BITSTREAM_BYTE(x) ((x) >> 3) // iceman note: isn't this NIBBLE???
#define BitStream_Bit(X) ((X) & 7) #define BITSTREAM_BIT(x) ((x) & 7)
#define t55_llr_ref (136 * 8)
#define t55_send_PwdMode (arg & 0x01) #define T55_LLR_REF (136 * 8)
#define t55_send_Page ((arg & 0x02) >> 1)
#define t55_send_TestMode ((arg & 0x04) >> 2)
#define t55_send_RegReadMode ((arg & 0x20) >> 5)
#define t55_send_ReadCmd ((arg & 0x40) >> 6)
#define t55_send_Reset ((arg & 0x80) >> 7)
// Write one bit to chip // Write one bit to chip
void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) { void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// Dbprintf ("%d",bit);
// If bit = 4 Send Long Leading Reference which is (138*8) + WRITE_0
switch (bit) { switch (bit) {
case 0 : case 0 :
// send bit 0/00
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0);
break; // Send bit 0/00 break;
case 1 : case 1 :
// send bit 1/01
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_1);
break; // Send bit 1/01 break;
case 2 : case 2 :
// send bits 10 (1 of 4)
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_2);
break; // Send bits 10 (1 of 4) break;
case 3 : case 3 :
// send bits 11 (1 of 4)
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3); TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_3);
break; // Send bits 11 (1 of 4) break;
case 4 : case 4 :
TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + t55_llr_ref); // send Long Leading Reference
break; // Send Long Leading Reference TurnReadLFOn(T55xx_Timing.m[downlink_idx].write_0 + T55_LLR_REF);
break;
} }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1522,31 +1541,32 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
// num_bits - how many bits (low x bits of data) Max 32 bits at a time // num_bits - how many bits (low x bits of data) Max 32 bits at a time
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow) // max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
// returns "Next" bit offset / bits stored (for next store) // returns "Next" bit offset / bits stored (for next store)
uint8_t T55xx_SetBits(uint8_t *BitStream, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) { uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) {
int8_t offset; int8_t offset;
int8_t NextOffset = start_offset; int8_t next_offset = start_offset;
// Check if data will fit. // Check if data will fit.
if ((start_offset + num_bits) <= (max_len * 8)) { if ((start_offset + num_bits) <= (max_len * 8)) {
// Loop through the data and store // Loop through the data and store
for (offset = (num_bits - 1); offset >= 0; offset--) { for (offset = (num_bits - 1); offset >= 0; offset--) {
if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1 if ((data >> offset) & 1)
else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0 bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1
else
bs[BITSTREAM_BYTE(next_offset)] &= (0xff ^ (1 << BITSTREAM_BIT(next_offset))); // Set 0
NextOffset++; next_offset++;
} }
} else { } else {
// Note: This should never happen unless some code changes cause it. // Note: This should never happen unless some code changes cause it.
// So short message for coders when testing. // So short message for coders when testing.
Dbprintf("T55 too many bits"); Dbprintf(_RED_("T55 too many bits"));
} }
return NextOffset; return next_offset;
} }
// Send one downlink command to the card // Send one downlink command to the card
// void T55xx_SendCMD (uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) {
void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) {
/* /*
arg bits arg bits
@ -1560,56 +1580,72 @@ void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) {
xxx1 xxxxxxxx 0x100 brute force xxx1 xxxxxxxx 0x100 brute force
111x xxxxxxxx 0xE00 Block 111x xxxxxxxx 0xE00 Block
*/ */
bool t55_send_pwdmode = (arg & 0x1);
bool t55_send_page = ((arg >> 1) & 0x1);
bool t55_send_testmode = ((arg >> 2) & 0x1);
bool t55_send_regreadmode = ((arg >> 5) & 0x1);
bool t55_send_readcmd = ((arg >> 6) & 0x1);
bool t55_send_reset = ((arg >> 7) & 0x1);
// Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
uint8_t bs[10];
uint8_t i = 0, len = 0;
uint8_t downlink_mode = (arg >> 3) & 0x03; uint8_t downlink_mode = (arg >> 3) & 0x03;
uint8_t i = 0; uint8_t block = (arg >> 9) & 0x07;
uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
uint8_t BitStreamLen = 0;
uint8_t SendBits;
uint8_t start_wait = 4;
bool brute_mem = (arg & 0x100);
uint8_t Block = (arg >> 9) & 0x07;
if (brute_mem) start_wait = 0; bool brute_mem = (arg & 0x100);
// Build Bit Stream to send. // no startup delay when in bruteforce command
memset(BitStream, 0x00, sizeof(BitStream)); uint8_t start_wait = (brute_mem) ? 0 : 4;
BitStreamLen = 0; // Ensure 0 bit index to start. memset(bs, 0x00, sizeof(bs));
// Add Leading 0 and 1 of 4 reference bit // build bit stream to send.
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4))
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream));
// Add extra reference 0 for 1 of 4 // add Leading 0
if (downlink_mode == T55xx_DLMode_1of4) if (downlink_mode == T55XX_DLMODE_LEADING_ZERO)
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
// Add Opcode // add 1 of 4 reference bit
if (t55_send_Reset) { if (downlink_mode == T55XX_DLMODE_1OF4) {
// Reset : r*) 00 len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); // add extra zero
len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
}
// add Opcode
if (t55_send_reset) {
// reset : r*) 00
len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs));
} else { } else {
if (t55_send_TestMode) Dbprintf("TestMODE");
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 0 : 1, 1, sizeof(BitStream)); if (t55_send_testmode)
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, t55_send_TestMode ? 1 : t55_send_Page, 1, sizeof(BitStream)); Dbprintf(_YELLOW_("Using Test Mode"));
//if (PwdMode) {
if (t55_send_PwdMode) { len = T55xx_SetBits(bs, len, t55_send_testmode ? 0 : 1, 1, sizeof(bs));
len = T55xx_SetBits(bs, len, t55_send_testmode ? 1 : t55_send_page, 1, sizeof(bs));
if (t55_send_pwdmode) {
// Leading 0 and 1 of 4 00 fixed bits if passsword used // Leading 0 and 1 of 4 00 fixed bits if passsword used
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) { if ((downlink_mode == T55XX_DLMODE_LEADING_ZERO) || (downlink_mode == T55XX_DLMODE_1OF4)) {
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 2, sizeof(BitStream)); len = T55xx_SetBits(bs, len, 0, 2, sizeof(bs));
} }
BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Pwd, 32, sizeof(BitStream)); len = T55xx_SetBits(bs, len, pwd, 32, sizeof(bs));
} }
// Add Lock bit 0 // Add Lock bit 0
if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, 0, 1, sizeof(BitStream)); if (t55_send_regreadmode == false)
len = T55xx_SetBits(bs, len, 0, 1, sizeof(bs));
// Add Data if a write command // Add Data if a write command
if (!t55_send_ReadCmd) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Data, 32, sizeof(BitStream)); if (t55_send_readcmd == false)
len = T55xx_SetBits(bs, len, data, 32, sizeof(bs));
// Add Address // Add Address
if (!t55_send_RegReadMode) BitStreamLen = T55xx_SetBits(BitStream, BitStreamLen, Block, 3, sizeof(BitStream)); if (t55_send_regreadmode == false)
len = T55xx_SetBits(bs, len, block, 3, sizeof(bs));
} }
// Send Bits to T55xx // Send Bits to T55xx
@ -1624,19 +1660,20 @@ void T55xx_SendCMD(uint32_t Data, uint32_t Pwd, uint16_t arg) {
WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8); WaitUS(T55xx_Timing.m[downlink_mode].start_gap * 8);
// If long leading 0 send long reference pulse // If long leading 0 send long reference pulse
if (downlink_mode == T55xx_DLMode_LLR) if (downlink_mode == T55XX_DLMODE_LLR)
T55xxWriteBit(T55xx_LongLeadingReference, downlink_mode);//Timing); // Send Long Leading Start Reference T55xxWriteBit(T55XX_LONGLEADINGREFERENCE, downlink_mode);//Timing); // Send Long Leading Start Reference
if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time uint8_t sendbits;
for (i = 0; i < BitStreamLen - 1; i += 2) { if ((downlink_mode == T55XX_DLMODE_1OF4) && (len > 0)) { // 1 of 4 need to send 2 bits at a time
SendBits = (BitStream[BitStream_Byte(i)] >> (BitStream_Bit(i)) & 1) << 1; // Bit i for (i = 0; i < len - 1; i += 2) {
SendBits += (BitStream[BitStream_Byte(i + 1)] >> (BitStream_Bit(i + 1)) & 1); // Bit i+1; sendbits = (bs[BITSTREAM_BYTE(i)] >> (BITSTREAM_BIT(i)) & 1) << 1; // Bit i
T55xxWriteBit(SendBits & 3, downlink_mode);//Timing); sendbits += (bs[BITSTREAM_BYTE(i + 1)] >> (BITSTREAM_BIT(i + 1)) & 1); // Bit i+1;
T55xxWriteBit(sendbits & 3, downlink_mode);
} }
} else { } else {
for (i = 0; i < BitStreamLen; i++) { for (i = 0; i < len; i++) {
SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i)); sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i));
T55xxWriteBit(SendBits & 1, downlink_mode);//Timing); T55xxWriteBit(sendbits & 1, downlink_mode);
} }
} }
} }
@ -1941,12 +1978,12 @@ OUT:
LEDsoff(); LEDsoff();
} }
void T55xxWakeUp(uint32_t Pwd, uint8_t flags) { void T55xxWakeUp(uint32_t pwd, uint8_t flags) {
flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block flags |= 0x01 | 0x40 | 0x20; //Password | Read Call (no data) | reg_read no block
LED_B_ON(); LED_B_ON();
T55xx_SendCMD(0, Pwd, flags); T55xx_SendCMD(0, pwd, flags);
//-- Turn and leave field on to let the begin repeating transmission //-- Turn and leave field on to let the begin repeating transmission
TurnReadLFOn(20 * 1000); TurnReadLFOn(20 * 1000);