RC663-读取14443 UID-mifare classic & mifare ultralight

#测试环境
Arduino SPI接口

在这里插入图片描述

在这里插入图片描述

1、程序入口初始化printf打印,调用RFID接口 main.ino



int serial_putc(char c, struct __file*) {
  Serial.write(c);
  return c;
}
void printf_begin(void) {
  fdevopen(&serial_putc, 0);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  printf_begin();

  RC663_Init();
}

void loop() {
  // put your main code here, to run repeatedly:
  uint8_t uid[8];

  printf("RC663_Version:");
  printf("%2.2x\n", RC663_ReadReg(0x7f));
  bt_rfid_query_14443a(uid);
  delay(1000);
}

## 2、RFID读UID示例 librc663.ino

> Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本、小容量的卡片。低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片之一;小容量,是指其存储容量只有512bit(Mifare S50有8192bit)。
		Mifare Ulitralight的卡序列号有7个字节,而Mifare S50的卡序列号只有4个字节,因此在卡片防冲突选择阶段需要两层(Cascade93H和95H)操作;

```c

#include <stdint.h>
#include "librc663.h"

#define SPI_PIN_NSS (49)
#define SPI_PIN_SCK (48)
#define SPI_PIN_MOSI (47)
#define SPI_PIN_MISO (46)

void RC663_Init(void) {
  pinMode(SPI_PIN_NSS, OUTPUT);
  pinMode(SPI_PIN_SCK, OUTPUT);
  pinMode(SPI_PIN_MOSI, OUTPUT);
  pinMode(SPI_PIN_MISO, INPUT);
}

void _delay() {
  for (volatile uint32_t i = 0; i < 20; i++)
    ;
}

void RC663_WriteReg(uint8_t address, uint8_t value) {
  uint8_t i;
  digitalWrite(SPI_PIN_SCK, LOW);
  digitalWrite(SPI_PIN_NSS, LOW);

  address = (address << 1) & 0xfe;  // 低位为0

  for (i = 8; i > 0; i--) {
    if (address & 0x80) {
      digitalWrite(SPI_PIN_MOSI, HIGH);
    } else {
      digitalWrite(SPI_PIN_MOSI, LOW);
    }
    digitalWrite(SPI_PIN_SCK, HIGH);
    _delay();
    address <<= 1;
    digitalWrite(SPI_PIN_SCK, LOW);
    _delay();
  }
  for (i = 8; i > 0; i--) {
    if (value & 0x80) {
      digitalWrite(SPI_PIN_MOSI, HIGH);
    } else {
      digitalWrite(SPI_PIN_MOSI, LOW);
    }
    digitalWrite(SPI_PIN_SCK, HIGH);
    _delay();
    value <<= 1;
    digitalWrite(SPI_PIN_SCK, LOW);

    _delay();
  }
  digitalWrite(SPI_PIN_SCK, HIGH);
  digitalWrite(SPI_PIN_NSS, HIGH);
}

uint8_t RC663_ReadReg(uint8_t ucAddr) {
  uint8_t i;
  uint8_t ucResult = 0;
  digitalWrite(SPI_PIN_SCK, LOW);
  digitalWrite(SPI_PIN_NSS, LOW);
  _delay();
  // 读寄存器需要地址转换
  ucAddr = (ucAddr << 1) | 0x01;  // 读最低位为1

  for (i = 8; i > 0; i--) {
    if (ucAddr & 0x80) {
      digitalWrite(SPI_PIN_MOSI, HIGH);
    } else {
      digitalWrite(SPI_PIN_MOSI, LOW);
    }
    digitalWrite(SPI_PIN_SCK, HIGH);
    _delay();
    ucAddr <<= 1;
    digitalWrite(SPI_PIN_SCK, LOW);

    _delay();
  }
  for (i = 8; i > 0; i--)  // 接收数据
  {
    digitalWrite(SPI_PIN_SCK, HIGH);

    _delay();
    ucResult <<= 1;

    if (digitalRead(SPI_PIN_MISO)) {
      ucResult |= 1;
    }
    digitalWrite(SPI_PIN_SCK, LOW);
    _delay();
  }
  // printf("value:%x \n", ucResult);

  digitalWrite(SPI_PIN_SCK, HIGH);
  digitalWrite(SPI_PIN_NSS, HIGH);
  return ucResult;
}

void RC663_SetBitMask(uint8_t reg, uint8_t mask) {
  uint8_t tmp = RC663_ReadReg(reg);
  RC663_WriteReg(reg, tmp | mask);
}

void RC663_ClearBitMask(uint8_t reg, uint8_t mask) {
  uint8_t tmp = RC663_ReadReg(reg);
  RC663_WriteReg(reg, tmp & ~mask);
}

void RC663_SetRawRC(uint8_t reg, uint8_t mask, uint8_t set) {
  uint8_t temp = RC663_ReadReg(reg);
  temp = (temp & mask) | set;
  RC663_WriteReg(reg, temp);
}
///
void RC663_FlushFifo() {
  RC663_SetBitMask(rRegFIFOControl, 0x10);
}

void RC663_FieldOn() {
  RC663_SetBitMask(rRegDrvMod, 0x08);
}

void RC663_FieldOff() {
  RC663_ClearBitMask(rRegDrvMod, 0x08);
}

void RC663_FieldReset() {
  RC663_FieldOff();
  delay(20);
  RC663_FieldOn();
  delay(20);
}

// extern uint8_t Status_INT;
uint8_t mode;
int8_t RC663_Command_Int(struct TranSciveBuffer *pi) {
  uint16_t i;
  uint8_t j, n;
  RC663_WriteReg(rRegCommand, RC663_Idle);
  RC663_SetBitMask(rRegFIFOControl, 0x10);  // FlushFifo
  RC663_WriteReg(rRegIRQ0, 0x7F);
  RC663_WriteReg(rRegIRQ1, 0x7F);

  for (n = 0; n < pi->Length; n++)
    RC663_WriteReg(rRegFIFOData, pi->Data[n]);
  if (pi->Command & 0x80) {
    RC663_WriteReg(rRegIRQ0En, 0x90);
    if (mode)
      RC663_WriteReg(rRegIRQ1En, 0xE0);
    else
      RC663_WriteReg(rRegIRQ1En, 0xE8);
#if 0
		Status_INT = 0;
		RC663_WriteReg(rRegCommand, pi->Command);
		while (Status_INT == 0)
			; // wait for IRQ
		Status_INT = 0;
#else
    RC663_WriteReg(rRegCommand, pi->Command);
    delay(1000);
    delay(1000);
    delay(1000);

#endif

    RC663_WriteReg(rRegIRQ0En, 0x10);
    if (mode)
      RC663_WriteReg(rRegIRQ1En, 0x20);
    else
      RC663_WriteReg(rRegIRQ1En, 0x28);
  } else
    RC663_WriteReg(rRegCommand, pi->Command);

  for (i = 2000; i > 0; i--) {
    n = RC663_ReadReg(rRegIRQ0);
    if (n & 0x10)
      break;  // IDLEIRQ
  }
  if (i == 0)
    return MI_ERR;
  n = RC663_ReadReg(rRegFIFOLength);
#if 0
	printf("N:%x\n", n);
	if (n > 64)
		n = 64;
#endif
  for (j = 0; j < n; j++)
    pi->Data[j % 64] = RC663_ReadReg(rRegFIFOData);
  return MI_OK;
}

int8_t RC663_CMD_LoadProtocol(uint8_t rx, uint8_t tx) {
  struct TranSciveBuffer ComData;

  ComData.Command = RC663_LoadProtocol;
  ComData.Length = 2;
  ComData.Data[0] = rx;
  ComData.Data[1] = tx;

  return RC663_Command_Int(&ComData);
}

int8_t RC663_CMD_LoadKey(uint8_t *pkey) {
  struct TranSciveBuffer ComData;

  ComData.Command = RC663_LoadKey;
  ComData.Length = 6;
  memcpy(ComData.Data, pkey, 6);

  return RC663_Command_Int(&ComData);
}

int8_t RC663_CMD_MfcAuthenticate(uint8_t auth_mode, uint8_t block, uint8_t *pSnr) {
  int8_t status;
  uint8_t reg;
  struct TranSciveBuffer ComData;

  ComData.Command = RC663_MFAuthent;
  ComData.Length = 6;
  ComData.Data[0] = auth_mode;
  ComData.Data[1] = block;
  memcpy(&ComData.Data[2], pSnr, 4);

  status = RC663_Command_Int(&ComData);
  if (status == MI_OK) {
    reg = RC663_ReadReg(rRegStatus);
    if (!(reg & 0x20))
      status = MI_AUTHERR;
  }
  return status;
}

int8_t RC663_PcdConfigISOType(uint8_t type) {
  //	uint8_t temp;
  RC663_WriteReg(rRegT0Control, 0x98);   // Starts at the end of Tx. Stops after Rx of first data. Auto-reloaded. 13.56 MHz input clock.
  RC663_WriteReg(rRegT1Control, 0x92);   // Starts at the end of Tx. Stops after Rx of first data. Input clock - cascaded with Timer-0.
  RC663_WriteReg(rRegT2Control, 0x20);   // Timer used for LFO trimming
  RC663_WriteReg(rRegT2ReloadHi, 0x03);  //
  RC663_WriteReg(rRegT2ReloadLo, 0xFF);  //
  RC663_WriteReg(rRegT3Control, 0x00);   // Not started automatically. Not reloaded. Input clock 13.56 MHz
  if (type == 'A') {
    RC663_WriteReg(rRegWaterLevel, 0x10);  // Set WaterLevel =(FIFO length -1)

    RC663_WriteReg(rRegRxBitCtrl, 0x80);  // Received bit after collision are replaced with 1.
    RC663_WriteReg(rRegDrvMod, 0x80);     // Tx2Inv=1
#if 1
    RC663_WriteReg(rRegTxAmp, 0xC0);  // 0x00
#else
    RC663_WriteReg(rRegTxAmp, 0x40);        // 0x00
#endif

    RC663_WriteReg(rRegDrvCon, 0x09);  // 01
    RC663_WriteReg(rRegTxl, 0x05);     //
    RC663_WriteReg(rRegRxSofD, 0x00);  //

    RC663_CMD_LoadProtocol(0, 0);

    // Disable Irq 0,1 sources
    RC663_WriteReg(rRegIRQ0En, 0);
    RC663_WriteReg(rRegIRQ1En, 0);

    RC663_WriteReg(rRegFIFOControl, 0xB0);

    RC663_WriteReg(rRegTxModWidth, 0x20);    // Length of the pulse modulation in carrier clks+1
    RC663_WriteReg(rRegTxSym10BurstLen, 0);  // Symbol 1 and 0 burst lengths = 8 bits.
    RC663_WriteReg(rRegFrameCon, 0xCF);      // Start symbol=Symbol2, Stop symbol=Symbol3

    RC663_WriteReg(rRegRxCtrl, 0x04);  // Set Rx Baudrate 106 kBaud
#if 1
    RC663_WriteReg(rRegRxThreshold, 0x55);  // Set min-levels for Rx and phase shift  //32
#else
    RC663_WriteReg(rRegRxThreshold, 0x33);  // Set min-levels for Rx and phase shift  //32

#endif
    RC663_WriteReg(rRegRcv, 0x12);    //
    RC663_WriteReg(rRegRxAna, 0x0A);  // 0

    RC663_WriteReg(rRegDrvMod, 0x81);
    //> MIFARE Crypto1 state is further disabled.
    RC663_WriteReg(rRegStatus, 0);
    //>  FieldOn
    RC663_WriteReg(rRegDrvMod, 0x89);
  } else if (type == 'B') {
    RC663_WriteReg(rRegWaterLevel, 0x10);  // Set WaterLevel =(FIFO length -1)

    RC663_WriteReg(rRegRxBitCtrl, 0x80);  // Received bit after collision are replaced with 1.
    RC663_WriteReg(rRegDrvMod, 0x8F);     // Tx2Inv=1
    RC663_WriteReg(rRegTxAmp, 0x0C);      // 0xCC
    RC663_WriteReg(rRegDrvCon, 0x01);
    RC663_WriteReg(rRegTxl, 0x05);
    RC663_WriteReg(rRegRxSofD, 0x00);

    RC663_CMD_LoadProtocol(4, 4);

    // Disable Irq 0,1 sources
    RC663_WriteReg(rRegIRQ0En, 0);
    RC663_WriteReg(rRegIRQ1En, 0);

    RC663_WriteReg(rRegFIFOControl, 0xB0);

    RC663_WriteReg(rRegTxModWidth, 0x0A);    // Length of the pulse modulation in carrier clks+1
    RC663_WriteReg(rRegTxSym10BurstLen, 0);  // Symbol 1 and 0 burst lengths = 8 bits.
    RC663_WriteReg(rRegTXWaitCtrl, 1);
    RC663_WriteReg(rRegFrameCon, 0x05);
    RC663_WriteReg(rRegRxSofD, 0xB2);

    RC663_WriteReg(rRegRxCtrl, 0x34);       // Set Rx Baudrate 106 kBaud
    RC663_WriteReg(rRegRxThreshold, 0x9F);  // Set min-levels for Rx and phase shift  0x7F
    RC663_WriteReg(rRegRcv, 0x12);
    RC663_WriteReg(rRegRxAna, 0x0a);  // 0x0a 0X0e

    RC663_WriteReg(rRegDrvMod, 0x87);
    RC663_WriteReg(rRegStatus, 0);
    //>  FieldOn
    RC663_WriteReg(rRegDrvMod, 0x8F);
  } else if (type == 'F') {
    RC663_WriteReg(rRegWaterLevel, 0x10);  // Set WaterLevel =(FIFO length -1)

    RC663_WriteReg(rRegRxBitCtrl, 0x80);  // Received bit after collision are replaced with 1.
    RC663_WriteReg(rRegDrvMod, 0x88);     // Tx2Inv=1
    RC663_WriteReg(rRegTxAmp, 0x04);      //
    RC663_WriteReg(rRegDrvCon, 0x01);     //
    RC663_WriteReg(rRegTxl, 0x05);        //
    RC663_WriteReg(rRegRxSofD, 0x00);     //

    RC663_CMD_LoadProtocol(8, 8);

    // Disable Irq 0,1 sources
    RC663_WriteReg(rRegIRQ0En, 0);
    RC663_WriteReg(rRegIRQ1En, 0);

    RC663_WriteReg(rRegFIFOControl, 0xB0);

    RC663_WriteReg(rRegTxModWidth, 0x00);       // Length of the pulse modulation in carrier clks+1
    RC663_WriteReg(rRegTxSym10BurstLen, 0x03);  // Symbol 1 and 0 burst lengths = 8 bits.
    // RC663_WriteReg(rRegTXWaitCtrl,0xC0);
    // RC663_WriteReg(rRegTxWaitLo,0);
    RC663_WriteReg(rRegFrameCon, 0x01);

    // RC663_WriteReg(rRegRxSofD,0xB2);

    RC663_WriteReg(rRegRxCtrl, 0x05);       // Set Rx Baudrate 212 kBaud
    RC663_WriteReg(rRegRxThreshold, 0x5C);  // Set min-levels for Rx and phase shift  0x3C
    RC663_WriteReg(rRegRcv, 0x12);
    RC663_WriteReg(rRegRxAna, 0x02);  // 0xa  initial value 0x02

    RC663_WriteReg(rRegRxWait, 0x86);

    RC663_WriteReg(rRegDrvMod, 0x87);
    RC663_WriteReg(rRegStatus, 0);
    //>  FieldOn
    RC663_WriteReg(rRegDrvMod, 0x8F);
  } else if (type == 'V') {
    RC663_WriteReg(rRegWaterLevel, 0x10);  // Set WaterLevel =(FIFO length -1)

    RC663_WriteReg(rRegRxBitCtrl, 0x80);  // Received bit after collision are replaced with 1.
    RC663_WriteReg(rRegDrvMod, 0x89);     // Tx2Inv=1 0x80
    RC663_WriteReg(rRegTxAmp, 0x10);      // 0	//0x04
    RC663_WriteReg(rRegDrvCon, 0x09);     // 0x01
    RC663_WriteReg(rRegTxl, 0x0A);        // 0x05
    RC663_WriteReg(rRegRxSofD, 0x00);     //

    RC663_CMD_LoadProtocol(0x0A, 0x0A);

    // Disable Irq 0,1 sources
    RC663_WriteReg(rRegIRQ0En, 0);
    RC663_WriteReg(rRegIRQ1En, 0);

    RC663_WriteReg(rRegFIFOControl, 0xB0);

    RC663_WriteReg(rRegTxModWidth, 0x00);    // Length of the pulse modulation in carrier clks+1
    RC663_WriteReg(rRegTxSym10BurstLen, 0);  // Symbol 1 and 0 burst lengths = 8 bits.
    // RC663_WriteReg(rRegTXWaitCtrl,0xC0);	//0x88
    // RC663_WriteReg(rRegTxWaitLo,0);	//0xa9
    RC663_WriteReg(rRegFrameCon, 0x0F);

    // RC663_WriteReg(rRegRxSofD,0xB2);

    RC663_WriteReg(rRegRxCtrl, 0x02);       // Set Rx Baudrate 26 kBaud
    RC663_WriteReg(rRegRxThreshold, 0x74);  // Set min-levels for Rx and phase shift
    RC663_WriteReg(rRegRcv, 0x12);
    RC663_WriteReg(rRegRxAna, 0x07);

    RC663_WriteReg(rRegRxWait, 0x9C);

    RC663_WriteReg(rRegDrvMod, 0x81);
    RC663_WriteReg(rRegStatus, 0);
    //>  FieldOn
    RC663_WriteReg(rRegDrvMod, 0x89);
  }
  return MI_OK;
}

void reset() {
  uint32_t volatile i;
  // // RSET signal low
  // RF_RST_GPIO_L();

  // // delay of ~1,2 ms
  // for (i = 0x2000; i > 0; i--)
  //   ;
  // delay(10);
  // // RSET signal high to reset the RC663 IC
  // RF_RST_GPIO_H();

  // // // delay of ~1,2 ms
  // // for (i = 0x2000; i > 0; i--)
  // // 	;
  // delay(10);

  // // RSET signal low
  // RF_RST_GPIO_L();

  // // delay of ~1,2 ms
  // for (i = 0x2000; i > 0; i--)
  //   ;
}
int8_t RC663_PcdComTransceive(struct TranSciveBuffer *pi) {
  int8_t status = MI_ERR;
  uint16_t i;
  uint8_t reg1, temp, lastBits;  // reg0,
  uint8_t errReg;
  // Terminate any running command.
  RC663_WriteReg(rRegCommand, RC663_Idle);  // 0x00 // Starts and stops command execution
  RC663_SetBitMask(rRegFIFOControl, 0x10);  // Flush_FiFo     0x02 // Control register of the FIFO
  // Clear all IRQ 0,1 flags
  RC663_WriteReg(rRegIRQ0, 0x7F);
  RC663_WriteReg(rRegIRQ1, 0x7F);

  for (i = 0; i < pi->Length; i++)
    RC663_WriteReg(rRegFIFOData, pi->Data[i]);  //  0x05 // Data In/Out exchange register of FIFO buffer
  // Idle interrupt(Command terminated), RC663_BIT_IDLEIRQ=0x10
  RC663_WriteReg(rRegIRQ0En, 0x18);  // IdleIRQEn,TxIRQEn
  RC663_WriteReg(rRegIRQ1En, 0x42);  // Global IRQ,Timer1IRQEn
  //>  Start RC663 command "Transcieve"=0x07. Activate Rx after Tx finishes.
  RC663_WriteReg(rRegCommand, RC663_Transceive);
#if 1
  i = 0;
  do {
    if (i++ > 0x800)
      return MI_ERR;  // 超时

    reg1 = RC663_ReadReg(rRegIRQ1);  // 07h //wait for TxIRQ
  } while ((reg1 & 0x40) == 0);      // GlobalIRQ
#else
  do {
    reg1 = RC663_ReadReg(rRegIRQ0);  // 07h //wait for TxIRQ
    if (reg1 & 0x8)
      break;                         // TxIRQ
    reg1 = RC663_ReadReg(rRegIRQ1);  // 07h //wait for TxIRQ
    if (reg1 & 0x2)
      break;                         // Timer1IRQEn
  } while (1);                       //(reg1 & 0x40) == 0); // GlobalIRQ

#endif
  RC663_WriteReg(rRegIRQ0En, 0x54);  // HiAlertIRQEN,IdleIRQEn,RxIRQEn
  RC663_WriteReg(rRegIRQ1En, 0x42);  // Global IRQ,Timer1IRQEn

  for (i = 8000; i > 0; i--) {
#if 1
    reg1 = RC663_ReadReg(rRegIRQ1);  // 07h  //wait for RxIRQ
    if (reg1 & 0x40)
      break;  // GlobalIRQ
#else
    reg1 = RC663_ReadReg(rRegIRQ0);  // 07h  //wait for RxIRQ
    if (reg1 & 0x04)
      break;                         // RxIRQEn
    reg1 = RC663_ReadReg(rRegIRQ1);  // 07h  //wait for RxIRQ
    if (reg1 & 0x02)
      break;  // Timer1IRQEn
#endif
  }

  RC663_WriteReg(rRegIRQ0En, 0);
  RC663_WriteReg(rRegIRQ1En, 0);

  errReg = RC663_ReadReg(rRegError);
  // printf("errReg %x\n", errReg);

  if (i == 0) {
    status = MI_QUIT;
  } else if (reg1 & 0x02)  // Timer1IRQ
  {
    status = MI_NOTAGERR;
  } else if (errReg)  // 0Bh
  {
    if (errReg & 0x04)
      status = MI_COLLERR;
    else if (errReg & 0x01)
      status = MI_FRAMINGERR;
    else
      status = MI_ERR;
  } else {
    status = MI_OK;
    if (pi->Command == RC663_Transceive) {
      temp = RC663_ReadReg(rRegFIFOLength);            // 04h
      lastBits = RC663_ReadReg(rRegRxBitCtrl) & 0x07;  // 0ch

      if (lastBits)
        pi->Length = (temp - 1) * 8 + lastBits;
      else
        pi->Length = temp * 8;
      if (temp == 0)
        temp = 1;
      if (temp > 250)
        temp = 250;  // maxlen ...

      for (i = 0; i < temp; i++)
        pi->Data[i] = RC663_ReadReg(rRegFIFOData);  // 05h
    }
  }
  return status;
}
int8_t RC663_PcdHaltA(void) {
  int8_t status;
  struct TranSciveBuffer ComData, *pi = &ComData;

  ComData.Command = RC663_Transceive;
  ComData.Length = 2;
  ComData.Data[0] = PICC_HALT;
  ComData.Data[1] = 0;

  status = RC663_PcdComTransceive(pi);
  if (status == MI_NOTAGERR)  // halt command has no response
    status = MI_OK;
  else
    status = MI_ERR;
  return status;
}

int8_t RC663_PcdRequestA(uint8_t req_code, uint8_t *pTagType) {
  int8_t status;
  struct TranSciveBuffer ComData, *pi = &ComData;

  RC663_WriteReg(rRegTxCrcPreset, 0x18);  // 0x2C Transmitter CRC control register, preset value
  RC663_WriteReg(rRegRxCrcPreset, 0x18);
  RC663_WriteReg(rRegStatus, 0);  //  0x0B  Contains status of the communication

  RC663_WriteReg(rRegTXWaitCtrl, 0xC0);  // 0x31  TxWaitStart at the end of Rx data
  RC663_WriteReg(rRegTxWaitLo, 0x0B);    // 0x32   Set min.time between Rx and Tx or between two Tx
  // Set timeout for this command cmd. Init reload values for timers-0,1
  RC663_WriteReg(rRegT0ReloadHi, 0x08);  // 2196/fc        0x10 // High register of the reload value of Timer0
  RC663_WriteReg(rRegT0ReloadLo, 0x94);  // 0x11 // Low register of the reload value of Timer0
  RC663_WriteReg(rRegT1ReloadHi, 0);     // 0x15 // High register of the reload value of Timer1
  RC663_WriteReg(rRegT1ReloadLo, 0x40);  // timerout ~= 10ms      	0x16 // Low register of the reload value of Timer1

  RC663_WriteReg(rRegIRQ0, 0x08);       //	0x06 // Interrupt register 0
  RC663_WriteReg(rRegRxWait, 0x90);     // 0x36 // Receiver wait register
  RC663_WriteReg(rRegTxDataNum, 0x0F);  // 7bit                      0x2E // Transmitter data number register

  //> Send the ReqA command
  ComData.Command = RC663_Transceive;  // 0x07 //- transmits data from the FIFO buffer and automatically activates the receiver after transmission finished
  ComData.Length = 1;
  ComData.Data[0] = req_code;

  status = RC663_PcdComTransceive(pi);

  if (status == MI_OK) {
    // printf("ComData.Length:%d\n", ComData.Length);
    if (ComData.Length == 0x10) {
      *pTagType = ComData.Data[0];
      *(pTagType + 1) = ComData.Data[1];
    } else
      status = MI_VALERR;
  }
  // RC663_WriteReg(rRegTxDataNum,0x08);
  return status;
}


int8_t RC663_PcdAnticoll(uint8_t *pSnr) {

  /*

	| ATQA | Type |
	| :----: | :----------------- |
	| 0x4400 | Mifare_UltraLight |
	| 0x0400 | Mifare_One(M1 S50) |
	| 0x0200 | Mifare_One(M1 S70) |
	| 0x0800 | Mifare_Pro(X) |
	| 0x4403 | Mifare_DESFire |

	Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本、小容量的卡片。低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片之一;小容量,是指其存储容量只有512bit(Mifare S50有8192bit)。
		Mifare Ulitralight的卡序列号有7个字节,而Mifare S50的卡序列号只有4个字节,因此在卡片防冲突选择阶段需要两层(Cascade93H和95H)操作;
	*/
  int8_t status;
  uint8_t i;
  uint8_t ucBits, ucBytes;
  uint8_t snr_check = 0;
  uint8_t ucCollPosition = 0;
  uint8_t ucTemp;
  uint8_t ucSNR[5] = { 0, 0, 0, 0, 0 };
  struct TranSciveBuffer ComData, *pi = &ComData;
  uint16_t t = 0;
  RC663_WriteReg(rRegTxDataNum, 0x08);
  do {
    ucBits = (ucCollPosition) % 8;
    if (ucBits != 0) {
      ucBytes = ucCollPosition / 8 + 1;
      RC663_SetRawRC(rRegRxBitCtrl, 0x8f, ucBits << 4);
      RC663_SetRawRC(rRegTxDataNum, 0xf8, ucBits);
    } else
      ucBytes = ucCollPosition / 8;

    ComData.Command = RC663_Transceive;
    ComData.Data[0] = PICC_ANTICOLL1;
    ComData.Data[1] = 0x20 + ((ucCollPosition / 8) << 4) + (ucBits & 0x0F);
    for (i = 0; i < ucBytes; i++)
      ComData.Data[i + 2] = ucSNR[i];
    ComData.Length = ucBytes + 2;

    status = RC663_PcdComTransceive(pi);

    ucTemp = ucSNR[(ucCollPosition / 8)];
    if (status == MI_COLLERR) {
      for (i = 0; i < 5 - (ucCollPosition / 8); i++)
        ucSNR[i + (ucCollPosition / 8)] = ComData.Data[i + 1];
      ucSNR[(ucCollPosition / 8)] |= ucTemp;
      ucCollPosition = ComData.Data[0];
    } else if (status == MI_OK) {
      for (i = 0; i < (ComData.Length / 8); i++)
        ucSNR[4 - i] = ComData.Data[ComData.Length / 8 - i - 1];
      ucSNR[(ucCollPosition / 8)] |= ucTemp;
    }

    if (t++ > 0x8000)  // 超时
    {
      return MI_ERR;
    }
  } while (status == MI_COLLERR);

  if (status == MI_OK) {
    for (i = 0; i < 4; i++) {
      *(pSnr + i) = ucSNR[i];
      snr_check ^= ucSNR[i];
    }
    if (snr_check != ucSNR[i])
      status = MI_COM_ERR;
  }
  return status;
}



int8_t RC663_PcdAnticoll2(uint8_t *pSnr) {

  /*

	| ATQA | Type |
	| :----: | :----------------- |
	| 0x4400 | Mifare_UltraLight |
	| 0x0400 | Mifare_One(M1 S50) |
	| 0x0200 | Mifare_One(M1 S70) |
	| 0x0800 | Mifare_Pro(X) |
	| 0x4403 | Mifare_DESFire |

	Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本、小容量的卡片。低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片之一;小容量,是指其存储容量只有512bit(Mifare S50有8192bit)。
		Mifare Ulitralight的卡序列号有7个字节,而Mifare S50的卡序列号只有4个字节,因此在卡片防冲突选择阶段需要两层(Cascade93H和95H)操作;
	*/
  int8_t status;
  uint8_t i;
  uint8_t ucBits, ucBytes;
  uint8_t snr_check = 0;
  uint8_t ucCollPosition = 0;
  uint8_t ucTemp;
  uint8_t ucSNR[5] = { 0, 0, 0, 0, 0 };
  struct TranSciveBuffer ComData, *pi = &ComData;
  uint16_t t = 0;
  RC663_WriteReg(rRegTxDataNum, 0x08);
#if 1                                     // 必须有,否则读不到UID
  RC663_WriteReg(rRegTxCrcPreset, 0x18);  // 0x2C Transmitter CRC control register, preset value
  RC663_WriteReg(rRegRxCrcPreset, 0x18);
  RC663_WriteReg(rRegStatus, 0);  //  0x0B  Contains status of the communication
#endif

  ComData.Command = RC663_Transceive;
  ComData.Data[0] = PICC_ANTICOLL2;
  ComData.Data[1] = 0x20;

  ComData.Length = 2;

  status = RC663_PcdComTransceive(pi);

  // printf("RC663_PcdAnticoll2-RC663_PcdComTransceive :%d \n", status);
  // for (i = 0; i < ComData.Length / 8; i++)
  //   printf("%2.2X ", ComData.Data[i]);
  // printf("\n");
  if (status == MI_OK) {
    for (i = 0; i < 4; i++) {
      *(pSnr + i) = ComData.Data[i];
      snr_check ^= pSnr[i];
    }
    // printf("snr_check:%2.2X =? %2.2X\n",snr_check,ComData.Data[i]);
    if (snr_check != ComData.Data[i])
      status = MI_COM_ERR;
  }
  // printf("RC663_PcdAnticoll2 :%d \n", status);
  return status;
}




int8_t RC663_PcdSelect(uint8_t *pSnr, uint8_t *pSize) {
  int8_t status;
  uint8_t i, snr_check = 0;
  struct TranSciveBuffer ComData, *pi = &ComData;

  RC663_SetRawRC(rRegTxCrcPreset, 0xfe, 0x01);  // On
  RC663_SetRawRC(rRegRxCrcPreset, 0xfe, 0x01);  // On

  ComData.Command = RC663_Transceive;
  ComData.Length = 7;
  ComData.Data[0] = PICC_ANTICOLL1;
  ComData.Data[1] = 0x70;
  for (i = 0; i < 4; i++) {
    snr_check ^= *(pSnr + i);
    ComData.Data[i + 2] = *(pSnr + i);
  }
#if 0
  ComData.Data[3] = 0xab;
#endif
  ComData.Data[6] = snr_check;

  status = RC663_PcdComTransceive(pi);

  if (status == MI_OK) {
    if (ComData.Length != 0x8)
      status = MI_BITCOUNTERR;
    else
      *pSize = ComData.Data[0];
  }
  return status;
}


// int8_t RC663_PcdSelect2(uint8_t *pSnr, uint8_t *pSize) {
//   int8_t status;
//   uint8_t i, snr_check = 0;
//   struct TranSciveBuffer ComData, *pi = &ComData;

//   RC663_SetRawRC(rRegTxCrcPreset, 0xfe, 0x01);  // On
//   RC663_SetRawRC(rRegRxCrcPreset, 0xfe, 0x01);  // On

//   ComData.Command = RC663_Transceive;
//   ComData.Length = 7;
//   ComData.Data[0] = PICC_ANTICOLL2;
//   ComData.Data[1] = 0x70;
//   for (i = 0; i < 4; i++) {
//     snr_check ^= *(pSnr + i);
//     ComData.Data[i + 2] = *(pSnr + i);
//   }
//   ComData.Data[6] = snr_check;

//   status = RC663_PcdComTransceive(pi);

//   if (status == MI_OK) {
//     if (ComData.Length != 0x8)
//       status = MI_BITCOUNTERR;
//     else
//       *pSize = ComData.Data[0];
//   }
//   return status;
// }


#define RFID_DEBUG

uint8_t bt_rfid_query_14443a(uint8_t *uid) {
  int8_t status;
  uint8_t reg;
  uint8_t dSize;
  uint8_t M1_Data[12];  // CT:2 SN:4 SAK:1
  static uint8_t KEY[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

#if 0
  /*
	VERSION Reg:
	bit7~4
		CLRC66301: 0x1
		CLRC66302: 0x1
		CLRC66303: 0x1
	bit3~0
		CLRC66301: 0x8
		CLRC66302: 0x8
		CLRC66303: 0xA
	*/
  reg = RC663_ReadReg(rRegVersion);
  // 版本寄存器读错误 重启
  if ((reg != 0x1A) && (reg != 0x18)) {
#ifdef RFID_DEBUG
    printf("rfid reset...\n");
#endif

    reset();
    delay(100);
  }
#endif
#ifdef RFID_DEBUG
  printf("RC663_PcdConfigISOType...\n");
#endif

  RC663_PcdConfigISOType('A');

  ///mifare S50
  /*

	| ATQA | Type |
	| :----: | :----------------- |
	| 0x4400 | Mifare_UltraLight |
	| 0x0400 | Mifare_One(M1 S50) |
	| 0x0200 | Mifare_One(M1 S70) |
	| 0x0800 | Mifare_Pro(X) |
	| 0x4403 | Mifare_DESFire |

	Mifare UltraLight又称为MF0,从UltraLight(超轻的)这个名字就可以看出来,它是一个低成本、小容量的卡片。低成本,是指它是目前市场中价格最低的遵守ISO14443A协议的芯片之一;小容量,是指其存储容量只有512bit(Mifare S50有8192bit)。
		Mifare Ulitralight的卡序列号有7个字节,而Mifare S50的卡序列号只有4个字节,因此在卡片防冲突选择阶段需要两层(Cascade93H和95H)操作;

	*/
  uint8_t i;
  status = RC663_PcdRequestA(PICC_REQALL, M1_Data);
#ifdef RFID_DEBUG
  printf("ATQA: %d_", status);
  if (status == MI_OK)
    printf("CardTyep:%02X %02X", M1_Data[1], M1_Data[0]);
  printf("\n");
#endif
  if (status != MI_OK) {
    // 关闭场
    RC663_FieldOff();
    return 1;
  }

  if (M1_Data[0] == 0x44 && M1_Data[1] == 0x00) {
    status = RC663_PcdAnticoll(&M1_Data[2]);
    if (status != MI_OK) {
      // 关闭场
      RC663_FieldOff();
      return 1;
    }
    printf("UID-1: %02X %02X %02X ", M1_Data[3], M1_Data[4], M1_Data[5]);

    status = RC663_PcdSelect(&M1_Data[2], &dSize);
    printf("Selete1_Status: %d_\n", status);
    if (status != MI_OK) {
      // 关闭场
      RC663_FieldOff();
      return 1;
    }
    status = RC663_PcdAnticoll2(&M1_Data[6]);

    // printf("Anticoll-2: %d_\n", status);
    // printf("UID-2:%02X %02X %02X %02X\n", M1_Data[6], M1_Data[7], M1_Data[8], M1_Data[9]);
    printf("Mifare Ultralight UID:");
    for (i = 0; i < 7; i++)
      printf("%2.2X ", M1_Data[3 + i]);
    printf("\n");
    if (status != MI_OK) {
      // 关闭场
      RC663_FieldOff();
      return 1;
    }


  } else {
    status = RC663_PcdAnticoll(&M1_Data[2]);
    printf("Anticoll-1: %d_\n", status);

    if (status != MI_OK) {
      // 关闭场
      RC663_FieldOff();
      return 1;
    }
#ifdef RFID_DEBUG
    printf("Mifare Classic UID: %d_", status);
    if (status == MI_OK) {
      printf("%02X %02X %02X %02X ", M1_Data[2], M1_Data[3], M1_Data[4], M1_Data[5]);
    }
    printf("\n");
#endif
  }




  if (status == MI_OK) {
    memcpy(uid, &M1_Data[2], 8);
  } else {
    memset(&uid, 0, 8);
  }
  // 关闭场
  RC663_FieldOff();

  return status;
}

## 3、寄存器定义 librc663.ino
```c
#ifndef _LIBRC663_H
#define _LIBRC663_H
#define rRegCommand 0x00           // Starts and stops command execution
#define rRegHostCtrl 0x01          // Host control register
#define rRegFIFOControl 0x02       // Control register of the FIFO
#define rRegWaterLevel 0x03        // Level of the FIFO underflow and overflow warning
#define rRegFIFOLength 0x04        // Length of the FIFO
#define rRegFIFOData 0x05          // Data In/Out exchange register of FIFO buffer
#define rRegIRQ0 0x06              // Interrupt register 0
#define rRegIRQ1 0x07              // Interrupt register 1
#define rRegIRQ0En 0x08            // Interrupt enable register 0
#define rRegIRQ1En 0x09            // Interrupt enable register 1
#define rRegError 0x0A             // Error bits showing the error status of the last command execution
#define rRegStatus 0x0B            // Contains status of the communication
#define rRegRxBitCtrl 0x0C         // Control register for anticollision adjustments for bit oriented protocols
#define rRegRxColl 0x0D            // Collision position register
#define rRegTControl 0x0E          // Control of Timer 0..3
#define rRegT0Control 0x0F         // Control of Timer0
#define rRegT0ReloadHi 0x10        // High register of the reload value of Timer0
#define rRegT0ReloadLo 0x11        // Low register of the reload value of Timer0
#define rRegT0CounterValHi 0x12    // Counter value high register of Timer0
#define rRegT0CounterValLo 0x13    // Counter value low register of Timer0
#define rRegT1Control 0x14         // Control of Timer1
#define rRegT1ReloadHi 0x15        // High register of the reload value of Timer1
#define rRegT1ReloadLo 0x16        // Low register of the reload value of Timer1
#define rRegT1CounterValHi 0x17    // Counter value high register of Timer1
#define rRegT1CounterValLo 0x18    // Counter value low register of Timer1
#define rRegT2Control 0x19         // Control of Timer2
#define rRegT2ReloadHi 0x1A        // High byte of the reload value of Timer2
#define rRegT2ReloadLo 0x1B        // Low byte of the reload value of Timer2
#define rRegT2CounterValHi 0x1C    // Counter value high byte of Timer2
#define rRegT2CounterValLo 0x1D    // Counter value low byte of Timer2
#define rRegT3Control 0x1E         // Control of Timer3
#define rRegT3ReloadHi 0x1F        // High byte of the reload value of Timer3
#define rRegT3ReloadLo 0x20        // Low byte of the reload value of Timer3
#define rRegT3CounterValHi 0x21    // Counter value high byte of Timer3
#define rRegT3CounterValLo 0x22    // Counter value low byte of Timer3
#define rRegT4Control 0x23         // Control of Timer4
#define rRegT4ReloadHi 0x24        // High byte of the reload value of Timer4
#define rRegT4ReloadLo 0x25        // Low byte of the reload value of Timer4
#define rRegT4CounterValHi 0x26    // Counter value high byte of Timer4
#define rRegT4CounterValLo 0x27    // Counter value low byte of Timer4
#define rRegDrvMod 0x28            // Driver mode register
#define rRegTxAmp 0x29             // Transmitter amplifier register
#define rRegDrvCon 0x2A            // Driver configuration register
#define rRegTxl 0x2B               // Transmitter register
#define rRegTxCrcPreset 0x2C       // Transmitter CRC control register, preset value
#define rRegRxCrcPreset 0x2D       // Receiver CRC control register, preset value
#define rRegTxDataNum 0x2E         // Transmitter data number register
#define rRegTxModWidth 0x2F        // Transmitter modulation width register
#define rRegTxSym10BurstLen 0x30   // Transmitter symbol 1 + symbol 0 burst length register
#define rRegTXWaitCtrl 0x31        // Transmitter wait control
#define rRegTxWaitLo 0x32          // Transmitter wait low
#define rRegFrameCon 0x33          // Transmitter frame control
#define rRegRxSofD 0x34            // Receiver start of frame detection
#define rRegRxCtrl 0x35            // Receiver control register
#define rRegRxWait 0x36            // Receiver wait register
#define rRegRxThreshold 0x37       // Receiver threshold register
#define rRegRcv 0x38               // Receiver register
#define rRegRxAna 0x39             // Receiver analog register
#define rRegRFU_3A 0x3A            // -
#define rRegSerialSpeed 0x3B       // Serial speed register
#define rRegLFO_Trimm 0x3C         // Low-power oscillator trimming register
#define rRegPLL_Ctrl 0x3D          // IntegerN PLL control register, for microcontroller clock output adjustment
#define rRegPLL_DivOut 0x3E        // IntegerN PLL control register, for microcontroller clock output adjustment
#define rRegLPCD_QMin 0x3F         // Low-power card detection Q channel minimum threshold
#define rRegLPCD_QMax 0x40         // Low-power card detection Q channel maximum threshold
#define rRegLPCD_IMin 0x41         // Low-power card detection I channel minimum threshold
#define rRegLPCD_I_Result 0x42     // Low-power card detection I channel result register
#define rRegLPCD_Q_Result 0x43     // Low-power card detection Q channel result register
#define rRegPadEn 0x44             // PIN enable register
#define rRegPadOut 0x45            // PIN out register
#define rRegPadIn 0x46             // PIN in register
#define rRegSigOut 0x47            // Enables and controls the SIGOUT Pin
#define rRegTxBitMod 0x48          // Transmitter bit mode register
#define rRegRFU_49 0x49            // -
#define rRegTxDataCon 0x4A         // Transmitter data configuration register
#define rRegTxDataMod 0x4B         // Transmitter data modulation register
#define rRegTxSymFreq 0x4C         // Transmitter symbol frequency
#define rRegTxSym0H 0x4D           // Transmitter symbol 0 high register
#define rRegTxSym0L 0x4E           // Transmitter symbol 0 low register
#define rRegTxSym1H 0x4F           // Transmitter symbol 1 high register
#define rRegTxSym1L 0x50           // Transmitter symbol 1 low register
#define rRegTxSym2 0x51            // Transmitter symbol 2 register
#define rRegTxSym3 0x52            // Transmitter symbol 3 register
#define rRegTxSym10Len 0x53        // Transmitter symbol 1 + symbol 0 length register
#define rRegTxSym32Len 0x54        // Transmitter symbol 3 + symbol 2 length register
#define rRegTxSym10BurstCtrl 0x55  // Transmitter symbol 1 + symbol 0 burst control register
#define rRegTxSym10Mod 0x56        // Transmitter symbol 1 + symbol 0 modulation register
#define rRegTxSym32Mod 0x57        // Transmitter symbol 3 + symbol 2 modulation register
#define rRegRxBitMod 0x58          // Receiver bit modulation register
#define rRegRxEofSym 0x59          // Receiver end of frame symbol register
#define rRegRxSyncValH 0x5A        // Receiver synchronisation value high register
#define rRegRxSyncValL 0x5B        // Receiver synchronisation value low register
#define rRegRxSyncMod 0x5C         // Receiver synchronisation mode register
#define rRegRxMod 0x5D             // Receiver modulation register
#define rRegRxCorr 0x5E            // Receiver correlation register
#define rRegFabCal 0x5F            // Calibration register of the receiver, calibration performed at production
#define rReg_60 0x60               //
#define rReg_61 0x61               //
#define rReg_66 0x66               //
#define rReg_6A 0x6A               //
#define rReg_6B 0x6B               //
#define rReg_6C 0x6C               //
#define rReg_6D 0x6D               //
#define rReg_6E 0x6E               //
#define rReg_6F 0x6F               //
#define rRegVersion 0x7F           // Version and subversion register
//
//		Command 			No. Parameter (bytes) 	Short description
#define RC663_Idle 0x00          //- 					no action, cancels current command execution
#define RC663_LPCD 0x01          //- 					low-power card detection
#define RC663_LoadKey 0x02       //(keybyte1..6); 		reads a MIFARE key (size of 6 bytes) from FIFO buffer and puts it into Key buffer
#define RC663_MFAuthent 0x03     //60h or 61h,(block address),(card serial number byte0..3) 	performs the MIFARE standard authentication in MIFARE read/write mode only
#define RC663_AckReq 0x04        //- 					performs a query, an Ack and a Req-Rn for ISO/IEC 18000-3 mode 3/ EPC Class-1 HF
#define RC663_Receive 0x05       //- 					activates the receive circuit
#define RC663_Transmit 0x06      //- 					transmits data from the FIFO buffer
#define RC663_Transceive 0x07    //- 					transmits data from the FIFO buffer and automatically activates the receiver after transmission finished
#define RC663_WriteE2 0x08       //addressH, addressL, data; 	gets one byte from FIFO buffer and writes it to the internal EEPROM,
#define RC663_WriteE2Page 0x09   //(page Address), data0, [data1..data63]; 	gets up to 64 bytes (one EEPROM page) from the FIFO buffer and writes it to the EEPROM
#define RC663_ReadE2 0x0A        // address H, addressL,length; 	reads data from the EEPROM and copies it into the FIFO buffer
#define RC663_LoadReg 0x0C       //(EEPROM addressL), (EEPROM addressH), RegAdr, (number of Register to be copied);  reads data from the internal EEPROM and initializes the CLRC663 registers. EEPROM address needs to be within EEPROM sector 2
#define RC663_LoadProtocol 0x0D  //(Protocol number RX), (Protocol number TX);		reads data from the internal EEPROM and initializes the CLRC663 registers needed for a Protocol change
#define RC663_LoadKeyE2 0x0E     //KeyNr; 				copies a key of the EEPROM into the key buffer
#define RC663_StoreKeyE2 0x0F    //KeyNr, byte1..6;	stores a MIFARE key (size of 6 bytes) into the EEPROM
#define RC663_ReadRNR 0x1C       //- 					Copies bytes from the Random Number generator into the FIFO until the FiFo is full
#define RC663_Soft_Reset 0x1F    //- 					resets the CLRC663





