First Badge detection working
authorandre Ebersold <andre.ebersold@free.fr>
Sun, 12 Nov 2023 20:44:07 +0000 (21:44 +0100)
committerandre Ebersold <andre.ebersold@free.fr>
Sun, 12 Nov 2023 20:44:07 +0000 (21:44 +0100)
12 files changed:
Application/WorkhourMeter/CMakeLists.txt
Application/WorkhourMeter/WorkMeterHandler.cpp
Application/WorkhourMeter/main.cpp
HAL/Abstract/RFID/IPN532Interface.h
HAL/Drivers/PN532.cpp
HAL/Drivers/PN532.h
HAL/Drivers/PN532Interface_I2C.cpp
HAL/Drivers/PN532Interface_I2C.h
Metadata/WorkMeterParamIds.h
Platform/CMakeLists.txt
Platform/RFIDReader/RFIDReaderHandler.cpp [new file with mode: 0644]
Platform/RFIDReader/RFIDReaderHandler.h [new file with mode: 0644]

index 113c8a2208b284d14fd90b964a4a25ad12c6925b..705607d2fcd2000592330b379de27018d6b55718 100644 (file)
@@ -13,8 +13,8 @@ target_link_libraries(
   avrHAL-${AVR_MCU}
   avrDrivers-${AVR_MCU}
   avrComm-${AVR_MCU}
-  avrPS-Ptf-${AVR_MCU}
-  avrPowerswitchParameters-${AVR_MCU}
+  avrWM-Ptf-${AVR_MCU}
+  avrWorkMeterParameters-${AVR_MCU}
 )
 
 IF ( "${AVR_MCU}" STREQUAL "atmega328p")
index 2cf14c3a8e8468d0e4905a5cee5243bb1c421f9e..2648468a6bfcf49110ed175535bc0d091eadf185 100644 (file)
@@ -19,6 +19,7 @@ WorkMeterHandler::WorkMeterHandler(IRtc *argRtc,ILCD *argLCD,IParameterHandler *
     m_Params->writeValue(PID_Hour,i);
     m_Time.seconds = 10;
     m_Params->registerListener(PID_BackLight,this); /* State on or off */
+    m_Params->registerListener(PID_Display,this); /* State on or off */
 
     m_Params->registerListener(PID_Hour,this); /* State on or off */
     m_Params->registerListener(PID_Minute,this); /* State on or off */
@@ -43,6 +44,9 @@ void WorkMeterHandler::onWriteValue(const Uint8_t paramID,const Uint8_t _val)
         case PID_BackLight:
             m_LCD->setDisplay(_val);
         break;
+        case PID_Display:
+            m_LCD->setDisplay(_val);
+        break;
         default:
             ;
     }
@@ -106,7 +110,10 @@ void WorkMeterHandler::run()
             m_State = ST_DISP_UPDATE_TIME;
         break;
         case ST_DISP_UPDATE_TAG:
-            if (m_UidLength > 0) 
+        {
+             uint8_t  _present = 0; 
+             m_Params->readValue(PID_BadgePresent,_present);
+            if (_present> 0) 
             {
                 m_LCD->print(reinterpret_cast<const Uint8_t *>("1"));
             } else
@@ -114,6 +121,7 @@ void WorkMeterHandler::run()
                 m_LCD->print(reinterpret_cast<const Uint8_t *>("0"));
             }
             m_State = ST_WAIT;
+        }
         break;
         case ST_DISP_UPDATE_TIME:
             timeToString();
@@ -122,14 +130,8 @@ void WorkMeterHandler::run()
         break;
         case ST_WAIT_BADGE:
             /* 0 is fail :*/
-            m_UidLength =
-              m_NFC->readPassiveTargetID(PN532_MIFARE_ISO14443A,m_UID,&m_UidLength);
-            if (m_UidLength > 0)
-            {
-                m_State = ST_DISP_UPDATE_CURSOR_TAG;
-            } else
-                m_State = ST_DISP_UPDATE_CURSOR_TAG;
-                //m_State = ST_WAIT;
+            m_State = ST_DISP_UPDATE_CURSOR_TAG;
+            //m_State = ST_WAIT;
         break;
         case ST_WAIT:
             m_State = ST_WAIT;
index bb8252c4f6f422fc033ae1238497fcb46b137211..401ec4f85b35fe844917ae8fe90901bf5a686269 100644 (file)
@@ -24,8 +24,8 @@
 #include <AVR/AvrEeprom.h>
 #include <AVR/AvrI2C.h>
 #include <Platform/IParameterHandler.h>
-#include <Metadata/PowerswitchParamIds.h>
-#include <Platform/PowerswitchParameterHandler.h>
+#include <Metadata/WorkmeterParamIds.h>
+#include <Platform/ParameterHandler.h>
 #include <Platform/PersistentStorage.h>
 #include <Communication/CommunicationHandler.h>
 
@@ -35,6 +35,8 @@
 #include <Drivers/LiquidCrystal.h>
 #include <Drivers/PN532Interface_I2C.h>
 #include <Drivers/PN532.h>
+
+#include <Platform/RFIDReader/RFIDReaderHandler.h>
 #include "Led0.h"
 #include "WorkMeterHandler.h"
 #if 0
@@ -73,15 +75,19 @@ class Scheduler : public IInterruptActivity
 
       static Task_type gTasks[TASK_COUNT];
   public:
-    Scheduler(Led0 *_led,IProtocolLayer2 *_net,CommunicationHandler *_com,ITask *_argRtc
-                   ,ITask *_Storage
-                   )
+    Scheduler( Led0 *_led,IProtocolLayer2 *_net
+             , CommunicationHandler *_com
+             , ITask *_argRtc
+             , ITask *_Storage
+             , ITask *_RFIDReader
+             )
       : 
               m_Led(_led)
               , m_Netstring(_net)
               , m_Com(_com)
               , m_WorkMeter(_argRtc)
-             , m_Storage(_Storage)
+              , m_Storage(_Storage)
+              , m_RFIDReader(_RFIDReader)
               , m_CurrentTimeslot(FIRST_TIME_SLOT)
               , m_CurrentTask(TASK1)
     {
@@ -100,6 +106,7 @@ class Scheduler : public IInterruptActivity
             break;
             case TASK2:
                 m_Led->tick();
+                m_RFIDReader->run();
             break;
             case TASK3:
                 m_Led->tick();
@@ -140,6 +147,7 @@ class Scheduler : public IInterruptActivity
     CommunicationHandler   *m_Com;
     ITask                  *m_WorkMeter;
     ITask                  *m_Storage;
+    ITask                  *m_RFIDReader;
     volatile TIME_SLOTS     m_CurrentTimeslot;
     ETASK_ID                m_CurrentTask;
     RtcTime_t               m_Time;
@@ -166,7 +174,7 @@ void init(IParameterHandler *m_Param)
  */
 int main(void)
 {
-   PowerswitchParameterHandler gParam; 
+   ParameterHandler gParam; 
 #if defined (__AVR_ATmega32U4__)
    Led0                 led(&PORTC, &DDRC, PINB7,&gParam);
 #else
@@ -185,8 +193,15 @@ int main(void)
    NetString            netstring(&uart);
    CommunicationHandler gCom(&netstring,&gParam);
    PersistentStorage    gStorage(&gEeprom,&gParam);
+   RFIDReaderHandler    gRFIDReader(&nfc,&gParam);
    WorkMeterHandler     gWorkMeter(&gRtc,&lcd,&gParam,&nfc);
-   Scheduler            sched(&led,&netstring,&gCom,&gWorkMeter,&gStorage);
+   Scheduler            sched( &led
+                             , &netstring
+                             , &gCom
+                             , &gWorkMeter
+                             , &gStorage
+                             , &gRFIDReader
+                             );
    Uint8_t  msg[15] ; 
    uart.init();
    gI2c.init();
@@ -210,7 +225,7 @@ int main(void)
    msg[0]= static_cast<Uint8_t >( (ver >>16 & 0xFF)  + 48 );
    msg[1]= static_cast<Uint8_t >( (ver  >>8 & 0xFF ) + 48 );
    lcd.print(msg);
-   nfc.setPassiveActivationRetries(0xFF);
+   nfc.setPassiveActivationRetries(0x01);
    nfc.SAMConfig();
    lTimer.init();
    init(&gParam);
index b26ca2baba9197e29be9d2dc0044b1920795a864..4daed1fbd179fdd31c9a627b947f578d5de1f9de 100644 (file)
@@ -37,6 +37,13 @@ class IPN532Interface
          *
          */
         virtual void wakeup() = 0;
+        /**
+         * \brief before reading a response, the caller must
+         * check if a response is ready or else, he needs to 
+         * wait and check later
+         *
+         */
+        virtual Bool_t isReady() = 0;
         /**
          *
          */
@@ -50,7 +57,7 @@ class IPN532Interface
          */
         virtual Int16_t readResponse( Uint8_t *buf
                                     , Uint8_t len
-                                    , Uint8_t timeout = 100) = 0;
+                                    , Uint16_t timeout = 100) = 0;
 
 
 };
