AnsweredAssumed Answered

如何将自己的PN512程序移植到RC663芯片

Question asked by n k on Aug 27, 2017
Latest reply on Aug 30, 2017 by Kan_Li

已经大量使用过RC522、RC523、PN512,驱动程序是自己写的,主要包括:复位IC、根据不用的读卡协议配置读卡IC寄存器、通过FIFO完成数据通信命令 从而实现读写卡功能, RC522 RC523 PN512 这三个驱动程序可以做到互相兼容,但现在想使用RC663完成更多的功能,比如ISO15693卡片的读写,现在发现RC663的底层驱动好像和PN512这种有很大不同, 请问有没有直接配置寄存器的方式操作RC663的代码历程?  因为我们后端的读卡应用都是已经做好的,现在如果转入使用官方的库对后面的应用层操作影响很大, 我们想直接修改RC663的底层驱动 然后上层接口与我们原来的兼容就可以了。   大概主要包括读卡器协议配置、 数据交换底层操作这两部分。

 

例如我们原来的读卡器IC工作模式是这样配置:

void PcdISOType(unsigned char ucType)
{
#if PCD_MODE == PN512
 // PN512
 if(ucType == ISO18092_NFCIP)
 {
  RcSetReg(JREG_CONTROL, 0x10);              
  RcSetReg(JREG_TXMODE, 0x92);              
  RcSetReg(JREG_RXMODE, 0x96);              
    RcSetReg(JREG_TXASK, 0x37);               
  RcSetReg(JREG_RXTHRESHOLD, 0x55);            
  RcSetReg(JREG_DEMOD, 0x41);             
  RcSetReg(JREG_RFCFG, 0x59);              
  RcSetReg(JREG_GSN, 0xFF);                
         
        
 }
 else if(ucType == SONY_FELICA)
 {
  RcSetReg(JREG_CONTROL, 0x10);              
  RcSetReg(JREG_TXMODE, 0x92);              
  RcSetReg(JREG_RXMODE, 0x96);             
   RcSetReg(JREG_TXCONTROL, 0x80);           
   RcSetReg(JREG_TXASK, 0x00 & 0X37);           
  RcSetReg(JREG_RXTHRESHOLD, 0x55);           
  RcSetReg(JREG_DEMOD, 0x41);                 
    RcSetReg(JREG_GSNOFF, 0x6F);              
  RcSetReg(JREG_MODWIDTH, 0x26);             
  RcSetReg(JREG_TXBITPHASE, (0x8F & 0x80) | 0x0f);     
  RcSetReg(JREG_RFCFG, 0x59);            
  RcSetReg(JREG_GSN, 0xFF);                
  RcSetReg(JREG_CWGSP, 0x3F);                 
     
 }
 else if (ucType == ISO14443_TYPEB)
 {
  RcSetReg(JREG_TXASK, 0x00);  
  RcSetReg(JREG_CONTROL, 0x10);  
  RcSetReg(JREG_TXMODE, 0x03);
  RcSetReg(JREG_RXMODE, 0x0B);
  RcSetReg(JREG_TYPEB, 0x03);       
  RcSetReg(JREG_DEMOD, 0x4D);
  RcSetReg(JREG_GSN, 0xFF);
  RcSetReg(JREG_CWGSP, 0x3F);  

 

  RcSetReg(JREG_MODGSP, 0x18); 

 

 }
 else
 {
  RcSetReg(JREG_TXASK, 0x40);  
  RcSetReg(JREG_CONTROL, 0x10); 
  RcSetReg(JREG_TXMODE, 0x00); 
  RcSetReg(JREG_RXMODE, 0x08); 

  RcSetReg(JREG_DEMOD, 0x4D);
 
  }
 
#elif PCD_MODE == RC523
 // RC523
  if(ucType == ISO14443_TYPEB)
  {
    RcSetReg(JREG_TXASK, 0x00);  
  RcSetReg(JREG_CONTROL, 0x10);  
    RcSetReg(JREG_TXMODE, 0x03);  
  RcSetReg(JREG_RXMODE, 0x0B); 
  RcSetReg(JREG_TYPEB, 0x03);   
              
  RcSetReg(JREG_DEMOD, 0x4d);
  RcSetReg(JREG_GSN, 0xff);
  RcSetReg(JREG_CWGSP, 0x3f);   
  RcSetReg(JREG_RXTHRESHOLD, 0x55); 
  RcSetReg(JREG_RFCFG, 0x68);   
 }
 else
 {
  RcSetReg(JREG_TXASK, 0x40);   
  RcSetReg(JREG_CONTROL, 0x10);  
  RcSetReg(JREG_TXMODE, 0x00);  
  RcSetReg(JREG_RXMODE, 0x08);  

  RcSetReg(JREG_DEMOD, 0x4D);
  RcSetReg(JREG_CWGSP, 0x3F);   
   }
 
#else
 // RC522
 ucType = ucType;
 RcSetReg(JREG_TXASK, 0x40);  
 RcSetReg(JREG_CONTROL, 0x10); 
 RcSetReg(JREG_TXMODE, 0x00);  
 RcSetReg(JREG_RXMODE, 0x08);  

 RcSetReg(JREG_DEMOD, 0x4D);
 RcSetReg(JREG_CWGSP, 0x3F);   

 

#endif

}

 

 

配置完成后我们就有一个PcdCmd的数据交换命令  其他后续的应用操作只要调用这个命令就可以完成对卡片的操作了,这个结构也是参考先前的MRFC500的驱动代码做的, 现在我们就是想把前面的配置 加上RC663模式,同时下面的PcdCmd支持RC663的数据交换。

 

unsigned char  PcdCmd(unsigned char ucCmd,unsigned int ucCmdLen,unsigned char *pExchangeBuf, unsigned int nUserBufSize)
{
    unsigned char  ucStatus = STATUS_SUCCESS;
 
    unsigned char  commIrqEn   = 0;
    unsigned char  divIrqEn    = 0;
    unsigned char  waitForComm = JBIT_ERRI | JBIT_TXI;
    unsigned char  waitForDiv  = 0;
    unsigned char  doReceive   = 0;


    
  MInfo.cmd = ucCmd;
  MInfo.nBytesToSend = ucCmdLen;
    RcSetReg(JREG_COMMIRQ, 0x7f);                 
    RcSetReg(JREG_DIVIRQ, 0x7f);
    RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);

    getRegVal = RcGetReg(JREG_COMMAND);                 
    if(MInfo.cmd == JCMD_TRANSCEIVE)
    {  
        setRegVal = (getRegVal & ~JMASK_COMMAND) | JCMD_TRANSCEIVE;
        RcSetReg(JREG_COMMAND, setRegVal);//0c
    }
    else
    { 
        setRegVal = (getRegVal & ~JMASK_COMMAND);
        RcSetReg(JREG_COMMAND, setRegVal);
    }
    switch(MInfo.cmd)
    {
        case JCMD_IDLE:// ¿ÕÏÐÃüÁî
      waitForComm = 0;
            waitForDiv  = 0;
            break;
#ifndef MFRC522
    case JCMD_MEM: 
      commIrqEn = JBIT_IDLEI;
            waitForComm = JBIT_IDLEI;
            break;
#endif
        case JCMD_CALCCRC
            waitForComm = 0;
            waitForDiv  = 0;
            break;
        case JCMD_TRANSMIT
            commIrqEn = JBIT_TXI | JBIT_TIMERI;
            waitForComm = JBIT_TXI;
            break;
        case JCMD_RECEIVE://
            commIrqEn = JBIT_RXI | JBIT_TIMERI;  //| JBIT_ERRI;
            waitForComm = JBIT_RXI | JBIT_TIMERI;  //| JBIT_ERRI;
            doReceive = 1;
            break;
        case JCMD_TRANSCEIVE
            commIrqEn = JBIT_RXI | JBIT_TIMERI;  //| JBIT_ERRI;
           doReceive = 1;
            break;
        case JCMD_AUTHENT
            commIrqEn = JBIT_IDLEI | JBIT_TIMERI; //| JBIT_ERRI;
            
            break;
        case JCMD_SOFTRESET: // Èí¸´Î»
            waitForComm = 0;
            waitForDiv  = 0;
            break;
        default:
            ucStatus = STATUS_UNSUPPORTED_COMMAND;         
    }
  
  
    if(ucStatus == STATUS_SUCCESS)
    {  
    
        getRegVal = RcGetReg(JREG_COMMIEN);
        RcSetReg(JREG_COMMIEN, (unsigned char)(getRegVal | commIrqEn));

        getRegVal = RcGetReg(JREG_DIVIEN);
        RcSetReg(JREG_DIVIEN, (unsigned char)(getRegVal | divIrqEn));

        WriteFIFO(pExchangeBuf,MInfo.nBytesToSend);         

       
        if(MInfo.cmd == JCMD_TRANSCEIVE)               
        {  
     
          RcModifyReg(JREG_BITFRAMING, 1, JBIT_STARTSEND);
        }
        else
        {
            getRegVal = RcGetReg(JREG_COMMAND);
            RcSetReg(JREG_COMMAND, (unsigned char)((getRegVal & ~JMASK_COMMAND) | MInfo.cmd));
        }
        getRegVal = 0;                           
        setRegVal = 0;
        
    
    g_uiPcdTmOut = PCD_DELAY100MS;                 
        while(!(waitForComm ? (waitForComm & setRegVal) : 1) || !(waitForDiv ? (waitForDiv & getRegVal) :1))
        {
            setRegVal = RcGetReg(JREG_COMMIRQ);                         
            getRegVal = RcGetReg(JREG_DIVIRQ);             
            if(g_uiPcdTmOut == 0)
                break;                         
        }
    if(g_uiPcdTmOut == 0)
    {
     ucStatus = STATUS_ACCESS_TIMEOUT;               
    }
    else
    {     
       waitForComm = (unsigned char)(waitForComm & setRegVal);
       waitForDiv  = (unsigned char)(waitForDiv & getRegVal);
   
       if (setRegVal & JBIT_TIMERI)                  
       {
         ucStatus = STATUS_IO_TIMEOUT;
       }
     g_uiPcdTmOut = 0;
    }
    }

    RcModifyReg(JREG_COMMIEN, 0, commIrqEn);                
    RcModifyReg(JREG_DIVIEN, 0, divIrqEn);

    if(doReceive && (ucStatus == STATUS_SUCCESS))
    {  
        MInfo.nBytesReceived = RcGetReg(JREG_FIFOLEVEL);
   
        getRegVal = RcGetReg(JREG_CONTROL);
        MInfo.nBitsReceived = (unsigned char)(getRegVal & 0x07);
    

        getRegVal = RcGetReg(JREG_ERROR);

        if(getRegVal)                   
        {
            if(getRegVal & JBIT_COLLERR)
                ucStatus = STATUS_COLLISION_ERROR; 
            else if(getRegVal & JBIT_PARITYERR)
                ucStatus = STATUS_PARITY_ERROR;    

            if(getRegVal & JBIT_PROTERR)
                ucStatus = STATUS_PROTOCOL_ERROR;  
            else if(getRegVal & JBIT_BUFFEROVFL)
                ucStatus = STATUS_BUFFER_OVERFLOW;  
            else if(getRegVal & JBIT_CRCERR)
            {   // 
                if(MInfo.nBytesReceived == 0x01 &&
                    (MInfo.nBitsReceived == 0x04 ||
                     MInfo.nBitsReceived == 0x00))
                {   
                    pExchangeBuf[0] = RcGetReg(JREG_FIFODATA);
                    MInfo.nBytesReceived = 1;
                    ucStatus = STATUS_ACK_SUPPOSED; // (N)ACK
                }
                else
                    ucStatus = STATUS_CRC_ERROR;    // CRC´íÎó
            }
            else if(getRegVal & JBIT_TEMPERR)
                ucStatus = STATUS_TEMP_ERROR;       // ζȴíÎó
            if(getRegVal & JBIT_WRERR)
                ucStatus = STATUS_FIFO_WRITE_ERROR; // дFIFO´íÎó
            if(ucStatus == STATUS_SUCCESS)
                ucStatus = STATUS_ERROR_NY_IMPLEMENTED
           
            RcSetReg(JREG_ERROR, 0);
        }

        if(ucStatus != STATUS_ACK_SUPPOSED)  
        {
            ReadFIFO(pExchangeBuf,MInfo.nBytesReceived);
            if(MInfo.nBitsReceived && MInfo.nBytesReceived) 
                MInfo.nBytesReceived --;
        }
    }
    RcSetReg(JREG_COMMIRQ, waitForComm);
    RcSetReg(JREG_DIVIRQ, waitForDiv);
    RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
     return ucStatus;
}

 

 

 

 

请问RC663有没有这样的例子?或示例代码。 最好是MDK-ARM平台的例子。

Outcomes