Skip to content

Commit 50ed2dc

Browse files
authored
Merge pull request #270 from Maxime0506/nfc-fast-polling-option
feat(nfc): add configurable fast polling options
2 parents 8cc5496 + 675819c commit 50ed2dc

10 files changed

Lines changed: 49 additions & 7 deletions

File tree

data/src/lib/components/AppMisc.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@
376376
ethSpiConfig={miscConfig.ethSpiConfig}
377377
ethConfig={ethConfig}
378378
nfcConnected={nfcConnected}
379+
nfcFastPollingEnabled={miscConfig.nfcFastPollingEnabled}
379380
onNfcPresetChange={handleNfcPresetChange}
380381
onEthPresetChange={handleEthPresetChange}
381382
onNfcPinsChange={(pins) => miscConfig.nfcGpioPins = pins}

data/src/lib/components/HardwareConfig.svelte

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ethConfig: EthConfig | null;
1818
nfcConnected?: boolean;
1919
loading?: boolean;
20+
nfcFastPollingEnabled: boolean;
2021
onNfcPresetChange: (preset: number) => void;
2122
onEthPresetChange: (preset: number) => void;
2223
onNfcPinsChange: (pins: [number, number, number, number]) => void;
@@ -38,6 +39,7 @@
3839
ethRmiiConfig,
3940
ethSpiConfig,
4041
ethConfig,
42+
nfcFastPollingEnabled,
4143
nfcConnected = false,
4244
loading = false,
4345
onNfcPresetChange,
@@ -133,7 +135,7 @@
133135
<option value={255}>Custom</option>
134136
</select>
135137
</div>
136-
<div class="grid grid-cols-4 gap-2">
138+
<div class="grid grid-cols-4 gap-2 mb-2">
137139
<div class="form-control">
138140
<label class="label" for="nfcSsPin">
139141
<span class="label-text text-xs">SS Pin</span>
@@ -187,6 +189,17 @@
187189
/>
188190
</div>
189191
</div>
192+
<div class="flex items-center justify-between py-2 px-3 bg-base-200 rounded-lg">
193+
<div>
194+
<p class="text-sm font-medium">Fast NFC Polling</p>
195+
<p class="text-xs text-base-content/60">{"Reduces the delay (100ms -> 5ms) after each PN532 poll cycle for quicker follow-up detection."}</p>
196+
</div>
197+
<input
198+
type="checkbox"
199+
bind:checked={nfcFastPollingEnabled}
200+
class="toggle toggle-primary toggle-sm"
201+
/>
202+
</div>
190203
</div>
191204

192205
<!-- Ethernet Configuration -->

