RFID(MFRC522) İncelemesi Hakkında Kısa Kısa

Başlatan MrDarK, 01 Mayıs 2014, 15:17:30

Mucit23

Hocam kartlar sıfır. Evet dediğiniz gibi Mifare Classic Tool uygulaması ile kontrol ettim sorun yok gibi keya ve keyb FF lerden oluşuyor.

Mucit23

#61
Kartı telefonla okuduğumda bu şekilde olduğunu görebiliyorum.

Sektör 1 blok 0 daki dataları yine telefonla ben yazdım.
Hatta Kart sorgusundan sonra kartın seri numarası ile birlikte TAG Select işlemi yapıyorum. Buna da pozitif cevap alıyorum. Fakat sektöre giriş yapamıyorum bir türlü.

@MrDarK sebebi ne olabilir bunun?

MrDarK

#62
Kodların tamamına bakmak lazım ama genelde bu write auth read gibi işlemlerde kullanılan timer'ın süresi hatalı olabiliyor. Timer'ı init esnasında 1 kere kurduktan sonra library değiştirmiyordu yanlış hatırlamıyorsam. MFRC522'de bir timer var timeout'u tutmak için, o timeout işlemi genelde card detect için gerekli olan süreye kuruluyor. Oradan şüphe ediyorum.

Kodları görmeden net birşey söylemek çok kolay değil hocam tahmin edebileceğin gibi :)

En azından rfid tag'de bir sorun olmadığını gördük. Bundan sonra MFRC'nin setup işlemlerine bakabiliriz.

Birde şimdi dikkatimi çekti Sen KEYB ile auth olmaya çalışıyorsun. Oysa ki default kartlarda KEYA yetkilidir. Değiştir orayı çalışacaktır :) Yani aşağıdaki gibi dene..
if (TM_MFRC522_Check(CardID) == MI_OK) 
{
	printf( "[%02x-%02x-%02x-%02x-%02x] \r\n", CardID[0], CardID[1], CardID[2], CardID[3], CardID[4]);
	if( (TM_MFRC522_Auth(PICC_AUTHENT1A,1,KEY,CardID) == MI_OK))
           printf("OK");
       else 
	   printf("FAILED\n\n");
}
Picproje Eğitim Gönüllüleri ~ MrDarK

Mucit23

İkisini de denedim hocam. En son keyB kalmış orada.

Kütüphanenin tamamı da budur.
/**	
 * |----------------------------------------------------------------------
 * | Edited by PhanDAT 23/09/2015
 * | Copyright (C) Tilen Majerle, 2014
 * | 
 * | This program is free software: you can redistribute it and/or modify
 * | it under the terms of the GNU General Public License as published by
 * | the Free Software Foundation, either version 3 of the License, or
 * | any later version.
 * |  
 * | This program is distributed in the hope that it will be useful,
 * | but WITHOUT ANY WARRANTY; without even the implied warranty of
 * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * | GNU General Public License for more details.
 * | 
 * | You should have received a copy of the GNU General Public License
 * | along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * |----------------------------------------------------------------------
 */
#include "MFRC522.h" 
#include <stdio.h>
#include "systick.h"
#include <stm32f10x.h>
//-------------------------------------------------
void TM_MFRC522_Init(void) 
{
	
  TM_MFRC522_InitPins(); 
	//CS high
	MFRC522_CS_HIGH; 
	
	TM_MFRC522_Reset();

	TM_MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
	TM_MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
	TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);           
	TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);

	/* 48dB gain */
	//TM_MFRC522_WriteRegister(MFRC522_REG_RF_CFG, 0x70); 
	TM_MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
	TM_MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);

	TM_MFRC522_AntennaOn();		//Open the antenna
}
  
//SPI2
void	TM_MFRC522_InitPins(void)
 {
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* Enable SPI2 and GPIOB clocks */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);  
	//  
	//CS  ---- Output, duoc dieu khien khi read/write
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);  
	//SET CS HIGH LEVEL
  GPIO_SetBits(GPIOB,GPIO_Pin_12);
	 
	/*Configure SPI2 pins: SCK, MISO and MOSI*/
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	  
	/* SPI2 configuration */ 
  /* Data bytes on both MOSI and MISO lines are sent with the MSB first. Data on both MOSI 
		and MISO lines must be stable on the rising edge of the clock and can be changed on the 
		falling edge. Data is provided by the MFRC522 on the falling clock edge and is stable 
		during the rising clock edge. */
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; // 72Mhz / 8 = 9Mhz  
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(SPI2, &SPI_InitStructure);
	 
	/* Enable SPI2  */
	SPI_Cmd(SPI2, ENABLE); 
 }
 //-------------------------------------------------
 //SPI2
