#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

#define GO_CMD 0x21
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;                   //启动标志位
    
    uint32_t adder_offset;          //地址偏移
}stmisp_device_t;

typedef struct 
{
    uint32_t stmisp_file_size;
}stmisp_parm_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实现go命令
 */
int cmd_go(stmisp_device_t *stmisp_device, uint32_t adder);

/**
 * @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);


/**
 * @brief 运行示例
 */
void Examples_run(void);

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 