📄 trf7960.c
字号:
#include "TRF7960.h"
#include <avr/delay.h>
#include <avr/crc16.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
volatile char IRQ_Status=0;
//volatile char *cFIFO_Data[30];
//volatile char cFIFO_Len;
/*
//计算CRC16
unsigned int calcrc(unsigned char *ptr, unsigned char count)
{
unsigned int crc = 0;
while (count--)
{
crc =_crc16_update(crc,*ptr++);
}
return crc;
}
*/
// get data from TRF7963
char Data_Input(void)
{
char data=0;
// data5-0 input, 上拉使能
DDRC &= ~AD5_AD0;
//PORTC |= (1<<AD0)|(1<<AD1)|(1<<AD2)|(1<<AD3);
// data7-6 input, 上拉使能
DDRB &= ~AD7_AD6;
//PORTB |= (1<<AD4)|(1<<AD5)|(1<<AD6)|(1<<AD7);
DelayUs(10);
data |= (PINC & AD5_AD0);// bit5-0
data |= ( (PINB & AD7_AD6)<<6 );// bit7-6
return data;
}
// put data to TRF7963
char Data_Output(char data)
{
// output data5-0
DDRC |= AD5_AD0;
PORTC = (PORTC & (~AD5_AD0)) | (data & AD5_AD0);
// output data7-6
DDRB |= AD7_AD6;
PORTB = (PORTB & (~AD7_AD6)) | (data>>6);
DelayUs(10);
return data;
}
void CLK_Low(void)
{
// DATA_CLK output low
PORTB &= ~(1<<DATA_CLK);
DelayUs(10);
}
void CLK_High(void)
{
// DATA_CLK output high
PORTB |= (1<<DATA_CLK);
DelayUs(10);
}
void Start_Condition(void)
{
// start condition
CLK_High();
Data_Output(0x00);
Data_Output(0xFF);
CLK_Low();
}
void Stop_Condition(void)
{
// stop condition
CLK_High();
Data_Output(0xFF);
Data_Output(0x00);
CLK_Low();
}
void Stop_Continue(void)
{
// stop continue condition
CLK_Low();
Data_Output(0x00);
Data_Output(0xFF);
Data_Output(0x00);
}
// put cmd to TRF7963
void TRF7963_cmd(char cCmd)
{
// start condition
Start_Condition();
// addr, data or cmd
Data_Output(cCmd|TRF7963_CMD);
CLK_High();
CLK_Low();
// stop condition
Stop_Condition();
}
// get data from TRF7963
char TRF7963_getc(char cAddr)
{
char cTmp;
// start condition
Start_Condition();
// addr
Data_Output(cAddr|TRF7963_READ);
CLK_High();
CLK_Low();
// get data
CLK_High();
cTmp = Data_Input();
CLK_Low();
// stop condition
Stop_Condition();
return cTmp;
}
int TRF7963_gets(char cAddr, char *cData, int length)
{
int i;
// start continue condition
Start_Condition();
// addr
Data_Output(cAddr | TRF7963_READ | TRF7963_CON_MODE);
CLK_High();
CLK_Low();
// get data
for (i=0; i<length; i++)
{
CLK_High();
cData[i] = Data_Input();
CLK_Low();
}
// stop continue condition
Stop_Continue();
return i;
}
// put cmd to TRF7963
void TRF7963_putc(char cAddr, char cData)
{
// start condition
Start_Condition();
// addr
Data_Output(cAddr);
CLK_High();
CLK_Low();
// put data
Data_Output(cData);
CLK_High();
CLK_Low();
// stop condition
Stop_Condition();
}
// put addr, data or cmd to TRF7963
// cFIFO_start means the address of cData, or else 0
int TRF7963_puts(char *cData, int length, char cFIFO_start, char bDelay)
{
int i, j;
// start continue condition
Start_Condition();
// no FIFO data, or FIFO bytes <=12
if( (length-cFIFO_start)<13 )
{
for (i=0; i<length; i++)
{
Data_Output(cData[i]);
CLK_High();
CLK_Low();
}
}
else
{
// first 12 bytes to FIFO
for (i=0; i<cFIFO_start+12; i++)
{
Data_Output(cData[i]);
CLK_High();
CLK_Low();
}
//DelayMs(500);
Stop_Continue();
// wait for FIFO data sending out
j = 0;
while (1)
{
WaitforSignal(0x20, 100);
if (TRF7963_getc(0x1C) & 0x20)
{
break;
}
j++;
//DelayMs(10);
if (j == 5)
{
return -1;// delay 500ms, exit
}
}
Start_Condition();
// addr
Data_Output(0x3F);
CLK_High();
CLK_Low();
for (; i<length; i++)
{
Data_Output(cData[i]);
CLK_High();
CLK_Low();
}
}
// stop continue condition
if(bDelay)
{
DelayMs(10);
}
Stop_Continue();
return i;
}
int TRF7963_Init(void)
{
char i;
// EN high
DDRD |= (1<<DDD7);
PORTD |= (1<<PD7);
// ASK/OOK , 0-ASK, 1-OOK
//DDRD |= (1<<DDD4);
//PORTD |= (1<<PD4);
// EN2 high
DDRB |= (1<<DDD6);
PORTB |= (1<<PD6);
// DATA_CLK output
DDRB |= (1<<DATA_CLK);
DelayMs(10);
//
Data_Input();
TRF7963_cmd(0x03);// TRF7963 soft init
TRF7963_putc(0, 0x21); // TX Enbale
DelayMs(10);
if (TRF7963_getc(0) != 0x21)
{
return -1;
}
return 0;
//TRF7963_putc(1, 0x08); // ISO14443A
// No response interrupt
//cTmp = TRF7963_getc(0x0D);
//cTmp |= 0x01;
//TRF7963_putc(0x0D, cTmp);
// memset(cFIFO_Data, 0x00, sizeof(cFIFO_Data));
// cFIFO_Len = 0;
}
// 0 for OK
// 0xFF for time out
char WaitforSignal(char cMask, int ms)
{
int i=0;
char cTmp;
while (1)
{
if (IRQ_Status)
{
if (IRQ_Status&cMask)
{
IRQ_Status = 0;
return 0;
}
cTmp = IRQ_Status;
IRQ_Status = 0;
return cTmp;
}
else if (i++ >= ms)
{
break;
}
DelayMs(1);
}
return 0xFF;
}
/*int WaitforInt(char cValue, int ms)
{
int i=0;
while (1)
{
if ((PIND&(1<<PIND3)))
{
if(TRF7963_getc(0x0C) & cValue)
{
return 0;
}
}
else if (i++ == ms)
{
break;
}
DelayMs(1);
}
return -1;
}*/
int GetFIFOData(char *cBuf, int nlength)
{
char cTmp;
int length;
length = 0;
while(1)
{
// Read FIFO status register to determine number of bytes in FIFO
cTmp = TRF7963_getc(0x1C) ;
if(cTmp & 0x10)
{
UART_puts("Over flow!\r\n");
return 0xFF;
}
cTmp &= 0x0F;
// Read data from FIFO
if (cTmp)
{
TRF7963_gets(0x1F, cBuf+length, cTmp+1);
length += cTmp+1;
if (length > 256)
{
break;
}
}
if (WaitforSignal(0x20, 300))
{
break;
}
}
// cTmp = TRF7963_getc(0x1C)&0x0F;
if (length == 0)
{
cBuf[0] = TRF7963_getc(0x1F);
length = 1;
}
// reset FIFO
TRF7963_cmd(0x0F);
return length;
}
// first call the function , must be mask_length=0, mask_value[0..8]=0, cpreSLOT_Pointer=16
// such as GetTagUID(mask_value, 0, cTagNO);
// mask_length= 4, 8, 12, 16 ...
// mask_value[0..8] half byte is: [0x0..0x0F]
// if the mask value is 25A3D, then
// mask_value[0] = 0x3D,
// mask_value[1] = 0x5A,
// mask_value[2] = 0x02,
// return <0, err
// return 0, no tag it
// return >0, tag NO
int GetTagUID(char *mask_value, char mask_length, char *cTagNO)
{
char cStr[50];
char TRF7963_FIFO[50];
char cTmp, cTmp1;
char cBuf[30], i, length;
char size;
int iTagitNUM = 0;
IRQ_Status = 0;
size = (mask_length+4)/8;
memset(cBuf, 0x00, sizeof(cBuf));
//memset(mask_value, 0x00, sizeof(mask_value));
// mask depth is overlay
if (size > 15)
{
return 0;
}
// No response interrupt
cTmp = TRF7963_getc(0x0D);
cTmp |= 0x01;
TRF7963_putc(0x0D, cTmp);
cBuf[0] = 0x8f; // Reset FIFO command
cBuf[1] = 0x91; // send with CRC
cBuf[2] = 0x3d; // write continuous from register 1D
cBuf[3] = (char)( (3+size)>>8 );
cBuf[4] = (char)( (3+size)<<4 );
cBuf[5] = 0x06; // ISO15693 flag with 16 slots bit set
cBuf[6] = 0x01; // ISO15693 anti collision command code
cBuf[7] = mask_length; // mask length
if (size > 0)
{
memcpy(cBuf+8, mask_value, size);
}
length = 8+size;
TRF7963_puts(cBuf, length, 5, 0);
// waitfor End of transmit interrupt
if(WaitforSignal(0x80, 100) == 0xFF)
{
return -1;
}
for(i=0; i<16; i++)
{
memset(cStr, 0x00, sizeof(cStr));
// waitfor End of RX interrupt
cTmp = WaitforSignal(0x40,100);
if ( cTmp == 0 )
{
memset(TRF7963_FIFO, 0x00, sizeof(TRF7963_FIFO));
cTmp = GetFIFOData(TRF7963_FIFO, 0);
if (cTmp >= 9)
{
cTmp = iTagitNUM;
// for (cTmp1=2; cTmp1<10; cTmp1++)
// {
// cTagNO[cTmp1-2+cTmp*8] = TRF7963_FIFO[cTmp1];
// }
memcpy(cTagNO+iTagitNUM*8, TRF7963_FIFO+2, 8);
iTagitNUM++;
}
}
else if (cTmp & 0x02 && i)
{
cTmp = (mask_length+4)>>3;
if (mask_length & 0x04)
{
mask_value[cTmp] |= i<<4;// high 4 bits
}
else
{
mask_value[cTmp] |= i;//low 4 bits
}
iTagitNUM += GetTagUID(mask_value, mask_length+4, cTagNO+iTagitNUM*8);
if (mask_length & 0x04)
{
mask_value[cTmp] &= 0x0F;// high 4 bits
}
else
{
mask_value[cTmp] = 0;//low 4 bits
}
}
// Reset FIFO
TRF7963_cmd(0x0F);
DelayUs(50);
// send EOF
TRF7963_cmd(0x16); // Send Block RX command
DelayUs(50);
TRF7963_cmd(0x17); // Send Enable RX command
DelayUs(50);
TRF7963_cmd(0x14); // Send Transmit Next Slot (EOF) command
}
// disable No response interrupt
cTmp = TRF7963_getc(0x0D);
cTmp &= 0xFE;
TRF7963_putc(0x0D, cTmp);
return iTagitNUM;
}
int GetTagUID1Slot(char *cTagNO)
{
char TRF7963_FIFO[50];
char cTmp;
char cBuf[30], length;
int iTagitNUM = 0;
IRQ_Status = 0;
memset(cBuf, 0x00, sizeof(cBuf));
cBuf[0] = 0x8f; // Reset FIFO command
cBuf[1] = 0x91; // send with CRC
cBuf[2] = 0x3d; // write continuous from register 1D
cBuf[3] = (char)( 3>>8 );
cBuf[4] = (char)( 3<<4 );
cBuf[5] = 0x26; // ISO15693 flag with 16 slots bit set
cBuf[6] = 0x01; // ISO15693 anti collision command code
cBuf[7] = 0;//mask_length; // mask length
// if (size > 0)
// {
// memcpy(cBuf+8, mask_value, size);
// }
length = 8;
TRF7963_puts(cBuf, length, 5, 0);
// waitfor End of transmit interrupt
if(WaitforSignal(0x80, 500) == 0xFF)
{
return -1;
}
// waitfor End of RX interrupt
if(WaitforSignal(0x40, 500) == 0xFF)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -