215 lines
6.8 KiB
C
215 lines
6.8 KiB
C
/**
|
||
****************************(C) COPYRIGHT 2019 DJI****************************
|
||
* @file remote_control.c/h
|
||
* @brief ?????????????????????????SBUS??<3F><>?<3F><>??????DMA????????CPU
|
||
* ????????????????<3F><>????????????????????<3F><>????????DMA??????
|
||
* ??????????<3F><>???????
|
||
* @note ????????????????<3F><>???????????freeRTOS????
|
||
* @history
|
||
* Version Date Author Modification
|
||
* V1.0.0 Dec-01-2019 RM 1. ???
|
||
*
|
||
@verbatim
|
||
==============================================================================
|
||
|
||
==============================================================================
|
||
@endverbatim
|
||
****************************(C) COPYRIGHT 2019 DJI****************************
|
||
*/
|
||
|
||
#include "remote_control.h"
|
||
|
||
#include "main.h"
|
||
|
||
|
||
extern UART_HandleTypeDef huart3;
|
||
extern DMA_HandleTypeDef hdma_usart3_rx;
|
||
|
||
/**
|
||
* @brief remote control protocol resolution
|
||
* @param[in] sbus_buf: raw data point
|
||
* @param[out] rc_ctrl: remote control data struct point
|
||
* @retval none
|
||
*/
|
||
/**
|
||
* @brief ?????<3F><>?????
|
||
* @param[in] sbus_buf: ??????????
|
||
* @param[out] rc_ctrl: ??????????
|
||
* @retval none
|
||
*/
|
||
static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl);
|
||
|
||
//remote control data
|
||
//????????????
|
||
RC_ctrl_t rc_ctrl;
|
||
|
||
//receive data, 18 bytes one frame, but set 36 bytes
|
||
//????????????18??????????36????????????DMA???????
|
||
static uint8_t sbus_rx_buf[2][SBUS_RX_BUF_NUM];
|
||
|
||
//遥控器掉线检测:记录最后一次成功解析的时间戳(ms)
|
||
static volatile uint32_t rc_last_update_tick = 0;
|
||
|
||
/**
|
||
* @brief remote control init
|
||
* @param[in] none
|
||
* @retval none
|
||
*/
|
||
/**
|
||
* @brief ??????????
|
||
* @param[in] none
|
||
* @retval none
|
||
*/
|
||
void remote_control_init(void)
|
||
{
|
||
RC_init(sbus_rx_buf[0], sbus_rx_buf[1], SBUS_RX_BUF_NUM);
|
||
}
|
||
/**
|
||
* @brief get remote control data point
|
||
* @param[in] none
|
||
* @retval remote control data point
|
||
*/
|
||
/**
|
||
* @brief ???????????????
|
||
* @param[in] none
|
||
* @retval ????????????
|
||
*/
|
||
const RC_ctrl_t *get_remote_control_point(void)
|
||
{
|
||
return &rc_ctrl;
|
||
}
|
||
|
||
|
||
//?????<3F><>?
|
||
void RC_USART3_IRQHandler(void)
|
||
{
|
||
if(huart3.Instance->SR & UART_FLAG_RXNE)//?????????
|
||
{
|
||
__HAL_UART_CLEAR_PEFLAG(&huart3);
|
||
}
|
||
else if(USART3->SR & UART_FLAG_IDLE)
|
||
{
|
||
static uint16_t this_time_rx_len = 0;
|
||
|
||
__HAL_UART_CLEAR_PEFLAG(&huart3);
|
||
|
||
if ((hdma_usart3_rx.Instance->CR & DMA_SxCR_CT) == RESET)
|
||
{
|
||
/* Current memory buffer used is Memory 0 */
|
||
|
||
//disable DMA
|
||
//?<3F><>DMA
|
||
__HAL_DMA_DISABLE(&hdma_usart3_rx);
|
||
|
||
//get receive data length, length = set_data_length - remain_length
|
||
//??????????????,???? = ?څ???? - ?????
|
||
this_time_rx_len = SBUS_RX_BUF_NUM - hdma_usart3_rx.Instance->NDTR;
|
||
|
||
//reset set_data_lenght
|
||
//?????څ???????
|
||
hdma_usart3_rx.Instance->NDTR = SBUS_RX_BUF_NUM;
|
||
|
||
//set memory buffer 1
|
||
//?څ??????1
|
||
hdma_usart3_rx.Instance->CR |= DMA_SxCR_CT;
|
||
|
||
//enable DMA
|
||
//???DMA
|
||
__HAL_DMA_ENABLE(&hdma_usart3_rx);
|
||
|
||
if(this_time_rx_len == RC_FRAME_LENGTH)
|
||
{
|
||
sbus_to_rc(sbus_rx_buf[0], &rc_ctrl);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/* Current memory buffer used is Memory 1 */
|
||
//disable DMA
|
||
//?<3F><>DMA
|
||
__HAL_DMA_DISABLE(&hdma_usart3_rx);
|
||
|
||
//get receive data length, length = set_data_length - remain_length
|
||
//??????????????,???? = ?څ???? - ?????
|
||
this_time_rx_len = SBUS_RX_BUF_NUM - hdma_usart3_rx.Instance->NDTR;
|
||
|
||
//reset set_data_lenght
|
||
//?????څ???????
|
||
hdma_usart3_rx.Instance->NDTR = SBUS_RX_BUF_NUM;
|
||
|
||
//set memory buffer 0
|
||
//?څ??????0
|
||
DMA1_Stream1->CR &= ~(DMA_SxCR_CT);
|
||
|
||
//enable DMA
|
||
//???DMA
|
||
__HAL_DMA_ENABLE(&hdma_usart3_rx);
|
||
|
||
if(this_time_rx_len == RC_FRAME_LENGTH)
|
||
{
|
||
//?????????????
|
||
sbus_to_rc(sbus_rx_buf[1], &rc_ctrl);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief remote control protocol resolution
|
||
* @param[in] sbus_buf: raw data point
|
||
* @param[out] rc_ctrl: remote control data struct point
|
||
* @retval none
|
||
*/
|
||
/**
|
||
* @brief ?????<3F><>?????
|
||
* @param[in] sbus_buf: ??????????
|
||
* @param[out] rc_ctrl: ??????????
|
||
* @retval none
|
||
*/
|
||
static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl)
|
||
{
|
||
if (sbus_buf == NULL || rc_ctrl == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
rc_ctrl->rc.ch[0] = (sbus_buf[0] | (sbus_buf[1] << 8)) & 0x07ff; //!< Channel 0 ???????
|
||
rc_ctrl->rc.ch[1] = ((sbus_buf[1] >> 3) | (sbus_buf[2] << 5)) & 0x07ff; //!< Channel 1 ???????
|
||
rc_ctrl->rc.ch[2] = ((sbus_buf[2] >> 6) | (sbus_buf[3] << 2) | //!< Channel 2 ???????
|
||
(sbus_buf[4] << 10)) &0x07ff;
|
||
rc_ctrl->rc.ch[3] = ((sbus_buf[4] >> 1) | (sbus_buf[5] << 7)) & 0x07ff; //!< Channel 3 ???????
|
||
rc_ctrl->rc.s[0] = ((sbus_buf[5] >> 4) & 0x0003); //!< Switch left
|
||
rc_ctrl->rc.s[1] = ((sbus_buf[5] >> 4) & 0x000C) >> 2; //!< Switch right
|
||
rc_ctrl->mouse.x = sbus_buf[6] | (sbus_buf[7] << 8); //!< Mouse X axis
|
||
rc_ctrl->mouse.y = sbus_buf[8] | (sbus_buf[9] << 8); //!< Mouse Y axis
|
||
rc_ctrl->mouse.z = sbus_buf[10] | (sbus_buf[11] << 8); //!< Mouse Z axis
|
||
rc_ctrl->mouse.press_l = sbus_buf[12]; //!< Mouse Left Is Press ?
|
||
rc_ctrl->mouse.press_r = sbus_buf[13]; //!< Mouse Right Is Press ?
|
||
rc_ctrl->key.v = sbus_buf[14] | (sbus_buf[15] << 8); //!< KeyBoard value
|
||
rc_ctrl->rc.ch[4] = sbus_buf[16] | (sbus_buf[17] << 8); //NULL
|
||
|
||
rc_ctrl->rc.ch[0] -= RC_CH_VALUE_OFFSET;
|
||
rc_ctrl->rc.ch[1] -= RC_CH_VALUE_OFFSET;
|
||
rc_ctrl->rc.ch[2] -= RC_CH_VALUE_OFFSET;
|
||
rc_ctrl->rc.ch[3] -= RC_CH_VALUE_OFFSET;
|
||
rc_ctrl->rc.ch[4] -= RC_CH_VALUE_OFFSET;
|
||
|
||
//更新遥控器最后一次在线时间戳,用于掉线检测
|
||
rc_last_update_tick = HAL_GetTick();
|
||
}
|
||
|
||
/**
|
||
* @brief check if remote control is online
|
||
* @param[in] none
|
||
* @retval 1: online, 0: offline (no data for > 100ms)
|
||
*/
|
||
/**
|
||
* @brief 检测遥控器是否在线
|
||
* @param[in] none
|
||
* @retval 1: 在线, 0: 掉线(超过100ms无数据)
|
||
*/
|
||
uint8_t is_rc_online(void)
|
||
{
|
||
return (HAL_GetTick() - rc_last_update_tick) < 100;
|
||
} |