Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3613] NFC response delay timer #3115

Merged
merged 4 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion firmware/targets/f7/furi_hal/furi_hal_nfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#define TAG "FuriHalNfc"

static const FuriHalNfcTechBase* furi_hal_nfc_tech[FuriHalNfcTechNum] = {
const FuriHalNfcTechBase* furi_hal_nfc_tech[FuriHalNfcTechNum] = {
[FuriHalNfcTechIso14443a] = &furi_hal_nfc_iso14443a,
[FuriHalNfcTechIso14443b] = &furi_hal_nfc_iso14443b,
[FuriHalNfcTechIso15693] = &furi_hal_nfc_iso15693,
Expand Down
7 changes: 6 additions & 1 deletion firmware/targets/f7/furi_hal/furi_hal_nfc_felica.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,17 @@ static FuriHalNfcError furi_hal_nfc_felica_poller_deinit(FuriHalSpiBusHandle* ha
const FuriHalNfcTechBase furi_hal_nfc_felica = {
.poller =
{
.compensation =
{
.fdt = FURI_HAL_NFC_POLLER_FDT_COMP_FC,
.fwt = FURI_HAL_NFC_POLLER_FWT_COMP_FC,
},
.init = furi_hal_nfc_felica_poller_init,
.deinit = furi_hal_nfc_felica_poller_deinit,
.wait_event = furi_hal_nfc_wait_event_common,
.tx = furi_hal_nfc_poller_tx_common,
.rx = furi_hal_nfc_common_fifo_rx,
},

.listener = {0},
.listener = {},
};
98 changes: 59 additions & 39 deletions firmware/targets/f7/furi_hal/furi_hal_nfc_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
#include <furi.h>
#include <furi_hal_nfc.h>
#include <furi_hal_spi.h>

#include <drivers/st25r3916.h>
#include <drivers/st25r3916_reg.h>

#ifdef __cplusplus
extern "C" {
#endif

#define FURI_HAL_NFC_POLLER_FDT_COMP_FC (-500)
#define FURI_HAL_NFC_POLLER_FWT_COMP_FC (FURI_HAL_NFC_POLLER_FDT_COMP_FC)

typedef enum {
FuriHalNfcEventInternalTypeAbort = (1U << 0),
FuriHalNfcEventInternalTypeIrq = (1U << 1),
Expand All @@ -35,45 +39,6 @@ typedef struct {
FuriHalNfcTech tech;
} FuriHalNfc;

extern FuriHalNfc furi_hal_nfc;

void furi_hal_nfc_event_init();

void furi_hal_nfc_event_set(FuriHalNfcEventInternalType event);

void furi_hal_nfc_init_gpio_isr();

void furi_hal_nfc_deinit_gpio_isr();

void furi_hal_nfc_timers_init();

void furi_hal_nfc_timers_deinit();

uint32_t furi_hal_nfc_get_irq(FuriHalSpiBusHandle* handle);

bool furi_hal_nfc_event_wait_for_specific_irq(
FuriHalSpiBusHandle* handle,
uint32_t mask,
uint32_t timeout_ms);

// Common technology methods
FuriHalNfcEvent furi_hal_nfc_wait_event_common(uint32_t timeout_ms);
FuriHalNfcError furi_hal_nfc_common_listener_rx_start(FuriHalSpiBusHandle* handle);
FuriHalNfcError furi_hal_nfc_common_fifo_tx(
FuriHalSpiBusHandle* handle,
const uint8_t* tx_data,
size_t tx_bits);
FuriHalNfcError furi_hal_nfc_common_fifo_rx(
FuriHalSpiBusHandle* handle,
uint8_t* rx_data,
size_t rx_data_size,
size_t* rx_bits);

FuriHalNfcError furi_hal_nfc_poller_tx_common(
FuriHalSpiBusHandle* handle,
const uint8_t* tx_data,
size_t tx_bits);

// Technology specific API
typedef FuriHalNfcError (*FuriHalNfcChipConfig)(FuriHalSpiBusHandle* handle);
typedef FuriHalNfcError (
Expand All @@ -88,6 +53,12 @@ typedef FuriHalNfcError (*FuriHalNfcSleep)(FuriHalSpiBusHandle* handle);
typedef FuriHalNfcError (*FuriHalNfcIdle)(FuriHalSpiBusHandle* handle);

typedef struct {
int32_t fdt;
int32_t fwt;
} FuriHalNfcPollerCompensation;

typedef struct {
FuriHalNfcPollerCompensation compensation;
FuriHalNfcChipConfig init;
FuriHalNfcChipConfig deinit;
FuriHalNfcWaitEvent wait_event;
Expand All @@ -96,6 +67,11 @@ typedef struct {
} FuriHalNfcTechPollerBase;

typedef struct {
int32_t fdt;
} FuriHalNfcListenerCompensation;

typedef struct {
FuriHalNfcListenerCompensation compensation;
FuriHalNfcChipConfig init;
FuriHalNfcChipConfig deinit;
FuriHalNfcWaitEvent wait_event;
Expand All @@ -115,6 +91,50 @@ extern const FuriHalNfcTechBase furi_hal_nfc_iso14443b;
extern const FuriHalNfcTechBase furi_hal_nfc_iso15693;
extern const FuriHalNfcTechBase furi_hal_nfc_felica;

extern const FuriHalNfcTechBase* furi_hal_nfc_tech[];

extern FuriHalNfc furi_hal_nfc;

void furi_hal_nfc_event_init();

void furi_hal_nfc_event_set(FuriHalNfcEventInternalType event);

void furi_hal_nfc_init_gpio_isr();

void furi_hal_nfc_deinit_gpio_isr();

void furi_hal_nfc_timers_init();

void furi_hal_nfc_timers_deinit();

uint32_t furi_hal_nfc_get_irq(FuriHalSpiBusHandle* handle);

bool furi_hal_nfc_event_wait_for_specific_irq(
FuriHalSpiBusHandle* handle,
uint32_t mask,
uint32_t timeout_ms);

// Common technology methods
FuriHalNfcEvent furi_hal_nfc_wait_event_common(uint32_t timeout_ms);

FuriHalNfcError furi_hal_nfc_common_listener_rx_start(FuriHalSpiBusHandle* handle);

FuriHalNfcError furi_hal_nfc_common_fifo_tx(
FuriHalSpiBusHandle* handle,
const uint8_t* tx_data,
size_t tx_bits);

FuriHalNfcError furi_hal_nfc_common_fifo_rx(
FuriHalSpiBusHandle* handle,
uint8_t* rx_data,
size_t rx_data_size,
size_t* rx_bits);

FuriHalNfcError furi_hal_nfc_poller_tx_common(
FuriHalSpiBusHandle* handle,
const uint8_t* tx_data,
size_t tx_bits);

#ifdef __cplusplus
}
#endif
12 changes: 12 additions & 0 deletions firmware/targets/f7/furi_hal/furi_hal_nfc_iso14443a.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

#define TAG "FuriHalIso14443a"

// Prevent FDT timer from starting
#define FURI_HAL_NFC_ISO14443A_LISTENER_FDT_COMP_FC (INT32_MAX)

static Iso14443_3aSignal* iso14443_3a_signal = NULL;

static FuriHalNfcError furi_hal_nfc_iso14443a_common_init(FuriHalSpiBusHandle* handle) {
Expand Down Expand Up @@ -326,6 +329,11 @@ FuriHalNfcError furi_hal_nfc_iso14443_3a_listener_idle(FuriHalSpiBusHandle* hand
const FuriHalNfcTechBase furi_hal_nfc_iso14443a = {
.poller =
{
.compensation =
{
.fdt = FURI_HAL_NFC_POLLER_FDT_COMP_FC,
.fwt = FURI_HAL_NFC_POLLER_FWT_COMP_FC,
},
.init = furi_hal_nfc_iso14443a_poller_init,
.deinit = furi_hal_nfc_iso14443a_poller_deinit,
.wait_event = furi_hal_nfc_wait_event_common,
Expand All @@ -335,6 +343,10 @@ const FuriHalNfcTechBase furi_hal_nfc_iso14443a = {

.listener =
{
.compensation =
{
.fdt = FURI_HAL_NFC_ISO14443A_LISTENER_FDT_COMP_FC,
},
.init = furi_hal_nfc_iso14443a_listener_init,
.deinit = furi_hal_nfc_iso14443a_listener_deinit,
.wait_event = furi_hal_nfc_iso14443_3a_listener_wait_event,
Expand Down
7 changes: 6 additions & 1 deletion firmware/targets/f7/furi_hal/furi_hal_nfc_iso14443b.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,17 @@ static FuriHalNfcError furi_hal_nfc_iso14443b_poller_deinit(FuriHalSpiBusHandle*
const FuriHalNfcTechBase furi_hal_nfc_iso14443b = {
.poller =
{
.compensation =
{
.fdt = FURI_HAL_NFC_POLLER_FDT_COMP_FC,
.fwt = FURI_HAL_NFC_POLLER_FWT_COMP_FC,
},
.init = furi_hal_nfc_iso14443b_poller_init,
.deinit = furi_hal_nfc_iso14443b_poller_deinit,
.wait_event = furi_hal_nfc_wait_event_common,
.tx = furi_hal_nfc_poller_tx_common,
.rx = furi_hal_nfc_common_fifo_rx,
},

.listener = {0},
.listener = {},
};
12 changes: 12 additions & 0 deletions firmware/targets/f7/furi_hal/furi_hal_nfc_iso15693.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
#define FURI_HAL_NFC_ISO15693_RESP_PATTERN_0 (0x01U)
#define FURI_HAL_NFC_ISO15693_RESP_PATTERN_1 (0x02U)

// Derived experimentally
#define FURI_HAL_NFC_ISO15693_LISTENER_FDT_COMP_FC (2735)

#define BITS_IN_BYTE (8U)

#define TAG "FuriHalIso15693"
Expand Down Expand Up @@ -419,6 +422,11 @@ FuriHalNfcError furi_hal_nfc_iso15693_listener_sleep(FuriHalSpiBusHandle* handle
const FuriHalNfcTechBase furi_hal_nfc_iso15693 = {
.poller =
{
.compensation =
{
.fdt = FURI_HAL_NFC_POLLER_FDT_COMP_FC,
.fwt = FURI_HAL_NFC_POLLER_FWT_COMP_FC,
},
.init = furi_hal_nfc_iso15693_poller_init,
.deinit = furi_hal_nfc_iso15693_poller_deinit,
.wait_event = furi_hal_nfc_wait_event_common,
Expand All @@ -428,6 +436,10 @@ const FuriHalNfcTechBase furi_hal_nfc_iso15693 = {

.listener =
{
.compensation =
{
.fdt = FURI_HAL_NFC_ISO15693_LISTENER_FDT_COMP_FC,
},
.init = furi_hal_nfc_iso15693_listener_init,
.deinit = furi_hal_nfc_iso15693_listener_deinit,
.wait_event = furi_hal_nfc_iso15693_wait_event,
Expand Down
51 changes: 48 additions & 3 deletions firmware/targets/f7/furi_hal/furi_hal_nfc_timer.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
#include "furi_hal_nfc_i.h"

#include <furi_hal_interrupt.h>
#include <stm32wbxx_ll_tim.h>

#include <furi_hal_interrupt.h>
#include <furi_hal_resources.h>
#include <furi_hal_gpio.h>
#include <furi_hal_bus.h>

#define FURI_HAL_NFC_FREQ_KHZ (13560U)

/**
* To enable timer debug output on GPIO, define the FURI_HAL_NFC_TIMER_DEBUG macro
* Example: ./fbt --extra-define=FURI_HAL_NFC_TIMER_DEBUG
*/

typedef enum {
FuriHalNfcTimerFwt,
FuriHalNfcTimerBlockTx,
Expand All @@ -23,13 +28,17 @@ typedef struct {
FuriHalInterruptId irq_id;
IRQn_Type irq_type;
bool is_configured;
#ifdef FURI_HAL_NFC_TIMER_DEBUG
const GpioPin* pin;
#endif
} FuriHalNfcTimerConfig;

static FuriHalNfcTimerConfig furi_hal_nfc_timers[FuriHalNfcTimerCount] = {
[FuriHalNfcTimerFwt] =
{
#ifdef FURI_HAL_NFC_TIMER_DEBUG
.pin = &gpio_ext_pa7,
#endif
.timer = TIM1,
.bus = FuriHalBusTIM1,
.prescaler = 15,
Expand All @@ -41,7 +50,9 @@ static FuriHalNfcTimerConfig furi_hal_nfc_timers[FuriHalNfcTimerCount] = {
},
[FuriHalNfcTimerBlockTx] =
{
#ifdef FURI_HAL_NFC_TIMER_DEBUG
.pin = &gpio_ext_pa6,
#endif
.timer = TIM17,
.bus = FuriHalBusTIM17,
.prescaler = 31,
Expand All @@ -58,7 +69,9 @@ static void furi_hal_nfc_timer_irq_callback(void* context) {
if(LL_TIM_IsActiveFlag_UPDATE(timer_config->timer)) {
LL_TIM_ClearFlag_UPDATE(timer_config->timer);
furi_hal_nfc_event_set(timer_config->event);
#ifdef FURI_HAL_NFC_TIMER_DEBUG
furi_hal_gpio_write(timer_config->pin, false);
#endif
}
}

Expand All @@ -84,9 +97,11 @@ static void furi_hal_nfc_timer_init(FuriHalNfcTimer timer) {
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(furi_hal_nfc_timers[timer].irq_type);
furi_hal_nfc_timers[timer].is_configured = true;
#ifdef FURI_HAL_NFC_TIMER_DEBUG
furi_hal_gpio_init(
furi_hal_nfc_timers[timer].pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
furi_hal_gpio_write(furi_hal_nfc_timers[timer].pin, false);
#endif
}

static void furi_hal_nfc_timer_deinit(FuriHalNfcTimer timer) {
Expand All @@ -100,13 +115,39 @@ static void furi_hal_nfc_timer_deinit(FuriHalNfcTimer timer) {
}
}

static int32_t furi_hal_nfc_timer_get_compensation(FuriHalNfcTimer timer) {
const FuriHalNfcTechBase* current_tech = furi_hal_nfc_tech[furi_hal_nfc.tech];

if(furi_hal_nfc.mode == FuriHalNfcModePoller) {
const FuriHalNfcPollerCompensation* comp = &current_tech->poller.compensation;
if(timer == FuriHalNfcTimerFwt)
return comp->fwt;
else if(timer == FuriHalNfcTimerBlockTx)
return comp->fdt;

} else if(furi_hal_nfc.mode == FuriHalNfcModeListener) {
const FuriHalNfcListenerCompensation* comp = &current_tech->listener.compensation;
if(timer == FuriHalNfcTimerBlockTx) return comp->fdt;
}

return 0;
}

static void furi_hal_nfc_timer_start(FuriHalNfcTimer timer, uint32_t time_fc) {
uint32_t arr_reg = furi_hal_nfc_timers[timer].freq_khz * time_fc / FURI_HAL_NFC_FREQ_KHZ;
const int32_t comp_fc = furi_hal_nfc_timer_get_compensation(timer);

// Not starting the timer if the compensation value is greater than the requested delay
if(comp_fc >= (int32_t)time_fc) return;

const uint32_t arr_reg =
furi_hal_nfc_timers[timer].freq_khz * (time_fc - comp_fc) / FURI_HAL_NFC_FREQ_KHZ;
furi_check(arr_reg < UINT16_MAX);

LL_TIM_SetAutoReload(furi_hal_nfc_timers[timer].timer, arr_reg);
LL_TIM_EnableCounter(furi_hal_nfc_timers[timer].timer);
#ifdef FURI_HAL_NFC_TIMER_DEBUG
furi_hal_gpio_write(furi_hal_nfc_timers[timer].pin, true);
#endif
}

static void furi_hal_nfc_timer_stop(FuriHalNfcTimer timer) {
Expand All @@ -116,7 +157,9 @@ static void furi_hal_nfc_timer_stop(FuriHalNfcTimer timer) {
if(LL_TIM_IsActiveFlag_UPDATE(furi_hal_nfc_timers[timer].timer)) {
LL_TIM_ClearFlag_UPDATE(furi_hal_nfc_timers[timer].timer);
}
#ifdef FURI_HAL_NFC_TIMER_DEBUG
furi_hal_gpio_write(furi_hal_nfc_timers[timer].pin, false);
#endif
}

void furi_hal_nfc_timers_init() {
Expand Down Expand Up @@ -157,7 +200,9 @@ void furi_hal_nfc_timer_block_tx_start_us(uint32_t time_us) {

LL_TIM_SetAutoReload(furi_hal_nfc_timers[FuriHalNfcTimerBlockTx].timer, arr_reg);
LL_TIM_EnableCounter(furi_hal_nfc_timers[FuriHalNfcTimerBlockTx].timer);
#ifdef FURI_HAL_NFC_TIMER_DEBUG
furi_hal_gpio_write(furi_hal_nfc_timers[FuriHalNfcTimerBlockTx].pin, true);
#endif
}

void furi_hal_nfc_timer_block_tx_stop() {
Expand Down
1 change: 0 additions & 1 deletion firmware/targets/furi_hal_include/furi_hal_nfc.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
extern "C" {
#endif

#define FURI_HAL_NFC_TIMER_COMPENSATION_FC (500)
#define FURI_HAL_NFC_EVENT_WAIT_FOREVER (0xFFFFFFFFU)

typedef enum {
Expand Down
Loading