protocolExpose.h 7.4 KB
#ifndef __PROTOCOLEX_EXPOSE_H_
#define __PROTOCOLEX_EXPOSE_H_

#include "stdint.h"
#include <stdbool.h>

#include "protocolExpose_Config.h"

#include "protocolCommon.h"

/*

 ,---.  ,--.,--.          ,------.                 ,--.                      ,--.
'   .-' |  |`--',--,--,--.|  .--. ',--.--. ,---. ,-'  '-. ,---.  ,---. ,---. |  |
`.  `-. |  |,--.|        ||  '--' ||  .--'| .-. |'-.  .-'| .-. || .--'| .-. ||  |
.-'    ||  ||  ||  |  |  ||  | --' |  |   ' '-' '  |  |  ' '-' '\ `--.' '-' '|  |
`-----' `--'`--'`--`--`--'`--'     `--'    `---'   `--'   `---'  `---' `---' `--'

SlimProtocol - Simple frame-based communication protocol
======================ProtocolExpose.h======================

WARNING: This Lib used by More than One Project , Please check compatibility before modifying

*/
// /*==================== PreDefine ===================*/

// typedef enum {
//     PROTOCOLEX_SUPPORT_DEVICE_NOTDEVICE = 0,
//     PROTOCOLEX_SUPPORT_DEVICE_A12F4_3AXIS_HOLDER = 1,
// }PROTOCOLEX_SUPPORT_DEVICE;

#define PROTOCOLEX_USING_DEVICE PROTOCOLEXCONFIG_USING_DEVICE
#define PROTOCOLEX_C1_ENABLE PROTOCOLEXCONFIG_C1_ENABEL
#define PROTOCOLEX_PARSE_ENABLE PROTOCOLEXCONFIG_PARSE_ENABLE

/*==================== Settings ====================*/

// Device Special
// Only can be select from PROTOCOLEX_SUPPORT_DEVICE

// ProtocolEX C1 Funtion Enable
#if PROTOCOLEX_USING_DEVICE == PROTOCOLEX_SUPPORT_DEVICE_A12F4_3AXIS_HOLDER
#define PROTOCOLEX_C1_ENABLE PROTOCOLEX_SETTING_TRUE
#else
#define PROTOCOLEX_C1_ENABLE PROTOCOLEXCONFIG_C1_ENABEL
#endif

/*================== Explanation ===================*/

/*
    枚举缩写解析
    F - Frame 帧 用来表示该枚举/数据与帧格式有关
    P - Parse 解析 用来表示该枚举/数据与解析过程有关
    M - Make  构造 用来表示该枚举/数据与帧构造过程有关

*/

/*==================Enum/Mark Define==================*/

/*__________Enum/Mark Of The Frame__________*/

typedef enum
{
    // Funtion Group
    PROTOCOLEX_F_TYPE_0X11 = 0x1, // 修改Pitch轴角度
    PROTOCOLEX_F_TYPE_0X12,       // 修改Roll轴角度
    PROTOCOLEX_F_TYPE_0X13,       // 修改Yaw轴角度

    // Control Group
    PROTOCOLEX_F_TYPE_0X51, // 云台电机使能
    PROTOCOLEX_F_TYPE_0X52, // 云台电机失能

    // Debug Group
    PROTOCOLEX_F_TYPE_0XAA, // 电机参数调整PID组
} PROTOCOLEX_F_TYPE;

typedef enum
{
    // Funtion Group
    PROTOCOLEX_F_TYPE_DATA_0X11 = 0x11, // 修改Pitch轴角度-协议内容
    PROTOCOLEX_F_TYPE_DATA_0X12 = 0x12, // 修改Roll轴角度-协议内容
    PROTOCOLEX_F_TYPE_DATA_0X13 = 0x13, // 修改Yaw轴角度-协议内容


    // Control Group
    PROTOCOLEX_F_TYPE_DATA_0X51 = 0x51, // 云台电机使能
    PROTOCOLEX_F_TYPE_DATA_0X52 = 0x52, // 云台电机失能
    
    // Debug Group
    PROTOCOLEX_F_TYPE_DATA_0XAA = 0xAA, // 电机参数调整PID组
} PROTOCOLEX_F_TYPE_DATA;

/*__________Enum/Mark Of The Parse__________*/

typedef enum
{
    PROTOCOLEX_P_STATUS_OK = 0,           // 帧解析成功
    PROTOCOLEX_P_STATUS_NOFRAME = -1,     // 没识别到帧
    PROTOCOLEX_P_STATUS_VERFAIL = -2,     // 校验失败
    PROTOCOLEX_P_STATUS_UNKNOWFRAME = -3, // 帧类型未知
} PROTOCOLEX_P_STATUS;

/*__________Enum/Mark Of The Make__________*/

typedef enum
{
    PROTOCOLEX_M_STATUS_OK = 0,
    PROTOCOLEX_M_STATUS_BUFFLENERR,
} PROTOCOLEX_M_STATUS;

/*==================DataType Define==================*/

#pragma pack(1) /*指定按1字节对齐*/

typedef struct
{
    uint8_t arg1[4];
    float arg2;
} PayDataEX_T1;

