/** ****************************(C) COPYRIGHT 2019 DJI**************************** * @file remote_control.c/h * @brief ?????????????????????????SBUS??��?��??????DMA????????CPU * ????????????????��????????????????????��????????DMA?????? * ??????????��??????? * @note ????????????????��???????????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 ?????��????? * @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; } //?????��? 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 //?��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 //?��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 ?????��????? * @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; }