1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-19 22:35:23 +03:00

Merge pull request #4982 from mikeller/added_rx_processing_function

Added rx data processing function and used it for FPort processing.
This commit is contained in:
Michael Keller 2018-01-24 00:16:38 +13:00 committed by GitHub
commit a9068e1997
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 81 additions and 36 deletions

View file

@ -397,7 +397,9 @@ void processRx(timeUs_t currentTimeUs)
static bool armedBeeperOn = false; static bool armedBeeperOn = false;
static bool airmodeIsActivated; static bool airmodeIsActivated;
calculateRxChannelsAndUpdateFailsafe(currentTimeUs); if (!calculateRxChannelsAndUpdateFailsafe(currentTimeUs)) {
return;
}
// in 3D mode, we need to be able to disarm by switch at any time // in 3D mode, we need to be able to disarm by switch at any time
if (feature(FEATURE_3D)) { if (feature(FEATURE_3D)) {

View file

@ -133,6 +133,9 @@ static volatile bool clearToSend = false;
static volatile uint8_t framePosition = 0; static volatile uint8_t framePosition = 0;
static smartPortPayload_t *mspPayload = NULL;
static timeUs_t lastRcFrameReceivedMs = 0;
static serialPort_t *fportPort; static serialPort_t *fportPort;
static bool telemetryEnabled = false; static bool telemetryEnabled = false;
@ -239,9 +242,6 @@ static bool checkChecksum(uint8_t *data, uint8_t length)
static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig) static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
{ {
static smartPortPayload_t payloadBuffer; static smartPortPayload_t payloadBuffer;
static smartPortPayload_t *mspPayload = NULL;
static bool hasTelemetryRequest = false;
static timeUs_t lastRcFrameReceivedMs = 0;
uint8_t result = RX_FRAME_PENDING; uint8_t result = RX_FRAME_PENDING;
@ -261,7 +261,7 @@ static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
if (frameLength != FPORT_FRAME_PAYLOAD_LENGTH_CONTROL) { if (frameLength != FPORT_FRAME_PAYLOAD_LENGTH_CONTROL) {
reportFrameError(DEBUG_FPORT_ERROR_TYPE_SIZE); reportFrameError(DEBUG_FPORT_ERROR_TYPE_SIZE);
} else { } else {
result = sbusChannelsDecode(rxRuntimeConfig, &frame->data.controlData.channels); result |= sbusChannelsDecode(rxRuntimeConfig, &frame->data.controlData.channels);
setRssiUnfiltered(scaleRange(constrain(frame->data.controlData.rssi, 0, 100), 0, 100, 0, 1024), RSSI_SOURCE_RX_PROTOCOL); setRssiUnfiltered(scaleRange(constrain(frame->data.controlData.rssi, 0, 100), 0, 100, 0, 1024), RSSI_SOURCE_RX_PROTOCOL);
@ -282,13 +282,14 @@ static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
switch(frame->data.telemetryData.frameId) { switch(frame->data.telemetryData.frameId) {
case FPORT_FRAME_ID_NULL: case FPORT_FRAME_ID_NULL:
case FPORT_FRAME_ID_DATA: // never used case FPORT_FRAME_ID_DATA: // never used
hasTelemetryRequest = true; result = result | RX_FRAME_PROCESSING_REQUIRED;
break; break;
case FPORT_FRAME_ID_READ: case FPORT_FRAME_ID_READ:
case FPORT_FRAME_ID_WRITE: // never used case FPORT_FRAME_ID_WRITE: // never used
memcpy(&payloadBuffer, &frame->data.telemetryData, sizeof(smartPortPayload_t)); memcpy(&payloadBuffer, &frame->data.telemetryData, sizeof(smartPortPayload_t));
mspPayload = &payloadBuffer; mspPayload = &payloadBuffer;
result = result | RX_FRAME_PROCESSING_REQUIRED;
break; break;
default: default:
@ -309,8 +310,23 @@ static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
} }
rxBufferReadIndex = (rxBufferReadIndex + 1) % NUM_RX_BUFFERS; rxBufferReadIndex = (rxBufferReadIndex + 1) % NUM_RX_BUFFERS;
}
if (lastRcFrameReceivedMs && ((millis() - lastRcFrameReceivedMs) > FPORT_MAX_TELEMETRY_AGE_MS)) {
setRssiFiltered(0, RSSI_SOURCE_RX_PROTOCOL);
lastRcFrameReceivedMs = 0;
}
return result;
}
static bool fportProcessFrame(const rxRuntimeConfig_t *rxRuntimeConfig)
{
UNUSED(rxRuntimeConfig);
bool processingDone = false;
#if defined(USE_TELEMETRY_SMARTPORT) #if defined(USE_TELEMETRY_SMARTPORT)
} else {
timeUs_t currentTimeUs = micros(); timeUs_t currentTimeUs = micros();
if (telemetryEnabled && clearToSend && cmpTimeUs(currentTimeUs, lastTelemetryFrameReceivedUs) >= FPORT_MIN_TELEMETRY_RESPONSE_DELAY_US) { if (telemetryEnabled && clearToSend && cmpTimeUs(currentTimeUs, lastTelemetryFrameReceivedUs) >= FPORT_MIN_TELEMETRY_RESPONSE_DELAY_US) {
if (cmpTimeUs(currentTimeUs, lastTelemetryFrameReceivedUs) > FPORT_MAX_TELEMETRY_RESPONSE_DELAY_US) { if (cmpTimeUs(currentTimeUs, lastTelemetryFrameReceivedUs) > FPORT_MAX_TELEMETRY_RESPONSE_DELAY_US) {
@ -320,9 +336,7 @@ static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
if (clearToSend) { if (clearToSend) {
DEBUG_SET(DEBUG_FPORT, DEBUG_FPORT_TELEMETRY_DELAY, currentTimeUs - lastTelemetryFrameReceivedUs); DEBUG_SET(DEBUG_FPORT, DEBUG_FPORT_TELEMETRY_DELAY, currentTimeUs - lastTelemetryFrameReceivedUs);
if (hasTelemetryRequest || mspPayload) {
processSmartPortTelemetry(mspPayload, &clearToSend, NULL); processSmartPortTelemetry(mspPayload, &clearToSend, NULL);
}
if (clearToSend) { if (clearToSend) {
smartPortWriteFrameFport(&emptySmartPortFrame); smartPortWriteFrameFport(&emptySmartPortFrame);
@ -330,16 +344,14 @@ static uint8_t fportFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
clearToSend = false; clearToSend = false;
} }
} }
processingDone = true;
} }
#else
processingDone = true;
#endif #endif
}
if (lastRcFrameReceivedMs && ((millis() - lastRcFrameReceivedMs) > FPORT_MAX_TELEMETRY_AGE_MS)) { return processingDone;
setRssiFiltered(0, RSSI_SOURCE_RX_PROTOCOL);
lastRcFrameReceivedMs = 0;
}
return result;
} }
bool fportRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig) bool fportRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
@ -352,6 +364,7 @@ bool fportRxInit(const rxConfig_t *rxConfig, rxRuntimeConfig_t *rxRuntimeConfig)
rxRuntimeConfig->rxRefreshRate = 11000; rxRuntimeConfig->rxRefreshRate = 11000;
rxRuntimeConfig->rcFrameStatusFn = fportFrameStatus; rxRuntimeConfig->rcFrameStatusFn = fportFrameStatus;
rxRuntimeConfig->rcProcessFrameFn = fportProcessFrame;
const serialPortConfig_t *portConfig = findSerialPortConfig(FUNCTION_RX_SERIAL); const serialPortConfig_t *portConfig = findSerialPortConfig(FUNCTION_RX_SERIAL);
if (!portConfig) { if (!portConfig) {

View file

@ -76,6 +76,8 @@ static timeUs_t lastMspRssiUpdateUs = 0;
rssiSource_t rssiSource; rssiSource_t rssiSource;
static bool rxDataReceived = false; static bool rxDataReceived = false;
static bool processingRequired = false;
static bool rxSignalReceived = false; static bool rxSignalReceived = false;
static bool rxSignalReceivedNotDataDriven = false; static bool rxSignalReceivedNotDataDriven = false;
static bool rxFlightChannelsValid = false; static bool rxFlightChannelsValid = false;
@ -204,6 +206,13 @@ static uint8_t nullFrameStatus(rxRuntimeConfig_t *rxRuntimeConfig)
return RX_FRAME_PENDING; return RX_FRAME_PENDING;
} }
static bool nullProcessFrame(const rxRuntimeConfig_t *rxRuntimeConfig)
{
UNUSED(rxRuntimeConfig);
return true;
}
#define REQUIRED_CHANNEL_MASK 0x0F // first 4 channels #define REQUIRED_CHANNEL_MASK 0x0F // first 4 channels
static uint8_t validFlightChannelMask; static uint8_t validFlightChannelMask;
@ -302,6 +311,7 @@ void rxInit(void)
{ {
rxRuntimeConfig.rcReadRawFn = nullReadRawRC; rxRuntimeConfig.rcReadRawFn = nullReadRawRC;
rxRuntimeConfig.rcFrameStatusFn = nullFrameStatus; rxRuntimeConfig.rcFrameStatusFn = nullFrameStatus;
rxRuntimeConfig.rcProcessFrameFn = nullProcessFrame;
rcSampleIndex = 0; rcSampleIndex = 0;
needRxSignalMaxDelayUs = DELAY_10_HZ; needRxSignalMaxDelayUs = DELAY_10_HZ;
@ -433,7 +443,6 @@ bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTime)
} else } else
#endif #endif
{ {
rxDataReceived = false;
const uint8_t frameStatus = rxRuntimeConfig.rcFrameStatusFn(&rxRuntimeConfig); const uint8_t frameStatus = rxRuntimeConfig.rcFrameStatusFn(&rxRuntimeConfig);
if (frameStatus & RX_FRAME_COMPLETE) { if (frameStatus & RX_FRAME_COMPLETE) {
rxDataReceived = true; rxDataReceived = true;
@ -441,8 +450,12 @@ bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTime)
rxSignalReceived = !rxIsInFailsafeMode; rxSignalReceived = !rxIsInFailsafeMode;
needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs; needRxSignalBefore = currentTimeUs + needRxSignalMaxDelayUs;
} }
if (frameStatus & RX_FRAME_PROCESSING_REQUIRED) {
processingRequired = true;
} }
return rxDataReceived || (currentTimeUs >= rxUpdateAt); // data driven or 50Hz }
return rxDataReceived || processingRequired || (currentTimeUs >= rxUpdateAt); // data driven or 50Hz
} }
static uint16_t calculateChannelMovingAverage(uint8_t chan, uint16_t sample) static uint16_t calculateChannelMovingAverage(uint8_t chan, uint16_t sample)
@ -597,8 +610,18 @@ static void detectAndApplySignalLossBehaviour(timeUs_t currentTimeUs)
#endif #endif
} }
void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs) bool calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs)
{ {
if (processingRequired) {
processingRequired = !rxRuntimeConfig.rcProcessFrameFn(&rxRuntimeConfig);
}
if (!rxDataReceived) {
return false;
}
rxDataReceived = false;
rxUpdateAt = currentTimeUs + DELAY_50_HZ; rxUpdateAt = currentTimeUs + DELAY_50_HZ;
// only proceed when no more samples to skip and suspend period is over // only proceed when no more samples to skip and suspend period is over
@ -606,13 +629,16 @@ void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs)
if (currentTimeUs > suspendRxSignalUntil) { if (currentTimeUs > suspendRxSignalUntil) {
skipRxSamples--; skipRxSamples--;
} }
return;
return true;
} }
readRxChannelsApplyRanges(); readRxChannelsApplyRanges();
detectAndApplySignalLossBehaviour(currentTimeUs); detectAndApplySignalLossBehaviour(currentTimeUs);
rcSampleIndex++; rcSampleIndex++;
return true;
} }
void parseRcChannels(const char *input, rxConfig_t *rxConfig) void parseRcChannels(const char *input, rxConfig_t *rxConfig)