typedef struct
{
    int16_t arg1_1_2;
    uint8_t arg1_3_4[2];
    float arg2;
} PayDataEX_T2;

/**
 * @brief 协议Payload数据结构体,单个结构体为8个字节,覆盖协议的Payload部分
 */
typedef union
{
    // 通用索引
    uint8_t rawdata_8t[8];
    uint32_t rawdata_32t[2];
    // 特定索引
    PayDataEX_T1 paydataT1;
    PayDataEX_T2 paydataT2;
} ProEX_Data;

typedef struct
{
    int8_t error;      // 错误类型
    uint8_t fType;     // 帧类型
    uint8_t sRoute;    // 子路由节点
    uint8_t readPoint; // 最后读取点 - 帧尾索引 - 最多读到255
} ProEX_Parse_Result;

#pragma pack() /*取消强制对齐*/

//_____________________通用数据帧设置 - 除非协议修改否则不能修改_____________________

#define PROTOCOLEX_LEN 14 // 数据帧长度

#define PROTOCOLEX_P_HEAD_0 0 // 帧头0位置
// #define PROTOCOLEX_P_HEAD_1 1 // 帧头1位置

#define PROTOCOLEX_P_ROUTE 1  // 路由位置
#define PROTOCOLEX_P_SROUTE 2 // 路由预留(子路由位置)

#define PROTOCOLEX_P_DATA 4 // 数据起始位置

#define PROTOCOLEX_P_VERIFY_SW 3 // 校验预留位(校验开关)
#define PROTOCOLEX_P_VERIFY 12   // 校验位位置

#define PROTOCOLEX_P_END 13 // 帧尾位置

#define PROTOCOLEX_CONTENT_HEAD_0 0xFA //  帧头数据0

// #define PROTOCOLEX_CONTENT_VER_OFF  0x00 //关闭校验的内容
// #define PROTOCOLEX_CONTENT_VER_ON   0x01 //开启校验的内容

#define PROTOCOLEX_CONTENT_END 0xED //  帧尾数据0

#define PROTOCOLEX_CONTENT_RESERVE 0x00 //  保留数据

//_____________________协议接收结果区_____________________
#if PROTOCOLEX_PARSE_ENABLE == PROTOCOLEX_SETTING_TRUE

// extern ProEX_Data target_axis_data;
// extern ProEX_Data Gen_dataResult;
extern uint32_t frameCnt;
#if PROTOCOLEX_C1_ENABLE == PROTOCOLEX_SETTING_TRUE
extern uint32_t frameCnt_C1;
#endif

#endif
//_____________________数据处理相关_______________________

#define PROTOCOLEX_PROCESS_BUFF 128 // Buffer length, NEED to be a power of 2( 2^x )

typedef struct
{
    uint16_t Wd_Indx;
    uint16_t Rd_Indx;
} RingBuf_Shot;

typedef struct
{
    uint16_t volatile Wd_Indx;
    uint16_t volatile Rd_Indx;
    uint16_t Mask;
    uint8_t *pbuf;
} RingBuf;

/**
 * @brief Init the protocolEX parse Funtion , if need to parse the protocolEX frame , the funtion must be call first
 * @param
 */
void protocolEX_frame_parse_INIT(void);

#if PROTOCOLEX_PARSE_ENABLE == PROTOCOLEX_SETTING_TRUE

#if PROTOCOLEX_USING_DEVICE == PROTOCOLEX_SUPPORT_DEVICE_A12F4_3AXIS_HOLDER
void protocolEX_frame_parse(uint8_t *buff, const uint32_t buff_len);
#else
ProEX_Parse_Result protocolEX_frame_parse(uint8_t *buff, const uint32_t buff_len);
#endif

#if PROTOCOLEX_C1_ENABLE == PROTOCOLEX_SETTING_TRUE
#if PROTOCOLEX_USING_DEVICE == PROTOCOLEX_SUPPORT_DEVICE_A12F4_3AXIS_HOLDER
void protocolEX_frame_parse_C1(uint8_t *buff, const uint32_t buff_len);
#else
ProEX_Parse_Result protocolEX_frame_parse_C1(uint8_t *buff, const uint32_t buff_len);
#endif
#endif

#endif
/**
 * @brief Frame constructor. If you want to use this protocol to send data, you need to use this function to construct the frame.
 * @param frameType PROTOCOLEX_F_TYPE frame type
 * @param buff Output buffer address
 * @param buff_len Output buffer len
 * @param data Data address to be entered , the content of PAYLOAD , uint32[2] , can use ProEX_Data struct
 * @return -1 : the buff too short ; 0 : Success
 */
int protocolEX_frame_make(PROTOCOLEX_F_TYPE frameType, uint8_t *buff, uint16_t buff_len, void const *data);

/**
 * @brief Angle mapping, used for mapping from float to uint16_t, range -180.0f~180.0f
 * @param anglef the angle need to be mapped
 * @return the uint16_t angle
 */
inline int16_t proEX_Util_angleMapping(float anglef);

/**
 * @brief Angle mapping, used for mapping from uint16_t to float, range -32767~32767
 * @param angleU16 the angle need to be mapped
 * @return the float angle
 */
inline float proEX_Util_angleInvMapping(int16_t angleU16);

#endif