Dear Sir or Madam:We are working on a project with the TRF 7960 with a PIC 32 in SPI mode with Slave select on our own designed board according the TI datasheet TRF7960 SLOU186F page 10 "Application Schematic for the TRF796x EVM (SPI Mode)" and dealing with the following problem.
We can not receive a RX interrupt right now but we receive a TX interrupt and a No Response Interrupt (after sending “Transmit next time slot” command).We are trying to implement the ISO 15693 Protocol with 16 slots according the guideline from TI. We have a TAGit Card (this is what is written on it, but reading with EVM board of Ti result in an ISO 15693 card) and we could check the UID with an EVM board from TI, the card ends with the character B -so in the slot 11(=B)first i will explaing you a two main functions you need to understandRWSPI2() //This functions only sends Data over SPI when the SPI Buffer is empty and also return the MISO data when Data is available in the buffer...this function works, we can write and read RegisterSendDirectCommand(short x); //This function will send the following direct commands according the number , it also includes SSlow and SShigh
x= 0x00, //0= Idle //in the datasheets, SPI datesheet for TRF796x, Idle and SW Init are switched with their value. So not sure to whom to believe 0x03, //1= SW Init 0x0f, //2= Reset 0x14, //3= Transmit next Time slot 0x16, //4= Block receiver 0x17, //5= Enable receiver 0x18, //6= Test internal RF 0x19, //7= Test external RF 0x1A, //8= Receiver Gain Adjust 0x10, //9= Transmit without CRC 0x11, //10= Transmit with CRC 0x12, //11= Delayed transmit without CRC 0x13 //12= Delayed tansmit with CRC all directcommands are stored in a const array DiCo[13], the function SendDirectCommand() check x >=0 && x<=12 and also when x < 9 it will send a dummy write after sending the correct direct command, according the TRF 7960 SPI Datasheet! These are the steps we implemented up to date:Step one:We write to all Registers the standart Value according the datasheet for the trf796x, we did this because some registers don't have the standard value and for future use to bring the System back in a "factory reset"
SlaveSelectRFIDOn(); RWSPI2( CodeAdressWriteCont|AdresseChipStatusControl); //Schreibe ab Adresse ChipStatusControll cont. RWSPI2(0x01); //ChipStatusControllCode; //active, decoded signal, , RF output active, full power, AM, AGC on, Ext. Feld messung an, 3V operation RWSPI2(0x02); //Daten für ISOControl RWSPI2(0x00); //Daten für ISO14443B_TX_Options RWSPI2(0x00); //Daten für ISO 14443A high bit rate options RWSPI2(0xC2); //Daten für TX timer setting, H-byte RWSPI2(0x00); //Daten für TX timer setting, L-byte RWSPI2(0x00); //Daten für TX pulse-length control RWSPI2(0x0E); //Daten für RX no response wait RWSPI2(0x1F); //Daten für RX wait time RWSPI2(0x11); //Daten für Modulator and SYS_CLK control RWSPI2( 0x40 ); //Daten für RX special setting RWSPI2( 0x87); //Daten für Regulator and I/O control SlaveSelectRFIDOff(); This register is almost in standard mode except it has the No Response interrupt activate SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseCollisionPositionandInterruptMaskRegister); RWSPI2(0x3F); //Daten für Collision position and interrupt mask register SlaveSelectRFIDOff();Reading all these Registers, we get the same value we wrote them -> so OK! Step two:some special stettings for our systemSendDirectCommand(5);//Enable Receiver SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseChipStatusControl); RWSPI2(ChipStatusControllCode); //0x24; Antenna on, fullpower, AGC on, 3V, SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseISOControl); RWSPI2(0x02); //(ISO15693 high bit rate 26.48 kbps one sub-carrier 1 out of 4) SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseModulatorandSYS_CLKControl); RWSPI2(0x21);//CL_SYS Output state = 3.3 MHz and OOK = 100 % SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseTX_PulseLengthControl); RWSPI2(0x80); // TX Pulse Length SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseRX_NoResponseWaitTime); RWSPI2(0x2F);// Rx No Response wait time SlaveSelectRFIDOff(); SendDirectCommand(8);//Receiver Gain Adjust Step 3 a):the main commands to start to comunicate with a TAG SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseISOControl);// we did this again to write this register in case of change. RWSPI2(0x02); SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(CodeAdressWriteSingle|AdresseRX_NoResponseWaitTime); RWSPI2(0x14);// we are trying to write some other values to fix the problem, but until now...no success RWSPI2(CodeAdressWriteSingle|AdresseModulatorandSYS_CLKControl); RWSPI2(0x31); // we are trying to write some other values to fix the problem, but until now...no success SlaveSelectRFIDOff(); Here the Inventory request for ISO 15693 according the Implementation ISO 15693 datasheet AND the SLOA140–April 2009 Using the SPI Interface With TRF7960 DATA Sheet SlaveSelectRFIDOn(); RWSPI2(0x8F);/* Reset FIFO command */ RWSPI2(0x91);/* Send with CRC */ RWSPI2(0x3D);/* Write continuous from register 1D */ RWSPI2((char)(3>>4));//3 Bytes are going to be send to FIFO RWSPI2((char)(3<<4)); SlaveSelectRFIDOff(); SlaveSelectRFIDOn(); RWSPI2(0x3F);//cont write in register 1F(FIFO) //sende 3 bytes ins fifo RWSPI2(0x06); // ISO15693 flag with 16 slots bit set RWSPI2(0x01); // ISO15693 anti collision command code RWSPI2(0x00);// Mask length RWSPI2(0x00);//about this zeros ware and not sure but also we tried without this. this was not so clear for us reading the SLOA140–April 2009 Using the SPI Interface With TRF7960 DATA Sheet SlaveSelectRFIDOff(); NOW we are waiting for the ISR (Interrupt) untill the corresponding FLAGS will be set. while(!TXFlag); TXFlag = 0;//we can get to this point, so the TX Interrupt worked DelayMs(20); //accourding one commentar in the Forum of TI this is neccessary for(i=1; i<16; i++) // 16 slots loop, { while(!RXFlag) { if(NoResponseFlag) { NoResponseFlag = 0; // we can get to this point,No Response Interrupt worked! SendDirectCommand(2); //RESET SendDirectCommand(4);//Block receiver SendDirectCommand(5);//Enable Receiver SendDirectCommand(3);//Transmit next Time slot break; } } RXFlag = 0; } SendDirectCommand(4);//Block ReceiverSTEP 3 b):THE ISR (Interrupt Service Routine)://Each Interrupt will increase itsown counter. also there are some notes we still have to do in the ISR, but until RX is not received we can't do anything :(TRF_Ein_Register_lesen(AdresseIRQStatusRegister); // READ one Register in this case IRQ Status Register, also when especial reading this registerd on dummy write will be performed according SLOA140–April 2009 Using the SPI Interface With TRF7960 DATA Sheet // Data will be also stored in the array READ_TRF[16]. All this will be executed in this function if((READ_TRF[16]&0b00000001)&&counter[0]<16) //No RESPONSE { //show error NoResponseFlag = 1; counter[0]++; //No Response counter } if((READ_TRF[16]&0b00000010)&&counter[1]<16) //Collision error { SendDirectCommand(4); SendDirectCommand(2);//Reset FIFO counter[1]++; //Collision error counter } if((READ_TRF[16]&0b00000100)&&counter[2]<16) //Byte framing or EOF error { //Show Error counter[2]++;// Byte framing er EOF error Counter } if((READ_TRF[16]&0b00001000)&&counter[3]<16) //Parity error { counter[3]++;//Parity error counter } if((READ_TRF[16]&0b00010000)&&counter[4]<16)//CRC error { //show Error counter[4]++; // CRC Error counter } if((READ_TRF[16]&0b00100000)&&counter[5]<16)//Signals the FIFO is 1/3 > FIFO > 2/3 { //Read 9 Bytes from FIFO //check if IRQ pin high // no abbort // yes read IRQSTATUSREgister //check EOF received //yes: //Read Status Register to determine Number of bytes in FIFO //Read Data from FIFO counter[5]++;//signals the FIFO is 1/3 > FIFO>2/3 Counter } if((READ_TRF[16]&0b01000000)&&counter[6]<16)//IRQ set due to RX start {
HERE: No RX Interrupt
//Read Status Register to determine Number of bytes in FIFO //Read Data from FIFO RXFlag = 1; counter[6]++; //IRQ set due to RX start Counter } if((READ_TRF[16]&0b10000000)&&counter[7]<16)//IRQ set due to end of TX { SendDirectCommand(2);//Reset FIFO counter[7]++;// IRQ set due to end of TX Counter TXFlag = 1; } INTClearFlag(INT_INT3);}//void __ISR(_EXTERNAL_3_VECTOR, ipl3) ISR_INT3(void)So that is the state where we are sticking and where we are freezed.I hope you can help us...PLEASE
Vitali -
Please see attached several LSA captures for correct way to implement the EOF/Slot marker for ISO15693. Also - we do have the C source firmware on the web in the product folder - this might also be quite helpful to you. key point is to have a look at the configuration and then the inventory captures.
Free viewer can be retrieved from Saleae website here ==>http://www.saleae.com/downloads
4431.ISO15693.zip
BR-
Josh
---------------------------------------------------------------------------------------------------------Please click the Verify Answer button on this post if it answers your question.---------------------------------------------------------------------------------------------------------
Thank you Josh for you fast answer,
we checked our configuration with yours and there is almost no difference, the main difference is when you send direct command you put the SPI Clock high before the SS goes high, we use the option sendig 8 clocksycles (it is easier to implement) , and this is also working, because when we send Transmit next time slot, we receive each time when sending it, a no response Interrupt.
also we are anaylasing the c source firmware and trying to implenent it, but without success yet. The code is programmed hard / confused, because it has many things we don't need like a GUI, other Protocolls and other Interfaces . So i prefer to stick with our code, it is lighter.
with our code we can write and read to all possible registers. and we receive TX interrupt and No receive interrupt(when transmitting "Transmit next Time slot")
also we do have an EVM Module and we wired our SPI interfaces (also the supply wires) with the EVM Module (of course we "disconected" the µC "wires" on the EVM Module and hold it in Reset) . and we have the same results like our PCB. So the our PCB works properly.
So the only thing now is the code....but we can't see the mistirious problem.
SPI works.
we can communicate with the TRF7960
we are sending all the commands discribed in the datasheet and the one in the LSA captures.
We would be so happy if we can just read the UID form the TAG
Best Greetings
Vitali Haag