unsigned char	SPI2_ReadWrite(unsigned char writedat)
	{
		/* Loop while DR register in not emplty */
		while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
		
		/* Send byte through the SPI2 peripheral */
		SPI_I2S_SendData(SPI2, writedat);
		
		/* Wait to receive a byte */
		while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
		
		/* Return the byte read from the SPI bus */
		return SPI_I2S_ReceiveData(SPI2);
	}	
	
 //-------------------------------------------------
void TM_MFRC522_WriteRegister(uint8_t addr, uint8_t val) 
 {
	//CS low
	unsigned char status;
	MFRC522_CS_LOW;
	//Send address
	delay_us(100); 
  status = SPI2_ReadWrite((addr << 1) & 0x7E); 
	//Send data	
  delay_us(100); 
  status = SPI2_ReadWrite(val); 
	//CS high
	MFRC522_CS_HIGH;
}
//-------------------------------------------------
uint8_t TM_MFRC522_ReadRegister(uint8_t addr) 
{
	uint8_t val; 
	//CS low
	MFRC522_CS_LOW; 
  delay_us(100);
	SPI2_ReadWrite(((addr << 1) & 0x7E) | 0x80);
  delay_us(100);
	val =  SPI2_ReadWrite(0x00); // SPI2_ReadWrite(0x00);
	//CS high
	MFRC522_CS_HIGH;

	return val;	
}
//-------------------------------------------------
void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask) {
	TM_MFRC522_WriteRegister(reg, TM_MFRC522_ReadRegister(reg) | mask);
}
//-------------------------------------------------
void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask){
	TM_MFRC522_WriteRegister(reg, TM_MFRC522_ReadRegister(reg) & (~mask));
} 
//-------------------------------------------------
void TM_MFRC522_AntennaOn(void) {
	uint8_t temp;

	temp = TM_MFRC522_ReadRegister(MFRC522_REG_TX_CONTROL);
	if (!(temp & 0x03)) {
		TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
	}
}
//-------------------------------------------------
void TM_MFRC522_AntennaOff(void) {
	TM_MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
}
//-------------------------------------------------
void TM_MFRC522_Reset(void) {
	TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_RESETPHASE);
}
//-------------------------------------------------
uint8_t getFirmwareVersion()
{
  uint8_t response;
  response = TM_MFRC522_ReadRegister(MFRC522_REG_VERSION);
  return response;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType) {
	TM_MFRC522_Status_t status;  
	uint16_t backBits;			//The received data bits

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

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

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

	return status;
}

//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Check(uint8_t* id) {
	TM_MFRC522_Status_t status;
	//Find cards, return card type
	status = TM_MFRC522_Request(PICC_REQIDL, id);	
	if (status == MI_OK) {
		//Card detected
		//Anti-collision, return card serial number 4 bytes
		status = TM_MFRC522_Anticoll(id);	
	}
	TM_MFRC522_Halt();			//Command card into hibernation 

	return status;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Compare(uint8_t* CardID, uint8_t* CompareID) {
	uint8_t i;
	for (i = 0; i < 5; i++) {
		if (CardID[i] != CompareID[i]) {
			return MI_ERR;
		}
	}
	return MI_OK;
} 
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) {
	TM_MFRC522_Status_t status = MI_ERR;
	uint8_t irqEn = 0x00;
	uint8_t waitIRq = 0x00;
	uint8_t lastBits;
	uint8_t n;
	uint16_t i;

	switch (command) {
		case PCD_AUTHENT: {
			irqEn = 0x12;
			waitIRq = 0x10;
			break;
		}
		case PCD_TRANSCEIVE: {
			irqEn = 0x77;
			waitIRq = 0x30;
			break;
		}
		default:
			break;
	}

	TM_MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
	TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
	TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);

	TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);

	//Writing data to the FIFO
	for (i = 0; i < sendLen; i++) {   
		TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);    
	}

	//Execute the command
	TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
	if (command == PCD_TRANSCEIVE) {    
		TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);		//StartSend=1,transmission of data starts  
	}   

	//Waiting to receive data to complete
	i = 2000;	//i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
	do {
		//CommIrqReg[7..0]
		//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
		n = TM_MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
		i--;
	} while ((i!=0) && !(n&0x01) && !(n&waitIRq));

	TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);			//StartSend=0

	if (i != 0)  {
		if (!(TM_MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) {
			status = MI_OK;
			if (n & irqEn & 0x01) {   
				status = MI_NOTAGERR;			
			}

			if (command == PCD_TRANSCEIVE) {
				n = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);
				lastBits = TM_MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
				if (lastBits) {   
					*backLen = (n - 1) * 8 + lastBits;   
				} else {   
					*backLen = n * 8;   
				}

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

				//Reading the received data in FIFO
				for (i = 0; i < n; i++) {   
					backData[i] = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);    
				}
			}
		} else {   
			status = MI_ERR;  
		}
	}

	return status;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Anticoll(uint8_t* serNum) {
	TM_MFRC522_Status_t status;
	uint8_t i;
	uint8_t serNumCheck = 0;
	uint16_t unLen;

	TM_MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x00);		//TxLastBists = BitFramingReg[2..0]

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

	if (status == MI_OK) {
		//Check card serial number
		for (i = 0; i < 4; i++) {   
			serNumCheck ^= serNum[i];
		}
		if (serNumCheck != serNum[i]) {   
			status = MI_ERR;    
		}
	}
	return status;
} 