View file

@ -43,7 +43,8 @@
typedef enum { typedef enum {
RX_FRAME_PENDING = 0, RX_FRAME_PENDING = 0,
RX_FRAME_COMPLETE = (1 << 0), RX_FRAME_COMPLETE = (1 << 0),
RX_FRAME_FAILSAFE = (1 << 1) RX_FRAME_FAILSAFE = (1 << 1),
RX_FRAME_PROCESSING_REQUIRED = (1 << 2),
} rxFrameState_e; } rxFrameState_e;
typedef enum { typedef enum {
@ -150,12 +151,14 @@ PG_DECLARE(rxConfig_t, rxConfig);
struct rxRuntimeConfig_s; struct rxRuntimeConfig_s;
typedef uint16_t (*rcReadRawDataFnPtr)(const struct rxRuntimeConfig_s *rxRuntimeConfig, uint8_t chan); // used by receiver driver to return channel data typedef uint16_t (*rcReadRawDataFnPtr)(const struct rxRuntimeConfig_s *rxRuntimeConfig, uint8_t chan); // used by receiver driver to return channel data
typedef uint8_t (*rcFrameStatusFnPtr)(struct rxRuntimeConfig_s *rxRuntimeConfig); typedef uint8_t (*rcFrameStatusFnPtr)(struct rxRuntimeConfig_s *rxRuntimeConfig);
typedef bool (*rcProcessFrameFnPtr)(const struct rxRuntimeConfig_s *rxRuntimeConfig);
typedef struct rxRuntimeConfig_s { typedef struct rxRuntimeConfig_s {
uint8_t channelCount; // number of RC channels as reported by current input driver uint8_t channelCount; // number of RC channels as reported by current input driver
uint16_t rxRefreshRate; uint16_t rxRefreshRate;
rcReadRawDataFnPtr rcReadRawFn; rcReadRawDataFnPtr rcReadRawFn;
rcFrameStatusFnPtr rcFrameStatusFn; rcFrameStatusFnPtr rcFrameStatusFn;
rcProcessFrameFnPtr rcProcessFrameFn;
uint16_t *channelData; uint16_t *channelData;
void *frameData; void *frameData;
} rxRuntimeConfig_t; } rxRuntimeConfig_t;
@ -176,7 +179,7 @@ void rxInit(void);
bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs); bool rxUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs);
bool rxIsReceivingSignal(void); bool rxIsReceivingSignal(void);
bool rxAreFlightChannelsValid(void); bool rxAreFlightChannelsValid(void);
void calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs); bool calculateRxChannelsAndUpdateFailsafe(timeUs_t currentTimeUs);
void parseRcChannels(const char *input, rxConfig_t *rxConfig); void parseRcChannels(const char *input, rxConfig_t *rxConfig);

View file

@ -64,6 +64,7 @@ extern "C" {
gpsSolutionData_t gpsSol; gpsSolutionData_t gpsSol;
uint32_t targetPidLooptime; uint32_t targetPidLooptime;
bool cmsInMenu = false; bool cmsInMenu = false;
rxRuntimeConfig_t rxRuntimeConfig = {};
} }
uint32_t simulationFeatureFlags = 0; uint32_t simulationFeatureFlags = 0;
@ -634,7 +635,7 @@ extern "C" {
void mixTable(timeUs_t , uint8_t) {}; void mixTable(timeUs_t , uint8_t) {};
void writeMotors(void) {}; void writeMotors(void) {};
void writeServos(void) {}; void writeServos(void) {};
void calculateRxChannelsAndUpdateFailsafe(timeUs_t) {} bool calculateRxChannelsAndUpdateFailsafe(timeUs_t) { return true; }
bool isMixerUsingServos(void) { return false; } bool isMixerUsingServos(void) { return false; }
void gyroUpdate(timeUs_t) {} void gyroUpdate(timeUs_t) {}
timeDelta_t getTaskDeltaTime(cfTaskId_e) { return 0; } timeDelta_t getTaskDeltaTime(cfTaskId_e) { return 0; }