Generic driver for the RWD RFID Modules from IB Technology.

Dependents:   RSEDP_DPDemo

RWDModule.cpp

Committer:
donatien
Date:
2010-07-13
Revision:
1:e96aaf4d5c55
Parent:
0:a893227b988a
Child:
2:37fafd1e1a20

File content as of revision 1:e96aaf4d5c55:

#include "RWDModule.h"

RWDModule::RWDModule(PinName tx, PinName rx, PinName cts) : m_serial(tx, rx), m_cts(cts),
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)
{
  m_serial.attach(this, &RWDModule::intTx, Serial::TxIrq);
  m_serial.attach(this, &RWDModule::intRx, Serial::RxIrq);
  m_cts.fall(this, &RWDModule::intClearToSend);
}

RWDModule::~RWDModule()
{

}

void RWDModule::command(byte cmd, const byte* params, int paramsLen, byte* resp, int respLen, byte ackOk, byte ackOkMask) //Ack Byte is not included in the resp buf
{
  if(!ready())
    return;
  m_cmd = cmd;
  m_paramsBuf = (byte*) params;
  m_paramsLen = paramsLen;
  m_respBuf = resp;
  m_respLen = respLen;
  m_pos = 0;
  m_ackOk = ackOk;
  m_ackOkMask = ackOkMask;
  m_state = CMD_QUEUED;
}
  
bool RWDModule::ready()
{
#if 0
  static int lastState;
  if(m_state != lastState)
  {
    printf("State %d\n", m_state);
    lastState = m_state;
    if(m_state==RECEIVING_ACK)
      printf("Ack %02x\n", m_ack);
  }
#endif
  return (m_state==READY);
}
   
bool RWDModule::result(byte* pAck /*= NULL*/)
{
  if(!ready())
    return false;
  if(pAck)
    *pAck = m_ack;
  return ((m_ack & m_ackOkMask) == m_ackOk);
}

void RWDModule::intClearToSend()
{
  //Start sending command when Clear To Send falls
  if(m_state == CMD_QUEUED)
  {
    m_state = SENDING_CMD;
    intTx(); //Start sending command
  }
}


void RWDModule::intTx()
{
  if(m_state != SENDING_CMD)
    return;  
  if(m_pos==0) //Must send command-byte first
    m_serial.putc((char)m_cmd);
  while(true)
  {
    if(m_pos >= m_paramsLen)
    {
      m_pos = 0;
      m_state = WAITING_FOR_ACK;
      return;
    }
    m_serial.putc((char)m_paramsBuf[m_pos]);
    m_pos++;
  }
}

void RWDModule::intRx()
{
  if(m_state == WAITING_FOR_ACK) //Get answer
  {
    m_ack = m_serial.getc();
    if( (m_ack & m_ackOkMask) != m_ackOk )
    {
      m_state = READY;
      return;
    }
    if(m_respLen)
    {
      m_state = RECEIVING_ACK;
    }
    else
    {
      m_state = READY;
      return;
    }
  }
  if(m_state != RECEIVING_ACK) //Error
  {
    while(m_serial.readable())
      m_serial.getc(); //Dump these bytes
    return; 
  }
  while(m_serial.readable()) //Read payload
  {
    m_respBuf[m_pos] = (byte) m_serial.getc();
    m_pos++;
    if(m_pos >= m_respLen)
    {
      m_pos = 0;
      m_state = READY;
    }
  }
}