diff --git a/mk/source.mk b/mk/source.mk
index 70e4d00b57..c28a739577 100644
--- a/mk/source.mk
+++ b/mk/source.mk
@@ -22,6 +22,7 @@ PG_SRC = \
pg/motor.c \
pg/msp.c \
pg/pg.c \
+ pg/pilot.c \
pg/piniobox.c \
pg/pinio.c \
pg/pin_pull_up_down.c \
diff --git a/src/main/blackbox/blackbox.c b/src/main/blackbox/blackbox.c
index de74df3c30..89fa7a2632 100644
--- a/src/main/blackbox/blackbox.c
+++ b/src/main/blackbox/blackbox.c
@@ -81,8 +81,9 @@
#include "pg/alt_hold.h"
#include "pg/autopilot.h"
#include "pg/motor.h"
-#include "pg/rx.h"
+#include "pg/pilot.h"
#include "pg/pos_hold.h"
+#include "pg/rx.h"
#include "rx/rx.h"
diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c
index 926b5ada5a..46e2f9e325 100644
--- a/src/main/cli/cli.c
+++ b/src/main/cli/cli.c
@@ -139,6 +139,7 @@ bool cliMode = false;
#include "pg/max7456.h"
#include "pg/mco.h"
#include "pg/motor.h"
+#include "pg/pilot.h"
#include "pg/pinio.h"
#include "pg/pin_pull_up_down.h"
#include "pg/pg.h"
diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c
index fc4e9a703a..95406b6a91 100644
--- a/src/main/cli/settings.c
+++ b/src/main/cli/settings.c
@@ -95,6 +95,7 @@
#include "pg/msp.h"
#include "pg/pg.h"
#include "pg/pg_ids.h"
+#include "pg/pilot.h"
#include "pg/pinio.h"
#include "pg/piniobox.h"
#include "pg/pos_hold.h"
diff --git a/src/main/config/config.c b/src/main/config/config.c
index de895e7484..aedfdb12d1 100644
--- a/src/main/config/config.c
+++ b/src/main/config/config.c
@@ -106,13 +106,6 @@ pidProfile_t *currentPidProfile;
#define RX_SPI_DEFAULT_PROTOCOL 0
#endif
-PG_REGISTER_WITH_RESET_TEMPLATE(pilotConfig_t, pilotConfig, PG_PILOT_CONFIG, 2);
-
-PG_RESET_TEMPLATE(pilotConfig_t, pilotConfig,
- .craftName = { 0 },
- .pilotName = { 0 },
-);
-
PG_REGISTER_WITH_RESET_TEMPLATE(systemConfig_t, systemConfig, PG_SYSTEM_CONFIG, 3);
PG_RESET_TEMPLATE(systemConfig_t, systemConfig,
diff --git a/src/main/config/config.h b/src/main/config/config.h
index 94118a8611..17f35ee36c 100644
--- a/src/main/config/config.h
+++ b/src/main/config/config.h
@@ -25,20 +25,11 @@
#include "pg/pg.h"
-#define MAX_NAME_LENGTH 16u
-
typedef enum {
CONFIGURATION_STATE_UNCONFIGURED = 0,
CONFIGURATION_STATE_CONFIGURED,
} configurationState_e;
-typedef struct pilotConfig_s {
- char craftName[MAX_NAME_LENGTH + 1];
- char pilotName[MAX_NAME_LENGTH + 1];
-} pilotConfig_t;
-
-PG_DECLARE(pilotConfig_t, pilotConfig);
-
typedef struct systemConfig_s {
uint8_t pidProfileIndex;
uint8_t activeRateProfile;
diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c
index dcb6df0f75..31ff012e62 100644
--- a/src/main/msp/msp.c
+++ b/src/main/msp/msp.c
@@ -124,6 +124,7 @@
#include "pg/gps_rescue.h"
#include "pg/gyrodev.h"
#include "pg/motor.h"
+#include "pg/pilot.h"
#include "pg/pos_hold.h"
#include "pg/rx.h"
#include "pg/rx_spi.h"
@@ -1158,12 +1159,7 @@ static bool mspProcessOutCommand(mspDescriptor_t srcDesc, int16_t cmdMSP, sbuf_t
break;
case MSP_NAME:
- {
- const int nameLen = strlen(pilotConfig()->craftName);
- for (int i = 0; i < nameLen; i++) {
- sbufWriteU8(dst, pilotConfig()->craftName[i]);
- }
- }
+ sbufWriteString(dst, pilotConfig()->craftName);
break;
#ifdef USE_SERVOS
@@ -2610,9 +2606,7 @@ static mspResult_e mspFcProcessOutCommandWithArg(mspDescriptor_t srcDesc, int16_
// type byte, then length byte followed by the actual characters
sbufWriteU8(dst, textType);
sbufWriteU8(dst, textLength);
- for (unsigned int i = 0; i < textLength; i++) {
- sbufWriteU8(dst, textVar[i]);
- }
+ sbufWriteData(dst, textVar, textLength);
}
break;
#ifdef USE_LED_STRIP
@@ -3985,10 +3979,8 @@ static mspResult_e mspProcessInCommand(mspDescriptor_t srcDesc, int16_t cmdMSP,
#endif
case MSP_SET_NAME:
- memset(pilotConfigMutable()->craftName, 0, ARRAYLEN(pilotConfig()->craftName));
- for (unsigned int i = 0; i < MIN(MAX_NAME_LENGTH, dataSize); i++) {
- pilotConfigMutable()->craftName[i] = sbufReadU8(src);
- }
+ memset(pilotConfigMutable()->craftName, 0, sizeof(pilotConfigMutable()->craftName));
+ sbufReadData(src, pilotConfigMutable()->craftName, MIN(ARRAYLEN(pilotConfigMutable()->craftName) - 1, dataSize));
#ifdef USE_OSD
osdAnalyzeActiveElements();
#endif
@@ -4068,35 +4060,51 @@ static mspResult_e mspProcessInCommand(mspDescriptor_t srcDesc, int16_t cmdMSP,
case MSP2_SET_TEXT:
{
// type byte, then length byte followed by the actual characters
- const uint8_t textType = sbufReadU8(src);
+ const unsigned textType = sbufReadU8(src);
char* textVar;
- const uint8_t textLength = MIN(MAX_NAME_LENGTH, sbufReadU8(src));
+ unsigned textSpace;
switch (textType) {
case MSP2TEXT_PILOT_NAME:
textVar = pilotConfigMutable()->pilotName;
+ textSpace = sizeof(pilotConfigMutable()->pilotName) - 1;
break;
case MSP2TEXT_CRAFT_NAME:
textVar = pilotConfigMutable()->craftName;
+ textSpace = sizeof(pilotConfigMutable()->craftName) - 1;
break;
case MSP2TEXT_PID_PROFILE_NAME:
textVar = currentPidProfile->profileName;
+ textSpace = sizeof(currentPidProfile->profileName) - 1;
break;
case MSP2TEXT_RATE_PROFILE_NAME:
textVar = currentControlRateProfile->profileName;
+ textSpace = sizeof(currentControlRateProfile->profileName) - 1;
break;
+ case MSP2TEXT_CUSTOM_MSG_0:
+ case MSP2TEXT_CUSTOM_MSG_0 + 1:
+ case MSP2TEXT_CUSTOM_MSG_0 + 2:
+ case MSP2TEXT_CUSTOM_MSG_0 + 3: {
+ unsigned msgIdx = textType - MSP2TEXT_CUSTOM_MSG_0;
+ if (msgIdx < OSD_CUSTOM_MSG_COUNT) {
+ textVar = pilotConfigMutable()->message[msgIdx];
+ textSpace = sizeof(pilotConfigMutable()->message[msgIdx]) - 1;
+ } else {
+ return MSP_RESULT_ERROR;
+ }
+ break;
+ }
default:
return MSP_RESULT_ERROR;
}
+ const unsigned textLength = MIN(textSpace, sbufReadU8(src));
memset(textVar, 0, strlen(textVar));
- for (unsigned int i = 0; i < textLength; i++) {
- textVar[i] = sbufReadU8(src);
- }
+ sbufReadData(src, textVar, textLength);
#ifdef USE_OSD
if (textType == MSP2TEXT_PILOT_NAME || textType == MSP2TEXT_CRAFT_NAME) {
diff --git a/src/main/msp/msp_protocol_v2_betaflight.h b/src/main/msp/msp_protocol_v2_betaflight.h
index f96cd6a817..beefb27f2f 100644
--- a/src/main/msp/msp_protocol_v2_betaflight.h
+++ b/src/main/msp/msp_protocol_v2_betaflight.h
@@ -38,3 +38,6 @@
#define MSP2TEXT_RATE_PROFILE_NAME 4
#define MSP2TEXT_BUILDKEY 5
#define MSP2TEXT_RELEASENAME 6
+#define MSP2TEXT_CUSTOM_MSG_0 7 // CUSTOM_MSG_MAX_NUM entries are allocated
+#define CUSTOM_MSG_MAX_NUM 4
+// next new variable type must be >= MSP2TEXT_CUSTOM_MSG_0 + CUSTOM_MSG_MAX_NUM (11)
diff --git a/src/main/osd/osd.h b/src/main/osd/osd.h
index c7cfbc19d5..c311bb1f45 100644
--- a/src/main/osd/osd.h
+++ b/src/main/osd/osd.h
@@ -190,6 +190,10 @@ typedef enum {
OSD_GPS_LAP_TIME_PREVIOUS,
OSD_GPS_LAP_TIME_BEST3,
OSD_DEBUG2,
+ OSD_CUSTOM_MSG0,
+ OSD_CUSTOM_MSG1,
+ OSD_CUSTOM_MSG2,
+ OSD_CUSTOM_MSG3,
OSD_ITEM_COUNT // MUST BE LAST
} osd_items_e;
diff --git a/src/main/osd/osd_elements.c b/src/main/osd/osd_elements.c
index 51e43cff53..23ddd5c9e4 100644
--- a/src/main/osd/osd_elements.c
+++ b/src/main/osd/osd_elements.c
@@ -161,6 +161,7 @@
#include "osd/osd_warnings.h"
#include "pg/motor.h"
+#include "pg/pilot.h"
#include "pg/stats.h"
#include "rx/rx.h"
@@ -810,6 +811,18 @@ static void osdElementCompassBar(osdElementParms_t *element)
element->buff[9] = 0;
}
+//display custom message from MSPv2
+static void osdElementCustomMsg(osdElementParms_t *element)
+{
+ int msgIndex = element->item - OSD_CUSTOM_MSG0;
+ if (msgIndex < 0 || msgIndex >= OSD_CUSTOM_MSG_COUNT || pilotConfig()->message[msgIndex][0] == '\0') {
+ tfp_sprintf(element->buff, "CUSTOM_MSG%d", msgIndex + 1);
+ } else {
+ strncpy(element->buff, pilotConfig()->message[msgIndex], MAX_NAME_LENGTH);
+ element->buff[MAX_NAME_LENGTH] = 0; // terminate maximum-length string
+ }
+}
+
#ifdef USE_ADC_INTERNAL
static void osdElementCoreTemperature(osdElementParms_t *element)
{
@@ -1804,6 +1817,10 @@ static const uint8_t osdElementDisplayOrder[] = {
OSD_MAH_DRAWN,
OSD_WATT_HOURS_DRAWN,
OSD_CRAFT_NAME,
+ OSD_CUSTOM_MSG0,
+ OSD_CUSTOM_MSG1,
+ OSD_CUSTOM_MSG2,
+ OSD_CUSTOM_MSG3,
OSD_ALTITUDE,
OSD_ROLL_PIDS,
OSD_PITCH_PIDS,
@@ -1902,6 +1919,10 @@ const osdElementDrawFn osdElementDrawFunction[OSD_ITEM_COUNT] = {
[OSD_ITEM_TIMER_2] = osdElementTimer,
[OSD_FLYMODE] = osdElementFlymode,
[OSD_CRAFT_NAME] = NULL, // only has background
+ [OSD_CUSTOM_MSG0] = osdElementCustomMsg,
+ [OSD_CUSTOM_MSG1] = osdElementCustomMsg,
+ [OSD_CUSTOM_MSG2] = osdElementCustomMsg,
+ [OSD_CUSTOM_MSG3] = osdElementCustomMsg,
[OSD_THROTTLE_POS] = osdElementThrottlePosition,
#ifdef USE_VTX_COMMON
[OSD_VTX_CHANNEL] = osdElementVtxChannel,
diff --git a/src/main/pg/pilot.c b/src/main/pg/pilot.c
new file mode 100644
index 0000000000..4691cd00a4
--- /dev/null
+++ b/src/main/pg/pilot.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#include
+#include
+
+#include "platform.h"
+
+#include "pg/pg.h"
+#include "pg/pg_ids.h"
+
+#include "pilot.h"
+
+PG_REGISTER_WITH_RESET_TEMPLATE(pilotConfig_t, pilotConfig, PG_PILOT_CONFIG, 2);
+
+PG_RESET_TEMPLATE(pilotConfig_t, pilotConfig,
+ .craftName = { 0 },
+ .pilotName = { 0 },
+ .message = { {0} },
+);
diff --git a/src/main/pg/pilot.h b/src/main/pg/pilot.h
new file mode 100644
index 0000000000..644016f7c0
--- /dev/null
+++ b/src/main/pg/pilot.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of Betaflight.
+ *
+ * Betaflight is free software. You can redistribute this software
+ * and/or modify this software under the terms of the GNU General
+ * Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * Betaflight is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this software.
+ *
+ * If not, see .
+ */
+
+#pragma once
+
+#include "pg/pg.h"
+
+#define MAX_NAME_LENGTH 16u
+#define OSD_CUSTOM_MSG_COUNT 4
+
+typedef struct pilotConfig_s {
+ char craftName[MAX_NAME_LENGTH + 1];
+ char pilotName[MAX_NAME_LENGTH + 1];
+ char message[OSD_CUSTOM_MSG_COUNT][MAX_NAME_LENGTH + 1];
+} pilotConfig_t;
+
+PG_DECLARE(pilotConfig_t, pilotConfig);
diff --git a/src/test/unit/cli_unittest.cc b/src/test/unit/cli_unittest.cc
index cb3243a771..63362e630f 100644
--- a/src/test/unit/cli_unittest.cc
+++ b/src/test/unit/cli_unittest.cc
@@ -53,6 +53,7 @@ extern "C" {
#include "pg/pg_ids.h"
#include "pg/beeper.h"
#include "pg/gps.h"
+ #include "pg/pilot.h"
#include "pg/rx.h"
#include "rx/rx.h"
#include "scheduler/scheduler.h"
diff --git a/src/test/unit/link_quality_unittest.cc b/src/test/unit/link_quality_unittest.cc
index c7eb278496..c01de00455 100644
--- a/src/test/unit/link_quality_unittest.cc
+++ b/src/test/unit/link_quality_unittest.cc
@@ -61,6 +61,7 @@ extern "C" {
#include "pg/pg.h"
#include "pg/pg_ids.h"
+ #include "pg/pilot.h"
#include "pg/rx.h"
#include "rx/rx.h"
diff --git a/src/test/unit/osd_unittest.cc b/src/test/unit/osd_unittest.cc
index 0812c863cc..d11230d42b 100644
--- a/src/test/unit/osd_unittest.cc
+++ b/src/test/unit/osd_unittest.cc
@@ -58,6 +58,7 @@ extern "C" {
#include "pg/gps_rescue.h"
#include "pg/pg.h"
#include "pg/pg_ids.h"
+ #include "pg/pilot.h"
#include "pg/rx.h"
#include "sensors/acceleration.h"