From c63cc16bb5ab99550197093b046635032bbdb21b Mon Sep 17 00:00:00 2001 From: Niel Nielsen Date: Fri, 1 May 2026 17:50:32 +0200 Subject: [PATCH] Add files via upload --- .../src/rfid/nfctag/lf/lf_tag_em.c | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c b/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c index 2a83193..5c66d12 100644 --- a/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c +++ b/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c @@ -43,7 +43,7 @@ static void lf_field_lost(void) { g_is_tag_emulating = false; // Reset the flag in the emulation m_is_lf_emulating = false; TAG_FIELD_LED_OFF() // Make sure the indicator light of the LF field status - NRF_LPCOMP->INTENSET = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; + // LPCOMP stays enabled (DETECT_CROSS) — no INTENSET/INTENCLR needed. // call sleep_timer_start *after* unsetting g_is_tag_emulating sleep_timer_start(SLEEP_DELAY_MS_FIELD_125KHZ_LOST); // Start the timer to enter the sleep NRF_LOG_INFO("LF FIELD LOST"); @@ -68,35 +68,29 @@ bool is_lf_field_exists(void) { * priority is set to APP_IRQ_PRIORITY_HIGH). */ static void lpcomp_event_handler(nrf_lpcomp_event_t event) { - // Only when the lf -frequency emulation is not launched, and the analog card is started - if (m_is_lf_emulating || event != NRF_LPCOMP_EVENT_UP) { - return; + if (!m_is_lf_emulating && event == NRF_LPCOMP_EVENT_UP) { + // Field appeared — start continuous looping broadcast. + // LPCOMP stays enabled so the DOWN event stops us when field is lost. + sleep_timer_stop(); + m_is_lf_emulating = true; + g_is_tag_emulating = true; + g_usb_led_marquee_enable = false; + set_slot_light_color(RGB_BLUE); + TAG_FIELD_LED_ON() + nrfx_pwm_simple_playback(&m_broadcast, m_pwm_seq, 1, NRFX_PWM_FLAG_LOOP); + NRF_LOG_INFO("LF FIELD DETECTED"); + } else if (m_is_lf_emulating && event == NRF_LPCOMP_EVENT_DOWN) { + // Field dropped during emulation — stop PWM; pwm_handler will clean up. + nrfx_pwm_stop(&m_broadcast, false); + NRF_LOG_INFO("LF FIELD LOST (LPCOMP DOWN)"); } - - sleep_timer_stop(); // turn off dormant delay - nrfx_lpcomp_disable(); - - // set the emulation status logo bit - m_is_lf_emulating = true; - g_is_tag_emulating = true; - // turn off USB light effect when emulating cards - g_usb_led_marquee_enable = false; - - // LED status update - set_slot_light_color(RGB_BLUE); - TAG_FIELD_LED_ON() - - // use precise hardware timer to broadcast card id - nrfx_pwm_simple_playback(&m_broadcast, m_pwm_seq, LF_125KHZ_BROADCAST_MAX, NRFX_PWM_FLAG_STOP); - - NRF_LOG_INFO("LF FIELD DETECTED"); } static void lpcomp_init(void) { nrfx_lpcomp_config_t cfg = NRFX_LPCOMP_DEFAULT_CONFIG; cfg.input = LF_RSSI; cfg.hal.reference = NRF_LPCOMP_REF_SUPPLY_1_16; - cfg.hal.detection = NRF_LPCOMP_DETECT_UP; + cfg.hal.detection = NRF_LPCOMP_DETECT_CROSS; cfg.hal.hyst = NRF_LPCOMP_HYST_50mV; ret_code_t err_code = nrfx_lpcomp_init(&cfg, lpcomp_event_handler); @@ -104,21 +98,13 @@ static void lpcomp_init(void) { } static void pwm_handler(nrfx_pwm_evt_type_t event_type) { + // In LOOP mode this only fires when nrfx_pwm_stop() is called explicitly + // (triggered by LPCOMP DOWN event when field is lost). if (event_type != NRFX_PWM_EVT_STOPPED) { return; } - - // after last broadcast, force NO_MOD on antenna to measure field. ANT_NO_MOD(); - bsp_delay_ms(1); - // We don't need any events, but only need to detect the state of the field - NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; - if (is_lf_field_exists()) { - nrfx_lpcomp_disable(); - nrfx_pwm_simple_playback(&m_broadcast, m_pwm_seq, LF_125KHZ_BROADCAST_MAX, NRFX_PWM_FLAG_STOP); - } else { - lf_field_lost(); - } + lf_field_lost(); } static void pwm_init(void) {