Skip to content

Commit

Permalink
OSD custom elements
Browse files Browse the repository at this point in the history
  • Loading branch information
error414 committed Feb 12, 2024
1 parent d6bba05 commit 9b889d3
Show file tree
Hide file tree
Showing 9 changed files with 409 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/main/CMakeLists.txt
Expand Up @@ -371,6 +371,8 @@ main_sources(COMMON_SRC
io/rcdevice_cam.c
io/rcdevice_cam.h

io/osd/custom_elements.c

msp/msp_serial.c
msp/msp_serial.h

Expand Down
1 change: 1 addition & 0 deletions src/main/config/parameter_group_ids.h
Expand Up @@ -123,6 +123,7 @@
#define PG_EZ_TUNE 1033
#define PG_LEDPIN_CONFIG 1034
#define PG_OSD_JOYSTICK_CONFIG 1035
#define PG_OSD_CUSTOM_ELEMENTS_CONFIG 1036
#define PG_INAV_END PG_OSD_JOYSTICK_CONFIG


Expand Down
140 changes: 140 additions & 0 deletions src/main/fc/cli.c
Expand Up @@ -93,6 +93,7 @@ bool cliMode = false;
#include "io/gps_ublox.h"
#include "io/ledstrip.h"
#include "io/osd.h"
#include "io/osd/custom_elements.h"
#include "io/serial.h"

#include "fc/fc_msp_box.h"
Expand Down Expand Up @@ -2229,6 +2230,137 @@ static void cliPid(char *cmdline) {
}
}

static void printOsdCustomElements(uint8_t dumpMask, const osdCustomElement_t *osdCustomElements, const osdCustomElement_t *defaultosdCustomElements)
{
const char *format = "osd_custom_elements %d %d %d %d %d %d %d %d %d \"%s\"";

if(CUSTOM_ELEMENTS_PARTS != 3)
{
cliPrintHashLine("Incompatible count of elements for custom OSD elements");
}

for (uint8_t i = 0; i < MAX_CUSTOM_ELEMENTS; i++) {
bool equalsDefault = false;

const osdCustomElement_t osdCustomElement = osdCustomElements[i];
if(defaultosdCustomElements){
const osdCustomElement_t defaultValue = defaultosdCustomElements[i];
equalsDefault =
osdCustomElement.part[0].type == defaultValue.part[0].type &&
osdCustomElement.part[0].value == defaultValue.part[0].value &&
osdCustomElement.part[1].type == defaultValue.part[1].type &&
osdCustomElement.part[1].value == defaultValue.part[1].value &&
osdCustomElement.part[2].type == defaultValue.part[2].type &&
osdCustomElement.part[2].value == defaultValue.part[2].value &&
osdCustomElement.visibility.type == defaultValue.visibility.type &&
osdCustomElement.visibility.value == defaultValue.visibility.value &&
strcmp(osdCustomElement.osdCustomElementText, defaultValue.osdCustomElementText) == 0;

cliDefaultPrintLinef(dumpMask, equalsDefault, format,
i,
osdCustomElement.part[0].type,
osdCustomElement.part[0].value,
osdCustomElement.part[1].type,
osdCustomElement.part[1].value,
osdCustomElement.part[2].type,
osdCustomElement.part[2].value,
osdCustomElement.visibility.type,
osdCustomElement.visibility.value,
osdCustomElement.osdCustomElementText
);
}

cliDumpPrintLinef(dumpMask, equalsDefault, format,
i,
osdCustomElement.part[0].type,
osdCustomElement.part[0].value,
osdCustomElement.part[1].type,
osdCustomElement.part[1].value,
osdCustomElement.part[2].type,
osdCustomElement.part[2].value,
osdCustomElement.visibility.type,
osdCustomElement.visibility.value,
osdCustomElement.osdCustomElementText
);
}
}

