
Basic Read and Writer implementation for an OEM Mifare RWD Device.
RWDMifare/RWDMifare.h
- Committer:
- seblovett
- Date:
- 2013-06-29
- Revision:
- 4:952267f44d02
- Parent:
- 3:4af68a2b8622
File content as of revision 4:952267f44d02:
/* Copyright (c) 2010 ARM Limited Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* This is a specific and quick implementation for the Mifare MicroRWD modules. The class configures the reader for Mifare operation and can poll for UIDs. */ /* Code originally as above. Only contained set up and ability to read UIDs * Code was expanded massively to implement read and writing of card blocks by seblovett. * * Responsibility for bricking any cards if section trailers are written to are entirely * on the user. This code has been written to avoid any chance of bricking the device, and * any attempt to write to section trailers requires effort on the user. * * Known Bugs and Limitations: * - Primitive UI * * * To Do: * - Turn into USB Device to work with Desktop software, giving a better UI to read and write cards. * - Inherit an InterruptIn to trigger a UID read on card detect */ #ifndef RWD_MIFARE_H #define RWD_MIFARE_H #include "mbed.h" #include "RWDModule.h" /** \class RWDMifare * Used to interface to a OEM-Mifare RFID card reader/writer */ class RWDMifare : public RWDModule { public: RWDMifare(PinName tx, PinName rx, PinName cts); virtual ~RWDMifare(); /** Error Codes: * An enumerate of the possible error codes generated by the class */ enum RWDMifareErr { MIFARE_OK, /**< No error */ MIFARE_HW, /**< Hardware-specific error */ MIFARE_NOCARD, /**< No card in field */ MIFARE_WRONGKEY, /**< Key is not valid (for auth command) */ MIFARE_TRAIL /**< Attempted a write to a section trailer - not allowed */ }; /** Commands: * An enumerate of the commands supported by this class */ enum MifareCMD { CMD_Get_Status = 0x53,/**<Get Status*/ CMD_Prog_EEPROM = 0x50,/**<Program the internal EEPROM*/ CMD_Read_Block = 0x52,/**<Read a Block of Data*/ CMD_Write_Block = 0x57,/**<Write a Block of Data*/ CMD_Store_Key = 0x4b,/**<Store a security key*/ CMD_Get_UID = 0x55/**<Read the UID of a card*/ }; /** Acknowledge Codes: * An enumerate of the masks of status code fields. */ enum Ack_Code { Ack_Code_EEPROM_ERR = 0x01, Ack_Code_Card_OK = 0x02, Ack_Code_RX_OK = 0x04, Ack_Code_RS232_ERR = 0x08, Ack_Code_MF_Type = 0x10, Ack_Code_UL_Type = 0x20, Ack_Code_MRRFC_Err = 0x40 }; /** EEPROM Address: * Address constants for accessing the EEPROM Addresses */ enum EEPROM_ADDR { POLL =0x00, Aux_Data_OP =0x01, Checksum =0x02, Mifare_ICODE =0x03, Weigand_Parity =0x04, Aux_Block_Addr =0x05, Key_Number =0x06, Beep_Delay =0x07, OP_Source_Data =0x08, Aux_Out_ReDir =0x09, OP_Fmt =0x0A, Byte_Order =0x0B }; /** Poll Times: * Available values of the EEPROM location controlling Poll Time */ enum POLL_TIME { POLL_4ms = 0x00, POLL_8ms = 0x10, POLL_16ms = 0x20, POLL_32ms = 0x30, POLL_65ms = 0x40, POLL_132ms = 0x50, POLL_262ms_d = 0x60, POLL_524ms = 0x70, POLL_1s = 0x80, POLL_2s = 0x90, POLL_4s = 0xA0, POLL_8s = 0xB0 }; /** Auxilary Data: * Values to set the function of OP0 and OP1 */ enum Aux_Data { Aux_Data_OP_OFF =0x00, Aux_Data_OP_24bit_W =0x01, Aux_Data_OP_32bit_W =0x02, Aux_Data_OP_Serial_OP0 =0x03 }; /** Mode: * Controls whether the device operates in MIFARE or ICODE mode * (NB only Mifare supported, this is included for completion) */ enum Mifare_Icode { MIFARE =0x00, ICODE =0x01 }; /** Weigand Parity: * Sets the Weigand Parity if the Weigand option is used * NB not implemented */ enum Weigand_Parity { None =0x00, On =0x01 }; /** OP Source * Sets the data output on OP0 */ enum OP_Source_Data { OP_Source_Data_UID =0x00, OP_Source_Data_Block =0x01 }; /** Aux Output Redirection * Sets the output pin for OP0 data */ enum Aux_Out_ReDir { OP0 =0x00, TX =0x01 }; /** OP Format * Controls the output format of data on OP */ enum OP_Fmt { Hex =0x00, ASCII =0x01 }; /** Aux output order * Changes the byte order data is sent on the Aux output line */ enum Byte_Order { Default =0x00, Reversed =0x01 }; //! Initialises the device /*! Programs the EEPROM to configure in Mifare Mode * \return Error code * \sa RWDMifareErr */ RWDMifareErr init();//initialise the device //! Gets UID of card, as well as the length of /*! Reads and returns the UID and length of UID of a card if in detect * \param pUID must be at least 10-bytes long * \param pLen will contain the length of the UID * \return Error code * \sa RWDMifareErr */ RWDMifareErr getUID(uint8_t* pUID, size_t* pLen); //! Gets the Reader Status /*! Gets the status of the RFID card reader. * \param Status - location will be filled with the status value * \sa Ack_Code */ RWDMifareErr getStatus(uint8_t* Status); //! Prints a description of status /*! Method prints lines giving a brief explanation of the Status bits * \param Status is the status byte received from getStatus() * \sa Ack_Code, getStatus() */ RWDMifareErr printStatus(uint8_t Status); //! Programs the EEPROM /*! Programs the EEPROM of the Card Reader * \param Address to program. Enumerated by EEPROM_ADDR * \param Value to write. Documented by Enums, depending on field writing to. Sets the internal value to change reader behaviour * \sa EEPROM_ADDR, POLL_TIME, Aux_Data, Mifare_Icode, Weigand_Parity, OP_Source_Data, Aux_Out_ReDir, OP_Fmt, Byte_Order */ RWDMifareErr Prog_EEPROM(uint8_t Address, uint8_t Value); //! Stores an access key to the internal EEPROM Memory /*! Writes a key to the internal memory to be used to access secured cards * \param KeyNumber is the location the key is stored at and is used to reference the key in other operations * \param Key is a 6 byte key to be written */ RWDMifareErr StoreKey(uint8_t KeyNumber, uint8_t* Key); //! Reads a block of data from the card /*! Reads a 16 byte block of memory from the card * \param Addr is the block address (0-63 for 1k cards, 0-255 for 4k cards) to read from. * \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 * \param Data is the location that the block data is stored at. Should be at least 16 bytes in length. */ RWDMifareErr ReadBlock(uint8_t Addr, uint8_t KeyNumber_Type, uint8_t* Data); //! Reads a block of data from the card /*! Reads a 16 byte block of memory from the card * \param Addr is the block address (0-63 for 1k cards, 0-255 for 4k cards) to read from. * \param Keynumber Key Number to use to access the card, between 0 and 31. * \param Type is the key type to use. 0 = A, !0 = B. * \param Data to store the data read back in. Should be at least 16 bytes in length. */ RWDMifareErr ReadBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data); //! Writes a block of data to the card /*! Writes an entire block of data to the RFID card * 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. * 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 ... * Writing to these sections is the same protocol, but it is necessary to understand the Section Trailers before attempting to do so. * \param Addr is the Block Address of a data field to write to. * \param Keynumber Key Number to use to access the card, between 0 and 31. * \param Type is the key type to use. 0 = A, !0 = B. * \param Data is the source of the data to be written. Should be at least 16 bytes in length. */ RWDMifareErr WriteBlock(uint8_t Addr, uint8_t KeyNumber, uint8_t Type, uint8_t* Data); //! Authorises all cards for the RWD /*! The Mifare Reader can contain up to 60 internal UIDs to match to a read UID. * 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 */ RWDMifareErr AuthAllCards(); }; #endif