From 609ca42ded9ecc0184ba597fdddf2bddffbe8693 Mon Sep 17 00:00:00 2001 From: andre Ebersold Date: Tue, 14 Nov 2023 23:30:33 +0100 Subject: [PATCH] Started New implementation for PN532. Still block when I2C fails. Need a way out --- HAL/Drivers/PN532.cpp | 25 ++++ HAL/Drivers/PN532.h | 4 + HAL/Drivers/PN532Interface_I2C.cpp | 178 ++++++++++++++++++++++++++++- HAL/Drivers/PN532Interface_I2C.h | 75 +++++++++--- 4 files changed, 267 insertions(+), 15 deletions(-) diff --git a/HAL/Drivers/PN532.cpp b/HAL/Drivers/PN532.cpp index e809eb4..349e988 100644 --- a/HAL/Drivers/PN532.cpp +++ b/HAL/Drivers/PN532.cpp @@ -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 diff --git a/HAL/Drivers/PN532.h b/HAL/Drivers/PN532.h index 52b55c6..d533727 100644 --- a/HAL/Drivers/PN532.h +++ b/HAL/Drivers/PN532.h @@ -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: diff --git a/HAL/Drivers/PN532Interface_I2C.cpp b/HAL/Drivers/PN532Interface_I2C.cpp index 988bcd2..9f41c1e 100644 --- a/HAL/Drivers/PN532Interface_I2C.cpp +++ b/HAL/Drivers/PN532Interface_I2C.cpp @@ -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); + } +} + diff --git a/HAL/Drivers/PN532Interface_I2C.h b/HAL/Drivers/PN532Interface_I2C.h index f30eaa7..f58662b 100644 --- a/HAL/Drivers/PN532Interface_I2C.h +++ b/HAL/Drivers/PN532Interface_I2C.h @@ -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 -- 2.30.2