r1upper/User/device/remote_control.c
2025-04-12 15:18:06 +08:00

329 lines
10 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.

/**
****************************(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"
#include "calc_lib.h"
extern UART_HandleTypeDef huart3;
extern DMA_HandleTypeDef hdma_usart3_rx;
#if DT7==1
uint8_t dbus_buf[DBUS_BUFLEN];
RC_ctrl_t rc_ctrl = rc_Init;//所有数据初始化
// 使用 DMA 接收 UART 数据的函数
static int uart_receive_dma_no_it(UART_HandleTypeDef* huart, uint8_t* pData, uint32_t Size) {
uint32_t tmp1 = huart->RxState;
if (tmp1 == HAL_UART_STATE_READY) {
if ((pData == NULL) || (Size == 0)) {
return HAL_ERROR;
}
huart->pRxBuffPtr = pData;
huart->RxXferSize = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
HAL_DMA_Start(huart->hdmarx, (uint32_t)&huart->Instance->DR, (uint32_t)pData, Size);
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
return HAL_OK;
}
return HAL_BUSY;
}
// DBUS 串口初始化
void dbus_uart_init(void) {
__HAL_UART_CLEAR_IDLEFLAG(&DBUS_HUART);
__HAL_UART_ENABLE_IT(&DBUS_HUART, UART_IT_IDLE);
uart_receive_dma_no_it(&DBUS_HUART, dbus_buf, DBUS_MAX_LEN);
}
// 串口中断处理函数
void USART3_IRQHandler(void)
{
uart_receive_handler(&huart3);//调用之前定义的函数传入DBUS串口的地址以处理接收事件
}
// 遥控器数据解码函数
void rc_callback_handler(RC_ctrl_t *rc_ctrl, uint8_t *buff) {
rc_ctrl->ch0 = (buff[0] | (buff[1] << 8)) & 0x07FF;
rc_ctrl->ch0 -= 1024;
rc_ctrl->ch1 = (buff[1] >> 3 | buff[2] << 5) & 0x07FF;
rc_ctrl->ch1 -= 1024;
rc_ctrl->ch2 = (buff[2] >> 6 | buff[3] << 2 | buff[4] << 10) & 0x07FF;
rc_ctrl->ch2 -= 1024;
rc_ctrl->ch3 = (buff[4] >> 1 | buff[5] << 7) & 0x07FF;
rc_ctrl->ch3 -= 1024;
rc_ctrl->roll = (buff[16] | (buff[17] << 8)) & 0x07FF;
rc_ctrl->roll -= 1024;
rc_ctrl->sw1 = ((buff[5] >> 4) & 0x000C) >> 2;
rc_ctrl->sw2 = (buff[5] >> 4) & 0x0003;
// if ((abs(rc_ctrl->ch0) > 660) || (abs(rc_ctrl->ch1) > 660) || (abs(rc_ctrl->ch2) > 660) || (abs(rc_ctrl->ch3) > 660))
// {
// memset(rc_ctrl, 0, sizeof(RC_ctrl_t));
// }
}
// 计算 DMA 剩余的数据长度
uint16_t dma_current_data_counter(DMA_Stream_TypeDef *dma_stream) {
return ((uint16_t)(dma_stream->NDTR));
}
// 处理 UART 空闲中断,处理接收到的数据
static void uart_rx_idle_callback(UART_HandleTypeDef* huart) {
__HAL_UART_CLEAR_IDLEFLAG(huart);
if (huart == &DBUS_HUART) {
__HAL_DMA_DISABLE(huart->hdmarx);
if ((DBUS_MAX_LEN - dma_current_data_counter(huart->hdmarx->Instance)) == DBUS_BUFLEN) {
rc_callback_handler(&rc_ctrl, dbus_buf);
}
__HAL_DMA_SET_COUNTER(huart->hdmarx, DBUS_MAX_LEN);
__HAL_DMA_ENABLE(huart->hdmarx);
}
}
// 检查 UART 接收状态,处理空闲状态
void uart_receive_handler(UART_HandleTypeDef *huart) {
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) &&
__HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE)) {
uart_rx_idle_callback(huart);
}
}
// int map(int x, int in_min, int in_max, int out_min, int out_max) //映射函数
// {
// return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
// }
/*
s1 s2
1/3/2 1/3/2
660 660
| |
| |
-660 -- --ch[2]660 -660 -- --ch[0]660
| |
| |
ch[3] ch[1]
-660 -660
*/
#else
static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl);
void RC_init(uint8_t *rx1_buf, uint8_t *rx2_buf, uint16_t dma_buf_num);
RC_ctrl_t rc_ctrl;
static uint8_t sbus_rx_buf[2][RC_FRAME_LENGTH];
uint8_t remote_ready = 0;//遥控器准备完成
//串口dma双缓冲区初始化
//串口中断
void remote_control_init(void)
{
RC_init(sbus_rx_buf[0], sbus_rx_buf[1], RC_FRAME_LENGTH);
}
static uint16_t this_time_rx_len = 0;
////////////////////////////////////////
void USART3_IRQHandler(void)
{
//have received data
if(huart3.Instance->SR & UART_FLAG_RXNE)
{
//如果是接收中断则通过读取dr寄存器清零
__HAL_UART_CLEAR_FEFLAG(&huart3);
}
else if(USART3->SR & UART_FLAG_IDLE)
{
//使用清除pe标志位的函数是因为pe idle等几个中断都是靠先读取sr再读取dr清零的
__HAL_UART_CLEAR_PEFLAG(&huart3);
if( (hdma_usart3_rx.Instance->CR & DMA_SxCR_CT) == RESET)
{
//current memory buffer used is memory0
//disable dma to change dma register
__HAL_DMA_DISABLE(&hdma_usart3_rx);
//get received data length, length = set_data_length - remain_length
this_time_rx_len = SBUS_RX_BUF_NUM - hdma_usart3_rx.Instance->NDTR;
//reset set_data_length
hdma_usart3_rx.Instance->NDTR = SBUS_RX_BUF_NUM;
//change memory0 to memory1
hdma_usart3_rx.Instance->CR |= DMA_SxCR_CT;
//enable 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
{
__HAL_DMA_DISABLE(&hdma_usart3_rx);
this_time_rx_len = SBUS_RX_BUF_NUM - hdma_usart3_rx.Instance->NDTR;
hdma_usart3_rx.Instance->NDTR = SBUS_RX_BUF_NUM;
//change memory1 to memory0
DMA1_Stream1->CR &= ~(DMA_SxCR_CT);
__HAL_DMA_ENABLE(&hdma_usart3_rx);
if(this_time_rx_len ==RC_FRAME_LENGTH)
{
sbus_to_rc(sbus_rx_buf[1], &rc_ctrl);
}
}
}
}
void RC_init(uint8_t *rx1_buf, uint8_t *rx2_buf, uint16_t dma_buf_num)
{
//enable the dma transfer for the receiver request
SET_BIT(huart3.Instance->CR3, USART_CR3_DMAR);
//enable idle interrupt
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);
//disable dma, to change the dma register
__HAL_DMA_DISABLE(&hdma_usart3_rx);
while(hdma_usart3_rx.Instance->CR & DMA_SxCR_EN)
{
__HAL_DMA_DISABLE(&hdma_usart3_rx);
}
hdma_usart3_rx.Instance->PAR = (uint32_t) & (USART3->DR);
//memory buffer 1
hdma_usart3_rx.Instance->M0AR = (uint32_t)(rx1_buf);
//momory buffer 2
hdma_usart3_rx.Instance->M1AR = (uint32_t)(rx2_buf);
//data length
hdma_usart3_rx.Instance->NDTR = dma_buf_num;
//enable double memory buffer
SET_BIT(hdma_usart3_rx.Instance->CR, DMA_SxCR_DBM);
//enable dma
__HAL_DMA_ENABLE(&hdma_usart3_rx);
}
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->ch[0] = (sbus_buf[1] | (sbus_buf[2] << 8)) & 0x07ff; //Channel 1
rc_ctrl->ch[1] = ((sbus_buf[2] >> 3) | (sbus_buf[3] << 5)) & 0x07ff; //Channel 2
rc_ctrl->ch[2] = ((sbus_buf[3] >> 6) | (sbus_buf[4] << 2) | //Channel 3
(sbus_buf[5] << 10)) &0x07ff;
rc_ctrl->ch[3] = ((sbus_buf[5] >> 1) | (sbus_buf[6] << 7)) & 0x07ff; //Channel 4
rc_ctrl->sw[0] = ((int16_t)sbus_buf[6] >> 4 | ((int16_t)sbus_buf[7] << 4 )) & 0x07FF; //Channel 5
rc_ctrl->sw[1] = ((int16_t)sbus_buf[7] >> 7 | ((int16_t)sbus_buf[8] << 1 ) | (int16_t)sbus_buf[9] << 9 ) & 0x07FF; //Channel 6
rc_ctrl->sw[2] = ((int16_t)sbus_buf[9] >> 2 | ((int16_t)sbus_buf[10] << 6 )) & 0x07FF;; //Channel 7
rc_ctrl->sw[3] = ((int16_t)sbus_buf[10] >> 5 | ((int16_t)sbus_buf[11] << 3 )) & 0x07FF; //Channel 8
rc_ctrl->sw[4] = ((int16_t)sbus_buf[12] << 0 | ((int16_t)sbus_buf[13] << 8 )) & 0x07FF; //Channel 9
rc_ctrl->sw[5] = ((int16_t)sbus_buf[13] >> 3 | ((int16_t)sbus_buf[14] << 5 )) & 0x07FF; //Channel 10
rc_ctrl->sw[6] = ((int16_t)sbus_buf[14] >> 6 | ((int16_t)sbus_buf[15] << 2 ) | (int16_t)sbus_buf[16] << 10 ) & 0x07FF; //Channel 11
rc_ctrl->sw[7] = ((int16_t)sbus_buf[16] >> 1 | ((int16_t)sbus_buf[17] << 7 )) & 0x07FF; //Channel 12
rc_ctrl->sw[2] = map(rc_ctrl->sw[2],306,1694,1694,306);
rc_ctrl->sw[3] = map(rc_ctrl->sw[3],306,1694,1694,306);
rc_ctrl->ch[1] = map(rc_ctrl->ch[1],-693,694,-700,700); //x
rc_ctrl->ch[0] = map(rc_ctrl->ch[0],-694,693,-700,700); //y
//死区(-30,30)
if(rc_ctrl->ch[0]>-14&&rc_ctrl->ch[0]<6) rc_ctrl->ch[0]=0;
if(rc_ctrl->ch[1]>-30&&rc_ctrl->ch[1]<-10) rc_ctrl->ch[1]=0;
if(rc_ctrl->ch[2]>=0&&rc_ctrl->ch[2]<=7) rc_ctrl->ch[2]=7;
if(rc_ctrl->ch[3]>-22&&rc_ctrl->ch[3]<-2) rc_ctrl->ch[3]=0;
remote_ready = 1;
}
#endif
/*
306 306
sw[] sw[7]
1694 1694
306 306
sw[6] sw[4]
1694 1694
306 306 306 306
sw[0] sw[2] sw[1]:306-1694 sw[5]:306-1694 sw[]1000 sw[3]
1694 1694 1694 1694
710
688 1425
| |
| |
54 -616------ch[3]770 -354---------ch[0] 339 0
| |
| |
ch[2] ch[1]
_699 38
*/