Go Down

Topic: Libreria Arduino per RFID MF522 - Mifare 522 (Read 2120 times) previous topic - next topic

BaBBuino

Nov 25, 2013, 04:55 am Last Edit: Nov 25, 2013, 09:00 am by BaBBuino Reason: 1
Ho scritto una libreria per le mie cosacce, i metodi sono rigorosi e ben scritti, però ho un problema con il linker finale:

Mi restituisce questo errore: undefined reference to...  riferito a tutti i metodi metodi nel file CPP.

Sembra come se mi leggesse il file.h, ma non mi vedesse il file.cpp.

Ho provato ad inserire il file.ccp della libreria, tramite la funzione Schetch > Aggiungi file... ma nulla. Eppure è nella stessa cartella dove c'è il file.h e il file keywords.txt, buttati dentro una cartella apposita dentro Libraries.

Cosa mi sono dimenticato per far "vedere" anche il file cpp?

leo72

Dai poche info. Che IDE usi? Si possono vedere i file?

BaBBuino

#2
Nov 25, 2013, 07:02 am Last Edit: Nov 25, 2013, 07:05 am by BaBBuino Reason: 1
Ho compilato sia con 1.5.4 che con 1.0.5.

Questo è il file.h (MF522.h)

Code: [Select]

#ifndef MF522_H
#define MF522_H
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define uchar unsigned char
#define uint  unsigned int

 
class MF522
{
  private:
  //***************************************************
  // Variabili Private
  //***************************************************
 
  //***************************************************
  // Funzioni Private
  //***************************************************

   public:  
 void Write_MFRC522(uchar addr, uchar val);
         uchar Read_MFRC522(uchar addr);
 void SetBitMask(uchar reg, uchar mask);
 void ClearBitMask(uchar reg, uchar mask);
 void AntennaOn(void);
 void AntennaOff(void);
 void MFRC522_Reset(void);
 uchar MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen);
 uchar MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum);
 uchar MFRC522_Read(uchar blockAddr, uchar *recvData);
 uchar MFRC522_Write(uchar blockAddr, uchar *writeData);
 void CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData);
 uchar MFRC522_SelectTag(uchar *serNum);
 
 //MF522();
 //~MF522();
    // void MFRC522_Init(void);
 //uchar MFRC522_Request(uchar reqMode, uchar *TagType);
 //uchar MFRC522_Anticoll(uchar *serNum);
 //void MFRC522_Halt(void);
 
};

#endif




BaBBuino

Questo è il file.h (MF522.cpp):

Code: [Select]

#include "SPI.h"
#include "MF522.h"
#include "Arduino.h"

#define uchar unsigned char
#define uint  unsigned int

#define NORESET 5
#define chipSelectPin 10

 
 
//MF522::MF522()
//{
//}

//MF522::~MF522()
//{
//}

void MF522::Write_MFRC522(uchar addr, uchar val)
{
digitalWrite(chipSelectPin, LOW);

//0XXXXXX0
SPI.transfer((addr<<1)&0x7E);
SPI.transfer(val);

digitalWrite(chipSelectPin, HIGH);
}

uchar MF522::Read_MFRC522(uchar addr)
{
uchar val;

digitalWrite(chipSelectPin, LOW);

//:1XXXXXX0
SPI.transfer(((addr<<1)&0x7E) | 0x80);
val =SPI.transfer(0x00);

digitalWrite(chipSelectPin, HIGH);

return val;
}


void MF522::SetBitMask(uchar reg, uchar mask)  
{
   uchar tmp;
   tmp = Read_MFRC522(reg);
   Write_MFRC522(reg, tmp | mask);  // set bit mask
}


void MF522::ClearBitMask(uchar reg, uchar mask)  
{
   uchar tmp;
   tmp = Read_MFRC522(reg);
   Write_MFRC522(reg, tmp & (~mask));  // clear bit mask
}


void MF522::AntennaOn(void)
{
uchar temp;

temp = Read_MFRC522(TxControlReg);
if (!(temp & 0x03))
{
SetBitMask(TxControlReg, 0x03);
}
}


void MF522::AntennaOff(void)
{
ClearBitMask(TxControlReg, 0x03);
}


void MF522::MFRC522_Reset(void)
{
   Write_MFRC522(CommandReg, PCD_RESETPHASE);
}