index b1dca1bc5b84306c6991d4768bb1d253fb84bd31..e49c706110ca02f6c900474fcb32a56b1c4007e9 100644 (file)
@@ -106,3 +106,42 @@ Bool_t PN532::setPassiveActivationRetries(Uint8_t _retries)
     }
     return ( 0 < ITF(readResponse)(m_PacketBuffer,sizeof(m_PacketBuffer)));
 }
+
+
+Bool_t PN532::reqPassiveTargetID(Uint8_t _type)
+{
+    m_PacketBuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
+    m_PacketBuffer[1] = 0x01; // normal mode
+    m_PacketBuffer[2] = _type;
+    
+    if (ITF(writeCommand)(m_PacketBuffer,3))
+    {
+       return false; // command failed
+    }
+    return true;
+}
+
+Bool_t PN532::processPassiveTargetID( Uint8_t *uid,Uint8_t *uidLength)
+{
+    // read response
+    if (ITF(readResponse)(m_PacketBuffer,sizeof(m_PacketBuffer)) < 0)
+    {
+       return 0; // command failed
+    }
+    /**
+     * Ok analyse the response 
+     */
+    if ( m_PacketBuffer[0] != 1)
+    {
+       return 0; //Tag not found
+    }
+
+    *uidLength  = m_PacketBuffer[5];
+
+    for (Uint8_t i = 0 ; (i < *uidLength) || (i < 7) ; i++)
+    {
+       uid[i] = m_PacketBuffer[6 + i];
+    }
+    return 1;
+}
+
index 262954a567cce4ab1e9518506f20184552af0c19..52b55c688872b6352b6224d2678b9c45132116e2 100644 (file)
@@ -123,6 +123,8 @@ class PN532
         IPN532Interface *m_Itf;
     public:
         PN532(IPN532Interface *itf); // Default contructor Needs in Interface
+        
+        inline Bool_t isReady() { return m_Itf->isReady(); };
 
         void begin();
 
@@ -134,9 +136,15 @@ class PN532
 
         Bool_t readPassiveTargetID(Uint8_t _type,Uint8_t *uid,Uint8_t *uidLength);
         
+        /**
+         * Req / process based not using internal wait delay
+         */
+        Bool_t reqPassiveTargetID(Uint8_t _type);
+
+        Bool_t processPassiveTargetID( Uint8_t *uid,Uint8_t *uidLength);
     private:
         Uint8_t m_PacketBuffer[64]; // For low level exchanges
-        Uint8_t m_UID[7]; // ISO14443A uid
+        Uint8_t m_UID[9]; // ISO14443A uid
         Uint8_t m_UIDLength;
 
 
index 79a6f3445caf6451f62c52e50a683ee2a6a541df..ae5a458b4726cf460ebbb64e336a6d193f256239 100644 (file)
@@ -12,6 +12,7 @@ Uint8_t PN532InterfaceI2C::m_Message[PN532_MESSAGE_SIZE] = {0};
 PN532InterfaceI2C::PN532InterfaceI2C(II2C *_i2c,Uint8_t _address)
     : m_I2C(_i2c), m_Address(_address)
 {
+    m_ReadReady = false;
 }
 
 
