Generic driver for the RWD RFID Modules from IB Technology.
Embed:
(wiki syntax)
Show/hide line numbers
RWDModule.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "RWDModule.h" 00025 00026 RWDModule::RWDModule(PinName tx, PinName rx, PinName cts) : m_serial(tx, rx), m_cts(cts), 00027 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) 00028 { 00029 //Setup baudrate 00030 m_serial.baud(9600); 00031 //Setup interrupts 00032 m_serial.attach(this, &RWDModule::intTx, Serial::TxIrq); //Serial port writeable 00033 m_serial.attach(this, &RWDModule::intRx, Serial::RxIrq); //Serial port readable 00034 m_cts.fall(this, &RWDModule::intClearToSend); //Clear To Send: can send a command 00035 } 00036 00037 RWDModule::~RWDModule () 00038 { 00039 00040 } 00041 00042 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 00043 { 00044 if(!ready()) //If reader is not ready, does not submit another command yet 00045 return; 00046 00047 //Setup command 00048 m_cmd = cmd; 00049 00050 //Setup parameters 00051 m_paramsBuf = (uint8_t*) params; 00052 m_paramsLen = paramsLen; 00053 00054 //Setup response 00055 m_respBuf = resp; 00056 m_respLen = respLen; 00057 00058 //Pos in buf is 0 00059 m_pos = 0; 00060 00061 //Setup ack requirements 00062 m_ackOk = ackOk; 00063 m_ackOkMask = ackOkMask; 00064 00065 m_state = CMD_QUEUED; 00066 } 00067 00068 bool RWDModule::ready() 00069 { 00070 return (m_state==READY); 00071 } 00072 00073 bool RWDModule::result(uint8_t* pAck /*= NULL*/) 00074 { 00075 if(!ready()) //Has command returned yet? 00076 return false; 00077 if(pAck) //If pointer is passed, return reader's ack 00078 *pAck = m_ack; 00079 return ((m_ack & m_ackOkMask) == m_ackOk); //Return whether the reader returned an error or OK ack 00080 } 00081 00082 void RWDModule::intClearToSend() 00083 { 00084 //Start sending command when Clear To Send falls 00085 if(m_state == CMD_QUEUED) //Is there a command to be sent? 00086 { 00087 m_state = SENDING_CMD; 00088 intTx(); //Start sending command 00089 } 00090 } 00091 00092 00093 void RWDModule::intTx() 00094 { 00095 if(m_state != SENDING_CMD) 00096 return; 00097 if(m_pos==0) //Must send command-byte first 00098 m_serial.putc((char)m_cmd); 00099 while(true) //Send payload 00100 { 00101 if(m_pos >= m_paramsLen) //Payload sent completely? 00102 { 00103 m_pos = 0; 00104 m_state = WAITING_FOR_ACK; //Next step 00105 return; 00106 } 00107 m_serial.putc((char)m_paramsBuf[m_pos]); //Send payload byte 00108 m_pos++; 00109 } 00110 } 00111 00112 void RWDModule::intRx() 00113 { 00114 if(m_state == WAITING_FOR_ACK) //Get answer 00115 { 00116 m_ack = m_serial.getc(); //Get Ack 00117 if( (m_ack & m_ackOkMask) != m_ackOk ) //Check if an error is returned 00118 { 00119 m_state = READY; //If yes, transfer is completed and result() will return false 00120 return; 00121 } 00122 if(m_respLen) 00123 { 00124 m_state = RECEIVING_ACK; //Ack OK, now need to get response 00125 } 00126 else 00127 { 00128 m_state = READY; //Ack OK, end of transfer 00129 return; 00130 } 00131 } 00132 if(m_state != RECEIVING_ACK) //Error, should not happen 00133 { 00134 while(m_serial.readable()) 00135 m_serial.getc(); //Dump these bytes 00136 return; 00137 } 00138 while(m_serial.readable()) //Read payload 00139 { 00140 m_respBuf[m_pos] = (uint8_t) m_serial.getc(); //Read byte and put it in resp buf 00141 m_pos++; 00142 if(m_pos >= m_respLen) 00143 { 00144 m_pos = 0; 00145 m_state = READY; //End of transfer, response retrieved with success 00146 } 00147 } 00148 }
Generated on Thu Jul 14 2022 03:09:25 by 1.7.2