1
0
Fork 0
mirror of https://github.com/iNavFlight/inav.git synced 2025-07-21 07:15:16 +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];
//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;

View file

@ -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);

View file

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

View file

@ -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)
if (dist < 0) {
tfp_sprintf(buff, "-%d%c ", dist_abs / 100, SYM_FT);
else
} else {
tfp_sprintf(buff, "%d%c ", dist_abs / 100, SYM_FT);
}
break;
default: // Metric
if (dist < 0)
if (dist < 0) {
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);
} 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) {
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 +204,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;
}
@ -225,7 +231,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 +284,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
@ -336,7 +342,7 @@ static void osdDrawSingleElement(uint8_t item)
p = "HOR ";
max7456Write(elemPosX, elemPosY, p);
return;
return true;
}
case OSD_CRAFT_NAME:
@ -354,12 +360,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 +406,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 <= 7; y++) {
max7456WriteChar(elemPosX + x, elemPosY + y, 0x20);
}
int y = (rollAngle * x) / 64;
y -= pitchAngle;
// y += 41; // == 4 * 9 + 5
@ -410,7 +420,7 @@ static void osdDrawSingleElement(uint8_t item)
osdDrawSingleElement(OSD_HORIZON_SIDEBARS);
return;
return true;
}
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_RIGHT);
return;
return true;
}
#if defined(BARO) || defined(GPS)
case OSD_VARIO:
{
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+3, vchars[3]);
max7456WriteChar(elemPosX, elemPosY+4, vchars[4]);
return;
return true;
}
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);
break;
}
#endif
case OSD_ROLL_PIDS:
{
@ -508,10 +520,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 +628,7 @@ void osdDrawElements(void)
}
void pgResetFn_osdConfig(osdConfig_t *osdConfig)
{
osdConfig->item_pos[OSD_ALTITUDE] = OSD_POS(1, 0) | VISIBLE_FLAG;
@ -816,7 +868,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;
@ -840,27 +892,7 @@ static void osdRefresh(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;
#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)
{
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())
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);
}
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
// do not allow ARM if we are in menu

View file

@ -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)