209 lines
5.9 KiB
C
209 lines
5.9 KiB
C
/*
|
||
VT13接收机
|
||
Example:
|
||
|
||
VT13_Init(&vt13);
|
||
|
||
while (1) {
|
||
VT13_StartDmaRecv(&vt13);
|
||
if (VT13_WaitDmaCplt(20)) {
|
||
if (VT13_Verify(&vt13)) {
|
||
VT13_ParseData(&vt13);
|
||
} else {
|
||
VT13_Offline(&vt13);
|
||
}
|
||
} else {
|
||
VT13_Offline(&vt13);
|
||
}
|
||
}
|
||
*/
|
||
|
||
/* Includes ----------------------------------------------------------------- */
|
||
#include "vt13.h"
|
||
#include "bsp/uart.h"
|
||
#include "bsp/time.h"
|
||
#include "device.h"
|
||
#include "component/crc16.h"
|
||
|
||
#include <string.h>
|
||
#include <stdbool.h>
|
||
|
||
/* USER INCLUDE BEGIN */
|
||
|
||
/* USER INCLUDE END */
|
||
/* Private define ----------------------------------------------------------- */
|
||
#define VT13_CH_VALUE_MIN (364u)
|
||
#define VT13_CH_VALUE_MID (1024u)
|
||
#define VT13_CH_VALUE_MAX (1684u)
|
||
|
||
#define VT13_FRAMEHEADER1 0xA9
|
||
#define VT13_FRAMEHEADER2 0x53
|
||
/* USER DEFINE BEGIN */
|
||
|
||
/* USER DEFINE END */
|
||
|
||
/* Private macro ------------------------------------------------------------ */
|
||
/* Private typedef ---------------------------------------------------------- */
|
||
/* Private variables -------------------------------------------------------- */
|
||
|
||
static osThreadId_t thread_alert;
|
||
static bool inited = false;
|
||
|
||
/* Private function -------------------------------------------------------- */
|
||
static void VT13_RxCpltCallback(void) {
|
||
osThreadFlagsSet(thread_alert, SIGNAL_VT13_RAW_REDY);
|
||
}
|
||
|
||
static bool VT13_Verify(VT13_t *vt13){
|
||
if (vt13 == NULL) return DEVICE_ERR_NULL;
|
||
|
||
if (vt13->raw_data.sof_1!=VT13_FRAMEHEADER1) {
|
||
return false;
|
||
}
|
||
if (vt13->raw_data.sof_2!=VT13_FRAMEHEADER2) {
|
||
return false;
|
||
}
|
||
if (!CRC16_Verify((const uint8_t *)&(vt13->raw_data),
|
||
sizeof(VT13_RawData_t))) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
static bool VT13_DataCorrupted(const VT13_t *vt13) {
|
||
if (vt13 == NULL) return DEVICE_ERR_NULL;
|
||
|
||
if ((vt13->raw_data.ch_0 < VT13_CH_VALUE_MIN) ||
|
||
(vt13->raw_data.ch_0 > VT13_CH_VALUE_MAX))
|
||
return DEVICE_ERR;
|
||
|
||
if ((vt13->raw_data.ch_1 < VT13_CH_VALUE_MIN) ||
|
||
(vt13->raw_data.ch_1 > VT13_CH_VALUE_MAX))
|
||
return DEVICE_ERR;
|
||
|
||
if ((vt13->raw_data.ch_2 < VT13_CH_VALUE_MIN) ||
|
||
(vt13->raw_data.ch_2 > VT13_CH_VALUE_MAX))
|
||
return DEVICE_ERR;
|
||
|
||
if ((vt13->raw_data.ch_3 < VT13_CH_VALUE_MIN) ||
|
||
(vt13->raw_data.ch_3 > VT13_CH_VALUE_MAX))
|
||
return DEVICE_ERR;
|
||
|
||
if ((vt13->raw_data.wheel < VT13_CH_VALUE_MIN) ||
|
||
(vt13->raw_data.wheel > VT13_CH_VALUE_MAX))
|
||
return DEVICE_ERR;
|
||
|
||
if (vt13->raw_data.mode_sw == 0) return DEVICE_ERR;
|
||
|
||
if (vt13->raw_data.pause == 0) return DEVICE_ERR;
|
||
|
||
if (vt13->raw_data.fn_1 == 0) return DEVICE_ERR;
|
||
|
||
if (vt13->raw_data.fn_2 == 0) return DEVICE_ERR;
|
||
|
||
return DEVICE_OK;
|
||
}
|
||
|
||
/* Exported functions ------------------------------------------------------- */
|
||
int8_t VT13_Init(VT13_t *vt13) {
|
||
if (vt13 == NULL) return DEVICE_ERR_NULL;
|
||
if (inited) return DEVICE_ERR_INITED;
|
||
if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL;
|
||
|
||
BSP_UART_RegisterCallback(BSP_UART_AT9S_PRO, BSP_UART_RX_CPLT_CB,
|
||
VT13_RxCpltCallback);
|
||
|
||
inited = true;
|
||
return DEVICE_OK;
|
||
}
|
||
|
||
int8_t VT13_Restart(void) {
|
||
__HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_AT9S_PRO));
|
||
__HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_AT9S_PRO));
|
||
return DEVICE_OK;
|
||
}
|
||
|
||
int8_t VT13_StartDmaRecv(VT13_t *vt13) {
|
||
if (HAL_UART_Receive_DMA(BSP_UART_GetHandle(BSP_UART_AT9S_PRO),
|
||
(uint8_t *)&(vt13->raw_data),
|
||
sizeof(vt13->raw_data)) == HAL_OK)
|
||
return DEVICE_OK;
|
||
return DEVICE_ERR;
|
||
}
|
||
|
||
bool VT13_WaitDmaCplt(uint32_t timeout) {
|
||
return (osThreadFlagsWait(SIGNAL_VT13_RAW_REDY, osFlagsWaitAll, timeout) ==
|
||
SIGNAL_VT13_RAW_REDY);
|
||
}
|
||
|
||
int8_t VT13_ParseData(VT13_t *vt13){
|
||
if (vt13 == NULL) return DEVICE_ERR_NULL;
|
||
|
||
if (!VT13_Verify(vt13)) {
|
||
return DEVICE_ERR;
|
||
}
|
||
if (VT13_DataCorrupted(vt13)) {
|
||
return DEVICE_ERR;
|
||
}
|
||
|
||
vt13->header.online = true;
|
||
vt13->header.last_online_time = BSP_TIME_Get_us();
|
||
|
||
memset(&(vt13->data), 0, sizeof(vt13->data));
|
||
|
||
float full_range = (float)(VT13_CH_VALUE_MAX - VT13_CH_VALUE_MIN);
|
||
|
||
// 解析摇杆数据
|
||
vt13->data.ch_r_x = 2.0f * ((float)vt13->raw_data.ch_0 - VT13_CH_VALUE_MID) / full_range;
|
||
vt13->data.ch_r_y = 2.0f * ((float)vt13->raw_data.ch_1 - VT13_CH_VALUE_MID) / full_range;
|
||
vt13->data.ch_l_x = 2.0f * ((float)vt13->raw_data.ch_2 - VT13_CH_VALUE_MID) / full_range;
|
||
vt13->data.ch_l_y = 2.0f * ((float)vt13->raw_data.ch_3 - VT13_CH_VALUE_MID) / full_range;
|
||
|
||
// 解析拨杆位置
|
||
vt13->data.sw_l = (VT13_SwitchPos_t)vt13->raw_data.fn_1;
|
||
vt13->data.sw_r = (VT13_SwitchPos_t)vt13->raw_data.fn_2;
|
||
vt13->data.sw_mode = (VT13_SwitchPos_t)vt13->raw_data.mode_sw;
|
||
vt13->data.sw_pause = (VT13_SwitchPos_t)vt13->raw_data.pause;
|
||
vt13->data.sw_trig = (VT13_SwitchPos_t)vt13->raw_data.trigger;
|
||
|
||
// 解析鼠标数据
|
||
vt13->data.mouse.x = vt13->raw_data.mouse_x;
|
||
vt13->data.mouse.y = vt13->raw_data.mouse_y;
|
||
vt13->data.mouse.z = vt13->raw_data.mouse_z;
|
||
|
||
vt13->data.mouse.l_click = vt13->raw_data.mouse_left;
|
||
vt13->data.mouse.m_click = vt13->raw_data.mouse_middle;
|
||
vt13->data.mouse.r_click = vt13->raw_data.mouse_right;
|
||
|
||
// 解析键盘按键 - 使用union简化代码
|
||
uint16_t key_value = vt13->raw_data.key;
|
||
|
||
// 解析键盘位映射(W-B键,位0-15)
|
||
for (int i = VT13_KEY_W; i <= VT13_KEY_B; i++) {
|
||
vt13->data.keyboard.key[i] = (key_value & (1 << i)) != 0;
|
||
}
|
||
|
||
// 解析鼠标点击
|
||
vt13->data.keyboard.key[VT13_L_CLICK] = vt13->data.mouse.l_click;
|
||
vt13->data.keyboard.key[VT13_R_CLICK] = vt13->data.mouse.r_click;
|
||
|
||
// 解析第五通道
|
||
vt13->data.ch_res = 2.0f * ((float)vt13->raw_data.wheel - VT13_CH_VALUE_MID) / full_range;
|
||
|
||
return DEVICE_OK;
|
||
}
|
||
|
||
int8_t VT13_Offline(VT13_t *vt13){
|
||
if (vt13 == NULL) return DEVICE_ERR_NULL;
|
||
|
||
vt13->header.online = false;
|
||
memset(&(vt13->data), 0, sizeof(vt13->data));
|
||
|
||
return DEVICE_OK;
|
||
}
|
||
|
||
/* USER FUNCTION BEGIN */
|
||
|
||
/* USER FUNCTION END */
|