Skip to content

Commit 9b0fbd7

Browse files
author
Jesus Lopez Garcia
committed
Add support for VTX MSP
Implement VTX MSP protocol support so the video channel can be changed from Betaflight, ELRS Lua Script or any other system that uses VTX MPS protocol. The plan is be able to change algo power and badnwidth.
1 parent f9d017b commit 9b0fbd7

File tree

9 files changed

+105
-4
lines changed

9 files changed

+105
-4
lines changed

dev_air.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ndk-build
2+
adb push libs/armeabi-v7a/msp_displayport_mux /blackbox
3+
adb shell setprop dji.hdvt_uav_service 0
4+
adb shell mv /dev/ttyS1 /dev/ttyS1_moved
5+
adb shell nohup /blackbox/msp_displayport_mux 192.168.41.2 /dev/ttyS1_moved /dev/ttyS1 &
6+
adb shell setprop dji.hdvt_uav_service 1

dev_goggles.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ndk-build
2+
adb shell setprop dji.glasses_wm150_service 0
3+
adb push libs/armeabi-v7a/libdisplayport_osd_shim.so /tmp
4+
adb shell LD_PRELOAD=/tmp/libdisplayport_osd_shim.so dji_gls_wm150_original -g

ipk/airunit/data/opt/etc/dinit.d/msp-osd-airside

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ type = bgprocess
22
command = /opt/bin/airunit-osd-start.sh
33
pid-file = /opt/var/run/airunit-osd-dji.pid
44
restart = true
5+
logfile = /blackbox/msp-osd.log
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
type = scripted
22
command = modmanager enable diy_glasses displayport_osd_shim
3-
stop-command = modmanager disable diy_glasses displayport_osd_shim
3+
stop-command = modmanager disable diy_glasses displayport_osd_shim
4+
logfile = /blackbox/msp-osd.log

jni/msp/msp.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
#define MSP_CMD_DISPLAYPORT 182
1818
#define MSP_CMD_SET_OSD_CANVAS 188
1919

