mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Add option for NFC Field Generator
I've integrated the option for the NFC Field Generator into Python CLI and application files. TODO: GUI integration.
This commit is contained in:
@@ -488,6 +488,35 @@ static data_frame_tx_t *cmd_processor_mf1_write_one_block(uint16_t cmd, uint16_t
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
|
||||
static data_frame_tx_t *cmd_processor_hf14a_set_field_on(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
device_mode_t mode = get_device_mode();
|
||||
if (mode != DEVICE_MODE_READER) {
|
||||
return data_frame_make(cmd, STATUS_DEVICE_MODE_ERROR, 0, NULL);
|
||||
}
|
||||
|
||||
// Reset and turn on the antenna
|
||||
pcd_14a_reader_reset();
|
||||
pcd_14a_reader_antenna_on();
|
||||
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
static data_frame_tx_t *cmd_processor_hf14a_set_field_off(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
device_mode_t mode = get_device_mode();
|
||||
if (mode != DEVICE_MODE_READER) {
|
||||
return data_frame_make(cmd, STATUS_DEVICE_MODE_ERROR, 0, NULL);
|
||||
}
|
||||
|
||||
// Turn off the antenna
|
||||
pcd_14a_reader_antenna_off();
|
||||
|
||||
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static data_frame_tx_t *cmd_processor_hf14a_raw(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
// Response Buffer
|
||||
uint8_t resp[DEF_FIFO_LENGTH] = { 0x00 };
|
||||
@@ -1578,6 +1607,9 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_VIKING_SCAN, before_reader_run, cmd_processor_viking_scan, NULL },
|
||||
{ DATA_CMD_VIKING_WRITE_TO_T55XX, before_reader_run, cmd_processor_viking_write_to_t55xx, NULL },
|
||||
|
||||
{ DATA_CMD_HF14A_SET_FIELD_ON, before_reader_run, cmd_processor_hf14a_set_field_on, NULL },
|
||||
{ DATA_CMD_HF14A_SET_FIELD_OFF, before_reader_run, cmd_processor_hf14a_set_field_off, NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ DATA_CMD_HF14A_GET_ANTI_COLL_DATA, NULL, cmd_processor_hf14a_get_anti_coll_data, NULL },
|
||||
|
||||
@@ -41,6 +41,10 @@ NRF_LOG_MODULE_REGISTER();
|
||||
#include "tag_persistence.h"
|
||||
#include "settings.h"
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
#include "rc522.h"
|
||||
#endif
|
||||
|
||||
// Defining soft timers
|
||||
APP_TIMER_DEF(m_button_check_timer); // Timer for button debounce
|
||||
|
||||
@@ -56,6 +60,9 @@ static bool m_is_a_btn_release = false;
|
||||
|
||||
static bool m_system_off_processing = false;
|
||||
|
||||
// NFC field generator state
|
||||
volatile bool m_is_field_on = false;
|
||||
|
||||
// cpu reset reason
|
||||
static uint32_t m_reset_source;
|
||||
static uint32_t m_gpregret_val;
|
||||
@@ -139,6 +146,35 @@ static void gpio_te_init(void) {
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
static void field_generator_rainbow_loop(void) {
|
||||
static uint8_t color_index = 0;
|
||||
static uint32_t last_update = 0;
|
||||
|
||||
if (!m_is_field_on) return;
|
||||
|
||||
uint32_t now = app_timer_cnt_get();
|
||||
|
||||
if (app_timer_cnt_diff_compute(now, last_update) < APP_TIMER_TICKS(100)) {
|
||||
return;
|
||||
}
|
||||
last_update = now;
|
||||
|
||||
// Rainbow colors
|
||||
const uint8_t colors[] = {RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_CYAN, RGB_BLUE, RGB_MAGENTA};
|
||||
|
||||
set_slot_light_color(colors[color_index]);
|
||||
uint32_t *led_pins = hw_get_led_array();
|
||||
|
||||
// Light up all LEDs with current color
|
||||
for (int i = 0; i < RGB_LIST_NUM; i++) {
|
||||
nrf_gpio_pin_set(led_pins[i]);
|
||||
}
|
||||
|
||||
color_index = (color_index + 1) % 6;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**@brief Button Matrix Events
|
||||
*/
|
||||
static void button_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||
@@ -162,7 +198,9 @@ static void timer_button_event_handle(void *arg) {
|
||||
NRF_LOG_INFO("BUTTON press during shutdown");
|
||||
return;
|
||||
}
|
||||
|
||||
nrf_drv_gpiote_pin_t pin = *(nrf_drv_gpiote_pin_t *)arg;
|
||||
|
||||
// Check here if the current GPIO is at the pressed level
|
||||
if (nrf_gpio_pin_read(pin) == 1) {
|
||||
if (pin == BUTTON_1) {
|
||||
@@ -757,13 +795,67 @@ static void run_button_function_by_settings(settings_button_function_t sbf) {
|
||||
case SettingsButtonCloneIcUid:
|
||||
btn_fn_copy_ic_uid();
|
||||
break;
|
||||
case SettingsButtonNfcFieldGenerator:
|
||||
if (!m_is_field_on) {
|
||||
// Initialize reader hardware if not already in reader mode
|
||||
device_mode_t current_mode = get_device_mode();
|
||||
if (current_mode != DEVICE_MODE_READER) {
|
||||
// Temporarily init reader hardware just for the field
|
||||
nrf_gpio_cfg_output(READER_POWER);
|
||||
nrf_gpio_pin_set(READER_POWER); // reader power enable
|
||||
nrf_gpio_cfg_output(HF_ANT_SEL);
|
||||
nrf_gpio_pin_clear(HF_ANT_SEL); // hf ant switch to reader mode
|
||||
|
||||
pcd_14a_reader_init();
|
||||
bsp_delay_ms(10);
|
||||
}
|
||||
|
||||
pcd_14a_reader_reset();
|
||||
pcd_14a_reader_antenna_on();
|
||||
m_is_field_on = true;
|
||||
NRF_LOG_INFO("NFC field ON");
|
||||
|
||||
// Set initial rainbow state
|
||||
set_slot_light_color(RGB_RED);
|
||||
uint32_t *led_pins = hw_get_led_array();
|
||||
for (int i = 0; i < RGB_LIST_NUM; i++) {
|
||||
nrf_gpio_pin_set(led_pins[i]);
|
||||
}
|
||||
|
||||
// Stop sleep timer while field is active
|
||||
NRF_LOG_INFO("Stopping sleep timer for field generator");
|
||||
sleep_timer_stop();
|
||||
NRF_LOG_INFO("Sleep timer stopped");
|
||||
} else {
|
||||
pcd_14a_reader_antenna_off();
|
||||
m_is_field_on = false;
|
||||
NRF_LOG_INFO("NFC field OFF");
|
||||
|
||||
// If we're not in reader mode, clean up the hardware
|
||||
device_mode_t current_mode = get_device_mode();
|
||||
if (current_mode != DEVICE_MODE_READER) {
|
||||
pcd_14a_reader_uninit();
|
||||
nrf_gpio_pin_clear(READER_POWER); // reader power disable
|
||||
nrf_gpio_pin_set(HF_ANT_SEL); // hf ant switch back to tag mode
|
||||
}
|
||||
|
||||
// Restore normal LED
|
||||
light_up_by_slot();
|
||||
|
||||
// Restart sleep timer
|
||||
NRF_LOG_INFO("Field off, restarting sleep timer");
|
||||
sleep_timer_start(SLEEP_DELAY_MS_BUTTON_CLICK);
|
||||
NRF_LOG_INFO("Sleep timer restarted");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case SettingsButtonShowBattery:
|
||||
show_battery();
|
||||
break;
|
||||
|
||||
default:
|
||||
NRF_LOG_ERROR("Unsupported button function")
|
||||
NRF_LOG_ERROR("Unsupported button function");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -792,8 +884,10 @@ static void button_press_process(void) {
|
||||
}
|
||||
// Disable led marquee for usb at button pressed.
|
||||
g_usb_led_marquee_enable = false;
|
||||
// Re-delay into hibernation
|
||||
sleep_timer_start(SLEEP_DELAY_MS_BUTTON_CLICK);
|
||||
// Re-delay into hibernation (unless field is on)
|
||||
if (!m_is_field_on) {
|
||||
sleep_timer_start(SLEEP_DELAY_MS_BUTTON_CLICK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,8 +981,17 @@ int main(void) {
|
||||
lesc_event_process();
|
||||
// Button event process
|
||||
button_press_process();
|
||||
// Led blink at usb status
|
||||
blink_usb_led_status();
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
// Field generator rainbow animation
|
||||
field_generator_rainbow_loop();
|
||||
#endif
|
||||
|
||||
// Led blink at usb status (only if field generator is off)
|
||||
if (!m_is_field_on) {
|
||||
blink_usb_led_status();
|
||||
}
|
||||
|
||||
// Data pack process
|
||||
data_frame_process();
|
||||
// Log print process
|
||||
@@ -902,4 +1005,4 @@ int main(void) {
|
||||
// Some task process done, we can enter cpu sleep state.
|
||||
sleep_system_run(system_off_enter, nrf_pwr_mgmt_run);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,6 +73,9 @@
|
||||
#define DATA_CMD_MF1_ENC_NESTED_ACQUIRE (2014)
|
||||
#define DATA_CMD_MF1_CHECK_KEYS_ON_BLOCK (2015)
|
||||
|
||||
#define DATA_CMD_HF14A_SET_FIELD_ON (2100)
|
||||
#define DATA_CMD_HF14A_SET_FIELD_OFF (2101)
|
||||
|
||||
//
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
#include "rfid_main.h"
|
||||
#include "rgb_marquee.h"
|
||||
|
||||
|
||||
|
||||
//The current mode of the device
|
||||
device_mode_t rfid_state = DEVICE_MODE_NONE;
|
||||
|
||||
// External declaration for field state
|
||||
extern bool m_is_field_on;
|
||||
|
||||
/**
|
||||
* @brief Function for enter tag reader mode
|
||||
@@ -42,6 +42,12 @@ void tag_mode_enter(void) {
|
||||
rfid_state = DEVICE_MODE_TAG;
|
||||
|
||||
#if defined(PROJECT_CHAMELEON_ULTRA)
|
||||
// Safety check: turn off field if it's on
|
||||
if (m_is_field_on) {
|
||||
pcd_14a_reader_antenna_off();
|
||||
m_is_field_on = false;
|
||||
}
|
||||
|
||||
// uninit reader
|
||||
lf_125khz_radio_uninit();
|
||||
pcd_14a_reader_uninit();
|
||||
@@ -116,4 +122,4 @@ uint8_t get_color_by_slot(uint8_t slot) {
|
||||
} else { // Low -frequency emulation, return B
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ typedef enum {
|
||||
// Read the UID card number immediately after pressing, continue searching, and simulate immediately after reading the card
|
||||
SettingsButtonCloneIcUid = 3U,
|
||||
SettingsButtonShowBattery = 4U,
|
||||
// Toggle NFC field generator on/off (Ultra only, must be in reader mode)
|
||||
SettingsButtonNfcFieldGenerator = 5U,
|
||||
} settings_button_function_t;
|
||||
|
||||
typedef struct ALIGN_U32 {
|
||||
@@ -74,4 +76,4 @@ void settings_set_ble_connect_key(uint8_t *key);
|
||||
void settings_set_ble_pairing_enable(bool enable);
|
||||
bool settings_get_ble_pairing_enable(void);
|
||||
bool settings_get_ble_pairing_enable_first_load(void);
|
||||
#endif
|
||||
#endif
|
||||
@@ -12,6 +12,7 @@ static volatile bool m_system_off_enter = false;
|
||||
|
||||
extern bool g_is_ble_connected; //Link to log in BLE
|
||||
extern bool g_is_tag_emulating; //The status of the logo emulation card
|
||||
extern volatile bool m_is_field_on; //NFC field generator state from app_main.c
|
||||
|
||||
|
||||
/** @brief Equipment sleep timer event
|
||||
@@ -48,8 +49,8 @@ void sleep_timer_start(uint32_t time_ms) {
|
||||
sleep_timer_stop();
|
||||
// Non -USB power supply status
|
||||
if (nrfx_power_usbstatus_get() == NRFX_POWER_USB_STATE_DISCONNECTED) {
|
||||
// If Bluetooth is still connected, or is still in the state of emulation card, you don't need to start sleep
|
||||
if (g_is_ble_connected == false && g_is_tag_emulating == false) {
|
||||
// If Bluetooth is still connected, or is still in the state of emulation card, or field generator is on, you don't need to start sleep
|
||||
if (g_is_ble_connected == false && g_is_tag_emulating == false && m_is_field_on == false) {
|
||||
// Start the timer
|
||||
ret_code_t err_code = app_timer_start(m_app_sleep_timer, APP_TIMER_TICKS(time_ms), NULL);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
@@ -72,4 +73,4 @@ void sleep_system_run(void (*sysOffSleep)(), void (*sysOnSleep)()) {
|
||||
// If no task can to process, we can sleep cpu sometime.
|
||||
sysOnSleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -533,6 +533,7 @@ class ButtonPressFunction(enum.IntEnum):
|
||||
PREVSLOT = 2
|
||||
CLONE = 3
|
||||
BATTERY = 4
|
||||
FIELDGEN = 5
|
||||
|
||||
def __str__(self):
|
||||
if self == ButtonPressFunction.NONE:
|
||||
@@ -545,9 +546,10 @@ class ButtonPressFunction(enum.IntEnum):
|
||||
return "Read then simulate the ID/UID card number"
|
||||
elif self == ButtonPressFunction.BATTERY:
|
||||
return "Show Battery Level"
|
||||
elif self == ButtonPressFunction.FIELDGEN:
|
||||
return "Toggle NFC Field Generator"
|
||||
return "None"
|
||||
|
||||
|
||||
@enum.unique
|
||||
class MfcValueBlockOperator(enum.IntEnum):
|
||||
DECREMENT = 0xC0
|
||||
|
||||
Reference in New Issue
Block a user