@@ -70,18 +71,38 @@ Int8_t PN532InterfaceI2C::writeCommand( const Uint8_t *header
     return readAckFrame();
 }
 
+/**
+ *
+ */
+Bool_t PN532InterfaceI2C::isReady()
+{
+    m_I2C->read(m_Address,m_Message,6);
+    if (m_Message[0] & 0x01)
+    {
+        m_ReadReady = true;
+    }
+    return m_ReadReady;
+}
+
+
 /**
  *
  */
 Int16_t PN532InterfaceI2C::readResponse(Uint8_t *buf
                                        ,Uint8_t len
-                                       ,Uint8_t timeout)
+                                       ,Uint16_t timeout)
 {
     Uint8_t _count = 0;
-    Uint8_t length = getResponseLength(buf,len,timeout);
+    Uint16_t ResponseLength = getResponseLength(buf,len,timeout);
     /* Error don't continue */
-    if (length < 0)
-        return length;
+    if (ResponseLength < 0)
+        return ResponseLength;
+    Uint8_t length = static_cast<Uint8_t>(ResponseLength);
+   
+    if ( PN532_MESSAGE_SIZE < (length + 8))
+    {
+        return PN532_NO_SPACE; 
+    }
 
     do 
     {
@@ -92,7 +113,7 @@ Int16_t PN532InterfaceI2C::readResponse(Uint8_t *buf
             break; // Ok, got frame ready
         }
         timeout--;
-        _delay_ms(1);
+        _delay_us(100);
     } while (timeout);
     /**/
     if (!timeout)
@@ -137,6 +158,7 @@ Int8_t  PN532InterfaceI2C::readAckFrame()
 {
     const Uint8_t PN532_ACK[] = {0, 0, 0xFF, 0 , 0xFF, 0};
     Uint16_t timeout = PN532_ACK_WAIT_TIME;
+    
     do 
     {
         m_I2C->read(m_Address,m_Message,sizeof(PN532_ACK) + 1);
@@ -148,6 +170,7 @@ Int8_t  PN532InterfaceI2C::readAckFrame()
         _delay_ms(1);
     } while (timeout > 0);
     /* If Succeed compare result */
+    m_ReadReady = false;
     if (memcmp(&m_Message[1],PN532_ACK,sizeof(PN532_ACK)))
     {
         return PN532_INVALID_ACK;
@@ -164,17 +187,19 @@ Int16_t  PN532InterfaceI2C::getResponseLength( Uint8_t *_buff
                                   , Uint16_t timeout)
 {
     Uint8_t PN532_NACK[] = {0,0,0xFF,0xFf,0,0};
-
-    do 
+    /* In case we already wait we don't retry */
+    if (!m_ReadReady)
     {
-        m_I2C->read(m_Address,m_Message,6);
-        if (m_Message[0] & 0x01)
+        do 
         {
-            break;
-        }
-        timeout--;
-        _delay_ms(1);
-    } while(timeout);
+            if (isReady())
+            {
+                break;
+            }
+            timeout--;
+            _delay_ms(1);
+        } while(timeout);
+    }
 
     if (memcmp(&m_Message[1],PN532_NACK,3))
     {
@@ -183,7 +208,7 @@ Int16_t  PN532InterfaceI2C::getResponseLength( Uint8_t *_buff
     Uint8_t  length = m_Message[4];
     /* Send NACK */
     m_I2C->write(m_Address,PN532_NACK,static_cast<Uint8_t>(sizeof(PN532_NACK)));
-
+    m_ReadReady = false;
     return length;
 }
 
index 45ebd6721fc0e166037449613b0d209b2168a7a7..f30eaa7f6f4ccec13372afe427b7efa351b762f9 100644 (file)
@@ -5,6 +5,7 @@
 /* Let's see if max header 11 + 21 data is enough */
 /* Seems that I2C max size is 32 bytes            */
 #define PN532_MESSAGE_SIZE 32
+
 class PN532InterfaceI2C : public IPN532Interface
 {
     private:
@@ -24,17 +25,23 @@ class PN532InterfaceI2C : public IPN532Interface
                            , Uint8_t *body = 0
                            , Uint8_t blen  = 0);
 
-        Int16_t readResponse(Uint8_t *buf,Uint8_t len,Uint8_t timeout);
+        Int16_t readResponse(Uint8_t *buf,Uint8_t len,Uint16_t timeout);
+        
+        /**
+         * In addition to check if a response is ready,
+         * this method also stores the length to read
+         */
+        Bool_t isReady() ;
 
     private:
-        Uint8_t m_ReceiveByte;
+        Bool_t m_ReadReady;
     private:
         Int8_t   readAckFrame();
         
         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);
@@ -45,6 +52,7 @@ class PN532InterfaceI2C : public IPN532Interface
             m_I2C->read(m_Address,&m_ReceiveByte,1);
             return m_ReceiveByte;
         }
+#endif
 
 };
 #endif