//M1,ISO14443A
/
#define PICC_REQIDL 0x26     //Ѱ��������δ��������״̬
#define PICC_REQALL 0x52     //Ѱ��������ȫ����
#define PICC_ANTICOLL1 0x93  //����ײ
#define PICC_ANTICOLL2 0x95  //����ײ
#define PICC_AUTHENT1A 0x60  //��֤A��Կ
#define PICC_AUTHENT1B 0x61  //��֤B��Կ
#define PICC_READ 0x30       //����
#define PICC_WRITE 0xA0      //�
#define PICC_DECREMENT 0xC0  //�ۿ�
#define PICC_INCREMENT 0xC1  //��ֵ
#define PICC_RESTORE 0xC2    //�������ݵ�������
#define PICC_TRANSFER 0xB0   //���滺����������
#define PICC_HALT 0x50       //����

/ISO14443B
#define PICC_ANTI 0x05
#define PICC_ATTRIB 0x1D
/
#define MI_OK 0
#define MI_CHK_OK 0

#define MI_NOTAGERR (-1)
#define MI_CHK_FAILED (-1)
#define MI_CRCERR (-2)
#define MI_CHK_COMPERR (-2)
#define MI_EMPTY (-3)
#define MI_AUTHERR (-4)
#define MI_PARITYERR (-5)
#define MI_CODEERR (-6)
#define MI_SERNRERR (-8)
#define MI_KEYERR (-9)
#define MI_NOTAUTHERR (-10)
#define MI_BITCOUNTERR (-11)
#define MI_BYTECOUNTERR (-12)
#define MI_IDLE (-13)
#define MI_TRANSERR (-14)
#define MI_WRITEERR (-15)
#define MI_INCRERR (-16)
#define MI_DECRERR (-17)
#define MI_READERR (-18)
#define MI_OVFLERR (-19)
#define MI_POLLING (-20)
#define MI_FRAMINGERR (-21)
#define MI_ACCESSERR (-22)
#define MI_UNKNOWN_COMMAND (-23)
#define MI_COLLERR (-24)
#define MI_RESETERR (-25)
#define MI_INITERR (-25)
#define MI_INTERFACEERR (-26)
#define MI_ACCESSTIMEOUT (-27)
#define MI_NOBITWISEANTICOLL (-28)
#define MI_QUIT (-30)
#define MI_RECBUF_OVERFLOW (-50)
#define MI_SENDBYTENR (-51)
#define MI_SENDBUF_OVERFLOW (-53)
#define MI_BAUDRATE_NOT_SUPPORTED (-54)
#define MI_SAME_BAUDRATE_REQUIRED (-55)
#define MI_WRONG_PARAMETER_VALUE (-60)
#define MI_BREAK (-99)
#define MI_NY_IMPLEMENTED (-100)
#define MI_NO_MFRC (-101)
#define MI_MFRC_NOTAUTH (-102)
#define MI_WRONG_DES_MODE (-103)
#define MI_HOST_AUTH_FAILED (-104)
#define MI_WRONG_LOAD_MODE (-106)
#define MI_WRONG_DESKEY (-107)
#define MI_MKLOAD_FAILED (-108)
#define MI_FIFOERR (-109)
#define MI_WRONG_ADDR (-110)
#define MI_DESKEYLOAD_FAILED (-111)
#define MI_WRONG_SEL_CNT (-114)
#define MI_WRONG_TEST_MODE (-117)
#define MI_TEST_FAILED (-118)
#define MI_TOC_ERROR (-119)
#define MI_COMM_ABORT (-120)
#define MI_INVALID_BASE (-121)
#define MI_MFRC_RESET (-122)
#define MI_WRONG_VALUE (-123)
#define MI_VALERR (-124)
#define MI_COM_ERR (-125)
#define MI_ERR (-126)


#define DEF_FIFO_LENGTH 64  //FIFO size=64byte

struct TranSciveBuffer {
  uint8_t Command;
  uint16_t Length;
  uint8_t Data[DEF_FIFO_LENGTH];
};

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值