Exemple #1
0
/**
 *		\brief Funkcja inicjalizująca piny GPIO, interfejs SPI oraz moduł RC522.
 *
 *		\warning Musi zostać wywołana przed pętlą nieskończoną w funkcji main()
 */
void RFID_init(void)
{
	uint8_t temp=0;
	// właczenie zegara do portów 
	SIM->SCGC5 |= SIM_SCGC5_PORTA_MASK
			|  SIM_SCGC5_PORTB_MASK
			|  SIM_SCGC5_PORTC_MASK
			|  SIM_SCGC5_PORTD_MASK
			|  SIM_SCGC5_PORTE_MASK;
	SPI_init();		// inicjalizacja SPI

	/* USTAWIENIE PORTU ODPOWIEDZIALNEGO ZA RESET SPRZĘTOWY UKŁADU MFRC522 */
	RESET_PORTx->PCR[RESET_NUMBER] |= PORT_PCR_MUX(1);
	RESET_PTx->PDDR |= (1<<RESET_NUMBER);
	RESET_PTx->PSOR |= (1<<RESET_NUMBER);		

	RC522_write(CommandReg,SoftReset_CMD);		// reset programowy, przywraca domyślne wartości wszystkim rejestrom

	RC522_write(TModeReg, 0x8D);					// TModeReg -> konfiguruje zewnętrzny timer => timer startuje od razu po zakończeniu transmisji, 0xD00 -> tak ustawione są 4 starsze bity preskalera
	RC522_write(TPrescalerReg, 0x3E);			// definiuje ustawienie 8 młodszych bitów preskalera 0x03E
	RC522_write(TReloadReg_1, 30);				// wartość rejestru przeładowania starszy bajt
	RC522_write(TReloadReg_2, 0);					// wartość rejstru przeładowania młodszy bajt
	RC522_write(TxASKReg, 0x40);					// rejestr kontroluje ustawienia modulacji transmisji => 100% używamy modulacji ASK niezależnie od ustawień rejestru ModGsPReg
	RC522_write(ModeReg, 0x3D);	          // rejestr od generalnych ustawień transmisji => tramiter stratuje tylko jest pole elektryczne,MFIN jest aktywny w stanie wysokim,usatwienie wartości startowej dla CRC


	// sprawdzenie włączenia anteny jeśli jest wyłączona to ją właczamy
	temp = RC522_read(TxControlReg);
	if(!(temp&0x03))
	{
		RC522_write(TxControlReg,temp|0x03);
	}
}
Exemple #2
0
/**
 *		\brief Funkcja odczytująca unikalny numer seryjny karty.
 *
 *		\param uint8_t *serial_out - wskaźnik do tablicy o wymiarze minimum 5, w której zapisujemy wynik pomiarów
 *	  \returns Zwraca status powodzenia wykonanej operacji 
 *		UID - Unique ID ( unikalny numer seryjny )
 *		\warning Przed wywołaniem funkcji karta musi zostać aktywowana wywołaniem funkcji RFID_request(...)
 *						 
 */
uint8_t RFID_read_card(uint8_t *serial_out)
{
	uint8_t status;           // trzyma aktualny status 
	uint8_t i;							  // zmienna pomocnicza
	uint8_t serNumCheck=0;		// zmienna służąca do sprawdzania poprawności odbioru serial number
	uint32_t unLen;           // zmienna pomocnicza

	RC522_write(BitFramingReg, 0x00);		//nTxLastBists = BitFramingReg[2..0]
	// ustawienie nadawania ramki danych do karty złożonej z 8 bitów

	serial_out[0] = PICC_ANTICOLL;			// ta komenda karty zwraca nam jej numer seryjny 
	serial_out[1] = 0x20;					
	status = RC522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);

	if (status == CARD_FOUND)
	{
		//Check card serial number
		// jeżeli po 4 krotnym xorowaniu wyjdzie nam to samo to znaczy się że odberany serial number z karty jest poprawny
		for (i=0; i<4; i++)
		{
			serNumCheck ^= serial_out[i];
		}
		if (serNumCheck != serial_out[i])
		{
			status = ERROR;
		}
	}
	return status;
}
Exemple #3
0
/**
 *	\brief Funkcja inicjuje komunikacje z kartą znajdującą się w zasięgu anteny czytnika.
 *
 * \param uint8_t *tag_type - wskaźnik do tablicy do której ma zostać napisany typ karty którą odczytujemy
 *	\return Zwraca status powodzenia komunikacji 
 *		
 * Funkcja wysyła rządanie nawiązania kounikacji do kart które znajdują się w polu magnetycznym czytnika. 
 * Karta odsyła nam jako informację zwrotną jakim jest typem
 *  
 */
uint8_t	RFID_request(uint8_t *tag_type)
{
	uint8_t  status=0;		// zmienna pomocnicza 
	uint32_t backBits=0;	// liczba otrzymanych z karty danych 

	RC522_write(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0], bit framing pokazuje jakiej długości mamy ramkę. Komenda reqall jest 7 bitowa zatem ustawiamy 0x07

	tag_type[0] = PICC_REQALL;						// przekazujemy do wysłania komendę typu request 
	status = RC522_to_card(Transceive_CMD, tag_type, 1, tag_type, &backBits);
	// Transcive CMD to komenda RC522 mówiąca że ma przesłać zawartość bufora FIFO
	if ((status != CARD_FOUND) || (backBits != 0x10))  // odpowiedź na zapytanie REQ ma 16bitów długości (0x10) zatem jeśli otrzymaliśmy inną długość ( w FIFO RC522) znalazło się więcej bajtów to znaczy że wystąpił błąd i nie oczytaliśmy poprawnie danych
	{
		status = ERROR;
	}

	return status;
}
void RC522_writeMI(u8 block, u8 *pKey, u8* data, u8 *pTagType, u8 *SelectedSnr)
{
    s8 status;
    status = RC522_request(MI_REQSTD, pTagType);
    if(!status)
    {
        status = RC522_anticoll(SelectedSnr);
        if(!status)
        {
            status = RC522_select(SelectedSnr);
            if(!status)
            {
                if(block == 0)
                {
                    status = RC522_halt();
                    if(!status)
                    {
                        status = RC522_unlock0(MI_UNLOCK0);
                        if(!status) status = RC522_unlock1(MI_UNLOCK1);
                        else printf("Unlock I Error\r\n");
                    }
                    else printf("Halt Error\r\n");
                }
                else status = RC522_auth(MI_AUTHENT1A, block, pKey, SelectedSnr);
                if(!status)
                {
                    status = RC522_write(block, data);
                    if(!status)
                    {
                        printf("Write Succeed\r\n");
                        RC522_wait4CardOff();
                    }
                    else printf("Write Error\r\n");
                }
                else printf("Auth Error\r\n");
            }
            else printf("Select Error\r\n");
        }
        else printf("Anticoll Error\r\n");
    }
    //else printf("Request Error\r\n");
}
Exemple #5
0
/**
 * \brief Funkcja realizująca komunikację kartą MIFARE poprzez RC522.
 *
 *	\param uint8_t cmd - komenda jaką ma zrealizować RC522
 *	\param uint8_t *send_data - wskaźnik do danych które chcemy wysłać do karty (mogą to być komendy obsługiwane przez kartę np PIC_REQALL
 *  \param uint8_t send_data_lenght - ile danych wysyłamy do karty
 *  \param uint8_t *back_data - wskaźnik do tablicy/zmiennej w której zapisujemy dane odebrane z karty (UID, zapisane wcześniej dane)
 *  \param uint32_t *back_data_lenght - ilość danych jaka znajduje się w buforze FIFO, i którą musimy odebrać
 *	\returns Zwraca status powodzenia wykonanej operacji 
 *
 * Realizuje podstawową komunikację z kartą typu MIFARE. Możliwe jest wysyłanie komend i danych do karty RFID. 
 * Funkcja umożliwia również odbiór danych z karty.
 */
