1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-21 15:25:29 +03:00

Merge pull request #1831 from martinbudden/inav_osd_single_element

Draw single OSD element per osdUpdate
This commit is contained in:
Konstantin Sharlaimov 2017-07-04 23:39:37 +10:00 committed by GitHub
commit f4850845df
5 changed files with 124 additions and 59 deletions

View file

@ -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]; static uint8_t shadowBuffer[VIDEO_BUFFER_CHARS_PAL];
//max chars to update in one idle //max chars to update in one idle
#define MAX_CHARS2UPDATE 100 #define MAX_CHARS2UPDATE 50
#ifdef MAX7456_DMA_CHANNEL_TX #ifdef MAX7456_DMA_CHANNEL_TX
volatile bool dmaTransactionInProgress = false; volatile bool dmaTransactionInProgress = false;
#endif #endif
@ -309,7 +309,7 @@ bool max7456DmaInProgres(void)
} }
#endif #endif
void max7456DrawScreen(void) void max7456DrawScreenPartial(void)
{ {
uint8_t check; uint8_t check;
static uint16_t pos = 0; static uint16_t pos = 0;

View file

@ -145,7 +145,7 @@ enum VIDEO_TYPES { AUTO = 0, PAL, NTSC };
extern uint16_t maxScreenSize; extern uint16_t maxScreenSize;
void max7456Init(uint8_t system); void max7456Init(uint8_t system);
void max7456DrawScreen(void); void max7456DrawScreenPartial(void);
void max7456WriteNvm(uint8_t char_address, const uint8_t *font_data); void max7456WriteNvm(uint8_t char_address, const uint8_t *font_data);
uint8_t max7456GetRowsCount(void); uint8_t max7456GetRowsCount(void);
void max7456Write(uint8_t x, uint8_t y, const char *buff); void max7456Write(uint8_t x, uint8_t y, const char *buff);

View file

@ -505,7 +505,7 @@ cfTask_t cfTasks[TASK_COUNT] = {
[TASK_OSD] = { [TASK_OSD] = {
.taskName = "OSD", .taskName = "OSD",
.taskFunc = taskUpdateOsd, .taskFunc = taskUpdateOsd,
.desiredPeriod = 1000000 / 60, // 60 Hz .desiredPeriod = TASK_PERIOD_HZ(OSD_TASK_FREQUENCY_HZ),
.staticPriority = TASK_PRIORITY_LOW, .staticPriority = TASK_PRIORITY_LOW,
}, },
#endif #endif

View file

@ -100,7 +100,7 @@ typedef struct statistic_s {
static statistic_t stats; static statistic_t stats;
uint16_t refreshTimeout = 0; uint16_t refreshTimeout = 0;
#define REFRESH_1S 12 #define REFRESH_1S OSD_TASK_FREQUENCY_HZ
static uint8_t armState; static uint8_t armState;
@ -138,16 +138,22 @@ static void osdFormatDistanceStr(char* buff, int32_t dist)
switch (osdConfig()->units) { switch (osdConfig()->units) {
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
if (dist < 0) if (dist < 0) {
tfp_sprintf(buff, "-%d%c ", dist_abs / 100, SYM_FT); tfp_sprintf(buff, "-%d%c ", dist_abs / 100, SYM_FT);
else } else {
tfp_sprintf(buff, "%d%c ", dist_abs / 100, SYM_FT); tfp_sprintf(buff, "%d%c ", dist_abs / 100, SYM_FT);
}
break; break;
default: // Metric default: // Metric
if (dist < 0) if (dist < 0) {
tfp_sprintf(buff, "-%d.%01d%c ", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); tfp_sprintf(buff, "-%d.%01d%c ", dist_abs / 100, (dist_abs % 100) / 10, SYM_M);
else } else {
if (dist < 10000) { // less than 100m
tfp_sprintf(buff, "%d.%01d%c ", dist_abs / 100, (dist_abs % 100) / 10, SYM_M); 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);
}
}
} }
} }
@ -173,17 +179,17 @@ static void osdFormatVelocityStr(char* buff, int32_t vel)
{ {
switch (osdConfig()->units) { switch (osdConfig()->units) {
case OSD_UNIT_IMPERIAL: case OSD_UNIT_IMPERIAL:
tfp_sprintf(buff, "%d%c", osdConvertVelocityToUnit(vel), SYM_MPH); tfp_sprintf(buff, "%2d%c", osdConvertVelocityToUnit(vel), SYM_MPH);
break; break;
default: // Metric 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])) { if (!VISIBLE(osdConfig()->item_pos[item]) || BLINK(osdConfig()->item_pos[item])) {
return; return false;
} }
uint8_t elemPosX = OSD_X(osdConfig()->item_pos[item]); uint8_t elemPosX = OSD_X(osdConfig()->item_pos[item]);
@ -198,7 +204,7 @@ static void osdDrawSingleElement(uint8_t item)
osdRssi = 99; osdRssi = 99;
buff[0] = SYM_RSSI; buff[0] = SYM_RSSI;
tfp_sprintf(buff + 1, "%d", osdRssi); tfp_sprintf(buff + 1, "%2d", osdRssi);
break; break;
} }
@ -225,7 +231,7 @@ static void osdDrawSingleElement(uint8_t item)
case OSD_GPS_SATS: case OSD_GPS_SATS:
buff[0] = 0x1e; buff[0] = 0x1e;
buff[1] = 0x1f; buff[1] = 0x1f;
tfp_sprintf(buff + 2, "%d", gpsSol.numSat); tfp_sprintf(buff + 2, "%2d", gpsSol.numSat);
break; break;
case OSD_GPS_SPEED: case OSD_GPS_SPEED:
@ -278,7 +284,7 @@ static void osdDrawSingleElement(uint8_t item)
if (h < 0) h+=360; if (h < 0) h+=360;
buff[0] = 0xA9; buff[0] = 0xA9;
tfp_sprintf(&buff[1], "%d%c", h , 0xA8 ); tfp_sprintf(&buff[1], "%3d%c", h , 0xA8 );
break; break;
} }
#endif // GPS #endif // GPS
@ -336,7 +342,7 @@ static void osdDrawSingleElement(uint8_t item)
p = "HOR "; p = "HOR ";
max7456Write(elemPosX, elemPosY, p); max7456Write(elemPosX, elemPosY, p);
return; return true;
} }
case OSD_CRAFT_NAME: case OSD_CRAFT_NAME:
@ -354,12 +360,12 @@ static void osdDrawSingleElement(uint8_t item)
case OSD_THROTTLE_POS: case OSD_THROTTLE_POS:
buff[0] = SYM_THR; buff[0] = SYM_THR;
buff[1] = SYM_THR1; 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; break;
#ifdef VTX #ifdef VTX
case OSD_VTX_CHANNEL: 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; break;
#endif // VTX #endif // VTX
@ -400,6 +406,10 @@ static void osdDrawSingleElement(uint8_t item)
pitchAngle = (pitchAngle / 8) - 41; // 41 = 4 * 9 + 5 pitchAngle = (pitchAngle / 8) - 41; // 41 = 4 * 9 + 5
for (int x = -4; x <= 4; x++) { for (int x = -4; x <= 4; x++) {
// clear the y area before writing the new horizon character
for (int y = 0; y <= 7; y++) {
max7456WriteChar(elemPosX + x, elemPosY + y, 0x20);
}
int y = (rollAngle * x) / 64; int y = (rollAngle * x) / 64;
y -= pitchAngle; y -= pitchAngle;
// y += 41; // == 4 * 9 + 5 // y += 41; // == 4 * 9 + 5
@ -410,7 +420,7 @@ static void osdDrawSingleElement(uint8_t item)
osdDrawSingleElement(OSD_HORIZON_SIDEBARS); osdDrawSingleElement(OSD_HORIZON_SIDEBARS);
return; return true;
} }
case OSD_HORIZON_SIDEBARS: case OSD_HORIZON_SIDEBARS:
@ -434,9 +444,10 @@ static void osdDrawSingleElement(uint8_t item)
max7456WriteChar(elemPosX - hudwidth + 1, elemPosY, SYM_AH_LEFT); max7456WriteChar(elemPosX - hudwidth + 1, elemPosY, SYM_AH_LEFT);
max7456WriteChar(elemPosX + hudwidth - 1, elemPosY, SYM_AH_RIGHT); max7456WriteChar(elemPosX + hudwidth - 1, elemPosY, SYM_AH_RIGHT);
return; return true;
} }
#if defined(BARO) || defined(GPS)
case OSD_VARIO: case OSD_VARIO:
{ {
int16_t v = getEstimatedActualVelocity(Z) / 50; //50cm = 1 arrow int16_t v = getEstimatedActualVelocity(Z) / 50; //50cm = 1 arrow
@ -472,7 +483,7 @@ static void osdDrawSingleElement(uint8_t item)
max7456WriteChar(elemPosX, elemPosY+2, vchars[2]); max7456WriteChar(elemPosX, elemPosY+2, vchars[2]);
max7456WriteChar(elemPosX, elemPosY+3, vchars[3]); max7456WriteChar(elemPosX, elemPosY+3, vchars[3]);
max7456WriteChar(elemPosX, elemPosY+4, vchars[4]); max7456WriteChar(elemPosX, elemPosY+4, vchars[4]);
return; return true;
} }
case OSD_VARIO_NUM: case OSD_VARIO_NUM:
@ -482,6 +493,7 @@ static void osdDrawSingleElement(uint8_t item)
tfp_sprintf(buff, "%c%d.%01d%c", value < 0 ? '-' : ' ', abs(value / 10), abs((value % 10)), 0x9F); tfp_sprintf(buff, "%c%d.%01d%c", value < 0 ? '-' : ' ', abs(value / 10), abs((value % 10)), 0x9F);
break; break;
} }
#endif
case OSD_ROLL_PIDS: case OSD_ROLL_PIDS:
{ {
@ -508,10 +520,49 @@ static void osdDrawSingleElement(uint8_t item)
} }
default: default:
return; return false;
} }
max7456Write(elemPosX, elemPosY, buff); 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) void osdDrawElements(void)
@ -577,6 +628,7 @@ void osdDrawElements(void)
} }
void pgResetFn_osdConfig(osdConfig_t *osdConfig) void pgResetFn_osdConfig(osdConfig_t *osdConfig)
{ {
osdConfig->item_pos[OSD_ALTITUDE] = OSD_POS(1, 0) | VISIBLE_FLAG; osdConfig->item_pos[OSD_ALTITUDE] = OSD_POS(1, 0) | VISIBLE_FLAG;
@ -816,7 +868,7 @@ static void osdArmMotors(void)
osdResetStats(); osdResetStats();
} }
static void osdRefresh(timeUs_t currentTimeUs) static void osdRefreshStats(timeUs_t currentTimeUs)
{ {
static uint8_t lastSec = 0; static uint8_t lastSec = 0;
uint8_t sec; uint8_t sec;
@ -840,27 +892,7 @@ static void osdRefresh(timeUs_t currentTimeUs)
lastSec = sec; lastSec = sec;
} }
if (refreshTimeout) {
if (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI)) // hide statistics
refreshTimeout = 1;
refreshTimeout--;
if (!refreshTimeout)
max7456ClearScreen();
return;
}
blinkState = (currentTimeUs / 200000) % 2; blinkState = (currentTimeUs / 200000) % 2;
#ifdef CMS
if (!displayIsGrabbed(osdDisplayPort)) {
osdUpdateAlarms();
osdDrawElements();
#ifdef OSD_CALLS_CMS
} else {
cmsUpdate(currentTimeUs);
#endif
}
#endif
} }
/* /*
@ -868,18 +900,49 @@ static void osdRefresh(timeUs_t currentTimeUs)
*/ */
void osdUpdate(timeUs_t currentTimeUs) void osdUpdate(timeUs_t currentTimeUs)
{ {
static uint32_t counter = 0; static uint8_t iterationCounter = 0;
#ifdef MAX7456_DMA_CHANNEL_TX #ifdef MAX7456_DMA_CHANNEL_TX
// don't touch buffers if DMA transaction is in progress // don't touch buffers if DMA transaction is in progress
if (max7456DmaInProgres()) if (max7456DmaInProgres()) {
return; return;
}
#endif // MAX7456_DMA_CHANNEL_TX #endif // MAX7456_DMA_CHANNEL_TX
// redraw values in buffer // refresh alarms every 20 iterations
if (counter++ % 5 == 0) if (iterationCounter == 0) {
osdRefresh(currentTimeUs); if (!displayIsGrabbed(osdDisplayPort)) {
else // rest of time redraw screen 10 chars per idle to don't lock the main idle osdUpdateAlarms();
max7456DrawScreen(); }
}
// refresh statistics every 20 iterations
if (iterationCounter++ >= 20) {
iterationCounter = 0;
osdRefreshStats(currentTimeUs);
}
if (refreshTimeout) {
if (checkStickPosition(THR_HI) || checkStickPosition(PIT_HI)) { // hide statistics
refreshTimeout = 1;
}
refreshTimeout--;
if (!refreshTimeout) {
max7456ClearScreen();
}
max7456DrawScreenPartial();
return;
}
#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 #ifdef CMS
// do not allow ARM if we are in menu // do not allow ARM if we are in menu

View file

@ -20,6 +20,8 @@
#include "common/time.h" #include "common/time.h"
#include "config/parameter_group.h" #include "config/parameter_group.h"
#define OSD_TASK_FREQUENCY_HZ 100
#define VISIBLE_FLAG 0x0800 #define VISIBLE_FLAG 0x0800
#define BLINK_FLAG 0x0400 #define BLINK_FLAG 0x0400
#define VISIBLE(x) (x & VISIBLE_FLAG) #define VISIBLE(x) (x & VISIBLE_FLAG)