mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-26 01:35:41 +03:00
Add OSD_STATE_GROUP_ELEMENTS state to osdUpdate() and optimise DMA vs polled MAX7456 SPI access
This commit is contained in:
parent
28e596a500
commit
2e8d026b4e
5 changed files with 68 additions and 45 deletions
|
@ -635,7 +635,7 @@ void spiSequenceStart(const extDevice_t *dev)
|
|||
}
|
||||
|
||||
// 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
|
||||
spiInternalInitStream(dev, false);
|
||||
|
||||
|
|
|
@ -367,7 +367,7 @@ void spiSequenceStart(const extDevice_t *dev)
|
|||
xferLen += checkSegment->len;
|
||||
}
|
||||
// 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
|
||||
spiInternalInitStream(dev, false);
|
||||
|
||||
|
|
|
@ -206,7 +206,9 @@ static uint8_t shadowBuffer[VIDEO_BUFFER_CHARS_PAL];
|
|||
//Max bytes to update in one call to max7456DrawScreen()
|
||||
|
||||
#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];
|
||||
|
||||
|
@ -622,11 +624,13 @@ bool max7456DrawScreen(void)
|
|||
uint8_t *buffer = getActiveLayerBuffer();
|
||||
int spiBufIndex = 0;
|
||||
int maxSpiBufStartIndex;
|
||||
timeDelta_t maxEncodeTime;
|
||||
bool setAddress = true;
|
||||
bool autoInc = false;
|
||||
int posLimit = pos + (maxScreenSize / 2);
|
||||
|
||||
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
|
||||
if (spiIsBusy(dev)) {
|
||||
|
@ -634,11 +638,13 @@ bool max7456DrawScreen(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
// Allow for 8 bytes followed by an ESCAPE and reset of DMM at end of buffer
|
||||
maxSpiBufStartIndex -= 12;
|
||||
timeUs_t startTime = micros();
|
||||
|
||||
// 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
|
||||
while ((spiBufIndex < maxSpiBufStartIndex) && (pos < posLimit)) {
|
||||
while ((spiBufIndex < maxSpiBufStartIndex) && (pos < posLimit) && (cmpTimeUs(micros(), startTime) < maxEncodeTime)) {
|
||||
if (buffer[pos] != shadowBuffer[pos]) {
|
||||
if (buffer[pos] == 0xff) {
|
||||
buffer[pos] = ' ';
|
||||
|
|
|
@ -198,6 +198,7 @@ const osd_stats_e osdStatsDisplayOrder[OSD_STAT_COUNT] = {
|
|||
#else
|
||||
#define OSD_ELEMENT_RENDER_GROUP_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
|
||||
|
||||
|
@ -1130,6 +1131,7 @@ typedef enum {
|
|||
OSD_STATE_PROCESS_STATS3,
|
||||
OSD_STATE_UPDATE_ALARMS,
|
||||
OSD_STATE_UPDATE_CANVAS,
|
||||
OSD_STATE_GROUP_ELEMENTS,
|
||||
OSD_STATE_UPDATE_ELEMENTS,
|
||||
OSD_STATE_UPDATE_HEARTBEAT,
|
||||
OSD_STATE_COMMIT,
|
||||
|
@ -1164,14 +1166,13 @@ bool osdUpdateCheck(timeUs_t currentTimeUs, timeDelta_t currentDeltaTimeUs)
|
|||
return (osdState != OSD_STATE_IDLE);
|
||||
}
|
||||
|
||||
|
||||
// Called when there is OSD update work to be done
|
||||
void osdUpdate(timeUs_t currentTimeUs)
|
||||
{
|
||||
// Times are known to be short so use uint16_t rather than timeUs_t
|
||||
static uint16_t osdStateDurationFracUs[OSD_STATE_COUNT] = { 0 };
|
||||
static uint16_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
||||
static uint16_t osdElementGroupMembership[OSD_ITEM_COUNT];
|
||||
static uint32_t osdElementDurationUs[OSD_ITEM_COUNT] = { 0 };
|
||||
static uint8_t osdElementGroupMembership[OSD_ITEM_COUNT];
|
||||
static uint16_t osdElementGroupTargetFracUs[OSD_GROUP_COUNT] = { 0 };
|
||||
static uint16_t osdElementGroupDurationFracUs[OSD_GROUP_COUNT] = { 0 };
|
||||
static uint8_t osdElementGroup;
|
||||
|
@ -1304,6 +1305,12 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
|
||||
osdSyncBlink();
|
||||
|
||||
osdState = OSD_STATE_GROUP_ELEMENTS;
|
||||
|
||||
break;
|
||||
|
||||
case OSD_STATE_GROUP_ELEMENTS:
|
||||
{
|
||||
uint8_t elementGroup;
|
||||
uint8_t activeElements = osdGetActiveElementCount();
|
||||
|
||||
|
@ -1325,7 +1332,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
osdElementGroupTargetFracUs[elementGroup] += osdElementDurationUs[curElement];
|
||||
// If group membership changes, reset the stats for the group
|
||||
if (osdElementGroupMembership[curElement] != elementGroup) {
|
||||
osdElementGroupDurationFracUs[elementGroup] = osdElementGroupTargetFracUs[elementGroup];
|
||||
osdElementGroupDurationFracUs[elementGroup] = osdElementGroupTargetFracUs[elementGroup] + (OSD_ELEMENT_RENDER_GROUP_MARGIN << OSD_EXEC_TIME_SHIFT);
|
||||
}
|
||||
osdElementGroupMembership[curElement] = elementGroup;
|
||||
} else {
|
||||
|
@ -1343,6 +1350,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
} else {
|
||||
osdState = OSD_STATE_COMMIT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OSD_STATE_UPDATE_ELEMENTS:
|
||||
|
@ -1406,6 +1414,7 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
|
||||
firstPass = false;
|
||||
osdState = OSD_STATE_IDLE;
|
||||
|
||||
break;
|
||||
|
||||
case OSD_STATE_IDLE:
|
||||
|
@ -1424,11 +1433,17 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
if (osdCurState == OSD_STATE_UPDATE_ELEMENTS) {
|
||||
if (executeTimeUs > (osdElementGroupDurationFracUs[osdCurElementGroup] >> OSD_EXEC_TIME_SHIFT)) {
|
||||
osdElementGroupDurationFracUs[osdCurElementGroup] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||
} else if (osdElementGroupDurationFracUs[osdCurElementGroup] > 0) {
|
||||
// Slowly decay the max time
|
||||
osdElementGroupDurationFracUs[osdCurElementGroup]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (executeTimeUs > (osdStateDurationFracUs[osdCurState] >> OSD_EXEC_TIME_SHIFT)) {
|
||||
osdStateDurationFracUs[osdCurState] = executeTimeUs << OSD_EXEC_TIME_SHIFT;
|
||||
} else if (osdStateDurationFracUs[osdCurState] > 0) {
|
||||
// Slowly decay the max time
|
||||
osdStateDurationFracUs[osdCurState]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1437,9 +1452,9 @@ void osdUpdate(timeUs_t currentTimeUs)
|
|||
schedulerSetNextStateTime((osdElementGroupDurationFracUs[osdElementGroup] >> OSD_EXEC_TIME_SHIFT) + OSD_ELEMENT_RENDER_GROUP_MARGIN);
|
||||
} else {
|
||||
if (osdState == OSD_STATE_IDLE) {
|
||||
schedulerSetNextStateTime(osdStateDurationFracUs[OSD_STATE_CHECK] >> OSD_EXEC_TIME_SHIFT);
|
||||
schedulerSetNextStateTime((osdStateDurationFracUs[OSD_STATE_CHECK] >> OSD_EXEC_TIME_SHIFT) + OSD_TASK_MARGIN);
|
||||
} else {
|
||||
schedulerSetNextStateTime(osdStateDurationFracUs[osdState] >> OSD_EXEC_TIME_SHIFT);
|
||||
schedulerSetNextStateTime((osdStateDurationFracUs[osdState] >> OSD_EXEC_TIME_SHIFT) + OSD_TASK_MARGIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -709,7 +709,7 @@ TEST_F(OsdTest, TestAlarms)
|
|||
// elements showing values in alarm range should flash
|
||||
simulationTime += 1000000;
|
||||
simulationTime -= simulationTime % 1000000;
|
||||
timeUs_t startTime = simulationTime + 0.25e6;
|
||||
timeUs_t startTime = simulationTime;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
// Blinking should happen at 2Hz
|
||||
simulationTime = startTime + i*0.25e6;
|
||||
|
@ -1083,6 +1083,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
|
|||
// Delay as the warnings are flashing
|
||||
simulationTime += 1000000;
|
||||
simulationTime -= simulationTime % 1000000;
|
||||
simulationTime += 0.25e6;
|
||||
osdRefresh();
|
||||
|
||||
// then
|
||||
|
@ -1098,6 +1099,7 @@ TEST_F(OsdTest, TestElementWarningsBattery)
|
|||
// Delay as the warnings are flashing
|
||||
simulationTime += 1000000;
|
||||
simulationTime -= simulationTime % 1000000;
|
||||
simulationTime += 0.25e6;
|
||||
osdRefresh();
|
||||
|
||||
// then
|
||||
|
@ -1204,7 +1206,7 @@ TEST_F(OsdTest, TestGpsElements)
|
|||
// Sat indicator should blink and show "NC"
|
||||
simulationTime += 1000000;
|
||||
simulationTime -= simulationTime % 1000000;
|
||||
timeUs_t startTime = simulationTime + 0.25e6;
|
||||
timeUs_t startTime = simulationTime;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
// Blinking should happen at 2Hz
|
||||
simulationTime = startTime + i*0.25e6;
|
||||
|
@ -1228,7 +1230,7 @@ TEST_F(OsdTest, TestGpsElements)
|
|||
// Sat indicator should blink and show "0"
|
||||
simulationTime += 1000000;
|
||||
simulationTime -= simulationTime % 1000000;
|
||||
startTime = simulationTime + 0.25e6;
|
||||
startTime = simulationTime;
|
||||
for (int i = 0; i < 15; i++) {
|
||||
// Blinking should happen at 2Hz
|
||||
simulationTime = startTime + i*0.25e6;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue