This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TRF7960ATB hardware issue and initialitaion problem using SPI

Other Parts Discussed in Thread: TRF7960, TRF7960A, TRF7970A

Good morning,

I am using the evaluation board TRF7960ATB to apply it to my design. My goal is to communicate with the STM32F101RB MCU.

The problem is that I can not initialize the reader and I do not know if the reason is I have damaged the evaluation board or I do not use correctly the command codes of the TRF7960.

Firstly, I think the evaluation board has been damaged because pin one, VDD_A,  should give a regulated voltage of 3.4Vmax, and gives a voltage of 5V. Another reason is the antenna does not emit signal. I think it is  due to improper initialization of the evaluation board.

About the command code, my question is as follows: on page 36 of the datasheet in Table 5.31 we can find a difference between ADRESS MODE and COMMAND MODE. As I understand it, the COMMAND MODE is used to send commands from the PC using communication software between the evaluation kit TRF7960ATB + MSP430F5384A and contains the following structure:
                 | BIT 7 | BIT 6 | BIT 5 | BIT 4 | BIT 3 | BIT 2 | BIT 1 | BIT 0 |
                        1       0           0        x          x        x          x            x
Where "x" are bits 0 through 4, corresponding to the commands given in the document "Using the SPI interface with TRF7960" table 2 (page 6). Therefore, for example, I would like to reset the TRF, the command should be use is  0x0f, and forming the previous structure that would be sent by the SPI would be 0x8F.

The case is that I initialize the TRF directly from my MCU, therefore, I should use the ADRESS MODE, right? Whose structure is as follows:
                  | BIT 7 |   BIT 6  |   BIT 5  | BIT 4 | BIT 3 | BIT 2 |  BIT 1 | BIT 0 |
                       0         R / W     R ​​/ W     x           x         x         x              x
Where bits 0 through 4 correspond to the commands given in the document "Using the SPI interface with TRF7960" table 1 (page 5). Therefore, for example, I would like to reset the TRF, the command should be use is  0x0f, and forming the previous structure that would be sent by the SPI would be 0x2F,if continius adress mode is used, if not, it would be 0x0F. Another  question is  when I must use R = READ and when W = WRITE in ADRESS MODE?

I have tried both formats and I couldn´t with any. Then I show part of the code that I use to communicate the MCU and the TRF and initialize the second

//////////////////////////code

BYTE readTagArray[]={
     0x8F, // Reset FIFO
     0x91, // Send with CRC
     0x3D, // Write continous from register 1D
     0x00, // Data for register 1D
     0x30, // Data for register 1E
     0x02, // ISO15693
     0x20,   
     0x00};
  const unsigned char commandArray[]={
      // Register #       Command:
     0x21, // 00 State control register    Turn ON RF driver
     0x02, // 01 ISO control register     ISO15693 protocol selection
     0x00, // 02 Select TX options register  Default setting
     0x00, // 03 High bit rate options register Default setting
     0xC1, // 04 TX Timer H-Byte register   ????
     0xBB, // 05 Timer L-Byte register    ????
     0x00, // 06 TX Pulse Length Control register  ????
     0x0E, // 07 No Response Wait Time register Default setting
     0x1F, // 08 RX Wait Time register    Default setting
     0x21, // 09 Modulator and SYS_CLK Control  ????
     0x40, // 0A RX Special Setting Register  Default setting
     0x87}; // 0B Regulator and I/O Control   Default setting
// static U64 cmd_stack[400];                       /* A bigger stack for command task     */
// static U64 rs485_stack[100];                      /* A bigger stack for command task     */
// static U64 menu_stack[100];                      /* A bigger stack for command task     */
 
 os_mut_init(SemDatos);
 os_mut_init(SemSPI1);

 os_mbx_init(mboxComandos, sizeof(mboxComandos));         // Inicialización del mailbox
 _init_box (msgpoolComandos, sizeof(msgpoolComandos), sizeof(COMANDO_MBX_MSG));  // Inicializacion de la memoria pool

 SPI1_Init();
 SPI_Cmd (SPI1, ENABLE);
 
  SPI1_Select();
 os_dly_wait(10);
 SPI1_Deselect();
 os_dly_wait(10);
 
     SPI1_Select();
    for(i=0x00; i<=0x0B; i++)
    {
       SPI1_Write(i);   // Send register address
     commandByte=commandArray[i];
     SPI1_Write(commandByte); // Send command
      os_dly_wait(10);
    }
    SPI1_Deselect();
 
    os_dly_wait(10);
       
    // ISO15693 READ TAG command   
    SPI1_Select();
    for(i=0; i<8; i++)
    {
     commandByte=readTagArray[i];
     SPI1_Write(commandByte);
    }
    SPI1_Deselect();


 ////////////////////////END CODE   


In this case I use the COMMAND MODE, is it correct, or should I use the ADRESS MODE? On the other hand, could you tell me the order of hardware initialization commands, if I use the COMMAND or ADRESS MODE, and how read the target please?

On the other hand, when communicating directly from the MCU, should I do a DUMMY READ?

Thank you, and I await your response.

Joseba Arginzoniz

  • Hello Joseba,

    If you are using the TRF7960ATB, you should be looking at the TRF7960A datasheet, not the TRF7960 Datasheet: http://www.ti.com/lit/ds/symlink/trf7960a.pdf

    Now then, regarding commands, there is a difference between a Direct Command, and a Register Read/Write. If you are using Direct Commands such as reset, they must start with B7 = 1. So the Reset command is sent over SPI as 0x8F. 0x2F is not a command the TRF7960A will recognize in any form.

    Please reference our existing TRF7960A firmware example to see how these commands are issued: http://www.ti.com/lit/zip/sloc251

    In addition to the SPI interface document you have found, please review these firmware design hints too: http://www.ti.com/lit/an/sloa155/sloa155.pdf

    I think if you review the right datasheet along with our example code, you'll better see how to communicate with the TRF7960A. Let me know if you further questions after reviewing these resources.

  • Hi Ralph,
    thanks for the answer,

    I have another question about RECEIVE and TRANSMIT from MCU to TRF7960. I´m reading the datasheet, but I can not understand how I have to form the frames, what cain of infromation I have to introduce. Could you explain me, pelase?

    I need to implement de ISO14443A. I analyzing the code tha you recommended but I have some questions about how to form the frames and how to initialize the evaluation board. I try to aplicate the solution from other forum "Problem in transmitting select command for ISO14443A", where it was used this code:

    I have some questions.

    1.In the first phase I have transmitted the REQA command and successfully gets ATQA response from the TAG.

    SS line low

    buf[0] = 0x8f; /* Reset FIFO command */
    buf[1] = 0x90; /* send with CRC */
    buf[2] = 0x3d; /* write continuous from register 1D */WHYYYY????
    buf[3] = 0x00; /* Data for register 1D */ WHYYYY????
    buf[4] = 0x0f; /* Data for register 1E */WHYYYY????
    buf[5] = 0x26; /* ISO14443A REQA command byte*/WHYYYY????

    SS line high

    2.In the next phase i execute a anticollision loop with the anticollission command and again i succesfully got response from the tag and collect 5 bytes of UID of the ISO14443A Tag from the FIFO of the TRF7970a

    SS line low

    buf[0] = 0x8f; /* Reset FIFO */
    buf[1] = 0x91; /* Transmit with no CRC for ANTICOLLISION command */
    buf[2] = 0x3d; /* Write continuous to register 0x1D */
    buf[3] = 0x00; /* Data for register 0x1D */ WHYYYY????
    buf[4] = NVB & 0xf0; /* Data for register 1E */WHYYYY????
    if ((NVB & 0x07) != 0x00) /* Number of complete bytes – Data for reg. 0x1E */WHYYYY????
    buf[4] |= ((NVB & 0x07) << 1) + 1; /* Number of broken bits with Broken byte flag set in reg. 0x1E */WHYYYY????
    buf[5] = select; /* Can be 0x93, 0x95 or 0x97 */WHYYYY????
    buf[6] = NVB; /* Number of valid bits = 0x20*/WHYYYY????
    buf[7] to buf[7+searchlength] = UID search criterion

    SS line high

    3.But when i goes further and transmit the SELECT command with the Collected UID(at cascade level 1),the TRF7970A chip behave abnormally.

    SS line low

    buf[0] = 0x8f; /* Reset FIFO */
    buf[1] = 0x90; /* Transmit with CRC for SELECT command */
    buf[2] = 0x3d; /* Write continuous to register 0x1D */
    buf[3] = 0x00; /* Data for register 0x1D */
    buf[4] = NVB & 0xf0; /* Data for register 1E */
    if ((NVB & 0x07) != 0x00) /* Number of complete bytes – Data for reg. 0x1E */
    buf[4] |= ((NVB & 0x07) << 1) + 1; /* Number of broken bits with Broken byte flag set in reg. 0x1E */
    buf[5] = select; /* Can be 0x93, 0x95 or 0x97 */
    buf[6] = NVB; /* Number of valid bits = 0x70 */
    buf[7] to buf[7+searchlength] = UID search criterion

    SS line high

    My biggest problem is how form frames, what kind of information I have to introduce in it and how to configurate the ISO.

    I hope you could explain me.

    Thanks
  • Hello Joseba,

    If you read the details within the datasheet Section 6.12.4.2 Serial Interface Mode With Slave Select (SS) then the framing of bytes to transmit data should become more clear. Particularly focus on the step by step walk through with images starting on Figure 6-20 where the first over the air command is issued. The standard in those images is ISO15693, but the process is identical for ISO14443A. You only need to change the over the air commands being transmitted, but all handling described in terms of how to load data into the FIFO and how to receive responses is the same.

    Section 6.12.3.2 Data Transmission to MCU also describes the reason for writing to 0x1D and 0x1E.

    Regarding the following notes:

    buf[5] = 0x26; /* ISO14443A REQA command byte*/WHYYYY????

    buf[5] = select; /* Can be 0x93, 0x95 or 0x97 */WHYYYY????
    buf[6] = NVB; /* Number of valid bits = 0x20*/WHYYYY????

    These are commands from the ISO14443 Standard. Please refer to the ISO14443 Specifications to understand what they represent.

    The least clear portion of the code is:

    buf[4] = NVB & 0xf0; /* Data for register 1E */WHYYYY????
    if ((NVB & 0x07) != 0x00) /* Number of complete bytes – Data for reg. 0x1E */WHYYYY????
    buf[4] |= ((NVB & 0x07) << 1) + 1; /* Number of broken bits with Broken byte flag set in reg. 0x1E */WHYYYY????

    This is handling done in firmware because the amount of bytes to transmit out varies on the tag response and you can never hard code that. Thus we must account for this variance with these lines in order to allow the TRF7960A to handle all possible situations.

  • Hello Ralph,

    I have another question. I am trying to communicate the MCU with the TRF7960A via SPI. For this, I have configured the SPI communication like this on the MCU:
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //CPOL=0
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // CPHA=0
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;

    So the SPI comunication works in MODE=0, and the clock speed is 2MHz. The following image show the data trasmited throught MOSI and CLK is trasmiten in the correct format ; as it´s specified on 6.12.4.2 Serial Interface Mode With Slave Select (SS) on TRF7960AMultiprotocol Fully Integrated 13.56-MHz RFID Reader/Writer IC (Rev. E) document:

    "The read command is sent out on the MOSI pin, MSB first, in the first eight clock cycles. MOSI data changes on the falling edge, and is validated in the reader on the rising edge, as shown in Figure 6-17."

    I try sending a REGISTER READ to show Status of a specific Register, then WITING IN REGISTER a specific configuration, and finaly READ THE NEW CONFIGURATION in the specific register:
    step 1: READ 0x00 Register -> SEND 0x40
    step 2: RECEIVE 0x00 STATUS -> RECEIVE 0x10
    step 3: WITE IN 0x00 REGISTER -> SEND 0x00
    step 4: WITE IN 0x00 NEW STATUS CONFI -> SEND 0x20
    step 5: READ 0x00 Register -> SEND 0x40
    step 6: RECEIVE 0x00 STATUS -> RECEIVE 0x10

    In step 6 it should be read 0x20, but it´s read 0x01 (the last configuration). What´s happen? I only do this process. Should I reset the FIFO before or after this process with followinf plot to save the new configuration?
    step 0: SEND 0x8F,0x91,0x3D,0x00,0x30,0x26,0x01,0x00 (before step 1)
    OR
    step 7: SEND 0x8F,0x91,0x3D,0x00,0x30,0x26,0x01,0x00 (after step 2)

    I do this simple example because I tried configuring the ISO15693 following the code that you recomended me: www.ti.com/.../sloc251, and I coudn´t.

    Could you give me any recomendation?

    Thanks,

    Joseba
  • Hello Joseba,

    Have you consulted the TRF7960A Firmware Design Hints document: www.ti.com/.../sloa155.pdf

    I think you are missing the SPI Clock Polarity Change needed when changing from Reads to Writes as covered in Section 7.5 of that document.
  • Hello Ralph,

    Thanks for the answer, you have solved my problem. 

    By the oder hand, looking the recomende code, should I reseset the FIFO after write the iso control?

    Thanks,

    Joseba

  • Hi Joseba,

    Writing the ISO Control doesn't need a FIFO reset in and of itself. In general you should reset the FIFO prior to any FIFO operation. So when initializing the part, it should be cleared before the first transaction and then after every completed TX or RX it should be reset again.
  • according to the las question, whe I configure the ISO15693, I set the modulator and SYS_CLK control register (0x09) to 0x21.That means that the system output frequency should be 6.78MHz, because the bit B7 is set as 0. But when a I measure the signal, I measure 3,339Mhz and when I read the register with 0x49, TRF7960A answers with 0x21. do yoy know what could be happen?

    I let you the code tha I´m using, and the some images of the signals that I measured.

    main

    {

     uint8_t       write[4];

     uint8_t      command[2];

    uint8_t      iso_control=0x02;

    command[0] = CHIP_STATE_CONTROL;

    command[1] = CHIP_STATE_CONTROL;

    Trf796xReadSingle(&command[1], 1);

    command[1] &= 0x3F;

    command[1] |= 0x20;

    Trf796xWriteSingle(command, 2);

    //Escritura en registro 0x01

    write[0] = ISO_CONTROL;

    write[1] = iso_control;

    write[1] &= 0xDF; // BIT5 a 0 para establecer RFID MODE

    Trf796xWriteSingle(write, 2);

    iso_control &= 0x1F;

    //Escritura en registro 0x0D

    write[0] = IRQ_MASK;

    write[1] = 0x3E;

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x09

    // NOTA: elegir modulacion OOK/ASK  (0x21/0x20)

    write[0] = MODULATOR_CONTROL;

    write[1] = 0x21; // // OOK 100% 6.78 MHz

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x06

    write[0] = TX_PULSE_LENGTH_CONTROL;

    write[1] = 0x80; // 9.44 us

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x07

    write[0] = RX_NO_RESPONSE_WAIT_TIME;

    write[1] = 0x14; // 755 us

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x08

    write[0] = RX_WAIT_TIME;

    write[1] = 0x1F; // 293 us

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x0A

    write[0] = RX_SPECIAL_SETTINGS;

    write[1] = RX_SPECIAL_SETTINGS;

    Trf796xReadSingle(&write[1], 1);

    write[1] &= 0x0F;

    write[1] |= 0x40; // bandpass 200 kHz to 900 kHz

    Trf796xWriteSingle(write, 2);

    //Escritura en registro 0x10

    write[0] = SPECIAL_FUNCTION;

    write[1] = SPECIAL_FUNCTION;

    Trf796xReadSingle(&write[1], 1);

    write[1] |= 0xEF; // BIT 4 a 0-> Establece el TIME GRID

    Trf796xWriteSingle(write, 2);

    for(;;) //This infinite loop is to read the register 0x09 on the oscilloscope

    {

    write[0] = MODULATOR_CONTROL;

         Trf796xReadSingle(write, 1);

    }

    }

    That is all the code that I use. Only with this code, the TRF7960A should detect tags, no¿?

    Thanks,  and sorry for doing so many questions.

    Joseba