From f183836b0f3c1ad668a98cdd0ea83816ee68e727 Mon Sep 17 00:00:00 2001 From: Hermes Date: Mon, 28 Sep 2026 16:07:47 +0200 Subject: [PATCH] hilink: pace MSP VTX table frames --- .../0001-wifilink-mspvtx-read-only.patch | 66 ++++++++++++------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/package/msposd/0001-wifilink-mspvtx-read-only.patch b/package/msposd/0001-wifilink-mspvtx-read-only.patch index 5c88b8d..472e467 100644 --- a/package/msposd/0001-wifilink-mspvtx-read-only.patch +++ b/package/msposd/0001-wifilink-mspvtx-read-only.patch @@ -80,10 +80,18 @@ index a8b756e..7e5ca2a 100644 break; } diff --git a/osd/msp/msp.c b/osd/msp/msp.c -index b1a538c..26171aa 100644 +index b1a538c..a527dff 100644 --- a/osd/msp/msp.c +++ b/osd/msp/msp.c -@@ -38,58 +38,62 @@ uint8_t saPowerLevelsLut[NUM_POWER_LEVELS] = {20, 25, 30, 35, 45, 50, 55, 58}; +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + #include + + extern bool verbose; +@@ -38,58 +39,76 @@ uint8_t saPowerLevelsLut[NUM_POWER_LEVELS] = {20, 25, 30, 35, 45, 50, 55, 58}; uint8_t saPowerLevelsLabel[NUM_POWER_LEVELS * POWER_LEVEL_LABEL_LENGTH] = {'2', '0', ' ', '2', '5', ' ', '3', '0', ' ', '3', '5', ' ', '4', '5', ' ', '5', '0', ' ', '5', '5', ' ', '5', '8', ' '}; @@ -114,23 +122,20 @@ index b1a538c..26171aa 100644 - payload[12] = 0; // newChannelCount - payload[13] = 0; // newPowerCount - payload[14] = 1; // vtxtable should be cleared -+static int get_wfb_vtx_config(int *band, int *channel, int *configured_frequency) { -+ *configured_frequency = read_wfb_frequency(); -+ if (*configured_frequency < 0) { -+ fprintf(stderr, "mspVTX: cannot read /etc/wfb.yaml channel\n"); -+ return -1; ++static void write_msp_packet(int serial_fd, const uint8_t *buffer, size_t size) { ++ ssize_t written = write(serial_fd, buffer, size); ++ if (written != (ssize_t)size) { ++ fprintf(stderr, "mspVTX: short serial write (%zd/%zu)\n", written, size); ++ return; + } - uint8_t buffer[256]; -+ *band = 1; -+ *channel = 1; -+ for (int index = 0; index < FREQ_TABLE_SIZE; index++) { -+ if (channelFreqTable[index] == *configured_frequency) { -+ *band = index / CHANNEL_COUNT + 1; -+ *channel = index % CHANNEL_COUNT + 1; -+ return 0; -+ } -+ } ++ // Betaflight's MSP parser is also carrying DisplayPort traffic on this ++ // UART. Drain and pace table frames so a cold boot cannot overrun its ++ // receive path before it has processed the preceding configuration frame. ++ tcdrain(serial_fd); ++ usleep(20 * 1000); ++} - construct_msp_command(buffer, MSP_SET_VTX_CONFIG, payload, sizeof(payload), MSP_OUTBOUND); - write(serial_fd, &buffer, sizeof(buffer)); @@ -151,6 +156,23 @@ index b1a538c..26171aa 100644 - payload[12] = CHANNEL_COUNT; // newChannelCount - payload[13] = NUM_POWER_LEVELS; // newPowerCount - payload[14] = 0; // vtxtable should be cleared ++static int get_wfb_vtx_config(int *band, int *channel, int *configured_frequency) { ++ *configured_frequency = read_wfb_frequency(); ++ if (*configured_frequency < 0) { ++ fprintf(stderr, "mspVTX: cannot read /etc/wfb.yaml channel\n"); ++ return -1; ++ } ++ ++ *band = 1; ++ *channel = 1; ++ for (int index = 0; index < FREQ_TABLE_SIZE; index++) { ++ if (channelFreqTable[index] == *configured_frequency) { ++ *band = index / CHANNEL_COUNT + 1; ++ *channel = index % CHANNEL_COUNT + 1; ++ return 0; ++ } ++ } ++ + fprintf(stderr, "mspVTX: %d MHz is absent from the VTX table\n", *configured_frequency); + return -1; +} @@ -177,7 +199,7 @@ index b1a538c..26171aa 100644 construct_msp_command(buffer, MSP_SET_VTX_CONFIG, payload, sizeof(payload), MSP_OUTBOUND); - write(serial_fd, &buffer, sizeof(buffer)); -+ write(serial_fd, buffer, sizeof(payload) + 6); ++ write_msp_packet(serial_fd, buffer, sizeof(payload) + 6); +} + +static void wipeVtxTable(int serial_fd, int band, int channel, int configured_frequency) { @@ -188,21 +210,21 @@ index b1a538c..26171aa 100644 } void setVtxTableBand(int serial_fd, uint8_t band) { -@@ -119,7 +123,7 @@ void setVtxTableBand(int serial_fd, uint8_t band) { +@@ -119,7 +138,7 @@ void setVtxTableBand(int serial_fd, uint8_t band) { } construct_msp_command(buffer, MSP_SET_VTXTABLE_BAND, payload2, sizeof(payload2), MSP_OUTBOUND); - write(serial_fd, &buffer, sizeof(buffer)); -+ write(serial_fd, buffer, sizeof(payload2) + 6); ++ write_msp_packet(serial_fd, buffer, sizeof(payload2) + 6); } void setVtxTablePowerLevel(int serial_fd, uint8_t idx) { -@@ -139,31 +143,24 @@ void setVtxTablePowerLevel(int serial_fd, uint8_t idx) { +@@ -139,31 +158,24 @@ void setVtxTablePowerLevel(int serial_fd, uint8_t idx) { construct_msp_command( buffer, MSP_SET_VTXTABLE_POWERLEVEL, payload2, sizeof(payload2), MSP_OUTBOUND); - write(serial_fd, &buffer, sizeof(buffer)); -+ write(serial_fd, buffer, sizeof(payload2) + 6); ++ write_msp_packet(serial_fd, buffer, sizeof(payload2) + 6); } void msp_set_vtx_config(int serial_fd) { @@ -240,7 +262,7 @@ index b1a538c..26171aa 100644 for (int i = 1; i <= BAND_COUNT; i++) { setVtxTableBand(serial_fd, i); -@@ -174,6 +171,18 @@ void msp_set_vtx_config(int serial_fd) { +@@ -174,6 +186,18 @@ void msp_set_vtx_config(int serial_fd) { vtxInitDone = true; }