Browse Source

almost read command

develop
Robin Thoni 7 years ago
parent
commit
e7019e0aa6
3 changed files with 724 additions and 17 deletions
  1. 476
    0
      SoftwareSerial8e1.cpp
  2. 98
    0
      SoftwareSerial8e1.h
  3. 150
    17
      main.ino

+ 476
- 0
SoftwareSerial8e1.cpp View File

@@ -0,0 +1,476 @@
1
+//
2
+// Created by robin on 2/24/17.
3
+//
4
+
5
+// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
6
+// oscilloscope or logic analyzer.  Beware: it also slightly modifies
7
+// the bit times, so don't rely on it too much at high baud rates
8
+#define _DEBUG 0
9
+#define _DEBUG_PIN1 11
10
+#define _DEBUG_PIN2 13
11
+//
12
+// Includes
13
+//
14
+#include <avr/interrupt.h>
15
+#include <avr/pgmspace.h>
16
+#include <Arduino.h>
17
+#include "SoftwareSerial8e1.h"
18
+#include <util/delay_basic.h>
19
+
20
+//
21
+// Statics
22
+//
23
+SoftwareSerial8e1 *SoftwareSerial8e1::active_object = 0;
24
+uint8_t SoftwareSerial8e1::_receive_buffer[_SS_MAX_RX_BUFF];
25
+volatile uint8_t SoftwareSerial8e1::_receive_buffer_tail = 0;
26
+volatile uint8_t SoftwareSerial8e1::_receive_buffer_head = 0;
27
+
28
+//
29
+// Debugging
30
+//
31
+// This function generates a brief pulse
32
+// for debugging or measuring on an oscilloscope.
33
+#if _DEBUG
34
+inline void DebugPulse(uint8_t pin, uint8_t count)
35
+{
36
+  volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
37
+
38
+  uint8_t val = *pport;
39
+  while (count--)
40
+  {
41
+    *pport = val | digitalPinToBitMask(pin);
42
+    *pport = val;
43
+  }
44
+}
45
+#else
46
+inline void DebugPulse(uint8_t, uint8_t) {}
47
+#endif
48
+
49
+//
50
+// Private methods
51
+//
52
+
53
+/* static */
54
+inline void SoftwareSerial8e1::tunedDelay(uint16_t delay) {
55
+    _delay_loop_2(delay);
56
+}
57
+
58
+// This function sets the current object as the "listening"
59
+// one and returns true if it replaces another
60
+bool SoftwareSerial8e1::listen()
61
+{
62
+    if (!_rx_delay_stopbit)
63
+        return false;
64
+
65
+    if (active_object != this)
66
+    {
67
+        if (active_object)
68
+            active_object->stopListening();
69
+
70
+        _buffer_overflow = false;
71
+        _receive_buffer_head = _receive_buffer_tail = 0;
72
+        active_object = this;
73
+
74
+        setRxIntMsk(true);
75
+        return true;
76
+    }
77
+
78
+    return false;
79
+}
80
+
81
+// Stop listening. Returns true if we were actually listening.
82
+bool SoftwareSerial8e1::stopListening()
83
+{
84
+    if (active_object == this)
85
+    {
86
+        setRxIntMsk(false);
87
+        active_object = NULL;
88
+        return true;
89
+    }
90
+    return false;
91
+}
92
+
93
+//
94
+// The receive routine called by the interrupt handler
95
+//
96
+void SoftwareSerial8e1::recv()
97
+{
98
+
99
+#if GCC_VERSION < 40302
100
+// Work-around for avr-gcc 4.3.0 OSX version bug
101
+// Preserve the registers that the compiler misses
102
+// (courtesy of Arduino forum user *etracer*)
103
+    asm volatile(
104
+    "push r18 \n\t"
105
+            "push r19 \n\t"
106
+            "push r20 \n\t"
107
+            "push r21 \n\t"
108
+            "push r22 \n\t"
109
+            "push r23 \n\t"
110
+            "push r26 \n\t"
111
+            "push r27 \n\t"
112
+    ::);
113
+#endif
114
+
115
+    uint8_t d = 0;
116
+
117
+    // If RX line is high, then we don't see any start bit
118
+    // so interrupt is probably not for us
119
+    if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
120
+    {
121
+        // Disable further interrupts during reception, this prevents
122
+        // triggering another interrupt directly after we return, which can
123
+        // cause problems at higher baudrates.
124
+        setRxIntMsk(false);
125
+
126
+        // Wait approximately 1/2 of a bit width to "center" the sample
127
+        tunedDelay(_rx_delay_centering);
128
+        DebugPulse(_DEBUG_PIN2, 1);
129
+
130
+        // Read each of the 8 bits
131
+        for (uint8_t i=8; i > 0; --i)
132
+        {
133
+            tunedDelay(_rx_delay_intrabit);
134
+            d >>= 1;
135
+            DebugPulse(_DEBUG_PIN2, 1);
136
+            if (rx_pin_read())
137
+                d |= 0x80;
138
+        }
139
+
140
+        if (_inverse_logic)
141
+            d = ~d;
142
+
143
+        // if buffer full, set the overflow flag and return
144
+        uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
145
+        if (next != _receive_buffer_head)
146
+        {
147
+            // save new data in buffer: tail points to where byte goes
148
+            _receive_buffer[_receive_buffer_tail] = d; // save new byte
149
+            _receive_buffer_tail = next;
150
+        }
151
+        else
152
+        {
153
+            DebugPulse(_DEBUG_PIN1, 1);
154
+            _buffer_overflow = true;
155
+        }
156
+
157
+        // skip the parity bit
158
+        tunedDelay(_rx_delay_stopbit);
159
+        DebugPulse(_DEBUG_PIN1, 1);
160
+
161
+        // skip the stop bit
162
+        tunedDelay(_rx_delay_stopbit);
163
+        DebugPulse(_DEBUG_PIN1, 1);
164
+
165
+        // Re-enable interrupts when we're sure to be inside the stop bit
166
+        setRxIntMsk(true);
167
+
168
+    }
169
+
170
+#if GCC_VERSION < 40302
171
+// Work-around for avr-gcc 4.3.0 OSX version bug
172
+// Restore the registers that the compiler misses
173
+    asm volatile(
174
+    "pop r27 \n\t"
175
+            "pop r26 \n\t"
176
+            "pop r23 \n\t"
177
+            "pop r22 \n\t"
178
+            "pop r21 \n\t"
179
+            "pop r20 \n\t"
180
+            "pop r19 \n\t"
181
+            "pop r18 \n\t"
182
+    ::);
183
+#endif
184
+}
185
+
186
+uint8_t SoftwareSerial8e1::rx_pin_read()
187
+{
188
+    return *_receivePortRegister & _receiveBitMask;
189
+}
190
+
191
+//
192
+// Interrupt handling
193
+//
194
+
195
+/* static */
196
+inline void SoftwareSerial8e1::handle_interrupt()
197
+{
198
+    if (active_object)
199
+    {
200
+        active_object->recv();
201
+    }
202
+}
203
+
204
+#if defined(PCINT0_vect)
205
+ISR(PCINT0_vect)
206
+{
207
+  SoftwareSerial8e1::handle_interrupt();
208
+}
209
+#endif
210
+
211
+#if defined(PCINT1_vect)
212
+ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
213
+#endif
214
+
215
+#if defined(PCINT2_vect)
216
+ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
217
+#endif
218
+
219
+#if defined(PCINT3_vect)
220
+ISR(PCINT3_vect, ISR_ALIASOF(PCINT0_vect));
221
+#endif
222
+
223
+//
224
+// Constructor
225
+//
226
+SoftwareSerial8e1::SoftwareSerial8e1(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic /* = false */) :
227
+        _rx_delay_centering(0),
228
+        _rx_delay_intrabit(0),
229
+        _rx_delay_stopbit(0),
230
+        _tx_delay(0),
231
+        _buffer_overflow(false),
232
+        _inverse_logic(inverse_logic)
233
+{
234
+    setTX(transmitPin);
235
+    setRX(receivePin);
236
+}
237
+
238
+//
239
+// Destructor
240
+//
241
+SoftwareSerial8e1::~SoftwareSerial8e1()
242
+{
243
+    end();
244
+}
245
+
246
+void SoftwareSerial8e1::setTX(uint8_t tx)
247
+{
248
+    // First write, then set output. If we do this the other way around,
249
+    // the pin would be output low for a short while before switching to
250
+    // output high. Now, it is input with pullup for a short while, which
251
+    // is fine. With inverse logic, either order is fine.
252
+    digitalWrite(tx, _inverse_logic ? LOW : HIGH);
253
+    pinMode(tx, OUTPUT);
254
+    _transmitBitMask = digitalPinToBitMask(tx);
255
+    uint8_t port = digitalPinToPort(tx);
256
+    _transmitPortRegister = portOutputRegister(port);
257
+}
258
+
259
+void SoftwareSerial8e1::setRX(uint8_t rx)
260
+{
261
+    pinMode(rx, INPUT);
262
+    if (!_inverse_logic)
263
+        digitalWrite(rx, HIGH);  // pullup for normal logic!
264
+    _receivePin = rx;
265
+    _receiveBitMask = digitalPinToBitMask(rx);
266
+    uint8_t port = digitalPinToPort(rx);
267
+    _receivePortRegister = portInputRegister(port);
268
+}
269
+
270
+uint16_t SoftwareSerial8e1::subtract_cap(uint16_t num, uint16_t sub) {
271
+    if (num > sub)
272
+        return num - sub;
273
+    else
274
+        return 1;
275
+}
276
+
277
+//
278
+// Public methods
279
+//
280
+
281
+void SoftwareSerial8e1::begin(long speed)
282
+{
283
+    _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0;
284
+
285
+    // Precalculate the various delays, in number of 4-cycle delays
286
+    uint16_t bit_delay = (F_CPU / speed) / 4;
287
+
288
+    // 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
289
+    // 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
290
+    // 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
291
+    // These are all close enough to just use 15 cycles, since the inter-bit
292
+    // timings are the most critical (deviations stack 8 times)
293
+    _tx_delay = subtract_cap(bit_delay, 15 / 4);
294
+
295
+    // Only setup rx when we have a valid PCINT for this pin
296
+    if (digitalPinToPCICR(_receivePin)) {
297
+#if GCC_VERSION > 40800
298
+        // Timings counted from gcc 4.8.2 output. This works up to 115200 on
299
+    // 16Mhz and 57600 on 8Mhz.
300
+    //
301
+    // When the start bit occurs, there are 3 or 4 cycles before the
302
+    // interrupt flag is set, 4 cycles before the PC is set to the right
303
+    // interrupt vector address and the old PC is pushed on the stack,
304
+    // and then 75 cycles of instructions (including the RJMP in the
305
+    // ISR vector table) until the first delay. After the delay, there
306
+    // are 17 more cycles until the pin value is read (excluding the
307
+    // delay in the loop).
308
+    // We want to have a total delay of 1.5 bit time. Inside the loop,
309
+    // we already wait for 1 bit time - 23 cycles, so here we wait for
310
+    // 0.5 bit time - (71 + 18 - 22) cycles.
311
+    _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 75 + 17 - 23) / 4);
312
+
313
+    // There are 23 cycles in each loop iteration (excluding the delay)
314
+    _rx_delay_intrabit = subtract_cap(bit_delay, 23 / 4);
315
+
316
+    // There are 37 cycles from the last bit read to the start of
317
+    // stopbit delay and 11 cycles from the delay until the interrupt
318
+    // mask is enabled again (which _must_ happen during the stopbit).
319
+    // This delay aims at 3/4 of a bit time, meaning the end of the
320
+    // delay will be at 1/4th of the stopbit. This allows some extra
321
+    // time for ISR cleanup, which makes 115200 baud at 16Mhz work more
322
+    // reliably
323
+    _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11) / 4);
324
+#else // Timings counted from gcc 4.3.2 output
325
+        // Note that this code is a _lot_ slower, mostly due to bad register
326
+        // allocation choices of gcc. This works up to 57600 on 16Mhz and
327
+        // 38400 on 8Mhz.
328
+        _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11) / 4);
329
+        _rx_delay_intrabit = subtract_cap(bit_delay, 11 / 4);
330
+        _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17) / 4);
331
+#endif
332
+
333
+
334
+        // Enable the PCINT for the entire port here, but never disable it
335
+        // (others might also need it, so we disable the interrupt by using
336
+        // the per-pin PCMSK register).
337
+        *digitalPinToPCICR(_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
338
+        // Precalculate the pcint mask register and value, so setRxIntMask
339
+        // can be used inside the ISR without costing too much time.
340
+        _pcint_maskreg = digitalPinToPCMSK(_receivePin);
341
+        _pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
342
+
343
+        tunedDelay(_tx_delay); // if we were low this establishes the end
344
+    }
345
+
346
+#if _DEBUG
347
+    pinMode(_DEBUG_PIN1, OUTPUT);
348
+  pinMode(_DEBUG_PIN2, OUTPUT);
349
+#endif
350
+
351
+    listen();
352
+}
353
+
354
+void SoftwareSerial8e1::setRxIntMsk(bool enable)
355
+{
356
+    if (enable)
357
+        *_pcint_maskreg |= _pcint_maskvalue;
358
+    else
359
+        *_pcint_maskreg &= ~_pcint_maskvalue;
360
+}
361
+
362
+void SoftwareSerial8e1::end()
363
+{
364
+    stopListening();
365
+}
366
+
367
+
368
+// Read data from buffer
369
+int SoftwareSerial8e1::read()
370
+{
371
+    if (!isListening())
372
+        return -1;
373
+
374
+    // Empty buffer?
375
+    if (_receive_buffer_head == _receive_buffer_tail)
376
+        return -1;
377
+
378
+    // Read from "head"
379
+    uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
380
+    _receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
381
+    return d;
382
+}
383
+
384
+int SoftwareSerial8e1::available()
385
+{
386
+    if (!isListening())
387
+        return 0;
388
+
389
+    return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
390
+}
391
+
392
+size_t SoftwareSerial8e1::write(uint8_t b)
393
+{
394
+    if (_tx_delay == 0) {
395
+        setWriteError();
396
+        return 0;
397
+    }
398
+//    setTX(_receivePin);
399
+
400
+    // By declaring these as local variables, the compiler will put them
401
+    // in registers _before_ disabling interrupts and entering the
402
+    // critical timing sections below, which makes it a lot easier to
403
+    // verify the cycle timings
404
+    volatile uint8_t *reg = _transmitPortRegister;
405
+    uint8_t reg_mask = _transmitBitMask;
406
+    uint8_t inv_mask = ~_transmitBitMask;
407
+    uint8_t oldSREG = SREG;
408
+    bool inv = _inverse_logic;
409
+    uint16_t delay = _tx_delay;
410
+    uint8_t p = 0;
411
+    for (uint8_t t = 0x80; t; t >>= 1)
412
+        if (b & t) p++;
413
+
414
+    if (inv)
415
+        b = ~b;
416
+
417
+    cli();  // turn off interrupts for a clean txmit
418
+
419
+    // Write the start bit
420
+    if (inv)
421
+        *reg |= reg_mask;
422
+    else
423
+        *reg &= inv_mask;
424
+
425
+    tunedDelay(delay);
426
+
427
+    // Write each of the 8 bits
428
+    for (uint8_t i = 8; i > 0; --i)
429
+    {
430
+        if (b & 1) // choose bit
431
+            *reg |= reg_mask; // send 1
432
+        else
433
+            *reg &= inv_mask; // send 0
434
+
435
+        tunedDelay(delay);
436
+        b >>= 1;
437
+    }
438
+
439
+    if (p & 0x01)
440
+        *reg |= reg_mask; // send 1
441
+    else
442
+        *reg &= inv_mask; // send 0
443
+    tunedDelay(_tx_delay);
444
+
445
+    // restore pin to natural state
446
+    if (inv)
447
+        *reg &= inv_mask;
448
+    else
449
+        *reg |= reg_mask;
450
+
451
+    SREG = oldSREG; // turn interrupts back on
452
+    tunedDelay(_tx_delay);
453
+
454
+//    setRX(_receivePin);
455
+//    pinMode(_receivePin, INPUT);
456
+
457
+    return 1;
458
+}
459
+
460
+void SoftwareSerial8e1::flush()
461
+{
462
+    // There is no tx buffering, simply return
463
+}
464
+
465
+int SoftwareSerial8e1::peek()
466
+{
467
+    if (!isListening())
468
+        return -1;
469
+
470
+    // Empty buffer?
471
+    if (_receive_buffer_head == _receive_buffer_tail)
472
+        return -1;
473
+
474
+    // Read from "head"
475
+    return _receive_buffer[_receive_buffer_head];
476
+}

