Просмотр исходного кода

reworking uhf_data to seprate classes and adding a module framework

Chaka 2 лет назад
Родитель
Сommit
0aa2d6f403
6 измененных файлов с 311 добавлено и 9 удалено
  1. 67 0
      uhf_buffer.c
  2. 23 0
      uhf_buffer.h
  3. 135 0
      uhf_module.c
  4. 30 5
      uhf_module.h
  5. 48 0
      uhf_module_cmd.h
  6. 8 4
      uhf_tag.h

+ 67 - 0
uhf_buffer.c

@@ -0,0 +1,67 @@
+#include "uhf_buffer.h"
+
+Buffer* buffer_alloc(size_t initial_capacity) {
+    Buffer* buf = (Buffer*)malloc(sizeof(Buffer));
+    if(!buf) return NULL;
+
+    buf->data = (uint8_t*)malloc(initial_capacity);
+    if(!buf->data) {
+        free(buf);
+        return NULL;
+    }
+
+    buf->size = 0;
+    buf->capacity = initial_capacity;
+    return buf;
+}
+
+bool 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;
+        uint8_t* new_data = (uint8_t*)realloc(buf->data, new_capacity);
+        if(!new_data) return false;
+        buf->data = new_data;
+        buf->capacity = new_capacity;
+    }
+    buf->data[buf->size++] = data;
+    return true;
+}
+
+bool 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;
+        uint8_t* new_data = (uint8_t*)realloc(buf->data, new_capacity);
+        if(!new_data) return false;
+
+        buf->data = new_data;
+        buf->capacity = new_capacity;
+    }
+
+    memcpy(buf->data + buf->size, data, data_size);
+    buf->size += data_size;
+    return true;
+}
+
+uint8_t* buffer_get_data(Buffer* buf) {
+    return buf->data;
+}
+
+size_t buffer_get_size(Buffer* buf) {
+    return buf->size;
+}
+
+void buffer_close(Buffer* buf) {
+    buf->closed = true;
+}
+
+void buffer_reset(Buffer* buf) {
+    buf->size = 0;
+    buf->closed = false;
+}
+
+void buffer_free(Buffer* buf) {
+    free(buf->data);
+    free(buf);
+}

+ 23 - 0
uhf_buffer.h

@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#define MAX_BUFFER_SIZE 128
+
+typedef struct Buffer {
+    uint8_t* data;
+    size_t size;
+    size_t capacity;
+    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);

+ 135 - 0
uhf_module.c