void TM_MFRC522_CalculateCRC(uint8_t*  pIndata, uint8_t len, uint8_t* pOutData) {
	uint8_t i, n;

	TM_MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);			//CRCIrq = 0
	TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);			//Clear the FIFO pointer
	//Write_MFRC522(CommandReg, PCD_IDLE);

	//Writing data to the FIFO	
	for (i = 0; i < len; i++) {   
		TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, *(pIndata+i));   
	}
	TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_CALCCRC);

	//Wait CRC calculation is complete
	i = 0xFF;
	do {
		n = TM_MFRC522_ReadRegister(MFRC522_REG_DIV_IRQ);
		i--;
	} while ((i!=0) && !(n&0x04));			//CRCIrq = 1

	//Read CRC calculation result
	pOutData[0] = TM_MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_L);
	pOutData[1] = TM_MFRC522_ReadRegister(MFRC522_REG_CRC_RESULT_M);
}
//-------------------------------------------------
uint8_t TM_MFRC522_SelectTag(uint8_t* serNum) {
	uint8_t i;
	TM_MFRC522_Status_t status;
	uint8_t size;
	uint16_t recvBits;
	uint8_t buffer[9]; 

	buffer[0] = PICC_SElECTTAG;
	buffer[1] = 0x70;
	for (i = 0; i < 5; i++) {
		buffer[i+2] = *(serNum+i);
	}
	TM_MFRC522_CalculateCRC(buffer, 7, &buffer[7]);		//??
	status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);

	if ((status == MI_OK) && (recvBits == 0x18)) {   
		size = buffer[0]; 
	} else {   
		size = 0;    
	}

	return size;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
	TM_MFRC522_Status_t status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[12]; 

	//Verify the command block address + sector + password + card serial number
	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 = TM_MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

	if ((status != MI_OK) || (!(TM_MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) {   
		status = MI_ERR;   
	}

	return status;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Read(uint8_t blockAddr, uint8_t* recvData) {
	TM_MFRC522_Status_t status;
	uint16_t unLen;

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

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

	return status;
}
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Write(uint8_t blockAddr, uint8_t* writeData) {
	TM_MFRC522_Status_t status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[18]; 

	buff[0] = PICC_WRITE;
	buff[1] = blockAddr;
	TM_MFRC522_CalculateCRC(buff, 2, &buff[2]);
	status = TM_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) {
		//Data to the FIFO write 16Byte
		for (i = 0; i < 16; i++) {    
			buff[i] = *(writeData+i);   
		}
		TM_MFRC522_CalculateCRC(buff, 16, &buff[16]);
		status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

		if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A)) {   
			status = MI_ERR;   
		}
	}

	return status;
}

void TM_MFRC522_Halt(void) {
	uint16_t unLen;
	uint8_t buff[4]; 

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

	TM_MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
}

TM_MFRC522_ToCard fonksiyonuna bakmanız mümkün mü? Orada gecikme ile ilgili bir "i" değişkeni var. Sizde bu değer nedir? Benim MCU 72Mhzde çalışıyor.

