#pragma once #ifdef __cplusplus extern "C" { #endif /* Includes ----------------------------------------------------------------- */ #include "bsp/can.h" #include "device/device.h" #include #include /* USER INCLUDE BEGIN */ /* USER INCLUDE END */ /* USER DEFINE BEGIN */ /* USER DEFINE END */ /* Exported constants ------------------------------------------------------- */ // CAN ID 定义 #define RC_CAN_DR16_JOYSTICK_ID 0x300 // 遥杆数据 #define RC_CAN_DR16_SWITCH_ID 0x301 // 拨杆数据 #define RC_CAN_DR16_MOUSE_ID 0x302 // 鼠标数据 #define RC_CAN_DR16_KEYBOARD_ID 0x303 // 键盘数据 #define RC_CAN_DR16_STATUS_ID 0x304 // 状态数据 /* Exported macro ----------------------------------------------------------- */ /* Exported types ----------------------------------------------------------- */ typedef enum { RC_CAN_SW_ERR = 0, RC_CAN_SW_UP = 1, RC_CAN_SW_MID = 3, RC_CAN_SW_DOWN = 2, } RC_CAN_SW_t; // 遥杆数据包 (CAN ID: 0x300) typedef struct __packed { int16_t ch_l_x; // 左侧摇杆X轴 (-1000~1000) int16_t ch_l_y; // 左侧摇杆Y轴 (-1000~1000) int16_t ch_r_x; // 右侧摇杆X轴 (-1000~1000) int16_t ch_r_y; // 右侧摇杆Y轴 (-1000~1000) } RC_CAN_JoystickData_t; // 拨杆数据包 (CAN ID: 0x301) typedef struct __packed { uint8_t sw_l; // 左拨杆状态 uint8_t sw_r; // 右拨杆状态 int16_t ch_res; // 第五通道 (-1000~1000) uint32_t reserved; // 保留字节 } RC_CAN_SwitchData_t; // 鼠标数据包 (CAN ID: 0x302) typedef struct __packed { int16_t mouse_x; // 鼠标X轴移动 int16_t mouse_y; // 鼠标Y轴移动 int16_t mouse_z; // 鼠标Z轴(滚轮) uint8_t mouse_l; // 鼠标左键 uint8_t mouse_r; // 鼠标右键 } RC_CAN_MouseData_t; // 键盘数据包 (CAN ID: 0x303) typedef struct __packed { uint16_t key_value; // 键盘按键位映射 uint8_t reserved[6]; // 保留字节 } RC_CAN_KeyboardData_t; // 状态数据包 (CAN ID: 0x304) typedef struct __packed { uint8_t online; // 在线状态 (1:在线, 0:离线) uint8_t data_valid; // 数据有效性 (1:有效, 0:无效) uint32_t timestamp; // 时间戳(ms) uint16_t reserved; // 保留字节 } RC_CAN_StatusData_t; // 工作模式枚举 typedef enum { RC_CAN_MODE_SENDER, // 发送模式(连接DR16的板子) RC_CAN_MODE_RECEIVER, // 接收模式(其他板子) RC_CAN_MODE_BOTH // 双向模式(可发送也可接收) } RC_CAN_Mode_t; // 接收数据状态 typedef struct { bool joystick_updated; bool switch_updated; bool mouse_updated; bool keyboard_updated; bool status_updated; uint32_t last_joystick_time; uint32_t last_switch_time; uint32_t last_mouse_time; uint32_t last_keyboard_time; uint32_t last_status_time; } RC_CAN_RxStatus_t; // RC_CAN 参数结构 typedef struct { BSP_CAN_t can; // 使用的CAN总线 RC_CAN_Mode_t mode; // 工作模式 bool enabled; // 是否启用发送(仅发送模式有效) uint32_t send_period; // 发送周期(ms) uint32_t timeout_ms; // 接收超时时间(ms) } RC_CAN_Param_t; // RC_CAN 主结构 typedef struct { RC_CAN_Param_t param; DEVICE_Header_t header; // 数据包 RC_CAN_JoystickData_t joystick_data; RC_CAN_SwitchData_t switch_data; RC_CAN_MouseData_t mouse_data; RC_CAN_KeyboardData_t keyboard_data; RC_CAN_StatusData_t status_data; // 接收状态(仅接收模式有效) RC_CAN_RxStatus_t rx_status; // 状态信息 uint32_t last_send_time; bool initialized; } RC_CAN_t; /* USER STRUCT BEGIN */ /* USER STRUCT END */ /* Exported functions prototypes -------------------------------------------- */ /** * @brief 初始化RC CAN发送模块 * @param rc_can RC_CAN结构体指针 * @param param 初始化参数 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_Init(RC_CAN_t *rc_can, RC_CAN_Param_t *param); /** * @brief 更新并发送DR16数据到CAN总线 * @param rc_can RC_CAN结构体指针 * @param dr16 DR16数据结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendData(RC_CAN_t *rc_can, const void *dr16); /** * @brief 发送遥杆数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendJoystickData(RC_CAN_t *rc_can); /** * @brief 发送拨杆数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendSwitchData(RC_CAN_t *rc_can); /** * @brief 发送鼠标数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendMouseData(RC_CAN_t *rc_can); /** * @brief 发送键盘数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendKeyboardData(RC_CAN_t *rc_can); /** * @brief 发送状态数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SendStatusData(RC_CAN_t *rc_can); /** * @brief 设置发送使能状态 * @param rc_can RC_CAN结构体指针 * @param enabled 使能状态 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_SetEnabled(RC_CAN_t *rc_can, bool enabled); /** * @brief 获取在线状态 * @param rc_can RC_CAN结构体指针 * @return true 在线,false 离线 */ bool RC_CAN_IsOnline(const RC_CAN_t *rc_can); /** * @brief 接收并更新CAN数据 * @param rc_can RC_CAN结构体指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_Update(RC_CAN_t *rc_can); /** * @brief 获取遥杆数据(接收模式) * @param rc_can RC_CAN结构体指针 * @param ch_l_x 左摇杆X轴输出指针 * @param ch_l_y 左摇杆Y轴输出指针 * @param ch_r_x 右摇杆X轴输出指针 * @param ch_r_y 右摇杆Y轴输出指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_GetJoystickData(const RC_CAN_t *rc_can, float *ch_l_x, float *ch_l_y, float *ch_r_x, float *ch_r_y); /** * @brief 获取拨杆数据(接收模式) * @param rc_can RC_CAN结构体指针 * @param sw_l 左拨杆状态输出指针 * @param sw_r 右拨杆状态输出指针 * @param ch_res 第五通道输出指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_GetSwitchData(const RC_CAN_t *rc_can, uint8_t *sw_l, uint8_t *sw_r, float *ch_res); /** * @brief 获取鼠标数据(接收模式) * @param rc_can RC_CAN结构体指针 * @param mouse_x 鼠标X轴输出指针 * @param mouse_y 鼠标Y轴输出指针 * @param mouse_z 鼠标Z轴输出指针 * @param mouse_l 鼠标左键输出指针 * @param mouse_r 鼠标右键输出指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_GetMouseData(const RC_CAN_t *rc_can, int16_t *mouse_x, int16_t *mouse_y, int16_t *mouse_z, bool *mouse_l, bool *mouse_r); /** * @brief 获取键盘数据(接收模式) * @param rc_can RC_CAN结构体指针 * @param key_value 键盘按键位映射输出指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_GetKeyboardData(const RC_CAN_t *rc_can, uint16_t *key_value); /** * @brief 获取远程DR16状态(接收模式) * @param rc_can RC_CAN结构体指针 * @param remote_online 远程DR16在线状态输出指针 * @param data_valid 数据有效性输出指针 * @param timestamp 时间戳输出指针 * @return DEVICE_OK 成功,其他值失败 */ int8_t RC_CAN_GetRemoteStatus(const RC_CAN_t *rc_can, bool *remote_online, bool *data_valid, uint32_t *timestamp); /** * @brief 检查数据是否有更新(接收模式) * @param rc_can RC_CAN结构体指针 * @param data_type 数据类型 (0:遥杆, 1:拨杆, 2:鼠标, 3:键盘, 4:状态) * @return true 有更新,false 无更新 */ bool RC_CAN_IsDataUpdated(RC_CAN_t *rc_can, uint8_t data_type); /** * @brief 检查数据是否超时(接收模式) * @param rc_can RC_CAN结构体指针 * @return true 超时,false 未超时 */ bool RC_CAN_IsDataTimeout(const RC_CAN_t *rc_can); /* USER FUNCTION BEGIN */ /* USER FUNCTION END */ #ifdef __cplusplus } #endif