2024-07-17 08:44 AM
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
Solved! Go to Solution.
2024-07-18 02:39 AM - edited 2024-07-18 02:40 AM
Hi,
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
2024-07-17 09:42 AM
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.
2024-07-17 12:18 PM
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
2024-07-17 04:21 PM
Perhaps link to the code and examples you're talking about.
2024-07-18 02:39 AM - edited 2024-07-18 02:40 AM
Hi,
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
2024-07-18 02:55 AM
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.
2024-07-19 02:48 AM
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
2024-07-19 02:50 AM
Hi Tesla DeLorean,
thank you also for your tips!
Could you explain this in a little more detail ?
regards,
Thomas