Siz STM32F103 de çalıştırabildiniz mi?

MrDarK

#64
Selamlar,

Gördüğüm kadarı ile TM_MFRC522_Check fonksiyonun yaptığı tek işlem kartın id'sini almak gibi görünüyor. Birde o fonksiyon içinde kartın id'sini aldıktan sonra TM_MFRC522_Halt() fonksiyonu çalıştırıyor. Ben halt işlemini çalıştırmıyorum. Birde anticoll işlemi okey fakat sonrasında direkt olarak siz authanticate işlemi yapmaya çalışmışsınız öncesinde select işlemini yapmanız gerekiyor. Yani özetle check fonksiyonundan sonra TM_MFRC522_SelectTag fonksiyonunu çağırın. Birde dipnot bana kalırsa check fonksiyonunun sonundaki halt fonksiyonunu da yoruma alın.

Sonucu buraya da yazarsınız =)

Ayrıca konuyu okuyalım lütfen :)

Alıntı yapılan: MrDarK - 01 Mayıs 2014, 15:17:30Öncelikle RF alana REQA denilen bir bilgi yolluyoruz. Eğer RF alan içinde bir mifare kart var ise bize cevap yolluyor. Ardından RF alana kartın seri numarasını öğrenmek için bir kod yolluyoruz. Kart seri numarasını gönderiyor. Ardından Anticollision (çarpışmama) RF alanda birden başka bir kart olmadığını teyit ettikten sonra Select denilen işlemi yapıyoruz.

Picproje Eğitim Gönüllüleri ~ MrDarK

zuzunin

#65
CCS C ile yazılmış kütüphane ve örnek devreye buradan ulaşabilirsiniz:

https://youtu.be/htoHSMjgVSE


Kart bilgisini seri haberleşme ile bilgisayar üzerinden  görmek için şu kodu kullanabilirsiniz:

#INCLUDE <16F876.H>
#USE DELAY(CLOCK=20M)
#FUSES PUT,HS,NOWDT,NOPROTECT,NOLVP
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7)

#define MFRC522_CS         PIN_C2                
#define MFRC522_SCK        PIN_C3
#define MFRC522_SI         PIN_C1                          
#define MFRC522_SO         PIN_C0              
#define MFRC522_RST        PIN_C4    
#include<Built_in.h>


void main()
{

   CHAR UID[6];
   UNSIGNED int TagType;                
   MFRC522_Init ();
   delay_ms(100);
   
   
   WHILE (true)
   {
     
      IF (MFRC522_isCard (&TagType)) //Check any card
      {                                           
         //Read ID 
         IF (MFRC522_ReadCardSerial (&UID))             
         {
           printf("\nUID:");
           FOR (INT i=0; i<5;i++)
           {
           printf("%X",UID[i]);
           }
           printf("");
        
          
            }     
            
         } 
        
        MFRC522_Halt () ;
      }    
   }

Mucit23

TM_MFRC522_SelectTag işlemini denemiştim. Yani ilk önce kart sorgulaması yaptım. Ok aldıktan sonra selec tag işlemini yaptım. Oda OK olduktan sonra Auth işlemi yapıyordum. Fakat bu işlem başarılı bir şekilde sonuçlanmıyor. Anti Coolision işlemini yapmak şartmı çünkü benim testlerimde öyle bir durum gerçekleşmiyor. Ama Halt işlemini pasif yapmayı deneyeceğim. Sonucu yazarım.

Mucit23

#67
Yahu şu kartlara blok yazma ve okuma yapabilen varmı. İnternette ne kadar uygulama yapan varsa ID kontrol edip led felan yakmış.

@MrDarK Hocam hepsini denedim. Fakat olmadı.

Check yaptıktan sonra TM_MFRC522_Halt işlemini yoruma alırsam bundan sonraki Select Tag işlemi de başarısız oluyor. En son dediğiniz gibi yaptım.

if (TM_MFRC522_Check(CardID) == MI_OK) 
		 {
				printf( "[%02x-%02x-%02x-%02x-%02x] \r\n", CardID[0], CardID[1], CardID[2], CardID[3], CardID[4]);
			 if(TM_MFRC522_SelectTag(CardID) == MI_OK)
			 {
           printf("OK TAG Selected\r\n");

			 		 if( (TM_MFRC522_Auth(PICC_AUTHENT1A,1,KEY,CardID) == MI_OK))
					 {
					    printf("AUTH OK\r\n");
					 }
					 else
					 {
					   printf("AUTH ERROR\r\n");
					 }
			 }
       else
			 {				 
				   printf("FAILED TAG SELECT\n\n");
			 }
		 }