uint8_t RC522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
	uint8_t status = ERROR;					// zmienna statusowa, jej zawartość jest zwracana po zakończeniu funckji 
	uint8_t irqEn = 0x00;						// póki co nie wiem co to wgl jest :(
	uint8_t waitIRq = 0x00;         // póki co nie wiem co to wgl jest :(
	uint8_t lastBits;
	uint8_t n;
	uint8_t	tmp;
	uint32_t i;

	switch (cmd)
	{
	case MFAuthent_CMD:		//Certification cards close
		irqEn = 0x12;
		waitIRq = 0x10;   
		break;

	case Transceive_CMD:	  //Transmit FIFO data
		irqEn = 0x77;
		waitIRq = 0x30;
		break;

	default:
		break;
	}

	/* PRZYGOTWANIE RC522 na komunikacja z kartą zbliżeniową */
	n=RC522_read(ComIrqReg);             // odczytuje stan wymuszeń przerwań
	RC522_write(ComIrqReg,n&(~0x80));    // czyścimy wszystkie przerwania 
	n=RC522_read(FIFOLevelReg);					 // odczytujemy poziom zapełnienia rejestru FIFO 
	RC522_write(FIFOLevelReg,n|0x80);    // kasujemy rejestr FIFO
	RC522_write(CommandReg, Idle_CMD);   // NO action; przerywa aktualne operacje przetwarzane przez RC522

	// Kopiujemy do rejestru FIFO RC522 dane do wysyłki ( mogą to też być komendy sterujące kartą )
	for (i=0; i<send_data_len; i++)
	{
		RC522_write(FIFODataReg, send_data[i]);
	}

	//Execute the cmd
	RC522_write(CommandReg, cmd);
	if (cmd == Transceive_CMD)
	{
		n=RC522_read(BitFramingReg);
		RC522_write(BitFramingReg,n|0x80);
	}

	// oczekiwanie na zakończenie wysyłania danych
	// gdyby się nie udało odczytać karty i timer wbudowany w RC522 nie zakończył transmisji
	// jest to dodatkowa pętla oczekująca, gdy zawiodą inne zabezpieczenia
	// pętla zakończy działanie prgoramu i wyświetli błąd
	// zegar zrywający transmisję przekręca się co 25ms. Startuje on zaraz gdy PCD zakończy transmisję.
	i = 2000;	
	do
	{
		//CommIrqReg[7..0]
		//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
		n = RC522_read(ComIrqReg);			// czytamy zawartość rejestru przerwań
		i--;														// teraz n trzyma wartość rejestru przerwań po zakończeniu transmisji, nie wolno nadpisać tej zmiennej!!!
	}
	while ((i!=0) && !(n&0x01) && !(n&waitIRq));  
	// przerywamy pętlę gdy:
	// a) doliczyliśmy do 0      => równoznaczne z błędem transmisji 
	// b) timer doliczył do zera => równoznaczne z timeout'em transmisji
	// c) zawartość rejestru pokrywa się z oczekiwaniami => transmija mogła się zakończyć dobrze , sprawdzamy czy tak się stało 


	tmp=RC522_read(BitFramingReg);
	RC522_write(BitFramingReg,tmp&(~0x80));  // wyłączamy zezwolenie na transmisję 

	/* SPRAWDZAMY STAN PO ZAKOŃCZENIU TRANSMISJI */
	if (i != 0)		// jeśli trasnmisja zakończyła się przed obiegiem pętli
	{
		// sprawdzamy czy w rejestrze pojawiły się jakieś błędy
		if(!(RC522_read(ErrorReg) & 0x1B))	//BufferOvfl Collerr CRCErr ProtecolErr
		{

			status = CARD_FOUND;   	// jeśli nie ma błędów to karta znaleziona poprawnie
			if (n & irqEn & 0x01)   // jeśli po zakończeniu transmisji wiemy że timer doliczył do końca to karta nie została znaleziona, zwracamy błąd
			{
				status = CARD_NOT_FOUND;			//??
			}

			if (cmd == Transceive_CMD)  // jeśli przesyłaliśmy dane 
			{
				n = RC522_read(FIFOLevelReg);							// przypisujemy zmiennej n ilość danych odebranych z karty 
				lastBits = RC522_read(ControlReg) & 0x07; // sprawdzamy ile bitów w ostatnim odebranym bajcie jest do odczytania przez nas 
				if (lastBits)
				{
					*back_data_len = (n-1)*8 + lastBits;
					// mówi nam ile bitów jest poprawnych 

				}
				else
				{
					*back_data_len = n*8; // jeżeli lasBits == 0 to cały baj jest ok
					// długość danych do odczytu to: ilość bajtów*8 bitów
				}
				if (n == 0) // jeśli FIFO pokazuje nam że odczytaliśmy 0 bajtów to tak naprawdę mamy jeden bajt odbrany
				{
					n = 1;		// odczytaliśmy 1 bajt
				}
				if (n > MAX_LEN)
				{
					n = MAX_LEN;
					// możemy odczytać maksymalnie tyle bajtów jak duży mamy bufor 
				}

				// pętla odczytująca wszystkie odbrane dane 
				for (i=0; i<n; i++)
				{
					back_data[i] = RC522_read(FIFODataReg);
				}
			}
		}
		else // jeśli transmija została zakończona przez pętlę zabezpieczającą to wiemy że na pewno mamy błąd w transmisji 
		{
			status = ERROR;
		}

	}

	return status;
}