@@ -0,0 +1,135 @@
+#include "uhf_module.h"
+#include "uhf_module_cmd.h"
+#include "uhf_buffer.h"
+#include "uhf_tag.h"
+#include <furi_hal.h>
+
+static void rx_callback(UartIrqEvent event, uint8_t data, void* ctx) {
+    UNUSED(event);
+    Buffer* buf = ctx;
+    if(data == FRAME_END) {
+        buffer_append_single(buf, data);
+        buffer_close(buf);
+    }
+    buffer_append_single(buf, data);
+}
+
+M100ModuleInfo* m100_module_info_alloc() {
+    M100ModuleInfo* module_info = (M100ModuleInfo*)malloc(sizeof(M100ModuleInfo));
+    return module_info;
+}
+
+void m100_module_info_free(M100ModuleInfo* module_info) {
+    free(module_info->hw_version);
+    free(module_info->sw_version);
+    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(128);
+}
+
+void m100_module_free(M100Module* module) {
+    m100_module_info_free(module->info);
+    buffer_free(module->buf);
+    free(module);
+}
+
+uint8_t checksum(uint8_t* data, size_t length) {
+    // CheckSum8 Modulo 256
+    // Sum of Bytes % 256
+    uint8_t sum_val = 0x00;
+    for(size_t i = 1; i < length; i++) {
+        sum_val += data[i];
+    }
+    return sum_val % 256;
+}
+
+uint16_t crc16_genibus(const uint8_t* data, size_t length) {
+    uint16_t crc = 0xFFFF; // Initial value
+    uint16_t polynomial = 0x1021; // CRC-16/GENIBUS polynomial
+
+    for(size_t i = 0; i < length; i++) {
+        crc ^= (data[i] << 8); // Move byte into MSB of 16bit CRC
+        for(int j = 0; j < 8; j++) {
+            if(crc & 0x8000) {
+                crc = (crc << 1) ^ polynomial;
+            } else {
+                crc <<= 1;
+            }
+        }
+    }
+
+    return crc ^ 0xFFFF; // Post-inversion
+}
+
+char* m100_get_hardware_version(M100Module* module) {
+    return module->info->hw_version;
+}
+char* m100_get_software_version(M100Module* module) {
+    return module->info->sw_version;
+}
+char* m100_get_manufacturers(M100Module* module) {
+    return module->info->manufacturer;
+}
+
+UHFTag* m100_read_single(M100Module* module) {
+    buffer_reset(module->buf);
+    furi_hal_uart_set_irq_cb(FuriHalUartIdLPUART1, rx_callback, module->buf);
+    furi_hal_uart_tx(FuriHalUartIdUSART1, CMD_SINGLE_POLLING.cmd, CMD_SINGLE_POLLING.length);
+    uint8_t* data = buffer_get_data(module->buf);
+    size_t length = buffer_get_size(module->buf);
+    if(length == 7 && data[2] == 0xFF) return NULL;
+    uint16_t pc = data[6];
+    uint16_t crc = 0;
+    size_t epc_len = pc;
+    epc_len <<= 1;
+    epc_len += (data[7] & 0x80) > 0;
+    epc_len *= 2;
+    pc <<= 8;
+    pc += data[7];
+    crc = data[8 + epc_len + 1];
+    crc <<= 8;
+    crc += data[8 + epc_len + 2];
+    if(checksum(data + 1, length - 3) != data[length - 2]) return NULL;
+    if(crc16_genibus(data + 6, epc_len + 2) != crc) return NULL;
+    UHFTag* uhf_tag = uhf_tag_alloc();
+    uhf_tag_set_epc_pc(uhf_tag, pc);
+    uhf_tag_set_epc_crc(uhf_tag, crc);
+    uhf_tag_set_epc(uhf_tag, data + 8, epc_len);
+    return uhf_tag;
+}
+
+void m100_set_baudrate(M100Module* module, uint16_t baudrate) {
+    size_t length = CMD_SET_COMMUNICATION_BAUD_RATE.length;
+    uint8_t cmd[length];
+    memcpy(cmd, CMD_SET_COMMUNICATION_BAUD_RATE.cmd, length);
+    cmd[6] = 0xFF & baudrate; // pow LSB
+    cmd[5] = 0xFF & (baudrate >> 4); // pow MSB
+    // furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL);
+    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
+    furi_hal_uart_set_br(FuriHalUartIdUSART1, baudrate * 100);
+    module->baudrate = baudrate;
+}
+bool m100_set_working_area(M100Module* module, WorkingArea area) {
+    size_t length = CMD_SET_WORK_AREA.length;
+    uint8_t cmd[length];
+    memcpy(cmd, CMD_SET_WORK_AREA.cmd, length);
+    cmd[5] = area;
+    Buffer* buf = buffer_alloc(9);
+    furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, rx_callback, buf);
+    furi_hal_uart_tx(FuriHalUartIdUSART1, cmd, length);
+    buffer_free(buf);
+    return true;
+}
+bool m100_set_working_channel(M100Module* module, WorkingChannel channel) {
+    return true;
+}
+bool m100_set_transmitting_power(M100Module* module, uint16_t power) {
+    return true;
+}
+bool m100_set_freq_hopping(M100Module* module, bool hopping) {
+    return true;
+}

+ 30 - 5
uhf_module.h

@@ -3,10 +3,13 @@
 #include <stdint.h>
 #include <stdint.h>
 #include <stdbool.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stddef.h>
+#include "uhf_buffer.h"
+
+#define FRAME_END 0x7E
 
 
 typedef struct{
 typedef struct{
     char* hw_version;
     char* hw_version;
-    char* sw_Version;
+    char* sw_version;
     char* manufacturer;
     char* manufacturer;
 }M100ModuleInfo;
 }M100ModuleInfo;
 
 
