MIFARE Plus 4b UID: fix signature check
[RRG-proxmark3.git] / armsrc / lfzx.c
blobf95b2c2b7c7eba5a4020afea41ff6f2b0d80eedb
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Low frequency ZX8211 funtions
17 //-----------------------------------------------------------------------------
18 #include "lfzx.h"
19 #include "zx8211.h"
21 #include "BigBuf.h"
22 #include "crc.h" // CRC-8 / Hitag1 / ZX8211
23 #include "fpgaloader.h"
24 #include "dbprint.h"
25 #include "lfops.h" // turn_read_lf_on / off
26 #include "lfadc.h"
27 #include "lfsampling.h" // getSamplingConfig
28 #include "pm3_cmd.h" // struct
29 #include "ticks.h"
32 ZX8211
34 RWE to tag
35 ----------
36 ASK w 100% modulation index
37 When power field is:
38 off, its considered LOW field
39 on, its considered HIGH field
42 Binary Pulse Length Coding (BPLC)
44 ZERO = 8 off, 8 on (14-22)
45 ONE = 8 off, 28 on (26-32)
46 EOF = 8 off, 30 on (38 or more)
48 Protection
49 ----------
50 32bit read password
51 32bit write password
53 Config bits
54 -------------
56 Timings
57 -------
59 Tx = 8us = 1fc
62 #define ZX_START_GAP 170
63 #define ZX_WAIT_GAP 90
64 #define ZX_GAP 8 // 4 - 10
65 #define ZX_T0 18
66 #define ZX_T0_MIN 14
67 #define ZX_T0_MAX 22
68 #define ZX_T1 28
69 #define ZX_T1_MIN 26
70 #define ZX_T1_MAX 32
71 #define ZX_TEOF 38
72 #define ZX_RESET_GAP 35000 // 35ms
73 #define ZX_RESPONSE_GAP 208
75 #define ZX_PROG 716
76 #define ZX_PROG_CT 4470
78 // TTF switch to RTF
79 #define ZX_SWITCH_RTF 350
81 // ZX commands
82 #define LF_ZX_GET_UID 0b00110
83 #define LF_ZX_READ
84 #define LF_ZX_WRITE
87 static void zx8211_setup_read(void) {
89 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
91 // Make sure the tag is reset
92 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
94 // use lf config settings
95 sample_config *sc = getSamplingConfig();
96 LFSetupFPGAForADC(sc->divisor, true);
98 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
100 // 50ms for the resonant antenna to settle.
101 WaitMS(50);
103 // Now set up the SSC to get the ADC samples that are now streaming at us.
104 FpgaSetupSsc(FPGA_MAJOR_MODE_LF_READER);
106 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125);
108 // Connect the A/D to the peak-detected low-frequency path.
109 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
111 // Start the timer
112 StartTicks();
114 // Watchdog hit
115 WDT_HIT();
118 static void zx_send(const uint8_t *cmd, uint8_t clen) {
120 if (clen == 0)
121 return;
123 turn_read_lf_on(ZX_START_GAP);
125 // now start writing with bitbanging the antenna.
126 while (clen-- > 0) {
128 turn_read_lf_off(ZX_GAP * 8);
130 if (((*cmd++) & 1) == 1) {
131 turn_read_lf_on(ZX_T1 * 8);
132 } else {
133 turn_read_lf_on(ZX_T0 * 8);
137 // send eof
138 turn_read_lf_off(ZX_GAP * 8);
139 turn_read_lf_on(ZX_TEOF * 8);
142 static void zx_get(bool ledcontrol) {
144 while (BUTTON_PRESS() == false) {
146 WDT_HIT();
148 if (ledcontrol && (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY)) {
149 LED_D_ON();
152 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
153 volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
154 (void)sample;
156 // (RDV4) Test point 8 (TP8) can be used to trigger oscilloscope
157 if (ledcontrol) LED_D_OFF();
163 int zx8211_read(zx8211_data_t *zxd, bool ledcontrol) {
164 zx8211_setup_read();
166 // clear buffer now so it does not interfere with timing later
167 BigBuf_Clear_ext(false);
169 if (ledcontrol) LED_A_ON();
171 // send GET_UID
172 zx_send(NULL, 0);
174 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
176 zx_get(ledcontrol);
178 //uint32_t cs = CRC8Hitag1(uint8_t *buff, size_t size);
180 if (ledcontrol) LEDsoff();
182 StopTicks();
183 lf_finalize(ledcontrol);
185 reply_ng(CMD_LF_ZX_READ, PM3_SUCCESS, NULL, 0);
186 return PM3_SUCCESS;
189 int zx8211_write(zx8211_data_t *zxd, bool ledcontrol) {
190 zx8211_setup_read();
192 StopTicks();
193 lf_finalize(ledcontrol);
194 //reply_ng(CMD_LF_ZX_WRITE, status, tag.data, sizeof(tag.data));
195 return PM3_SUCCESS;