+ 98
- 0
SoftwareSerial8e1.h View File

@@ -0,0 +1,98 @@
1
+//
2
+// Created by robin on 2/24/17.
3
+//
4
+
5
+#ifndef ARDUINOSMARTCARD_SOFTWARESERIAL8E1_H
6
+#define ARDUINOSMARTCARD_SOFTWARESERIAL8E1_H
7
+
8
+
9
+
10
+#include <inttypes.h>
11
+#include <Stream.h>
12
+
13
+/******************************************************************************
14
+* Definitions
15
+******************************************************************************/
16
+
17
+#ifndef _SS_MAX_RX_BUFF
18
+#define _SS_MAX_RX_BUFF 64 // RX buffer size
19
+#endif
20
+
21
+#ifndef GCC_VERSION
22
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
23
+#endif
24
+
25
+class SoftwareSerial8e1 : public Stream
26
+{
27
+private:
28
+    // per object data
29
+    uint8_t _receivePin;
30
+    uint8_t _receiveBitMask;
31
+    volatile uint8_t *_receivePortRegister;
32
+    uint8_t _transmitBitMask;
33
+    volatile uint8_t *_transmitPortRegister;
34
+    volatile uint8_t *_pcint_maskreg;
35
+    uint8_t _pcint_maskvalue;
36
+
37
+    // Expressed as 4-cycle delays (must never be 0!)
38
+    uint16_t _rx_delay_centering;
39
+    uint16_t _rx_delay_intrabit;
40
+    uint16_t _rx_delay_stopbit;
41
+    uint16_t _tx_delay;
42
+
43
+    uint16_t _buffer_overflow:1;
44
+    uint16_t _inverse_logic:1;
45
+
46
+    // static data
47
+    static uint8_t _receive_buffer[_SS_MAX_RX_BUFF];
48
+    static volatile uint8_t _receive_buffer_tail;
49
+    static volatile uint8_t _receive_buffer_head;
50
+    static SoftwareSerial8e1 *active_object;
51
+
52
+    // private methods
53
+    inline void recv() __attribute__((__always_inline__));
54
+    uint8_t rx_pin_read();
55
+    void setTX(uint8_t transmitPin);
56
+    void setRX(uint8_t receivePin);
57
+    inline void setRxIntMsk(bool enable) __attribute__((__always_inline__));
58
+
59
+    // Return num - sub, or 1 if the result would be < 1
60
+    static uint16_t subtract_cap(uint16_t num, uint16_t sub);
61
+
62
+    // private static method for timing
63
+    static inline void tunedDelay(uint16_t delay);
64
+
65
+public:
66
+    // public methods
67
+    SoftwareSerial8e1(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false);
68
+    ~SoftwareSerial8e1();
69
+    void begin(long speed);
70
+    bool listen();
71
+    void end();
72
+    bool isListening() { return this == active_object; }
73
+    bool stopListening();
74
+    bool overflow() { bool ret = _buffer_overflow; if (ret) _buffer_overflow = false; return ret; }
75
+    int peek();
76
+
77
+    virtual size_t write(uint8_t byte);
78
+    virtual int read();
79
+    virtual int available();
80
+    virtual void flush();
81
+    operator bool() { return true; }
82
+
83
+    using Print::write;
84
+
85
+    // public only for easy access by interrupt handlers
86
+    static inline void handle_interrupt() __attribute__((__always_inline__));
87
+};
88
+
89
+// Arduino 0012 workaround
90
+#undef int
91
+#undef char
92
+#undef long
93
+#undef byte
94
+#undef float
95
+#undef abs
96
+#undef round
97
+
98
+#endif //ARDUINOSMARTCARD_SOFTWARESERIAL8E1_H