static void osdCustom(char *cmdline){
char * saveptrMain;
char * saveptrParams;
int args[10], check = 0;
char text[OSD_CUSTOM_ELEMENT_TEXT_SIZE];
uint8_t len = strlen(cmdline);

if (len == 0) {
printOsdCustomElements(DUMP_MASTER, osdCustomElements(0), NULL);
} else {
//split by ", first are params second is text
char *ptrMain = strtok_r(cmdline, "\"", &saveptrMain);
enum {
INDEX = 0,
PART0_TYPE,
PART0_VALUE,
PART1_TYPE,
PART1_VALUE,
PART2_TYPE,
PART2_VALUE,
VISIBILITY_TYPE,
VISIBILITY_VALUE,
ARGS_COUNT
};
char *ptrParams = strtok_r(ptrMain, " ", &saveptrParams);
while (ptrParams != NULL && check < ARGS_COUNT) {
args[check++] = fastA2I(ptrParams);
ptrParams = strtok_r(NULL, " ", &saveptrParams);
}

if (check != ARGS_COUNT) {
cliShowParseError();
return;
}

//text
char *ptrText = strtok_r(NULL, "\"", &saveptrMain);
size_t copySize = 0;
if(ptrText != NULL){
copySize = MIN(strlen(ptrText), (size_t)(sizeof(text) - 1));
if(copySize > 0){
memcpy(text, ptrText, copySize);
}
}
text[copySize] = '\0';

int32_t i = args[INDEX];
if (
i >= 0 && i < MAX_CUSTOM_ELEMENTS &&
args[PART0_TYPE] >= 0 && args[PART0_TYPE] <= 7 &&
args[PART0_VALUE] >= 0 && args[PART0_VALUE] <= UINT8_MAX &&
args[PART1_TYPE] >= 0 && args[PART1_TYPE] <= 7 &&
args[PART1_VALUE] >= 0 && args[PART1_VALUE] <= UINT8_MAX &&
args[PART2_TYPE] >= 0 && args[PART2_TYPE] <= 7 &&
args[PART2_VALUE] >= 0 && args[PART2_VALUE] <= UINT8_MAX &&
args[VISIBILITY_TYPE] >= 0 && args[VISIBILITY_TYPE] <= 2 &&
args[VISIBILITY_VALUE] >= 0 && args[VISIBILITY_VALUE] <= UINT8_MAX
) {
osdCustomElementsMutable(i)->part[0].type = args[PART0_TYPE];
osdCustomElementsMutable(i)->part[0].value = args[PART0_VALUE];
osdCustomElementsMutable(i)->part[1].type = args[PART1_TYPE];
osdCustomElementsMutable(i)->part[1].value = args[PART1_VALUE];
osdCustomElementsMutable(i)->part[2].type = args[PART2_TYPE];
osdCustomElementsMutable(i)->part[2].value = args[PART2_VALUE];
osdCustomElementsMutable(i)->visibility.type = args[VISIBILITY_TYPE];
osdCustomElementsMutable(i)->visibility.value = args[VISIBILITY_VALUE];
memcpy(osdCustomElementsMutable(i)->osdCustomElementText, text, OSD_CUSTOM_ELEMENT_TEXT_SIZE);

osdCustom("");
} else {
cliShowParseError();
}
}
}


#endif

#ifdef USE_SDCARD
Expand Down Expand Up @@ -3863,6 +3995,10 @@ static void printConfig(const char *cmdline, bool doDiff)
cliPrintHashLine("Programming: PID controllers");
printPid(dumpMask, programmingPids_CopyArray, programmingPids(0));
#endif
#ifdef USE_PROGRAMMING_FRAMEWORK
cliPrintHashLine("OSD: custom elements");
printOsdCustomElements(dumpMask, osdCustomElements_CopyArray, osdCustomElements(0));
#endif

cliPrintHashLine("master");
dumpAllValues(MASTER_VALUE, dumpMask);
Expand Down Expand Up @@ -4089,6 +4225,10 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("pid", "configurable PID controllers",
"<#> <enabled> <setpoint type> <setpoint value> <measurement type> <measurement value> <P gain> <I gain> <D gain> <FF gain>\r\n"
"\treset\r\n", cliPid),

