mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 16:25:31 +03:00
Merge pull request #11340 from SteveCEvans/osd_peak_task
Increase number of element groups and use peak hold task estimation for OSD
This commit is contained in:
commit
8701d9141f
7 changed files with 108 additions and 80 deletions
|
@ -635,7 +635,7 @@ void spiSequenceStart(const extDevice_t *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use DMA if possible
|
// Use DMA if possible
|
||||||
if (bus->useDMA && dmaSafe && ((segmentCount > 1) || (xferLen > 8))) {
|
if (bus->useDMA && dmaSafe && ((segmentCount > 1) || (xferLen >= 8))) {
|
||||||
// Intialise the init structures for the first transfer
|
// Intialise the init structures for the first transfer
|
||||||
spiInternalInitStream(dev, false);
|
spiInternalInitStream(dev, false);
|
||||||
|
|
||||||
|
|
|
@ -367,7 +367,7 @@ void spiSequenceStart(const extDevice_t *dev)
|
||||||
xferLen += checkSegment->len;
|
xferLen += checkSegment->len;
|
||||||
}
|
}
|
||||||
// Use DMA if possible
|
// Use DMA if possible
|
||||||
if (bus->useDMA && dmaSafe && ((segmentCount > 1) || (xferLen > 8))) {
|
if (bus->useDMA && dmaSafe && ((segmentCount > 1) || (xferLen >= 8))) {
|
||||||
// Intialise the init structures for the first transfer
|
// Intialise the init structures for the first transfer
|
||||||
spiInternalInitStream(dev, false);
|
spiInternalInitStream(dev, false);
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,9 @@ static uint8_t shadowBuffer[VIDEO_BUFFER_CHARS_PAL];
|
||||||
//Max bytes to update in one call to max7456DrawScreen()
|
//Max bytes to update in one call to max7456DrawScreen()
|
||||||
|
|
||||||
#define MAX_BYTES2SEND 250
|
#define MAX_BYTES2SEND 250
|
||||||
#define MAX_BYTES2SEND_POLLED 20
|
#define MAX_BYTES2SEND_POLLED 12
|
||||||
|
#define MAX_ENCODE_US 20
|
||||||
|
#define MAX_ENCODE_US_POLLED 10
|
||||||
|
|
||||||
static DMA_DATA uint8_t spiBuf[MAX_BYTES2SEND];
|
static DMA_DATA uint8_t spiBuf[MAX_BYTES2SEND];
|
||||||
|
|
||||||
|
@ -622,11 +624,13 @@ bool max7456DrawScreen(void)
|
||||||
uint8_t *buffer = getActiveLayerBuffer();
|
uint8_t *buffer = getActiveLayerBuffer();
|
||||||
int spiBufIndex = 0;
|
int spiBufIndex = 0;
|
||||||
int maxSpiBufStartIndex;
|
int maxSpiBufStartIndex;
|
||||||
|
timeDelta_t maxEncodeTime;
|
||||||
bool setAddress = true;
|
bool setAddress = true;
|
||||||
bool autoInc = false;
|
bool autoInc = false;
|
||||||
int posLimit = pos + (maxScreenSize / 2);
|
int posLimit = pos + (maxScreenSize / 2);
|
||||||
|
|
||||||
maxSpiBufStartIndex = spiUseMOSI_DMA(dev) ? MAX_BYTES2SEND : MAX_BYTES2SEND_POLLED;
|
maxSpiBufStartIndex = spiUseMOSI_DMA(dev) ? MAX_BYTES2SEND : MAX_BYTES2SEND_POLLED;
|
||||||
|
maxEncodeTime = spiUseMOSI_DMA(dev) ? MAX_ENCODE_US : MAX_ENCODE_US_POLLED;
|
||||||
|
|
||||||
// Abort for now if the bus is still busy
|
// Abort for now if the bus is still busy
|
||||||
if (spiIsBusy(dev)) {
|
if (spiIsBusy(dev)) {
|
||||||
|
@ -634,11 +638,13 @@ bool max7456DrawScreen(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow for 8 bytes followed by an ESCAPE and reset of DMM at end of buffer
|
timeUs_t startTime = micros();
|
||||||
maxSpiBufStartIndex -= 12;
|
|
||||||
|
// Allow for an ESCAPE, a reset of DMM and a two byte MAX7456ADD_DMM command at end of buffer
|
||||||
|
maxSpiBufStartIndex -= 4;
|
||||||
|
|
||||||
// Initialise the transfer buffer
|
// Initialise the transfer buffer
|
||||||
while ((spiBufIndex < maxSpiBufStartIndex) && (pos < posLimit)) {
|
while ((spiBufIndex < maxSpiBufStartIndex) && (pos < posLimit) && (cmpTimeUs(micros(), startTime) < maxEncodeTime)) {
|
||||||
if (buffer[pos] != shadowBuffer[pos]) {
|
if (buffer[pos] != shadowBuffer[pos]) {
|
||||||
if (buffer[pos] == 0xff) {
|
if (buffer[pos] == 0xff) {
|
||||||
buffer[pos] = ' ';
|
buffer[pos] = ' ';
|
||||||
|
|
|
@ -182,7 +182,7 @@ bool taskUpdateRxMainInProgress()
|
||||||
|
|
||||||
static void taskUpdateRxMain(timeUs_t currentTimeUs)
|
static void taskUpdateRxMain(timeUs_t currentTimeUs)
|
||||||
{
|
{
|
||||||
static timeDelta_t rxStateDurationFracUs[RX_STATE_COUNT];
|
static timeDelta_t rxStateDurationFractionUs[RX_STATE_COUNT];
|
||||||
timeDelta_t executeTimeUs;
|
timeDelta_t executeTimeUs;
|
||||||
rxState_e oldRxState = rxState;
|
rxState_e oldRxState = rxState;
|
||||||
timeDelta_t anticipatedExecutionTime;
|
timeDelta_t anticipatedExecutionTime;
|
||||||
|
@ -230,23 +230,23 @@ static void taskUpdateRxMain(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
// If the scheduler has reduced the anticipatedExecutionTime due to task aging, pick that up
|
// If the scheduler has reduced the anticipatedExecutionTime due to task aging, pick that up
|
||||||
anticipatedExecutionTime = schedulerGetNextStateTime();
|
anticipatedExecutionTime = schedulerGetNextStateTime();
|
||||||
if (anticipatedExecutionTime != (rxStateDurationFracUs[oldRxState] >> RX_TASK_DECAY_SHIFT)) {
|
if (anticipatedExecutionTime != (rxStateDurationFractionUs[oldRxState] >> RX_TASK_DECAY_SHIFT)) {
|
||||||
rxStateDurationFracUs[oldRxState] = anticipatedExecutionTime << RX_TASK_DECAY_SHIFT;
|
rxStateDurationFractionUs[oldRxState] = anticipatedExecutionTime << RX_TASK_DECAY_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (executeTimeUs > (rxStateDurationFracUs[oldRxState] >> RX_TASK_DECAY_SHIFT)) {
|
if (executeTimeUs > (rxStateDurationFractionUs[oldRxState] >> RX_TASK_DECAY_SHIFT)) {
|
||||||
rxStateDurationFracUs[oldRxState] = executeTimeUs << RX_TASK_DECAY_SHIFT;
|
rxStateDurationFractionUs[oldRxState] = executeTimeUs << RX_TASK_DECAY_SHIFT;
|
||||||
} else {
|
} else {
|
||||||
// Slowly decay the max time
|
// Slowly decay the max time
|
||||||
rxStateDurationFracUs[oldRxState]--;
|
rxStateDurationFractionUs[oldRxState]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debugMode == DEBUG_RX_STATE_TIME) {
|
if (debugMode == DEBUG_RX_STATE_TIME) {
|
||||||
debug[oldRxState] = rxStateDurationFracUs[oldRxState] >> RX_TASK_DECAY_SHIFT;
|
debug[oldRxState] = rxStateDurationFractionUs[oldRxState] >> RX_TASK_DECAY_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
schedulerSetNextStateTime(rxStateDurationFracUs[rxState] >> RX_TASK_DECAY_SHIFT);
|
schedulerSetNextStateTime(rxStateDurationFractionUs[rxState] >> RX_TASK_DECAY_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -766,7 +766,7 @@ void gpsUpdate(timeUs_t currentTimeUs)
|
||||||
{
|
{
|
||||||
static gpsState_e gpsStateDurationUs[GPS_STATE_COUNT];
|
static gpsState_e gpsStateDurationUs[GPS_STATE_COUNT];
|
||||||
timeUs_t executeTimeUs;
|
timeUs_t executeTimeUs;
|
||||||
gpsState_e gpsCurState = gpsData.state;
|
gpsState_e gpsCurrentState = gpsData.state;
|
||||||
|
|
||||||
// read out available GPS bytes
|
// read out available GPS bytes
|
||||||
if (gpsPort) {
|
if (gpsPort) {
|
||||||
|
@ -861,8 +861,8 @@ void gpsUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
executeTimeUs = micros() - currentTimeUs;
|
executeTimeUs = micros() - currentTimeUs;
|
||||||
|
|
||||||
if (executeTimeUs > gpsStateDurationUs[gpsCurState]) {
|
if (executeTimeUs > gpsStateDurationUs[gpsCurrentState]) {
|
||||||
gpsStateDurationUs[gpsCurState] = executeTimeUs;
|
gpsStateDurationUs[gpsCurrentState] = executeTimeUs;
|
||||||
}
|
}
|
||||||
schedulerSetNextStateTime(gpsStateDurationUs[gpsData.state]);
|
schedulerSetNextStateTime(gpsStateDurationUs[gpsData.state]);
|
||||||
|
|
||||||
|
|
|
@ -188,16 +188,19 @@ const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Group elements in a number of groups to reduce task scheduling overhead
|
// Group elements in a number of groups to reduce task scheduling overhead
|
||||||
#define OSD_GROUP_COUNT 20
|
#define OSD_GROUP_COUNT OSD_ITEM_COUNT
|
||||||
// Aim to render a group of elements within a target time
|
// Aim to render a group of elements within a target time
|
||||||
#define OSD_ELEMENT_RENDER_TARGET 40
|
#define OSD_ELEMENT_RENDER_TARGET 30
|
||||||
// Allow a margin by which a group render can exceed that of the sum of the elements before declaring insane
|
// Allow a margin by which a group render can exceed that of the sum of the elements before declaring insane
|
||||||
// This will most likely be violated by a USB interrupt whilst using the CLI
|
// This will most likely be violated by a USB interrupt whilst using the CLI
|
||||||
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 5
|
#if defined(STM32F411xE)
|
||||||
// Safe margin when rendering elements
|
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 7
|
||||||
#define OSD_ELEMENT_RENDER_MARGIN 5
|
#else
|
||||||
// Safe margin in other states
|
#define OSD_ELEMENT_RENDER_GROUP_MARGIN 2
|
||||||
#define OSD_MARGIN 2
|
#endif
|
||||||
|
#define OSD_TASK_MARGIN 1
|
||||||
|
// Decay the estimated max task duration by 1/(1 << OSD_EXEC_TIME_SHIFT) on every invocation
|
||||||
|
#define OSD_EXEC_TIME_SHIFT 8
|
||||||
|
|
||||||
// Format a float to the specified number of decimal places with optional rounding.
|
// Format a float to the specified number of decimal places with optional rounding.
|
||||||
// OSD symbols can optionally be placed before and after the formatted number (use SYM_NONE for no symbol).
|
// OSD symbols can optionally be placed before and after the formatted number (use SYM_NONE for no symbol).
|
||||||
|
@ -1128,6 +1131,7 @@ typedef enum {
|
||||||
OSD_STATE_PROCESS_STATS3,
|
OSD_STATE_PROCESS_STATS3,
|
||||||
OSD_STATE_UPDATE_ALARMS,
|
OSD_STATE_UPDATE_ALARMS,
|
||||||
OSD_STATE_UPDATE_CANVAS,
|
OSD_STATE_UPDATE_CANVAS,
|
||||||
|
OSD_STATE_GROUP_ELEMENTS,
|
||||||
OSD_STATE_UPDATE_ELEMENTS,
|
OSD_STATE_UPDATE_ELEMENTS,
|
||||||
OSD_STATE_UPDATE_HEARTBEAT,
|
OSD_STATE_UPDATE_HEARTBEAT,
|
||||||
OSD_STATE_COMMIT,
|
OSD_STATE_COMMIT,
|
||||||
|
@ -1165,16 +1169,16 @@ bool osdUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs)
|
||||||
// Called when there is OSD update work to be done
|
// Called when there is OSD update work to be done
|
||||||
void osdUpdate(timeUs_t currentTimeUs)
|
void osdUpdate(timeUs_t currentTimeUs)
|
||||||
{
|
{
|
||||||
static timeUs_t osdStateDurationUs[OSD_STATE_COUNT] = { 0 };
|
static uint16_t osdStateDurationFractionUs[OSD_STATE_COUNT] = { 0 };
|
||||||
static timeUs_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
static uint32_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
||||||
static timeUs_t osdElementGroupMembership[OSD_ITEM_COUNT];
|
static uint8_t osdElementGroupMemberships[OSD_ITEM_COUNT];
|
||||||
static timeUs_t osdElementGroupTargetUs[OSD_GROUP_COUNT] = { 0 };
|
static uint16_t osdElementGroupTargetFractionUs[OSD_GROUP_COUNT] = { 0 };
|
||||||
static timeUs_t osdElementGroupDurationUs[OSD_GROUP_COUNT] = { 0 };
|
static uint16_t osdElementGroupDurationFractionUs[OSD_GROUP_COUNT] = { 0 };
|
||||||
static uint8_t osdElementGroup;
|
static uint8_t osdElementGroup;
|
||||||
static bool firstPass = true;
|
static bool firstPass = true;
|
||||||
uint8_t osdCurElementGroup = 0;
|
uint8_t osdCurrentElementGroup = 0;
|
||||||
timeUs_t executeTimeUs;
|
timeUs_t executeTimeUs;
|
||||||
osdState_e osdCurState = osdState;
|
osdState_e osdCurrentState = osdState;
|
||||||
|
|
||||||
if (osdState != OSD_STATE_UPDATE_CANVAS) {
|
if (osdState != OSD_STATE_UPDATE_CANVAS) {
|
||||||
schedulerIgnoreTaskExecRate();
|
schedulerIgnoreTaskExecRate();
|
||||||
|
@ -1213,7 +1217,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
case OSD_STATE_UPDATE_HEARTBEAT:
|
case OSD_STATE_UPDATE_HEARTBEAT:
|
||||||
if (displayHeartbeat(osdDisplayPort)) {
|
if (displayHeartbeat(osdDisplayPort)) {
|
||||||
// Extraordinary action was taken, so return without allowing osdStateDurationUs table to be updated
|
// Extraordinary action was taken, so return without allowing osdStateDurationFractionUs table to be updated
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,58 +1304,65 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
osdSyncBlink();
|
osdSyncBlink();
|
||||||
|
|
||||||
uint8_t elementGroup;
|
osdState = OSD_STATE_GROUP_ELEMENTS;
|
||||||
uint8_t activeElements = osdGetActiveElementCount();
|
|
||||||
|
|
||||||
// Reset groupings
|
break;
|
||||||
for (elementGroup = 0; elementGroup < OSD_GROUP_COUNT; elementGroup++) {
|
|
||||||
if (osdElementGroupDurationUs[elementGroup] > (osdElementGroupTargetUs[elementGroup] + OSD_ELEMENT_RENDER_GROUP_MARGIN)) {
|
|
||||||
osdElementGroupDurationUs[elementGroup] = 0;
|
|
||||||
}
|
|
||||||
osdElementGroupTargetUs[elementGroup] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
elementGroup = 0;
|
case OSD_STATE_GROUP_ELEMENTS:
|
||||||
|
{
|
||||||
|
uint8_t elementGroup;
|
||||||
|
uint8_t activeElements = osdGetActiveElementCount();
|
||||||
|
|
||||||
// Based on the current element rendering, group to execute in approx 40us
|
// Reset groupings
|
||||||
for (uint8_t curElement = 0; curElement < activeElements; curElement++) {
|
for (elementGroup = 0; elementGroup < OSD_GROUP_COUNT; elementGroup++) {
|
||||||
if ((osdElementGroupTargetUs[elementGroup] == 0) ||
|
if (osdElementGroupDurationFractionUs[elementGroup] > (OSD_ELEMENT_RENDER_TARGET << OSD_EXEC_TIME_SHIFT)) {
|
||||||
((osdElementGroupTargetUs[elementGroup] + osdElementDurationUs[curElement]) <= OSD_ELEMENT_RENDER_TARGET) ||
|
osdElementGroupDurationFractionUs[elementGroup] = 0;
|
||||||
(elementGroup == (OSD_GROUP_COUNT - 1))) {
|
|
||||||
osdElementGroupTargetUs[elementGroup] += osdElementDurationUs[curElement];
|
|
||||||
// If group membership changes, reset the stats for the group
|
|
||||||
if (osdElementGroupMembership[curElement] != elementGroup) {
|
|
||||||
osdElementGroupDurationUs[elementGroup] = 0;
|
|
||||||
}
|
}
|
||||||
osdElementGroupMembership[curElement] = elementGroup;
|
osdElementGroupTargetFractionUs[elementGroup] = 0;
|
||||||
} else {
|
|
||||||
elementGroup++;
|
|
||||||
// Try again for this element
|
|
||||||
curElement--;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Start with group 0
|
elementGroup = 0;
|
||||||
osdElementGroup = 0;
|
|
||||||
|
|
||||||
if (activeElements > 0) {
|
// Based on the current element rendering, group to execute in approx 40us
|
||||||
osdState = OSD_STATE_UPDATE_ELEMENTS;
|
for (uint8_t curElement = 0; curElement < activeElements; curElement++) {
|
||||||
} else {
|
if ((osdElementGroupTargetFractionUs[elementGroup] == 0) ||
|
||||||
osdState = OSD_STATE_COMMIT;
|
(osdElementGroupTargetFractionUs[elementGroup] + (osdElementDurationUs[curElement]) <= (OSD_ELEMENT_RENDER_TARGET << OSD_EXEC_TIME_SHIFT)) ||
|
||||||
|
(elementGroup == (OSD_GROUP_COUNT - 1))) {
|
||||||
|
osdElementGroupTargetFractionUs[elementGroup] += osdElementDurationUs[curElement];
|
||||||
|
// If group membership changes, reset the stats for the group
|
||||||
|
if (osdElementGroupMemberships[curElement] != elementGroup) {
|
||||||
|
osdElementGroupDurationFractionUs[elementGroup] = osdElementGroupTargetFractionUs[elementGroup] + (OSD_ELEMENT_RENDER_GROUP_MARGIN << OSD_EXEC_TIME_SHIFT);
|
||||||
|
}
|
||||||
|
osdElementGroupMemberships[curElement] = elementGroup;
|
||||||
|
} else {
|
||||||
|
elementGroup++;
|
||||||
|
// Try again for this element
|
||||||
|
curElement--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start with group 0
|
||||||
|
osdElementGroup = 0;
|
||||||
|
|
||||||
|
if (activeElements > 0) {
|
||||||
|
osdState = OSD_STATE_UPDATE_ELEMENTS;
|
||||||
|
} else {
|
||||||
|
osdState = OSD_STATE_COMMIT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OSD_STATE_UPDATE_ELEMENTS:
|
case OSD_STATE_UPDATE_ELEMENTS:
|
||||||
{
|
{
|
||||||
osdCurElementGroup = osdElementGroup;
|
osdCurrentElementGroup = osdElementGroup;
|
||||||
bool moreElements = true;
|
bool moreElements = true;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
timeUs_t startElementTime = micros();
|
timeUs_t startElementTime = micros();
|
||||||
uint8_t osdCurElement = osdGetActiveElement();
|
uint8_t osdCurrentElement = osdGetActiveElement();
|
||||||
|
|
||||||
// This element should be rendered in the next group
|
// This element should be rendered in the next group
|
||||||
if (osdElementGroupMembership[osdCurElement] != osdElementGroup) {
|
if (osdElementGroupMemberships[osdCurrentElement] != osdElementGroup) {
|
||||||
osdElementGroup++;
|
osdElementGroup++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1360,8 +1371,11 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
executeTimeUs = micros() - startElementTime;
|
executeTimeUs = micros() - startElementTime;
|
||||||
|
|
||||||
if (executeTimeUs > osdElementDurationUs[osdCurElement]) {
|
if (executeTimeUs > (osdElementDurationUs[osdCurrentElement] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdElementDurationUs[osdCurElement] = executeTimeUs;
|
osdElementDurationUs[osdCurrentElement] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
|
} else if (osdElementDurationUs[osdCurrentElement] > 0) {
|
||||||
|
// Slowly decay the max time
|
||||||
|
osdElementDurationUs[osdCurrentElement]--;
|
||||||
}
|
}
|
||||||
} while (moreElements);
|
} while (moreElements);
|
||||||
|
|
||||||
|
@ -1399,6 +1413,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
|
|
||||||
firstPass = false;
|
firstPass = false;
|
||||||
osdState = OSD_STATE_IDLE;
|
osdState = OSD_STATE_IDLE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OSD_STATE_IDLE:
|
case OSD_STATE_IDLE:
|
||||||
|
@ -1414,27 +1429,32 @@ void osdUpdate(timeUs_t currentTimeUs)
|
||||||
// On the first pass no element groups will have been formed, so all elements will have been
|
// On the first pass no element groups will have been formed, so all elements will have been
|
||||||
// rendered which is unrepresentative, so ignore
|
// rendered which is unrepresentative, so ignore
|
||||||
if (!firstPass) {
|
if (!firstPass) {
|
||||||
if (osdCurState == OSD_STATE_UPDATE_ELEMENTS) {
|
if (osdCurrentState == OSD_STATE_UPDATE_ELEMENTS) {
|
||||||
if (executeTimeUs > osdElementGroupDurationUs[osdCurElementGroup]) {
|
if (executeTimeUs > (osdElementGroupDurationFractionUs[osdCurrentElementGroup] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdElementGroupDurationUs[osdCurElementGroup] = executeTimeUs;
|
osdElementGroupDurationFractionUs[osdCurrentElementGroup] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
|
} else if (osdElementGroupDurationFractionUs[osdCurrentElementGroup] > 0) {
|
||||||
|
// Slowly decay the max time
|
||||||
|
osdElementGroupDurationFractionUs[osdCurrentElementGroup]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (executeTimeUs > osdStateDurationUs[osdCurState]) {
|
if (executeTimeUs > (osdStateDurationFractionUs[osdCurrentState] >> OSD_EXEC_TIME_SHIFT)) {
|
||||||
osdStateDurationUs[osdCurState] = executeTimeUs;
|
osdStateDurationFractionUs[osdCurrentState] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||||
|
} else if (osdStateDurationFractionUs[osdCurrentState] > 0) {
|
||||||
|
// Slowly decay the max time
|
||||||
|
osdStateDurationFractionUs[osdCurrentState]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (osdState == OSD_STATE_UPDATE_ELEMENTS) {
|
if (osdState == OSD_STATE_UPDATE_ELEMENTS) {
|
||||||
schedulerSetNextStateTime(osdElementGroupDurationUs[osdElementGroup] + OSD_ELEMENT_RENDER_MARGIN);
|
schedulerSetNextStateTime((osdElementGroupDurationFractionUs[osdElementGroup] >> OSD_EXEC_TIME_SHIFT) + OSD_ELEMENT_RENDER_GROUP_MARGIN);
|
||||||
} else {
|
} else {
|
||||||
if (osdState == OSD_STATE_IDLE) {
|
if (osdState == OSD_STATE_IDLE) {
|
||||||
schedulerSetNextStateTime(osdStateDurationUs[OSD_STATE_CHECK] + OSD_MARGIN);
|
schedulerSetNextStateTime((osdStateDurationFractionUs[OSD_STATE_CHECK] >> OSD_EXEC_TIME_SHIFT) + OSD_TASK_MARGIN);
|
||||||
} else {
|
} else {
|
||||||
schedulerSetNextStateTime(osdStateDurationUs[osdState] + OSD_MARGIN);
|
schedulerSetNextStateTime((osdStateDurationFractionUs[osdState] >> OSD_EXEC_TIME_SHIFT) + OSD_TASK_MARGIN);
|
||||||
}
|
}
|
||||||
schedulerIgnoreTaskExecTime();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -709,7 +709,7 @@ TEST_F(OsdTest, TestAlarms)
|
||||||
// elements showing values in alarm range should flash
|
// elements showing values in alarm range should flash
|
||||||
simulationTime += 1000000;
|
simulationTime += 1000000;
|
||||||
simulationTime -= simulationTime % 1000000;
|
simulationTime -= simulationTime % 1000000;
|
||||||
timeUs_t startTime = simulationTime + 0.25e6;
|
timeUs_t startTime = simulationTime;
|
||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
// Blinking should happen at 2Hz
|
// Blinking should happen at 2Hz
|
||||||
simulationTime = startTime + i*0.25e6;
|
simulationTime = startTime + i*0.25e6;
|
||||||
|
@ -1083,6 +1083,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
|
||||||
// Delay as the warnings are flashing
|
// Delay as the warnings are flashing
|
||||||
simulationTime += 1000000;
|
simulationTime += 1000000;
|
||||||
simulationTime -= simulationTime % 1000000;
|
simulationTime -= simulationTime % 1000000;
|
||||||
|
simulationTime += 0.25e6;
|
||||||
osdRefresh();
|
osdRefresh();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -1098,6 +1099,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
|
||||||
// Delay as the warnings are flashing
|
// Delay as the warnings are flashing
|
||||||
simulationTime += 1000000;
|
simulationTime += 1000000;
|
||||||
simulationTime -= simulationTime % 1000000;
|
simulationTime -= simulationTime % 1000000;
|
||||||
|
simulationTime += 0.25e6;
|
||||||
osdRefresh();
|
osdRefresh();
|
||||||
|
|
||||||
// then
|
// then
|
||||||
|
@ -1204,7 +1206,7 @@ TEST_F(OsdTest, TestGpsElements)
|
||||||
// Sat indicator should blink and show "NC"
|
// Sat indicator should blink and show "NC"
|
||||||
simulationTime += 1000000;
|
simulationTime += 1000000;
|
||||||
simulationTime -= simulationTime % 1000000;
|
simulationTime -= simulationTime % 1000000;
|
||||||
timeUs_t startTime = simulationTime + 0.25e6;
|
timeUs_t startTime = simulationTime;
|
||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
// Blinking should happen at 2Hz
|
// Blinking should happen at 2Hz
|
||||||
simulationTime = startTime + i*0.25e6;
|
simulationTime = startTime + i*0.25e6;
|
||||||
|
@ -1228,7 +1230,7 @@ TEST_F(OsdTest, TestGpsElements)
|
||||||
// Sat indicator should blink and show "0"
|
// Sat indicator should blink and show "0"
|
||||||
simulationTime += 1000000;
|
simulationTime += 1000000;
|
||||||
simulationTime -= simulationTime % 1000000;
|
simulationTime -= simulationTime % 1000000;
|
||||||
startTime = simulationTime + 0.25e6;
|
startTime = simulationTime;
|
||||||
for (int i = 0; i < 15; i++) {
|
for (int i = 0; i < 15; i++) {
|
||||||
// Blinking should happen at 2Hz
|
// Blinking should happen at 2Hz
|
||||||
simulationTime = startTime + i*0.25e6;
|
simulationTime = startTime + i*0.25e6;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue