Skip to main content
Graduate
July 17, 2024
Solved

Code for two or more ST25R3911

  • July 17, 2024
  • 3 replies
  • 1369 views

I would like to operate two or more ST25R3911 on one microcontroller (STM32F401). Which adaptations of the code from the example are necessary to accomplish this?

Is there anyone who has managed this or who could give me some tips ?
I am grateful for any help as I am still a beginner in the subject !

 

Thanks and best regards
Thomas

    This topic has been closed for replies.
    Best answer by Brian TIDAL

    Hi,

    See: https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/how-to-control-two-st25r3916-chips-with-rfal-api-using-spi/td-p/140888

    The rfal_platform.h can be tweaked to handle dynamically the CS and INT pins:

     

    #define ST25R_SS_PIN ((globalReaderInstance == PLF_INST_ST25R3916_1) ? SPI1_CS_Pin : SPI2_CS_Pin) /*!< GPIO pin used for ST25R SPI SS */
    #define ST25R_SS_PORT ((globalReaderInstance == PLF_INST_ST25R3916_1) ? SPI1_CS_GPIO_Port : SPI2_CS_GPIO_Port) /*!< GPIO port used for ST25R SPI SS port */
     
    #define ST25R_INT_PIN ((globalReaderInstance == PLF_INST_ST25R3916_1) ? IRQ_3916_Pin : IRQ_3916_2_Pin) /*!< GPIO pin used for ST25R External Interrupt */
    #define ST25R_INT_PORT ((globalReaderInstance == PLF_INST_ST25R3916_1) ? IRQ_3916_GPIO_Port : IRQ_3916_2_GPIO_Port) /*!< GPIO port used for ST25R External Interrupt */
    

     

    Then you can add a function like the following one to select a given reader instance (code to be adapted)

     

    /*******************************************************************************/
    ReturnCode demoSetReaderInstance(readerInstance instance)
    {
     ReturnCode err = RFAL_ERR_NONE;
     
     state = DEMO_ST_NOTINIT;
    
     rfalDeinitialize();
     
     globalReaderInstance = instance;
     platformLog("[%d] ST25R reader instance: %d\r\n", platformGetSysTick(), globalReaderInstance);
    
     spiInit((instance == PLF_INST_ST25R3916_1) ? &hspi1 : &hspi2 );
     err = rfalNfcInitialize();
     if(err == RFAL_ERR_NONE )
     {
     /* Check for valid configuration by calling Discover once */
     err = rfalNfcDiscover( &discParam );;
     if( err == RFAL_ERR_NONE )
     {
     state = DEMO_ST_START_DISCOVERY;
     }
     else
     {
     platformLog("rfalNfcDiscover: invalid param\r\n");
     }
     }
     else
     {
     platformLog("rfalNfcInitialize returns %d\r\n", err);
     }
     return err;
    }

     

    Then in your main cycle you can move from reader1 to reader2 once the state machine  has returned to RFAL_NFC_STATE_START_DISCOVERY.

    Rgds

    BT

     

    3 replies

    Super User
    July 17, 2024

    It's a standard 4-wire SPI interface. Use a different pin for each CS pin and switch between them when you want to talk to the other chip. You can use as many modules on one board as you want.

    Chip select - Wikipedia

    fishpokeAuthor
    Graduate
    July 17, 2024

    Hi TDK,
    thanks for your answer! I have used SPI many times and have wired the boards exactly as you described.

    However, my problem is not the hardware but the software. I don't understand how to create two separate instances of the NFC code. If you have any helpful tips I would be very grateful!

    regards
    Thomas

     

    Super User
    July 17, 2024

    Perhaps link to the code and examples you're talking about.

    Technical Moderator
    July 18, 2024

    Hi,

    See: https://community.st.com/t5/st25-nfc-rfid-tags-and-readers/how-to-control-two-st25r3916-chips-with-rfal-api-using-spi/td-p/140888

    The rfal_platform.h can be tweaked to handle dynamically the CS and INT pins:

     

    #define ST25R_SS_PIN ((globalReaderInstance == PLF_INST_ST25R3916_1) ? SPI1_CS_Pin : SPI2_CS_Pin) /*!< GPIO pin used for ST25R SPI SS */
    #define ST25R_SS_PORT ((globalReaderInstance == PLF_INST_ST25R3916_1) ? SPI1_CS_GPIO_Port : SPI2_CS_GPIO_Port) /*!< GPIO port used for ST25R SPI SS port */
     
    #define ST25R_INT_PIN ((globalReaderInstance == PLF_INST_ST25R3916_1) ? IRQ_3916_Pin : IRQ_3916_2_Pin) /*!< GPIO pin used for ST25R External Interrupt */
    #define ST25R_INT_PORT ((globalReaderInstance == PLF_INST_ST25R3916_1) ? IRQ_3916_GPIO_Port : IRQ_3916_2_GPIO_Port) /*!< GPIO port used for ST25R External Interrupt */
    

     

    Then you can add a function like the following one to select a given reader instance (code to be adapted)

     

    /*******************************************************************************/
    ReturnCode demoSetReaderInstance(readerInstance instance)
    {
     ReturnCode err = RFAL_ERR_NONE;
     
     state = DEMO_ST_NOTINIT;
    
     rfalDeinitialize();
     
     globalReaderInstance = instance;
     platformLog("[%d] ST25R reader instance: %d\r\n", platformGetSysTick(), globalReaderInstance);
    
     spiInit((instance == PLF_INST_ST25R3916_1) ? &hspi1 : &hspi2 );
     err = rfalNfcInitialize();
     if(err == RFAL_ERR_NONE )
     {
     /* Check for valid configuration by calling Discover once */
     err = rfalNfcDiscover( &discParam );;
     if( err == RFAL_ERR_NONE )
     {
     state = DEMO_ST_START_DISCOVERY;
     }
     else
     {
     platformLog("rfalNfcDiscover: invalid param\r\n");
     }
     }
     else
     {
     platformLog("rfalNfcInitialize returns %d\r\n", err);
     }
     return err;
    }

     

    Then in your main cycle you can move from reader1 to reader2 once the state machine  has returned to RFAL_NFC_STATE_START_DISCOVERY.

    Rgds

    BT

     

    fishpokeAuthor
    Graduate
    July 19, 2024

    Hi  Brian,
    many thanks for the tips!

    I will try to implement this and then present the results. However, my skills in relation to this technology are very limited. So it may take a little while.

    regards,
    Thomas

    Graduate II
    July 18, 2024

    You put everything in the instance structure or object, and avoid globals and defines.

    How much refactoring it takes depends on the overall amount of forethought that went into the given library or implementation as to how to scale it. The more rigid and naive the original implementation the harder it will be to scale. Start at the pin/peripheral layer.

    fishpokeAuthor
    Graduate
    July 19, 2024

    Hi Tesla DeLorean,

    thank you also for your tips!
    Could you explain this in a little more detail ?

    regards,
    Thomas