搜索
bottom↓
回复: 7

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

[复制链接]

出0入0汤圆

发表于 2008-8-7 17:31:43 | 显示全部楼层 |阅读模式
请教各位老兄老姐,小弟初学射频卡,采用的是M64+MFRC500 。现在读写各寄存器都很正常,复位 寻卡也可以。可涉及到读FIFODATA的地方就出错,读出来是固定一个数,请大家指点下,问题出在哪?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2008-8-7 17:34:25 | 显示全部楼层
相关的程序:
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
                        }
         
                }
        }
}

出0入0汤圆

 楼主| 发表于 2008-8-7 19:16:36 | 显示全部楼层
大虾们出来透透气吧。。。。

出0入0汤圆

发表于 2008-8-17 16:40:05 | 显示全部楼层
楼主可不可以把电路图共享一下,我现在也在做这个,不过更菜,还不认识RC500..

出0入0汤圆

发表于 2009-5-19 22:46:31 | 显示全部楼层
同意楼上…………请楼主共享下做做贡献吧!

出0入0汤圆

发表于 2011-1-23 18:59:30 | 显示全部楼层
能不能说明一下,这个函数的0x7F00是怎么来的,求解释....
void WriteRawIO(uint addr,uchar value)   
{
addr = 0x7f00 + addr;
(*(volatile unsigned char *)addr) = value;
}

出0入0汤圆

发表于 2011-4-20 22:09:01 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-12-5 15:26:54 | 显示全部楼层
doudouxiong 发表于 2011-1-23 18:59
能不能说明一下,这个函数的0x7F00是怎么来的,求解释....
void WriteRawIO(uint addr,uchar value)   
{

#define RcBaseAddr 0x7F00 
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 22:12

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表