Merge pull request #2593 from Akury83/master
[RRG-proxmark3.git] / armsrc / hfops.c
blobdf42c8685fedd646ae7715bcabd87331db05bbd3
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 // HF general operations
17 //-----------------------------------------------------------------------------
19 #include "hfops.h"
21 #include <string.h>
22 #include "appmain.h"
23 #include "proxmark3_arm.h"
24 #include "cmd.h"
25 #include "BigBuf.h"
26 #include "fpgaloader.h"
27 #include "ticks.h"
28 #include "dbprint.h"
29 #include "util.h"
30 #include "commonutil.h"
31 #include "lfsampling.h"
33 int HfReadADC(uint32_t samplesCount, bool ledcontrol) {
34 if (ledcontrol) LEDsoff();
36 BigBuf_Clear_ext(false);
37 // connect Demodulated Signal to ADC:
38 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
40 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
41 // And put the FPGA in the appropriate mode
42 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_212_KHZ | FPGA_HF_READER_MODE_RECEIVE_AMPLITUDE);
44 // Setup
45 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
47 if (ledcontrol) LED_A_ON();
49 uint32_t sbs = samplesCount;
50 initSampleBuffer(&sbs);
52 uint32_t wdtcntr = 0;
53 for (;;) {
54 if (BUTTON_PRESS()) {
55 break;
58 if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
59 volatile uint16_t sample = AT91C_BASE_SSC->SSC_RHR;
61 // FPGA side:
62 // corr_i_out <= {2'b00, corr_amplitude[13:8]};
63 // corr_q_out <= corr_amplitude[7:0];
64 if (sample > 0x1fff)
65 sample = 0xff;
66 else
67 sample = sample >> 5;
68 logSample(sample & 0xff, 1, 8, false);
69 if (getSampleCounter() >= samplesCount)
70 break;
72 if (wdtcntr++ > 512) {
73 WDT_HIT();
74 wdtcntr = 0;
76 } else {
77 continue;
81 FpgaDisableTracing();
83 FpgaSetupSsc(FPGA_MAJOR_MODE_OFF);
84 // Turn the field off
85 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
87 uint32_t scnt = getSampleCounter();
88 reply_ng(CMD_HF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&scnt, 4);
89 if (ledcontrol) LEDsoff();
91 return 0;
94 uint8_t encode_acc = 0;
95 uint8_t encode_acc_bit_count = 0;
96 uint32_t encode_indx = 0;
98 static void EncodeInit(void) {
99 encode_acc = 0;
100 encode_acc_bit_count = 0;
101 encode_indx = 0;
104 static void EncodeAddBit(uint8_t *data, uint8_t bit, uint8_t bit_count) {
105 for (int i = 0; i < bit_count; i++) {
106 encode_acc = (encode_acc << 1) | (bit & 0x01);
107 encode_acc_bit_count++;
108 if (encode_acc_bit_count > 7) {
109 data[encode_indx++] = encode_acc;
110 encode_acc = 0;
111 encode_acc_bit_count = 0;
116 static uint32_t EncodeFinish(uint8_t *data) {
117 if (encode_acc_bit_count > 0) {
118 encode_acc = encode_acc << (8 - encode_acc_bit_count);
119 data[encode_indx++] = encode_acc;
122 return encode_indx;
125 static uint32_t HfEncodeTkm(const uint8_t *uid, uint8_t modulation, uint8_t *data) {
126 uint32_t len = 0;
127 if (modulation == 0) {
128 // TK-13
129 // 74ns 1 field cycle,
130 // carrier frequency is fc/64 (212kHz), 4.7 mks
131 // 100 field cycle = impulse 1.6 ( 1 bit from real tag)
132 // 1000 field cycle = `1` 15.6 (17 bit from real tag)
133 // 500 field cycle = `0` 7.8 ( 7 bit from real tag)
135 EncodeInit();
136 for (int i = 0; i < 8; i++) {
137 for (int j = 0; j < 8; j++) {
138 if (((uid[i] << j) & 0x80) != 0) {
139 // `1`
140 EncodeAddBit(data, 1, 1);
141 EncodeAddBit(data, 0, 17);
142 EncodeAddBit(data, 1, 1);
143 EncodeAddBit(data, 0, 7);
144 } else {
145 // `0`
146 EncodeAddBit(data, 1, 1);
147 EncodeAddBit(data, 0, 7);
148 EncodeAddBit(data, 1, 1);
149 EncodeAddBit(data, 0, 17);
153 len = EncodeFinish(data);
154 } else {
155 // TK-17
156 // 74ns 1 field cycle,
157 // carrier frequency is fc/64 (212kHz), 4.7 mks
158 // 0 --- 8 --- 12-15 --- 18-19 --- 26-28 --- 32
159 // DO NOT NORMALIZE!!!! it must be with some error like this!!!!
160 // `00` -- 1-25-1-5
161 // `01` -- 1-12-1-18
162 // `10` -- 1-17-1-13
163 // `11` -- 1-7-1-23
165 EncodeInit();
166 for (int i = 0; i < 8; i++) {
167 for (int j = 0; j < 8; j += 2) {
168 uint8_t twobit = ((uid[i] >> j) & 0x03);
169 if (twobit == 0x00) {
170 // `00`
171 EncodeAddBit(data, 1, 1);
172 EncodeAddBit(data, 0, 25);
173 EncodeAddBit(data, 1, 1);
174 EncodeAddBit(data, 0, 5);
175 } else if (twobit == 0x01) {
176 // `01`
177 EncodeAddBit(data, 1, 1);
178 EncodeAddBit(data, 0, 12);
179 EncodeAddBit(data, 1, 1);
180 EncodeAddBit(data, 0, 18);
181 } else if (twobit == 0x02) {
182 // `10`
183 EncodeAddBit(data, 1, 1);
184 EncodeAddBit(data, 0, 17);
185 EncodeAddBit(data, 1, 1);
186 EncodeAddBit(data, 0, 13);
187 } else { // twobit == 0x03
188 // `11`
189 EncodeAddBit(data, 1, 1);
190 EncodeAddBit(data, 0, 7);
191 EncodeAddBit(data, 1, 1);
192 EncodeAddBit(data, 0, 23);
196 EncodeAddBit(data, 1, 1);
197 len = EncodeFinish(data);
200 return len;
203 int HfSimulateTkm(const uint8_t *uid, uint8_t modulation, uint32_t timeout) {
204 // free eventually allocated BigBuf memory
205 BigBuf_free_keep_EM();
207 LEDsoff();
209 uint8_t *data = BigBuf_calloc(256);
210 uint32_t elen = HfEncodeTkm(uid, modulation, data);
211 if (elen == 0) {
212 DbpString("encode error");
213 reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_EAPDU_ENCODEFAIL, NULL, 0);
214 return PM3_EAPDU_ENCODEFAIL;
217 LED_C_ON();
218 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
219 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
220 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_212K);
221 FpgaSetupSsc(FPGA_MAJOR_MODE_HF_SIMULATOR);
223 bool button_pressed = false;
224 bool exit_loop = false;
225 bool field_on = false;
227 uint32_t startTime = GetTickCount();
228 while (exit_loop == false) {
230 button_pressed = BUTTON_PRESS();
231 if (button_pressed || data_available()) {
232 break;
235 WDT_HIT();
237 if (timeout > 0 && startTime + timeout < GetTickCount())
238 break;
240 // in mV
241 int vHf = (MAX_ADC_HF_VOLTAGE * SumAdc(ADC_CHAN_HF, 32)) >> 15;
242 if (vHf > MF_MINFIELDV) {
243 if (field_on == false) {
244 LED_A_ON();
245 SpinDelay(50);
247 field_on = true;
248 } else {
249 if (field_on) {
250 LED_A_OFF();
252 field_on = false;
253 continue;
256 SpinDelay(3);
258 for (int i = 0; i < elen;) {
259 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
260 AT91C_BASE_SSC->SSC_THR = data[i++];
265 switch_off();
267 if (button_pressed)
268 DbpString("Exit by press button");
270 reply_ng(CMD_HF_TEXKOM_SIMULATE, PM3_SUCCESS, NULL, 0);
272 return PM3_SUCCESS;