1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-23 16:25:31 +03:00

Change rcsplit protocol to async

This commit is contained in:
azolyoung 2018-06-06 00:17:02 +08:00 committed by azol
parent 713e72321b
commit 53458d4cf1
13 changed files with 517 additions and 2105 deletions

View file

@ -34,21 +34,28 @@
#include "io/beeper.h"
#include "io/serial.h"
#include "io/osd.h"
#include "io/rcdevice_cam.h"
#include "rx/rx.h"
#include "fc/config.h"
#include "config/feature.h"
#ifdef USE_RCDEVICE
#define IS_HI(X) (rcData[X] > FIVE_KEY_CABLE_JOYSTICK_MAX)
#define IS_LO(X) (rcData[X] < FIVE_KEY_CABLE_JOYSTICK_MIN)
#define IS_MID(X) (rcData[X] > FIVE_KEY_CABLE_JOYSTICK_MID_START && rcData[X] < FIVE_KEY_CABLE_JOYSTICK_MID_END)
static runcamDevice_t runcamDevice;
runcamDevice_t *camDevice = &runcamDevice;
rcdeviceSwitchState_t switchStates[BOXCAMERA3 - BOXCAMERA1 + 1];
bool rcdeviceInMenu;
bool needRelease = false;
bool rcdeviceInMenu = false;
bool isButtonPressed = false;
bool waitingDeviceResponse = false;
static bool isFeatureSupported(uint8_t feature)
{
@ -59,21 +66,6 @@ static bool isFeatureSupported(uint8_t feature)
return false;
}
static bool rcdeviceIsCameraControlEnabled(void)
{
bool isPowerSimulationSupported = isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_SIMULATE_POWER_BUTTON);
bool isWiFiSimulationSupported = isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_SIMULATE_WIFI_BUTTON);
bool isChangeModeSupported = isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_CHANGE_MODE);
bool isStartRecordingSupported = isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_START_RECORDING);
bool isStopRecordingSupported = isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_STOP_RECORDING);
if (camDevice->serialPort != NULL && (isPowerSimulationSupported || isWiFiSimulationSupported || isChangeModeSupported || isStartRecordingSupported || isStopRecordingSupported)) {
return true;
}
return false;
}
bool rcdeviceIsEnabled(void)
{
return camDevice->serialPort != NULL;
@ -88,39 +80,13 @@ static bool rcdeviceIs5KeyEnabled(void)
return false;
}
static bool reInitializeDevice() {
#define MAX_RETRY_COUNT 4
#define RETRY_INTERVAL_MS 500
static timeMs_t lastInitializeTime = 0;
static int tryInitCount = 0;
bool result = false;
if (ARMING_FLAG(ARMED)) {
return false;
}
if (tryInitCount < MAX_RETRY_COUNT) {
timeMs_t nextRetryTime = lastInitializeTime + RETRY_INTERVAL_MS;
if (millis() >= nextRetryTime) {
result = rcdeviceInit();
tryInitCount++;
lastInitializeTime = millis();
}
}
return result;
}
static void rcdeviceCameraControlProcess(void)
{
for (boxId_e i = BOXCAMERA1; i <= BOXCAMERA3; i++) {
uint8_t switchIndex = i - BOXCAMERA1;
if (IS_RC_MODE_ACTIVE(i)) {
if (!rcdeviceIsCameraControlEnabled()) {
reInitializeDevice();
}
// check last state of this mode, if it's true, then ignore it.
// Here is a logic to make a toggle control for this mode
if (switchStates[switchIndex].isActivated) {
@ -136,7 +102,7 @@ static void rcdeviceCameraControlProcess(void)
break;
case BOXCAMERA2:
if (isFeatureSupported(RCDEVICE_PROTOCOL_FEATURE_SIMULATE_POWER_BUTTON)) {
behavior = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_POWER_BTN;
behavior = RCDEVICE_PROTOCOL_CAM_CTRL_SIMULATE_POWER_BTN;
}
break;
case BOXCAMERA3:
@ -157,7 +123,69 @@ static void rcdeviceCameraControlProcess(void)
}
}
static bool rcdeviceCamSimulate5KeyCablePress(rcdeviceCamSimulationKeyEvent_e key)
static void rcdeviceSimulationOSDCableFailed(rcdeviceResponseParseContext_t *ctx)
{
if (ctx->command == RCDEVICE_PROTOCOL_COMMAND_5KEY_CONNECTION) {
uint8_t operationID = ctx->paramData[0];
if (operationID == RCDEVICE_PROTOCOL_5KEY_CONNECTION_CLOSE) {
waitingDeviceResponse = false;
return;
}
} else {
rcdeviceInMenu = false;
waitingDeviceResponse = false;
}
}
static void rcdeviceSimulationRespHandle(rcdeviceResponseParseContext_t *ctx)
{
if (ctx->result != RCDEVICE_RESP_SUCCESS) {
rcdeviceSimulationOSDCableFailed(ctx);
return ;
}
switch (ctx->command) {
case RCDEVICE_PROTOCOL_COMMAND_5KEY_SIMULATION_RELEASE:
{
UNUSED(ctx);
isButtonPressed = false;
}
break;
case RCDEVICE_PROTOCOL_COMMAND_5KEY_CONNECTION:
{
// the high 4 bits is the operationID that we sent
// the low 4 bits is the result code
uint8_t operationID = ctx->paramData[0];
bool errorCode = (ctx->recvBuf[1] & 0x0F);
if (operationID == RCDEVICE_PROTOCOL_5KEY_CONNECTION_OPEN) {
if (errorCode == 1) {
rcdeviceInMenu = true;
beeper(BEEPER_CAM_CONNECTION_OPEN);
} else {
rcdeviceInMenu = false;
beeper(BEEPER_CAM_CONNECTION_CLOSE);
}
} else if (operationID == RCDEVICE_PROTOCOL_5KEY_CONNECTION_CLOSE) {
if (errorCode == 1) {
rcdeviceInMenu = false;
beeper(BEEPER_CAM_CONNECTION_CLOSE);
}
}
}
break;
case RCDEVICE_PROTOCOL_COMMAND_5KEY_SIMULATION_PRESS:
{
isButtonPressed = true;
}
break;
}
waitingDeviceResponse = false;
return ;
}
static void rcdeviceCamSimulate5KeyCablePress(rcdeviceCamSimulationKeyEvent_e key)
{
uint8_t operation = RCDEVICE_PROTOCOL_5KEY_SIMULATION_NONE;
switch (key) {
@ -176,32 +204,23 @@ static bool rcdeviceCamSimulate5KeyCablePress(rcdeviceCamSimulationKeyEvent_e ke
case RCDEVICE_CAM_KEY_ENTER:
operation = RCDEVICE_PROTOCOL_5KEY_SIMULATION_SET;
break;
case RCDEVICE_CAM_KEY_NONE:
default:
operation = RCDEVICE_PROTOCOL_5KEY_SIMULATION_NONE;
break;
}
return runcamDeviceSimulate5KeyOSDCableButtonPress(camDevice, operation);
runcamDeviceSimulate5KeyOSDCableButtonPress(camDevice, operation, rcdeviceSimulationRespHandle);
}
static bool rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEvent_e key)
void rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEvent_e key)
{
bool reqResult = false;
switch (key) {
case RCDEVICE_CAM_KEY_CONNECTION_OPEN:
reqResult = runcamDeviceOpen5KeyOSDCableConnection(camDevice);
if (reqResult) {
rcdeviceInMenu = true;
beeper(BEEPER_CAM_CONNECTION_OPEN);
}
runcamDeviceOpen5KeyOSDCableConnection(camDevice, rcdeviceSimulationRespHandle);
break;
case RCDEVICE_CAM_KEY_CONNECTION_CLOSE: {
uint8_t resultCode = 0;
reqResult = runcamDeviceClose5KeyOSDCableConnection(camDevice, &resultCode);
if (resultCode == 1) {
rcdeviceInMenu = false;
beeper(BEEPER_CAM_CONNECTION_CLOSE);
}
runcamDeviceClose5KeyOSDCableConnection(camDevice, rcdeviceSimulationRespHandle);
}
break;
case RCDEVICE_CAM_KEY_ENTER:
@ -209,17 +228,17 @@ static bool rcdeviceSend5KeyOSDCableSimualtionEvent(rcdeviceCamSimulationKeyEven
case RCDEVICE_CAM_KEY_UP:
case RCDEVICE_CAM_KEY_RIGHT:
case RCDEVICE_CAM_KEY_DOWN:
reqResult = rcdeviceCamSimulate5KeyCablePress(key);
rcdeviceCamSimulate5KeyCablePress(key);
break;
case RCDEVICE_CAM_KEY_RELEASE:
reqResult = runcamDeviceSimulate5KeyOSDCableButtonRelease(camDevice);
runcamDeviceSimulate5KeyOSDCableButtonRelease(camDevice, rcdeviceSimulationRespHandle);
break;
case RCDEVICE_CAM_KEY_NONE:
default:
reqResult = false;
break;
}
return reqResult;
return;
}
static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs)
@ -236,21 +255,20 @@ static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs)
return;
}
rcdeviceCamSimulationKeyEvent_e key = RCDEVICE_CAM_KEY_NONE;
if (waitingDeviceResponse) {
return;
}
if (needRelease) {
if (isButtonPressed) {
if (IS_MID(YAW) && IS_MID(PITCH) && IS_MID(ROLL)) {
if ((camDevice->serialPort != NULL || reInitializeDevice()) && rcdeviceIs5KeyEnabled()) {
key = RCDEVICE_CAM_KEY_RELEASE;
if (rcdeviceSend5KeyOSDCableSimualtionEvent(key)) {
needRelease = false;
} else {
rcdeviceInMenu = false;
}
if (rcdeviceIs5KeyEnabled()) {
rcdeviceSend5KeyOSDCableSimualtionEvent(RCDEVICE_CAM_KEY_RELEASE);
waitingDeviceResponse = true;
}
}
return;
} else {
rcdeviceCamSimulationKeyEvent_e key = RCDEVICE_CAM_KEY_NONE;
if (IS_MID(THROTTLE) && IS_MID(ROLL) && IS_MID(PITCH) && IS_LO(YAW)) { // Disconnect HI YAW
if (rcdeviceInMenu) {
key = RCDEVICE_CAM_KEY_CONNECTION_CLOSE;
@ -274,14 +292,11 @@ static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs)
}
}
}
}
if (key != RCDEVICE_CAM_KEY_NONE) {
if ((camDevice->serialPort != NULL || reInitializeDevice()) && rcdeviceIs5KeyEnabled()) {
if (rcdeviceSend5KeyOSDCableSimualtionEvent(key)) {
needRelease = true;
} else {
rcdeviceInMenu = false;
if (key != RCDEVICE_CAM_KEY_NONE) {
if (rcdeviceIs5KeyEnabled()) {
rcdeviceSend5KeyOSDCableSimualtionEvent(key);
waitingDeviceResponse = true;
}
}
}
@ -289,23 +304,23 @@ static void rcdevice5KeySimulationProcess(timeUs_t currentTimeUs)
void rcdeviceUpdate(timeUs_t currentTimeUs)
{
rcdeviceReceive(currentTimeUs);
rcdeviceCameraControlProcess();
rcdevice5KeySimulationProcess(currentTimeUs);
}
bool rcdeviceInit(void)
void rcdeviceInit(void)
{
// open serial port
if (!runcamDeviceInit(camDevice)) {
return false;
}
runcamDeviceInit(camDevice);
for (boxId_e i = BOXCAMERA1; i <= BOXCAMERA3; i++) {
uint8_t switchIndex = i - BOXCAMERA1;
switchStates[switchIndex].isActivated = true;
}
return true;
return;
}
#endif