Generic driver for the RWD RFID Modules from IB Technology.
RWDModule.cpp@4:0c21bc193afa, 2010-07-22 (annotated)
- Committer:
- donatien
- Date:
- Thu Jul 22 16:24:31 2010 +0000
- Revision:
- 4:0c21bc193afa
- Parent:
- 3:60db4ab4dafe
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
donatien | 2:37fafd1e1a20 | 1 | |
donatien | 2:37fafd1e1a20 | 2 | /* |
donatien | 2:37fafd1e1a20 | 3 | Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) |
donatien | 2:37fafd1e1a20 | 4 | |
donatien | 2:37fafd1e1a20 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy |
donatien | 2:37fafd1e1a20 | 6 | of this software and associated documentation files (the "Software"), to deal |
donatien | 2:37fafd1e1a20 | 7 | in the Software without restriction, including without limitation the rights |
donatien | 2:37fafd1e1a20 | 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
donatien | 2:37fafd1e1a20 | 9 | copies of the Software, and to permit persons to whom the Software is |
donatien | 2:37fafd1e1a20 | 10 | furnished to do so, subject to the following conditions: |
donatien | 2:37fafd1e1a20 | 11 | |
donatien | 2:37fafd1e1a20 | 12 | The above copyright notice and this permission notice shall be included in |
donatien | 2:37fafd1e1a20 | 13 | all copies or substantial portions of the Software. |
donatien | 2:37fafd1e1a20 | 14 | |
donatien | 2:37fafd1e1a20 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
donatien | 2:37fafd1e1a20 | 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
donatien | 2:37fafd1e1a20 | 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
donatien | 2:37fafd1e1a20 | 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
donatien | 2:37fafd1e1a20 | 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
donatien | 2:37fafd1e1a20 | 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
donatien | 2:37fafd1e1a20 | 21 | THE SOFTWARE. |
donatien | 2:37fafd1e1a20 | 22 | */ |
donatien | 2:37fafd1e1a20 | 23 | |
donatien | 0:a893227b988a | 24 | #include "RWDModule.h" |
donatien | 0:a893227b988a | 25 | |
donatien | 0:a893227b988a | 26 | RWDModule::RWDModule(PinName tx, PinName rx, PinName cts) : m_serial(tx, rx), m_cts(cts), |
donatien | 0:a893227b988a | 27 | 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) |
donatien | 0:a893227b988a | 28 | { |
donatien | 3:60db4ab4dafe | 29 | //Setup baudrate |
donatien | 3:60db4ab4dafe | 30 | m_serial.baud(9600); |
donatien | 2:37fafd1e1a20 | 31 | //Setup interrupts |
donatien | 2:37fafd1e1a20 | 32 | m_serial.attach(this, &RWDModule::intTx, Serial::TxIrq); //Serial port writeable |
donatien | 2:37fafd1e1a20 | 33 | m_serial.attach(this, &RWDModule::intRx, Serial::RxIrq); //Serial port readable |
donatien | 2:37fafd1e1a20 | 34 | m_cts.fall(this, &RWDModule::intClearToSend); //Clear To Send: can send a command |
donatien | 0:a893227b988a | 35 | } |
donatien | 0:a893227b988a | 36 | |
donatien | 0:a893227b988a | 37 | RWDModule::~RWDModule() |
donatien | 0:a893227b988a | 38 | { |
donatien | 0:a893227b988a | 39 | |
donatien | 0:a893227b988a | 40 | } |
donatien | 0:a893227b988a | 41 | |
donatien | 2:37fafd1e1a20 | 42 | 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 |
donatien | 0:a893227b988a | 43 | { |
donatien | 2:37fafd1e1a20 | 44 | if(!ready()) //If reader is not ready, does not submit another command yet |
donatien | 0:a893227b988a | 45 | return; |
donatien | 2:37fafd1e1a20 | 46 | |
donatien | 2:37fafd1e1a20 | 47 | //Setup command |
donatien | 0:a893227b988a | 48 | m_cmd = cmd; |
donatien | 2:37fafd1e1a20 | 49 | |
donatien | 2:37fafd1e1a20 | 50 | //Setup parameters |
donatien | 2:37fafd1e1a20 | 51 | m_paramsBuf = (uint8_t*) params; |
donatien | 0:a893227b988a | 52 | m_paramsLen = paramsLen; |
donatien | 2:37fafd1e1a20 | 53 | |
donatien | 2:37fafd1e1a20 | 54 | //Setup response |
donatien | 0:a893227b988a | 55 | m_respBuf = resp; |
donatien | 0:a893227b988a | 56 | m_respLen = respLen; |
donatien | 2:37fafd1e1a20 | 57 | |
donatien | 2:37fafd1e1a20 | 58 | //Pos in buf is 0 |
donatien | 0:a893227b988a | 59 | m_pos = 0; |
donatien | 2:37fafd1e1a20 | 60 | |
donatien | 2:37fafd1e1a20 | 61 | //Setup ack requirements |
donatien | 0:a893227b988a | 62 | m_ackOk = ackOk; |
donatien | 0:a893227b988a | 63 | m_ackOkMask = ackOkMask; |
donatien | 2:37fafd1e1a20 | 64 | |
donatien | 0:a893227b988a | 65 | m_state = CMD_QUEUED; |
donatien | 0:a893227b988a | 66 | } |
donatien | 0:a893227b988a | 67 | |
donatien | 0:a893227b988a | 68 | bool RWDModule::ready() |
donatien | 0:a893227b988a | 69 | { |
donatien | 0:a893227b988a | 70 | return (m_state==READY); |
donatien | 0:a893227b988a | 71 | } |
donatien | 0:a893227b988a | 72 | |
donatien | 2:37fafd1e1a20 | 73 | bool RWDModule::result(uint8_t* pAck /*= NULL*/) |
donatien | 0:a893227b988a | 74 | { |
donatien | 2:37fafd1e1a20 | 75 | if(!ready()) //Has command returned yet? |
donatien | 0:a893227b988a | 76 | return false; |
donatien | 2:37fafd1e1a20 | 77 | if(pAck) //If pointer is passed, return reader's ack |
donatien | 0:a893227b988a | 78 | *pAck = m_ack; |
donatien | 2:37fafd1e1a20 | 79 | return ((m_ack & m_ackOkMask) == m_ackOk); //Return whether the reader returned an error or OK ack |
donatien | 0:a893227b988a | 80 | } |
donatien | 0:a893227b988a | 81 | |
donatien | 0:a893227b988a | 82 | void RWDModule::intClearToSend() |
donatien | 0:a893227b988a | 83 | { |
donatien | 1:e96aaf4d5c55 | 84 | //Start sending command when Clear To Send falls |
donatien | 2:37fafd1e1a20 | 85 | if(m_state == CMD_QUEUED) //Is there a command to be sent? |
donatien | 0:a893227b988a | 86 | { |
donatien | 0:a893227b988a | 87 | m_state = SENDING_CMD; |
donatien | 0:a893227b988a | 88 | intTx(); //Start sending command |
donatien | 0:a893227b988a | 89 | } |
donatien | 0:a893227b988a | 90 | } |
donatien | 0:a893227b988a | 91 | |
donatien | 0:a893227b988a | 92 | |
donatien | 0:a893227b988a | 93 | void RWDModule::intTx() |
donatien | 0:a893227b988a | 94 | { |
donatien | 0:a893227b988a | 95 | if(m_state != SENDING_CMD) |
donatien | 0:a893227b988a | 96 | return; |
donatien | 1:e96aaf4d5c55 | 97 | if(m_pos==0) //Must send command-byte first |
donatien | 1:e96aaf4d5c55 | 98 | m_serial.putc((char)m_cmd); |
donatien | 2:37fafd1e1a20 | 99 | while(true) //Send payload |
donatien | 0:a893227b988a | 100 | { |
donatien | 2:37fafd1e1a20 | 101 | if(m_pos >= m_paramsLen) //Payload sent completely? |
donatien | 0:a893227b988a | 102 | { |
donatien | 0:a893227b988a | 103 | m_pos = 0; |
donatien | 2:37fafd1e1a20 | 104 | m_state = WAITING_FOR_ACK; //Next step |
donatien | 0:a893227b988a | 105 | return; |
donatien | 0:a893227b988a | 106 | } |
donatien | 2:37fafd1e1a20 | 107 | m_serial.putc((char)m_paramsBuf[m_pos]); //Send payload byte |
donatien | 0:a893227b988a | 108 | m_pos++; |
donatien | 0:a893227b988a | 109 | } |
donatien | 0:a893227b988a | 110 | } |
donatien | 0:a893227b988a | 111 | |
donatien | 0:a893227b988a | 112 | void RWDModule::intRx() |
donatien | 0:a893227b988a | 113 | { |
donatien | 1:e96aaf4d5c55 | 114 | if(m_state == WAITING_FOR_ACK) //Get answer |
donatien | 0:a893227b988a | 115 | { |
donatien | 2:37fafd1e1a20 | 116 | m_ack = m_serial.getc(); //Get Ack |
donatien | 2:37fafd1e1a20 | 117 | if( (m_ack & m_ackOkMask) != m_ackOk ) //Check if an error is returned |
donatien | 0:a893227b988a | 118 | { |
donatien | 2:37fafd1e1a20 | 119 | m_state = READY; //If yes, transfer is completed and result() will return false |
donatien | 0:a893227b988a | 120 | return; |
donatien | 0:a893227b988a | 121 | } |
donatien | 0:a893227b988a | 122 | if(m_respLen) |
donatien | 0:a893227b988a | 123 | { |
donatien | 2:37fafd1e1a20 | 124 | m_state = RECEIVING_ACK; //Ack OK, now need to get response |
donatien | 0:a893227b988a | 125 | } |
donatien | 0:a893227b988a | 126 | else |
donatien | 0:a893227b988a | 127 | { |
donatien | 2:37fafd1e1a20 | 128 | m_state = READY; //Ack OK, end of transfer |
donatien | 0:a893227b988a | 129 | return; |
donatien | 0:a893227b988a | 130 | } |
donatien | 0:a893227b988a | 131 | } |
donatien | 2:37fafd1e1a20 | 132 | if(m_state != RECEIVING_ACK) //Error, should not happen |
donatien | 0:a893227b988a | 133 | { |
donatien | 0:a893227b988a | 134 | while(m_serial.readable()) |
donatien | 0:a893227b988a | 135 | m_serial.getc(); //Dump these bytes |
donatien | 0:a893227b988a | 136 | return; |
donatien | 0:a893227b988a | 137 | } |
donatien | 1:e96aaf4d5c55 | 138 | while(m_serial.readable()) //Read payload |
donatien | 0:a893227b988a | 139 | { |
donatien | 2:37fafd1e1a20 | 140 | m_respBuf[m_pos] = (uint8_t) m_serial.getc(); //Read byte and put it in resp buf |
donatien | 0:a893227b988a | 141 | m_pos++; |
donatien | 0:a893227b988a | 142 | if(m_pos >= m_respLen) |
donatien | 0:a893227b988a | 143 | { |
donatien | 0:a893227b988a | 144 | m_pos = 0; |
donatien | 2:37fafd1e1a20 | 145 | m_state = READY; //End of transfer, response retrieved with success |
donatien | 0:a893227b988a | 146 | } |
donatien | 0:a893227b988a | 147 | } |
donatien | 0:a893227b988a | 148 | } |