CLI_COMMAND_DEF("osd_custom_elements", "configurable OSD custom elements",
"<#> <part0 type> <part0 value> <part1 type> <part1 value> <part2 type> <part2 value> <visibility type> <visibility value> <text>\r\n"
, osdCustom),
#endif
CLI_COMMAND_DEF("set", "change setting", "[<name>=<value>]", cliSet),
CLI_COMMAND_DEF("smix", "servo mixer",
Expand Down
40 changes: 40 additions & 0 deletions src/main/fc/fc_msp.c
Expand Up @@ -96,6 +96,8 @@
#include "io/vtx_string.h"
#include "io/gps_private.h" //for MSP_SIMULATOR

#include "io/osd/custom_elements.h"

#include "msp/msp.h"
#include "msp/msp_protocol.h"
#include "msp/msp_serial.h"
Expand Down Expand Up @@ -1637,12 +1639,30 @@ static bool mspFcProcessOutCommand(uint16_t cmdMSP, sbuf_t *dst, mspPostProcessF
break;

#endif
#ifdef USE_PROGRAMMING_FRAMEWORK
case MSP2_INAV_CUSTOM_OSD_ELEMENTS:
sbufWriteU8(dst, MAX_CUSTOM_ELEMENTS);
sbufWriteU8(dst, OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1);

for (int i = 0; i < MAX_CUSTOM_ELEMENTS; i++) {
const osdCustomElement_t *customElement = osdCustomElements(i);
for (int ii = 0; ii < CUSTOM_ELEMENTS_PARTS; ii++) {
sbufWriteU8(dst, customElement->part[ii].type);
sbufWriteU16(dst, customElement->part[ii].value);
}
sbufWriteU8(dst, customElement->visibility.type);
sbufWriteU16(dst, customElement->visibility.value);
for (int ii = 0; ii < OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1; ii++) {
sbufWriteU8(dst, customElement->osdCustomElementText[ii]);
}
}
break;
default:
return false;
}
return true;
}
#endif

#ifdef USE_SAFE_HOME
static mspResult_e mspFcSafeHomeOutCommand(sbuf_t *dst, sbuf_t *src)
Expand Down Expand Up @@ -3170,13 +3190,33 @@ static mspResult_e mspFcProcessInCommand(uint16_t cmdMSP, sbuf_t *src)
break;

#endif
#ifdef USE_PROGRAMMING_FRAMEWORK
case MSP2_INAV_SET_CUSTOM_OSD_ELEMENTS:
sbufReadU8Safe(&tmp_u8, src);
if ((dataSize == (OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1) + (MAX_CUSTOM_ELEMENTS * 3) + 4) && (tmp_u8 < MAX_CUSTOM_ELEMENTS)) {
for (int i = 0; i < CUSTOM_ELEMENTS_PARTS; i++) {
osdCustomElementsMutable(tmp_u8)->part[i].type = sbufReadU8(src);
osdCustomElementsMutable(tmp_u8)->part[i].value = sbufReadU16(src);
}
osdCustomElementsMutable(tmp_u8)->visibility.type = sbufReadU8(src);
osdCustomElementsMutable(tmp_u8)->visibility.value = sbufReadU16(src);
for (int i = 0; i < OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1; i++) {
osdCustomElementsMutable(tmp_u8)->osdCustomElementText[i] = sbufReadU8(src);
}
osdCustomElementsMutable(tmp_u8)->osdCustomElementText[OSD_CUSTOM_ELEMENT_TEXT_SIZE - 1] = '\0';
} else{
return MSP_RESULT_ERROR;
}

break;


default:
return MSP_RESULT_ERROR;
}
return MSP_RESULT_ACK;
}
#endif

static const setting_t *mspReadSetting(sbuf_t *src)
{
Expand Down
17 changes: 17 additions & 0 deletions src/main/io/osd.c
Expand Up @@ -72,6 +72,8 @@
#include "io/vtx.h"
#include "io/vtx_string.h"

#include "io/osd/custom_elements.h"

#include "fc/config.h"
#include "fc/controlrate_profile.h"
#include "fc/fc_core.h"
Expand Down Expand Up @@ -1689,6 +1691,21 @@ static bool osdDrawSingleElement(uint8_t item)
char buff[32] = {0};

switch (item) {
case OSD_CUSTOM_ELEMENT_1:
{
customElementDrawElement(buff, 0);
break;
}
case OSD_CUSTOM_ELEMENT_2:
{
customElementDrawElement(buff, 1);
break;
}
case OSD_CUSTOM_ELEMENT_3:
{
customElementDrawElement(buff, 2);
break;
}
case OSD_RSSI_VALUE:
{
uint16_t osdRssi = osdConvertRSSI();
Expand Down
3 changes: 3 additions & 0 deletions src/main/io/osd.h
Expand Up @@ -280,6 +280,9 @@ typedef enum {
OSD_MULTI_FUNCTION,
OSD_ODOMETER,
OSD_PILOT_LOGO,
OSD_CUSTOM_ELEMENT_1,
OSD_CUSTOM_ELEMENT_2,
OSD_CUSTOM_ELEMENT_3,
OSD_ITEM_COUNT // MUST BE LAST
} osd_items_e;

Expand Down

0 comments on commit 9b889d3

Please sign in to comment.