diff --git a/firmware/application/Makefile b/firmware/application/Makefile index c115fd81..d0836cae 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -345,6 +345,7 @@ ifeq (${CURRENT_DEVICE_TYPE}, ${CHAMELEON_ULTRA}) $(PROJ_DIR)/rfid/reader/lf/lf_t55xx_data.c \ $(PROJ_DIR)/rfid/reader/lf/lf_hidprox_data.c \ $(PROJ_DIR)/rfid/reader/lf/lf_viking_data.c \ + $(PROJ_DIR)/rfid/reader/lf/lf_reader_generic.c \ INC_FOLDERS +=\ ${PROJ_DIR}/rfid/reader/ \ diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index a48b27e0..3e9e45dc 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -703,6 +703,32 @@ static data_frame_tx_t *cmd_processor_viking_write_to_t55xx(uint16_t cmd, uint16 status = write_viking_to_t55xx(payload->id, payload->new_key, payload->old_keys, (length - offsetof(payload_t, old_keys)) / sizeof(payload->old_keys)); return data_frame_make(cmd, status, 0, NULL); } + +#define GENERIC_READ_LEN 800 +#define GENERIC_READ_TIMEOUT_MS 500 +static data_frame_tx_t *cmd_processor_generic_read(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + uint8_t *outdata = malloc(GENERIC_READ_LEN); + + if (outdata == NULL) { + return data_frame_make(cmd, STATUS_MEM_ERR, 0, NULL); + } + + size_t outlen = 0; + if (!raw_read_to_buffer(outdata, GENERIC_READ_LEN, GENERIC_READ_TIMEOUT_MS, &outlen)) { + free(outdata); + return data_frame_make(cmd, STATUS_CMD_ERR, 0, NULL); + }; + data_frame_tx_t *frame = data_frame_make(cmd, STATUS_LF_TAG_OK, outlen, outdata); + + free(outdata); + + if (frame == NULL) { + return data_frame_make(cmd, STATUS_CREATE_RESPONSE_ERR, 0, NULL); + } + + return frame; +} + #endif @@ -1606,6 +1632,7 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_HIDPROX_WRITE_TO_T55XX, before_reader_run, cmd_processor_hidprox_write_to_t55xx, NULL }, { 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_ADC_GENERIC_READ, before_reader_run, cmd_processor_generic_read, 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 }, diff --git a/firmware/application/src/app_status.h b/firmware/application/src/app_status.h index 26d7bf21..653336dc 100644 --- a/firmware/application/src/app_status.h +++ b/firmware/application/src/app_status.h @@ -31,5 +31,9 @@ #define STATUS_FLASH_WRITE_FAIL (0x70) // Flash writing failed #define STATUS_FLASH_READ_FAIL (0x71) // Flash read failed #define STATUS_INVALID_SLOT_TYPE (0x72) // Invalid slot type +#define STATUS_MEM_ERR (0x73) // Can't allocate memory or work with memory error +#define STATUS_CREATE_RESPONSE_ERR (0x74) // Can't create response for command +#define STATUS_CMD_ERR (0x75) // Execution of command failed + #endif diff --git a/firmware/application/src/data_cmd.h b/firmware/application/src/data_cmd.h index 3aa1c823..4133a9bc 100644 --- a/firmware/application/src/data_cmd.h +++ b/firmware/application/src/data_cmd.h @@ -91,6 +91,9 @@ #define DATA_CMD_HIDPROX_WRITE_TO_T55XX (3003) #define DATA_CMD_VIKING_SCAN (3004) #define DATA_CMD_VIKING_WRITE_TO_T55XX (3005) +#define DATA_CMD_ADC_GENERIC_READ (3006) +#define DATA_CMD_GENERIC_READ (3007) +#define DATA_CMD_CORR_GENERIC_READ (3008) // // ****************************************************************** diff --git a/firmware/application/src/rfid/reader/lf/lf_reader_data.h b/firmware/application/src/rfid/reader/lf/lf_reader_data.h index 55c68346..09a277bf 100644 --- a/firmware/application/src/rfid/reader/lf/lf_reader_data.h +++ b/firmware/application/src/rfid/reader/lf/lf_reader_data.h @@ -22,6 +22,8 @@ bool em410x_read(uint8_t *data, uint32_t timeout_ms); bool hidprox_read(uint8_t *data, uint8_t format_hint, uint32_t timeout_ms); bool viking_read(uint8_t *data, uint32_t timeout_ms); +bool raw_read_to_buffer(uint8_t *data, size_t maxlen, uint32_t timeout_ms, size_t *outlen); + #ifdef __cplusplus } #endif diff --git a/firmware/application/src/rfid/reader/lf/lf_reader_generic.c b/firmware/application/src/rfid/reader/lf/lf_reader_generic.c new file mode 100644 index 00000000..4fdbc424 --- /dev/null +++ b/firmware/application/src/rfid/reader/lf/lf_reader_generic.c @@ -0,0 +1,60 @@ +#include "lf_reader_data.h" + +#include "bsp_delay.h" +#include "bsp_time.h" +#include "circular_buffer.h" +#include "lf_125khz_radio.h" +#include "lf_reader_data.h" +#include "protocols/protocols.h" + +#define NRF_LOG_MODULE_NAME lfgeneric +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_log_default_backends.h" +NRF_LOG_MODULE_REGISTER(); + +#define CIRCULAR_BUFFER_SIZE (128) +static circular_buffer cb; + +// saadc irq is used to sample ANT GPIO. +static void saadc_cb(nrf_saadc_value_t *vals, size_t size) { + for (int i = 0; i < size; i++) { + nrf_saadc_value_t val = vals[i]; + if (!cb_push_back(&cb, &val)) { + return; + } + } +} + +static void init_saadc_hw(void) { + lf_125khz_radio_saadc_enable(saadc_cb); +} + +static void uninit_saadc_hw(void) { + lf_125khz_radio_saadc_disable(); +} + +bool raw_read_to_buffer(uint8_t *data, size_t maxlen, uint32_t timeout_ms, size_t *outlen) { + *outlen = 0; + + cb_init(&cb, CIRCULAR_BUFFER_SIZE, sizeof(uint16_t)); + init_saadc_hw(); + start_lf_125khz_radio(); + + autotimer *p_at = bsp_obtain_timer(0); + while (NO_TIMEOUT_1MS(p_at, timeout_ms) && *outlen < maxlen) { + uint16_t val = 0; + while (cb_pop_front(&cb, &val) && *outlen < maxlen) { + val = val >> 5; // 14 bit ADC to 8 bit value and /2 range + data[*outlen] = val > 0xff ? 0xff : val; + ++(*outlen); + } + } + + bsp_return_timer(p_at); + stop_lf_125khz_radio(); + uninit_saadc_hw(); + cb_free(&cb); + + return true; +} diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index a507d7f8..81441750 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -545,6 +545,7 @@ def on_exec(self, args: argparse.Namespace): lf_hid = lf.subgroup('hid', 'HID commands') lf_hid_prox = lf_hid.subgroup('prox', 'HID Prox commands') lf_viking = lf.subgroup('viking', 'Viking commands') +lf_generic = lf.subgroup('generic', 'Generic commands') @root.command('clear') class RootClear(BaseCLIUnit): @@ -3250,6 +3251,32 @@ def on_exec(self, args: argparse.Namespace): self.cmd.viking_write_to_t55xx(id_bytes) print(f" - Viking ID(8H): {id_hex} write done.") +@lf_generic.command('adcread') +class LFADCGenericRead(ReaderRequiredUnit): + def args_parser(self) -> ArgumentParserNoExit: + parser = ArgumentParserNoExit() + parser.description = 'Read ADC and return the array' + return parser + + def on_exec(self, args: argparse.Namespace): + resp = self.cmd.adc_generic_read() + + if resp is not None: + print(f"generic read data[{len(resp)}]:") + width = 50 + for i in range(0, len(resp), width): + chunk = resp[i : i + width] + hexpart = " ".join(f"{b:02x}" for b in chunk) + binpart = "".join('1' if b >= 0xbf else '0' for b in chunk) + print(f"{i:04x} {hexpart:<{width * 3}} {binpart}") + + avg = 0 + for val in resp: + avg += val + print(f'avg: {hex(round(avg / len(resp)))}') + else: + print(f"generic read error") + @hw_slot.command('list') class HWSlotList(DeviceRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index f34889b3..26c786a1 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -500,6 +500,18 @@ def viking_write_to_t55xx(self, id_bytes: bytes): data = struct.pack(f'!4s4s{4*len(old_keys)}s', id_bytes, new_key, b''.join(old_keys)) return self.device.send_cmd_sync(Command.VIKING_WRITE_TO_T55XX, data) + @expect_response(Status.LF_TAG_OK) + def adc_generic_read(self): + """ + Read the ADC when the field is on. + + :return: + """ + resp = self.device.send_cmd_sync(Command.ADC_GENERIC_READ, None) + if resp.status == Status.LF_TAG_OK: + resp.parsed = resp.data + return resp + @expect_response(Status.SUCCESS) def get_slot_info(self): """ diff --git a/software/script/chameleon_enum.py b/software/script/chameleon_enum.py index a66ebcae..eadb5160 100644 --- a/software/script/chameleon_enum.py +++ b/software/script/chameleon_enum.py @@ -80,6 +80,7 @@ class Command(enum.IntEnum): HIDPROX_WRITE_TO_T55XX = 3003 VIKING_SCAN = 3004 VIKING_WRITE_TO_T55XX = 3005 + ADC_GENERIC_READ = 3006 MF1_WRITE_EMU_BLOCK_DATA = 4000 HF14A_SET_ANTI_COLL_DATA = 4001