rm_balance/User/device/rc_can.h
2025-09-30 19:12:10 +08:00

300 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ----------------------------------------------------------------- */
#include "bsp/can.h"
#include "device/device.h"
#include <stdint.h>
#include <stdbool.h>
/* USER INCLUDE BEGIN */
/* USER INCLUDE END */
/* USER DEFINE BEGIN */
/* USER DEFINE END */
/* Exported constants ------------------------------------------------------- */
#define RC_CAN_DR16_JOY_ID 0x350 // 遥杆数据
#define RC_CAN_DR16_SWITCH_ID 0x351 // 拨杆数据
#define RC_CAN_DR16_MOUSE_ID 0x352 // 鼠标数据
#define RC_CAN_DR16_KEYBOARD_ID 0x353 // 键盘数据
#define RC_CAN_DR16_STATUS_ID 0x354 // 状态数据
/* 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;
typedef enum {
DR16_KEY_W = 0,
DR16_KEY_S,
DR16_KEY_A,
DR16_KEY_D,
DR16_KEY_SHIFT,
DR16_KEY_CTRL,
DR16_KEY_Q,
DR16_KEY_E,
DR16_KEY_R,
DR16_KEY_F,
DR16_KEY_G,
DR16_KEY_Z,
DR16_KEY_X,
DR16_KEY_C,
DR16_KEY_V,
DR16_KEY_B,
DR16_KEY_NUM,
} DR16_Key_t;
// 遥杆数据包 (CAN ID: 0x300)
typedef struct {
int16_t ch_l_x;
int16_t ch_l_y;
int16_t ch_r_x;
int16_t ch_r_y;
} RC_CAN_JoyData_t;
// 拨杆数据包 (CAN ID: 0x301)
typedef struct __packed {
RC_CAN_SW_t sw_l; // 左拨杆状态
RC_CAN_SW_t sw_r; // 右拨杆状态
int16_t ch_res; // 第五通道 (-1000~1000)
} 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轴(滚轮)
bool mouse_l; // 鼠标左键
bool mouse_r; // 鼠标右键
} RC_CAN_MouseData_t;
// 键盘数据包 (CAN ID: 0x303)
typedef union {
uint16_t key_value; // 键盘按键位映射
DR16_Key_t keys[16]; // 按键数组
} 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