Libreria Arduino per RFID MF522 - Mifare 522

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?

MF522.rar (5.96 KB)

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

Ho compilato sia con 1.5.4 che con 1.0.5.

Questo è il file.h (MF522.h)

#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

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

#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();		
}

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

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

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).

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....

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.

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

Thanks

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

MF522.rar (5.96 KB)

x iscrizione.