uchar MF522::MFRC522_Request(uchar reqMode, uchar *TagType)
{
uchar status;  
uint backBits;

Write_MFRC522(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ???

TagType[0] = reqMode;
status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

if ((status != MI_OK) || (backBits != 0x10))
{    
status = MI_ERR;
}
 
return status;
}


uchar MF522::MFRC522_ToCard(uchar command, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
{
   uchar status = MI_ERR;
   uchar irqEn = 0x00;
   uchar waitIRq = 0x00;
   uchar lastBits;
   uchar n;
   uint i;

   switch (command)
   {
       case PCD_AUTHENT:
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case PCD_TRANSCEIVE: //FIFO
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
   }
 
   Write_MFRC522(CommIEnReg, irqEn|0x80);
   ClearBitMask(CommIrqReg, 0x80);
   SetBitMask(FIFOLevelReg, 0x80); //FlushBuffer=1, FIFO
   
Write_MFRC522(CommandReg, PCD_IDLE); //NO action; ???

//IFO
   for (i=0; i<sendLen; i++)
   {  
Write_MFRC522(FIFODataReg, sendData[i]);    
}


Write_MFRC522(CommandReg, command);
   if (command == PCD_TRANSCEIVE)
   {    
SetBitMask(BitFramingReg, 0x80); //StartSend=1,transmission of data starts  
}  
   

i = 2000; //i,M 1 25ms ???
   do
   {
//CommIrqReg[7..0]
//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
       n = Read_MFRC522(CommIrqReg);
       i--;
   }
   while ((i!=0) && !(n&0x01) && !(n&waitIRq));

   ClearBitMask(BitFramingReg, 0x80); //StartSend=0

   if (i != 0)
   {    
       if(!(Read_MFRC522(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
       {
           status = MI_OK;
           if (n & irqEn & 0x01)
           {  
status = MI_NOTAGERR; //??  
}

           if (command == PCD_TRANSCEIVE)
           {
              n = Read_MFRC522(FIFOLevelReg);
              lastBits = Read_MFRC522(ControlReg) & 0x07;
               if (lastBits)
               {  
*backLen = (n-1)*8 + lastBits;  
}
               else
               {  
*backLen = n*8;  
}

               if (n == 0)
               {  
n = 1;    
}
               if (n > MAX_LEN)
               {  
n = MAX_LEN;  
}

//FIFO
               for (i=0; i<n; i++)
               {  
backData[i] = Read_MFRC522(FIFODataReg);    
}
           }
       }
       else
       {  
status = MI_ERR;  
}
       
   }

   //SetBitMask(ControlReg,0x80);           //timer stops
   //Write_MFRC522(CommandReg, PCD_IDLE);

   return status;
}


uchar MF522::MFRC522_Anticoll(uchar *serNum)
{
   uchar status;
   uchar i;
uchar serNumCheck=0;
   uint unLen;
   

   //ClearBitMask(Status2Reg, 0x08); //TempSensclear
   //ClearBitMask(CollReg,0x80); //ValuesAfterColl
Write_MFRC522(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]

   serNum[0] = PICC_ANTICOLL;
   serNum[1] = 0x20;
   status = MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

   if (status == MI_OK)
{

for (i=0; i<4; i++)
{  
serNumCheck ^= serNum[i];
}
if (serNumCheck != serNum[i])
{  
status = MI_ERR;    
}
   }

   //SetBitMask(CollReg, 0x80); //ValuesAfterColl=1

   return status;
}


void MF522::CalulateCRC(uchar *pIndata, uchar len, uchar *pOutData)
{
   uchar i, n;

   ClearBitMask(DivIrqReg, 0x04); //CRCIrq = 0
   SetBitMask(FIFOLevelReg, 0x80); //FIFO
   //Write_MFRC522(CommandReg, PCD_IDLE);

//FIFO?
   for (i=0; i<len; i++)
   {  
Write_MFRC522(FIFODataReg, *(pIndata+i));  
}
   Write_MFRC522(CommandReg, PCD_CALCCRC);

//CRC
   i = 0xFF;
   do
   {
       n = Read_MFRC522(DivIrqReg);
       i--;
   }
   while ((i!=0) && !(n&0x04)); //CRCIrq = 1

//CRC
   pOutData[0] = Read_MFRC522(CRCResultRegL);
   pOutData[1] = Read_MFRC522(CRCResultRegM);
}


uchar MF522::MFRC522_SelectTag(uchar *serNum)
{
   uchar i;
uchar status;
uchar size;
   uint recvBits;
   uchar buffer[9];

//ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0

   buffer[0] = PICC_SElECTTAG;
   buffer[1] = 0x70;
   for (i=0; i<5; i++)
   {
    buffer[i+2] = *(serNum+i);
   }
CalulateCRC(buffer, 7, &buffer[7]); //??
   status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
   
   if ((status == MI_OK) && (recvBits == 0x18))
   {  
size = buffer[0];
}
   else
   {  
size = 0;    
}

   return size;
}


uchar MF522::MFRC522_Auth(uchar authMode, uchar BlockAddr, uchar *Sectorkey, uchar *serNum)
{
   uchar status;
   uint recvBits;
   uchar i;
uchar buff[12];

   buff[0] = authMode;
   buff[1] = BlockAddr;
   for (i=0; i<6; i++)
   {    
buff[i+2] = *(Sectorkey+i);  
}
   for (i=0; i<4; i++)
   {    
buff[i+8] = *(serNum+i);  
}
   status = MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

   if ((status != MI_OK) || (!(Read_MFRC522(Status2Reg) & 0x08)))
   {  
status = MI_ERR;  
}
   
   return status;
}


uchar MF522::MFRC522_Read(uchar blockAddr, uchar *recvData)
{
   uchar status;
   uint unLen;

   recvData[0] = PICC_READ;
   recvData[1] = blockAddr;
   CalulateCRC(recvData,2, &recvData[2]);
   status = MFRC522_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

   if ((status != MI_OK) || (unLen != 0x90))
   {
       status = MI_ERR;
   }
   
   return status;
}


uchar MF522::MFRC522_Write(uchar blockAddr, uchar *writeData)
{
   uchar status;
   uint recvBits;
   uchar i;
uchar buff[18];
   
   buff[0] = PICC_WRITE;
   buff[1] = blockAddr;
   CalulateCRC(buff, 2, &buff[2]);
   status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

   if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
   {  
status = MI_ERR;  
}
       
   if (status == MI_OK)
   {
       for (i=0; i<16; i++) //FIFO16Byte
       {    
        buff[i] = *(writeData+i);  
       }
       CalulateCRC(buff, 16, &buff[16]);
       status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);
       
if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
       {  
status = MI_ERR;  
}
   }
   
   return status;
}


void MF522::MFRC522_Halt(void)
{
uchar status;
   uint unLen;
   uchar buff[4];

   buff[0] = PICC_HALT;
   buff[1] = 0;
   CalulateCRC(buff, 2, &buff[2]);

   status = MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff,&unLen);
}

void MF522::MFRC522_Init(void)
{
digitalWrite(NORESET,HIGH);

MFRC522_Reset();

//Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
   Write_MFRC522(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
   Write_MFRC522(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg
   Write_MFRC522(TReloadRegL, 30);          
   Write_MFRC522(TReloadRegH, 0);

Write_MFRC522(TxAutoReg, 0x40); //100%ASK
Write_MFRC522(ModeReg, 0x3D); //CRC 0x6363 ???

//ClearBitMask(Status2Reg, 0x08); //MFCrypto1On=0
//Write_MFRC522(RxSelReg, 0x86); //RxWait = RxSelReg[5..0]
//Write_MFRC522(RFCfgReg, 0x7F);   //RxGain = 48dB

AntennaOn();
}


BaBBuino

Voglio uccidermi...   Ho scritto .ccp invece che .cpp!


Vado a lasciarmi morire in un angolo dalla vergogna... :(

leo72

Cmq non compila ugualmente. Ti spara un sacco di errori con l'SPI che includi nel file cpp (io l'avevo salvato con l'estensione corretta).

BaBBuino

Ho sistemato un pò di cose e ora funziona.

Cmq è una libreria sul RFID Mifare522. In rete non si trova qualcosa di decente.

Ho fatto un porting pulito, levando tutti i commenti in cinese e sistemando qualche funzione. Se si può infilare da qualche parte ad imperitura memoria, è disponibile....

leo72

La possiamo anche lasciare qui, in Software. Magari cambia il titolo al 1° post, mettendo tipo "Libreria per RFID Mifare522" ed allega i file corretti sempre al 1° post. Se sei d'accordo, poi, cancello quelli dopo miei e tuoi almeno il thread resta pulito.

BaBBuino

Ok, fammi fare un pò di pulizia e un pò di commenti e nel pomeriggio pubblico, magari con un esempio di accompagnamento.

Thanks

BaBBuino

Ok, ho finito.

Cartella MF522 da inserirsi nella cartella Libraries dell'IDE.

Contiene:

MF522.h - file dei prototipi di funzione e #define dei metodi
MF522.cpp - file della classe MF522 con i metodi
keywords.txt - file dei simboli e colorazioni da applicare alle parole chiave della libreria
MF522.ino - file di esempio per semplice applicazione, commentata in italiano a prova di scimmia

PaoloP


Go Up