2021-09-06 08:27 AM
Hello all, my company has decided to use the STM32L03 series for a simple ISO 14443-3 tag reader, and we underestimated how much memory the full rfal takes up. Can anyone help me find an easier way to cut down the provided polling demo into 16k flash or less? I can scrap all other tag types except the T2T /nfc-a, and I only need read functionality. I am slowly working through and trimming the fat, but if there's a smarter way to limit program memory I'd be very thankful.
Solved! Go to Solution.
2021-09-06 10:14 AM
Hi Luke,
Can you share more information about your setup:
The RFAL code is scalable through the platform.h file. To remove useless features in your application, you just need to change the "RFAL FEATURES CONFIGURATION" in the platform.h. For example, if your application only needs to support NFC-A/T2T tags, the following features configuration can be used.
/*
*****************************************************
* RFAL FEATURES CONFIGURATION
*****************************************************
*/
#define RFAL_FEATURE_LISTEN_MODE false
#define RFAL_FEATURE_WAKEUP_MODE false
#define RFAL_FEATURE_LOWPOWER_MODE false
#define RFAL_FEATURE_NFCA true
#define RFAL_FEATURE_NFCB false
#define RFAL_FEATURE_NFCF false
#define RFAL_FEATURE_NFCV false
#define RFAL_FEATURE_T1T false
#define RFAL_FEATURE_T2T true
#define RFAL_FEATURE_T4T false
#define RFAL_FEATURE_ST25TB false
#define RFAL_FEATURE_ST25xV false
#define RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG false
#define RFAL_FEATURE_DPO false
#define RFAL_FEATURE_ISO_DEP false
#define RFAL_FEATURE_ISO_DEP_POLL false
#define RFAL_FEATURE_ISO_DEP_LISTEN false
#define RFAL_FEATURE_NFC_DEP false
Then, you can remove the USE_LOGGER define (printf on the serial console) and remove the UART.
Also, make sure to use the proper level of optimization in the compiler options (Optimize for size). See https://www.keil.com/appnotes/files/apnt202.pdf if using Keil µVision.
demo_polling.c file can also be modified to get rid of demoP2P, demoAPDU, demoNfcv, demoNfcf and demoCE and reduce the size of demo_polling.o.
You should then be close to the 16k flask size limit.
Once those suggestions are applied, feel free to share the map file of your application if you are still exceeding the 16k.
Rgds
BT
2021-09-06 10:14 AM
Hi Luke,
Can you share more information about your setup:
The RFAL code is scalable through the platform.h file. To remove useless features in your application, you just need to change the "RFAL FEATURES CONFIGURATION" in the platform.h. For example, if your application only needs to support NFC-A/T2T tags, the following features configuration can be used.
/*
*****************************************************
* RFAL FEATURES CONFIGURATION
*****************************************************
*/
#define RFAL_FEATURE_LISTEN_MODE false
#define RFAL_FEATURE_WAKEUP_MODE false
#define RFAL_FEATURE_LOWPOWER_MODE false
#define RFAL_FEATURE_NFCA true
#define RFAL_FEATURE_NFCB false
#define RFAL_FEATURE_NFCF false
#define RFAL_FEATURE_NFCV false
#define RFAL_FEATURE_T1T false
#define RFAL_FEATURE_T2T true
#define RFAL_FEATURE_T4T false
#define RFAL_FEATURE_ST25TB false
#define RFAL_FEATURE_ST25xV false
#define RFAL_FEATURE_DYNAMIC_ANALOG_CONFIG false
#define RFAL_FEATURE_DPO false
#define RFAL_FEATURE_ISO_DEP false
#define RFAL_FEATURE_ISO_DEP_POLL false
#define RFAL_FEATURE_ISO_DEP_LISTEN false
#define RFAL_FEATURE_NFC_DEP false
Then, you can remove the USE_LOGGER define (printf on the serial console) and remove the UART.
Also, make sure to use the proper level of optimization in the compiler options (Optimize for size). See https://www.keil.com/appnotes/files/apnt202.pdf if using Keil µVision.
demo_polling.c file can also be modified to get rid of demoP2P, demoAPDU, demoNfcv, demoNfcf and demoCE and reduce the size of demo_polling.o.
You should then be close to the 16k flask size limit.
Once those suggestions are applied, feel free to share the map file of your application if you are still exceeding the 16k.
Rgds
BT
2021-09-06 12:31 PM
Thank you for the reply. We are using the ST25R3911B driven by the STM32L031G6U7 (32k), and compiling through the standard CubeIDE gcc compiler. I have tried ripping out all the non required architecture out manually, and was able to get down to 16k, but wasn't getting tag interrupts (after the initialization ones) so I probably removed something important.
I'll try a new build and only setup the platform as you suggest, and yes I still need to modify polling heavily.
Ill send my mapping once I get that set up. Thanks
2021-09-06 01:02 PM
Hi Luke,
regarding the interrupt issue:
See stm32l0xx_it.c in STM32CubeExpansion_NFC5_V2.0.0\Projects\STM32L053R8-Nucleo\Applications\PollingTagDetect\Src from X-CUBE-NFC5 package for an example of interrupt configuration on STM32L053.
Rgds
BT
2021-09-06 02:14 PM
I was able to get it down to 37k with your suggested filtering and LDO optimization. Seems the lion share of this is in the nfcworker related functions and not the initialization. I still have the logger active as I will be using that anyway (and it only takes up about 2k). Below is the memory mapping down to 100B files:
FLASH 0x08000000 32 KB
.text 0x080000c0 0x080000c0 36.88 KB
HAL_RCC_OscConfig 0x08003720 0x08003720 1.74 KB
rfal_rfst25r3911.o 0x0800801c 0x0800801c 1.41 KB
UART_SetConfig 0x08004cd4 0x08004cd4 1.19 KB
rfalNfcaPollerSingleCollisionResolution 0x0800656c 0x0800656c 1.17 KB
demoCycle 0x080007d0 0x080007d0 1.03 KB
rfalSetBitRate 0x08007138 0x08007138 900 B
HAL_SPI_TransmitReceive 0x080045be 0x080045be 886 B
HAL_ADC_Init 0x080028b4 0x080028b4 744 B
HAL_GPIO_Init 0x080030f0 0x080030f0 732 B
rfal_rfst25r3911.o 0x08007d48 0x08007d48 724 B
HAL_RCC_ClockConfig 0x08003e18 0x08003e18 656 B
HAL_RCCEx_PeriphCLKConfig 0x08004260 0x08004260 588 B
rfalNfcaPollerFullCollisionResolution 0x08006a1c 0x08006a1c 576 B
rfalSetMode 0x08006ef8 0x08006ef8 576 B
rfal_nfc.o 0x08006180 0x08006180 568 B
rfalISO14443ATransceiveShortFrame 0x08008680 0x08008680 564 B
_printf_i 0x08008fd4 0x08008fd4 548 B
rfalISO14443ATransceiveAnticollisionFrame 0x080088b4 0x080088b4 544 B
rfalStartTransceive 0x08007680 0x08007680 516 B
_svfiprintf_r 0x08008cf4 0x08008cf4 512 B
_svfprintf_r 0x08008cf4 0x08008cf4 512 B
rfalNfcWorker 0x08005af8 0x08005af8 508 B
rfalNfcDiscover 0x08005810 0x08005810 440 B
rfalSetAnalogConfig 0x08005540 0x08005540 424 B
__udivmoddi4 0x080002d4 0x080002d4 408 B
UART_WaitOnFlagUntilTimeout 0x08005390 0x08005390 392 B
UART_AdvFeatureConfig 0x08005198 0x08005198 360 B
rfal_nfc.o 0x0800601c 0x0800601c 356 B
HAL_DMA_IRQHandler 0x08002f94 0x08002f94 348 B
rfal_nfc.o 0x08005ec0 0x08005ec0 348 B
HAL_UART_Transmit 0x08004b84 0x08004b84 336 B
HAL_RCC_GetSysClockFreq 0x080040a8 0x080040a8 332 B
rfal_rfst25r3911.o 0x08007c04 0x08007c04 324 B
rfalNfcaPollerSelect 0x08006c5c 0x08006c5c 320 B
MX_GPIO_Init 0x08000fa4 0x08000fa4 300 B
HAL_I2C_Init 0x080034c4 0x080034c4 300 B
st25r3911PerformCollisionAvoidance 0x08001e2c 0x08001e2c 294 B
rfalNfcDataExchangeStart 0x08005cf4 0x08005cf4 292 B
MX_ADC_Init 0x080004c0 0x080004c0 288 B
demo.o 0x08000dec 0x08000dec 284 B
stm32l0xx_hal_spi.o 0x08004934 0x08004934 284 B
rfal_rfst25r3911.o 0x08007abc 0x08007abc 284 B
HAL_SPI_Init 0x080044ac 0x080044ac 274 B
hex2Str 0x08001300 0x08001300 272 B
__aeabi_uidiv 0x0800012c 0x0800012c 268 B
__udivsi3 0x0800012c 0x0800012c 268 B
HAL_ADC_ConfigChannel 0x08002b9c 0x08002b9c 268 B
demo.o 0x08000cf0 0x08000cf0 252 B
HAL_DMA_Init 0x08002ea4 0x08002ea4 240 B
SystemClock_Config 0x080014c0 0x080014c0 236 B
rfal_analogConfig.o 0x080056e8 0x080056e8 236 B
_printf_common 0x08008ef4 0x08008ef4 222 B
stm32l0xx_hal_cortex.o 0x08002d1c 0x08002d1c 220 B
HAL_ADC_MspInit 0x080005e0 0x080005e0 216 B
HAL_I2C_MspInit 0x08001150 0x08001150 208 B
rfalFieldOnAndStartGT 0x08007588 0x08007588 204 B
__ssputs_r 0x08008c30 0x08008c30 196 B
_malloc_r 0x080092c8 0x080092c8 188 B
st25r3911AdjustRegulators 0x08001a64 0x08001a64 184 B
HAL_SPI_MspInit 0x08001628 0x08001628 180 B
rfalInitialize 0x08006dd4 0x08006dd4 180 B
main 0x08001410 0x08001410 176 B
HAL_UART_Init 0x08004adc 0x08004adc 168 B
rfalNfcDataExchangeGetStatus 0x08005e18 0x08005e18 168 B
st25r3911SetBitrate 0x08001b38 0x08001b38 166 B
demoIni 0x0800072c 0x0800072c 164 B
st25r3911ModifyInterrupts 0x080025a4 0x080025a4 160 B
st25r3911SetNoResponseTime_64fcs 0x08001d94 0x08001d94 152 B
HAL_I2CEx_ConfigAnalogFilter 0x080035f0 0x080035f0 152 B
HAL_I2CEx_ConfigDigitalFilter 0x08003688 0x08003688 152 B
_free_r 0x08009234 0x08009234 148 B
UART_CheckIdleState 0x08005300 0x08005300 144 B
stm32l0xx_hal_spi.o 0x08004a50 0x08004a50 140 B
demo.o 0x08000c00 0x08000c00 136 B
HAL_UART_MspInit 0x080018b8 0x080018b8 136 B
rfalTransceiveBlockingTx 0x080078cc 0x080078cc 130 B
rfalTransceiveBlockingTxRx 0x080079ba 0x080079ba 130 B
MX_I2C1_Init 0x080010d0 0x080010d0 128 B
st25r3911.o 0x08001f7c 0x08001f7c 120 B
st25r3911ChangeTestRegisterBits 0x08002384 0x08002384 118 B
demo.o 0x080006b8 0x080006b8 116 B
spiTxRx 0x080016dc 0x080016dc 116 B
MX_SPI1_Init 0x080015b8 0x080015b8 112 B
st25r3911ReadMultipleRegisters 0x0800209a 0x0800209a 112 B
st25r3911ModifyRegister 0x08002314 0x08002314 112 B
st25r3911WaitForInterruptsTimed 0x08002644 0x08002644 112 B
rfalNfcaPollerCheckPresence 0x080064a8 0x080064a8 112 B
rfalCalibrate 0x08006e88 0x08006e88 112 B
st25r3911ExecuteCommand 0x080024ba 0x080024ba 110 B
_sbrk 0x080017e0 0x080017e0 108 B
st25r3911ReadTestRegister 0x0800210a 0x0800210a 106 B
demo.o 0x08000c88 0x08000c88 104 B
st25r3911Initialize 0x080019fc 0x080019fc 104 B
st25r3911MeasureVoltage 0x08001c12 0x08001c12 104 B
HAL_InitTick 0x080027cc 0x080027cc 104 B
st25r3911WriteRegister 0x080021ce 0x080021ce 102 B
logUsartTx 0x0800123c 0x0800123c 100 B
2021-09-06 02:28 PM
IRQ is set up correctly, i was getting the original interrupts that get sent out during initialization, just not when in discovery mode (can't sense tags). Could be a hardware problem but i doubt it. I can activate the IRQ by applying a voltage directly.
2021-09-06 02:38 PM
Hi,
ST25R3911B sends interrupts during initialization. For example when oscillator frequency is stable, I_osc is raised (see st25r3911OscOn()).
Can you share more details about your HW setup: do you use a custom board or a X-NUCLEO-NFC05A1 plugged onto a NUCLEO-L031K6?
Rgds
BT
2021-09-06 02:43 PM
It's a custom board, but the schematic and layout of the RFID portion are almost identical to the X-NUCLEO-NFC05A1 expander (just without the capacitive sensor). It's worth noting that the initialization and rf calibration all pass, and i'm able to communicate with the R3911 fine. The current draw does seem low though if it is truly searching for passive tags. I would assume 100mA or so and it is in discovery mode at 16mA. I did order dev kits of the hardware to verify it's FW and not HW, but they will take a while.
2021-09-06 04:02 PM
Thank you for your continued support Brian. I had my compiler on Optimize Most (-O3) instead of for size (-Os). With that I was able to drop down to 27.7kB which is enough for testing the RFID at least. I'm sure I can scrounge around for the other 5k i'll need to add my other code back in.
Thanks!