+ 150
- 17
main.ino View File

@@ -1,7 +1,7 @@
1 1
 #include <Arduino.h>
2 2
 #include <pins_arduino.h>
3
-#include <SoftwareSerial.h>
4 3
 #include <SCLib.h>
4
+#include "SoftwareSerial8e1.h"
5 5
 
6 6
 #define STATUS_LED 13
7 7
 
@@ -24,9 +24,11 @@ SmartCardReader cardReader(CARD_IO, CARD_RST, CARD_VCC, CARD_PRE, CARD_CLK, fals
24 24
 uint8_t readerAtr[MAX_ATR_BYTES];
25 25
 int readerAtrSize = 0;
26 26
 
27
-bool readerReset = false;
27
+//SoftwareSerial8e1 emulatorSerial(READER_IO, 5);
28
+bool isResetUp;
28 29
 int baudRate = -1;
29
-int etu = -1;
30
+int emulatorAtrEtu = -1;
31
+bool emulatorIoData = false;
30 32
 #ifndef digitalPinToInterrupt
31 33
 int digitalPinToInterrupt(int pin)
32 34
 {
@@ -46,10 +48,10 @@ int digitalPinToInterrupt(int pin)
46 48
 void emulatorComputeEtu()
47 49
 {
48 50
     baudRate = 9600;
49
-    etu = 1000000 / baudRate;
51
+    emulatorAtrEtu = 1000000 / baudRate;
50 52
 }
51 53
 
52
-void emulatorSendAtrByte(char byte)
54
+void emulatorSendByte(char byte, int etu)
53 55
 {
54 56
     unsigned long nextBitTime = micros() + (2 * etu);
55 57
     digitalWrite(READER_IO, HIGH);
@@ -84,14 +86,81 @@ void emulatorSendAtrByte(char byte)
84 86
     }
85 87
 }
86 88
 
87
-void emulatorSendAtr(const uint8_t* atr, size_t size)
89
+void emulatorSend(const uint8_t* atr, size_t size, int etu)
88 90
 {
91
+    pinMode(5, OUTPUT);
92
+    digitalWrite(5, HIGH);
89 93
     pinMode(READER_IO, OUTPUT);
90 94
     for (int i = 0; i < size; ++i)
91 95
     {
92
-        emulatorSendAtrByte(atr[i]);
96
+        emulatorSendByte(atr[i], etu);
93 97
         delayMicroseconds(4*etu);
94 98
     }
99
+    digitalWrite(READER_IO, LOW);
100
+    pinMode(READER_IO, INPUT);
101
+    digitalWrite(5, LOW);
102
+}
103
+
104
+uint8_t emulatorReadByte(int etu)
105
+{
106
+//    while (digitalRead(READER_IO));
107
+
108
+    unsigned long nextBitTime = micros() + (3 * etu / 2);
109
+    uint8_t byte = 0;
110
+    int bitNumber = 0;
111
+    int parity = 0;
112
+    while (bitNumber < 10)
113
+    {
114
+        if (nextBitTime <= micros())
115
+        {
116
+            if (bitNumber < 8)
117
+            {
118
+                int bit = digitalRead(READER_IO);
119
+                bitWrite(byte, bitNumber, bit);
120
+            }
121
+            else if (bitNumber == 8)
122
+            {
123
+                int parity = digitalRead(READER_IO);
124
+            }
125
+            else if (bitNumber == 9)
126
+            {
127
+                break;
128
+            }
129
+            nextBitTime += etu;
130
+            ++bitNumber;
131
+        }
132
+    }
133
+    return byte;
134
+}
135
+
136
+void emulatorReadCommand(int etu)
137
+{
138
+    pinMode(READER_IO, INPUT);
139
+
140
+    uint8_t cla = emulatorReadByte(etu);
141
+    uint8_t ins = emulatorReadByte(etu);
142
+    uint8_t p1 = emulatorReadByte(etu);
143
+    uint8_t p2 = emulatorReadByte(etu);
144
+    Serial.print((int)cla);
145
+    Serial.print(' ');
146
+    Serial.print((int)ins);
147
+    Serial.print(' ');
148
+    Serial.print((int)p1);
149
+    Serial.print(' ');
150
+    Serial.println((int)p2);
151
+
152
+//    pinMode(READER_IO, OUTPUT);
153
+}
154
+
155
+void emulatorSetupIoInterrupt()
156
+{
157
+    attachInterrupt(digitalPinToInterrupt(READER_IO), emulatorOnIoInterrupt, FALLING);
158
+}
159
+
160
+void emulatorOnIoInterrupt()
161
+{
162
+    detachInterrupt(digitalPinToInterrupt(READER_IO));
163
+    emulatorIoData = true;
95 164
 }
96 165
 
97 166
 void readerResetAtr()
@@ -114,6 +183,9 @@ void setup() {
114 183
 
115 184
     pinMode(STATUS_LED, OUTPUT);
116 185
     digitalWrite(STATUS_LED, LOW);
186
+
187
+    isResetUp = digitalRead(READER_RST);
188
+
117 189
     Serial.println("Initialized");
118 190
 
119 191
     readerResetAtr();
@@ -121,6 +193,14 @@ void setup() {
121 193
 
122 194
 void loop() {
123 195
 
196
+//    if (emulatorIoData)
197
+//    {
198
+//        emulatorIoData = false;
199
+//        uint8_t b = emulatorReadCommand(12171);
200
+//        emulatorSetupIoInterrupt();
201
+//        Serial.println()
202
+//    }
203
+
124 204
     if (readerAtrSize == 0)
125 205
     {
126 206
         if (cardReader.cardInserted())
@@ -133,26 +213,79 @@ void loop() {
133 213
     }
134 214
     else
135 215
     {
216
+        int resetStatus = digitalRead(READER_RST);
136 217
         if (!cardReader.cardInserted())
137 218
         {
138 219
             readerResetAtr();
139 220
             digitalWrite(STATUS_LED, LOW);
140 221
         }
141
-        else if (digitalRead(READER_RST))
222
+        else if (!isResetUp && resetStatus)
142 223
         {
143
-            if (!readerReset)
224
+            Serial.println("Reset");
225
+            emulatorComputeEtu();
226
+            emulatorSend(readerAtr, readerAtrSize, emulatorAtrEtu);
227
+
228
+            int baudRate = 12171;
229
+            int etu = 1000000 / baudRate;
230
+            size_t dataSize = 0;
231
+            uint8_t data[42];
232
+
144 233
             {
145
-                emulatorComputeEtu();
146
-                emulatorSendAtr(readerAtr, readerAtrSize);
147
-                readerReset = true;
234
+                SoftwareSerial8e1 emulatorSerial(READER_IO, 5);
235
+                emulatorSerial.begin(baudRate);
236
+                while (emulatorSerial.available() < 8);
237
+                dataSize = emulatorSerial.available();
238
+                emulatorSerial.readBytes((char *) data, dataSize);
239
+                emulatorSerial.end();
148 240
             }
149
-        }
150
-        else
151
-        {
152
-            if (readerReset)
241
+
242
+            delayMicroseconds(1000);
243
+            {
244
+                SoftwareSerial8e1 emulatorSerial(5, READER_IO);
245
+                emulatorSerial.begin(baudRate);
246
+                const uint8_t resp[] = {0x90, 0x00};
247
+                emulatorSerial.write(resp, sizeof(resp));
248
+                emulatorSerial.end();
249
+            }
250
+
251
+
252
+            for (int i = 0; i < dataSize; ++i)
153 253
             {
154
-                readerReset = false;
254
+                Serial.print((int) data[i]);
255
+                Serial.print(' ');
155 256
             }
257
+            Serial.println();
258
+//            emulatorSend(resp, sizeof(resp), etu);
259
+//            emulatorSetupIoInterrupt();
260
+//                for (size_t i = 0; i < readerAtrSize; ++i)
261
+//                {
262
+//                    emulatorSerial.write(readerAtr[i]);
263
+//                }
264
+//                while (1)
265
+//                {
266
+////                    delayMicroseconds(10000);
267
+//                    bool has = false;
268
+//                    while (emulatorSerial.available())
269
+//                    {
270
+//                        Serial.print((int) emulatorSerial.read());
271
+//                        Serial.print(' ');
272
+//                        has = true;
273
+//                    }
274
+//                    if (has)
275
+//                    {
276
+//                        Serial.println();
277
+//                        const uint8_t resp[] = {0x90, 0x00};
278
+//                        emulatorSendAtr(resp, sizeof(resp), 12171);
279
+//                        emulatorSerial.begin(12171);
280
+////                        emulatorSerial.write((uint8_t)0x90);
281
+////                        emulatorSerial.write((uint8_t)0x00);
282
+//                    }
283
+//                }
284
+//            while (true)
285
+//            {
286
+//                emulatorReadCommand(12171);
287
+//            }
156 288
         }
289
+        isResetUp = resetStatus;
157 290
     }
158 291
 }

Loading…
Cancel
Save