Henry Lovett
/
MifareRFIDReaderWriter
Basic Read and Writer implementation for an OEM Mifare RWD Device.
Embed:
(wiki syntax)
Show/hide line numbers
RWDModule.cpp
00001 /* 00002 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 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 #include "RWDModule.h" 00024 00025 RWDModule::RWDModule(PinName tx, PinName rx, PinName cts) : m_serial(tx, rx), m_cts(cts), 00026 m_cmd(0), m_paramsBuf(NULL), m_respBuf(NULL), m_pos(0), m_paramsLen(0), m_respLen(0), m_ackOk(0), m_ackOkMask(0), m_ack(0), m_state(READY) 00027 { 00028 //Setup baudrate 00029 m_serial.baud(9600); 00030 //Setup interrupts 00031 m_serial.attach(this, &RWDModule::intTx, Serial::TxIrq); //Serial port writeable 00032 m_serial.attach(this, &RWDModule::intRx, Serial::RxIrq); //Serial port readable 00033 m_cts.fall(this, &RWDModule::intClearToSend); //Clear To Send: can send a command 00034 } 00035 00036 void RWDModule::command(uint8_t cmd, const uint8_t* params, int paramsLen, uint8_t* resp, size_t respLen, uint8_t ackOk, size_t ackOkMask) //Ack Byte is not included in the resp buf 00037 { 00038 if(!ready()) //If reader is not ready, does not submit another command yet 00039 return; 00040 00041 //Setup command 00042 m_cmd = cmd; 00043 00044 //Setup parameters 00045 m_paramsBuf = (uint8_t*) params; 00046 m_paramsLen = paramsLen; 00047 00048 //Setup response 00049 m_respBuf = resp; 00050 m_respLen = respLen; 00051 00052 //Pos in buf is 0 00053 m_pos = 0; 00054 00055 //Setup ack requirements 00056 m_ackOk = ackOk; 00057 m_ackOkMask = ackOkMask; 00058 00059 m_state = CMD_QUEUED; 00060 } 00061 00062 bool RWDModule::ready() 00063 { 00064 return (m_state==READY); 00065 } 00066 00067 bool RWDModule::result(uint8_t* pAck /*= NULL*/) 00068 { 00069 if(!ready()) //Has command returned yet? 00070 return false; 00071 if(pAck) //If pointer is passed, return reader's ack 00072 *pAck = m_ack; 00073 return ((m_ack & m_ackOkMask) == m_ackOk); //Return whether the reader returned an error or OK ack 00074 } 00075 00076 void RWDModule::intClearToSend() 00077 { 00078 //Start sending command when Clear To Send falls 00079 if(m_state == CMD_QUEUED) //Is there a command to be sent? 00080 { 00081 m_state = SENDING_CMD; 00082 intTx(); //Start sending command 00083 } 00084 } 00085 00086 00087 void RWDModule::intTx() 00088 { 00089 if(m_state != SENDING_CMD) 00090 return; 00091 if(m_pos==0) //Must send command-byte first 00092 m_serial.putc((char)m_cmd); 00093 while(true) //Send payload 00094 { 00095 if(m_pos >= m_paramsLen) //Payload sent completely? 00096 { 00097 m_pos = 0; 00098 m_state = WAITING_FOR_ACK; //Next step 00099 return; 00100 } 00101 m_serial.putc((char)m_paramsBuf[m_pos]); //Send payload byte 00102 m_pos++; 00103 } 00104 } 00105 00106 void RWDModule::intRx() 00107 { 00108 if(m_state == WAITING_FOR_ACK) //Get answer 00109 { 00110 m_ack = m_serial.getc(); //Get Ack 00111 if( (m_ack & m_ackOkMask) != m_ackOk ) //Check if an error is returned 00112 { 00113 m_state = READY; //If yes, transfer is completed and result() will return false 00114 return; 00115 } 00116 if(m_respLen) 00117 { 00118 m_state = RECEIVING_ACK; //Ack OK, now need to get response 00119 } 00120 else 00121 { 00122 m_state = READY; //Ack OK, end of transfer 00123 return; 00124 } 00125 } 00126 if(m_state != RECEIVING_ACK) //Error, should not happen 00127 { 00128 while(m_serial.readable()) 00129 m_serial.getc(); //Dump these bytes 00130 return; 00131 } 00132 while(m_serial.readable()) //Read payload 00133 { 00134 m_respBuf[m_pos] = (uint8_t) m_serial.getc(); //Read byte and put it in resp buf 00135 m_pos++; 00136 if(m_pos >= m_respLen) 00137 { 00138 m_pos = 0; 00139 m_state = READY; //End of transfer, response retrieved with success 00140 } 00141 } 00142 }
Generated on Wed Jul 13 2022 03:38:17 by 1.7.2