cancel
Showing results for 
Search instead for 
Did you mean: 

Code for two or more ST25R3911

fishpoke
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
Brian TIDAL
ST Employee

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

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

7 REPLIES 7
TDK
Guru

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

If you feel a post has answered your question, please click "Accept as Solution".

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

 

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

If you feel a post has answered your question, please click "Accept as Solution".
Brian TIDAL
ST Employee

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

 

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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

Hi Tesla DeLorean,

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

regards,
Thomas