QAQ ==!

Dependencies:   mbed QEI-1 nRF24L01P xiugai

pn532_cardcheck.h

Committer:
AlexQian
Date:
2019-12-14
Revision:
15:934289377f7a
Parent:
9:d03b1af2b8d8

File content as of revision 15:934289377f7a:

/*
读取标签卡uid的基本程序.
可以使用i2c, spi, hsu中的某种通讯接口.
*/

#include "mbed.h"
#include "PN532.h"
#include "PN532_HSU.h"
#include "PN532_SPI.h"
#include "PN532_I2C.h"
#include <string>

#define PN532_DBG_PRINT(...) do{}while(0)
//#define PN532_DBG_PRINT(...) pc.printf(##__VA_ARGS__)

class PN532Checker
{
private:
    PN532_HSU *pn532_if;
    PN532 *nfc;
    uint8_t passwd[64], userid[64];
    uint8_t passwd_len, userid_len;

    // card related
    uint8_t key[6];
    uint8_t uid[7];
    uint8_t uidLength; // UID的长度(根据ISO14443A卡类型4或7个字节)
    uint8_t passwd_block;
    uint8_t userid_block;

public:
    PN532Checker(HardwareSerial *pn532_hsu)
    {
        key[0] = 0xFF;
        key[1] = 0xFF;
        key[2] = 0xFF;
        key[3] = 0xFF;
        key[4] = 0xFF;
        key[5] = 0xFF;
        passwd_block = 5;
        userid_block = 6;
        pn532_if = new PN532_HSU(*pn532_hsu);
        nfc = new PN532(*pn532_if);
    }

    ~PN532Checker()
    {
        delete nfc;
        delete pn532_if;
    }
    
    inline void redLedOn()
    {
    	nfc->writeGPIOP3(0);
      nfc->writeGPIOP7((1 << PN532_GPIO_P71)); //MISO P71
	  }

    inline void beep()
    {
    	  nfc->writeGPIOP7(0);
        nfc->writeGPIOP3((1 << PN532_GPIO_P30)|(1 << PN532_GPIO_P31)); //DBGRXD P30  //DBGTXD P31
    }

    inline int setup()
    {
        wait_ms (100);          //等待,初始化pn532过程

        nfc->begin();
			  uint32_t versiondata = nfc->getFirmwareVersion();
			  if(!versiondata){
					PN532_DBG_PRINT("Didn't find PN53x board\r\n");
					return false;
				}

        // 获取ok数据,打印出来!
        PN532_DBG_PRINT ("Found chip PN5%02X , Firmware ver. %d.%d\r\n",
                    (versiondata >> 24) & 0xFF,
                    (versiondata >> 16) & 0xFF,
                    (versiondata >> 8) & 0xFF);

        // 设置从卡片读取的c重复尝试的最大重试次数。
        // 这使我们避免永远的等待读取一个卡,永远等待是PN532默认行为
        //nfc->setPassiveActivationRetries(0xFF);

        // 配置板读取RFID标签
        nfc->SAMConfig();
        
        //亮红灯
        redLedOn();

        return true;
    }

    inline int start_check(int timeout)  // polling
    {
        // Input:
        //  timeout: ms
        // Output:
        //   true/false
        //   if true, you can then call get_userid/get_passwd
        bool read_done = false;
        bool time_count = 0;
        while (!read_done && time_count < timeout) {
            bool success;
            uint16_t timeo = 50;

            // 配置板读取RFID标签
            //nfc->SAMConfig();

            // 等待一个ISO14443A类型的卡(如Mifare卡等). 当发现一个时,'uid'会被UID填充,并且uid长度会指出该uid是4字节(典型的Mifare)或7字节(超轻Mifare),100是超时时间(单位是毫秒,ms)
            success = nfc->readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength, timeo);
            if (success) {
                PN532_DBG_PRINT("Found a Mifare card!\r\n");
                PN532_DBG_PRINT("UID Length: %d bytes\r\n", uidLength);
                PN532_DBG_PRINT("UID Value:");
                for (int i = 0; i < uidLength; i++)
                    PN532_DBG_PRINT(" 0x%02X", uid[i]);
                PN532_DBG_PRINT("\r\n");

                success = nfc->mifareclassic_AuthenticateBlock(uid, uidLength, 7, 0, key);  // TODO
                if (success) {
                   PN532_DBG_PRINT("Authen success!\r\n");
                }
                PN532_DBG_PRINT("read block\r\n");
                success = nfc->mifareclassic_ReadDataBlock(passwd_block, passwd) & \
                          nfc->mifareclassic_ReadDataBlock(userid_block, userid);
                if (success) {
										passwd_len = 8;
										userid_len = 10;
                    PN532_DBG_PRINT("read success!\r\n");
                    read_done = true;
            		    beep();
									  wait_ms (50);
									
										for (int i = 0; i < 16; ++i) {
												PN532_DBG_PRINT("0x%x ", passwd[i]);
										}
                    PN532_DBG_PRINT("\r\n");
                }
								
								nfc->inRelease(0); //Release all cards

                //wait_ms (50);
    		      	redLedOn();

                // 等到移开卡时
                //while (nfc->readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength, 50)) {}

            } else {
                // PN532可能等待卡片超时
                PN532_DBG_PRINT("Timed out waiting for Mifare card\r\n");
                //wait_ms (200);
            }
 
						uint8_t AFI[] = {0};
						success = nfc->inListPassiveTarget(PN532_106KBPS_ISO14443B, sizeof(AFI) , AFI, 200);
						if (success) {
							uint8_t expire[3];
							nfc->inRelease();
							
							success = nfc->readTsighuaStuCard(uid, expire,(char*) userid);
							if(success){
								uidLength = 3;
								userid_len = 10;
								passwd_len = 0;
								PN532_DBG_PRINT("Found a student card!\r\n");
								PN532_DBG_PRINT("Student Number: %s\r\n", userid);
								read_done = true;
								beep();
								wait_ms (50);
    		      	redLedOn();
							}
							nfc->resetConfigFor14443B();
						} else {
                PN532_DBG_PRINT("Timed out waiting for student card\r\n");
            }


						time_count += timeo;
        }
        return read_done;
    }
    
    std::string get_passwd() { return std::string((char*)passwd, passwd_len); }
    std::string get_userid() { return std::string((char*)userid, userid_len); }

    inline int get_passwd(uint8_t *passwd)
    {
        for (int i = 0; i < passwd_len; ++i) {
            passwd[i] = this->passwd[i];
        }
        return passwd_len;
    }

    inline int get_userid(uint8_t *userid)
    {
        for (int i = 0; i < userid_len; ++i) {
            userid[i] = this->userid[i];
        }
        return userid_len;
    }
};