添加stmisp协议
This commit is contained in:
@@ -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")
|
||||
|
||||
232
app/drivers/sertrf/protocol/stmisp.c
Normal file
232
app/drivers/sertrf/protocol/stmisp.c
Normal file
@@ -0,0 +1,232 @@
|
||||
#include "stmisp.h"
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
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;
|
||||
}
|
||||
117
app/drivers/sertrf/protocol/stmisp.h
Normal file
117
app/drivers/sertrf/protocol/stmisp.h
Normal file
@@ -0,0 +1,117 @@
|
||||
#ifndef STMISP_H
|
||||
#define STMISP_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <termios.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#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
|
||||
@@ -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);
|
||||
|
||||
@@ -355,3 +359,24 @@ 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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user