data/src/lib/types/api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ export interface MiscConfig {
133133
lockAlwaysLock: boolean;
134134
/** Enable HomeKey auth precompute cache (faster taps, higher CPU/RAM) */
135135
hkAuthPrecomputeEnabled: boolean;
136+
/** Poll the PN532 more aggressively for faster tag detection */
137+
nfcFastPollingEnabled: boolean;
136138
/** GPIO pin for lock control */
137139
controlPin: number;
138140
/** GPIO pin for HomeSpan status indicator */

docs/content/configuration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ This section is organized into several subsections: **HomeKit**, **HomeKey**, **
195195

196196
* **Performance:** Authentication optimizations.
197197
* **Auth Precompute Cache:** Enable or disable precomputation of authentication context.
198+
* **Fast NFC Polling:** Reduces the delay after each PN532 polling cycle for faster follow-up detection.
198199

199200
### 5.3. PN532
200201

main/ConfigManager.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ ConfigManager::ConfigManager() : m_isInitialized(false) {
8989
{"lockAlwaysUnlock", &m_miscConfig.lockAlwaysUnlock},
9090
{"lockAlwaysLock", &m_miscConfig.lockAlwaysLock},
9191
{"hkAuthPrecomputeEnabled", &m_miscConfig.hkAuthPrecomputeEnabled},
92+
{"nfcFastPollingEnabled", &m_miscConfig.nfcFastPollingEnabled},
9293
{"controlPin", &m_miscConfig.controlPin},
9394
{"hsStatusPin", &m_miscConfig.hsStatusPin},
9495
{"webAuthEnabled", &m_miscConfig.webAuthEnabled},

main/NfcManager.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,16 @@ void NfcManager::authPrecomputeTask() {
207207
* @param readerDataManager Reference to the ReaderDataManager used to read and persist reader data.
208208
* @param nfcGpioPins Four GPIO pin numbers used to construct the PN532 SPI interface.
209209
* @param hkAuthPrecomputeEnabled If true, enables HomeKit authentication precompute behavior.
210+
* @param nfcFastPollingEnabled If true, shortens the delay between polling iterations.
210211
*/
211-
NfcManager::NfcManager(ReaderDataManager& readerDataManager, const std::array<uint8_t, 4> &nfcGpioPins, bool hkAuthPrecomputeEnabled)
212+
NfcManager::NfcManager(ReaderDataManager& readerDataManager,
213+
const std::array<uint8_t, 4> &nfcGpioPins,
214+
bool hkAuthPrecomputeEnabled,
215+
bool nfcFastPollingEnabled)
212216
: nfcGpioPins(nfcGpioPins),
213217
m_readerDataManager(readerDataManager),
214218
m_hkAuthPrecomputeEnabled(hkAuthPrecomputeEnabled),
219+
m_nfcFastPollingEnabled(nfcFastPollingEnabled),
215220
m_pollingTaskHandle(nullptr),
216221
m_retryTaskHandle(nullptr),
217222
m_ecpData({ 0x6A, 0x2, 0xCB, 0x2, 0x6, 0x2, 0x11, 0x0 })
@@ -259,6 +264,7 @@ bool NfcManager::begin() {
259264
} else {
260265
ESP_LOGI(TAG, "Auth precompute disabled.");
261266
}
267+
ESP_LOGI(TAG, "NFC fast polling: %s", m_nfcFastPollingEnabled ? "enabled" : "disabled");
262268
ESP_LOGI(TAG, "Starting NFC polling task...");
263269
xTaskCreateUniversal(pollingTaskEntry, "nfc_poll_task", 8192, this, 2, &m_pollingTaskHandle, 1);
264270
return true;
@@ -385,6 +391,17 @@ void NfcManager::pollingTask() {
385391
vTaskSuspend(NULL);
386392
}
387393

394+
const uint16_t inCommunicateThruTimeoutMs = 50;
395+
const uint16_t passiveTargetTimeoutMs = 500;
396+
const TickType_t pollDelayTicks =
397+
pdMS_TO_TICKS(m_nfcFastPollingEnabled ? 5 : 100);
398+
399+
ESP_LOGI(TAG,
400+
"NFC poll tuning active: delay=%lu ms, thruTimeout=%u ms, passiveTimeout=%u ms",
401+
static_cast<unsigned long>(pollDelayTicks * portTICK_PERIOD_MS),
402+
static_cast<unsigned int>(inCommunicateThruTimeoutMs),
403+
static_cast<unsigned int>(passiveTargetTimeoutMs));
404+
388405
while (true) {
389406
if (m_nfc->WriteRegister({0x63,0x3d,0x0}) != pn532::SUCCESS) {
390407
ESP_LOGE(TAG, "PN532 is unresponsive. Attempting to reconnect...");
@@ -397,12 +414,12 @@ void NfcManager::pollingTask() {
397414
}
398415

399416
std::vector<uint8_t> res;
400-
m_nfc->InCommunicateThru(std::vector<uint8_t>(m_ecpData.begin(), m_ecpData.end()), res, 50);
417+
m_nfc->InCommunicateThru(std::vector<uint8_t>(m_ecpData.begin(), m_ecpData.end()), res, inCommunicateThruTimeoutMs);
401418

402419
std::vector<uint8_t> uid;
403420
std::array<uint8_t,2> sens_res;
404421
uint8_t sel_res;
405-
pn532::Status passiveTargetFound = m_nfc->InListPassiveTarget(PN532_MIFARE_ISO14443A, uid, sens_res, sel_res, 500);
422+
pn532::Status passiveTargetFound = m_nfc->InListPassiveTarget(PN532_MIFARE_ISO14443A, uid, sens_res, sel_res, passiveTargetTimeoutMs);
406423

407424
if (passiveTargetFound == pn532::SUCCESS) {
408425
ESP_LOGI(TAG, "NFC tag detected!");
@@ -416,7 +433,7 @@ void NfcManager::pollingTask() {
416433
m_nfc->setPassiveActivationRetries(0);
417434
}
418435

419-
vTaskDelay(pdMS_TO_TICKS(100));
436+
vTaskDelay(pollDelayTicks);
420437
taskYIELD();
421438
}
422439
}

main/include/NfcManager.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ namespace espConfig { struct misc_config_t; }
1919

2020
class NfcManager {
2121
public:
22-
NfcManager(ReaderDataManager& readerDataManager, const std::array<uint8_t, 4> &nfcGpioPins, bool hkAuthPrecomputeEnabled);
22+
NfcManager(ReaderDataManager& readerDataManager,
23+
const std::array<uint8_t, 4> &nfcGpioPins,
24+
bool hkAuthPrecomputeEnabled,
25+
bool nfcFastPollingEnabled);
2326
/**
2427
* @brief Unsubscribes the manager's HomeKey event subscription from the global EventBus.
2528
*
@@ -69,6 +72,7 @@ class NfcManager {
6972

7073
ReaderDataManager& m_readerDataManager;
7174
const bool m_hkAuthPrecomputeEnabled;
75+
const bool m_nfcFastPollingEnabled;
7276

7377
TaskHandle_t m_pollingTaskHandle;
7478
TaskHandle_t m_retryTaskHandle;

main/include/config.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ namespace espConfig
145145
bool lockAlwaysUnlock = HOMEKEY_ALWAYS_UNLOCK;
146146
bool lockAlwaysLock = HOMEKEY_ALWAYS_LOCK;
147147
bool hkAuthPrecomputeEnabled = HK_AUTH_PRECOMPUTE_ENABLED;
148+
bool nfcFastPollingEnabled = NFC_FAST_POLLING_ENABLED;
148149
uint8_t controlPin = HS_PIN;
149150
uint8_t hsStatusPin = HS_STATUS_LED;
150151
bool webAuthEnabled = WEB_AUTH_ENABLED;

main/include/defaults.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#define HOMEKEY_ALWAYS_UNLOCK 0 // Flag indicating if a successful Homekey authentication should always set and publish the unlock state
5656
#define HOMEKEY_ALWAYS_LOCK 0 // Flag indicating if a successful Homekey authentication should always set and publish the lock state
5757
#define HK_AUTH_PRECOMPUTE_ENABLED true // Enable HomeKey auth precompute cache (faster taps, higher CPU/RAM)
58+
#define NFC_FAST_POLLING_ENABLED false // Poll the PN532 more aggressively for faster tag detection
5859
#define HS_STATUS_LED 255 // HomeSpan Status LED GPIO pin
5960
#define HS_PIN 255 // GPIO Pin for a Configuration Mode button (more info on https://github.com/HomeSpan/HomeSpan/blob/master/docs/UserGuide.md#device-configuration-mode)
6061
#define BTR_PROX_BAT_ENABLED false // Enable or disable battery monitoring

main/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ void setup() {
161161
nfc_init:
162162
nfcManager = std::make_unique<NfcManager>(*readerDataManager,
163163
miscConfig.nfcPinsPreset == PIN_UNSET ? miscConfig.nfcGpioPins : nfcGpioPinsPresets[miscConfig.nfcPinsPreset].gpioPins,
164-
miscConfig.hkAuthPrecomputeEnabled);
164+
miscConfig.hkAuthPrecomputeEnabled,
165+
miscConfig.nfcFastPollingEnabled);
165166
nfcManager->begin();
166167
}
167168
webServerManager->setNfcManager(nfcManager.get());

0 commit comments

Comments
 (0)