📄 mfrc50~1.c
字号:
CountDown--; // Decrease timeout counter
if(!CountDown)
{
T2IR = 1; // Set timeout state
TIMSK=0x00;
TCCR2=0x00;
}
}
void stop_timeout(void)
{
TCCR2=0x00;
CountDown = 0;
TCNT2=0x00;
TIMSK=0x00;
}
void start_timeout(unsigned int _10ms)
{
CountDown = _10ms;
TCCR2=0x00;
T2IR = 0;
TCNT2=0xb2;
TCCR2=0x07;
TIMSK=0x40; //44
}
#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
unsigned char irqBits;
unsigned char irqMask;
unsigned char oldPageSelect;
unsigned char nbytes;
unsigned char cnt;
if (MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
{
oldPageSelect = ReadRawRC(RegPage); // save old page select
WriteRawRC(RegPage,0x80); // select page 0 for ISR
while( (ReadRawRC(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
{
irqMask = ReadRawRC(RegInterruptEn); // read enabled interrupts
irqBits = ReadRawRC(RegInterruptRq) & irqMask;
MpIsrInfo->irqSource |= irqBits; // save pending interrupts
if (irqBits & 0x01) // LoAlert
{
nbytes = MFIFOLength - ReadRawRC(RegFIFOLength);
if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
{
nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
WriteRawRC(RegInterruptEn,0x01); // disable LoAlert IRQ
}
for ( cnt = 0;cnt < nbytes;cnt++)
{
WriteRawRC(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
MpIsrInfo->nBytesSent++;
}
WriteRawRC(RegInterruptRq,0x01); // reset IRQ bit
}
if (irqBits & 0x10) // TxIRQ
{
WriteRawRC(RegInterruptRq,0x10); // reset IRQ bit
WriteRawRC(RegInterruptEn,0x82); // enable HiAlert Irq for
// response
if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
{
WriteRC(RegChannelRedundancy,0x02); // RxCRC and TxCRC disable, parity disable
WriteRawRC(RegPage,0x00); // reset page address
}
}
if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
{
nbytes = ReadRawRC(RegFIFOLength);
for ( cnt = 0; cnt < nbytes; cnt++)
{
MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawRC(RegFIFOData);
MpIsrInfo->nBytesReceived++;
}
WriteRawRC(RegInterruptRq,0x0A & irqBits);
}
if (irqBits & 0x04) // Idle IRQ
{
WriteRawRC(RegInterruptEn,0x20); // disable Timer IRQ
WriteRawRC(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
WriteRawRC(RegInterruptRq,0x04); // reset IRQ bit
}
if (irqBits & 0x20) // timer IRQ
{
WriteRawRC(RegInterruptRq,0x20); // reset IRQ bit
MpIsrInfo->status = MI_NOTAGERR; // timeout error
}
}
WriteRawRC(RegPage,oldPageSelect | 0x80);
}
}
char PcdSingleResponseCmd(unsigned char cmd,unsigned char* send,unsigned char* rcv,MfCmdInfo *info)
{
int status = MI_OK;
char tmpStatus ;
unsigned char lastBits;
unsigned char timerCtl;
unsigned char irqEn = 0x00;
unsigned char waitFor;
waitFor = 0x00;
timerCtl = 0x00;
WriteRC(RegInterruptEn,0x3F); // disable all interrupts
WriteRC(RegInterruptRq,0x7F); // reset interrupt requests
WriteRC(RegCommand,0x00); // terminate probably running command
FlushFIFO(); // flush FIFO buffer
MpIsrInfo = info;
MpIsrOut = send;
MpIsrIn = rcv;
info->irqSource = 0x0; // reset interrupt flags
switch(cmd)
{
case 0x00:
irqEn = 0x00;
waitFor = 0x00;
break;
case 0x01:
irqEn = 0x11;
waitFor = 0x10;
break;
case 0x03:
irqEn = 0x07;
waitFor = 0x04;
break;
case 0x07:
case 0x0B:
case 0x0C:
irqEn = 0x05;
waitFor = 0x04;
break;
case 0x12:
irqEn = 0x11;
waitFor = 0x10;
break;
case 0x14:
irqEn = 0x04;
waitFor = 0x04;
break;
case 0x16:
info->nBitsReceived = -(ReadRC(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case 0x19:
irqEn = 0x05;
waitFor = 0x04;
break;
case 0x1A:
irqEn = 0x05;
waitFor = 0x04;
break;
case 0x1E:
info->nBitsReceived = -(ReadRC(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK)
{
irqEn |= 0x20; // always enable timout irq
waitFor |= 0x20; // always wait for timeout
start_timeout(20); // initialise and start guard timer for reader
// 50us resolution, 200ms
WriteRC(RegInterruptEn,irqEn | 0x80); //necessary interrupts are enabled
WriteRC(RegCommand,cmd); //start command
while (!(MpIsrInfo->irqSource & waitFor
|| T2IR)); // wait for cmd completion or timeout
WriteRC(RegInterruptEn,0x3F); // disable all interrupts
WriteRC(RegInterruptRq,0x7F); // clear all interrupt requests
SetBitMask(RegControl,0x04); // stop timer now
stop_timeout();
T2IR = 0;
WriteRC(RegCommand,0x00); // reset command register
if (!(MpIsrInfo->irqSource & waitFor)) // reader has not terminated
{
status = MI_ACCESSTIMEOUT;
}
else
status = MpIsrInfo->status; // set status
if (status == MI_OK) // no timeout error occured
{
if ((tmpStatus = (ReadRC(RegErrorFlag) & 0x17))) // error occured
{
if (tmpStatus & 0x01) // collision detected
{
info->collPos = ReadRC(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 (cmd == 0x1E)
{
lastBits = ReadRC(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;
}
void WriteRC(unsigned char Address, unsigned char value)
{
WriteRawRC(0x00,GetRegPage(Address)); // select appropriate page
WriteRawRC(Address,value); // write value at the specified
}
unsigned char ReadRC(unsigned char Address)
{
WriteRawRC(0x00,GetRegPage(Address)); // select appropriate page
return ReadRawRC(Address); // read value at the specified
}
void WriteRawRC(unsigned char address,unsigned char data)
{
unsigned char g_delay;
DDRB = ~address;
CLEAR_RC500CS();
g_delay=1;
TRIG_ALE();
DDRB = ~data;
CLEAR_WR();
g_delay=1;
g_delay=2;
g_delay=3;
g_delay=4;
g_delay=5;
SET_WR();
SET_RC500CS();
}
unsigned char ReadRawRC(unsigned char address)
{
unsigned char temp,g_delay;
DDRB = ~address;
CLEAR_RC500CS();
g_delay=1;
TRIG_ALE();
DDRB = 0; // PORTC AS INPUT.
CLEAR_RD();
g_delay=1;
g_delay=2;
g_delay=3;
g_delay=4;
g_delay=5;
temp = PINB; // READ DATA.
SET_RD();
SET_RC500CS();
return(temp);
}
void TRIG_ALE(void)
{
unsigned char i;
ALE_SET();
for (i=0;i<10;i++);
ALE_CLEAR();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -