打印

求救:MFRC500 读 FIFODATA 问题! 先谢谢了。

[复制链接]
3809|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wylwws|  楼主 | 2008-8-7 17:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教各位老兄老姐,小弟初学射频卡,采用的是M64+MFRC500 。现在读写各寄存器都很正常,复位 寻卡也可以。可涉及到读FIFODATA的地方就出错,读出来是固定一个数,请大家指点下,问题出在哪? 

相关帖子

沙发
wylwws|  楼主 | 2008-8-7 17:51 | 只看该作者

相关的程序:

相关的程序: 
void Device_Init(void) 

        MCUCR |= (1<<SRE); //使能总线 
    XMCRA = 0x00;  
    XMCRB = 0x07;    
        DDR_RC500RST(); 
        DDR_RC500IRQ();  
        DDRD &= ~(1<<PD0); 
        PORTD |= (1<<PD0); 

void WriteRawIO(uint addr,uchar value)   

        addr = 0x7f00 + addr; 
        (*(volatile unsigned char *)addr) = value; 

uchar ReadRawIO(uint addr)  

        addr = 0x7f00 + addr; 
        return (*(volatile unsigned char *)addr); 

char  M500PcdCmd(uchar cmd,volatile uchar* send,volatile uchar* rcv,volatile MfCmdInfo *info) 
{      
        char         status    = MI_OK; 
        char          tmpStatus ; 
        uchar         lastBits; 

        uchar  irqEn     = 0x00; 
        uchar  waitFor   = 0x00; 
        uchar  timerCtl  = 0x00; 

        WriteIO(RegInterruptEn,0x7F); // disable all interrupts 
        WriteIO(RegInterruptRq,0x7F); // reset interrupt requests 
        WriteIO(RegCommand,PCD_IDLE); // terminate probably running command 

        FlushFIFO();            // flush FIFO buffer 

   // save info structures to module pointers 
        MpIsrInfo = info;   
        MpIsrOut  = send; 
        MpIsrIn   = rcv; 

        info->irqSource = 0x0; // reset interrupt flags 
   // depending on the command code, appropriate interrupts are enabled (irqEn) 
   // and the commit interrupt is choosen (waitFor). 
        switch(cmd) 
        { 
                case PCD_IDLE:                   // nothing else required 
                        irqEn = 0x00; 
                        waitFor = 0x00; 
                        break; 
                case PCD_WRITEE2:                // LoAlert and TxIRq 
                        irqEn = 0x11; 
                        waitFor = 0x10; 
                        break; 
                case PCD_READE2:                 // HiAlert, LoAlert and IdleIRq 
                        irqEn = 0x07; 
                        waitFor = 0x04; 
                        break; 
                case PCD_LOADCONFIG:             // IdleIRq 
                case PCD_LOADKEYE2:              // IdleIRq 
                case PCD_AUTHENT1:               // IdleIRq 
                        irqEn = 0x05; 
                        waitFor = 0x04; 
                        break; 
                case PCD_CALCCRC:                // LoAlert and TxIRq 
                        irqEn = 0x11; 
                        waitFor = 0x10; 
                        break; 
                case PCD_AUTHENT2:               // IdleIRq 
                        irqEn = 0x04; 
                        waitFor = 0x04; 
                        break; 
                case PCD_RECEIVE:                // HiAlert and IdleIRq 
                        info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); 
                        irqEn = 0x06; 
                        waitFor = 0x04; 
                        break; 
                case PCD_LOADKEY:                // IdleIRq 
                        irqEn = 0x05; 
                        waitFor = 0x04; 
                        break; 
                case PCD_TRANSMIT:               // LoAlert and IdleIRq 
                        irqEn = 0x05; 
                        waitFor = 0x04; 
                        break; 
                case PCD_TRANSCEIVE:             // TxIrq, RxIrq, IdleIRq and LoAlert 
                        info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4); 
                        irqEn = 0x3D; 
                        waitFor = 0x04; 
                        break; 
                default: 
                        status = MI_UNKNOWN_COMMAND; 
        }         
   if (status == MI_OK) 
   { 
                // Initialize uC Timer for global Timeout management 
                irqEn |= 0x20;                        // always enable timout irq 
                waitFor |= 0x20;                      // always wait for timeout  

                start_timeout(4000);          // initialise and start guard timer for reader 
                                          // 50us resolution, 200ms 
       
                WriteIO(RegInterruptEn,irqEn | 0x80);  //necessary interrupts are enabled 
                WriteIO(RegCommand,cmd);               //start command    

      // wait for commmand completion 
      // a command is completed, if the corresponding interrupt occurs 
      // or a timeout is signaled   

                while (!(MpIsrInfo->irqSource & waitFor|| T2IR));    // wait for cmd completion or timeout 

                WriteIO(RegInterruptEn,0x7F);          // disable all interrupts 
                WriteIO(RegInterruptRq,0x7F);          // clear all interrupt requests 
                SetBitMask(RegControl,0x04);           // stop timer now 

                stop_timeout();                          // stop timeout for reader 
                WriteIO(RegCommand,PCD_IDLE);          // reset command register 


                if (!(MpIsrInfo->irqSource & waitFor))   // reader has not terminated 
                {                                // timer 2 expired 
                        status = MI_ACCESSTIMEOUT; 
                } 
                else 
                        status = MpIsrInfo->status;           // set status 

                if (status == MI_OK)                     // no timeout error occured 
                { 
                        if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17)) // error occured 
                        { 
                                if (tmpStatus & 0x01)   // collision detected 
                                { 
                                        info->collPos = ReadIO(RegCollpos); // read collision position 
                                        status = MI_COLLERR; 
                                } 
                                else 
                                { 
                                        info->collPos = 0; 
                                        if (tmpStatus & 0x02)   // parity error 
                                        { 
                                                status = MI_PARITYERR; 
                                        } 
                                } 
                                if (tmpStatus & 0x04)   // framing error 
                                { 
                                        status = MI_FRAMINGERR; 
                                } 
                                if (tmpStatus & 0x10)   // FIFO overflow 
                                { 
                                        FlushFIFO(); 
                                        status = MI_OVFLERR; 
                                } 
                                if (tmpStatus & 0x08) //CRC error 
                                { 
                                        status = MI_CRCERR; 
                                }         
                                if (status == MI_OK) 
                                        status = MI_NY_IMPLEMENTED; 
            } 
                        // if the last command was TRANSCEIVE, the number of  
                        // received bits must be calculated - even if an error occured 
                        if (cmd == PCD_TRANSCEIVE) 
                        { 
                                        // number of bits in the last byte 
                                lastBits = ReadIO(RegSecondaryStatus) & 0x07; 
                                if (lastBits) 
                                        info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits; 
                                else 
                                        info->nBitsReceived += info->nBytesReceived * 8; 
                        }                 
                } 
                else 
                { 
                        info->collPos = 0x00; 
                } 
        } 
        MpIsrInfo = 0;         // reset interface variables for ISR 
        MpIsrOut  = 0; 
        MpIsrIn   = 0;  
        return status; 
}    
char M500PiccCommonRequest(uchar req_code,uchar *atq) 

        char status = MI_OK; 

                //************* initialize ****************************** 
        WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable 
        ClearBitMask(RegControl,0x08);    // disable crypto 1 unit    
        WriteIO(RegBitFraming,0x07);        // set TxLastBits to 7  
        SetBitMask(RegTxControl,0x03);    // Tx2RF-En, Tx1RF-En enable 
    
        ResetInfo(MInfo);    
        MSndBuffer[0] = req_code; 
        MInfo.nBytesToSend   = 1;    
        status = M500PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer,&MInfo); 
   
        if (status)      // error occured 
        { 
                *atq = 0; 
        }  
        else  
        { 
                if (MInfo.nBitsReceived != 16) // 2 bytes expected 
                { 
                        *atq = 0; 
                        status = MI_BITCOUNTERR; 
                }  
                else  
                { 
                        status = MI_OK; 
                        memcpy(atq,MRcvBuffer,2); 
                } 
        } 
        return status;  

