Started New implementation for PN532. Still block when I2C fails. Need a way out
authorandre Ebersold <andre.ebersold@free.fr>
Tue, 14 Nov 2023 22:30:33 +0000 (23:30 +0100)
committerandre Ebersold <andre.ebersold@free.fr>
Tue, 14 Nov 2023 22:30:33 +0000 (23:30 +0100)
HAL/Drivers/PN532.cpp
HAL/Drivers/PN532.h
HAL/Drivers/PN532Interface_I2C.cpp
HAL/Drivers/PN532Interface_I2C.h

index e809eb42710dab89beae85c22aca443048cdfdee..349e988513b45d60162365c50fd9e53a40062561 100644 (file)
@@ -121,6 +121,31 @@ Bool_t PN532::reqPassiveTargetID(Uint8_t _type)
     return true;
 }
 
+Bool_t PN532::reqFirmwareVersion()
+{
+    m_PacketBuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
+    Int8_t res = (ITF(writeCommand)(m_PacketBuffer,1));
+    if (res)
+    {
+       return false;
+    }
+    return true;
+}
+
+Bool_t PN532::reqSAMConfig()
+{
+    m_PacketBuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
+    m_PacketBuffer[1] = 0x01; // normal mode
+    m_PacketBuffer[2] = 0x14; // timeout 50ms * 20 = 1 second ?
+    m_PacketBuffer[4] = 0x01; // use IRQ pin ?
+
+    if (ITF(writeCommand)(m_PacketBuffer,4))
+    {
+       return false;
+    }
+    return true;
+}
+
 Bool_t PN532::processPassiveTargetID( Uint8_t *uid,Uint8_t *uidLength)
 {
     // read response
index 52b55c688872b6352b6224d2678b9c45132116e2..d533727348b4f813ebe8ed2aaa6632e4fc90824c 100644 (file)
@@ -140,6 +140,10 @@ class PN532
          * Req / process based not using internal wait delay
          */
         Bool_t reqPassiveTargetID(Uint8_t _type);
+        
+        Bool_t reqFirmwareVersion();
+        
+        Bool_t reqSAMConfig();
 
         Bool_t processPassiveTargetID( Uint8_t *uid,Uint8_t *uidLength);
     private:
index 988bcd2c7b618a266d72a74c5f15735892b8e717..9f41c1e6db968f0d3a4e41aae810b9209558474e 100644 (file)
@@ -5,12 +5,15 @@
 //
 #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;
 }
@@ -67,6 +70,7 @@ Int8_t PN532InterfaceI2C::writeCommand( const Uint8_t *header
     {
         return PN532_INVALID_FRAME;
     }
+    m_TxFrameSize = _count;
     m_I2C->write(m_Address,m_Message,_count );
     return readAckFrame();
 }
@@ -212,3 +216,175 @@ Int16_t  PN532InterfaceI2C::getResponseLength( Uint8_t *_buff
     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);
+  }
+}
+
index f30eaa7f6f4ccec13372afe427b7efa351b762f9..f58662b8c9b3fda62fb3a8e752eacc235fb1de4f 100644 (file)
@@ -6,13 +6,34 @@
 /* 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);
 
@@ -32,6 +53,44 @@ class PN532InterfaceI2C : public IPN532Interface
          * 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;
@@ -41,18 +100,6 @@ class PN532InterfaceI2C : public IPN532Interface
         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