feat(mt12): make use of "servo test" port (#6528)

Co-authored-by: 3djc <3djc@gh.com>
Co-authored-by: raphaelcoeffic <1050031+raphaelcoeffic@users.noreply.github.com>
Co-authored-by: Peter Feerick <5500713+pfeerick@users.noreply.github.com>
This commit is contained in:
Raphael Coeffic
2026-08-19 09:18:17 +10:00
committed by GitHub
co-authored by 3djc raphaelcoeffic Peter Feerick
parent 559b9a9991
commit 423876b10b
27 changed files with 212 additions and 1 deletions
@@ -140,6 +140,7 @@ void menuRadioSpectrumAnalyser(event_t event);
void menuRadioPowerMeter(event_t event);
void menuRadioCalibration(event_t event);
void menuGhostModuleConfig(event_t event);
void menuServoPwmTool(event_t event);
void menuModelSelect(event_t event);
void menuModelSetup(event_t event);
@@ -0,0 +1,100 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program 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.
*/
#include "edgetx.h"
#include "os/sleep.h"
#if defined(SERVO_PWM)
#if LCD_W >= 212
#define HW_SETTINGS_COLUMN1 12*FW
#define HW_SETTINGS_COLUMN2 (20*FW - 3)
#define HW_SETTINGS_COLUMN3 HW_SETTINGS_COLUMN2
#else
#define HW_SETTINGS_COLUMN1 30
#define HW_SETTINGS_COLUMN2 (HW_SETTINGS_COLUMN1 + 5*FW)
#define HW_SETTINGS_COLUMN3 HW_SETTINGS_COLUMN2 + FW
#endif
#if !defined(SIMU)
extern void pwmOutputDisable();
extern void pwmOutputInit();
extern void pwmOutputEnable(uint16_t pulse_width_us);
#else
void pwmOutputDisable() {}
void pwmOutputInit() {}
void pwmOutputEnable(uint16_t) {}
#endif
// 1-based output channel number, not a mixsrc_t
static constexpr uint8_t PWM_SOURCE_NONE = 0;
static uint8_t pwmOutputSource;
enum {
ITEM_PWM_SOURCE,
ITEM_SERVO_PWM_MAX,
};
void menuServoPwmTool(event_t event)
{
SUBMENU(STR_PWM_OUTPUT, 0, {0});
if (menuEvent == EVT_ENTRY_UP) {
TRACE("stopping servo pwm...");
pwmOutputDisable();
return;
}
if (event == EVT_ENTRY) {
TRACE("starting servo pwm...");
pwmOutputSource = PWM_SOURCE_NONE;
pwmOutputInit();
}
if (pwmOutputSource != PWM_SOURCE_NONE) {
mixsrc_t chan = pwmOutputSource - 1;
pwmOutputEnable(PPM_CH_CENTER(chan) + channelOutputs[chan] / 2);
} else {
pwmOutputDisable();
}
for (int i = 0; i < ITEM_SERVO_PWM_MAX; i++) {
LcdFlags attr = (menuVerticalPosition == i ? (s_editMode > 0 ? INVERS | BLINK : INVERS) : 0);
coord_t y = MENU_HEADER_HEIGHT + 12 + i * FH;
switch (i) {
case ITEM_PWM_SOURCE: {
lcdDrawTextAlignedLeft(y, STR_SOURCE);
mixsrc_t src = (pwmOutputSource != PWM_SOURCE_NONE)
? MIXSRC_FIRST_CH + pwmOutputSource - 1
: MIXSRC_NONE;
drawSource(HW_SETTINGS_COLUMN2, y, src, attr);
if (attr & BLINK)
CHECK_INCDEC_GENVAR(event, pwmOutputSource, PWM_SOURCE_NONE,
MAX_OUTPUT_CHANNELS);
break;
}
}
}
}
#endif
@@ -220,6 +220,10 @@ void menuRadioTools(event_t event)
addRadioModuleToolHandler(index++, "Ghost Menu", menuGhostModuleConfig, EXTERNAL_MODULE);
#endif
#if defined(SERVO_PWM)
addRadioModuleToolHandler(index++, STR_PWM_OUTPUT, menuServoPwmTool, 0);
#endif
#endif
if (index == 0) {
+15
View File
@@ -568,6 +568,12 @@ if(ROTARY_ENCODER)
)
endif()
if(PCBREV STREQUAL MT12)
list(APPEND BOARD_COMMON_SRC
${TARGET_SRC_DIR}/pwm_ch_driver.cpp
)
endif()
# Bootloader board library
add_library(board_bl OBJECT EXCLUDE_FROM_ALL
${BOARD_COMMON_SRC}
@@ -641,6 +647,15 @@ if(FLAVOUR STREQUAL xlites)
)
endif()
if(FLAVOUR STREQUAL mt12)
target_sources(board PRIVATE
${TARGET_SRC_DIR}/pwm_ch_driver.cpp
)
set(SRC ${SRC}
gui/common/stdlcd/radio_servo_pwm.cpp
)
endif()
set(SRC ${SRC}
io/frsky_firmware_update.cpp
io/multi_firmware_update.cpp
+11
View File
@@ -975,6 +975,17 @@
#endif
#endif
#if defined(RADIO_MT12)
#define SERVO_PWM
#define PWM_GPIO GPIO_PIN(GPIOB, 0) // PB.00
#define PWM_GPIO_AF GPIO_AF2
#define PWM_GPIO_TIMER TIM3 // Timer 3 Channel3
#define PWM_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
#define PWM_COUNTER_REGISTER PWM_TIMER->CCR3
#define PWM_CCMR2 TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2
#define PWM_CCER TIM_CCER_CC3E
#endif
#if defined(RADIO_BOXER) || defined(RADIO_FAMILY_T20) || defined(RADIO_X9DP2019) || defined (RADIO_V14) || defined(RADIO_V14LCD) || defined(RADIO_GX12)
// Flysky Hall Stick
#define FLYSKY_HALL_SERIAL_USART UART4
@@ -0,0 +1,59 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program 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.
*/
#include "stm32_pulse_driver.h"
#include "stm32_gpio.h"
#include "edgetx_types.h"
#include "board.h"
static const stm32_pulse_timer_t _pwm_timer = {
.GPIO = (gpio_t)PWM_GPIO,
.GPIO_Alternate = PWM_GPIO_AF,
.TIMx = PWM_GPIO_TIMER,
.TIM_Freq = PWM_TIMER_FREQ,
.TIM_Channel = LL_TIM_CHANNEL_CH3,
.TIM_IRQn = (IRQn_Type)-1,
.DMAx = nullptr,
.DMA_Stream = 0,
.DMA_Channel = 0,
.DMA_IRQn = (IRQn_Type)-1,
.DMA_TC_CallbackPtr = nullptr,
};
void pwmOutputDisable()
{
stm32_pulse_stop(&_pwm_timer);
}
void pwmOutputInit()
{
stm32_pulse_init(&_pwm_timer, 2000000);
stm32_pulse_config_output(&_pwm_timer, true, LL_TIM_OCMODE_PWM1, 0);
LL_TIM_SetAutoReload(_pwm_timer.TIMx, 15000); // 15ms between PWM pulses
LL_TIM_EnableCounter(_pwm_timer.TIMx);
}
void pwmOutputEnable(uint16_t pulse_width_us)
{
stm32_pulse_set_cmp_val(&_pwm_timer, pulse_width_us);
stm32_pulse_start(&_pwm_timer);
}
+1
View File
@@ -1205,6 +1205,7 @@
#define TR_MENU_OTHER "其它"
#define TR_MENU_INVERT "反向"
#define TR_AUDIO_MUTE TR("自动静音","音频停播时自动静音")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC滤波器"
#define TR_DEAD_ZONE "死区"
#define TR_RTC_CHECK TR("RTC电池", "RTC纽扣电池电压")
+1
View File
@@ -1209,6 +1209,7 @@
#define TR_MENU_OTHER "Ostatní"
#define TR_MENU_INVERT "Invertovat"
#define TR_AUDIO_MUTE TR("Ztlumení zvuku","Ztlumení, pokud není slyšet zvuk")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC Filtr"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Kontr RTC", "Hlídat RTC napětí")
+1
View File
@@ -1212,6 +1212,7 @@
#define TR_MENU_OTHER "Andet"
#define TR_MENU_INVERT "Invers"
#define TR_AUDIO_MUTE TR("Audio fra","Audio fra, hvis der ikke gives lyd")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC filter"
#define TR_DEAD_ZONE "Dødt område"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC spænding")
+1
View File
@@ -1206,6 +1206,7 @@
#define TR_MENU_OTHER "Weitere"
#define TR_MENU_INVERT TR_BW_COL("Invert.", "Invertieren")
#define TR_AUDIO_MUTE TR("Ton Stumm","Geräuschunterdrückung")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC Filter"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("RTC Prüfen", "RTC Spannung prüfen")
+1
View File
@@ -1206,6 +1206,7 @@
#define TR_MENU_OTHER "Other"
#define TR_MENU_INVERT "Invert"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC filter"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
+1
View File
@@ -1207,6 +1207,7 @@
#define TR_MENU_OTHER "Otros"
#define TR_MENU_INVERT "Invertir"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Filtro ADC"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltaje")
+1
View File
@@ -1207,6 +1207,7 @@
#define TR_MENU_OTHER "Other"
#define TR_MENU_INVERT "Invert"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC Filter"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
+1
View File
@@ -1209,6 +1209,7 @@
#define TR_MENU_OTHER "Autres"
#define TR_MENU_INVERT "Inverser"
#define TR_AUDIO_MUTE TR("Audio muet","Muet si pas de son")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Filtre ADC"
#define TR_DEAD_ZONE "Zone Neutre"
#define TR_RTC_CHECK TR("Vérif. RTC", "Vérif. pile RTC")
+1
View File
@@ -1208,6 +1208,7 @@
#define TR_MENU_OTHER "אחר"
#define TR_MENU_INVERT "הפוך"
#define TR_AUDIO_MUTE TR("השתקת קול","השתק כאשר אין סאונד")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC filter"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
+1
View File
@@ -1205,6 +1205,7 @@
#define TR_MENU_OTHER "Altro"
#define TR_MENU_INVERT "Inverti"
#define TR_AUDIO_MUTE TR("Audio muto","Muto senza suono")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Filtro ADC"
#define TR_DEAD_ZONE "Zona morta"
#define TR_RTC_CHECK TR("Controllo RTC", "Controllo volt. RTC")
+1
View File
@@ -1204,6 +1204,7 @@
#define TR_MENU_OTHER "その他"
#define TR_MENU_INVERT "リバース"
#define TR_AUDIO_MUTE TR("Audio mute","音源ミュート")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADCフィルター"
#define TR_DEAD_ZONE "デッドゾーン"
#define TR_RTC_CHECK TR("Check RTC", "内蔵電池チェック")
+1
View File
@@ -1251,6 +1251,7 @@
#define TR_MENU_OTHER "기타"
#define TR_MENU_INVERT "반전"
#define TR_AUDIO_MUTE TR("오디오 음소거", "소리가 없을 때 음소거")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC 필터"
#define TR_DEAD_ZONE "데드존"
#define TR_RTC_CHECK TR("RTC 확인", "RTC 전압 확인")
+1
View File
@@ -1208,6 +1208,7 @@
#define TR_MENU_OTHER "Verdere"
#define TR_MENU_INVERT "Inverteer"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC Filter"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
+2 -1
View File
@@ -1204,7 +1204,8 @@
#define TR_MENU_DISPLAY "DISPLAY"
#define TR_MENU_OTHER "Inny "
#define TR_MENU_INVERT "Odwróć"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Filtr ADC"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage")
+1
View File
@@ -1205,6 +1205,7 @@
#define TR_MENU_OTHER "Outros"
#define TR_MENU_INVERT "Invert"
#define TR_AUDIO_MUTE TR("Audio mute","Mute if no sound")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Filtro ADC"
#define TR_DEAD_ZONE "Dead zone"
#define TR_RTC_CHECK TR("Check RTC", "Checar tensão RTC")
+1
View File
@@ -1207,6 +1207,7 @@
#define TR_MENU_OTHER "Другое"
#define TR_MENU_INVERT "Инвертир"
#define TR_AUDIO_MUTE TR("Выкл звук", "Выкл звук")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Фильтр АЦП"
#define TR_DEAD_ZONE "Зона нечувств"
#define TR_RTC_CHECK TR("Проверка RTC", "Проверка RTC")
+1
View File
@@ -1220,6 +1220,7 @@
#define TR_MENU_OTHER "Övrigt"
#define TR_MENU_INVERT "Invertera"
#define TR_AUDIO_MUTE TR("Audio av","Audio av om inget ljud")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC-filter"
#define TR_DEAD_ZONE "Dödläge"
#define TR_RTC_CHECK TR("Kolla RTC", "Kolla RTC-batteriet")
+1
View File
@@ -1203,6 +1203,7 @@
#define TR_MENU_OTHER "其它"
#define TR_MENU_INVERT "反向"
#define TR_AUDIO_MUTE TR("自動靜音","音頻停播時自動靜音")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "ADC濾波器"
#define TR_DEAD_ZONE "死區"
#define TR_RTC_CHECK TR("檢查時間電池", "檢查時間驅動電池電壓")
+1
View File
@@ -1206,6 +1206,7 @@
#define TR_MENU_OTHER "Інше"
#define TR_MENU_INVERT "Інверт"
#define TR_AUDIO_MUTE TR("Аудіо стоп","Тихо якщо немає звуку")
#define TR_PWM_OUTPUT "PWM output"
#define TR_JITTER_FILTER "Фільтр ADC"
#define TR_DEAD_ZONE "Мертва зона"
#define TR_RTC_CHECK TR("Перевір RTC", "Перевір напругу RTC")
+1
View File
@@ -812,6 +812,7 @@
#define STR_PROTOCOL currentLangStrings->STR_PROTOCOL
#define STR_PT currentLangStrings->STR_PT
#define STR_PTS currentLangStrings->STR_PTS
#define STR_PWM_OUTPUT currentLangStrings->STR_PWM_OUTPUT
#define STR_PWR_AUTO_OFF currentLangStrings->STR_PWR_AUTO_OFF
#define STR_PWR_OFF_DELAY currentLangStrings->STR_PWR_OFF_DELAY
#define STR_PWR_ON_DELAY currentLangStrings->STR_PWR_ON_DELAY
+1
View File
@@ -808,6 +808,7 @@ STR(PROTOCOL_INVALID)
STR(PROTOCOL)
STR(PT)
STR(PTS)
STR(PWM_OUTPUT)
STR(PWR_AUTO_OFF)
STR(PWR_OFF_DELAY)
STR(PWR_ON_DELAY)