#include "remote_control.h" #include "main.h" extern UART_HandleTypeDef huart3; extern DMA_HandleTypeDef hdma_usart3_rx; #if FREERTOS == 0 static void sbus_to_rc(volatile const uint8_t *sbus_buf, RC_ctrl_t *rc_ctrl); static int map(int x, int in_min, int in_max, int out_min, int out_max); RC_ctrl_t rc_ctrl; static uint8_t sbus_rx_buf[2][RC_FRAME_LENGTH]; //串口dma双缓冲区初始化 #if FREERTOS == 0 //串口中断 void USART3_IRQHandler(void) { //have received data if(huart3.Instance->SR & UART_FLAG_RXNE) { //如果是接收中断则通过读取dr寄存器清零 __HAL_UART_CLEAR_FEFLAG(&huart3); } if(USART3->SR & UART_FLAG_IDLE) { //使用清除pe标志位的函数是因为pe idle等几个中断都是靠先读取sr再读取dr清零的 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 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); //1 frame length is correct data 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); } } } } #else //如果打开了freertos,则只进行任务通知 void USART3_IRQHandler(void) { } #endif void RC_init(uint8_t *rx1_buf, uint8_t *rx2_buf, uint16_t dma_buf_num); void remote_control_init(void) { // BSP_UART_RegisterCallback(BSP_UART_DR16,BSP_UART_IDLE_LINE_CB,DR16_IDLE_CB);//还没有移入嘉宁的架构,待测试 RC_init(sbus_rx_buf[0], sbus_rx_buf[1], RC_FRAME_LENGTH); } 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; } 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; } /* 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 */ 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); } #else //DMA双缓冲区+串口空闲中断 static osEventFlagsId_t eventReceive; RC_mess_t RC_mess; #define hdma_rc hdma_usart3_rx #define uart_rc huart3 #define per_rc USART3 /* Private function -------------------------------------------------------- */ static void RC_RxCpltCallback(void) { osEventFlagsSet(eventReceive, EVENT_RC); if((hdma_rc.Instance->CR & DMA_SxCR_CT) == 0u)//DMA_SxM0AR RC_mess.dma_buffer = DMA_SxM0AR; else RC_mess.dma_buffer = DMA_SxM1AR; } static 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; } #if DEBUG == 0 static RC_data_t rc_buff; #else RC_data_t rc_buff; #endif //sbus协议解析 static int8_t sbus_to_rc( uint8_t *sbus_buf, RC_data_t *rc_ctrl) { if (sbus_buf == NULL || rc_ctrl == NULL) return DEVICE_ERR_NULL; rc_buff.ch[0] = (sbus_buf[1] | (sbus_buf[2] << 8)) & 0x07ff; //!< Channel 0 rc_buff.ch[1] = ((sbus_buf[2] >> 3) | (sbus_buf[3] << 5)) & 0x07ff; //!< Channel 1 rc_buff.ch[2] = ((sbus_buf[3] >> 6) | (sbus_buf[4] << 2) | //!< Channel 2 (sbus_buf[5] << 10)) &0x07ff; rc_buff.ch[3] = ((sbus_buf[5] >> 1) | (sbus_buf[6] << 7)) & 0x07ff; //!< Channel 3 rc_ctrl->sw[0] = ((int16_t)sbus_buf[6] >> 4 | ((int16_t)sbus_buf[7] << 4 )) & 0x07FF; //!< Switch left rc_ctrl->sw[1] = ((int16_t)sbus_buf[7] >> 7 | ((int16_t)sbus_buf[8] << 1 ) | (int16_t)sbus_buf[9] << 9 ) & 0x07FF; //!< Switch right rc_ctrl->sw[2] = ((int16_t)sbus_buf[9] >> 2 | ((int16_t)sbus_buf[10] << 6 )) & 0x07FF;; //!< Mouse X axis rc_ctrl->sw[3] = ((int16_t)sbus_buf[10] >> 5 | ((int16_t)sbus_buf[11] << 3 )) & 0x07FF; //!< Mouse Y axis rc_ctrl->sw[4] = ((int16_t)sbus_buf[12] << 0 | ((int16_t)sbus_buf[13] << 8 )) & 0x07FF; //!< Mouse Z axis rc_ctrl->sw[5] = ((int16_t)sbus_buf[13] >> 3 | ((int16_t)sbus_buf[14] << 5 )) & 0x07FF; //!< Mouse Left Is Press ? rc_ctrl->sw[6] = ((int16_t)sbus_buf[14] >> 6 | ((int16_t)sbus_buf[15] << 2 ) | (int16_t)sbus_buf[16] << 10 ) & 0x07FF; //!< Mouse Right Is Press ? rc_ctrl->sw[7] = ((int16_t)sbus_buf[16] >> 1 | ((int16_t)sbus_buf[17] << 7 )) & 0x07FF; //!< KeyBoard value rc_buff.ch[0] = map(rc_buff.ch[0],1693,306,-800,800);//x rc_buff.ch[1] = map(rc_buff.ch[1],1659,272,-800,800);//y rc_buff.ch[2] = map(rc_buff.ch[2],1693,337,0,100);//mul rc_buff.ch[3] = map(rc_buff.ch[3],1690,314,-800,800);//w if(rc_buff.ch[0]>-30&&rc_buff.ch[0]<30) rc_buff.ch[0]=0; if(rc_buff.ch[1]>-30&&rc_buff.ch[1]<30) rc_buff.ch[1]=0; if(rc_buff.ch[2]>-30&&rc_buff.ch[2]<30) rc_buff.ch[2]=0; if(rc_buff.ch[3]>-30&&rc_buff.ch[3]<30) rc_buff.ch[3]=0; rc_ctrl->ch[0] = rc_buff.ch[0]; rc_ctrl->ch[1] = rc_buff.ch[1]; rc_ctrl->ch[2] = rc_buff.ch[2]; rc_ctrl->ch[3] = rc_buff.ch[3]; return DEVICE_OK; } static void RC_restart(int8_t *Error_count) { __HAL_UART_DISABLE(&uart_rc); __HAL_DMA_DISABLE(&hdma_rc); hdma_rc.Instance->NDTR = 25u; __HAL_DMA_ENABLE(&hdma_rc); __HAL_UART_ENABLE(&uart_rc); *Error_count = 0; } /* Exported functions ------------------------------------------------------- */ int8_t RC_init() { uart_rc.Instance->CR3 |= USART_CR3_DMAR; //接收使能DMA模式 __HAL_UART_ENABLE_IT(&uart_rc, UART_IT_IDLE); //串口空闲中断使能 // uart_rc.Instance->CR1 |= USART_CR1_IDLEIE;//中断使能 // DMA1_Stream1->CR |= (1<<4); //DMA传输完成中断 while(hdma_rc.Instance->CR & DMA_SxCR_EN) { __HAL_DMA_DISABLE(&hdma_rc); } hdma_rc.Instance->PAR = (uint32_t)&(per_rc->DR); hdma_rc.Instance->M0AR= (uint32_t)&RC_mess.sbus_rx_buffer[0][0]; hdma_rc.Instance->M1AR= (uint32_t)&RC_mess.sbus_rx_buffer[1][0]; hdma_rc.Instance->NDTR= 25u; hdma_rc.Instance->CR |= DMA_SxCR_DBM;//使用双缓冲区 hdma_rc.Instance->CR &= ~DMA_SxCR_CT;//使用DMA_SxMOAR指针寻址 __HAL_DMA_ENABLE(&hdma_rc); BSP_UART_RegisterCallback(BSP_UART_DR16, BSP_UART_IDLE_LINE_CB, RC_RxCpltCallback); return DEVICE_OK; } uint32_t RC_WaitNew() { return osEventFlagsWait( eventReceive, EVENT_RC,osFlagsWaitAny, osWaitForever); } int8_t RC_rx_analysis(){ switch(RC_mess.dma_buffer) { case DMA_SxM0AR: if(RC_mess.sbus_rx_buffer[0][0] == 0x0F){ sbus_to_rc(RC_mess.sbus_rx_buffer[1], &RC_mess.RC_data); RC_mess.Error_flag = DATA_OK; }else{ RC_mess.Error_flag = DATA_ERROR; } break; case DMA_SxM1AR: if(RC_mess.sbus_rx_buffer[1][0] == 0x0F){ sbus_to_rc(RC_mess.sbus_rx_buffer[0], &RC_mess.RC_data); RC_mess.Error_flag = DATA_OK; }else{ RC_mess.Error_flag = DATA_ERROR; } break; } //累计三次数据错误,重启 RC_mess.Error_flag == DATA_OK ? RC_mess.Error_count-- : RC_mess.Error_count++; if(RC_mess.Error_count>3) RC_restart(&RC_mess.Error_count); if(RC_mess.Error_count<0) RC_mess.Error_count=0; RC_mess.Error_flag = 0; return DEVICE_OK; } RC_data_t* get_rc_data() { return &RC_mess.RC_data; } #endif