From 7b060aa88d211c272b85f12b8ad42d0182a82685 Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Sun, 25 Jun 2017 22:12:25 +0100 Subject: [PATCH 1/5] Draw single OSD element per osdUpdate --- src/main/drivers/max7456.c | 4 +- src/main/drivers/max7456.h | 2 +- src/main/fc/fc_tasks.c | 2 +- src/main/io/osd.c | 123 ++++++++++++++++++++++++++----------- 4 files changed, 92 insertions(+), 39 deletions(-) diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c index 89a5b4ac16..0f5225d24c 100644 --- a/src/main/drivers/max7456.c +++ b/src/main/drivers/max7456.c @@ -59,7 +59,7 @@ static uint8_t screenBuffer[VIDEO_BUFFER_CHARS_PAL+40]; //for faster writes we u static uint8_t shadowBuffer[VIDEO_BUFFER_CHARS_PAL]; //max chars to update in one idle -#define MAX_CHARS2UPDATE 100 +#define MAX_CHARS2UPDATE 50 #ifdef MAX7456_DMA_CHANNEL_TX volatile bool dmaTransactionInProgress = false; #endif @@ -309,7 +309,7 @@ bool max7456DmaInProgres(void) } #endif -void max7456DrawScreen(void) +void max7456DrawScreenPartial(void) { uint8_t check; static uint16_t pos = 0; diff --git a/src/main/drivers/max7456.h b/src/main/drivers/max7456.h index a4ebe0ab4e..e3fd9b4166 100644 --- a/src/main/drivers/max7456.h +++ b/src/main/drivers/max7456.h @@ -145,7 +145,7 @@ enum VIDEO_TYPES { AUTO = 0, PAL, NTSC }; extern uint16_t maxScreenSize; void max7456Init(uint8_t system); -void max7456DrawScreen(void); +void max7456DrawScreenPartial(void); void max7456WriteNvm(uint8_t char_address, const uint8_t *font_data); uint8_t max7456GetRowsCount(void); void max7456Write(uint8_t x, uint8_t y, const char *buff); diff --git a/src/main/fc/fc_tasks.c b/src/main/fc/fc_tasks.c index a478ade519..01876698c0 100755 --- a/src/main/fc/fc_tasks.c +++ b/src/main/fc/fc_tasks.c @@ -509,7 +509,7 @@ cfTask_t cfTasks[TASK_COUNT] = { [TASK_OSD] = { .taskName = "OSD", .taskFunc = taskUpdateOsd, - .desiredPeriod = 1000000 / 60, // 60 Hz + .desiredPeriod = TASK_PERIOD_HZ(100), // 100 Hz .staticPriority = TASK_PRIORITY_LOW, }, #endif diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 244146c38d..4de0a3080b 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -173,17 +173,17 @@ static void osdFormatVelocityStr(char* buff, int32_t vel) { switch (osdConfig()->units) { case OSD_UNIT_IMPERIAL: - tfp_sprintf(buff, "%d%c", osdConvertVelocityToUnit(vel), SYM_MPH); + tfp_sprintf(buff, "%2d%c", osdConvertVelocityToUnit(vel), SYM_MPH); break; default: // Metric - tfp_sprintf(buff, "%d%c", osdConvertVelocityToUnit(vel), SYM_KMH); + tfp_sprintf(buff, "%3d%c", osdConvertVelocityToUnit(vel), SYM_KMH); } } -static void osdDrawSingleElement(uint8_t item) +static bool osdDrawSingleElement(uint8_t item) { if (!VISIBLE(osdConfig()->item_pos[item]) || BLINK(osdConfig()->item_pos[item])) { - return; + return false; } uint8_t elemPosX = OSD_X(osdConfig()->item_pos[item]); @@ -198,7 +198,7 @@ static void osdDrawSingleElement(uint8_t item) osdRssi = 99; buff[0] = SYM_RSSI; - tfp_sprintf(buff + 1, "%d", osdRssi); + tfp_sprintf(buff + 1, "%2d", osdRssi); break; } @@ -207,7 +207,7 @@ static void osdDrawSingleElement(uint8_t item) uint8_t p = calculateBatteryPercentage(); p = (100 - p) / 16.6; buff[0] = SYM_BATT_FULL + p; - tfp_sprintf(buff + 1, "%d.%1dV", vbat / 10, vbat % 10); + tfp_sprintf(buff + 1, "%2d.%1dV", vbat / 10, vbat % 10); break; } @@ -225,7 +225,7 @@ static void osdDrawSingleElement(uint8_t item) case OSD_GPS_SATS: buff[0] = 0x1e; buff[1] = 0x1f; - tfp_sprintf(buff + 2, "%d", gpsSol.numSat); + tfp_sprintf(buff + 2, "%2d", gpsSol.numSat); break; case OSD_GPS_SPEED: @@ -278,7 +278,7 @@ static void osdDrawSingleElement(uint8_t item) if (h < 0) h+=360; buff[0] = 0xA9; - tfp_sprintf(&buff[1], "%d%c", h , 0xA8 ); + tfp_sprintf(&buff[1], "%3d%c", h , 0xA8 ); break; } #endif // GPS @@ -313,7 +313,7 @@ static void osdDrawSingleElement(uint8_t item) #if 0 if (isAirmodeActive()) - p = "AIR"; + p = "AIR "; #endif if (FLIGHT_MODE(PASSTHRU_MODE)) @@ -333,10 +333,10 @@ static void osdDrawSingleElement(uint8_t item) else if (FLIGHT_MODE(ANGLE_MODE)) p = "STAB"; else if (FLIGHT_MODE(HORIZON_MODE)) - p = "HOR"; + p = "HOR "; max7456Write(elemPosX, elemPosY, p); - return; + return true; } case OSD_CRAFT_NAME: @@ -354,12 +354,12 @@ static void osdDrawSingleElement(uint8_t item) case OSD_THROTTLE_POS: buff[0] = SYM_THR; buff[1] = SYM_THR1; - tfp_sprintf(buff + 2, "%d", (constrain(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN)); + tfp_sprintf(buff + 2, "%3d", (constrain(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX) - PWM_RANGE_MIN) * 100 / (PWM_RANGE_MAX - PWM_RANGE_MIN)); break; #ifdef VTX case OSD_VTX_CHANNEL: - tfp_sprintf(buff, "CH:%d", current_vtx_channel % CHANNELS_PER_BAND + 1); + tfp_sprintf(buff, "CH:%2d", current_vtx_channel % CHANNELS_PER_BAND + 1); break; #endif // VTX @@ -400,6 +400,10 @@ static void osdDrawSingleElement(uint8_t item) pitchAngle = (pitchAngle / 8) - 41; // 41 = 4 * 9 + 5 for (int x = -4; x <= 4; x++) { + // clear the y area before writing the new horizon character + for (int y = 0; y <= 9; y++) { + max7456WriteChar(elemPosX + x, elemPosY + y, 0x20); + } int y = (rollAngle * x) / 64; y -= pitchAngle; // y += 41; // == 4 * 9 + 5 @@ -410,7 +414,7 @@ static void osdDrawSingleElement(uint8_t item) osdDrawSingleElement(OSD_HORIZON_SIDEBARS); - return; + return true; } case OSD_HORIZON_SIDEBARS: @@ -434,9 +438,10 @@ static void osdDrawSingleElement(uint8_t item) max7456WriteChar(elemPosX - hudwidth + 1, elemPosY, SYM_AH_LEFT); max7456WriteChar(elemPosX + hudwidth - 1, elemPosY, SYM_AH_RIGHT); - return; + return true; } +#if defined(BARO) || defined(GPS) case OSD_VARIO: { int16_t v = getEstimatedActualVelocity(Z) / 50; //50cm = 1 arrow @@ -472,7 +477,7 @@ static void osdDrawSingleElement(uint8_t item) max7456WriteChar(elemPosX, elemPosY+2, vchars[2]); max7456WriteChar(elemPosX, elemPosY+3, vchars[3]); max7456WriteChar(elemPosX, elemPosY+4, vchars[4]); - return; + return true; } case OSD_VARIO_NUM: @@ -482,6 +487,7 @@ static void osdDrawSingleElement(uint8_t item) tfp_sprintf(buff, "%c%d.%01d%c", value < 0 ? '-' : ' ', abs(value / 10), abs((value % 10)), 0x9F); break; } +#endif case OSD_ROLL_PIDS: { @@ -508,10 +514,49 @@ static void osdDrawSingleElement(uint8_t item) } default: - return; + return false; } max7456Write(elemPosX, elemPosY, buff); + return true; +} + +static uint8_t osdIncElementIndex(uint8_t elementIndex) +{ + ++elementIndex; + if (sensors(SENSOR_ACC)) { + if (elementIndex == OSD_CROSSHAIRS) { + elementIndex = OSD_ONTIME; + } + } + if (feature(FEATURE_CURRENT_METER)) { + if (elementIndex == OSD_CURRENT_DRAW) { + elementIndex = OSD_GPS_SPEED; + } + + } + if (sensors(SENSOR_GPS)) { + if (elementIndex == OSD_GPS_SPEED) { + elementIndex = OSD_ALTITUDE; + } + if (elementIndex == OSD_GPS_LON) { + elementIndex = OSD_VARIO; + } + } + + if (elementIndex == OSD_ITEM_COUNT) { + elementIndex = 0; + } + return elementIndex; +} + +void osdDrawNextElement(void) +{ + static uint8_t elementIndex = 0; + while (osdDrawSingleElement(elementIndex) == false) { + elementIndex = osdIncElementIndex(elementIndex); + } + elementIndex = osdIncElementIndex(elementIndex); } void osdDrawElements(void) @@ -577,6 +622,7 @@ void osdDrawElements(void) } + void pgResetFn_osdConfig(osdConfig_t *osdConfig) { osdConfig->item_pos[OSD_ALTITUDE] = OSD_POS(1, 0) | VISIBLE_FLAG; @@ -816,7 +862,7 @@ static void osdArmMotors(void) osdResetStats(); } -static void osdRefresh(timeUs_t currentTimeUs) +static void osdRefreshStats(timeUs_t currentTimeUs) { static uint8_t lastSec = 0; uint8_t sec; @@ -850,17 +896,6 @@ static void osdRefresh(timeUs_t currentTimeUs) } blinkState = (currentTimeUs / 200000) % 2; - -#ifdef CMS - if (!displayIsGrabbed(osdDisplayPort)) { - osdUpdateAlarms(); - osdDrawElements(); -#ifdef OSD_CALLS_CMS - } else { - cmsUpdate(currentTimeUs); -#endif - } -#endif } /* @@ -868,18 +903,36 @@ static void osdRefresh(timeUs_t currentTimeUs) */ void osdUpdate(timeUs_t currentTimeUs) { - static uint32_t counter = 0; + static uint8_t iterationCounter = 0; + #ifdef MAX7456_DMA_CHANNEL_TX // don't touch buffers if DMA transaction is in progress if (max7456DmaInProgres()) return; #endif // MAX7456_DMA_CHANNEL_TX - // redraw values in buffer - if (counter++ % 5 == 0) - osdRefresh(currentTimeUs); - else // rest of time redraw screen 10 chars per idle to don't lock the main idle - max7456DrawScreen(); + // refresh alarms every 20 iterations + if (iterationCounter == 0) { + if (!displayIsGrabbed(osdDisplayPort)) { + osdUpdateAlarms(); + } + } + // refresh statistics every 20 iterations + if (iterationCounter++ >= 20) { + iterationCounter = 0; + osdRefreshStats(currentTimeUs); + } +#ifdef CMS + if (!displayIsGrabbed(osdDisplayPort)) { + osdDrawNextElement(); +#ifdef OSD_CALLS_CMS + } else { + cmsUpdate(currentTimeUs); +#endif + } +#endif + // draw part of screen 10 chars per idle to don't lock the main idle + max7456DrawScreenPartial(); #ifdef CMS // do not allow ARM if we are in menu From 060367c367049c56cf1d6eaa587bc632630b4569 Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Mon, 26 Jun 2017 17:07:59 +0100 Subject: [PATCH 2/5] Fix osdIncElementIndex --- src/main/io/osd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 4de0a3080b..9c87df837a 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -524,18 +524,18 @@ static bool osdDrawSingleElement(uint8_t item) static uint8_t osdIncElementIndex(uint8_t elementIndex) { ++elementIndex; - if (sensors(SENSOR_ACC)) { + if (!sensors(SENSOR_ACC)) { if (elementIndex == OSD_CROSSHAIRS) { elementIndex = OSD_ONTIME; } } - if (feature(FEATURE_CURRENT_METER)) { + if (!feature(FEATURE_CURRENT_METER)) { if (elementIndex == OSD_CURRENT_DRAW) { elementIndex = OSD_GPS_SPEED; } } - if (sensors(SENSOR_GPS)) { + if (!sensors(SENSOR_GPS)) { if (elementIndex == OSD_GPS_SPEED) { elementIndex = OSD_ALTITUDE; } From 23874e90c60117d9d102548c3816befb9b07900a Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Wed, 28 Jun 2017 19:58:57 +0100 Subject: [PATCH 3/5] Fixes as suggested by @marbalon --- src/main/io/osd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 9c87df837a..61c814c83a 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -207,7 +207,7 @@ static bool osdDrawSingleElement(uint8_t item) uint8_t p = calculateBatteryPercentage(); p = (100 - p) / 16.6; buff[0] = SYM_BATT_FULL + p; - tfp_sprintf(buff + 1, "%2d.%1dV", vbat / 10, vbat % 10); + tfp_sprintf(buff + 1, "%d.%1dV ", vbat / 10, vbat % 10); break; } @@ -401,7 +401,7 @@ static bool osdDrawSingleElement(uint8_t item) for (int x = -4; x <= 4; x++) { // clear the y area before writing the new horizon character - for (int y = 0; y <= 9; y++) { + for (int y = 0; y <= 7; y++) { max7456WriteChar(elemPosX + x, elemPosY + y, 0x20); } int y = (rollAngle * x) / 64; From e817ff4f54231b72a383314873268ce6fa92de25 Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Wed, 28 Jun 2017 20:26:34 +0100 Subject: [PATCH 4/5] Further fixes as suggested by @marbalon --- src/main/fc/fc_tasks.c | 2 +- src/main/io/osd.c | 49 +++++++++++++++++++++++++----------------- src/main/io/osd.h | 2 ++ 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/main/fc/fc_tasks.c b/src/main/fc/fc_tasks.c index 01876698c0..242134068b 100755 --- a/src/main/fc/fc_tasks.c +++ b/src/main/fc/fc_tasks.c @@ -509,7 +509,7 @@ cfTask_t cfTasks[TASK_COUNT] = { [TASK_OSD] = { .taskName = "OSD", .taskFunc = taskUpdateOsd, - .desiredPeriod = TASK_PERIOD_HZ(100), // 100 Hz + .desiredPeriod = TASK_PERIOD_HZ(OSD_TASK_FREQUENCY_HZ), .staticPriority = TASK_PRIORITY_LOW, }, #endif diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 61c814c83a..882fa6cccc 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -100,7 +100,7 @@ typedef struct statistic_s { static statistic_t stats; uint16_t refreshTimeout = 0; -#define REFRESH_1S 12 +#define REFRESH_1S OSD_TASK_FREQUENCY_HZ static uint8_t armState; @@ -138,16 +138,22 @@ static void osdFormatDistanceStr(char* buff, int32_t dist) switch (osdConfig()->units) { case OSD_UNIT_IMPERIAL: - if (dist < 0) - tfp_sprintf(buff, "-%d%c", dist_abs / 100, SYM_FT); - else - tfp_sprintf(buff, "%d%c", dist_abs / 100, SYM_FT); + if (dist < 0) { + tfp_sprintf(buff, "-%d%c ", dist_abs / 100, SYM_FT); + } else { + tfp_sprintf(buff, "%d%c ", dist_abs / 100, SYM_FT); + } break; default: // Metric - if (dist < 0) - tfp_sprintf(buff, "-%d.%01d%c", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); - else - tfp_sprintf(buff, "%d.%01d%c", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); + if (dist < 0) { + tfp_sprintf(buff, "-%d.%01d%c ", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); + } else { + if (dist < 10000) { // less than 100m + tfp_sprintf(buff, "%d.%01d%c ", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); + } else { + tfp_sprintf(buff, "%d%c ", dist_abs / 100, SYM_M); + } + } } } @@ -213,7 +219,7 @@ static bool osdDrawSingleElement(uint8_t item) case OSD_CURRENT_DRAW: buff[0] = SYM_AMP; - tfp_sprintf(buff + 1, "%d.%02d", abs(amperage) / 100, abs(amperage) % 100); + tfp_sprintf(buff + 1, "%d.%02d ", abs(amperage) / 100, abs(amperage) % 100); break; case OSD_MAH_DRAWN: @@ -886,15 +892,6 @@ static void osdRefreshStats(timeUs_t currentTimeUs) lastSec = sec; } - if (refreshTimeout) { - if (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI)) // hide statistics - refreshTimeout = 1; - refreshTimeout--; - if (!refreshTimeout) - max7456ClearScreen(); - return; - } - blinkState = (currentTimeUs / 200000) % 2; } @@ -907,8 +904,9 @@ void osdUpdate(timeUs_t currentTimeUs) #ifdef MAX7456_DMA_CHANNEL_TX // don't touch buffers if DMA transaction is in progress - if (max7456DmaInProgres()) + if (max7456DmaInProgres()) { return; + } #endif // MAX7456_DMA_CHANNEL_TX // refresh alarms every 20 iterations @@ -922,6 +920,17 @@ void osdUpdate(timeUs_t currentTimeUs) iterationCounter = 0; osdRefreshStats(currentTimeUs); } + if (refreshTimeout) { + if (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI)) { // hide statistics + refreshTimeout = 1; + } + refreshTimeout--; + if (!refreshTimeout) { + max7456ClearScreen(); + } + return; + } + #ifdef CMS if (!displayIsGrabbed(osdDisplayPort)) { osdDrawNextElement(); diff --git a/src/main/io/osd.h b/src/main/io/osd.h index 258c4095ba..32961e25f5 100755 --- a/src/main/io/osd.h +++ b/src/main/io/osd.h @@ -20,6 +20,8 @@ #include "common/time.h" #include "config/parameter_group.h" +#define OSD_TASK_FREQUENCY_HZ 100 + #define VISIBLE_FLAG 0x0800 #define BLINK_FLAG 0x0400 #define VISIBLE(x) (x & VISIBLE_FLAG) From 2b47b6ce974951df096cbb487d5155d6cf9677e3 Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Wed, 28 Jun 2017 21:48:44 +0100 Subject: [PATCH 5/5] Fix status/splash --- src/main/io/osd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/io/osd.c b/src/main/io/osd.c index 882fa6cccc..7523f25545 100755 --- a/src/main/io/osd.c +++ b/src/main/io/osd.c @@ -928,6 +928,7 @@ void osdUpdate(timeUs_t currentTimeUs) if (!refreshTimeout) { max7456ClearScreen(); } + max7456DrawScreenPartial(); return; }