char PcdReadE2(uchar startaddr,uchar length,uchar* _data) 

        char status = MI_OK; 

     // ************* Cmd Sequence **********************************  
    ResetInfo(MInfo);    
    MSndBuffer[0] = startaddr & 0xFF; 
    MSndBuffer[1] = (startaddr >> 8) & 0xFF; 
    MSndBuffer[2] = length; 
    MInfo.nBytesToSend   = 3; 
    status = M500PcdCmd(PCD_READE2,MSndBuffer,MRcvBuffer,&MInfo); 
    if (status == MI_OK) 
    { 
                memcpy(_data,MRcvBuffer,length); 
    } 
    else   // Response Processing 
    { 
                _data[0] = 0; 
    } 
    return status ; 

SIGNAL(SIG_INTERRUPT0)    //Ext0 interrupt 

        static uchar irqBits; 
        static uchar irqMask;             
        static uchar nbytes; 
        static uchar cnt; 

        EIFR |= (1<<INT0);         // Clear interrupt request flag 
        //WriteRawIO(0,0x80);//?????????????????? 
        if (MpIsrInfo && MpIsrOut && MpIsrIn)  // transfer pointers have to be set correctly 
        { 
                while( ReadRawIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending   
                                                                                                        //Attention: IRQ bit is  
                                                                                                        // inverted when used with 
                                                                                                        // low activ IRQ 
                { 
                        irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts 读取激活的中断 
                        // read pending interrupts 
                        irqBits = ReadRawIO(RegInterruptRq) & irqMask;//读取未激活的中断 
                        MpIsrInfo->irqSource |= irqBits; // save pending interrupts 保存未激活的中断 
                        //************ LoAlertIRQ ****************** 
                        if (irqBits & 0x01)    // LoAlert  数据发送 
                        {   
                                nbytes = MFIFOLength - ReadRawIO(RegFIFOLength); 
                                // less bytes to send, than space in FIFO 
                                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes) 
                                { 
                                        nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent; 
                                        WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ 
                                } 
                                // write remaining data to the FIFO 
                                for ( cnt = 0;cnt < nbytes;cnt++) 
                                { 
                                        WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);//写数据到FIFO 
                                        MpIsrInfo->nBytesSent++; 
                                } 
                                WriteRawIO(RegInterruptRq,0x01);  // reset IRQ bit 
                        } 
                        //************* TxIRQ Handling **************发送结束中断处理 
                        if (irqBits & 0x10)       // TxIRQ 
                        { 
                                WriteRawIO(RegInterruptRq,0x10);    // reset IRQ bit  
                                WriteRawIO(RegInterruptEn,0x82);    // enable HiAlert Irq for response 
                                if (MpIsrInfo->cmd == PICC_ANTICOLL1)         // if cmd is anticollision 
                                {                                           // switch off parity generation 
                                        WriteRawIO(RegChannelRedundancy,0x02);        // RXCRC and TXCRC disable, parity disable 
                                }         
                        } 

                        //************* HiAlertIRQ or RxIRQ Handling ******************接收数据中断处理 
                        if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ 
                        { 
                                        // read some bytes ( length of FIFO queue)   into the receive buffer            
                                        // 读FIFO队列中的数据到 receive buffer 
                                nbytes = ReadRawIO(RegFIFOLength); 
                                // read date from the FIFO and store them in the receive buffer 
                                for ( cnt = 0; cnt < nbytes; cnt++)                
                                { 
                                        MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData); 
                                        MpIsrInfo->nBytesReceived++; 
                                } 
                                WriteRawIO(RegInterruptRq,0x0A & irqBits);   
                // reset IRQ bit - idle irq will be deleted in a seperate section 
                        }    
    
                        //************** IdleIRQ Handling ***********指令寄存器清零 中断处理 
                        if (irqBits & 0x04)     // Idle IRQ 
                        { 
                                WriteRawIO(RegInterruptEn,0x20); // disable Timer IRQ 
                                WriteRawIO(RegInterruptRq,0x20); // disable Timer IRQ request 
                                irqBits &= ~0x20;   // clear Timer IRQ in local var 
                                MpIsrInfo->irqSource &= ~0x20;  
                                // clear Timer IRQ in info var when idle received, then cancel timeout 
                                WriteRawIO(RegInterruptRq,0x04);   
                                // reset IRQ bit status should still be MI_OK no error - only used for wake up 
                        } 
        
                        //************* TimerIRQ Handling ***********超时中断处理 
                        if (irqBits & 0x20)       // timer IRQ 
                        { 
                                WriteRawIO(RegInterruptRq,0x20); // reset IRQ bit  
                                MpIsrInfo->status = MI_NOTAGERR; // timeout error 
                // otherwise ignore the interrupt 
                        } 
          
                } 
        } 

使用特权

评论回复
板凳
jobkong| | 2014-5-27 11:49 | 只看该作者
各位大兄,大姐
我也碰到了类似的问题,MFRC500读写其它的寄存器都正常,但是读FIFO寄存器时却读数错误,只读出一个固定的数,即使在使用FlushFIFO进行FIFO清零后,重新向FIFO写入数据,接着读FIFO寄存器,还是读不到正确的数据,但能观察到FIFOLength的变化。请大虾们指点一下。

使用特权

评论回复
地板
Durant35| | 2015-12-18 11:13 | 只看该作者
请问一下您 “MFRC500读写其它的寄存器都正常,但是读FIFO寄存器时却读数错误,只读出一个固定的数” 这个问题问题解决了吗?我是新手 最近在做STM32控制MFRC500 也遇到这个问题 打扰您了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