/* Includes ----------------------------------------------------------------- */ #include "remote_control.h" #include #include "bsp_usart.h" #include "error_detect.h" //两个遥控器都是 // x // | // | // ———y //在这下面更换遥控器 #define DR16 //#define R12DS #ifdef DR16 #define FRAME_LEN 36 #endif #ifdef R12DS #define FRAME_LEN 25 #endif /* Private define ----------------------------------------------------------- */ #define REMOTE_CH_VALUE_MIN (364u) #define REMOTE_CH_VALUE_MID (1024u) #define REMOTE_CH_VALUE_MAX (1684u) /* Private macro ------------------------------------------------------------ */ /* Private typedef ---------------------------------------------------------- */ /* Private variables -------------------------------------------------------- */ static osThreadId_t thread_alert; uint8_t cbuf[FRAME_LEN]; //此处设置为两帧字节的长度 若为一帧会出现乱码的情况 /* Private function -------------------------------------------------------- */ int8_t REMOTE_Restart(void) { __HAL_UART_DISABLE(BSP_UART_GetHandle(BSP_UART_REMOTE)); __HAL_UART_ENABLE(BSP_UART_GetHandle(BSP_UART_REMOTE)); return DEVICE_OK; } static void REMOTE_RxCpltCallback(void) { osThreadFlagsSet(thread_alert, SIGNAL_DR16_RAW_REDY); //detect_hook(DR16_TOE); } //遥控器初始化 int8_t REMOTE_Init(void) { if ((thread_alert = osThreadGetId()) == NULL) return DEVICE_ERR_NULL; BSP_UART_RegisterCallback(BSP_UART_REMOTE, BSP_UART_IDLE_LINE_CB, REMOTE_RxCpltCallback); memset(cbuf, 0, sizeof(cbuf));//初始化清空数据包 return DEVICE_OK; } int8_t REMOTE_StartDmaRecv(void) { if (HAL_UARTEx_ReceiveToIdle_DMA(BSP_UART_GetHandle(BSP_UART_REMOTE), (uint8_t *)cbuf, sizeof(cbuf)) == HAL_OK) return DEVICE_OK; return DEVICE_ERR; } bool REMOTE_WaitDmaCplt(uint32_t timeout) { return (osThreadFlagsWait(SIGNAL_DR16_RAW_REDY, osFlagsWaitAll, timeout) == SIGNAL_DR16_RAW_REDY); } /*大疆数据解析 */ static bool DR16_DataCorrupted(const DR16_t *dr16) { if (dr16 == NULL) return DEVICE_ERR_NULL; if ((dr16->data.ch_r_x < REMOTE_CH_VALUE_MIN) || (dr16->data.ch_r_x > REMOTE_CH_VALUE_MAX)) return true; if ((dr16->data.ch_r_y < REMOTE_CH_VALUE_MIN) || (dr16->data.ch_r_y > REMOTE_CH_VALUE_MAX)) return true; if ((dr16->data.ch_l_x < REMOTE_CH_VALUE_MIN) || (dr16->data.ch_l_x > REMOTE_CH_VALUE_MAX)) return true; if ((dr16->data.ch_l_y < REMOTE_CH_VALUE_MIN) || (dr16->data.ch_l_y > REMOTE_CH_VALUE_MAX)) return true; if (dr16->data.sw_l == 0) return true; if (dr16->data.sw_r == 0) return true; return false; } int8_t DR16_ParseRaw(DR16_t *dr16){ if(dr16 ==NULL) return DEVICE_ERR_NULL; dr16->data.ch_r_x = (cbuf[0] | (cbuf[1] <<8)); dr16->data.ch_r_y = ((cbuf[1] >> 3)| (cbuf[2] << 5)); dr16->data.ch_l_x = ((cbuf[2] >>6) | (cbuf[3] << 2) | (cbuf[4] <<10)); dr16->data.ch_l_y = ((cbuf[4] >>1) | (cbuf[5] <<7)); dr16->data.sw_r = ((cbuf[5] >>4)); dr16->data.sw_l = ((cbuf[5] >> 4) & 0x000C) >> 2; return 1; } /*乐迪数据解析 */ /*乐迪用的按键封装 */ CMD_SwitchPos_t Keymap(int16_t value) { return (value > 300 && value < 500) ? CMD_SW_DOWN : (value >= 500 && value < 1500) ? CMD_SW_MID : (value >= 1500 && value < 1700) ? CMD_SW_UP : CMD_SW_ERR; } int8_t LD_ParseRaw( LD_raw_t *raw){ raw->ch[0] = (cbuf[1] | (cbuf[2] << 8)) & 0x07ff; //Channel 1 raw->ch[1] = ((cbuf[2] >> 3) | (cbuf[3] << 5)) & 0x07ff; //Channel 2 raw->ch[2] = ((cbuf[3] >> 6) | (cbuf[4] << 2) | (cbuf[5] << 10)) &0x07ff; //Channel 3 raw->ch[3] = ((cbuf[5] >> 1) | (cbuf[6] << 7)) & 0x07ff; //Channel 4 raw->sw[0] = ((int16_t)cbuf[6] >> 4 | ((int16_t)cbuf[7] << 4 )) & 0x07FF;//Channel 5 raw->sw[1] = ((int16_t)cbuf[7] >> 7 | ((int16_t)cbuf[8] << 1 ) | (int16_t)cbuf[9] << 9 ) & 0x07FF;//Channel 6 raw->sw[2] = ((int16_t)cbuf[9] >> 2 | ((int16_t)cbuf[10] << 6 )) & 0x07FF;;//Channel 7 raw->sw[3] = ((int16_t)cbuf[10] >> 5 | ((int16_t)cbuf[11] << 3 )) & 0x07FF;//Channel 8 raw->sw[4] = ((int16_t)cbuf[12] << 0 | ((int16_t)cbuf[13] << 8 )) & 0x07FF;//Channel 9 raw->sw[5] = ((int16_t)cbuf[13] >> 3 | ((int16_t)cbuf[14] << 5 )) & 0x07FF;//Channel 10 raw->sw[6] = ((int16_t)cbuf[14] >> 6 | ((int16_t)cbuf[15] << 2 ) | (int16_t)cbuf[16] << 10 ) & 0x07FF;//Channel 11 raw->sw[7] = ((int16_t)cbuf[16] >> 1 | ((int16_t)cbuf[17] << 7 )) & 0x07FF;//Channel 12 raw->ch[0] -= REMOTE_CH_VALUE_MID; raw->ch[1] -= REMOTE_CH_VALUE_MID; raw->ch[2] -= REMOTE_CH_VALUE_MID; raw->ch[3] -= REMOTE_CH_VALUE_MID; raw->ch[0] = +raw->ch[0]; raw->ch[1] = -raw->ch[1]; raw->ch[2] = -raw->ch[2]; raw->ch[3] = +raw->ch[3]; //中心平移 raw->ch[0] += 24.5; //(-693.5,693.5) raw->ch[1] -= 24.5; //(-693.5,693.5) raw->ch[2] -= 125; //(-693,693) raw->ch[3] += 24.5; //(-693.5,693.5) return 1; /* 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] sw[5] sw[]1000 nsw[3] 1694 1694 306-1694 306-1694 1694 1694 818 718 | | | | -718----------ch[3]669 -718---------ch[0] 669 | | | | ch[2] ch[1] -568 -669 */ } int8_t REMOTE_ParseRC(DR16_t *dr16, CMD_RC_t *rc,LD_raw_t *LD) { if (dr16 == NULL) return DEVICE_ERR_NULL; if (LD == NULL) return DEVICE_ERR_NULL; #ifdef DR16 rc->rc_type=RC_DR16; DR16_ParseRaw(dr16); if (DR16_DataCorrupted(dr16)) { return DEVICE_ERR; } else { memset(rc, 0, sizeof(*rc)); } float full_range = (float)(REMOTE_CH_VALUE_MAX - REMOTE_CH_VALUE_MIN); rc->DJ.ch_r_x = 2 * ((float)dr16->data.ch_r_y - REMOTE_CH_VALUE_MID) / full_range; rc->DJ.ch_r_y = 2 * ((float)dr16->data.ch_r_x - REMOTE_CH_VALUE_MID) / full_range; rc->DJ.ch_l_x = 2 * ((float)dr16->data.ch_l_y - REMOTE_CH_VALUE_MID) / full_range; rc->DJ.ch_l_y = 2 * ((float)dr16->data.ch_l_x - REMOTE_CH_VALUE_MID) / full_range; rc->DJ.sw_l = (CMD_SwitchPos_t)dr16->data.sw_l; rc->DJ.sw_r = (CMD_SwitchPos_t)dr16->data.sw_r; // rc->dr16.key = dr16->data.key; // rc->ch_res = ((float)dr16->data.res - DR16_CH_VALUE_MID) / full_range; #elif defined(R12DS) /*乐迪*/ rc->rc_type=RC_LD; LD_ParseRaw(LD); //memcpy(&rc->LD, LD, sizeof(LD_Data_t)); rc->LD.ch_r_x = (float)LD->ch[1] /693.5f; rc->LD.ch_r_y = (float)LD->ch[0] /693.5f; rc->LD.ch_l_x = (float)LD->ch[2] /693; rc->LD.ch_l_y = (float)LD->ch[3] /693.5f; rc->LD.key_A = Keymap(LD->sw[0]); rc->LD.key_C = Keymap(LD->sw[2]); rc->LD.key_E = Keymap(LD->sw[5]); rc->LD.key_F = Keymap(LD->sw[3]); rc->LD.key_G = Keymap(LD->sw[7]); rc->LD.key_H = Keymap(LD->sw[4]); rc->LD.knob_left = Keymap(LD->sw[1]); rc->LD.knob_right = Keymap(LD->sw[6]); // /*离线处理,和dr16位置不同*/ if(LD->sw[6]!=1694) { LD_HandleOffline(LD,rc); // memset(cbuf, 0, sizeof(cbuf)); //有时候会出现消息数组错位,所以直接清空,在离线和指定按键不对的情况下,原数据不可信 } #endif return DEVICE_OK; } int8_t DR16_HandleOffline(const DR16_t *dr16, CMD_RC_t *rc) { if (dr16 == NULL) return DEVICE_ERR_NULL; if (rc == NULL) return DEVICE_ERR_NULL; rc->rc_type =Control_loss ; memset(&rc->DJ , 0, sizeof(DR16_t)); return 0; } int8_t LD_HandleOffline(const LD_raw_t *LD, CMD_RC_t *rc) { if (LD == NULL) return DEVICE_ERR_NULL; if (rc == NULL) return DEVICE_ERR_NULL; rc->rc_type =Control_loss ; memset(&rc->LD , 0, sizeof(LD_raw_t)); return 0; }