//
#include "Abstract/II2C.h"
#include "Abstract/RFID/IPN532Interface.h"
+#include "Abstract/IProtocolLayer2.h"
#include "Drivers/PN532Interface_I2C.h"
Uint8_t PN532InterfaceI2C::m_Message[PN532_MESSAGE_SIZE] = {0};
PN532InterfaceI2C::PN532InterfaceI2C(II2C *_i2c,Uint8_t _address)
- : m_I2C(_i2c), m_Address(_address)
+ : m_I2C(_i2c), m_Address(_address), m_Command(0)
+ , m_CurrentState(STATE_INIT) , m_TxFrameSize(0)
+ , m_TxByteCount(0) , m_RxFrameSize(0)
{
m_ReadReady = false;
}
{
return PN532_INVALID_FRAME;
}
+ m_TxFrameSize = _count;
m_I2C->write(m_Address,m_Message,_count );
return readAckFrame();
}
return length;
}
+/*
+ *
+ * Implement IProtocolLayer2 Methods
+ *
+ */
+
+void PN532InterfaceI2C::init()
+{
+
+}
+
+
+const uint8_t PN532InterfaceI2C::getRxSize() const
+{
+ return 0;
+}
+
+/**
+ * @return a pointer to the received message
+ * if no message is available, return NULL.
+ */
+const uint8_t *PN532InterfaceI2C::receiveMsg()
+{
+ return nullptr;
+}
+
+
+void PN532InterfaceI2C::setTxMsg(const uint8_t *_src,uint8_t _length)
+{
+
+}
+
+/**
+ * \bried transmit message stored in m_Buffer.
+ * The message must previously be set by
+ * setTxMsg()
+ */
+void PN532InterfaceI2C::transmitMsg()
+{
+
+ updateState(EVT_TRANSMIT);
+}
+
+/**
+ * @brief called by scheduler I think.
+ */
+void PN532InterfaceI2C::tick()
+{
+ /* Do something like read of check state */
+ updateState(EVT_TICK);
+}
+/* Actions .... */
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doInit(const Event_t _evt)
+{
+ return STATE_IDLE;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doIdle(const Event_t _evt)
+{
+ State_t newState = STATE_IDLE;
+ if (_evt == EVT_TRANSMIT)
+ {
+ newState = STATE_SEND;
+ }
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doSend(const Event_t _evt)
+{
+
+ State_t newState = STATE_IDLE;
+ if (_evt == EVT_TICK)
+ {
+ m_I2C->write(m_Address,m_Message,m_TxFrameSize);
+ newState = STATE_RECEIVE_ACK;
+ }
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doReceive(const Event_t _evt)
+{
+ State_t newState = STATE_RECEIVE;
+ if (_evt == EVT_TICK)
+ {
+ // On Success get Length and send NACK
+ newState = STATE_CONTROL;
+ }
+
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doReceiveAck(const Event_t _evt)
+{
+
+ State_t newState = STATE_RECEIVE_ACK;
+ if (_evt == EVT_TICK)
+ {
+ if ( readAckFrame() )
+ {
+ // On Success get Length and send NACK
+ newState = STATE_RECEIVE_LENGTH;
+ }
+ }
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doReceiveLength(const Event_t _evt)
+{
+ State_t newState = STATE_RECEIVE_LENGTH;
+ if (_evt == EVT_TICK)
+ {
+ // On Success get length,
+ newState = STATE_RECEIVE;
+ }
+
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doCancel(const Event_t _evt)
+{
+ State_t newState = STATE_CANCEL;
+ if (_evt == EVT_TICK)
+ {
+ // On Success get length,
+ newState = STATE_IDLE;
+ }
+
+ return newState;
+}
+
+PN532InterfaceI2C::State_t
+PN532InterfaceI2C::doControl(const Event_t _evt)
+{
+ State_t newState = STATE_CONTROL;
+ if (_evt == EVT_TICK)
+ {
+ // On Success get length,
+ newState = STATE_IDLE;
+ }
+
+ return newState;
+}
+
+void PN532InterfaceI2C::updateState(const Event_t _evt)
+{
+ State_t oldState = m_CurrentState;
+ // Does work on AVR!?
+ static const PN532InterfaceI2C::pFunction_t laction[8] = {
+ &PN532InterfaceI2C::doInit
+ ,&PN532InterfaceI2C::doIdle
+ ,&PN532InterfaceI2C::doSend
+ ,&PN532InterfaceI2C::doReceive
+ ,&PN532InterfaceI2C::doReceiveAck
+ ,&PN532InterfaceI2C::doReceiveLength
+ ,&PN532InterfaceI2C::doCancel
+ ,&PN532InterfaceI2C::doControl
+ };
+
+ m_CurrentState = (this->*(laction[m_CurrentState]))(_evt);
+ if (m_CurrentState != oldState)
+ {
+ m_CurrentState = (this->*(laction[m_CurrentState]))(EVT_ENTRY);
+ }
+}
+
/* Seems that I2C max size is 32 bytes */
#define PN532_MESSAGE_SIZE 32
-class PN532InterfaceI2C : public IPN532Interface
+class PN532InterfaceI2C : public IPN532Interface , public IProtocolLayer2
{
+ enum State_t {
+ STATE_INIT = 0
+ , STATE_IDLE = 1
+ , STATE_SEND = 2
+ , STATE_RECEIVE = 3
+ , STATE_RECEIVE_ACK = 4
+ , STATE_RECEIVE_LENGTH = 5
+ , STATE_CANCEL = 6
+ , STATE_CONTROL = 7
+ };
+ enum Event_t { EVT_NONE,EVT_TICK,EVT_TRANSMIT,EVT_ENTRY};
+
+ enum Mode_t { MODE_RX, MODE_TX};
+
+ typedef State_t (PN532InterfaceI2C::*pFunction_t)(const Event_t);
private:
+ static Uint8_t m_Message[PN532_MESSAGE_SIZE];
II2C *m_I2C;
Uint8_t m_Address;
Uint8_t m_Command;
- static Uint8_t m_Message[PN532_MESSAGE_SIZE];
+ State_t m_CurrentState;
+ Uint16_t m_TxFrameSize;
+ Uint16_t m_TxByteCount;
+ Uint16_t m_RxFrameSize;
+ Uint16_t m_RxByteCount;
+
public:
PN532InterfaceI2C(II2C *m_i2c,Uint8_t address = PN532_I2C_ADDRESS);
* this method also stores the length to read
*/
Bool_t isReady() ;
+ /*
+ * *******************************************************************
+ * IProtocolLevel2 Interface
+ * Implement a state machine to handle requests properly
+ * *******************************************************************
+ */
+ virtual void init();
+
+ virtual const uint8_t getRxSize() const;
+ /**
+ * @return a pointer to the received message
+ * if no message is available, return NULL.
+ */
+ virtual const uint8_t *receiveMsg();
+
+ virtual void setTxMsg(const uint8_t *_src,uint8_t _length);
+ /**
+ * \bried transmit message stored in m_Buffer.
+ * The message must previously be set by
+ * setTxMsg()
+ */
+ virtual void transmitMsg();
+ /**
+ * @brief called by scheduler I think.
+ */
+ virtual void tick();
+
+ private:
+ void updateState(const Event_t _evt);
+ /* Actions .... */
+ State_t doInit(const Event_t _evt);
+ State_t doIdle(const Event_t _evt);
+ State_t doSend(const Event_t _evt);
+ State_t doReceive(const Event_t _evt);
+ State_t doReceiveAck(const Event_t _evt);
+ State_t doReceiveLength(const Event_t _evt);
+ State_t doCancel(const Event_t _evt);
+ State_t doControl(const Event_t _evt);
private:
Bool_t m_ReadReady;
Int16_t getResponseLength( Uint8_t *_buff
, Uint8_t len
, Uint16_t timeout);
-#if 0
- inline Uint8_t write(Uint8_t data)
- {
- return m_I2C->write(m_Address,&data,1);
- }
-
- inline Uint8_t read()
- {
- m_I2C->read(m_Address,&m_ReceiveByte,1);
- return m_ReceiveByte;
- }
-#endif
};
#endif