index 42c9594bd210f68e1f6639930db9e8026dbff46c..bd3b707218478d578a213aab2c13914400aa2dd9 100644 (file)
@@ -15,10 +15,10 @@ enum ParameterIds {
     , PID_LedCycle   =  5 /* Ye Blinking led cycle. 0 is off */
     , PID_LedState   =  6 /* Set let state ... */
     , PID_Display    =  7 /* Set On/Off Display */
-    , PID_DelayP2    =  8
-    , PID_DelayP3    =  9 /* Cycle Per rotation used in closed loop  */
-    , PID_DelayP4    = 10 /* Set PID constant factor   */
-    , PID_Ki         = 11 /* Set PID integral factor   */
+    , PID_RFFirmwareVersion  =  8
+    , PID_FirmwareVersion    =  9 /* Cycle Per rotation used in closed loop  */
+    , PID_BadgePresent       = 10 /* Set PID constant factor   */
+    , PID_BadgeCount         = 11 /* Set PID integral factor   */
     , PID_Kd         = 12 /* Set PID derivation factor */
     , PID_MAConsPwm  = 13 /* Pwm modulation instruction, Applied in open loop, ignore in closed loop */
     , PID_MAConsRpm  = 14 /* Rpm instruction used as reference in closed loop */
index 283bf362cf1017cde0ff665cff4c926364f9ceba..3b9d0e22f8f4125e3e04089c04122193fbea9d7b 100644 (file)
@@ -46,6 +46,7 @@ add_avr_library(
     avrWM-Ptf
     ParameterHandler.cpp
     PersistentStorage.cpp
+    RFIDReader/RFIDReaderHandler.cpp
    )
 
 set_target_properties(
diff --git a/Platform/RFIDReader/RFIDReaderHandler.cpp b/Platform/RFIDReader/RFIDReaderHandler.cpp
new file mode 100644 (file)
index 0000000..ef992ab
--- /dev/null
@@ -0,0 +1,126 @@
+#include "Utils/StdTypes.h"
+#include "Application/ITask.h"
+#include "Abstract/RFID/IPN532Interface.h"
+#include "HAL/Drivers/PN532.h"
+#include "Platform/IParameterHandler.h"
+
+#include "Metadata/WorkmeterParamIds.h"
+#include "Platform/RFIDReader/RFIDReaderHandler.h"
+
+
+
+
+
+RFIDReaderHandler::RFIDReaderHandler(PN532 *argNFC,IParameterHandler *argParam)
+  : m_NFC(argNFC), m_Param(argParam),m_State(ST_IDLE)
+{
+}
+
+void RFIDReaderHandler::run()
+{
+    if (m_Ticks++ > 100)
+    {
+        m_Ticks = 0;
+        m_State = ST_IDLE;
+    }
+    doStateMachine();
+}
+
+void RFIDReaderHandler::doStateMachine()
+{
+    switch (m_State)
+    {
+       case ST_IDLE:
+       { // Check if 
+           //m_State = ST_DISP_OFF;
+           m_State = ST_REQ_BADGE_ID;
+       }
+       break;
+       case ST_REQ_FIRMWAREVERSION:
+       break;
+       case ST_REQ_BADGE_ID:
+       doRequestBadgeID();
+       
+       m_CurrentRequest = ST_PROCESS_BADGE_ID;
+       m_State = ST_PROCESS_BADGE_ID;
+       break;
+       case ST_PROCESS_BADGE_ID:
+       if (m_NFC->isReady())
+       {
+           doProcessBadgeID();
+           m_State = ST_DISP_ON; // Do nothing
+       } else 
+       {
+           m_1Milli = 10;
+           m_State  = ST_WAIT_RESPONSE;
+       }
+       break;
+       case ST_PROCESS_FIRMWAREVERSION:
+       break;
+       case ST_DISP_ON:
+           doDisplay(false);
+           m_State = ST_WAIT_BADGE; // Do nothing
+       break;
+       case ST_DISP_OFF:
+           doDisplay(true);
+           m_1Milli = 10;
+           m_State  = ST_WAIT_RESPONSE;
+           m_CurrentRequest = ST_REQ_BADGE_ID;
+       break;
+       case ST_WAIT_BADGE:
+       break;
+       case ST_WAIT_RESPONSE:
+       {
+           // Check if I get a ready response
+           // If not go to state 
+           doDelay1Milli();
+       }
+       break;
+       case ST_DELAY_1MILLI:
+       {
+           if (! (m_1Milli--) )
+               m_State = ST_WAIT_RESPONSE;
+       }
+       break;
+       default:
+       ;
+    }
+}
+
+void RFIDReaderHandler::doRequestFirmwareVersion()
+{
+}
+
+void RFIDReaderHandler::doRequestBadgeID()
+{
+     m_NFC->reqPassiveTargetID(PN532_MIFARE_ISO14443A);
+
+}
+
+void RFIDReaderHandler::doDelay1Milli()
+{
+    if ( ! m_1Milli--)
+    {
+        m_State = m_CurrentRequest;
+    }
+}
+
+
+void RFIDReaderHandler::doProcessFirmwareVersion()
+{
+}
+
+void RFIDReaderHandler::doProcessBadgeID()
+{
+     Uint8_t Uid[9];
+     Uint8_t UidLength = 0;
+     m_NFC->processPassiveTargetID(Uid,&UidLength);
+     m_Param->writeValue(PID_BadgePresent,UidLength);
+     Uint8_t disp = 0;
+     m_Param->writeValue(PID_Display,disp);
+}
+
+void RFIDReaderHandler::doDisplay(Uint8_t _on)
+{
+     m_Param->writeValue(PID_Display,_on);
+}
diff --git a/Platform/RFIDReader/RFIDReaderHandler.h b/Platform/RFIDReader/RFIDReaderHandler.h
new file mode 100644 (file)
index 0000000..9326d96
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __RFIDREADERHANDLER_H__
+#define __RFIDREADERHANDLER_H__
+
+#define RFID_TICKS_1MILLI  10
+#define RFID_TICKS_10MILLI 100
+
+class RFIDReaderHandler : public ITask
+{
+    enum eStates {
+      ST_IDLE
+      ,ST_REQ_FIRMWAREVERSION
+      ,ST_REQ_BADGE_ID
+      ,ST_PROCESS_BADGE_ID
+      ,ST_PROCESS_FIRMWAREVERSION
+      ,ST_DISP_OFF
+      ,ST_DISP_ON
+      ,ST_WAIT_BADGE
+      ,ST_WAIT_RESPONSE
+      ,ST_DELAY_1MILLI
+    };
+    public:
+        RFIDReaderHandler(PN532 *argNFC,IParameterHandler *argParam);
+        void run();
+    private:
+        void doStateMachine();
+        void doRequestFirmwareVersion();
+        void doRequestBadgeID();
+        void doProcessFirmwareVersion();
+        void doProcessBadgeID();
+        void doDelay1Milli();
+        void doDisplay(Uint8_t _on);
+    private:
+        PN532             *m_NFC;
+        IParameterHandler *m_Param;
+        Uint8_t            m_State;
+        Uint8_t            m_1Milli;
+        Uint8_t            m_CurrentRequest;
+        Uint16_t           m_Ticks; // Count 100us ticks
+};
+#endif