From 0336a20472ad10f699ce751c7bec01197b44c675 Mon Sep 17 00:00:00 2001 From: OPTOC <9159397+optoc@user.noreply.gitee.com> Date: Tue, 7 Oct 2025 17:49:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0stmisp=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/CMakeLists.txt | 1 + app/drivers/sertrf/protocol/stmisp.c | 232 +++++++++++++++++++++++++++ app/drivers/sertrf/protocol/stmisp.h | 117 ++++++++++++++ app/drivers/sertrf/sertrf.c | 29 +++- app/drivers/sertrf/sertrf.h | 5 + 5 files changed, 382 insertions(+), 2 deletions(-) create mode 100644 app/drivers/sertrf/protocol/stmisp.c create mode 100644 app/drivers/sertrf/protocol/stmisp.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 16a2a76..4fdff86 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -36,6 +36,7 @@ list(APPEND srcs "drivers/sertrf/protocol/MSP.c") list(APPEND srcs "drivers/sertrf/protocol/p_protocol.c") list(APPEND srcs "drivers/sertrf/protocol/mavlink_control.c") list(APPEND srcs "drivers/sertrf/protocol/resend_protl.c") +list(APPEND srcs "drivers/sertrf/protocol/stmisp.c") list(APPEND srcs "drivers/led_strip/led_strip.c") list(APPEND srcs "drivers/led_strip/led_strip_encoder.c") diff --git a/app/drivers/sertrf/protocol/stmisp.c b/app/drivers/sertrf/protocol/stmisp.c new file mode 100644 index 0000000..93e0b1f --- /dev/null +++ b/app/drivers/sertrf/protocol/stmisp.c @@ -0,0 +1,232 @@ +#include "stmisp.h" +#include +#include +extern int uart_fd; +// Utility: XOR checksum of bytes +uint8_t xor_checksum(const uint8_t *buf, size_t len) { + uint8_t cs = 0; + for (size_t i = 0; i < len; ++i) cs ^= buf[i]; + return cs; +} + +int stmisp_init(stmisp_device_t *stmisp_device, int (*send)(void* data, uint16_t len, int timeout), int (*recv)(void* data, uint16_t len, int timeout), int (*get_length )(void)) +{ + stmisp_device->send = send; + stmisp_device->recv = recv; + stmisp_device->get_length = get_length; + return 0; +} + +int wait_ack(stmisp_device_t *stmisp_device, uint32_t timeout) +{ + uint8_t ack = 0; + uint8_t size =stmisp_device->recv(&ack, 1, timeout); + + if(size > 0) + { + switch (ack) + { + case ACK: + return 1; + case NACK: + return 2; + + default: + break; + } + } + return 0; +} + +// int wait_ack(stmisp_device_t *stmisp_device, uint32_t timeout) { +// double elapsed = 0.0; +// const double step = 0.02; // poll step +// struct timeval t0; +// gettimeofday(&t0, NULL); +// while (elapsed < timeout) { +// uint8_t b; +// int r = stmisp_device->recv(&b, 1, 0); +// if (r < 0) return -1; +// if (r == 0) { +// // nothing +// // printf("stmisp: No ACK (timeout)\n"); +// } else { +// if (b == ACK) return 1; +// if (b == NACK) return 2; +// // else ignore and continue +// } +// struct timeval t1; +// gettimeofday(&t1, NULL); +// elapsed = (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1e6; +// } +// return 0; // timeout +// } + +int send_cmd_wait(stmisp_device_t *stmisp_device, uint8_t cmd, uint32_t timeout) +{ + uint8_t pkt[2]; + pkt[0] = cmd; pkt[1] = cmd ^ 0xFF; + tcflush(uart_fd, TCIOFLUSH); + stmisp_device->send(pkt, 2, 1000); + uint8_t ack = wait_ack(stmisp_device, timeout); + + switch(ack) + { + case 1: + printf("stmisp: ACK to cmd 0x%02x\n", cmd); + return 1; + case 2: + printf("stmisp: NACK to cmd 0x%02x\n", cmd); + return 2; + default: + break; + } + printf("stmisp: No ACK to cmd 0x%02x (timeout)\n", cmd); + return 0; +} + +int send_sync(stmisp_device_t *stmisp_device, uint32_t retries) +{ + for(int i = 0; i < retries; i++) + { + uint8_t sync = SYNC_BYTE; + stmisp_device->send(&sync, 1, 1000); + if(wait_ack(stmisp_device, 1000) == 1) + { + return 1; + } + } + return 0; +} + +int cmd_get(stmisp_device_t *stmisp_device) +{ + uint8_t ack = send_cmd_wait(stmisp_device, GET_CMD, 2000); + if(ack == 1) + { + stmisp_device->cmd_count = 0; + + uint8_t size = stmisp_device->recv(&stmisp_device->cmd_count, 1, 1000); + size = stmisp_device->recv(&stmisp_device->version, 1, 1000); + printf("stmisp: version: %x cmd_count %d\n", stmisp_device->version, stmisp_device->cmd_count); + if(stmisp_device->cmd_count > 0 && size > 0) + { + size = stmisp_device->recv(stmisp_device->cmd_data, stmisp_device->cmd_count, 1000); + + for(int i = 0; i < stmisp_device->cmd_count; i++) + { + printf(" %0x", stmisp_device->cmd_data[i]); + } + printf("\n"); + if(wait_ack(stmisp_device, 1000) == 1){ + return 1; + } else { + printf("stmisp: No ACK to cmd 0x%02x (timeout)\n", GET_CMD); + return 0; + } + } + } + + return 0; +} + +int cmd_getid(stmisp_device_t *stmisp_device) +{ + uint8_t ack = send_cmd_wait(stmisp_device, GETID_CMD, 1000); + + if(ack == 1) + { + uint8_t size = stmisp_device->recv(&stmisp_device->num, 1, 1000); + size = stmisp_device->recv(&stmisp_device->pid, 2, 1000); + if(size == 2) + { + if(wait_ack(stmisp_device, 1000) == 1) + { + return 1; + } + } + } + return 0; +} + +int cmd_extended_erase_mass(stmisp_device_t *stmisp_device) +{ + uint8_t ack = send_cmd_wait(stmisp_device, ERASE_CMD, 1000); + if(ack == 1) + { + uint8_t payload[3]; + payload[0] = 0xFF; payload[1] = 0xFF; payload[2] = xor_checksum(payload, 2); + stmisp_device->send(&payload, 3, 1000); + if(wait_ack(stmisp_device, 60000) == 1) + { + return 1; + } + } + return 0; +} + +int cmd_write_unprotect(stmisp_device_t *stmisp_device) +{ + uint8_t ack = send_cmd_wait(stmisp_device, WRITE_UN_CMD, 1000); + if(ack == 1) + { + if(wait_ack(stmisp_device, 1000) == 1) + { + return 1; + } + } + return 0; +} + +int cmd_read_protect(stmisp_device_t *stmisp_device) +{ + uint8_t ack = send_cmd_wait(stmisp_device, READ_UN_CMD, 1000); + if(ack == 1) + { + if(wait_ack(stmisp_device, 1000) == 1) + { + return 1; + } + } + return 0; +} + +int cmd_write_memory(stmisp_device_t *stmisp_device, uint32_t addr, const uint8_t *data, size_t len, bool verify) +{ + size_t idx = 0; + while(idx < len) + { + size_t chunk = (len - idx) > 256 ? 256 : (len - idx); + + uint8_t ack = send_cmd_wait(stmisp_device, WRITE_CMD, 1000); + if(ack == 1) + { + uint32_t a = addr + (uint32_t)idx; + uint8_t addrb[4] = { (uint8_t)(a >> 24), (uint8_t)(a >> 16), (uint8_t)(a >> 8), (uint8_t)(a >> 0) }; + uint8_t cs_addr = xor_checksum(addrb, 4); + uint8_t pkt[5]; memcpy(pkt, addrb, 4); pkt[4] = cs_addr; + + stmisp_device->send(pkt, 5, 1000); + + if(wait_ack(stmisp_device, 1000) != 1) return 0; + + uint8_t nfield = (uint8_t)(chunk - 1); + + uint8_t cs = nfield; + for (size_t i = 0; i < chunk; ++i) cs ^= data[idx + i]; + + stmisp_device->send(&nfield, 1, 1000); + stmisp_device->send((void *)&data[idx], chunk, 1000); + stmisp_device->send(&cs, 1, 1000); + + if(wait_ack(stmisp_device, 5000) != 1) return 0; + //是否需要校验写入的数据块 + if (verify) + { + + } + idx += chunk; + } + } + return 1; +} \ No newline at end of file diff --git a/app/drivers/sertrf/protocol/stmisp.h b/app/drivers/sertrf/protocol/stmisp.h new file mode 100644 index 0000000..d61dde8 --- /dev/null +++ b/app/drivers/sertrf/protocol/stmisp.h @@ -0,0 +1,117 @@ +#ifndef STMISP_H +#define STMISP_H + +#include +#include +#include +#include +#include +#include + +#define ACK 0x79 +#define NACK 0x1F +#define SYNC_BYTE 0x7F + +#define GET_CMD 0x00 +#define GETID_CMD 0x02 +#define ERASE_CMD 0x44 +#define WRITE_UN_CMD 0x73 +#define READ_UN_CMD 0x92 + +#define WRITE_CMD 0x31 +typedef struct +{ + uint8_t version; //目标buildroot版本 + uint8_t cmd_count; //支持命令数量 + uint8_t cmd_data[64]; //所支持的命令 + uint16_t pid; //产品ID + uint8_t num; + + int (*send)(void* data, uint16_t len, int timeout); // 发送数据 + int (*recv)(void* data, uint16_t len, int timeout); // 接收数据 + int (*get_length )(void); // 获取数据长度 + + uint8_t flag; //启动标志位 +}stmisp_device_t; + +/** + * @brief 计算校验和 + */ +uint8_t xor_checksum(const uint8_t *buf, size_t len); + +/** + * @brief 初始化stmisp + */ +int stmisp_init(stmisp_device_t *stmisp_device, int (*send)(void* data, uint16_t len, int timeout), int (*recv)(void* data, uint16_t len, int timeout), int (*get_length )(void)); + +/** + * @brief isp应答信号 + */ +int wait_ack(stmisp_device_t *stmisp_device, uint32_t timeout); + +/** + * @brief isp发送命令 + */ +int send_cmd_wait(stmisp_device_t *stmisp_device, uint8_t cmd, uint32_t timeout); + +/** + * @brief isp发送同步信号 + */ +int send_sync(stmisp_device_t *stmisp_device, uint32_t retries); + +/** + * @brief isp实现GET命令获取 + */ +int cmd_get(stmisp_device_t *stmisp_device); + +/** + * @brief isp获取ID + */ +int cmd_getid(stmisp_device_t *stmisp_device); + +/** + * @brief isp设置写保护 + */ + +int cmd_write_protect(stmisp_device_t *stmisp_device); +/** + * @brief isp解除写保护 + */ + +int cmd_write_unprotect(stmisp_device_t *stmisp_device); + +/** + * @brief isp设置读保护 + */ +int cmd_read_protect(stmisp_device_t *stmisp_device); + +/** + * @brief isp解除读保护 + */ +int cmd_read_unprotect(stmisp_device_t *stmisp_device); + +/** + * @brief isp进行全擦除 + */ +int cmd_extended_erase_mass(stmisp_device_t *stmisp_device); + +/** + * @brief isp进行指定扇区擦除 + */ +int cmd_erase_sector(stmisp_device_t *stmisp_device, uint32_t sector, uint32_t count); + +/** + * @brief isp进行指定扇区读取 + */ +int cmd_read_memory(stmisp_device_t *stmisp_device, uint32_t addr, uint32_t length, uint8_t *outbuf); + +/** + * @brief isp进行指定扇区写入 + */ +int cmd_write_memory(stmisp_device_t *stmisp_device, uint32_t addr, const uint8_t *data, size_t len, bool verify); + + +int stmisp_send(void* data, uint16_t len, int timeout); +int stmisp_recv(void* data, uint16_t len, int timeout); +int stmisp_get_length(void); +#endif \ No newline at end of file diff --git a/app/drivers/sertrf/sertrf.c b/app/drivers/sertrf/sertrf.c index 120b7bc..82e0e8d 100644 --- a/app/drivers/sertrf/sertrf.c +++ b/app/drivers/sertrf/sertrf.c @@ -20,6 +20,8 @@ void sertrf_init(void) // 协议初始化 sertrf.resend_read_mutex = xSemaphoreCreateMutex(); resend_init(&sertrf.resend_device, resend_send, resend_recv, resend_get_length,resend_user_parse); + // stmisp协议初始化 + stmisp_init(&sertrf.stmisp_device,stmisp_send,stmisp_recv,stmisp_get_length); //OAT信息获取 get_partition_status(&sertrf.otau); //线程启动 @@ -62,7 +64,8 @@ void embedded_thread(void* arg) { uint8_t data[embedded_size ]; // data[embedded_size] = '\0'; - embedded_device_read(&sertrf.device, data, embedded_size,0); + if(!sertrf.stmisp_device.flag) + embedded_device_read(&sertrf.device, data, embedded_size,0); Protocol_buf_decode(data, embedded_size); // SYS_LOG_INF("data : %s", data); @@ -86,7 +89,8 @@ void pc_thread(void* arg) uint8_t data[pc_size]; pc_device_read(&sertrf.device, data, pc_size); // SYS_LOG_INF("data : %s", data); - embedded_device_write(&sertrf.device, data, pc_size); + if(!sertrf.stmisp_device.flag) + embedded_device_write(&sertrf.device, data, pc_size); } // printf_chill_time(10,1000); @@ -354,4 +358,25 @@ void resend_user_parse(void *resend_device) } break; } +} + + +int stmisp_send(void* data, uint16_t len, int timeout) +{ + return embedded_device_write(&sertrf.device, data, len); +} +int stmisp_recv(void* data, uint16_t len, int timeout) +{ + uint32_t time_start = os_get_sys_time(); + int size = 0; + while(os_get_sys_time() - time_start < timeout) + { + size = embedded_device_read(&sertrf.device, data, len, 0); + os_thread_sleep(1); + } + return size; +} +int stmisp_get_length(void) +{ + return embedded_device_get_rx_length(&sertrf.device); } \ No newline at end of file diff --git a/app/drivers/sertrf/sertrf.h b/app/drivers/sertrf/sertrf.h index 5656716..64af36d 100644 --- a/app/drivers/sertrf/sertrf.h +++ b/app/drivers/sertrf/sertrf.h @@ -5,6 +5,7 @@ #include "key.h" #include "protocol/p_protocol.h" #include "protocol/resend_protl.h" +#include "protocol/stmisp.h" #include "ota_u.h" #include "../../config/app_config.h" @@ -17,9 +18,13 @@ typedef struct os_thread_t app_thread; ota_u_t otau; + //自定义协议 resend_device_t resend_device; SemaphoreHandle_t resend_read_mutex; + //STMISP协议 + stmisp_device_t stmisp_device; + }sertrf_t; typedef struct