diff --git a/non_catalog_apps/uhf_rfid/application.fam b/non_catalog_apps/uhf_rfid/application.fam index 105dc0a1da0..33d90bee215 100644 --- a/non_catalog_apps/uhf_rfid/application.fam +++ b/non_catalog_apps/uhf_rfid/application.fam @@ -1,6 +1,6 @@ App( appid="uhf_rfid", - name="[(Q)M100] UHF RFID", + name="[YRM100] UHF RFID", apptype=FlipperAppType.EXTERNAL, targets=["f7"], entry_point="uhf_app_main", @@ -8,10 +8,10 @@ App( "storage", "gui", ], - stack_size=8 * 1024, + stack_size=10 * 1024, order=30, fap_icon="icons/uhf_10px.png", - fap_category="RFID", + fap_category="GPIO", fap_icon_assets="icons", fap_icon_assets_symbol="uhf_rfid", ) diff --git a/non_catalog_apps/uhf_rfid/scenes/uhf_scene_settings.c b/non_catalog_apps/uhf_rfid/scenes/uhf_scene_settings.c index f1cb30bccd0..49210260541 100644 --- a/non_catalog_apps/uhf_rfid/scenes/uhf_scene_settings.c +++ b/non_catalog_apps/uhf_rfid/scenes/uhf_scene_settings.c @@ -2,15 +2,15 @@ #include "../uhf_module.h" void uhf_settings_set_module_baudrate(VariableItem* item) { - M100Module* uhf_module = variable_item_get_context(item); + M100Module* module = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); if(index >= BAUD_RATES_COUNT) { return; } uint32_t baudrate = BAUD_RATES[index]; - m100_set_baudrate(uhf_module, baudrate); + m100_set_baudrate(module, baudrate); char text_buf[10]; - snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate); + snprintf(text_buf, sizeof(text_buf), "%lu", module->uart->baudrate); variable_item_set_current_value_text(item, text_buf); } @@ -40,7 +40,7 @@ void uhf_settings_set_module_working_region(VariableItem* item) { uint8_t uhf_settings_get_module_baudrate_index(M100Module* module) { for(uint8_t i = 0; i < BAUD_RATES_COUNT; i++) { - if(BAUD_RATES[i] == module->baudrate) { + if(BAUD_RATES[i] == module->uart->baudrate) { return i; } } @@ -73,7 +73,7 @@ void uhf_scene_settings_on_enter(void* ctx) { uint8_t value_index = uhf_settings_get_module_baudrate_index(uhf_module); char text_buf[10]; - snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->baudrate); + snprintf(text_buf, sizeof(text_buf), "%lu", uhf_module->uart->baudrate); item = variable_item_list_add( variable_item_list, "Baudrate:", diff --git a/non_catalog_apps/uhf_rfid/uhf_app.c b/non_catalog_apps/uhf_rfid/uhf_app.c index ff52882df8d..8e6fe5e93b4 100644 --- a/non_catalog_apps/uhf_rfid/uhf_app.c +++ b/non_catalog_apps/uhf_rfid/uhf_app.c @@ -201,25 +201,20 @@ int32_t uhf_app_main(void* ctx) { expansion_disable(expansion); UHFApp* uhf_app = uhf_alloc(); - // enable 5v pin - uint8_t attempts = 0; + uint8_t attempts = 0; bool otg_was_enabled = furi_hal_power_is_otg_enabled(); while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) { furi_hal_power_enable_otg(); furi_delay_ms(10); } - furi_delay_ms(200); - // init pin a2 - // furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + // enter app scene_manager_next_scene(uhf_app->scene_manager, UHFSceneModuleInfo); view_dispatcher_run(uhf_app->view_dispatcher); - // disable 5v pin - if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { + if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) { furi_hal_power_disable_otg(); } - // furi_hal_gpio_disable_int_callback() // exit app uhf_free(uhf_app); diff --git a/non_catalog_apps/uhf_rfid/uhf_buffer.c b/non_catalog_apps/uhf_rfid/uhf_buffer.c index 8e56f88df98..5ee32c40292 100644 --- a/non_catalog_apps/uhf_rfid/uhf_buffer.c +++ b/non_catalog_apps/uhf_rfid/uhf_buffer.c @@ -2,7 +2,7 @@ #include #include -Buffer* buffer_alloc(size_t initial_capacity) { +Buffer* uhf_buffer_alloc(size_t initial_capacity) { Buffer* buf = (Buffer*)malloc(sizeof(Buffer)); buf->data = (uint8_t*)malloc(sizeof(uint8_t) * initial_capacity); if(!buf->data) { @@ -14,7 +14,7 @@ Buffer* buffer_alloc(size_t initial_capacity) { return buf; } -bool buffer_append_single(Buffer* buf, uint8_t data) { +bool uhf_buffer_append_single(Buffer* buf, uint8_t data) { if(buf->closed) return false; if(buf->size + 1 > buf->capacity) { size_t new_capacity = buf->capacity * 2; @@ -27,7 +27,7 @@ bool buffer_append_single(Buffer* buf, uint8_t data) { return true; } -bool buffer_append(Buffer* buf, uint8_t* data, size_t data_size) { +bool uhf_buffer_append(Buffer* buf, uint8_t* data, size_t data_size) { if(buf->closed) return false; if(buf->size + data_size > buf->capacity) { size_t new_capacity = buf->capacity * 2; @@ -43,19 +43,23 @@ bool buffer_append(Buffer* buf, uint8_t* data, size_t data_size) { return true; } -uint8_t* buffer_get_data(Buffer* buf) { +uint8_t* uhf_buffer_get_data(Buffer* buf) { return buf->data; } -size_t buffer_get_size(Buffer* buf) { +size_t uhf_buffer_get_size(Buffer* buf) { return buf->size; } -void buffer_close(Buffer* buf) { +bool uhf_is_buffer_closed(Buffer* buf) { + return buf->closed; +} + +void uhf_buffer_close(Buffer* buf) { buf->closed = true; } -void buffer_reset(Buffer* buf) { +void uhf_buffer_reset(Buffer* buf) { for(size_t i = 0; i < MAX_BUFFER_SIZE; i++) { buf->data[i] = 0; } @@ -63,7 +67,7 @@ void buffer_reset(Buffer* buf) { buf->closed = false; } -void buffer_free(Buffer* buf) { +void uhf_buffer_free(Buffer* buf) { free(buf->data); free(buf); } \ No newline at end of file diff --git a/non_catalog_apps/uhf_rfid/uhf_buffer.h b/non_catalog_apps/uhf_rfid/uhf_buffer.h index 045b0e3e403..d1420094bc6 100644 --- a/non_catalog_apps/uhf_rfid/uhf_buffer.h +++ b/non_catalog_apps/uhf_rfid/uhf_buffer.h @@ -12,11 +12,13 @@ typedef struct Buffer { bool closed; } Buffer; -Buffer* buffer_alloc(size_t inital_capacity); -bool buffer_append_single(Buffer* buf, uint8_t value); -bool buffer_append(Buffer* buf, uint8_t* data, size_t size); -uint8_t* buffer_get_data(Buffer* buf); -size_t buffer_get_size(Buffer* buf); -void buffer_close(Buffer* buf); -void buffer_reset(Buffer* buf); -void buffer_free(Buffer* buf); \ No newline at end of file +Buffer* uhf_buffer_alloc(size_t inital_capacity); +bool uhf_buffer_append_single(Buffer* buf, uint8_t value); +bool uhf_buffer_append(Buffer* buf, uint8_t* data, size_t size); + +uint8_t* uhf_buffer_get_data(Buffer* buf); +size_t uhf_buffer_get_size(Buffer* buf); +bool uhf_is_buffer_closed(Buffer* buf); +void uhf_buffer_close(Buffer* buf); +void uhf_buffer_reset(Buffer* buf); +void uhf_buffer_free(Buffer* buf); \ No newline at end of file diff --git a/non_catalog_apps/uhf_rfid/uhf_device.c b/non_catalog_apps/uhf_rfid/uhf_device.c index c560b4e56c0..812aa565d2c 100644 --- a/non_catalog_apps/uhf_rfid/uhf_device.c +++ b/non_catalog_apps/uhf_rfid/uhf_device.c @@ -7,8 +7,6 @@ static const char* uhf_file_header = "Flipper UHF RFID device"; static const uint32_t uhf_file_version = 1; -// static const uint8_t bank_data_start = 20; -// static const uint8_t bank_data_length = 16; UHFDevice* uhf_device_alloc() { UHFDevice* uhf_device = malloc(sizeof(UHFDevice)); @@ -178,15 +176,6 @@ static bool uhf_device_load_data(UHFDevice* dev, FuriString* path, bool show_dia return parsed; } -// void picopass_device_clear(UHFDevice* dev) { -// furi_assert(dev); - -// picopass_device_data_clear(&dev->dev_data); -// memset(&dev->dev_data, 0, sizeof(dev->dev_data)); -// dev->format = PicopassDeviceSaveFormatHF; -// furi_string_reset(dev->load_path); -// } - void uhf_device_free(UHFDevice* uhf_dev) { furi_assert(uhf_dev); furi_record_close(RECORD_STORAGE); @@ -224,16 +213,6 @@ bool uhf_file_select(UHFDevice* dev) { return res; } -// void uhf_device_data_clear(UHFDevice* dev_data) { -// for(size_t i = 0; i < PICOPASS_MAX_APP_LIMIT; i++) { -// memset(dev_data->AA1[i].data, 0, sizeof(dev_data->AA1[i].data)); -// } -// dev_data->pacs.legacy = false; -// dev_data->pacs.se_enabled = false; -// dev_data->pacs.elite_kdf = false; -// dev_data->pacs.pin_length = 0; -// } - bool uhf_device_delete(UHFDevice* dev, bool use_load_path) { furi_assert(dev); @@ -265,84 +244,4 @@ void uhf_device_set_loading_callback(UHFDevice* dev, UHFLoadingCallback callback dev->loading_cb = callback; dev->loading_cb_ctx = context; -} - -// ReturnCode picopass_device_decrypt(uint8_t* enc_data, uint8_t* dec_data) { -// uint8_t key[32] = {0}; -// memcpy(key, picopass_iclass_decryptionkey, sizeof(picopass_iclass_decryptionkey)); -// mbedtls_des3_context ctx; -// mbedtls_des3_init(&ctx); -// mbedtls_des3_set2key_dec(&ctx, key); -// mbedtls_des3_crypt_ecb(&ctx, enc_data, dec_data); -// mbedtls_des3_free(&ctx); -// return ERR_NONE; -// } - -// ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pacs) { -// ReturnCode err; - -// pacs->biometrics = AA1[6].data[4]; -// pacs->pin_length = AA1[6].data[6] & 0x0F; -// pacs->encryption = AA1[6].data[7]; - -// if(pacs->encryption == PicopassDeviceEncryption3DES) { -// FURI_LOG_D(TAG, "3DES Encrypted"); -// err = picopass_device_decrypt(AA1[7].data, pacs->credential); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } - -// err = picopass_device_decrypt(AA1[8].data, pacs->pin0); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } - -// err = picopass_device_decrypt(AA1[9].data, pacs->pin1); -// if(err != ERR_NONE) { -// FURI_LOG_E(TAG, "decrypt error %d", err); -// return err; -// } -// } else if(pacs->encryption == PicopassDeviceEncryptionNone) { -// FURI_LOG_D(TAG, "No Encryption"); -// memcpy(pacs->credential, AA1[7].data, PICOPASS_BLOCK_LEN); -// memcpy(pacs->pin0, AA1[8].data, PICOPASS_BLOCK_LEN); -// memcpy(pacs->pin1, AA1[9].data, PICOPASS_BLOCK_LEN); -// } else if(pacs->encryption == PicopassDeviceEncryptionDES) { -// FURI_LOG_D(TAG, "DES Encrypted"); -// } else { -// FURI_LOG_D(TAG, "Unknown encryption"); -// } - -// pacs->sio = (AA1[10].data[0] == 0x30); // rough check - -// return ERR_NONE; -// } - -// ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record) { -// uint32_t* halves = (uint32_t*)data; -// if(halves[0] == 0) { -// uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[1])); -// record->bitLength = 31 - leading0s; -// } else { -// uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[0])); -// record->bitLength = 63 - leading0s; -// } -// FURI_LOG_D(TAG, "bitLength: %d", record->bitLength); - -// if(record->bitLength == 26) { -// uint8_t* v4 = data + 4; -// uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24); - -// record->CardNumber = (bot >> 1) & 0xFFFF; -// record->FacilityCode = (bot >> 17) & 0xFF; -// FURI_LOG_D(TAG, "FC: %u CN: %u", record->FacilityCode, record->CardNumber); -// record->valid = true; -// } else { -// record->CardNumber = 0; -// record->FacilityCode = 0; -// record->valid = false; -// } -// return ERR_NONE; -// } +} \ No newline at end of file diff --git a/non_catalog_apps/uhf_rfid/uhf_module.c b/non_catalog_apps/uhf_rfid/uhf_module.c index b07639dc181..2e002aac629 100644 --- a/non_catalog_apps/uhf_rfid/uhf_module.c +++ b/non_catalog_apps/uhf_rfid/uhf_module.c @@ -2,33 +2,23 @@ #include "uhf_module_cmd.h" #define DELAY_MS 100 -#define WAIT_TICK 8000 // max wait time in between each byte - -volatile uint16_t tick = 0; - -void rx_callback(FuriHalSerialHandle* handle, FuriHalSerialRxEvent event, void* ctx) { - UNUSED(event); - Buffer* buffer = ctx; - if(buffer->closed) return; // buffer closed - if(event == FuriHalSerialRxEventData) { - uint8_t data = furi_hal_serial_async_rx(handle); - buffer_append_single(buffer, data); // append data - if(data == FRAME_END) buffer_close(buffer); // end of frame - tick = WAIT_TICK; // reset tick - } -} +#define WAIT_TICK 4000 // max wait time in between each byte static M100ResponseType setup_and_send_rx(M100Module* module, uint8_t* cmd, size_t cmd_length) { - buffer_reset(module->buf); - tick = WAIT_TICK; - furi_hal_serial_tx(module->serial_handle, cmd, cmd_length); - while(--tick) { - furi_delay_us(5); + UHFUart* uart = module->uart; + Buffer* buffer = uart->buffer; + // clear buffer + uhf_buffer_reset(buffer); + // send cmd + uhf_uart_send_wait(uart, cmd, cmd_length); + // wait for response by polling + while(!uhf_is_buffer_closed(buffer) && !uhf_uart_tick(uart)) { } - buffer_close(module->buf); + // reset tick + uhf_uart_tick_reset(uart); // Validation Checks - uint8_t* data = buffer_get_data(module->buf); - size_t length = buffer_get_size(module->buf); + uint8_t* data = uhf_buffer_get_data(buffer); + size_t length = uhf_buffer_get_size(buffer); // check if size > 0 if(!length) return M100EmptyResponse; // check if data is valid @@ -44,30 +34,24 @@ M100ModuleInfo* m100_module_info_alloc() { } void m100_module_info_free(M100ModuleInfo* module_info) { - free(module_info->hw_version); - free(module_info->sw_version); - free(module_info->manufacturer); + if(module_info->hw_version != NULL) free(module_info->hw_version); + if(module_info->sw_version != NULL) free(module_info->sw_version); + if(module_info->manufacturer != NULL) free(module_info->manufacturer); free(module_info); } + M100Module* m100_module_alloc() { M100Module* module = (M100Module*)malloc(sizeof(M100Module)); - module->info = m100_module_info_alloc(); - module->buf = buffer_alloc(MAX_BUFFER_SIZE); - module->baudrate = DEFAULT_BAUDRATE; module->transmitting_power = DEFAULT_TRANSMITTING_POWER; module->region = DEFAULT_WORKING_REGION; - module->serial_handle = furi_hal_serial_control_acquire(FuriHalSerialIdUsart); - furi_check(module->serial_handle); - furi_hal_serial_init(module->serial_handle, module->baudrate); - furi_hal_serial_async_rx_start(module->serial_handle, rx_callback, module->buf, false); + module->info = m100_module_info_alloc(); + module->uart = uhf_uart_alloc(); return module; } void m100_module_free(M100Module* module) { - furi_hal_serial_deinit(module->serial_handle); - furi_hal_serial_control_release(module->serial_handle); m100_module_info_free(module->info); - buffer_free(module->buf); + uhf_uart_free(module->uart); free(module); } @@ -100,8 +84,8 @@ uint16_t crc16_genibus(const uint8_t* data, size_t length) { } char* _m100_info_helper(M100Module* module, char** info) { - if(!buffer_get_size(module->buf)) return NULL; - uint8_t* data = buffer_get_data(module->buf); + if(!uhf_buffer_get_size(module->uart->buffer)) return NULL; + uint8_t* data = uhf_buffer_get_data(module->uart->buffer); uint16_t payload_len = data[3]; payload_len = (payload_len << 8) + data[4]; FuriString* temp_str = furi_string_alloc(); @@ -137,8 +121,7 @@ M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag) { M100ResponseType rp_type = setup_and_send_rx(module, (uint8_t*)&CMD_SINGLE_POLLING.cmd[0], CMD_SINGLE_POLLING.length); if(rp_type != M100SuccessResponse) return rp_type; - uint8_t* data = buffer_get_data(module->buf); - size_t length = buffer_get_size(module->buf); + uint8_t* data = uhf_buffer_get_data(module->uart->buffer); uint16_t pc = data[6]; uint16_t crc = 0; // mask out epc length from protocol control @@ -152,8 +135,6 @@ M100ResponseType m100_single_poll(M100Module* module, UHFTag* uhf_tag) { crc = data[8 + epc_len]; crc <<= 8; crc += data[8 + epc_len + 1]; - // validate checksum - if(checksum(data + 1, length - 3) != data[length - 2]) return M100ValidationFail; // validate crc if(crc16_genibus(data + 6, epc_len + 2) != crc) return M100ValidationFail; uhf_tag_set_epc_pc(uhf_tag, pc); @@ -192,25 +173,26 @@ M100ResponseType m100_set_select(M100Module* module, UHFTag* uhf_tag) { // end frame cmd[cmd_length - 1] = FRAME_END; - setup_and_send_rx(module, cmd, 12 + mask_length_bytes + 3); + M100ResponseType rp_type = setup_and_send_rx(module, cmd, 12 + mask_length_bytes + 3); + + if(rp_type != M100SuccessResponse) return rp_type; - uint8_t* data = buffer_get_data(module->buf); - if(checksum(data + 1, 5) != data[6]) return M100ValidationFail; // error in rx + uint8_t* data = uhf_buffer_get_data(module->uart->buffer); if(data[5] != 0x00) return M100ValidationFail; // error if not 0 return M100SuccessResponse; } UHFTag* m100_get_select_param(M100Module* module) { - buffer_reset(module->buf); - // furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, rx_callback, module->buf); - furi_hal_serial_tx( - module->serial_handle, - (uint8_t*)&CMD_GET_SELECT_PARAMETER.cmd, - CMD_GET_SELECT_PARAMETER.length); - furi_delay_ms(DELAY_MS); + uhf_buffer_reset(module->uart->buffer); + // furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, rx_callback, module->uart->buffer); + // furi_hal_uart_tx( + // FuriHalUartIdUSART1, + // (uint8_t*)&CMD_GET_SELECT_PARAMETER.cmd, + // CMD_GET_SELECT_PARAMETER.length); + // furi_delay_ms(DELAY_MS); // UHFTag* uhf_tag = uhf_tag_alloc(); - // uint8_t* data = buffer_get_data(module->buf); + // uint8_t* data = buffer_get_data(module->uart->buffer); // size_t mask_length = // uhf_tag_set_epc(uhf_tag, data + 12, ) // TODO : implement @@ -246,7 +228,7 @@ M100ResponseType m100_read_label_data_storage( M100ResponseType rp_type = setup_and_send_rx(module, cmd, cmd_length); if(rp_type != M100SuccessResponse) return rp_type; - uint8_t* data = buffer_get_data(module->buf); + uint8_t* data = uhf_buffer_get_data(module->uart->buffer); uint8_t rtn_command = data[2]; uint16_t payload_len = data[3]; @@ -326,17 +308,10 @@ M100ResponseType m100_write_label_data_storage( cmd[cmd_length - 2] = checksum(cmd + 1, cmd_length - 3); cmd[cmd_length - 1] = FRAME_END; // send cmd - // furi_hal_serial_async_rx_start(module->serial_handle, rx_callback, module->buf, false); - // furi_hal_serial_tx(module->serial_handle, cmd, cmd_length); - // unsigned int delay = DELAY_MS / 2; - // unsigned int timeout = 15; - // while(!buffer_get_size(module->buf)) { - // furi_delay_ms(delay); - // if(!timeout--) break; - // } - setup_and_send_rx(module, cmd, cmd_length); - uint8_t* buff_data = buffer_get_data(module->buf); - size_t buff_length = buffer_get_size(module->buf); + M100ResponseType rp_type = setup_and_send_rx(module, cmd, cmd_length); + if(rp_type != M100SuccessResponse) return rp_type; + uint8_t* buff_data = uhf_buffer_get_data(module->uart->buffer); + size_t buff_length = uhf_buffer_get_size(module->uart->buffer); if(buff_data[2] == 0xFF && buff_length == 8) return M100NoTagResponse; else if(buff_data[2] == 0xFF) @@ -351,9 +326,10 @@ void m100_set_baudrate(M100Module* module, uint32_t baudrate) { cmd[6] = 0xFF & br_mod; // pow LSB cmd[5] = 0xFF & (br_mod >> 8); // pow MSB cmd[length - 2] = checksum(cmd + 1, length - 3); - furi_hal_serial_tx(module->serial_handle, cmd, length); - furi_hal_serial_set_br(module->serial_handle, baudrate); - module->baudrate = baudrate; + // setup_and_send_rx(module, cmd, length); + uhf_uart_send_wait(module->uart, cmd, length); + uhf_uart_set_baudrate(module->uart, baudrate); + module->uart->baudrate = baudrate; } bool m100_set_working_region(M100Module* module, WorkingRegion region) { @@ -392,5 +368,5 @@ bool m100_set_power(M100Module* module, uint8_t* power) { } uint32_t m100_get_baudrate(M100Module* module) { - return module->baudrate; + return module->uart->baudrate; } \ No newline at end of file diff --git a/non_catalog_apps/uhf_rfid/uhf_module.h b/non_catalog_apps/uhf_rfid/uhf_module.h index 7303f7375ac..320f7514fcc 100644 --- a/non_catalog_apps/uhf_rfid/uhf_module.h +++ b/non_catalog_apps/uhf_rfid/uhf_module.h @@ -1,13 +1,11 @@ #pragma once - +#include #include #include #include -#include +#include "uhf_uart.h" #include "uhf_tag.h" #include "uhf_buffer.h" -#include "uhf_tag.h" -#include #include "uhf_module_settings.h" #define FRAME_START 0xBB @@ -33,13 +31,12 @@ typedef enum { typedef struct { M100ModuleInfo* info; - uint32_t baudrate; WorkingRegion region; uint16_t region_frequency; uint16_t transmitting_power; + uint16_t max_transmitting_power; bool freq_hopping; - Buffer* buf; - FuriHalSerialHandle* serial_handle; + UHFUart* uart; } M100Module; M100ModuleInfo* m100_module_info_alloc(); diff --git a/non_catalog_apps/uhf_rfid/uhf_module_cmd.h b/non_catalog_apps/uhf_rfid/uhf_module_cmd.h index 12f241ddad2..86605d8e954 100644 --- a/non_catalog_apps/uhf_rfid/uhf_module_cmd.h +++ b/non_catalog_apps/uhf_rfid/uhf_module_cmd.h @@ -13,38 +13,77 @@ static const uint8_t CMD_HW_VERSION_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x00 static const uint8_t CMD_SW_VERSION_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x01, 0x05, 0x7E}; static const uint8_t CMD_MANUFACTURERS_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x02, 0x06, 0x7E}; static const uint8_t CMD_SINGLE_POLLING_DATA[] = {0xBB, 0x00, 0x22, 0x00, 0x00, 0x22, 0x7E}; -static const uint8_t CMD_MULTIPLE_POLLING_DATA[] = {0xBB, 0x00, 0x27, 0x00, 0x03, 0x22, 0x27, 0x10, 0x83, 0x7E}; +static const uint8_t CMD_MULTIPLE_POLLING_DATA[] = + {0xBB, 0x00, 0x27, 0x00, 0x03, 0x22, 0x27, 0x10, 0x83, 0x7E}; static const uint8_t CMD_STOP_MULTIPLE_POLLING_DATA[] = {0xBB, 0x00, 0x28, 0x00, 0x00, 0x28, 0x7E}; -static const uint8_t CMD_SET_SELECT_PARAMETER_DATA[] = {0xBB, 0x00, 0x0C, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x20, 0x60, 0x00, 0x30, 0x75, 0x1F, 0xEB, 0x70, 0x5C, 0x59, 0x04, 0xE3, 0xD5, 0x0D, 0x70, 0xAD, 0x7E}; +static const uint8_t CMD_SET_SELECT_PARAMETER_DATA[] = {0xBB, 0x00, 0x0C, 0x00, 0x13, 0x01, 0x00, + 0x00, 0x00, 0x20, 0x60, 0x00, 0x30, 0x75, + 0x1F, 0xEB, 0x70, 0x5C, 0x59, 0x04, 0xE3, + 0xD5, 0x0D, 0x70, 0xAD, 0x7E}; static const uint8_t CMD_GET_SELECT_PARAMETER_DATA[] = {0xBB, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x7E}; static const uint8_t CMD_SET_SELECT_MODE_DATA[] = {0xBB, 0x00, 0x12, 0x00, 0x01, 0x01, 0x14, 0x7E}; -static const uint8_t CMD_READ_LABEL_DATA_STORAGE_AREA_DATA[] = {0xBB, 0x00, 0x39, 0x00, 0x09, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x45, 0x7E}; -static const uint8_t CMD_WRITE_LABEL_DATA_STORE_DATA[] = {0xBB, 0x00, 0x49, 0x00, 0x0D, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x12, 0x34, 0x56, 0x78, 0x6D, 0x7E}; -static const uint8_t CMD_LOCK_LABEL_DATA_STORE_DATA[] = {0xBB, 0x00, 0x82, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0x80, 0x09, 0x7E}; -static const uint8_t CMD_INACTIVATE_KILL_TAG_DATA[] = {0xBB, 0x00, 0x65, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x67, 0x7E}; -static const uint8_t CMD_SET_COMMUNICATION_BAUD_RATE_DATA[] = {0xBB, 0x00, 0x11, 0x00, 0x02, 0x00, 0xC0, 0xD3, 0x7E}; +static const uint8_t CMD_READ_LABEL_DATA_STORAGE_AREA_DATA[] = + {0xBB, 0x00, 0x39, 0x00, 0x09, 0x00, 0x00, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, 0x45, 0x7E}; +static const uint8_t CMD_WRITE_LABEL_DATA_STORE_DATA[] = {0xBB, 0x00, 0x49, 0x00, 0x0D, 0x00, 0x00, + 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x02, + 0x12, 0x34, 0x56, 0x78, 0x6D, 0x7E}; +static const uint8_t CMD_LOCK_LABEL_DATA_STORE_DATA[] = + {0xBB, 0x00, 0x82, 0x00, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0x00, 0x80, 0x09, 0x7E}; +static const uint8_t CMD_INACTIVATE_KILL_TAG_DATA[] = + {0xBB, 0x00, 0x65, 0x00, 0x04, 0x00, 0x00, 0xFF, 0xFF, 0x67, 0x7E}; +static const uint8_t CMD_SET_COMMUNICATION_BAUD_RATE_DATA[] = + {0xBB, 0x00, 0x11, 0x00, 0x02, 0x00, 0xC0, 0xD3, 0x7E}; static const uint8_t CMD_GET_QUERY_PARAMETERS_DATA[] = {0xBB, 0x00, 0x0D, 0x00, 0x00, 0x0D, 0x7E}; -static const uint8_t CMD_SET_QUERY_PARAMETER_DATA[] = {0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E}; +static const uint8_t CMD_SET_QUERY_PARAMETER_DATA[] = + {0xBB, 0x00, 0x0E, 0x00, 0x02, 0x10, 0x20, 0x40, 0x7E}; static const uint8_t CMD_SET_WORK_AREA_DATA[] = {0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 0x7E}; -static const uint8_t CMD_SET_TRANSMITTING_POWER_DATA[] = {0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 0x7E}; - +static const uint8_t CMD_SET_TRANSMITTING_POWER_DATA[] = + {0xBB, 0x00, 0xB6, 0x00, 0x02, 0x07, 0xD0, 0x8F, 0x7E}; // Define the Command structs static const Command CMD_HW_VERSION = {CMD_HW_VERSION_DATA, sizeof(CMD_HW_VERSION_DATA)}; static const Command CMD_SW_VERSION = {CMD_SW_VERSION_DATA, sizeof(CMD_SW_VERSION_DATA)}; static const Command CMD_MANUFACTURERS = {CMD_MANUFACTURERS_DATA, sizeof(CMD_MANUFACTURERS_DATA)}; -static const Command CMD_SINGLE_POLLING = {CMD_SINGLE_POLLING_DATA, sizeof(CMD_SINGLE_POLLING_DATA)}; -static const Command CMD_MULTIPLE_POLLING = {CMD_MULTIPLE_POLLING_DATA, sizeof(CMD_MULTIPLE_POLLING_DATA)}; -static const Command CMD_STOP_MULTIPLE_POLLING = {CMD_STOP_MULTIPLE_POLLING_DATA, sizeof(CMD_STOP_MULTIPLE_POLLING_DATA)}; -static const Command CMD_SET_SELECT_PARAMETER = {CMD_SET_SELECT_PARAMETER_DATA, sizeof(CMD_SET_SELECT_PARAMETER_DATA)}; -static const Command CMD_GET_SELECT_PARAMETER = {CMD_GET_SELECT_PARAMETER_DATA, sizeof(CMD_GET_SELECT_PARAMETER_DATA)}; -static const Command CMD_SET_SELECT_MODE = {CMD_SET_SELECT_MODE_DATA, sizeof(CMD_SET_SELECT_MODE_DATA)}; -static const Command CMD_READ_LABEL_DATA_STORAGE_AREA = {CMD_READ_LABEL_DATA_STORAGE_AREA_DATA, sizeof(CMD_READ_LABEL_DATA_STORAGE_AREA_DATA)}; -static const Command CMD_WRITE_LABEL_DATA_STORE = {CMD_WRITE_LABEL_DATA_STORE_DATA, sizeof(CMD_WRITE_LABEL_DATA_STORE_DATA)}; -static const Command CMD_LOCK_LABEL_DATA_STORE = {CMD_LOCK_LABEL_DATA_STORE_DATA, sizeof(CMD_LOCK_LABEL_DATA_STORE_DATA)}; -static const Command CMD_INACTIVATE_KILL_TAG = {CMD_INACTIVATE_KILL_TAG_DATA, sizeof(CMD_INACTIVATE_KILL_TAG_DATA)}; -static const Command CMD_SET_COMMUNICATION_BAUD_RATE = {CMD_SET_COMMUNICATION_BAUD_RATE_DATA, sizeof(CMD_SET_COMMUNICATION_BAUD_RATE_DATA)}; -static const Command CMD_GET_QUERY_PARAMETERS = {CMD_GET_QUERY_PARAMETERS_DATA, sizeof(CMD_GET_QUERY_PARAMETERS_DATA)}; -static const Command CMD_SET_QUERY_PARAMETER = {CMD_SET_QUERY_PARAMETER_DATA, sizeof(CMD_SET_QUERY_PARAMETER_DATA)}; +static const Command CMD_SINGLE_POLLING = { + CMD_SINGLE_POLLING_DATA, + sizeof(CMD_SINGLE_POLLING_DATA)}; +static const Command CMD_MULTIPLE_POLLING = { + CMD_MULTIPLE_POLLING_DATA, + sizeof(CMD_MULTIPLE_POLLING_DATA)}; +static const Command CMD_STOP_MULTIPLE_POLLING = { + CMD_STOP_MULTIPLE_POLLING_DATA, + sizeof(CMD_STOP_MULTIPLE_POLLING_DATA)}; +static const Command CMD_SET_SELECT_PARAMETER = { + CMD_SET_SELECT_PARAMETER_DATA, + sizeof(CMD_SET_SELECT_PARAMETER_DATA)}; +static const Command CMD_GET_SELECT_PARAMETER = { + CMD_GET_SELECT_PARAMETER_DATA, + sizeof(CMD_GET_SELECT_PARAMETER_DATA)}; +static const Command CMD_SET_SELECT_MODE = { + CMD_SET_SELECT_MODE_DATA, + sizeof(CMD_SET_SELECT_MODE_DATA)}; +static const Command CMD_READ_LABEL_DATA_STORAGE_AREA = { + CMD_READ_LABEL_DATA_STORAGE_AREA_DATA, + sizeof(CMD_READ_LABEL_DATA_STORAGE_AREA_DATA)}; +static const Command CMD_WRITE_LABEL_DATA_STORE = { + CMD_WRITE_LABEL_DATA_STORE_DATA, + sizeof(CMD_WRITE_LABEL_DATA_STORE_DATA)}; +static const Command CMD_LOCK_LABEL_DATA_STORE = { + CMD_LOCK_LABEL_DATA_STORE_DATA, + sizeof(CMD_LOCK_LABEL_DATA_STORE_DATA)}; +static const Command CMD_INACTIVATE_KILL_TAG = { + CMD_INACTIVATE_KILL_TAG_DATA, + sizeof(CMD_INACTIVATE_KILL_TAG_DATA)}; +static const Command CMD_SET_COMMUNICATION_BAUD_RATE = { + CMD_SET_COMMUNICATION_BAUD_RATE_DATA, + sizeof(CMD_SET_COMMUNICATION_BAUD_RATE_DATA)}; +static const Command CMD_GET_QUERY_PARAMETERS = { + CMD_GET_QUERY_PARAMETERS_DATA, + sizeof(CMD_GET_QUERY_PARAMETERS_DATA)}; +static const Command CMD_SET_QUERY_PARAMETER = { + CMD_SET_QUERY_PARAMETER_DATA, + sizeof(CMD_SET_QUERY_PARAMETER_DATA)}; static const Command CMD_SET_WORK_AREA = {CMD_SET_WORK_AREA_DATA, sizeof(CMD_SET_WORK_AREA_DATA)}; -static const Command CMD_SET_TRANSMITTING_POWER = {CMD_SET_TRANSMITTING_POWER_DATA, sizeof(CMD_SET_TRANSMITTING_POWER_DATA)}; +static const Command CMD_SET_TRANSMITTING_POWER = { + CMD_SET_TRANSMITTING_POWER_DATA, + sizeof(CMD_SET_TRANSMITTING_POWER_DATA)}; diff --git a/non_catalog_apps/uhf_rfid/uhf_uart.c b/non_catalog_apps/uhf_rfid/uhf_uart.c new file mode 100644 index 00000000000..f052a83f5c0 --- /dev/null +++ b/non_catalog_apps/uhf_rfid/uhf_uart.c @@ -0,0 +1,129 @@ +#include "uhf_uart.h" + +// int32_t uhf_uart_worker_callback(void *ctx){ +// UHFUart* uart = (UHFUart*)ctx; +// Buffer* buffer = (Buffer*)uart->buffer; +// uint32_t events; +// size_t length_read = 0; +// uint8_t read_buffer[1]; +// FURI_LOG_E("UHF_UART_WORKER", "UHF UART WORKER STARTED"); +// do{ +// events = furi_thread_flags_wait( +// UHFUartWorkerWaitingDataFlag | UHFUartWorkerExitingFlag, FuriFlagWaitAny, FuriWaitForever +// ); +// FURI_LOG_E("UHF_UART_WORKER", "events = %lu", events); +// if(events & UHFUartWorkerWaitingDataFlag){ +// FURI_LOG_E("UHF_UART_WORKER", "Waiting data..."); +// length_read = furi_stream_buffer_receive(uart->rx_buff_stream, read_buffer, 1, 0); +// if(length_read){ +// do{ +// length_read = furi_stream_buffer_receive(uart->rx_buff_stream, read_buffer, 1, 0); +// uhf_buffer_append_single(buffer, read_buffer[0]); +// uhf_uart_tick_reset(uart); +// }while(read_buffer[0] != UHF_UART_FRAME_END && length_read > 0); +// FURI_LOG_E("UHF_UART_WORKER", "UHF Total length read = %u", uhf_buffer_get_size(buffer)); +// uhf_buffer_close(buffer); +// furi_stream_buffer_reset(uart->rx_buff_stream); +// } +// } +// }while((events & UHFUartWorkerExitingFlag) != UHFUartWorkerExitingFlag); +// return 0; +// } + +void uhf_uart_default_rx_callback( + FuriHalSerialHandle* handle, + FuriHalSerialRxEvent event, + void* ctx) { + UHFUart* uart = (UHFUart*)ctx; + // FURI_LOG_E("UHF_UART", "UHF UART RX CALLBACK"); + if((event & FuriHalSerialRxEventData) == FuriHalSerialRxEventData) { + uint8_t data = furi_hal_serial_async_rx(handle); + // if(data == UHF_UART_FRAME_START){ + // uhf_buffer_reset(uart->buffer); + // } + if(uhf_is_buffer_closed(uart->buffer)) { + return; + } + if(data == UHF_UART_FRAME_END) { + uhf_buffer_append_single(uart->buffer, data); + uhf_buffer_close(uart->buffer); + FURI_LOG_E( + "UHF_UART", "UHF Total length read = %u", uhf_buffer_get_size(uart->buffer)); + } + uhf_buffer_append_single(uart->buffer, data); + uhf_uart_tick_reset(uart); + // furi_stream_buffer_send(uart->rx_buff_stream, (void*)&data, 1, 0); + // furi_thread_flags_set(furi_thread_get_id(uart->thread), UHFUartWorkerWaitingDataFlag); + } +} + +UHFUart* uhf_uart_alloc() { + UHFUart* uart = (UHFUart*)malloc(sizeof(UHFUart)); + uart->bus = FuriHalBusUSART1; + uart->handle = furi_hal_serial_control_acquire(FuriHalSerialIdUsart); + // uart->rx_buff_stream = furi_stream_buffer_alloc(UHF_UART_RX_BUFFER_SIZE, 1); + uart->init_by_app = !furi_hal_bus_is_enabled(uart->bus); + uart->tick = UHF_UART_WAIT_TICK; + uart->baudrate = UHF_UART_DEFAULT_BAUDRATE; + // expansion_disable(); + if(uart->init_by_app) { + FURI_LOG_E("UHF_UART", "UHF UART INIT BY APP"); + furi_hal_serial_init(uart->handle, uart->baudrate); + } else { + FURI_LOG_E("UHF_UART", "UHF UART INIT BY HAL"); + } + uart->buffer = uhf_buffer_alloc(UHF_UART_RX_BUFFER_SIZE); + // uart->thread = furi_thread_alloc_ex("UHFUartWorker", UHF_UART_WORKER_STACK_SIZE, uhf_uart_worker_callback, uart); + // furi_thread_start(uart->thread); + furi_hal_serial_async_rx_start(uart->handle, uhf_uart_default_rx_callback, uart, false); + return uart; +} + +void uhf_uart_free(UHFUart* uart) { + furi_assert(uart); + // furi_assert(uart->thread); + // furi_thread_flags_set(furi_thread_get_id(uart->thread), UHFUartWorkerExitingFlag); + // furi_thread_join(uart->thread); + // furi_thread_free(uart->thread); + // furi_stream_buffer_free(uart->rx_buff_stream); + uhf_buffer_free(uart->buffer); + if(uart->init_by_app) { + furi_hal_serial_deinit(uart->handle); + } + furi_hal_serial_control_release(uart->handle); + free(uart); +} + +void uhf_uart_set_receive_byte_callback( + UHFUart* uart, + FuriHalSerialAsyncRxCallback callback, + void* ctx, + bool report_errors) { + furi_hal_serial_async_rx_start(uart->handle, callback, ctx, report_errors); +} + +void uhf_uart_send(UHFUart* uart, uint8_t* data, size_t size) { + furi_hal_serial_tx(uart->handle, data, size); +} + +void uhf_uart_send_wait(UHFUart* uart, uint8_t* data, size_t size) { + uhf_uart_send(uart, data, size); + furi_hal_serial_tx_wait_complete(uart->handle); + // furi_thread_flags_set(furi_thread_get_id(uart->thread), UHFUartWorkerWaitingDataFlag); +} + +void uhf_uart_set_baudrate(UHFUart* uart, uint32_t baudrate) { + furi_hal_serial_set_br(uart->handle, baudrate); + uart->baudrate = baudrate; +} + +bool uhf_uart_tick(UHFUart* uart) { + if(uart->tick > 0) { + uart->tick--; + } + return uart->tick == 0; +} + +void uhf_uart_tick_reset(UHFUart* uart) { + uart->tick = UHF_UART_WAIT_TICK; +} \ No newline at end of file diff --git a/non_catalog_apps/uhf_rfid/uhf_uart.h b/non_catalog_apps/uhf_rfid/uhf_uart.h new file mode 100644 index 00000000000..47298cfd75d --- /dev/null +++ b/non_catalog_apps/uhf_rfid/uhf_uart.h @@ -0,0 +1,48 @@ +#pragma once +#include +// #include +#include +#include +#include "uhf_buffer.h" + +#define UHF_UART_RX_BUFFER_SIZE 250 +// #define UHF_UART_WORKER_STACK_SIZE 1 * 1024 +#define UHF_UART_DEFAULT_BAUDRATE 115200 +#define UHF_UART_FRAME_START 0xBB +#define UHF_UART_FRAME_END 0x7E +#define UHF_UART_WAIT_TICK 1000 + +typedef void (*CallbackFunction)(uint8_t* data, void* ctx); + +typedef enum { + UHFUartWorkerWaitingDataFlag = 1 << 0, + UHFUartWorkerExitingFlag = 1 << 2, +} UHFUartWorkerEventFlag; + +typedef struct { + FuriHalBus bus; + FuriHalSerialHandle* handle; + // FuriStreamBuffer *rx_buff_stream; + // FuriThread *thread; + CallbackFunction callback; + Buffer* buffer; + uint32_t baudrate; + bool init_by_app; + void* ctx; + volatile int tick; +} UHFUart; + +int32_t uhf_uart_worker_callback(void* ctx); + +UHFUart* uhf_uart_alloc(); +void uhf_uart_free(UHFUart* uart); +void uhf_uart_send(UHFUart* uart, uint8_t* data, size_t size); +void uhf_uart_send_wait(UHFUart* uart, uint8_t* data, size_t size); +void uhf_uart_set_receive_byte_callback( + UHFUart* uart, + FuriHalSerialAsyncRxCallback callback, + void* ctx, + bool report_errors); +void uhf_uart_set_baudrate(UHFUart* uart, uint32_t baudrate); +bool uhf_uart_tick(UHFUart* uart); +void uhf_uart_tick_reset(UHFUart* uart); diff --git a/non_catalog_apps/uhf_rfid/uhf_worker.c b/non_catalog_apps/uhf_rfid/uhf_worker.c index 75911463182..1b695537552 100644 --- a/non_catalog_apps/uhf_rfid/uhf_worker.c +++ b/non_catalog_apps/uhf_rfid/uhf_worker.c @@ -14,14 +14,14 @@ UHFWorkerEvent verify_module_connected(UHFWorker* uhf_worker) { UHFTag* send_polling_command(UHFWorker* uhf_worker) { // read epc bank UHFTag* uhf_tag = uhf_tag_alloc(); - while(true) { - M100ResponseType status = m100_single_poll(uhf_worker->module, uhf_tag); + M100ResponseType status; + do { if(uhf_worker->state == UHFWorkerStateStop) { uhf_tag_free(uhf_tag); return NULL; } - if(status == M100SuccessResponse) break; - } + status = m100_single_poll(uhf_worker->module, uhf_tag); + } while(status != M100SuccessResponse); return uhf_tag; } @@ -48,8 +48,8 @@ UHFWorkerEvent read_single_card(UHFWorker* uhf_worker) { if(uhf_tag == NULL) return UHFWorkerEventAborted; uhf_tag_wrapper_set_tag(uhf_worker->uhf_tag_wrapper, uhf_tag); // set select - if(m100_set_select(uhf_worker->module, uhf_tag) != M100SuccessResponse) - return UHFWorkerEventFail; + while(m100_set_select(uhf_worker->module, uhf_tag) != M100SuccessResponse) { + } // read tid UHFWorkerEvent event; event = read_bank_till_max_length(uhf_worker, uhf_tag, TIDBank); @@ -64,16 +64,20 @@ UHFWorkerEvent write_single_card(UHFWorker* uhf_worker) { UHFTag* uhf_tag_des = send_polling_command(uhf_worker); if(uhf_tag_des == NULL) return UHFWorkerEventAborted; UHFTag* uhf_tag_from = uhf_worker->uhf_tag_wrapper->uhf_tag; - if(m100_set_select(uhf_worker->module, uhf_tag_des) != M100SuccessResponse) - return UHFWorkerEventFail; + M100ResponseType rp_type; + do { + rp_type = m100_set_select(uhf_worker->module, uhf_tag_des); + if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; + if(rp_type == M100SuccessResponse) break; + } while(true); do { - M100ResponseType rp_type = m100_write_label_data_storage( + rp_type = m100_write_label_data_storage( uhf_worker->module, uhf_tag_from, uhf_tag_des, UserBank, 0, 0); if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; if(rp_type == M100SuccessResponse) break; } while(true); do { - M100ResponseType rp_type = m100_write_label_data_storage( + rp_type = m100_write_label_data_storage( uhf_worker->module, uhf_tag_from, uhf_tag_des, EPCBank, 0, 0); if(uhf_worker->state == UHFWorkerStateStop) return UHFWorkerEventAborted; if(rp_type == M100SuccessResponse) break; @@ -98,7 +102,8 @@ int32_t uhf_worker_task(void* ctx) { UHFWorker* uhf_worker_alloc() { UHFWorker* uhf_worker = (UHFWorker*)malloc(sizeof(UHFWorker)); - uhf_worker->thread = furi_thread_alloc_ex("UHFWorker", 8 * 1024, uhf_worker_task, uhf_worker); + uhf_worker->thread = + furi_thread_alloc_ex("UHFWorker", UHF_WORKER_STACK_SIZE, uhf_worker_task, uhf_worker); uhf_worker->module = m100_module_alloc(); uhf_worker->callback = NULL; uhf_worker->ctx = NULL; diff --git a/non_catalog_apps/uhf_rfid/uhf_worker.h b/non_catalog_apps/uhf_rfid/uhf_worker.h index b4f5aef1ff3..09d1c14e99e 100644 --- a/non_catalog_apps/uhf_rfid/uhf_worker.h +++ b/non_catalog_apps/uhf_rfid/uhf_worker.h @@ -4,6 +4,8 @@ #include #include "uhf_module.h" +#define UHF_WORKER_STACK_SIZE 1 * 1024 + typedef enum { // Init states UHFWorkerStateNone,