+// Send one downlink command to the card
+void T55xx_SendCMD (uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+
+ /*
+ arg bits
+ xxxxxxx1 0x01 PwdMode
+ xxxxxx1x 0x02 Page
+ xxxxx1xx 0x04 testMode
+ xxx11xxx 0x18 downlink mode
+ xx1xxxxx 0x20 !reg_readmode
+ x1xxxxxx 0x40 called for a read, so no data packet
+ 1xxxxxxx 0x80 reset
+
+ */
+ bool PwdMode = ((arg & 0x01) == 0x01);
+ bool Page = (arg & 0x02);
+ bool testMode = ((arg & 0x04) == 0x04);
+ uint8_t downlink_mode = (arg >> 3) & 0x03;
+ bool reg_readmode = ((arg & 0x20) == 0x20);
+ bool read_cmd = ((arg & 0x40) == 0x40);
+ bool reset = (arg & 0x80);
+
+ uint8_t i = 0;
+ uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
+ uint8_t BitStreamLen;
+ T55xx_Timing *Timing;
+ uint8_t SendBits;
+
+ // Assigning Downlink Timeing for write
+ switch (downlink_mode)
+ {
+ case T55xx_DLMode_Fixed : Timing = &T55xx_Timing_FixedBit; break;
+ case T55xx_DLMode_LLR : Timing = &T55xx_Timing_LLR; break;
+ case T55xx_DLMode_Leading0 : Timing = &T55xx_Timing_Leading0; break;
+ case T55xx_DLMode_1of4 : Timing = &T55xx_Timing_1of4; break;
+ default:
+ Timing = &T55xx_Timing_FixedBit;
+ }
+
+ // Build Bit Stream to send.
+ memset (BitStream,0x00,sizeof(BitStream));
+
+ BitStreamLen = 0; // Ensure 0 bit index to start.
+
+ // Add Leading 0 and 1 of 4 reference bit
+ 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
+ if (downlink_mode == T55xx_DLMode_1of4)
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
+
+ // Add Opcode
+ if (reset) {
+ // Reset : r*) 00
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
+ }
+ else
+ {
+ if (testMode) Dbprintf("TestMODE");
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 0 : 1 , 1,sizeof(BitStream));
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 1 : Page , 1,sizeof(BitStream));
+
+ if (PwdMode) {
+ // Leading 0 and 1 of 4 00 fixed bits if passsword used
+ if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) {
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
+ }
+ BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Pwd, 32,sizeof(BitStream));
+ }
+
+ // Add Lock bit 0
+ if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
+
+ // Add Data if a write command
+ if (!read_cmd) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Data, 32,sizeof(BitStream));
+
+ // Add Address
+ if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Block, 3,sizeof(BitStream));
+ }
+
+ // Send Bits to T55xx