hilink: pace MSP VTX table frames

This commit is contained in:
2026-09-28 16:07:47 +02:00
parent fc34d457a0
commit f183836b0f
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
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;
}