#include "f_hal_nfc_i.h"
#include <furi_hal_interrupt.h>
#include <stm32wbxx_ll_tim.h>
#include <furi_hal_resources.h>
#include <furi_hal_gpio.h>
#include <furi_hal_bus.h>
#define F_HAL_NFC_FREQ_KHZ (13560U)
typedef enum {
FHalNfcTimerFwt,
FHalNfcTimerBlockTx,
FHalNfcTimerCount,
} FHalNfcTimer;
typedef struct {
TIM_TypeDef* timer;
FuriHalBus bus;
uint32_t prescaler;
uint32_t freq_khz;
FHalNfcEventInternalType event;
FuriHalInterruptId irq_id;
IRQn_Type irq_type;
bool is_configured;
const GpioPin* pin;
} FHalNfcTimerConfig;
static FHalNfcTimerConfig f_hal_nfc_timers[FHalNfcTimerCount] = {
[FHalNfcTimerFwt] =
{
.pin = &gpio_ext_pa7,
.timer = TIM1,
.bus = FuriHalBusTIM1,
.prescaler = 15,
.freq_khz = 4000U,
.event = FHalNfcEventInternalTypeTimerFwtExpired,
.irq_id = FuriHalInterruptIdTim1UpTim16,
.irq_type = TIM1_UP_TIM16_IRQn,
.is_configured = false,
},
[FHalNfcTimerBlockTx] =
{
.pin = &gpio_ext_pa6,
.timer = TIM2,
.bus = FuriHalBusTIM2,
.prescaler = 0,
.freq_khz = 64000U,
.event = FHalNfcEventInternalTypeTimerBlockTxExpired,
.irq_id = FuriHalInterruptIdTIM2,
.irq_type = TIM2_IRQn,
.is_configured = false,
},
};
static void f_hal_nfc_timer_irq_callback(void* context) {
FHalNfcTimerConfig* timer = context;
if(LL_TIM_IsActiveFlag_UPDATE(timer->timer)) {
LL_TIM_ClearFlag_UPDATE(timer->timer);
f_hal_nfc_set_event(timer->event);
furi_hal_gpio_write(timer->pin, false);
}
}
static void f_hal_nfc_timer_init(FHalNfcTimer timer) {
furi_hal_bus_enable(f_hal_nfc_timers[timer].bus);
LL_TIM_EnableUpdateEvent(f_hal_nfc_timers[timer].timer);
LL_TIM_SetOnePulseMode(f_hal_nfc_timers[timer].timer, LL_TIM_ONEPULSEMODE_SINGLE);
LL_TIM_SetCounterMode(f_hal_nfc_timers[timer].timer, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetPrescaler(f_hal_nfc_timers[timer].timer, f_hal_nfc_timers[timer].prescaler);
LL_TIM_SetClockSource(f_hal_nfc_timers[timer].timer, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_EnableIT_UPDATE(f_hal_nfc_timers[timer].timer);
furi_hal_interrupt_set_isr(
f_hal_nfc_timers[timer].irq_id, f_hal_nfc_timer_irq_callback, &f_hal_nfc_timers[timer]);
NVIC_SetPriority(
f_hal_nfc_timers[timer].irq_type, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(f_hal_nfc_timers[timer].irq_type);
f_hal_nfc_timers[timer].is_configured = true;
furi_hal_gpio_init(
f_hal_nfc_timers[timer].pin, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
furi_hal_gpio_write(f_hal_nfc_timers[timer].pin, false);
}
static void f_hal_nfc_timer_deinit(FHalNfcTimer timer) {
furi_hal_interrupt_set_isr(f_hal_nfc_timers[timer].irq_id, NULL, NULL);
NVIC_DisableIRQ(f_hal_nfc_timers[timer].irq_type);
f_hal_nfc_timers[timer].is_configured = false;
if(furi_hal_bus_is_enabled(f_hal_nfc_timers[timer].bus)) {
furi_hal_bus_disable(f_hal_nfc_timers[timer].bus);
}
}
static void f_hal_nfc_timer_start(FHalNfcTimer timer, uint32_t time_fc) {
uint32_t arr_reg = f_hal_nfc_timers[timer].freq_khz * time_fc / F_HAL_NFC_FREQ_KHZ;
LL_TIM_SetAutoReload(f_hal_nfc_timers[timer].timer, arr_reg);
LL_TIM_EnableCounter(f_hal_nfc_timers[timer].timer);
furi_hal_gpio_write(f_hal_nfc_timers[timer].pin, true);
}
static void f_hal_nfc_timer_stop(FHalNfcTimer timer) {
LL_TIM_DisableCounter(f_hal_nfc_timers[timer].timer);
LL_TIM_SetCounter(f_hal_nfc_timers[timer].timer, 0);
LL_TIM_SetAutoReload(f_hal_nfc_timers[timer].timer, 0);
if(LL_TIM_IsActiveFlag_UPDATE(f_hal_nfc_timers[timer].timer)) {
LL_TIM_ClearFlag_UPDATE(f_hal_nfc_timers[timer].timer);
}
furi_hal_gpio_write(f_hal_nfc_timers[timer].pin, false);
}
void f_hal_nfc_timers_init() {
for(size_t i = 0; i < FHalNfcTimerCount; i++) {
f_hal_nfc_timer_init(i);
}
}
void f_hal_nfc_timers_deinit() {
for(size_t i = 0; i < FHalNfcTimerCount; i++) {
f_hal_nfc_timer_deinit(i);
}
}
void f_hal_nfc_timer_fwt_start(uint32_t time_fc) {
furi_assert(f_hal_nfc_timers[FHalNfcTimerFwt].is_configured);
f_hal_nfc_timer_start(FHalNfcTimerFwt, time_fc);
}
void f_hal_nfc_timer_fwt_stop() {
furi_assert(f_hal_nfc_timers[FHalNfcTimerFwt].is_configured);
f_hal_nfc_timer_stop(FHalNfcTimerFwt);
}
void f_hal_nfc_timer_block_tx_start(uint32_t time_fc) {
furi_assert(f_hal_nfc_timers[FHalNfcTimerBlockTx].is_configured);
f_hal_nfc_timer_start(FHalNfcTimerBlockTx, time_fc);
}
void f_hal_nfc_timer_block_tx_start_us(uint32_t time_us) {
furi_assert(f_hal_nfc_timers[FHalNfcTimerBlockTx].is_configured);
uint32_t arr_reg = f_hal_nfc_timers[FHalNfcTimerBlockTx].freq_khz / 1000 * time_us;
LL_TIM_SetAutoReload(f_hal_nfc_timers[FHalNfcTimerBlockTx].timer, arr_reg);
LL_TIM_EnableCounter(f_hal_nfc_timers[FHalNfcTimerBlockTx].timer);
furi_hal_gpio_write(f_hal_nfc_timers[FHalNfcTimerBlockTx].pin, true);
}
void f_hal_nfc_timer_block_tx_stop() {
furi_assert(f_hal_nfc_timers[FHalNfcTimerBlockTx].is_configured);
f_hal_nfc_timer_stop(FHalNfcTimerBlockTx);
}
bool f_hal_nfc_timer_block_tx_is_running() {
return LL_TIM_IsEnabledCounter(f_hal_nfc_timers[FHalNfcTimerBlockTx].timer) == 1;
}
↑ V1051 Consider checking for misprints. It's possible that the 'timer' should be used inside 'LL_TIM_IsActiveFlag_UPDATE' function.