From 104990c507bddce2539faab9d77564758141504d Mon Sep 17 00:00:00 2001 From: jflyper Date: Fri, 22 Nov 2019 23:52:01 +0900 Subject: [PATCH] Add device local blinking support --- src/main/cli/settings.c | 1 + src/main/drivers/display.h | 3 +++ src/main/io/displayport_msp.c | 12 ++++++++- src/main/io/displayport_msp.h | 7 ++++- src/main/osd/osd_elements.c | 55 +++++++++++++++++++++++++------------- src/main/pg/displayport_profiles.h | 1 + 6 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c index 0b5051b94..60526d557 100644 --- a/src/main/cli/settings.c +++ b/src/main/cli/settings.c @@ -1451,6 +1451,7 @@ const clivalue_t valueTable[] = { { "displayport_msp_row_adjust", VAR_INT8 | MASTER_VALUE, .config.minmax = { -3, 0 }, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, rowAdjust) }, { "displayport_msp_serial", VAR_INT8 | MASTER_VALUE, .config.minmax = { SERIAL_PORT_NONE, SERIAL_PORT_IDENTIFIER_MAX }, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, displayPortSerial) }, { "displayport_msp_attrs", VAR_UINT8 | MASTER_VALUE | MODE_ARRAY, .config.array.length = 4, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, attrValues) }, + { "displayport_msp_use_device_blink", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, useDeviceBlink) }, #ifdef USE_DISPLAYPORT_MSP_VENDOR_SPECIFIC { "displayport_msp_vendor_init", VAR_UINT8 | MASTER_VALUE | MODE_ARRAY, .config.array.length = 253, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, vendorInit) }, { "displayport_msp_vendor_init_length", VAR_UINT8 | MASTER_VALUE, .config.minmaxUnsigned = { 0, 252 }, PG_DISPLAY_PORT_MSP_CONFIG, offsetof(displayPortProfile_t, vendorInitLength) }, diff --git a/src/main/drivers/display.h b/src/main/drivers/display.h index 82e4a13b7..4b7fa83f7 100644 --- a/src/main/drivers/display.h +++ b/src/main/drivers/display.h @@ -59,6 +59,9 @@ typedef struct displayPort_s { bool cleared; int8_t cursorRow; int8_t grabCount; + + // Displayport device capability + bool useDeviceBlink; } displayPort_t; typedef struct displayPortVTable_s { diff --git a/src/main/io/displayport_msp.c b/src/main/io/displayport_msp.c index 356c5f901..9f045836c 100644 --- a/src/main/io/displayport_msp.c +++ b/src/main/io/displayport_msp.c @@ -109,7 +109,12 @@ static int writeString(displayPort_t *displayPort, uint8_t col, uint8_t row, uin buf[0] = 3; buf[1] = row; buf[2] = col; - buf[3] = displayPortProfileMsp()->attrValues[attr]; + buf[3] = displayPortProfileMsp()->attrValues[attr] & ~DISPLAYPORT_MSP_ATTR_BLINK & DISPLAYPORT_MSP_ATTR_MASK; + + if (attr & DISPLAYPORT_ATTR_BLINK) { + buf[3] |= DISPLAYPORT_MSP_ATTR_BLINK; + } + memcpy(&buf[4], string, len); return output(displayPort, MSP_DISPLAYPORT, buf, len + 4); @@ -185,6 +190,11 @@ displayPort_t *displayPortMspInit(void) #endif displayInit(&mspDisplayPort, &mspDisplayPortVTable); + + if (displayPortProfileMsp()->useDeviceBlink) { + mspDisplayPort.useDeviceBlink = true; + } + resync(&mspDisplayPort); return &mspDisplayPort; } diff --git a/src/main/io/displayport_msp.h b/src/main/io/displayport_msp.h index 720774398..fac120576 100644 --- a/src/main/io/displayport_msp.h +++ b/src/main/io/displayport_msp.h @@ -24,4 +24,9 @@ #include "pg/displayport_profiles.h" -displayPort_t *displayPortMspInit(void); +// MSP displayport V2 attribute byte bit functions +#define DISPLAYPORT_MSP_ATTR_VERSION BIT(7) // Format indicator; must be zero for V2 (and V1) +#define DISPLAYPORT_MSP_ATTR_BLINK BIT(6) // Device local blink +#define DISPLAYPORT_MSP_ATTR_MASK (~(DISPLAYPORT_MSP_ATTR_VERSION|DISPLAYPORT_MSP_ATTR_BLINK)) + +struct displayPort_s *displayPortMspInit(void); diff --git a/src/main/osd/osd_elements.c b/src/main/osd/osd_elements.c index 0f4bb6a46..82e12d8ec 100644 --- a/src/main/osd/osd_elements.c +++ b/src/main/osd/osd_elements.c @@ -180,6 +180,25 @@ static uint32_t blinkBits[(OSD_ITEM_COUNT + 31) / 32]; #define IS_BLINK(item) (blinkBits[(item) / 32] & (1 << ((item) % 32))) #define BLINK(item) (IS_BLINK(item) && blinkState) +static int osdDisplayWrite(osdElementParms_t *element, uint8_t x, uint8_t y, uint8_t attr, const char *s) +{ + if (IS_BLINK(element->item)) { + attr |= DISPLAYPORT_ATTR_BLINK; + } + + return displayWrite(element->osdDisplayPort, x, y, attr, s); +} + +static int osdDisplayWriteChar(osdElementParms_t *element, uint8_t x, uint8_t y, uint8_t attr, char c) +{ + char buf[2]; + + buf[0] = c; + buf[1] = 0; + + return osdDisplayWrite(element, x, y, attr, buf); +} + #if defined(USE_ESC_SENSOR) || defined(USE_DSHOT_TELEMETRY) typedef int (*getEscRpmOrFreqFnPtr)(int i); @@ -212,7 +231,7 @@ static void renderOsdEscRpmOrFreq(getEscRpmOrFreqFnPtr escFnPtr, osdElementParms const int rpm = MIN((*escFnPtr)(i),99999); const int len = tfp_sprintf(rpmStr, "%d", rpm); rpmStr[len] = '\0'; - displayWrite(element->osdDisplayPort, x, y + i, DISPLAYPORT_ATTR_NONE, rpmStr); + osdDisplayWrite(element, x, y + i, DISPLAYPORT_ATTR_NONE, rpmStr); } element->drawElement = false; } @@ -569,7 +588,7 @@ static void osdElementArtificialHorizon(osdElementParms_t *element) for (int x = -4; x <= 4; x++) { const int y = ((-rollAngle * x) / 64) - pitchAngle; if (y >= 0 && y <= 81) { - displayWriteChar(element->osdDisplayPort, element->elemPosX + x, element->elemPosY + (y / AH_SYMBOL_COUNT), DISPLAYPORT_ATTR_NONE, (SYM_AH_BAR9_0 + (y % AH_SYMBOL_COUNT))); + osdDisplayWriteChar(element, element->elemPosX + x, element->elemPosY + (y / AH_SYMBOL_COUNT), DISPLAYPORT_ATTR_NONE, (SYM_AH_BAR9_0 + (y % AH_SYMBOL_COUNT))); } } @@ -611,12 +630,12 @@ static void osdBackgroundCameraFrame(osdElementParms_t *element) element->buff[width - 1] = SYM_STICK_OVERLAY_CENTER; element->buff[width] = 0; // string terminator - displayWrite(element->osdDisplayPort, xpos, ypos, DISPLAYPORT_ATTR_NONE, element->buff); + osdDisplayWrite(element, xpos, ypos, DISPLAYPORT_ATTR_NONE, element->buff); for (int i = 1; i < (height - 1); i++) { - displayWriteChar(element->osdDisplayPort, xpos, ypos + i, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); - displayWriteChar(element->osdDisplayPort, xpos + width - 1, ypos + i, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); + osdDisplayWriteChar(element, xpos, ypos + i, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); + osdDisplayWriteChar(element, xpos + width - 1, ypos + i, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); } - displayWrite(element->osdDisplayPort, xpos, ypos + height - 1, DISPLAYPORT_ATTR_NONE, element->buff); + osdDisplayWrite(element, xpos, ypos + height - 1, DISPLAYPORT_ATTR_NONE, element->buff); element->drawElement = false; // element already drawn } @@ -911,13 +930,13 @@ static void osdBackgroundHorizonSidebars(osdElementParms_t *element) const int8_t hudwidth = AH_SIDEBAR_WIDTH_POS; const int8_t hudheight = AH_SIDEBAR_HEIGHT_POS; for (int y = -hudheight; y <= hudheight; y++) { - displayWriteChar(element->osdDisplayPort, element->elemPosX - hudwidth, element->elemPosY + y, DISPLAYPORT_ATTR_NONE, SYM_AH_DECORATION); - displayWriteChar(element->osdDisplayPort, element->elemPosX + hudwidth, element->elemPosY + y, DISPLAYPORT_ATTR_NONE, SYM_AH_DECORATION); + osdDisplayWriteChar(element, element->elemPosX - hudwidth, element->elemPosY + y, DISPLAYPORT_ATTR_NONE, SYM_AH_DECORATION); + osdDisplayWriteChar(element, element->elemPosX + hudwidth, element->elemPosY + y, DISPLAYPORT_ATTR_NONE, SYM_AH_DECORATION); } // AH level indicators - displayWriteChar(element->osdDisplayPort, element->elemPosX - hudwidth + 1, element->elemPosY, DISPLAYPORT_ATTR_NONE, SYM_AH_LEFT); - displayWriteChar(element->osdDisplayPort, element->elemPosX + hudwidth - 1, element->elemPosY, DISPLAYPORT_ATTR_NONE, SYM_AH_RIGHT); + osdDisplayWriteChar(element, element->elemPosX - hudwidth + 1, element->elemPosY, DISPLAYPORT_ATTR_NONE, SYM_AH_LEFT); + osdDisplayWriteChar(element, element->elemPosX + hudwidth - 1, element->elemPosY, DISPLAYPORT_ATTR_NONE, SYM_AH_RIGHT); element->drawElement = false; // element already drawn } @@ -1081,7 +1100,7 @@ static void osdElementRcChannels(osdElementParms_t *element) // Decimal notation can be added when tfp_sprintf supports float among fancy options. char fmtbuf[6]; tfp_sprintf(fmtbuf, "%5d", data); - displayWrite(element->osdDisplayPort, xpos, ypos + i, DISPLAYPORT_ATTR_NONE, fmtbuf); + osdDisplayWrite(element, xpos, ypos + i, DISPLAYPORT_ATTR_NONE, fmtbuf); } } @@ -1137,11 +1156,11 @@ static void osdBackgroundStickOverlay(osdElementParms_t *element) for (unsigned y = 0; y < OSD_STICK_OVERLAY_HEIGHT; y++) { // draw the axes, vertical and horizonal if ((x == ((OSD_STICK_OVERLAY_WIDTH - 1) / 2)) && (y == (OSD_STICK_OVERLAY_HEIGHT - 1) / 2)) { - displayWriteChar(element->osdDisplayPort, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_CENTER); + osdDisplayWriteChar(element, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_CENTER); } else if (x == ((OSD_STICK_OVERLAY_WIDTH - 1) / 2)) { - displayWriteChar(element->osdDisplayPort, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); + osdDisplayWriteChar(element, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_VERTICAL); } else if (y == ((OSD_STICK_OVERLAY_HEIGHT - 1) / 2)) { - displayWriteChar(element->osdDisplayPort, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_HORIZONTAL); + osdDisplayWriteChar(element, xpos + x, ypos + y, DISPLAYPORT_ATTR_NONE, SYM_STICK_OVERLAY_HORIZONTAL); } } } @@ -1169,7 +1188,7 @@ static void osdElementStickOverlay(osdElementParms_t *element) const uint8_t cursorY = OSD_STICK_OVERLAY_VERTICAL_POSITIONS - 1 - scaleRange(constrain(rcData[vertical_channel], PWM_RANGE_MIN, PWM_RANGE_MAX - 1), PWM_RANGE_MIN, PWM_RANGE_MAX, 0, OSD_STICK_OVERLAY_VERTICAL_POSITIONS); const char cursor = SYM_STICK_OVERLAY_SPRITE_HIGH + (cursorY % OSD_STICK_OVERLAY_SPRITE_HEIGHT); - displayWriteChar(element->osdDisplayPort, xpos + cursorX, ypos + cursorY / OSD_STICK_OVERLAY_SPRITE_HEIGHT, DISPLAYPORT_ATTR_NONE, cursor); + osdDisplayWriteChar(element, xpos + cursorX, ypos + cursorY / OSD_STICK_OVERLAY_SPRITE_HEIGHT, DISPLAYPORT_ATTR_NONE, cursor); element->drawElement = false; // element already drawn } @@ -1742,7 +1761,7 @@ static void osdDrawSingleElement(displayPort_t *osdDisplayPort, uint8_t item) // Element has no drawing function return; } - if (BLINK(item)) { + if (!osdDisplayPort->useDeviceBlink && BLINK(item)) { return; } @@ -1762,7 +1781,7 @@ static void osdDrawSingleElement(displayPort_t *osdDisplayPort, uint8_t item) // Call the element drawing function osdElementDrawFunction[item](&element); if (element.drawElement) { - displayWrite(osdDisplayPort, elemPosX, elemPosY, element.attr, buff); + osdDisplayWrite(&element, elemPosX, elemPosY, element.attr, buff); } } @@ -1788,7 +1807,7 @@ static void osdDrawSingleElementBackground(displayPort_t *osdDisplayPort, uint8_ // Call the element background drawing function osdElementBackgroundFunction[item](&element); if (element.drawElement) { - displayWrite(osdDisplayPort, elemPosX, elemPosY, DISPLAYPORT_ATTR_NONE, buff); + osdDisplayWrite(&element, elemPosX, elemPosY, DISPLAYPORT_ATTR_NONE, buff); } } diff --git a/src/main/pg/displayport_profiles.h b/src/main/pg/displayport_profiles.h index 58a9cc434..307bea752 100644 --- a/src/main/pg/displayport_profiles.h +++ b/src/main/pg/displayport_profiles.h @@ -33,6 +33,7 @@ typedef struct displayPortProfile_s { // For attribute-rich OSDs uint8_t attrValues[4]; // NORMAL, INFORMATIONAL, WARNING, CRITICAL + uint8_t useDeviceBlink; // Use device local blink capability #ifdef USE_DISPLAYPORT_MSP_VENDOR_SPECIFIC uint8_t vendorInitLength; // Actual length of vendorInit byte string uint8_t vendorInit[253]; // Max 253 bytes of vendor specific initialization byte string -- 2.11.4.GIT