#include "Application/ITask.h"
#include "Abstract/IRtc.h"
#include "Abstract/ILCD.h"
+#include "Abstract/RFID/IPN532Interface.h"
+#include "HAL/Drivers/PN532.h"
#include "Platform/IParameterHandler.h"
#include "Metadata/WorkmeterParamIds.h"
#include "WorkMeterHandler.h"
-WorkMeterHandler::WorkMeterHandler(IRtc *argRtc,ILCD *argLCD,IParameterHandler *argPH)
- : m_Rtc(argRtc), m_LCD(argLCD),m_Params(argPH),m_Ticks(0)
+WorkMeterHandler::WorkMeterHandler(IRtc *argRtc,ILCD *argLCD,IParameterHandler *argPH,PN532 *argPN532)
+ : m_Rtc(argRtc), m_LCD(argLCD),m_NFC(argPN532),m_Params(argPH),m_Ticks(0),m_State(ST_IDLE)
{
Uint8_t i = 0;
m_Params->writeValue(PID_Seconde,i);
m_Params->writeValue(PID_Hour,i);
m_Time.seconds = 10;
m_Params->registerListener(PID_BackLight,this); /* State on or off */
-#if 1
+
m_Params->registerListener(PID_Hour,this); /* State on or off */
m_Params->registerListener(PID_Minute,this); /* State on or off */
-#endif
+
}
void WorkMeterHandler::onWriteValue(const Uint8_t paramID,const Uint8_t _val)
switch (paramID)
{
case PID_Seconde:
- m_Time.seconds = _val;
+ m_Time.seconds = _val;
break;
case PID_Minute:
- m_Time.min = _val;
- //m_Rtc->setTime(m_Time);
+ m_Time.min = _val;
+ m_State = ST_SET_TIME;
break;
case PID_Hour:
- m_Time.hour = _val;
- //m_Rtc->setTime(m_Time);
+ m_Time.hour = _val;
+ m_State = ST_SET_TIME;
break;
case PID_BackLight:
m_LCD->setDisplay(_val);
break;
- default:
- ;
+ default:
+ ;
}
}
m_StrTime[7] = ((m_Time.seconds) -( (m_Time.seconds / 10) *10 )) + 0x30;
m_StrTime[8] = 0;
}
+
+void WorkMeterHandler::getTime()
+{
+ m_Rtc->getTime(m_Time);
+ m_Params->writeValue(PID_Seconde,m_Time.seconds);
+ m_Params->writeValue(PID_Minute,m_Time.min);
+ m_Params->writeValue(PID_Hour,m_Time.hour);
+}
+/**/
+void WorkMeterHandler::setTime()
+{
+}
void WorkMeterHandler::run()
{
if (m_Ticks++ > 100)
{
- m_Rtc->getTime(m_Time);
- m_Params->writeValue(PID_Seconde,m_Time.seconds);
- m_Params->writeValue(PID_Minute,m_Time.min);
- m_Params->writeValue(PID_Hour,m_Time.hour);
m_Ticks = 0;
+ m_State = ST_IDLE;
}
- switch (m_Ticks)
+ switch (m_State)
{
- case 8:
+ case ST_IDLE:
+ m_State = ST_GET_TIME;
+ break;
+ case ST_SET_TIME:
+ m_Rtc->setTime(m_Time);
+ m_State = ST_WAIT;
+ break;
+ case ST_GET_TIME:
+ getTime();
+ m_State = ST_DISP_UPDATE_CURSOR;
+ break;
+ case ST_DISP_UPDATE_CURSOR_TAG:
+ m_LCD->setCursor(11,0);
+ m_State = ST_DISP_UPDATE_TAG;
+ break;
+ case ST_DISP_UPDATE_CURSOR:
+ m_LCD->setCursor(4,1);
+ m_State = ST_DISP_UPDATE_TIME;
+ break;
+ case ST_DISP_UPDATE_TAG:
+ if (m_UidLength > 0)
+ {
+ m_LCD->print(reinterpret_cast<const Uint8_t *>("1"));
+ } else
+ {
+ m_LCD->print(reinterpret_cast<const Uint8_t *>("0"));
+ }
+ m_State = ST_WAIT;
+ break;
+ case ST_DISP_UPDATE_TIME:
timeToString();
- break;
- case 10:
- m_LCD->setCursor(4,6);
- //m_LCD->setCursor(6,0);
- break;
- case 25:
m_LCD->print(m_StrTime);
- break;
+ m_State = ST_WAIT_BADGE;
+ 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;
+ break;
+ case ST_WAIT:
+ m_State = ST_WAIT;
+ break;
};
}
class WorkMeterHandler : public ITask, public IParameterListener
{
+ enum eStates {
+ ST_IDLE
+ ,ST_GET_TIME
+ ,ST_SET_TIME
+ ,ST_WAIT_BADGE
+ ,ST_WAIT
+ ,ST_DISP_UPDATE_TIME
+ ,ST_DISP_UPDATE_TAG
+ ,ST_DISP_UPDATE_CURSOR
+ ,ST_DISP_UPDATE_CURSOR_TAG
+ ,ST_DISP_VISIBILITY
+ };
public:
- WorkMeterHandler(IRtc *argRTC,ILCD *argLCD,IParameterHandler *argPH);
+ WorkMeterHandler(IRtc *argRTC,ILCD *argLCD,IParameterHandler *argPH,PN532 *argPN532);
void run();
void onWriteValue(const Uint8_t paramID,const Float32_t _val) ;
private:
- void timeToString();
+ void timeToString();
+ /**/
+ void getTime();
+ /**/
+ void setTime();
private:
- Uint8_t m_StrTime[9];
- IRtc *m_Rtc;
- ILCD *m_LCD;
+ Uint8_t m_StrTime[9];
+ Uint8_t m_UID[7];
+ Uint8_t m_UidLength;
+ IRtc *m_Rtc;
+ ILCD *m_LCD;
+ PN532 *m_NFC;
IParameterHandler *m_Params;
RtcTime_t m_Time;
Uint32_t m_Ticks;
+ Uint8_t m_State;
};
#endif
#include <Abstract/IRtc.h>
#include <Abstract/ILCD.h>
#include <Abstract/ISwitch.h>
+#include "Abstract/RFID/IPN532Interface.h"
#include <Abstract/IEeprom.h>
#include <Application/ITask.h>
#include <AVR/AvrTimer0.h>
#include <Drivers/NetString.h>
#include <Drivers/DS3231.h>
#include <Drivers/LiquidCrystal.h>
+#include <Drivers/PN532Interface_I2C.h>
+#include <Drivers/PN532.h>
#include "Led0.h"
#include "WorkMeterHandler.h"
#if 0
switch (m_CurrentTask)
{
case TASK1:
- //m_Adc->run();
- m_WorkMeter->run();
+ //m_Adc->run();
+ m_WorkMeter->run();
//m_Led->tick();
break;
case TASK2:
break;
case TASK3:
m_Led->tick();
- m_Storage->run();
+ m_Storage->run();
break;
default:
;
AvrI2C gI2c;
DS3231 gRtc(&gI2c);
LiquidCrystal lcd(&gI2c
- ,static_cast<Uint8_t>(0x4E)
- ,static_cast<Uint8_t>(16)
- ,static_cast<Uint8_t>(2));
+ ,static_cast<Uint8_t>(0x4E)
+ ,static_cast<Uint8_t>(16)
+ ,static_cast<Uint8_t>(2));
+ PN532InterfaceI2C gPN532If(&gI2c);
+ PN532 nfc(&gPN532If);
AvrEeprom gEeprom;
NetString netstring(&uart);
CommunicationHandler gCom(&netstring,&gParam);
PersistentStorage gStorage(&gEeprom,&gParam);
- WorkMeterHandler gWorkMeter(&gRtc,&lcd,&gParam);
+ WorkMeterHandler gWorkMeter(&gRtc,&lcd,&gParam,&nfc);
Scheduler sched(&led,&netstring,&gCom,&gWorkMeter,&gStorage);
-
+ Uint8_t msg[15] ;
uart.init();
gI2c.init();
netstring.init();
_delay_ms(300);
led.off();
_delay_ms(300);
-
+ nfc.begin();
+ lcd.setCursor(0,1);
+ Uint32_t ver = nfc.getFirmwareVersion();
+ //Uint32_t ver = 13;
+ msg[0]= static_cast<Uint8_t >(((ver >>24) & 0xFF) / 10 + 48 );
+ msg[1]= static_cast<Uint8_t >((ver>>24) - ( (( (ver >>24) & 0xFF) / 10) * 10 ) + 48 );
+ msg[2] = 0;
+ lcd.print(msg);
+ lcd.setCursor(14,1);
+ 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.SAMConfig();
lTimer.init();
init(&gParam);
gEeprom.init();
+ gRtc.init();
while(1)
{
sched.schedule();
//PORTC &= ~((1<<TW_SDA_PIN) | (1 <<TW_SCL_PIN));
DDRC &= ~((1<<TW_SDA_PIN) | (1 <<TW_SCL_PIN));
- //TWCR = (1<<(TWINT))|(1<<TWSTA )|(1<<TWEN);
-
-#if 0
- printf("TWCR 0x%x \n",TWCR);
-#endif
- //while( !( TWCR & (1<< TWINT) ) ) ;
-#if 0
- printf(" Start condition has been transmitted \n");
- if( (TWSR&0xF8) != TW_START)
- {
-
- printf(" Error \n");
- }
-#endif
-#if 0
- // Setting Address
- TWDR = 0x1C;
- // cleating TWCR
- TWCR = (1<<TWINT) |(1<<TWEN);
-
- while ( !(TWCR & (1<<TWINT))) ;
-#endif
-#if 0
- if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
- {
- printf(" Error at TWSR 0x%x\n", TWSR); // here is the problem !!!!!!!!! TWSR value should be 0x18
- return;
- }
-#endif
}
II2C::Error_t AvrI2C::write(const Uint8_t argAddress,Uint8_t *argData,Uint8_t argLen)
II2C::Error_t AvrI2C::read(const Uint8_t argAddress,Uint8_t *argData,Uint8_t argLen)
{
if ( ! start() )
+ {
+ stop();
return I2C_ERROR;
-
+ }
if ( ! sendSla( (argAddress | 1 ) ) )
+ {
+ stop();
return I2C_ERROR;
+ }
for (Uint8_t i = 0; i < argLen -1 ; ++i)
{
if ( ! receiveByte(&argData[i],true) )
+ {
+ stop();
return I2C_ERROR;
+ }
}
if ( ! receiveByte(&argData[argLen-1],false) )
+ {
+ stop();
return I2C_ERROR;
+ }
stop();
return I2C_SUCCESS;
virtual Error_t read(const Uint8_t argAddress,Uint8_t *argData ,Uint8_t argLen) = 0;
virtual Error_t read( const Uint8_t argAddress
- , const Uint8_t regAddr
- , Uint8_t *argData
- , Uint8_t argLen) = 0;
+ , const Uint8_t regAddr
+ , Uint8_t *argData
+ , Uint8_t argLen) = 0;
};
#endif
--- /dev/null
+#ifndef __IPN532Interface_H__
+#define __IPN532Interface_H__
+
+#define PN532_PREAMBLE (0x00)
+#define PN532_STARTCODE1 (0x00)
+#define PN532_STARTCODE2 (0xFF)
+#define PN532_POSTAMBLE (0x00)
+
+#define PN532_HOSTTOPN532 (0xD4)
+#define PN532_PN532TOHOST (0xD5)
+
+#define PN532_ACK_WAIT_TIME (10) // ms, timeout of waiting for ACK
+
+#define PN532_INVALID_ACK (-1)
+#define PN532_TIMEOUT (-2)
+#define PN532_INVALID_FRAME (-3)
+#define PN532_NO_SPACE (-4)
+#define PN532_INVALID_FRAME2 (-5)
+#define PN532_INVALID_FRAME3 (-6)
+#define PN532_INVALID_FRAME4 (-7)
+#define PN532_INVALID_FRAME5 (-8)
+
+#define REVERSE_BITS_ORDER(b) b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; \
+ b = (b & 0xCC) >> 2 | (b & 0x33) << 2; \
+ b = (b & 0xAA) >> 1 | (b & 0x55) << 1
+
+class IPN532Interface
+{
+ public:
+ IPN532Interface() {};
+ /**
+ *
+ */
+ virtual void begin() = 0;
+
+ /**
+ *
+ */
+ virtual void wakeup() = 0;
+ /**
+ *
+ */
+ virtual Int8_t writeCommand( const Uint8_t *header
+ , Uint8_t len
+ , Uint8_t *body = 0
+ , Uint8_t blen = 0) = 0;
+
+ /**
+ *
+ */
+ virtual Int16_t readResponse( Uint8_t *buf
+ , Uint8_t len
+ , Uint8_t timeout = 100) = 0;
+
+
+};
+
+#endif
DS3231.cpp
XPT2046_Touchscreen.cpp
LiquidCrystal.cpp
+ PN532Interface_I2C.cpp
+ PN532.cpp
)
{
}
+void DS3231::init()
+{
+ Uint8_t cmd[4];
+ cmd[0] = 0x0E;
+ Bool_t success = itsII2C->read(DS3231_ADDRESS,cmd[0],&cmd[1],2);
+ if (success)
+ {
+ if ((cmd[1] & 0x80 ) || (cmd[2] & 0x80))
+ {
+ cmd[1] &= 0x7F;
+ itsII2C->write(DS3231_ADDRESS,cmd,2);
+ }
+ }
+#if 0
+ else
+#endif
+ {
+ cmd[1] = 0x00;
+ cmd[2] = 0x00;
+ itsII2C->write(DS3231_ADDRESS,cmd,3);
+ }
+}
void DS3231::getTime(RtcTime_t &argTime)
{
Uint8_t cmd[9] ;
- cmd[0] = 0x00; cmd[1] = 128;
+ cmd[0] = 0x00;
#if 1
Bool_t success = itsII2C->read(DS3231_ADDRESS,cmd[0],&cmd[1],8);
Uint8_t cmd[5] ;
cmd[0] = 0x00;
cmd[1] = (argTime.seconds / 10)<<4;
- cmd[1] |= (argTime.seconds - (argTime.seconds/10));
+ cmd[1] |= (argTime.seconds - (argTime.seconds/10) * 10 );
// Set Minutes
cmd[2] = (argTime.min / 10)<<4;
- cmd[2] |= (argTime.min - (argTime.min/10) );
+ cmd[2] |= (argTime.min - (argTime.min/10) * 10 );
// Hours
cmd[3] = (argTime.hour / 10)<<4;
- cmd[3] |= ( argTime.hour - (argTime.hour/10) ) | 0x40;
+ cmd[3] |= ( argTime.hour - (argTime.hour/10) * 10 ) ;
itsII2C->write(DS3231_ADDRESS,cmd,4);
}
public:
DS3231(II2C *);
+ void init();
+
void getTime(RtcTime_t &argTime);
void setTime(const RtcTime_t &argTime);
--- /dev/null
+#include <Utils/StdTypes.h>
+#include "Abstract/II2C.h"
+
+#include "Abstract/RFID/IPN532Interface.h"
+#include "PN532.h"
+
+#define ITF(fct) (m_Itf->fct)
+
+PN532::PN532(IPN532Interface *_itf)
+ : m_Itf(_itf)
+{
+}
+
+
+void PN532::begin()
+{
+ ITF(begin)();
+ ITF(wakeup)();
+}
+
+Uint32_t PN532::getFirmwareVersion()
+{
+ Uint32_t response;
+
+ m_PacketBuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
+ Int8_t res = (ITF(writeCommand)(m_PacketBuffer,1));
+ if (res)
+ {
+ return 3;
+ }
+ Int16_t status = ITF(readResponse)(m_PacketBuffer,sizeof(m_PacketBuffer));
+ if (0 > status)
+ {
+ //return status;
+ return 5;
+ }
+ response = m_PacketBuffer[0]; response <<= 8;
+ response |= m_PacketBuffer[1]; response <<= 8;
+ response |= m_PacketBuffer[2]; response <<= 8;
+ response |= m_PacketBuffer[3];
+ return response;
+}
+
+Bool_t PN532::SAMConfig()
+{
+ 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 ( 0 < ITF(readResponse)(m_PacketBuffer,sizeof(m_PacketBuffer)));
+}
+
+Bool_t PN532::readPassiveTargetID( Uint8_t _type
+ , Uint8_t *uid
+ , Uint8_t *uidLength)
+{
+ m_PacketBuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
+ m_PacketBuffer[1] = 0x01; // normal mode
+ m_PacketBuffer[2] = _type;
+
+ if (ITF(writeCommand)(m_PacketBuffer,3))
+ {
+ return 0; // command failed
+ }
+ // 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++)
+ {
+ m_UID[i] = m_PacketBuffer[6 + i];
+ }
+ return 1;
+}
+
+/**
+ *
+ */
+Bool_t PN532::setPassiveActivationRetries(Uint8_t _retries)
+{
+ m_PacketBuffer[0] = PN532_COMMAND_RFCONFIGURATION;
+ m_PacketBuffer[1] = 0x05; // Config item 5 (MaxRetries)
+ m_PacketBuffer[2] = 0xFF;
+ m_PacketBuffer[3] = 0x01;
+ m_PacketBuffer[4] = _retries;
+
+ if (ITF(writeCommand)(m_PacketBuffer,5))
+ {
+ return 0; // no Ack
+ }
+ return ( 0 < ITF(readResponse)(m_PacketBuffer,sizeof(m_PacketBuffer)));
+}
--- /dev/null
+#ifndef __PN532_H__
+#define __PN532_H__
+
+// PN532 Commands
+#define PN532_COMMAND_DIAGNOSE (0x00)
+#define PN532_COMMAND_GETFIRMWAREVERSION (0x02)
+#define PN532_COMMAND_GETGENERALSTATUS (0x04)
+#define PN532_COMMAND_READREGISTER (0x06)
+#define PN532_COMMAND_WRITEREGISTER (0x08)
+#define PN532_COMMAND_READGPIO (0x0C)
+#define PN532_COMMAND_WRITEGPIO (0x0E)
+#define PN532_COMMAND_SETSERIALBAUDRATE (0x10)
+#define PN532_COMMAND_SETPARAMETERS (0x12)
+#define PN532_COMMAND_SAMCONFIGURATION (0x14)
+#define PN532_COMMAND_POWERDOWN (0x16)
+#define PN532_COMMAND_RFCONFIGURATION (0x32)
+#define PN532_COMMAND_RFREGULATIONTEST (0x58)
+#define PN532_COMMAND_INJUMPFORDEP (0x56)
+#define PN532_COMMAND_INJUMPFORPSL (0x46)
+#define PN532_COMMAND_INLISTPASSIVETARGET (0x4A)
+#define PN532_COMMAND_INATR (0x50)
+#define PN532_COMMAND_INPSL (0x4E)
+#define PN532_COMMAND_INDATAEXCHANGE (0x40)
+#define PN532_COMMAND_INCOMMUNICATETHRU (0x42)
+#define PN532_COMMAND_INDESELECT (0x44)
+#define PN532_COMMAND_INRELEASE (0x52)
+#define PN532_COMMAND_INSELECT (0x54)
+#define PN532_COMMAND_INAUTOPOLL (0x60)
+#define PN532_COMMAND_TGINITASTARGET (0x8C)
+#define PN532_COMMAND_TGSETGENERALBYTES (0x92)
+#define PN532_COMMAND_TGGETDATA (0x86)
+#define PN532_COMMAND_TGSETDATA (0x8E)
+#define PN532_COMMAND_TGSETMETADATA (0x94)
+#define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88)
+#define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90)
+#define PN532_COMMAND_TGGETTARGETSTATUS (0x8A)
+
+#define PN532_RESPONSE_INDATAEXCHANGE (0x41)
+#define PN532_RESPONSE_INLISTPASSIVETARGET (0x4B)
+
+
+#define PN532_MIFARE_ISO14443A (0x00)
+
+// Mifare Commands
+#define MIFARE_CMD_AUTH_A (0x60)
+#define MIFARE_CMD_AUTH_B (0x61)
+#define MIFARE_CMD_READ (0x30)
+#define MIFARE_CMD_WRITE (0xA0)
+#define MIFARE_CMD_WRITE_ULTRALIGHT (0xA2)
+#define MIFARE_CMD_TRANSFER (0xB0)
+#define MIFARE_CMD_DECREMENT (0xC0)
+#define MIFARE_CMD_INCREMENT (0xC1)
+#define MIFARE_CMD_STORE (0xC2)
+
+// FeliCa Commands
+#define FELICA_CMD_POLLING (0x00)
+#define FELICA_CMD_REQUEST_SERVICE (0x02)
+#define FELICA_CMD_REQUEST_RESPONSE (0x04)
+#define FELICA_CMD_READ_WITHOUT_ENCRYPTION (0x06)
+#define FELICA_CMD_WRITE_WITHOUT_ENCRYPTION (0x08)
+#define FELICA_CMD_REQUEST_SYSTEM_CODE (0x0C)
+
+// Prefixes for NDEF Records (to identify record type)
+#define NDEF_URIPREFIX_NONE (0x00)
+#define NDEF_URIPREFIX_HTTP_WWWDOT (0x01)
+#define NDEF_URIPREFIX_HTTPS_WWWDOT (0x02)
+#define NDEF_URIPREFIX_HTTP (0x03)
+#define NDEF_URIPREFIX_HTTPS (0x04)
+#define NDEF_URIPREFIX_TEL (0x05)
+#define NDEF_URIPREFIX_MAILTO (0x06)
+#define NDEF_URIPREFIX_FTP_ANONAT (0x07)
+#define NDEF_URIPREFIX_FTP_FTPDOT (0x08)
+#define NDEF_URIPREFIX_FTPS (0x09)
+#define NDEF_URIPREFIX_SFTP (0x0A)
+#define NDEF_URIPREFIX_SMB (0x0B)
+#define NDEF_URIPREFIX_NFS (0x0C)
+#define NDEF_URIPREFIX_FTP (0x0D)
+#define NDEF_URIPREFIX_DAV (0x0E)
+#define NDEF_URIPREFIX_NEWS (0x0F)
+#define NDEF_URIPREFIX_TELNET (0x10)
+#define NDEF_URIPREFIX_IMAP (0x11)
+#define NDEF_URIPREFIX_RTSP (0x12)
+#define NDEF_URIPREFIX_URN (0x13)
+#define NDEF_URIPREFIX_POP (0x14)
+#define NDEF_URIPREFIX_SIP (0x15)
+#define NDEF_URIPREFIX_SIPS (0x16)
+#define NDEF_URIPREFIX_TFTP (0x17)
+#define NDEF_URIPREFIX_BTSPP (0x18)
+#define NDEF_URIPREFIX_BTL2CAP (0x19)
+#define NDEF_URIPREFIX_BTGOEP (0x1A)
+#define NDEF_URIPREFIX_TCPOBEX (0x1B)
+#define NDEF_URIPREFIX_IRDAOBEX (0x1C)
+#define NDEF_URIPREFIX_FILE (0x1D)
+#define NDEF_URIPREFIX_URN_EPC_ID (0x1E)
+#define NDEF_URIPREFIX_URN_EPC_TAG (0x1F)
+#define NDEF_URIPREFIX_URN_EPC_PAT (0x20)
+#define NDEF_URIPREFIX_URN_EPC_RAW (0x21)
+#define NDEF_URIPREFIX_URN_EPC (0x22)
+#define NDEF_URIPREFIX_URN_NFC (0x23)
+
+#define PN532_GPIO_VALIDATIONBIT (0x80)
+#define PN532_GPIO_P30 (0)
+#define PN532_GPIO_P31 (1)
+#define PN532_GPIO_P32 (2)
+#define PN532_GPIO_P33 (3)
+#define PN532_GPIO_P34 (4)
+#define PN532_GPIO_P35 (5)
+
+// FeliCa consts
+#define FELICA_READ_MAX_SERVICE_NUM 16
+#define FELICA_READ_MAX_BLOCK_NUM 12 // for typical FeliCa card
+#define FELICA_WRITE_MAX_SERVICE_NUM 16
+#define FELICA_WRITE_MAX_BLOCK_NUM 10 // for typical FeliCa card
+#define FELICA_REQ_SERVICE_MAX_NODE_NUM 32
+
+
+/**
+ * Driver to control the PN532 chip
+ */
+class PN532
+{
+ private:
+ IPN532Interface *m_Itf;
+ public:
+ PN532(IPN532Interface *itf); // Default contructor Needs in Interface
+
+ void begin();
+
+ Uint32_t getFirmwareVersion();
+
+ Bool_t SAMConfig();
+
+ Bool_t setPassiveActivationRetries(Uint8_t _retries);
+
+ Bool_t readPassiveTargetID(Uint8_t _type,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_UIDLength;
+
+
+};
+
+#endif
--- /dev/null
+#include <Utils/StdTypes.h>
+// AVr Gcc includes
+#include <string.h>
+#include <util/delay.h>
+//
+#include "Abstract/II2C.h"
+#include "Abstract/RFID/IPN532Interface.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)
+{
+}
+
+
+
+void PN532InterfaceI2C::begin()
+{
+}
+
+void PN532InterfaceI2C::wakeup()
+{
+}
+
+Int8_t PN532InterfaceI2C::writeCommand( const Uint8_t *header
+ , Uint8_t len
+ , Uint8_t *body
+ , Uint8_t blen)
+{
+ Uint8_t _count = 0;
+ Uint8_t length = len + blen + 1; // TFI + DATA
+ Uint8_t sum = PN532_HOSTTOPN532;
+ m_Command = header[0]; // Used when cheking the response
+ m_Message[_count++] = PN532_PREAMBLE;
+ m_Message[_count++] = PN532_STARTCODE1;
+ m_Message[_count++] = PN532_STARTCODE2;
+ m_Message[_count++] = length;
+ m_Message[_count++] = ~length + 1 ; // Checksum of length
+ m_Message[_count++] = sum; // PN532_HOSTTOPN532
+
+ /* Copy Header */
+ for ( Uint8_t i = 0
+ ; (i < len) && (_count < PN532_MESSAGE_SIZE )
+ ; _count++ , i++)
+ {
+ m_Message[_count] = header[i];
+ sum += header[i];
+ }
+ /* Copy body */
+ for ( Uint8_t i = 0
+ ; (i < blen) && (_count < PN532_MESSAGE_SIZE )
+ ; _count++ , i++)
+ {
+ m_Message[_count] = body[i];
+ sum += body[i];
+ }
+
+ Uint8_t checksum = ~sum + 1;
+ if (_count < PN532_MESSAGE_SIZE - 2)
+ {
+ m_Message[_count++] = checksum;
+ m_Message[_count++] = PN532_POSTAMBLE;
+ } else
+ {
+ return PN532_INVALID_FRAME;
+ }
+ m_I2C->write(m_Address,m_Message,_count );
+ return readAckFrame();
+}
+
+/**
+ *
+ */
+Int16_t PN532InterfaceI2C::readResponse(Uint8_t *buf
+ ,Uint8_t len
+ ,Uint8_t timeout)
+{
+ Uint8_t _count = 0;
+ Uint8_t length = getResponseLength(buf,len,timeout);
+ /* Error don't continue */
+ if (length < 0)
+ return length;
+
+ do
+ {
+ m_I2C->read(m_Address,m_Message,6+length + 2);
+ if (m_Message[_count] & 0x01)
+ {
+ _count+=4;
+ break; // Ok, got frame ready
+ }
+ timeout--;
+ _delay_ms(1);
+ } while (timeout);
+ /**/
+ if (!timeout)
+ return -1; // timeout
+ length = m_Message[_count++];
+ /* Check len checksum */
+ if ( 0 != (Uint8_t )(length + m_Message[_count++]) )
+ {
+ return PN532_INVALID_FRAME;
+ }
+ Uint8_t cmd = m_Command + 1;
+ /* Check response to command */
+ if ( (PN532_PN532TOHOST != m_Message[_count++])
+ || (cmd != m_Message[_count++]))
+ {
+ return PN532_INVALID_FRAME;
+ }
+
+ length-=2;
+ if ( len < length)
+ {
+ return PN532_NO_SPACE;
+ }
+
+ Uint8_t sum = PN532_PN532TOHOST + cmd;
+ /* Read response frame */
+ for (Uint8_t i = 0 ; i < length ; i++)
+ {
+ buf[i] = m_Message[_count++];
+ sum+=buf[i];
+ }
+ /* Check message checksum*/
+ if (0 != (Uint8_t)(sum + m_Message[_count++]))
+ {
+ return PN532_INVALID_FRAME;
+ }
+ return length;
+ //return 5;
+}
+
+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);
+ if (m_Message[0] & 0x01)
+ {
+ break;
+ }
+ timeout--;
+ _delay_ms(1);
+ } while (timeout > 0);
+ /* If Succeed compare result */
+ if (memcmp(&m_Message[1],PN532_ACK,sizeof(PN532_ACK)))
+ {
+ return PN532_INVALID_ACK;
+ }
+ return 0;
+}
+
+/**
+ *
+ * Odd, _buff and len are unsed
+ */
+Int16_t PN532InterfaceI2C::getResponseLength( Uint8_t *_buff
+ , Uint8_t len
+ , Uint16_t timeout)
+{
+ Uint8_t PN532_NACK[] = {0,0,0xFF,0xFf,0,0};
+
+ do
+ {
+ m_I2C->read(m_Address,m_Message,6);
+ if (m_Message[0] & 0x01)
+ {
+ break;
+ }
+ timeout--;
+ _delay_ms(1);
+ } while(timeout);
+
+ if (memcmp(&m_Message[1],PN532_NACK,3))
+ {
+ return PN532_INVALID_FRAME;
+ }
+ Uint8_t length = m_Message[4];
+ /* Send NACK */
+ m_I2C->write(m_Address,PN532_NACK,static_cast<Uint8_t>(sizeof(PN532_NACK)));
+
+ return length;
+}
+
--- /dev/null
+#ifndef __IPN532INTERFACE_I2C_H__
+#define __IPN532INTERFACE_I2C_H__
+
+#define PN532_I2C_ADDRESS 0x48
+/* 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:
+ II2C *m_I2C;
+ Uint8_t m_Address;
+ Uint8_t m_Command;
+ static Uint8_t m_Message[PN532_MESSAGE_SIZE];
+ public:
+ PN532InterfaceI2C(II2C *m_i2c,Uint8_t address = PN532_I2C_ADDRESS);
+
+ void begin();
+
+ void wakeup();
+
+ Int8_t writeCommand( const Uint8_t *header
+ , Uint8_t len
+ , Uint8_t *body = 0
+ , Uint8_t blen = 0);
+
+ Int16_t readResponse(Uint8_t *buf,Uint8_t len,Uint8_t timeout);
+
+ private:
+ Uint8_t m_ReceiveByte;
+ private:
+ Int8_t readAckFrame();
+
+ Int16_t getResponseLength( Uint8_t *_buff
+ , Uint8_t len
+ , Uint16_t timeout);
+
+ 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