Henry Lovett
/
MifareRFIDReaderWriter
Basic Read and Writer implementation for an OEM Mifare RWD Device.
Embed:
(wiki syntax)
Show/hide line numbers
RWDMifare.h
00001 /* 00002 Copyright (c) 2010 ARM Limited 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 /* 00024 This is a specific and quick implementation for the Mifare MicroRWD modules. 00025 The class configures the reader for Mifare operation and can poll for UIDs. 00026 */ 00027 00028 /* Code originally as above. Only contained set up and ability to read UIDs 00029 * Code was expanded massively to implement read and writing of card blocks by seblovett. 00030 * 00031 * Responsibility for bricking any cards if section trailers are written to are entirely 00032 * on the user. This code has been written to avoid any chance of bricking the device, and 00033 * any attempt to write to section trailers requires effort on the user. 00034 * 00035 * Known Bugs and Limitations: 00036 * - Primitive UI 00037 * 00038 * 00039 * To Do: 00040 * - Turn into USB Device to work with Desktop software, giving a better UI to read and write cards. 00041 * - Inherit an InterruptIn to trigger a UID read on card detect 00042 */ 00043 00044 00045 #ifndef RWD_MIFARE_H 00046 #define RWD_MIFARE_H 00047 00048 #include "mbed.h" 00049 #include "RWDModule.h" 00050 /** \class RWDMifare 00051 * Used to interface to a OEM-Mifare RFID card reader/writer 00052 */ 00053 class RWDMifare : public RWDModule 00054 { 00055 public: 00056 RWDMifare(PinName tx, PinName rx, PinName cts); 00057 virtual ~RWDMifare(); 00058 00059 00060 /** Error Codes: 00061 * An enumerate of the possible error codes generated by the class 00062 */ 00063 enum RWDMifareErr 00064 { 00065 MIFARE_OK, /**< No error */ 00066 MIFARE_HW, /**< Hardware-specific error */ 00067 MIFARE_NOCARD, /**< No card in field */ 00068 MIFARE_WRONGKEY, /**< Key is not valid (for auth command) */ 00069 MIFARE_TRAIL /**< Attempted a write to a section trailer - not allowed */ 00070 }; 00071 /** Commands: 00072 * An enumerate of the commands supported by this class 00073 */ 00074 enum MifareCMD 00075 { 00076 CMD_Get_Status = 0x53,/**<Get Status*/ 00077 CMD_Prog_EEPROM = 0x50,/**<Program the internal EEPROM*/ 00078 CMD_Read_Block = 0x52,/**<Read a Block of Data*/ 00079 CMD_Write_Block = 0x57,/**<Write a Block of Data*/ 00080 CMD_Store_Key = 0x4b,/**<Store a security key*/ 00081 CMD_Get_UID = 0x55/**<Read the UID of a card*/ 00082 }; 00083 00084 /** Acknowledge Codes: 00085 * An enumerate of the masks of status code fields. 00086 */ 00087 enum Ack_Code { 00088 Ack_Code_EEPROM_ERR = 0x01, 00089 Ack_Code_Card_OK = 0x02, 00090 Ack_Code_RX_OK = 0x04, 00091 Ack_Code_RS232_ERR = 0x08, 00092 Ack_Code_MF_Type = 0x10, 00093 Ack_Code_UL_Type = 0x20, 00094 Ack_Code_MRRFC_Err = 0x40 00095 }; 00096 00097 00098 00099 /** EEPROM Address: 00100 * Address constants for accessing the EEPROM Addresses 00101 */ 00102 enum EEPROM_ADDR { 00103 POLL =0x00, 00104 Aux_Data_OP =0x01, 00105 Checksum =0x02, 00106 Mifare_ICODE =0x03, 00107 Weigand_Parity =0x04, 00108 Aux_Block_Addr =0x05, 00109 Key_Number =0x06, 00110 Beep_Delay =0x07, 00111 OP_Source_Data =0x08, 00112 Aux_Out_ReDir =0x09, 00113 OP_Fmt =0x0A, 00114 Byte_Order =0x0B 00115 }; 00116 /** Poll Times: 00117 * Available values of the EEPROM location controlling Poll Time 00118 */ 00119 enum POLL_TIME { 00120 POLL_4ms = 0x00, 00121 POLL_8ms = 0x10, 00122 POLL_16ms = 0x20, 00123 POLL_32ms = 0x30, 00124 POLL_65ms = 0x40, 00125 POLL_132ms = 0x50, 00126 POLL_262ms_d = 0x60, 00127 POLL_524ms = 0x70, 00128 POLL_1s = 0x80, 00129 POLL_2s = 0x90, 00130 POLL_4s = 0xA0, 00131 POLL_8s = 0xB0 00132 }; 00133 /** Auxilary Data: 00134 * Values to set the function of OP0 and OP1 00135 */ 00136 enum Aux_Data { 00137 Aux_Data_OP_OFF =0x00, 00138 Aux_Data_OP_24bit_W =0x01, 00139 Aux_Data_OP_32bit_W =0x02, 00140 Aux_Data_OP_Serial_OP0 =0x03 00141 }; 00142 00143 /** Mode: 00144 * Controls whether the device operates in MIFARE or ICODE mode 00145 * (NB only Mifare supported, this is included for completion) 00146 */ 00147 enum Mifare_Icode { 00148 MIFARE =0x00, 00149 ICODE =0x01 00150 }; 00151 /** Weigand Parity: 00152 * Sets the Weigand Parity if the Weigand option is used 00153 * NB not implemented 00154 */ 00155 enum Weigand_Parity { 00156 None =0x00, 00157 On =0x01 00158 }; 00159 /** OP Source 00160 * Sets the data output on OP0 00161 */ 00162 enum OP_Source_Data { 00163 OP_Source_Data_UID =0x00, 00164 OP_Source_Data_Block =0x01 00165 }; 00166 /** Aux Output Redirection 00167 * Sets the output pin for OP0 data 00168 */ 00169 enum Aux_Out_ReDir { 00170 OP0 =0x00, 00171 TX =0x01 00172 }; 00173 /** OP Format 00174 * Controls the output format of data on OP 00175 */ 00176 enum OP_Fmt { 00177 Hex =0x00, 00178 ASCII =0x01 00179 }; 00180 /** Aux output order 00181 * Changes the byte order data is sent on the Aux output line 00182 */ 00183 enum Byte_Order { 00184 Default =0x00, 00185 Reversed =0x01 00186 }; 00187 //! Initialises the device 00188 /*! Programs the EEPROM to configure in Mifare Mode 00189 * \return Error code 00190 * \sa RWDMifareErr 00191 */ 00192 RWDMifareErr init();//initialise the device 00193 00194 //! Gets UID of card, as well as the length of 00195 /*! Reads and returns the UID and length of UID of a card if in detect 00196 * \param pUID must be at least 10-bytes long 00197 * \param pLen will contain the length of the UID 00198 * \return Error code 00199 * \sa RWDMifareErr 00200 */ 00201 RWDMifareErr getUID(uint8_t* pUID, size_t* pLen); 00202 00203 //! Gets the Reader Status 00204 /*! Gets the status of the RFID card reader. 00205 * \param Status - location will be filled with the status value 00206 * \sa Ack_Code 00207 */ 00208 RWDMifareErr getStatus(uint8_t* Status); 00209 00210 //! Prints a description of status 00211 /*! Method prints lines giving a brief explanation of the Status bits 00212 * \param Status is the status byte received from getStatus() 00213 * \sa Ack_Code, getStatus() 00214 */ 00215 RWDMifareErr printStatus(uint8_t Status); 00216 00217 //! Programs the EEPROM 00218 /*! Programs the EEPROM of the Card Reader 00219 * \param Address to program. Enumerated by EEPROM_ADDR 00220 * \param Value to write. Documented by Enums, depending on field writing to. Sets the internal value to change reader behaviour 00221 * \sa EEPROM_ADDR, POLL_TIME, Aux_Data, Mifare_Icode, Weigand_Parity, OP_Source_Data, Aux_Out_ReDir, OP_Fmt, Byte_Order 00222 */ 00223 RWDMifareErr Prog_EEPROM(uint8_t Address, uint8_t Value); 00224 00225 //! Stores an access key to the internal EEPROM Memory 00226 /*! Writes a key to the internal memory to be used to access secured cards 00227 * \param KeyNumber is the location the key is stored at and is used to reference the key in other operations 00228 * \param Key is a 6 byte key to be written 00229 */ 00230 RWDMifareErr StoreKey(uint8_t KeyNumber, uint8_t* Key); 00231 00232 //! Reads a block of data from the card 00233 /*! Reads a 16 byte block of memory from the card 00234 * \param Addr is the block address (0-63 for 1k cards, 0-255 for 4k cards) to read from. 00235 * \param Keynumber_Tpye is the combined Key Number and card type of the form 0xTxxKKKKK - T => A = 0; B = 1. K is 5 bit key number 00236 * \param Data is the location that the block data is stored at. Should be at least 16 bytes in length. 00237 */ 00238 RWDMifareErr ReadBlock(uint8_t Addr, uint8_t KeyNumber_Type, uint8_t* Data); 00239 00240 //! Reads a block of data from the card 00241 /*! Reads a 16 byte block of memory from the card 00242 * \param Addr is the block address (0-63 for 1k cards, 0-255 for 4k cards) to read from. 00243 * \param Keynumber Key Number to use to access the card, between 0 and 31. 00244 * \param Type is the key type to use. 0 = A, !0 = B. 00245 * \param Data to store the data read back in. Should be at least 16 bytes in length. 00246 */ 00247 RWDMifareErr ReadBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data); 00248 00249 //! Writes a block of data to the card 00250 /*! Writes an entire block of data to the RFID card 00251 * WILL NOT WRITE TO A SECTION TRAILER. Incorrect writing to trailers can render the card useless. Therefore this method WILL NOT ALLOW writing to these to avoid accidentally bricking the card. 00252 * Section trailers are located at Blocks 3, 7, 11 ... 63 for the 1k cards and lower part of 4k cards, and also at 15, 31, 47 ... 00253 * Writing to these sections is the same protocol, but it is necessary to understand the Section Trailers before attempting to do so. 00254 * \param Addr is the Block Address of a data field to write to. 00255 * \param Keynumber Key Number to use to access the card, between 0 and 31. 00256 * \param Type is the key type to use. 0 = A, !0 = B. 00257 * \param Data is the source of the data to be written. Should be at least 16 bytes in length. 00258 */ 00259 RWDMifareErr WriteBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data); 00260 00261 //! Authorises all cards for the RWD 00262 /*! The Mifare Reader can contain up to 60 internal UIDs to match to a read UID. 00263 * This method will write 0xFFFFFFFF to the first field so that all cards brought into detect will be able to be read from the mbed 00264 */ 00265 RWDMifareErr AuthAllCards(); 00266 }; 00267 00268 #endif
Generated on Wed Jul 13 2022 03:38:17 by 1.7.2