diff --git a/src/main/cms/cms_menu_builtin.c b/src/main/cms/cms_menu_builtin.c index abc3da37b0..43e8e5f6f8 100644 --- a/src/main/cms/cms_menu_builtin.c +++ b/src/main/cms/cms_menu_builtin.c @@ -133,7 +133,7 @@ static OSD_Entry menuMainEntries[] = {"PROFILE", OME_Submenu, cmsMenuChange, &cmsx_menuImu, 0}, {"FEATURES", OME_Submenu, cmsMenuChange, &menuFeatures, 0}, #ifdef OSD - {"SCR LAYOUT", OME_Submenu, cmsMenuChange, &cmsx_menuOsdLayout, 0}, + {"OSD", OME_Submenu, cmsMenuChange, &cmsx_menuOsd, 0}, {"ALARMS", OME_Submenu, cmsMenuChange, &cmsx_menuAlarms, 0}, #endif {"FC&FW INFO", OME_Submenu, cmsMenuChange, &menuInfo, 0}, diff --git a/src/main/cms/cms_menu_osd.c b/src/main/cms/cms_menu_osd.c index 4a28c1e89e..54053492ff 100644 --- a/src/main/cms/cms_menu_osd.c +++ b/src/main/cms/cms_menu_osd.c @@ -36,6 +36,7 @@ #include "config/parameter_group.h" #include "config/parameter_group_ids.h" +#include "io/displayport_max7456.h" #include "io/osd.h" static uint8_t osdConfig_rssi_alarm; @@ -145,20 +146,55 @@ CMS_Menu menuOsdActiveElems = { .entries = menuOsdActiveElemsEntries }; -OSD_Entry cmsx_menuOsdLayoutEntries[] = +#ifdef USE_MAX7456 +static bool displayPortProfileMax7456_invert; +static uint8_t displayPortProfileMax7456_blackBrightness; +static uint8_t displayPortProfileMax7456_whiteBrightness; +#endif + +static long cmsx_menuOsdOnEnter(void) { - {"---SCREEN LAYOUT---", OME_Label, NULL, NULL, 0}, - {"ACTIVE ELEM", OME_Submenu, cmsMenuChange, &menuOsdActiveElems, 0}, - {"BACK", OME_Back, NULL, NULL, 0}, - {NULL, OME_END, NULL, NULL, 0} +#ifdef USE_MAX7456 + displayPortProfileMax7456_invert = displayPortProfileMax7456()->invert; + displayPortProfileMax7456_blackBrightness = displayPortProfileMax7456()->blackBrightness; + displayPortProfileMax7456_whiteBrightness = displayPortProfileMax7456()->whiteBrightness; +#endif + + return 0; +} + +static long cmsx_menuOsdOnExit(const OSD_Entry *self) +{ + UNUSED(self); + +#ifdef USE_MAX7456 + displayPortProfileMax7456Mutable()->invert = displayPortProfileMax7456_invert; + displayPortProfileMax7456Mutable()->blackBrightness = displayPortProfileMax7456_blackBrightness; + displayPortProfileMax7456Mutable()->whiteBrightness = displayPortProfileMax7456_whiteBrightness; +#endif + + return 0; +} + +OSD_Entry cmsx_menuOsdEntries[] = +{ + {"---OSD---", OME_Label, NULL, NULL, 0}, + {"ACTIVE ELEM", OME_Submenu, cmsMenuChange, &menuOsdActiveElems, 0}, +#ifdef USE_MAX7456 + {"INVERT", OME_Bool, NULL, &displayPortProfileMax7456_invert, 0}, + {"BRT BLACK", OME_UINT8, NULL, &(OSD_UINT8_t){&displayPortProfileMax7456_blackBrightness, 0, 3, 1}, 0}, + {"BRT WHITE", OME_UINT8, NULL, &(OSD_UINT8_t){&displayPortProfileMax7456_whiteBrightness, 0, 3, 1}, 0}, +#endif + {"BACK", OME_Back, NULL, NULL, 0}, + {NULL, OME_END, NULL, NULL, 0} }; -CMS_Menu cmsx_menuOsdLayout = { - .GUARD_text = "MENULAYOUT", +CMS_Menu cmsx_menuOsd = { + .GUARD_text = "MENUOSD", .GUARD_type = OME_MENU, - .onEnter = NULL, - .onExit = NULL, + .onEnter = cmsx_menuOsdOnEnter, + .onExit = cmsx_menuOsdOnExit, .onGlobalExit = NULL, - .entries = cmsx_menuOsdLayoutEntries + .entries = cmsx_menuOsdEntries }; #endif // CMS diff --git a/src/main/cms/cms_menu_osd.h b/src/main/cms/cms_menu_osd.h index 9b0b001d28..c4e306a9ea 100644 --- a/src/main/cms/cms_menu_osd.h +++ b/src/main/cms/cms_menu_osd.h @@ -18,4 +18,4 @@ #pragma once extern CMS_Menu cmsx_menuAlarms; -extern CMS_Menu cmsx_menuOsdLayout; +extern CMS_Menu cmsx_menuOsd; diff --git a/src/main/drivers/display.h b/src/main/drivers/display.h index cadf31f615..1cecb77ca7 100644 --- a/src/main/drivers/display.h +++ b/src/main/drivers/display.h @@ -46,6 +46,9 @@ typedef struct displayPortVTable_s { typedef struct displayPortProfile_s { int8_t colAdjust; int8_t rowAdjust; + bool invert; + uint8_t blackBrightness; + uint8_t whiteBrightness; } displayPortProfile_t; void displayGrab(displayPort_t *instance); diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c index b057d57d54..11c69fe268 100644 --- a/src/main/drivers/max7456.c +++ b/src/main/drivers/max7456.c @@ -107,6 +107,7 @@ // DMM special bits #define CLEAR_DISPLAY 0x04 #define CLEAR_DISPLAY_VERT 0x06 +#define INVERT_PIXEL_COLOR 0x08 // Special address for terminating incremental write #define END_STRING 0xff @@ -183,6 +184,7 @@ static uint8_t spiBuff[MAX_CHARS2UPDATE*6]; static uint8_t videoSignalCfg; static uint8_t videoSignalReg = OSD_ENABLE; // OSD_ENABLE required to trigger first ReInit +static uint8_t displayMemoryModeReg = 0; static uint8_t hosRegValue; // HOS (Horizontal offset register) value static uint8_t vosRegValue; // VOS (Vertical offset register) value @@ -370,7 +372,7 @@ void max7456ReInit(void) max7456Send(MAX7456ADD_HOS, hosRegValue); max7456Send(MAX7456ADD_VOS, vosRegValue); - max7456Send(MAX7456ADD_DMM, CLEAR_DISPLAY); + max7456Send(MAX7456ADD_DMM, displayMemoryModeReg | CLEAR_DISPLAY); DISABLE_MAX7456; // Clear shadow to force redraw all screen in non-dma mode. @@ -414,6 +416,38 @@ void max7456Init(const vcdProfile_t *pVcdProfile) // Real init will be made later when driver detect idle. } +/** + * Sets inversion of black and white pixels. + */ +void max7456Invert(bool invert) +{ + if (invert) + displayMemoryModeReg |= INVERT_PIXEL_COLOR; + else + displayMemoryModeReg &= ~INVERT_PIXEL_COLOR; + + ENABLE_MAX7456; + max7456Send(MAX7456ADD_DMM, displayMemoryModeReg); + DISABLE_MAX7456; +} + +/** + * Sets the brighness of black and white pixels. + * + * @param black Black brightness (0-3, 0 is darkest) + * @param white White brightness (0-3, 0 is darkest) + */ +void max7456Brightness(uint8_t black, uint8_t white) +{ + uint8_t reg = (black << 2) | (3 - white); + + ENABLE_MAX7456; + for (int i = MAX7456ADD_RB0; i <= MAX7456ADD_RB15; i++) { + max7456Send(i, reg); + } + DISABLE_MAX7456; +} + //just fill with spaces with some tricks void max7456ClearScreen(void) { @@ -560,7 +594,7 @@ void max7456RefreshAll(void) ENABLE_MAX7456; max7456Send(MAX7456ADD_DMAH, 0); max7456Send(MAX7456ADD_DMAL, 0); - max7456Send(MAX7456ADD_DMM, 1); + max7456Send(MAX7456ADD_DMM, displayMemoryModeReg | 1); for (xx = 0; xx < maxScreenSize; ++xx) { @@ -569,7 +603,7 @@ void max7456RefreshAll(void) } max7456Send(MAX7456ADD_DMDI, 0xFF); - max7456Send(MAX7456ADD_DMM, 0); + max7456Send(MAX7456ADD_DMM, displayMemoryModeReg); DISABLE_MAX7456; max7456Lock = false; } diff --git a/src/main/drivers/max7456.h b/src/main/drivers/max7456.h index 65cd4699ad..8e74d46fab 100755 --- a/src/main/drivers/max7456.h +++ b/src/main/drivers/max7456.h @@ -37,6 +37,8 @@ extern uint16_t maxScreenSize; struct vcdProfile_s; void max7456HardwareReset(void); void max7456Init(const struct vcdProfile_s *vcdProfile); +void max7456Invert(bool invert); +void max7456Brightness(uint8_t black, uint8_t white); void max7456DrawScreen(void); void max7456WriteNvm(uint8_t char_address, const uint8_t *font_data); uint8_t max7456GetRowsCount(void); diff --git a/src/main/fc/settings.c b/src/main/fc/settings.c index a1cfb2d0ed..d1542a23d6 100644 --- a/src/main/fc/settings.c +++ b/src/main/fc/settings.c @@ -700,6 +700,9 @@ const clivalue_t valueTable[] = { #ifdef USE_MAX7456 { "displayport_max7456_col_adjust", VAR_INT8| MASTER_VALUE, .config.minmax = { -6, 0 }, PG_DISPLAY_PORT_MAX7456_CONFIG, offsetof(displayPortProfile_t, colAdjust) }, { "displayport_max7456_row_adjust", VAR_INT8| MASTER_VALUE, .config.minmax = { -3, 0 }, PG_DISPLAY_PORT_MAX7456_CONFIG, offsetof(displayPortProfile_t, rowAdjust) }, + { "displayport_max7456_inv", VAR_UINT8| MASTER_VALUE | MODE_LOOKUP, .config.lookup = { TABLE_OFF_ON }, PG_DISPLAY_PORT_MAX7456_CONFIG, offsetof(displayPortProfile_t, invert) }, + { "displayport_max7456_blk", VAR_UINT8| MASTER_VALUE, .config.minmax = { 0, 3 }, PG_DISPLAY_PORT_MAX7456_CONFIG, offsetof(displayPortProfile_t, blackBrightness) }, + { "displayport_max7456_wht", VAR_UINT8| MASTER_VALUE, .config.minmax = { 0, 3 }, PG_DISPLAY_PORT_MAX7456_CONFIG, offsetof(displayPortProfile_t, whiteBrightness) }, #endif #ifdef USE_ESC_SENSOR diff --git a/src/main/io/displayport_max7456.c b/src/main/io/displayport_max7456.c index a62eff6031..5297b77ed0 100644 --- a/src/main/io/displayport_max7456.c +++ b/src/main/io/displayport_max7456.c @@ -37,8 +37,18 @@ displayPort_t max7456DisplayPort; -// no template required since defaults are zero -PG_REGISTER(displayPortProfile_t, displayPortProfileMax7456, PG_DISPLAY_PORT_MAX7456_CONFIG, 0); +PG_REGISTER_WITH_RESET_FN(displayPortProfile_t, displayPortProfileMax7456, PG_DISPLAY_PORT_MAX7456_CONFIG, 0); + +void pgResetFn_displayPortProfileMax7456(displayPortProfile_t *displayPortProfile) +{ + displayPortProfile->colAdjust = 0; + displayPortProfile->rowAdjust = 0; + + // Set defaults as per MAX7456 datasheet + displayPortProfile->invert = false; + displayPortProfile->blackBrightness = 0; + displayPortProfile->whiteBrightness = 2; +} static int grab(displayPort_t *displayPort) { @@ -62,6 +72,10 @@ static int release(displayPort_t *displayPort) static int clearScreen(displayPort_t *displayPort) { UNUSED(displayPort); + + max7456Invert(displayPortProfileMax7456()->invert); + max7456Brightness(displayPortProfileMax7456()->blackBrightness, displayPortProfileMax7456()->whiteBrightness); + max7456ClearScreen(); return 0;