![](/media/cache/profiles/a7bf3f5462cc82062e41b3a2262e1a21.50x50_q85.jpg)
Wiegand compatible RFID reader class
wiegand.h@0:033aa4854957, 2011-02-03 (annotated)
- Committer:
- pwheels
- Date:
- Thu Feb 03 18:48:04 2011 +0000
- Revision:
- 0:033aa4854957
- Child:
- 1:024f831fa51e
Initial creation date 3-feb-2011
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
pwheels | 0:033aa4854957 | 1 | /* |
pwheels | 0:033aa4854957 | 2 | * Copyright (c) 2011 Paul van der Wielen, Pro-Serv |
pwheels | 0:033aa4854957 | 3 | * |
pwheels | 0:033aa4854957 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
pwheels | 0:033aa4854957 | 5 | * of this software and associated documentation files (the "Software"), to use |
pwheels | 0:033aa4854957 | 6 | * and implement the software for none commercial reason and usage only and |
pwheels | 0:033aa4854957 | 7 | * subject to the following conditions: |
pwheels | 0:033aa4854957 | 8 | * |
pwheels | 0:033aa4854957 | 9 | * The above copyright notice and this permission notice shall be included in |
pwheels | 0:033aa4854957 | 10 | * all copies or substantial portions of the Software. |
pwheels | 0:033aa4854957 | 11 | * |
pwheels | 0:033aa4854957 | 12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
pwheels | 0:033aa4854957 | 13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
pwheels | 0:033aa4854957 | 14 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
pwheels | 0:033aa4854957 | 15 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
pwheels | 0:033aa4854957 | 16 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
pwheels | 0:033aa4854957 | 17 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
pwheels | 0:033aa4854957 | 18 | * THE SOFTWARE. |
pwheels | 0:033aa4854957 | 19 | * |
pwheels | 0:033aa4854957 | 20 | * Usage and assumptions: |
pwheels | 0:033aa4854957 | 21 | * a RFID reader Model MF7(1.05) is configured in wiegand mode and attached |
pwheels | 0:033aa4854957 | 22 | * ports per call to class (could be to p5 & p6 via a level converter as to |
pwheels | 0:033aa4854957 | 23 | * isolate the 5V source voltage from the 3.3V needed by MCU, this can easily |
pwheels | 0:033aa4854957 | 24 | * be done with diode in series with signal data0 and data1 of RFID reader and |
pwheels | 0:033aa4854957 | 25 | * pull up on MCU side. |
pwheels | 0:033aa4854957 | 26 | * |
pwheels | 0:033aa4854957 | 27 | * Note: using 'Wiegand' format rfid reader has one drawback as it only is capable |
pwheels | 0:033aa4854957 | 28 | * of returning 6 digits out of the 8 digits of the full RFID code, which is |
pwheels | 0:033aa4854957 | 29 | * the case for an 1K MiFare card. |
pwheels | 0:033aa4854957 | 30 | * Benefit is that a lot of Wiegand compatible reader do exist from various |
pwheels | 0:033aa4854957 | 31 | * brands at an reasonable price. |
pwheels | 0:033aa4854957 | 32 | */ |
pwheels | 0:033aa4854957 | 33 | |
pwheels | 0:033aa4854957 | 34 | #include "mbed.h" |
pwheels | 0:033aa4854957 | 35 | |
pwheels | 0:033aa4854957 | 36 | class Wiegand { |
pwheels | 0:033aa4854957 | 37 | public: |
pwheels | 0:033aa4854957 | 38 | Wiegand(PinName pin0, PinName pin1) : _D0(pin0), _D1(pin1) { // create the InterruptIn on the pin specified to Wiegand |
pwheels | 0:033aa4854957 | 39 | _D0.mode(PullUp); |
pwheels | 0:033aa4854957 | 40 | _D1.mode(PullUp); |
pwheels | 0:033aa4854957 | 41 | _D0.rise(this, &Wiegand::data_0); // attach data_0 function of this wiegand instance |
pwheels | 0:033aa4854957 | 42 | _D1.rise(this, &Wiegand::data_1); // attach data_1 function of this wiegand instance |
pwheels | 0:033aa4854957 | 43 | } |
pwheels | 0:033aa4854957 | 44 | |
pwheels | 0:033aa4854957 | 45 | /* |
pwheels | 0:033aa4854957 | 46 | * Interrupt driven signal from data0 data line |
pwheels | 0:033aa4854957 | 47 | */ |
pwheels | 0:033aa4854957 | 48 | void data_0() { |
pwheels | 0:033aa4854957 | 49 | if (_pulses == 26) { |
pwheels | 0:033aa4854957 | 50 | clear(); |
pwheels | 0:033aa4854957 | 51 | } |
pwheels | 0:033aa4854957 | 52 | _wiegand = ((_wiegand << 1) & 0x3ffffff) + 0x00; |
pwheels | 0:033aa4854957 | 53 | if (_pulses < 13) { |
pwheels | 0:033aa4854957 | 54 | _e_par = (_e_par & 0x01); |
pwheels | 0:033aa4854957 | 55 | } else { |
pwheels | 0:033aa4854957 | 56 | _e_par = (_e_par & 0x01); |
pwheels | 0:033aa4854957 | 57 | } |
pwheels | 0:033aa4854957 | 58 | _pulses++; |
pwheels | 0:033aa4854957 | 59 | } |
pwheels | 0:033aa4854957 | 60 | |
pwheels | 0:033aa4854957 | 61 | /* |
pwheels | 0:033aa4854957 | 62 | * Interrupt driven signal from data1 data line |
pwheels | 0:033aa4854957 | 63 | */ |
pwheels | 0:033aa4854957 | 64 | void data_1() { |
pwheels | 0:033aa4854957 | 65 | if (_pulses == 26) { |
pwheels | 0:033aa4854957 | 66 | clear(); |
pwheels | 0:033aa4854957 | 67 | } |
pwheels | 0:033aa4854957 | 68 | _wiegand = ((_wiegand << 1) & 0x3ffffff) + 0x01; |
pwheels | 0:033aa4854957 | 69 | if (_pulses < 13) { |
pwheels | 0:033aa4854957 | 70 | _o_par = (_o_par & 0x01) + 0x01; |
pwheels | 0:033aa4854957 | 71 | } else { |
pwheels | 0:033aa4854957 | 72 | _o_par = (_o_par & 0x01) + 0x01; |
pwheels | 0:033aa4854957 | 73 | } |
pwheels | 0:033aa4854957 | 74 | _pulses++; |
pwheels | 0:033aa4854957 | 75 | } |
pwheels | 0:033aa4854957 | 76 | |
pwheels | 0:033aa4854957 | 77 | /* |
pwheels | 0:033aa4854957 | 78 | * Various callable class members as to obtain data parts |
pwheels | 0:033aa4854957 | 79 | */ |
pwheels | 0:033aa4854957 | 80 | unsigned long site() { |
pwheels | 0:033aa4854957 | 81 | return (_wiegand >> 17) & 0xff; |
pwheels | 0:033aa4854957 | 82 | } |
pwheels | 0:033aa4854957 | 83 | |
pwheels | 0:033aa4854957 | 84 | unsigned long data() { |
pwheels | 0:033aa4854957 | 85 | return (_wiegand >> 1) & 0xffff; |
pwheels | 0:033aa4854957 | 86 | } |
pwheels | 0:033aa4854957 | 87 | |
pwheels | 0:033aa4854957 | 88 | unsigned long rfid() { |
pwheels | 0:033aa4854957 | 89 | return (_wiegand >> 1) & 0xffffff; |
pwheels | 0:033aa4854957 | 90 | } |
pwheels | 0:033aa4854957 | 91 | |
pwheels | 0:033aa4854957 | 92 | /* |
pwheels | 0:033aa4854957 | 93 | * returns true if we have read all pulses and we have proper parity for both data halves |
pwheels | 0:033aa4854957 | 94 | */ |
pwheels | 0:033aa4854957 | 95 | bool readable() { |
pwheels | 0:033aa4854957 | 96 | if (( _pulses == 26) && (_e_par == 0) && (_o_par == 1)) { |
pwheels | 0:033aa4854957 | 97 | return true; |
pwheels | 0:033aa4854957 | 98 | } else { |
pwheels | 0:033aa4854957 | 99 | return false; |
pwheels | 0:033aa4854957 | 100 | } |
pwheels | 0:033aa4854957 | 101 | } |
pwheels | 0:033aa4854957 | 102 | |
pwheels | 0:033aa4854957 | 103 | /* |
pwheels | 0:033aa4854957 | 104 | * clear last read card entry, prepare for next card entry |
pwheels | 0:033aa4854957 | 105 | */ |
pwheels | 0:033aa4854957 | 106 | void clear() { |
pwheels | 0:033aa4854957 | 107 | _pulses = _e_par = _o_par = 0; |
pwheels | 0:033aa4854957 | 108 | _wiegand = 0; |
pwheels | 0:033aa4854957 | 109 | } |
pwheels | 0:033aa4854957 | 110 | |
pwheels | 0:033aa4854957 | 111 | private: |
pwheels | 0:033aa4854957 | 112 | InterruptIn _D0; |
pwheels | 0:033aa4854957 | 113 | InterruptIn _D1; |
pwheels | 0:033aa4854957 | 114 | volatile unsigned long _wiegand; |
pwheels | 0:033aa4854957 | 115 | volatile unsigned int _pulses; |
pwheels | 0:033aa4854957 | 116 | volatile unsigned int _e_par; |
pwheels | 0:033aa4854957 | 117 | volatile unsigned int _o_par; |
pwheels | 0:033aa4854957 | 118 | }; |