@@ -16,7 +19,7 @@ typedef enum{
     EU,             // Freq_CH-865.1M
     EU,             // Freq_CH-865.1M
     CHINA_800,      // Freq_CH-840.125M
     CHINA_800,      // Freq_CH-840.125M
     KOREA = 6       // Freq_CH-917.1M
     KOREA = 6       // Freq_CH-917.1M
-}WorkingArea;
+} WorkingArea;
 
 
 typedef enum{
 typedef enum{
     CHINA_900 = 1,  // CH_Index(CN,900MHz) = (Freq_CH-920.125M)/0.25M
     CHINA_900 = 1,  // CH_Index(CN,900MHz) = (Freq_CH-920.125M)/0.25M
@@ -24,10 +27,32 @@ typedef enum{
     EU,             // CH_Index(EU) = (Freq_CH-865.1M)/0.2M
     EU,             // CH_Index(EU) = (Freq_CH-865.1M)/0.2M
     CHINA_800,      // CH_Index(CN,800MHz) = (Freq_CH-840.125M)/0.25M
     CHINA_800,      // CH_Index(CN,800MHz) = (Freq_CH-840.125M)/0.25M
     KOREA = 6       // CH_Index(Korea) = (Freq_CH-917.1M)/0.2M
     KOREA = 6       // CH_Index(Korea) = (Freq_CH-917.1M)/0.2M
-}WorkingChannel;
+} WorkingChannel;
 
 
 typedef struct{
 typedef struct{
-    M100ModuleInfo info;
+    M100ModuleInfo* info;
     uint16_t baudrate;
     uint16_t baudrate;
+    WorkingArea area;
+    WorkingChannel channel;
+    uint16_t transmitting_power;
+    bool freq_hopping;
+    Buffer* buf;
+} M100Module;
+
+M100ModuleInfo* m100_module_info_alloc();
+void m100_module_info_free(M100ModuleInfo* module_info);
+
+M100Module* m100_module_alloc();
+void m100_module_free(M100Module* module);
+uint16_t crc16_genibus(const uint8_t* data, size_t length);
+uint8_t checksum(const uint8_t* data, size_t length);
 
 
-}M100Module;
+// Function prototypes
+char* m100_get_hardware_version(M100Module* module);
+char* m100_get_software_version(M100Module* module);
+char* m100_get_manufacturers(M100Module* module);
+void m100_set_baudrate(M100Module* module, uint16_t baudrate);
+bool m100_set_working_area(M100Module* module, WorkingArea area);
+bool m100_set_working_channel(M100Module* module, WorkingChannel channel);
+bool m100_set_transmitting_power(M100Module* module, uint16_t power);
+bool m100_set_freq_hopping(M100Module* module, bool hopping);

+ 48 - 0
uhf_module_cmd.h

@@ -0,0 +1,48 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+typedef struct {
+    const uint8_t* cmd;
+    size_t length;
+} Command;
+
+// Define the command data arrays
+static const uint8_t CMD_HW_VERSION_DATA[] = {0xBB, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x7E};
+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_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_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_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_WORK_AREA_DATA[] = {0xBB, 0x00, 0x07, 0x00, 0x01, 0x01, 0x09, 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_SET_WORK_AREA = {CMD_SET_WORK_AREA_DATA, sizeof(CMD_SET_WORK_AREA_DATA)};

+ 8 - 4
uhf_tag.h

@@ -14,6 +14,8 @@ typedef struct {
 typedef struct {
 typedef struct {
     size_t size; // Size of EPC memory data
     size_t size; // Size of EPC memory data
     uint8_t data[18]; // 2 bytes for CRC16, 2 bytes for PC, and max 14 bytes for EPC
     uint8_t data[18]; // 2 bytes for CRC16, 2 bytes for PC, and max 14 bytes for EPC
+    uint16_t pc;
+    uint16_t crc;
 } EPCMemoryBank;
 } EPCMemoryBank;
 
 
 // TID Memory Bank
 // TID Memory Bank
@@ -30,10 +32,10 @@ typedef struct {
 
 
 // EPC Gen 2 Tag containing all memory banks
 // EPC Gen 2 Tag containing all memory banks
 typedef struct {
 typedef struct {
-    ReservedMemoryBank reserved;
-    EPCMemoryBank epc;
-    TIDMemoryBank tid;
-    UserMemoryBank user;
+    ReservedMemoryBank* reserved;
+    EPCMemoryBank* epc;
+    TIDMemoryBank* tid;
+    UserMemoryBank* user;
 } UHFTag;
 } UHFTag;
 
 
 UHFTag* uhf_tag_alloc();
 UHFTag* uhf_tag_alloc();
@@ -41,6 +43,8 @@ void uhf_tag_free(UHFTag* uhf_tag);
 
 
 void uhf_tag_set_kill_pwd(UHFTag* uhf_tag, uint8_t* data_in);
 void uhf_tag_set_kill_pwd(UHFTag* uhf_tag, uint8_t* data_in);
 void uhf_tag_set_access_pwd(UHFTag* uhf_tag, uint8_t* data_in);
 void uhf_tag_set_access_pwd(UHFTag* uhf_tag, uint8_t* data_in);
+void uhf_tag_set_epc_pc(UHFTag* uhf_tag, uint16_t pc);
+void uhf_tag_set_epc_crc(UHFTag* uhf_tag, uint16_t crc);
 void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
 void uhf_tag_set_epc(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
 void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
 void uhf_tag_set_tid(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
 void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data_in, size_t size);
 void uhf_tag_set_user(UHFTag* uhf_tag, uint8_t* data_in, size_t size);