2024-03-14 06:44 PM
Hello,
I am working on a version of the STM32L476RG_NUCLEO_AP2P_PROP_NFC8 demo included with the RFAL library examples, trying to get it going on a NUCLEO-F072RB.
I have my code running, and if I bring an L476RG flashed with the unmodified AP2P demo, the boards will transact, but the F0 board is always the initiator. Previously, when using two L476RG boards and the original demo, they would change which was the initiator and target depending on the timing they were brought in proximity.
I've been debugging thoroughly, but I can't quite narrow down what my issue could be. rfalNfcWorker() seems to be setting gNfc.state to the correct states: RFAL_NFC_STATE_POLL_TECHDETECT, RFAL_NFC_STATE_LISTEN_TECHDETECT, etc. I've noticed when stepping through, though, that it never leaves RFAL_NFC_STATE_POLL_TECHDETECT, but if I set a breakpoint at the different cases in rfalNfcWorker() it will cycle through them during discovery.
My big issue: when I program two F0 boards with my modified version, I cannot get them to detect each other. It is almost like they are only looking for a listen target and never leave that state.
The way I cobbled this together is by starting a new project using the X-NFC-6 middleware, got pins and peripherals configured, then ported over the demoIni(), demoCycle(), etc, functions over right into main.c (just for the first steps in getting a working demo). I've attached it, if this is helpful.
Any pointers on where to look? I've spent hours stepping through both my F0 version and the original AP2P demo for the L476RG, and I can't seem to see a different during run time.
Solved! Go to Solution.
2024-04-02 12:18 AM
See X-CUBE-NFC6 Polling Demo on NUCLEO-L476 can't detect AP2P techs
2024-03-15 05:07 AM
Hi dwagner4,
I would go and investigate by first setting ST25R_SELFTEST to verify the timer and interrupt handling are indeed correct. If all good then in a next step I would attach a logic analyzer and compare the polling and timing (without a peer) to see differences to the STM32L4 based implementation: Interrupt line should be high only for very short times (few us). Compare the timing between interrupt pulses.
BR, Ulysses
2024-03-15 09:10 AM - edited 2024-03-15 09:11 AM
Thank you, I enabled both ST25R_SELFTEST and ST25R_SELFTEST_TIMER.
ST25R_SELFTEST_TIMER throws a RFAL_ERR_SYSTEM at this block:
#ifdef ST25R_SELFTEST_TIMER
/******************************************************************************
* Check SW timer operation :
* - use the General Purpose timer to measure an amount of time
* - test whether an interrupt is seen when less time was given
* - test whether an interrupt is seen when sufficient time was given
*/
st25r3916EnableInterrupts( ST25R3916_IRQ_MASK_GPE );
st25r3916SetStartGPTimer( (uint16_t)ST25R3916_TEST_TMR_TOUT_8FC, ST25R3916_REG_TIMER_EMV_CONTROL_gptc_no_trigger);
if( st25r3916WaitForInterruptsTimed( ST25R3916_IRQ_MASK_GPE, (ST25R3916_TEST_TMR_TOUT - ST25R3916_TEST_TMR_TOUT_DELTA)) != 0U )
{
platformErrorHandle();
return RFAL_ERR_SYSTEM;
}
Stepping into st25r3916WaitForInterruptsTimed(), the do block only iterates once, and returns status = 0x2000 instead of 0x0:
uint32_t st25r3916WaitForInterruptsTimed( uint32_t mask, uint16_t tmo )
{
uint32_t tmrDelay;
uint32_t status;
tmrDelay = platformTimerCreate( tmo );
/* Run until specific interrupt has happen or the timer has expired */
do
{
status = (st25r3916interrupt.status & mask);
} while( ( (!platformTimerIsExpired( tmrDelay )) || (tmo == 0U)) && (status == 0U) );
platformTimerDestroy( tmrDelay );
status = st25r3916interrupt.status & mask;
platformProtectST25RIrqStatus();
st25r3916interrupt.status &= ~status;
platformUnprotectST25RIrqStatus();
return status;
}
So something with the interrupt?
If I step back in the timer selftest and follow st25r3916EnableInterrupts(), it leads to st25r3916ModifyInterrupts(), which ultimately is supposed to write to a register using st25r3916WriteRegister(), but the internal if-statement in the for loop always evaluates true and nothing is ever written to the interrupt register:
void st25r3916ModifyInterrupts(uint32_t clr_mask, uint32_t set_mask)
{
uint8_t i;
uint32_t old_mask;
uint32_t new_mask;
old_mask = st25r3916interrupt.mask;
new_mask = ((~old_mask & set_mask) | (old_mask & clr_mask));
st25r3916interrupt.mask &= ~clr_mask;
st25r3916interrupt.mask |= set_mask;
for(i=0; i<ST25R3916_INT_REGS_LEN; i++)
{
if( ((new_mask >> (8U*i)) & 0xFFU) == 0U )
{
continue;
}
st25r3916WriteRegister(ST25R3916_REG_IRQ_MASK_MAIN + i, (uint8_t)((st25r3916interrupt.mask>>(8U*i)) & 0xFFU) );
}
return;
}
So I think there is some issue in enabling the interrupt? I'm going to go back to the AP2P demo code running on the L476 to see what the difference is there (since it obviously passes the timer selftest). I definitely have PA0 set as EXTI0, and NVIC set up for EXTI0 as well, on the F0 board. I'll update soon.
2024-03-15 02:12 PM
I decided to take a step back and just create a freshly generated project using the NFC08A1 PollingTagDetect demo flashed onto two F072RB boards. In the default state, they detect each other polling for the different technologies just fine.
When I modify rfal_defConfig.h and rfal_features.h to turn off certain technologies and flash one of the boards, though, I can't get AP2P transaction to happen.
rfal_defConfig.h:
******************************************************************************
* RFAL FEATURES CONFIGURATION
******************************************************************************
*/
#define RFAL_FEATURE_LISTEN_MODE true /*!< Enable/Disable RFAL support for Listen Mode */
#define RFAL_FEATURE_WAKEUP_MODE true /*!< Enable/Disable RFAL support for the Wake-Up mode */
#define RFAL_FEATURE_LOWPOWER_MODE false /*!< Enable/Disable RFAL support for the Low Power mode */
#define RFAL_FEATURE_NFCA false /*!< Enable/Disable RFAL support for NFC-A (ISO14443A) */
#define RFAL_FEATURE_NFCB false /*!< Enable/Disable RFAL support for NFC-B (ISO14443B) */
#define RFAL_FEATURE_NFCF true /*!< Enable/Disable RFAL support for NFC-F (FeliCa) */
#define RFAL_FEATURE_NFCV true /*!< Enable/Disable RFAL support for NFC-V (ISO15693) */
#define RFAL_FEATURE_T1T false /*!< Enable/Disable RFAL support for T1T (Topaz) */
#define RFAL_FEATURE_T2T false /*!< Enable/Disable RFAL support for T2T */
#define RFAL_FEATURE_T4T false /*!< Enable/Disable RFAL support for T4T */
#define RFAL_FEATURE_ST25TB false /*!< Enable/Disable RFAL support for ST25TB */
#define RFAL_FEATURE_ST25xV false /*!< Enable/Disable RFAL support for ST25TV/ST25DV */
#define RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG false /*!< Enable/Disable Analog Configs to be dynamically updated (RAM) */
#define RFAL_FEATURE_DPO false /*!< Enable/Disable RFAL Dynamic Power Output support */
#define RFAL_FEATURE_ISO_DEP true /*!< Enable/Disable RFAL support for ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_ISO_DEP_POLL true /*!< Enable/Disable RFAL support for Poller mode (PCD) ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_ISO_DEP_LISTEN true /*!< Enable/Disable RFAL support for Listen mode (PICC) ISO-DEP (ISO14443-4) */
#define RFAL_FEATURE_NFC_DEP true /*!< Enable/Disable RFAL support for NFC-DEP (NFCIP1/P2P) */
#define RFAL_FEATURE_ISO_DEP_IBLOCK_MAX_LEN 256U /*!< ISO-DEP I-Block max length. Please use values as defined by rfalIsoDepFSx */
#define RFAL_FEATURE_NFC_DEP_BLOCK_MAX_LEN 254U /*!< NFC-DEP Block/Payload length. Allowed values: 64, 128, 192, 254 */
#define RFAL_FEATURE_NFC_RF_BUF_LEN 258U /*!< RF buffer length used by RFAL NFC layer */
#define RFAL_FEATURE_ISO_DEP_APDU_MAX_LEN 512U /*!< ISO-DEP APDU max length. Please use multiples of I-Block max length */
#define RFAL_FEATURE_NFC_DEP_PDU_MAX_LEN 512U /*!< NFC-DEP PDU max length.
rfal_features.h:
/*
******************************************************************************
* GLOBAL DEFINES
******************************************************************************
*/
#define RFAL_SUPPORT_MODE_POLL_NFCA false /*!< RFAL Poll NFCA mode support switch */
#define RFAL_SUPPORT_MODE_POLL_NFCB false /*!< RFAL Poll NFCB mode support switch */
#define RFAL_SUPPORT_MODE_POLL_NFCF true /*!< RFAL Poll NFCF mode support switch */
#define RFAL_SUPPORT_MODE_POLL_NFCV true /*!< RFAL Poll NFCV mode support switch */
#define RFAL_SUPPORT_MODE_POLL_ACTIVE_P2P true /*!< RFAL Poll AP2P mode support switch */
#define RFAL_SUPPORT_MODE_LISTEN_NFCA false /*!< RFAL Listen NFCA mode support switch */
#define RFAL_SUPPORT_MODE_LISTEN_NFCB false /*!< RFAL Listen NFCB mode support switch */
#define RFAL_SUPPORT_MODE_LISTEN_NFCF true /*!< RFAL Listen NFCF mode support switch */
#define RFAL_SUPPORT_MODE_LISTEN_ACTIVE_P2P true /*!< RFAL Listen AP2P mode support switch */
It is still very strange. The project example with the RFAL download (AP2P_PROP for L476RG board) will work with the F0 board.
2024-04-02 12:18 AM
See X-CUBE-NFC6 Polling Demo on NUCLEO-L476 can't detect AP2P techs