Ama sorun devam ediyor. Bir türlü Sektöre giriş yapamıyorum. Kafayı yedirtecek.

@MrDarK STM32 için denediğin verebileceğin bir örnek varmı. Rica etsem paylaşabilirmisin. Karşılaştırmak adına bakmak istiyorum.

CCS kütüphanesini inceledim. Oda aynı şekilde çalışıyor. Fonksiyon isimleri bile neredeyse aynı. Sorun nerde çözemiyorum.

Birşey Dikkatimi çekti. Kart ID normalde 4 Byte'dan oluşmuyormu? Ben cep telefonu ile okuduğumda 69:77:DC:06 olarak okuyorum. Benim kendi yazılımda ise CardID 5 Byte'dan oluşuyor. Okuduğum değerler 69:77:DC:06:C4 şeklinde oluyor. Acaba kart farklılığı mı var? C4 değeri nerden geliyor?

MrDarK

Hocam selamlar,

Arduino ile çok güzel çalışan uygulamalar var. Okuma yazma increment decrement. Benim kendi library'im state machine göre uyarlanmış hali o sebeple paylaşılabileceğim gibi alt yapısı yok. Şu an yapabileceğiniz arduino library'sinde işletilen kodlar ile sizin kodları karşılaştırmak olabilir.

Card Id için 5 byte kullanmışım. Aşağıdaki resimdeki şablona göre 4 byte seri no, 1 byte ise crc oluyor.



Birde şimdi dikkatimi çekti. TM_MFRC522_Auth fonksiyonunda 2. parametre blok numarası. Blok 1 için auth olmaya çalışıyorsanız hata alırsınız. Sadece sector trailer'a auth işlemi yapılabilir. Hatanın temeli sanırım burası. Ayrıca ilk 4 blok (0-1-2-3) Manufacturer specific. Sonraki sektörlere auth işlemi yapmanız gerekiyor. Auth yaparken sektöre değil blok numarasına auth işlemi yapılıyor. 0. sektör manufacturer, 1.sektörde işlem yapalım diyelim blok numaraları (4 - 5 - 6 - 7 ) şeklindedir. Siz 1.sektöre auth yapmak istiyorsanız 7 numaralı bloktan izin istemelisiniz. Onay geldikten sonra 4 - 5 - 6 numaralı bloklar kullanılabilir olacaktır.

MrDarK

Picproje Eğitim Gönüllüleri ~ MrDarK

Mucit23

MrDark dediğini anladım ve hemen uyguladım. 1. Sektörde okuma yazma yapabilmek için 7 nolu bloktan giriş izni isteniyor key ile.

Check ve Tag Select işlemi yaptıktan sonra aşağıdaki sorgu ile auth işlemi yapıyorum.

if( (TM_MFRC522_Auth(PICC_AUTHENT1A,7,KEY,CardID) == MI_OK))

Aynı sorun devam ediyor. MI_ERROR alıyorum sonuç olarak.

Siz arduinoyu hatırlatınca hemen 2 dk da aynı modülü arduino ya bağladım ve içerisine "rfid default keys" örneğini yükledim. 5. dakika olmadan sistemi çalıştırdım.  Denediğim 2 farklı kart var elimde, iki karta da 0xFF keyler ile giriş yapılabiliyor.
Alıntı YapTry the most used default keys to print block 0 of a MIFARE PICC.
Card UID: 59 9F F3 4E
PICC type: MIFARE 1KB
Success with key: FF FF FF FF FF FF
Block 0: 59 9F F3 4E 7B 08 04 00 02 3B E4 D8 2C 1E CE 1D

Card UID: 69 77 DC 06
PICC type: MIFARE 1KB
Success with key: FF FF FF FF FF FF
Block 0: 69 77 DC 06 C4 08 04 00 02 A6 80 7B 00 8A 5B 1D


Blok0 daki datalar telefonumda okuduklarımla uyuşuyor. Ayrıca Block yazma ve okuma örneklerini denedim onlarda çalışıyor. Arduino kütüphanesine biraz bakmam lazım.

Mucit23