20+
// https://github.com/betaflight/betaflight/blob/master/src/main/msp/msp_protocol.h#L201C1-L202C50
21+
#define MSP_CMD_VTX_CONFIG 88 // from FC
22+
#define MSP_CMD_SET_VTX_CONFIG 89 // to FC
23+
2024
typedef enum {
2125
MSP_ERR_NONE,
2226
MSP_ERR_HDR,
@@ -58,4 +62,4 @@ typedef struct msp_state_s {
5862

5963
uint16_t msp_data_from_msg(uint8_t message_buffer[], msp_msg_t *msg);
6064
msp_error_e construct_msp_command(uint8_t message_buffer[], uint8_t command, uint8_t payload[], uint8_t size, msp_direction_e direction);
61-
msp_error_e msp_process_data(msp_state_t *msp_state, uint8_t dat);
65+
msp_error_e msp_process_data(msp_state_t *msp_state, uint8_t dat);

jni/msp_displayport_mux.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static uint8_t serial_passthrough = 1;
7474
static uint8_t compress = 0;
7575
static uint8_t no_btfl_hd = 0;
7676

77+
int8_t fc_vtx_channel = -1;
78+
7779
static void sig_handler(int _)
7880
{
7981
quit = 1;
@@ -142,6 +144,20 @@ static void send_version_request(int serial_fd) {
142144
write(serial_fd, &buffer, sizeof(buffer));
143145
}
144146

147+
static void send_vtx_config_request(int serial_fd) {
148+
DEBUG_PRINT("Sending VTX CONFIG requests message...\n");
149+
uint8_t buffer[6];
150+
construct_msp_command(buffer, MSP_CMD_VTX_CONFIG, NULL, 0, MSP_OUTBOUND);
151+
write(serial_fd, &buffer, sizeof(buffer));
152+
}
153+
154+
static void send_vtx_set_config_request(int serial_fd) {
155+
DEBUG_PRINT("Sending VTX READY message...\n");
156+
uint8_t buffer[6];
157+
construct_msp_command(buffer, MSP_CMD_SET_VTX_CONFIG, NULL, 0, MSP_OUTBOUND);
158+
write(serial_fd, &buffer, sizeof(buffer));
159+
}
160+
145161
static void copy_to_msp_frame_buffer(void *buffer, uint16_t size) {
146162
memcpy(&frame_buffer[fb_cursor], buffer, size);
147163
fb_cursor += size;
@@ -208,6 +224,15 @@ static void rx_msp_callback(msp_msg_t *msp_message)
208224
}
209225
break;
210226
}
227+
case MSP_CMD_VTX_CONFIG: {
228+
DEBUG_PRINT("Received VTX CONFIG message...\n");
229+
printf("data: %d %d %d \n", msp_message->payload[0], msp_message->payload[1], msp_message->payload[2]);
230+
// TODO: Damage control accessing to index 2 if not exists
231+
fc_vtx_channel = msp_message->payload[2];
232+
}
233+
case MSP_CMD_SET_VTX_CONFIG: {
234+
DEBUG_PRINT("Received SET VTX CONFIG message...\n");
235+
}
211236
default: {
212237
uint16_t size = msp_data_from_msg(message_buffer, msp_message);
213238
if(serial_passthrough || cache_msp_message(msp_message)) {
@@ -249,8 +274,9 @@ static void send_data_packet(int data_socket_fd, dji_shm_state_t *dji_shm) {
249274
data.version_specifier = 0xFFFF;
250275
data.tx_temperature = get_int_from_fs(CPU_TEMP_PATH);
251276
data.tx_voltage = get_int_from_fs(AU_VOLTAGE_PATH);
277+
data.fc_vtx_channel = fc_vtx_channel;
252278
memcpy(data.fc_variant, current_fc_identifier, sizeof(current_fc_identifier));
253-
DEBUG_PRINT("got voltage %f V temp %d C variant %.4s\n", (float)(data.tx_voltage / 64.0f), data.tx_temperature, data.fc_variant);
279+
DEBUG_PRINT("got voltage %f V temp %d C variant %.4s and channel %d\n", (float)(data.tx_voltage / 64.0f), data.tx_temperature, data.fc_variant, data.fc_vtx_channel);
254280
write(data_socket_fd, &data, sizeof(data));
255281
}
256282

@@ -390,6 +416,8 @@ int main(int argc, char *argv[]) {
390416
clock_gettime(CLOCK_MONOTONIC, &last_data);
391417
clock_gettime(CLOCK_MONOTONIC, &last_frame);
392418

419+
send_vtx_set_config_request(serial_fd);
420+
393421
while (!quit) {
394422
poll_fds[0].fd = serial_fd;
395423
poll_fds[1].fd = pty_fd;
@@ -431,6 +459,8 @@ int main(int argc, char *argv[]) {
431459
if(current_fc_identifier[0] == 0) {
432460
send_variant_request(serial_fd);
433461
}
462+
//INFO: For testing purpose, request VTX_CONFIG
463+
send_vtx_config_request(serial_fd);
434464
}
435465
if(compress && (timespec_subtract_ns(&now, &last_frame) > (NSEC_PER_SEC / update_rate_hz))) {
436466
send_compressed_screen(compressed_fd);

jni/net/data_protocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ typedef struct packet_data_s {
44
uint16_t tx_temperature;
55
uint16_t version_specifier; // Used to be bitrate! Danger! 0xFFFF means V2 (no bitrate) for now.
66
uint16_t tx_voltage;
7+
int8_t fc_vtx_channel;
78
char fc_variant[4];
89
} __attribute__((packed)) packet_data_t;
910

jni/osd_dji_overlay_udp.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "rec/rec.h"
3535
#include "rec/rec_pb.h"
3636

37+
#include "util/vtx_manager.c"
38+
3739
#define MSP_PORT 7654
3840
#define DATA_PORT 7655
3941
#define COMPRESSED_DATA_PORT 7656
@@ -485,7 +487,7 @@ static void check_is_au_overlay_enabled()
485487

486488
static void process_data_packet(uint8_t *buf, int len, dji_shm_state_t *radio_shm) {
487489
packet_data_t *packet = (packet_data_t *)buf;
488-
DEBUG_PRINT("got data %04X version spec %d C %f V variant %.4s\n", packet->version_specifier, packet->tx_temperature, packet->tx_voltage / 64.0f, packet->fc_variant);
490+
DEBUG_PRINT("got data %04X version spec %d C %f V variant %.4s and vtx channel %d\n", packet->version_specifier, packet->tx_temperature, packet->tx_voltage / 64.0f, packet->fc_variant, packet->fc_vtx_channel);
489491
char str[8];
490492
clear_overlay();
491493
if(au_overlay_enabled) {
@@ -494,6 +496,7 @@ static void process_data_packet(uint8_t *buf, int len, dji_shm_state_t *radio_sh
494496
snprintf(str, 8, "A %2.1fV", packet->tx_voltage / 64.0f);
495497
display_print_string(overlay_display_info.char_width - 7, overlay_display_info.char_height - 7, str, 7);
496498
}
499+
changeChannel(packet->fc_vtx_channel);
497500
if(len > 6) {
498501
DEBUG_PRINT("Got new packet with variant %.4s\n", packet->fc_variant);
499502
// should have FC type

jni/util/vtx_manager.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#include <stdlib.h>
2+
#include <dlfcn.h>
3+
#include "util/debug.h"
4+
5+
6+
7+
static void *tp1801_gui_lib = NULL;
8+
static uint32_t (* setChannelPilotOriginal)(void *this,unsigned short param_1, bool param_2) = 0;
9+
static uint32_t (* userSettingsGetInstanceOriginal)() = 0;
10+
static uint32_t userSettingsInstance = 0;
11+
static int8_t currentChannel = -1;
12+
13+
void changeChannel(int8_t channel) {
14+
//Load SetPilotChannel original
15+
setChannelPilotOriginal = dlsym (RTLD_NEXT, "_ZN17GlassUserSettings15setPilotChannelEtb");
16+
if (setChannelPilotOriginal == NULL) {
17+
if(!tp1801_gui_lib){
18+
tp1801_gui_lib = dlopen("/system/lib/libtp1801_gui.so", 1);
19+
}
20+
setChannelPilotOriginal = dlsym (tp1801_gui_lib, "_ZN17GlassUserSettings15setPilotChannelEtb");
21+
if (setChannelPilotOriginal == NULL)
22+
{
23+
printf("dlsym: %s\n", dlerror());
24+
return;
25+
}
26+
}
27+
28+
//Load UserSettingGetInstance original
29+
userSettingsGetInstanceOriginal = dlsym (tp1801_gui_lib, "_ZN17GlassUserSettings11getInstanceEv");
30+
if (userSettingsGetInstanceOriginal == NULL)
31+
{
32+
printf("dlsym: %s\n", dlerror());
33+
return;
34+
}
35+
36+
if (channel <= 0 || channel > 8) {
37+
printf("VTX_MANAGER Error:, invalid channel index: %d\n", channel);
38+
return;
39+
}
40+
41+
if(currentChannel == channel) {
42+
return;
43+
}
44+
currentChannel = channel;
45+
46+
// if 8, need to set to public or works with the index?
47+
DEBUG_PRINT("VTX_MANAGER: requesting to the goggles to set channel %d\n", channel);
48+
49+
int8_t channelIdx = channel - 1;
50+
setChannelPilotOriginal(userSettingsGetInstanceOriginal(), channelIdx, true);
51+
}

0 commit comments

Comments
 (0)