Arduino Kütüphanesi Güzel çalışıyor. Ben kendi kütüphanemi biraz debug da inceledim.

Auth İşlemi bu fonksiyonda yapılıyor.
//-------------------------------------------------
TM_MFRC522_Status_t TM_MFRC522_Auth(uint8_t authMode, uint8_t BlockAddr, uint8_t* Sectorkey, uint8_t* serNum) {
	TM_MFRC522_Status_t status;
	uint16_t recvBits;
	uint8_t i;
	uint8_t buff[12]; 

	//Verify the command block address + sector + password + card serial number
	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 = TM_MFRC522_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

	if ((status != MI_OK) || (!(TM_MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) {   
		status = MI_ERR;   
	}

	return status;
}

Program en son burda hataya düşüyor.
if ((status != MI_OK) || (!(TM_MFRC522_ReadRegister(MFRC522_REG_STATUS2) & 0x08))) {   
		status = MI_ERR;   
	}

TM_MFRC522_ToCard fonksiyonuna cevap olarak MI_OK geliyor fakat MFRC522_REG_STATUS2 registerinin 3. biti 0 olduğu için hataya düşüyor.

İlgili bit MFCrypto1On biti şöyle bir açıklama var.
Alıntı Yapindicates that the MIFARE Crypto1 unit is switched on and
therefore all data communication with the card is encrypted
can only be set to logic 1 by a successful execution of the
MFAuthent command
only valid in Read/Write mode for MIFARE standard cards
this bit is cleared by software

Sanırım şifreli haberleşme yapılmadığı için bu hataya düşüyor. Nasıl düzeltilir pek anlayamadım. Çözenler bu işi nasıl çözmüş onuda bilmiyorum.

Akşam CCS C ve Pic için yazılmış kodları bir deneyeyim. Olmadı Arduino Kütüphanesini satır satır ARM da çalışacak şekilde tekrar yazacam. Bu da baya bi vakit demek.

görkem

Hocam ben haberleştirdim ve veri yazıp okuyabilmiştim blok lara. Pc başına geçince göndereyim kodu f103 için kullanmıştım.sağlam saç baş yolmuştum :)

Mucit23

#72
@görkem şuan aynı saç baş yolma evresindeyim. Çok makbule geçer.

@MrDarK Ciddi anlamda internette dolaşan örneklerin hepsi sorunlu. Yada kimsenin bilmediği bir hata yapıyorum. (Bu ihtimal daha kuvvetli) Az önce CCS için verilen örneği Pic16F1827 ile denedim aynı şekilde çalışıyor. Check Ve SelectTag işleminde sorun yok Gayet güzel çalışıyor fakat Auth işlemi yaptığımda program donuyor. Çalışmıyor. Auth yapmadan önce başka bir işlem yapılması gerekiyor fakat bununla ilgili pek bir açıklama bulamadım.

MrDarK

Gerçekten ilginç yaşadıklarınız. Bu kadar zor bir cihaz değil MFRC522 abartmayalım :) 2014 yılında dökümanların eksikliği library'lerin az oluşu vs bana çektirmişti ama hala aynı sorunları yaşıyor olmanız enteresan geliyor.

Fakat bana göre yanlış yoldasınız. Hazır şeylere yönelmeyin artık farklı ne yapıyorsunuz onu arayın. Logic analizör ile registerları kontrol ederek ilerlemenizi öneririm.

Sıralamada farklı veya ekstra birşey yok,
Request -> Anticoll -> Select -> Auth -> Read / Write / X

Picproje Eğitim Gönüllüleri ~ MrDarK

Mucit23

Kullandığım kütüphane de zaten sırayla bunları yapıyorum.

Request ile sorgu yapıyor. OK gelirse Anticoll işlemi ile ID okunuyor. ID okumada sorun yok. Ardından Select Tag yapıyorum. Bu aşamada da sorun yok. Fakat Auth işleminde MFRC522_REG_STATUS2 registerinin StopCrypto1 biti daima sıfır oluyor. En son çıkarken bu register kontrol ediliyor. Bundan dolayı hataya düşüyor.

Bu sorunu yaşayanlar Auth işleminden sonra mutlaka bu bitin temizlenmesi gerektiğini söylüyor fakat bende hiç set edilmiyor. Sorun temelde bu aslında. Bu muhtemelen eksik bir ayarla ilgili fakat dökümanlarda bununla ilgili bir açıklama bulamadım.