diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index d94bf3ac423..8d1e40572da 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -95,6 +95,7 @@ body:
- FrSky X10 Express / X10S Express (ACCESS)
- FrSky X12
- FrSky X-Lite / S / Pro
+ - HelloRadioSky V16
- Jumper T12
- Jumper T14
- Jumper T16
diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml
index f642bf742dd..18a969f2412 100644
--- a/.github/workflows/actions.yml
+++ b/.github/workflows/actions.yml
@@ -106,6 +106,7 @@ jobs:
- tx12;tx12mk2;boxer
- tx16s
- f16
+ - v16
- x10;x10express
- x12s
- x7;x7access
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 3b3a96bb031..b834d90e325 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -26,6 +26,7 @@ jobs:
- tx12;tx12mk2;boxer
- tx16s
- f16
+ - v16
- x10;x10express
- x12s
- x7;x7access
diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt
index 8a8eef54f5c..6fd2f8d115f 100644
--- a/companion/src/CMakeLists.txt
+++ b/companion/src/CMakeLists.txt
@@ -338,6 +338,8 @@ elseif(PCB STREQUAL X10 AND PCBREV STREQUAL TX16S)
set(FLAVOUR tx16s)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL F16)
set(FLAVOUR f16)
+elseif(PCB STREQUAL X10 AND PCBREV STREQUAL V16)
+ set(FLAVOUR v16)
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T14)
set(FLAVOUR t14)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T15)
diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc
index 285775e7166..aa873dd5359 100644
--- a/companion/src/companion.qrc
+++ b/companion/src/companion.qrc
@@ -336,6 +336,15 @@
images/simulator/Pocket/right.png
images/simulator/Pocket/top.png
images/simulator/Pocket/bottom.png
+ images/simulator/V16/left.png
+ images/simulator/V16/left_pagedn.png
+ images/simulator/V16/left_pageup.png
+ images/simulator/V16/left_rtn.png
+ images/simulator/V16/left_sys.png
+ images/simulator/V16/left_tele.png
+ images/simulator/V16/right.png
+ images/simulator/V16/right_ent.png
+ images/simulator/V16/right_mdl.png
images/wizard/ailerons.png
images/wizard/airbrakes.png
images/wizard/elevons.png
diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp
index 170f7e8f4a2..6acb5e83b0e 100644
--- a/companion/src/firmwares/boards.cpp
+++ b/companion/src/firmwares/boards.cpp
@@ -213,6 +213,7 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_FLYSKY_EL18:
case BOARD_FLYSKY_PL18:
case BOARD_FATFISH_F16:
+ case BOARD_HELLORADIOSKY_V16:
return 0;
default:
return 0;
@@ -267,6 +268,7 @@ int Boards::getFlashSize(Type board)
case BOARD_FLYSKY_EL18:
case BOARD_FLYSKY_PL18:
case BOARD_FATFISH_F16:
+ case BOARD_HELLORADIOSKY_V16:
return FSIZE_HORUS;
case BOARD_UNKNOWN:
return FSIZE_MAX;
@@ -581,6 +583,8 @@ QString Boards::getBoardName(Board::Type board)
return "iFlight Commando 8";
case BOARD_FATFISH_F16:
return "Fatfish F16";
+ case BOARD_HELLORADIOSKY_V16:
+ return "HelloRadioSky V16";
default:
return CPN_STR_UNKNOWN_ITEM;
}
@@ -694,6 +698,7 @@ int Boards::getDefaultInternalModules(Board::Type board)
case BOARD_JUMPER_T20V2:
case BOARD_JUMPER_TPROS:
case BOARD_FATFISH_F16:
+ case BOARD_HELLORADIOSKY_V16:
return (int)MODULE_TYPE_CROSSFIRE;
case BOARD_FLYSKY_NV14:
diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h
index 5e2f3354567..c67403ec5a7 100644
--- a/companion/src/firmwares/boards.h
+++ b/companion/src/firmwares/boards.h
@@ -87,6 +87,7 @@ namespace Board {
BOARD_RADIOMASTER_POCKET,
BOARD_JUMPER_T20V2,
BOARD_FATFISH_F16,
+ BOARD_HELLORADIOSKY_V16,
BOARD_TYPE_COUNT,
BOARD_TYPE_MAX = BOARD_TYPE_COUNT - 1
};
@@ -514,9 +515,14 @@ inline bool IS_FATFISH_F16(Board::Type board)
return board == Board::BOARD_FATFISH_F16;
}
+inline bool IS_HELLORADIOSKY_V16(Board::Type board)
+{
+ return board == Board::BOARD_HELLORADIOSKY_V16;
+}
+
inline bool IS_FAMILY_T16(Board::Type board)
{
- return board == Board::BOARD_JUMPER_T15 || board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S || board == Board::BOARD_JUMPER_T18 || board == Board::BOARD_FATFISH_F16;
+ return board == Board::BOARD_JUMPER_T15 || board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S || board == Board::BOARD_JUMPER_T18 || board == Board::BOARD_FATFISH_F16 || board == Board::BOARD_HELLORADIOSKY_V16;
}
inline bool IS_FAMILY_T12(Board::Type board)
diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp
index 693a01a4065..1627c24914c 100644
--- a/companion/src/firmwares/opentx/opentxinterface.cpp
+++ b/companion/src/firmwares/opentx/opentxinterface.cpp
@@ -143,6 +143,8 @@ const char * OpenTxEepromInterface::getName()
return "EdgeTX for iFlight Commando 8";
case BOARD_FATFISH_F16:
return "EdgeTX for Fatfish F16";
+ case BOARD_HELLORADIOSKY_V16:
+ return "EdgeTX for HelloRadioSky V16";
default:
return "Board is unknown to EdgeTX";
}
@@ -1390,6 +1392,13 @@ void registerOpenTxFirmwares()
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX);
+ /* HelloRadioSky V16 board */
+ firmware = new OpenTxFirmware(FIRMWAREID("v16"), Firmware::tr("HelloRadioSky V16"), BOARD_HELLORADIOSKY_V16);
+ addOpenTxFrskyOptions(firmware);
+ addOpenTxRfOptions(firmware, FLEX);
+ firmware->addOptionsGroup({opt_bt, opt_internal_gps});
+ registerOpenTxFirmware(firmware);
+
/* iFlight Commando8 board */
firmware = new OpenTxFirmware(FIRMWAREID("commando8"), QCoreApplication::translate("Firmware", "iFlight Commando8"), BOARD_IFLIGHT_COMMANDO8);
addOpenTxCommonOptions(firmware);
diff --git a/companion/src/images/simulator/V16/left.png b/companion/src/images/simulator/V16/left.png
new file mode 100644
index 00000000000..5e0e80427ae
Binary files /dev/null and b/companion/src/images/simulator/V16/left.png differ
diff --git a/companion/src/images/simulator/V16/left_pagedn.png b/companion/src/images/simulator/V16/left_pagedn.png
new file mode 100644
index 00000000000..e4fb28d6113
Binary files /dev/null and b/companion/src/images/simulator/V16/left_pagedn.png differ
diff --git a/companion/src/images/simulator/V16/left_pageup.png b/companion/src/images/simulator/V16/left_pageup.png
new file mode 100644
index 00000000000..016af4aac08
Binary files /dev/null and b/companion/src/images/simulator/V16/left_pageup.png differ
diff --git a/companion/src/images/simulator/V16/left_rtn.png b/companion/src/images/simulator/V16/left_rtn.png
new file mode 100644
index 00000000000..0862203d8e7
Binary files /dev/null and b/companion/src/images/simulator/V16/left_rtn.png differ
diff --git a/companion/src/images/simulator/V16/left_sys.png b/companion/src/images/simulator/V16/left_sys.png
new file mode 100644
index 00000000000..e4118ef130d
Binary files /dev/null and b/companion/src/images/simulator/V16/left_sys.png differ
diff --git a/companion/src/images/simulator/V16/left_tele.png b/companion/src/images/simulator/V16/left_tele.png
new file mode 100644
index 00000000000..84a8451754d
Binary files /dev/null and b/companion/src/images/simulator/V16/left_tele.png differ
diff --git a/companion/src/images/simulator/V16/right.png b/companion/src/images/simulator/V16/right.png
new file mode 100644
index 00000000000..3679aa45248
Binary files /dev/null and b/companion/src/images/simulator/V16/right.png differ
diff --git a/companion/src/images/simulator/V16/right_ent.png b/companion/src/images/simulator/V16/right_ent.png
new file mode 100644
index 00000000000..a2d8e4f3c1a
Binary files /dev/null and b/companion/src/images/simulator/V16/right_ent.png differ
diff --git a/companion/src/images/simulator/V16/right_mdl.png b/companion/src/images/simulator/V16/right_mdl.png
new file mode 100644
index 00000000000..7fbccb49d36
Binary files /dev/null and b/companion/src/images/simulator/V16/right_mdl.png differ
diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt
index 6816540c969..a05e28668e4 100644
--- a/companion/src/simulation/CMakeLists.txt
+++ b/companion/src/simulation/CMakeLists.txt
@@ -55,6 +55,7 @@ set(${PROJECT_NAME}_SRCS
simulateduiwidgetT8.cpp
simulateduiwidgetTX12.cpp
simulateduiwidgetTX16S.cpp
+ simulateduiwidgetV16.cpp
simulateduiwidgetX10.cpp
simulateduiwidgetX12.cpp
simulateduiwidgetX7.cpp
diff --git a/companion/src/simulation/simulateduiwidget.h b/companion/src/simulation/simulateduiwidget.h
index a420b626ae9..39f96f4f530 100644
--- a/companion/src/simulation/simulateduiwidget.h
+++ b/companion/src/simulation/simulateduiwidget.h
@@ -162,6 +162,7 @@ namespace Ui {
class SimulatedUIWidgetNV14;
class SimulatedUIWidgetEL18;
class SimulatedUIWidgetPL18;
+ class SimulatedUIWidgetV16;
}
class SimulatedUIWidget9X: public SimulatedUIWidget
@@ -540,4 +541,16 @@ class SimulatedUIWidgetPL18: public SimulatedUIWidget
Ui::SimulatedUIWidgetPL18 * ui;
};
+class SimulatedUIWidgetV16: public SimulatedUIWidget
+{
+ Q_OBJECT
+
+ public:
+ explicit SimulatedUIWidgetV16(SimulatorInterface * simulator, QWidget * parent = nullptr);
+ virtual ~SimulatedUIWidgetV16();
+
+ private:
+ Ui::SimulatedUIWidgetV16 * ui;
+};
+
#endif // SIMULATEDUIWIDGET_H
diff --git a/companion/src/simulation/simulateduiwidgetV16.cpp b/companion/src/simulation/simulateduiwidgetV16.cpp
new file mode 100644
index 00000000000..04222797483
--- /dev/null
+++ b/companion/src/simulation/simulateduiwidgetV16.cpp
@@ -0,0 +1,69 @@
+/*
+ * 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 "simulateduiwidget.h"
+#include "ui_simulateduiwidgetV16.h"
+
+SimulatedUIWidgetV16::SimulatedUIWidgetV16(SimulatorInterface *simulator, QWidget * parent):
+ SimulatedUIWidget(simulator, parent),
+ ui(new Ui::SimulatedUIWidgetV16)
+{
+ RadioUiAction * act;
+
+ ui->setupUi(this);
+
+ // add actions in order of appearance on the help menu
+
+ act = new RadioUiAction(KEY_SYS, QList() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS);
+ addRadioWidget(ui->left->addArea(QRect(60, 10, 81, 51), "V16/left_sys.png", act));
+
+ act = new RadioUiAction(KEY_EXIT, QList() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace,
+ SIMU_STR_HLP_KEY_DN % "
" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN);
+ addRadioWidget(ui->left->addArea(QRect(75, 105, 60, 30), "V16/left_rtn.png", act));
+
+ act = new RadioUiAction(KEY_PAGEDN, QList() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN);
+ addRadioWidget(ui->left->addArea(QRect(75, 160, 60, 30), "V16/left_pagedn.png", act));
+
+ act = new RadioUiAction(KEY_PAGEUP, QList() << Qt::Key_PageUp, SIMU_STR_HLP_KEY_PGUP, SIMU_STR_HLP_ACT_PGUP);
+ addRadioWidget(ui->left->addArea(QRect(75, 220, 60, 30), "V16/left_pageup.png", act));
+
+ act = new RadioUiAction(KEY_TELE, QList() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE);
+ addRadioWidget(ui->left->addArea(QRect(75, 280, 80, 35), "V16/left_tele.png", act));
+
+ m_mouseMidClickAction = new RadioUiAction(KEY_ENTER, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN);
+ addRadioWidget(ui->right->addArea(QRect(40, 130, 51, 131), "V16/right_ent.png", m_mouseMidClickAction));
+
+ act = new RadioUiAction(KEY_MODEL, QList() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL);
+ addRadioWidget(ui->right->addArea(QRect(30, 10, 81, 51), "V16/right_mdl.png", act));
+
+ m_scrollUpAction = new RadioUiAction(-1, QList() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT);
+ m_scrollDnAction = new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT);
+ connectScrollActions();
+
+ m_backlightColors << QColor(47, 123, 227);
+
+ setLcd(ui->lcd);
+}
+
+SimulatedUIWidgetV16::~SimulatedUIWidgetV16()
+{
+ delete ui;
+}
diff --git a/companion/src/simulation/simulateduiwidgetV16.ui b/companion/src/simulation/simulateduiwidgetV16.ui
new file mode 100644
index 00000000000..8d276cf97f7
--- /dev/null
+++ b/companion/src/simulation/simulateduiwidgetV16.ui
@@ -0,0 +1,151 @@
+
+
+ SimulatedUIWidgetV16
+
+
+ true
+
+
+
+ 0
+ 0
+ 829
+ 320
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 829
+ 320
+
+
+
+
+ 829
+ 355
+
+
+
+
+
+ 658
+ 0
+ 167
+ 320
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 167
+ 320
+
+
+
+
+ 167
+ 320
+
+
+
+ background:url(:/images/simulator/V16/right.png)
+
+
+
+
+
+ 1
+ 0
+ 175
+ 320
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 175
+ 320
+
+
+
+
+ 175
+ 320
+
+
+
+ true
+
+
+ background:url(:/images/simulator/V16/left.png);
+
+
+
+
+
+ 177
+ 24
+ 480
+ 272
+
+
+
+
+ 0
+ 0
+
+
+
+
+ 480
+ 272
+
+
+
+
+ 480
+ 272
+
+
+
+
+ 5
+
+
+
+
+
+
+ LcdWidget
+ QWidget
+
+ 1
+
+
+ ButtonsWidget
+ QWidget
+
+ 1
+
+
+
+
+
+
+
diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp
index 2d115a3ec7e..b6293ebcc0d 100644
--- a/companion/src/simulation/simulatorwidget.cpp
+++ b/companion/src/simulation/simulatorwidget.cpp
@@ -159,6 +159,9 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato
case Board::BOARD_FLYSKY_PL18:
radioUiWidget = new SimulatedUIWidgetPL18(simulator, this);
break;
+ case Board::BOARD_HELLORADIOSKY_V16:
+ radioUiWidget = new SimulatedUIWidgetV16(simulator, this);
+ break;
default:
radioUiWidget = new SimulatedUIWidget9X(simulator, this);
break;
diff --git a/fw.json b/fw.json
index f09b1795c99..bd292a8f5b7 100644
--- a/fw.json
+++ b/fw.json
@@ -20,6 +20,7 @@
["FrSky X9 Lite S", "x9lites-"],
["FrSky X-Lite", "xlite-"],
["FrSky X-Lite S", "xlites-"],
+ ["HelloRadioSky V16", "v16-"],
["iFlight Commando 8", "commando8-"],
["Jumper T12", "t12-"],
["Jumper T12 MAX", "t12max-"],
diff --git a/radio/src/audio.cpp b/radio/src/audio.cpp
index fb8c98bb1eb..d62e347679d 100644
--- a/radio/src/audio.cpp
+++ b/radio/src/audio.cpp
@@ -368,7 +368,7 @@ void audioTask(void * pdata)
setSampleRate(AUDIO_SAMPLE_RATE);
-#if defined(PCBX12S) || defined(RADIO_TX16S) || defined(RADIO_F16)
+#if defined(PCBX12S) || defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
// The audio amp needs ~2s to start
RTOS_WAIT_MS(1000); // 1s
#endif
diff --git a/radio/src/boards/generic_stm32/rgb_leds.cpp b/radio/src/boards/generic_stm32/rgb_leds.cpp
index 47996ffe215..cd060b192c8 100644
--- a/radio/src/boards/generic_stm32/rgb_leds.cpp
+++ b/radio/src/boards/generic_stm32/rgb_leds.cpp
@@ -43,7 +43,11 @@ static StaticTimer_t rgbLedTimerBuffer;
void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
+#if defined(SIXPOS_SWITCH_INDEX)
+ ws2812_set_color(led + 6, r, g, b);
+#else
ws2812_set_color(led, r, g, b);
+#endif
}
void rgbLedColorApply()
diff --git a/radio/src/edgetx.cpp b/radio/src/edgetx.cpp
index ebd6d4cbdfd..54979bfdcbc 100644
--- a/radio/src/edgetx.cpp
+++ b/radio/src/edgetx.cpp
@@ -65,6 +65,10 @@
#include "telemetry/crossfire.h"
#endif
+#if defined(CSD203_SENSOR)
+ #include "csd203_sensor.h"
+#endif
+
#if !defined(SIMU)
#include
#endif
@@ -209,6 +213,10 @@ void timer_10ms()
}
#endif
+#if defined(CSD203_SENSOR) && !defined(SIMU)
+ readCSD203();
+#endif
+
telemetryInterrupt10ms();
// These moved here from evalFlightModeMixes() to improve beep trigger reliability.
diff --git a/radio/src/hal/adc_driver.cpp b/radio/src/hal/adc_driver.cpp
index 46b7c5263bd..41688e8e12d 100644
--- a/radio/src/hal/adc_driver.cpp
+++ b/radio/src/hal/adc_driver.cpp
@@ -29,6 +29,10 @@ const etx_hal_adc_inputs_t* _hal_adc_inputs = nullptr;
static uint16_t adcValues[MAX_ANALOG_INPUTS] __DMA;
+#if defined(CSD203_SENSOR)
+ extern uint16_t getCSD203BatteryVoltage(void);
+#endif
+
bool adcInit(const etx_hal_adc_driver_t* driver)
{
// If there is an init function, it MUST succeed
@@ -243,6 +247,11 @@ uint16_t getRTCBatteryVoltage()
uint16_t getAnalogValue(uint8_t index)
{
if (index >= MAX_ANALOG_INPUTS) return 0;
+#if defined(SIXPOS_SWITCH_INDEX) && !defined(SIMU)
+ if (index == SIXPOS_SWITCH_INDEX)
+ return getSixPosAnalogValue(adcValues[index]);
+ else
+#endif
return adcValues[index];
}
@@ -297,6 +306,9 @@ tmr10ms_t jitterResetTime = 0;
uint16_t getBatteryVoltage()
{
+#if defined(CSD203_SENSOR) && !defined(SIMU)
+ return getCSD203BatteryVoltage() / 10;
+#else
// using filtered ADC value on purpose
if (adcGetMaxInputs(ADC_INPUT_VBAT) < 1) return 0;
int32_t instant_vbat = anaIn(adcGetInputOffset(ADC_INPUT_VBAT));
@@ -321,6 +333,7 @@ uint16_t getBatteryVoltage()
return (uint16_t)((instant_vbat * (1000 + g_eeGeneral.txVoltageCalibration)) /
BATTERY_DIVIDER);
#endif
+#endif
}
static uint32_t apply_low_pass_filter(uint32_t v, uint32_t v_prev,
diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp
index 7cc1f962b21..05d00f94768 100644
--- a/radio/src/lua/api_general.cpp
+++ b/radio/src/lua/api_general.cpp
@@ -3213,7 +3213,11 @@ LROT_BEGIN(etxcst, NULL, 0)
LROT_NUMENTRY( PLAY_BACKGROUND, PLAY_BACKGROUND )
LROT_NUMENTRY( TIMEHOUR, TIMEHOUR )
#if defined(LED_STRIP_GPIO)
- LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH )
+ #if defined(RADIO_V16)
+ LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH - 6)
+ #else
+ LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH )
+ #endif
#endif
LROT_NUMENTRY( UNIT_RAW, UNIT_RAW )
LROT_NUMENTRY( UNIT_VOLTS, UNIT_VOLTS )
diff --git a/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp b/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp
index 51c8212b573..e9ac462cd83 100644
--- a/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp
+++ b/radio/src/targets/common/arm/stm32/stm32_ws2812.cpp
@@ -82,22 +82,23 @@ static void _led_dbg_init() {
#endif
-#if defined(STM32_SUPPORT_32BIT_TIMERS)
-typedef uint32_t led_timer_value_t;
-#else
typedef uint16_t led_timer_value_t;
-#endif
+uint8_t pulse_inc = 1;
// DMA buffer contains pulses for 2 LED at a time
// (allows for refill at HT and TC)
+#if defined(STM32_SUPPORT_32BIT_TIMERS)
+static led_timer_value_t _led_dma_buffer[WS2821_DMA_BUFFER_LEN * 2] __DMA;
+#else
static led_timer_value_t _led_dma_buffer[WS2821_DMA_BUFFER_LEN] __DMA;
+#endif
static uint8_t _led_seq_cnt;
static void _fill_byte(uint8_t c, led_timer_value_t* dma_buffer)
{
for (int i = 0; i < 8; i++) {
- dma_buffer[i] = c & 0x80 ? WS2812_ONE : WS2812_ZERO;
+ dma_buffer[i*pulse_inc] = c & 0x80 ? WS2812_ONE : WS2812_ZERO;
c <<= 1;
}
}
@@ -106,14 +107,14 @@ static void _fill_pulses(const uint8_t* colors, led_timer_value_t* dma_buffer, u
{
for (uint32_t i = 0; i < len; i++) {
_fill_byte(*colors, dma_buffer);
- dma_buffer += 8;
+ dma_buffer += 8 * pulse_inc;
colors++;
}
}
static inline uint32_t _calc_offset(uint8_t tc)
{
- return tc * WS2821_DMA_BUFFER_HALF_LEN;
+ return tc * WS2821_DMA_BUFFER_HALF_LEN * pulse_inc;
}
static void _update_dma_buffer(const stm32_pulse_timer_t* tim, uint8_t tc)
@@ -131,7 +132,7 @@ static void _update_dma_buffer(const stm32_pulse_timer_t* tim, uint8_t tc)
// no need to reset the buffer after 2 cycles
if (_led_seq_cnt < _led_strip_len + 2) {
auto offset = _calc_offset(tc);
- auto size = WS2821_DMA_BUFFER_HALF_LEN * sizeof(led_timer_value_t);
+ auto size = WS2821_DMA_BUFFER_HALF_LEN * sizeof(led_timer_value_t) * pulse_inc;
memset(&_led_dma_buffer[offset], 0, size);
}
_led_seq_cnt++;
@@ -191,7 +192,7 @@ static void _init_timer(const stm32_pulse_timer_t* tim)
_led_set_dma_periph_addr(tim);
LL_DMA_SetMode(tim->DMAx, tim->DMA_Stream, LL_DMA_MODE_CIRCULAR);
- LL_DMA_SetDataLength(tim->DMAx, tim->DMA_Stream, WS2821_DMA_BUFFER_LEN);
+ LL_DMA_SetDataLength(tim->DMAx, tim->DMA_Stream, WS2821_DMA_BUFFER_LEN * pulse_inc);
LL_DMA_SetMemoryAddress(tim->DMAx, tim->DMA_Stream, (uint32_t)_led_dma_buffer);
// we need to use a higher prio to avoid having
@@ -202,6 +203,7 @@ static void _init_timer(const stm32_pulse_timer_t* tim)
void ws2812_init(const stm32_pulse_timer_t* timer, uint8_t strip_len, uint8_t type)
{
WS2812_DBG_INIT;
+ pulse_inc = IS_TIM_32B_COUNTER_INSTANCE(timer->TIMx) ? 2 : 1;
memset(_led_colors, 0, sizeof(_led_colors));
memset(_led_dma_buffer, 0, sizeof(_led_dma_buffer));
diff --git a/radio/src/targets/common/arm/stm32/stm32_ws2812.h b/radio/src/targets/common/arm/stm32/stm32_ws2812.h
index c2dd69d48bb..d993ea5856f 100644
--- a/radio/src/targets/common/arm/stm32/stm32_ws2812.h
+++ b/radio/src/targets/common/arm/stm32/stm32_ws2812.h
@@ -32,7 +32,7 @@
// Maximum number of supported LEDs
#if !defined(WS2812_MAX_LEDS)
-# define WS2812_MAX_LEDS 8
+# define WS2812_MAX_LEDS 48
#endif
// Number of LED periods used for trailing reset
diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt
index f5ee746522d..efe8a84f9ca 100644
--- a/radio/src/targets/horus/CMakeLists.txt
+++ b/radio/src/targets/horus/CMakeLists.txt
@@ -117,11 +117,25 @@ if (PCB STREQUAL X10)
set(DEFAULT_INTERNAL_MODULE MULTIMODULE CACHE STRING "Default internal module")
option(BLUETOOTH "Support for bluetooth module" OFF)
option(INTERNAL_GPS "Support for internal NMEA GPS" OFF)
- set(DEFAULT_THEME "DARKBLUE")
add_definitions(-DMANUFACTURER_FATFISH)
set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
set(FLEXSW "2" CACHE STRING "Max flex inputs usable as switches")
set(VIDEO_SWITCH ON)
+ elseif (PCBREV STREQUAL V16)
+ set(FLAVOUR v16)
+ add_definitions(-DRADIO_V16)
+ add_definitions(-DRADIO_FAMILY_T16)
+ set(DEFAULT_INTERNAL_MODULE CROSSFIRE CACHE STRING "Default internal module")
+ option(BLUETOOTH "Support for bluetooth module" OFF)
+ option(INTERNAL_GPS "Support for internal NMEA GPS" OFF)
+ add_definitions(-DMANUFACTURER_HELLORADIOSKY)
+ set(INTERNAL_GPS_BAUDRATE "9600" CACHE STRING "Baud rate for internal GPS")
+ set(FLEXSW "2" CACHE STRING "Max flex inputs usable as switches")
+ set(AUX2_SERIAL OFF)
+ set(HAS_CSD203_SENSOR ON)
+ if (BLUETOOTH)
+ set(AUX_SERIAL OFF)
+ endif()
elseif (PCBREV STREQUAL T18)
set(FLAVOUR t18)
add_definitions(-DRADIO_T18)
@@ -331,6 +345,10 @@ if(USB_CHARGER)
target_sources(board PRIVATE ${TARGET_SRC_DIR}/usb_charger_driver.cpp)
endif()
+if(HAS_CSD203_SENSOR)
+ set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} csd203_sensor.cpp)
+ add_definitions(-DCSD203_SENSOR)
+endif()
set(FIRMWARE_SRC
${FIRMWARE_SRC}
targets/common/arm/loadboot.cpp
diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp
index 470d5a32f88..0d1506d4ec2 100644
--- a/radio/src/targets/horus/board.cpp
+++ b/radio/src/targets/horus/board.cpp
@@ -22,6 +22,7 @@
#include "stm32_hal.h"
#include "stm32_hal_ll.h"
#include "stm32_gpio.h"
+#include "stm32_ws2812.h"
#include "hal/adc_driver.h"
#include "hal/trainer_driver.h"
@@ -34,6 +35,7 @@
#include "boards/generic_stm32/module_ports.h"
#include "boards/generic_stm32/intmodule_heartbeat.h"
#include "boards/generic_stm32/analog_inputs.h"
+#include "boards/generic_stm32/rgb_leds.h"
#include "timers_driver.h"
#include "dataconstants.h"
@@ -48,6 +50,23 @@
#include "flysky_gimbal_driver.h"
#endif
+#if defined(CSD203_SENSOR)
+ #include "csd203_sensor.h"
+#endif
+
+#if defined(LED_STRIP_GPIO)
+// Common LED driver
+extern const stm32_pulse_timer_t _led_timer;
+
+void ledStripOff()
+{
+ for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
+ ws2812_set_color(i, 0, 0, 0);
+ }
+ ws2812_update(&_led_timer);
+}
+#endif
+
HardwareOptions hardwareOptions;
bool boardBacklightOn = false;
@@ -63,6 +82,44 @@ void boardBLInit()
#if !defined(BOOT)
#include "edgetx.h"
+#if defined(SIXPOS_SWITCH_INDEX)
+uint8_t lastADCState = 0;
+uint8_t sixPosState = 0;
+bool dirty = true;
+uint16_t getSixPosAnalogValue(uint16_t adcValue)
+{
+ uint8_t currentADCState = 0;
+ if (adcValue > 3800)
+ currentADCState = 6;
+ else if (adcValue > 3100)
+ currentADCState = 5;
+ else if (adcValue > 2300)
+ currentADCState = 4;
+ else if (adcValue > 1500)
+ currentADCState = 3;
+ else if (adcValue > 1000)
+ currentADCState = 2;
+ else if (adcValue > 400)
+ currentADCState = 1;
+ if (lastADCState != currentADCState) {
+ lastADCState = currentADCState;
+ } else if (lastADCState != 0 && lastADCState - 1 != sixPosState) {
+ sixPosState = lastADCState - 1;
+ dirty = true;
+ }
+ if (dirty) {
+ for (uint8_t i = 0; i < 6; i++) {
+ if (i == sixPosState)
+ ws2812_set_color(i, SIXPOS_LED_RED, SIXPOS_LED_GREEN, SIXPOS_LED_BLUE);
+ else
+ ws2812_set_color(i, 0, 0, 0);
+ }
+ ws2812_update(&_led_timer);
+ }
+ return (4096/5)*(sixPosState);
+}
+#endif
+
void boardInit()
{
#if defined(RADIO_FAMILY_T16)
@@ -163,9 +220,22 @@ void boardInit()
timersInit();
+#if defined(HARDWARE_TOUCH) && !defined(SIMU)
+ touchPanelInit();
+#endif
+
+#if defined(CSD203_SENSOR)
+ initCSD203();
+#endif
+
usbInit();
hapticInit();
+#if defined(LED_STRIP_GPIO)
+ ws2812_init(&_led_timer, LED_STRIP_LENGTH, WS2812_GRB);
+ ledStripOff();
+#endif
+
#if defined(BLUETOOTH)
bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE, true);
#endif
diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h
index f0319e07647..1fd06d38f5f 100644
--- a/radio/src/targets/horus/board.h
+++ b/radio/src/targets/horus/board.h
@@ -145,7 +145,7 @@ enum {
#endif
// POTS and SLIDERS default configuration
-#if defined(RADIO_TX16S) || defined(RADIO_F16)
+#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define XPOS_CALIB_DEFAULT {0x3, 0xc, 0x15, 0x1e, 0x26}
#endif
@@ -197,6 +197,10 @@ uint32_t pwrPressedDuration();
void usbChargerInit();
bool usbChargerLed();
+#if defined(RADIO_V16)
+ uint16_t getSixPosAnalogValue(uint16_t adcValue);
+#endif
+
// Led driver
void ledInit();
void ledOff();
@@ -288,7 +292,7 @@ void telemetryPortInvertedInit(uint32_t baudrate);
// Aux serial port driver
-#if defined(RADIO_TX16S) || defined(RADIO_F16)
+#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define DEBUG_BAUDRATE 400000
#define LUA_DEFAULT_BAUDRATE 115200
#else
@@ -315,7 +319,7 @@ void bluetoothWriteWakeup();
uint8_t bluetoothIsWriting();
void bluetoothDisable();
-#if defined(RADIO_TX16S) || defined(RADIO_F16)
+#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define BATTERY_DIVIDER 1495
#else
#define BATTERY_DIVIDER 1629
diff --git a/radio/src/targets/horus/csd203_sensor.cpp b/radio/src/targets/horus/csd203_sensor.cpp
new file mode 100644
index 00000000000..575bef2f07e
--- /dev/null
+++ b/radio/src/targets/horus/csd203_sensor.cpp
@@ -0,0 +1,410 @@
+/*
+ * 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 "csd203_sensor.h"
+
+#include
+#include
+
+#include "debug.h"
+#include "delays_driver.h"
+#include "edgetx_types.h"
+#include "hal.h"
+#include "rtos.h"
+#include "stm32_exti_driver.h"
+#include "stm32_gpio_driver.h"
+#include "stm32_hal.h"
+#include "stm32_hal_ll.h"
+#include "stm32_i2c_driver.h"
+
+// clang-format off
+/* CSD203 Regsistor map */
+#define CONFIGURATION 0X00
+/*Read Only*/
+#define SHUNT_VOLTAGE 0X01
+#define BUS_VOLTAGE 0X02
+#define POWER 0X03
+#define CURRENT 0x04
+/*Read Only*/
+#define CALIBRATION 0x05
+#define MASKENABLE 0x06
+#define ALERTLIMIT 0x07
+
+#define ManufacturerID 0xFE //Manufacturer ID Register
+#define DieID 0xFF //Die ID Register
+
+#define ManIDCode 0x4153 //CHIP ID
+
+/*Calibration Calculation parameter*/
+/* This Parameter Gain*10000K*/
+#define CalParam 51200
+/* ↓ add your shunt here ↓ */
+#define CSD_CONFIG_Rs_1mR 1
+#define CSD_CONFIG_Rs_2mR 2
+#define CSD_CONFIG_Rs_5mR 5
+#define CSD_CONFIG_Rs_10mR 10
+#define CSD_CONFIG_Rs_20mR 20
+#define CSD_CONFIG_Rs_50mR 50
+#define CSD_CONFIG_CurrentLsb1mA 10
+#define CSD_CONFIG_CurrentLsb2mA 20
+#define CSD_CONFIG_CurrentLsb5mA 50
+#define CSD_CONFIG_CurrentLsb10mA 100
+#define CSD_CONFIG_CurrentLsb20mA 200
+/*Calibration Calculation parameter*/
+
+/* CSD203 Regsistor Config*/
+#define CSD_CONFIG_RST 1
+#define CSD_CONFIG_UnRST 0
+
+#define CSD_CONFIG_Avg1 0
+#define CSD_CONFIG_Avg4 1
+#define CSD_CONFIG_Avg16 2
+#define CSD_CONFIG_Avg64 3
+#define CSD_CONFIG_Avg128 4
+#define CSD_CONFIG_Avg256 5
+#define CSD_CONFIG_Avg512 6
+#define CSD_CONFIG_Avg1024 7
+
+#define CSD_CONFIG_VBUS_CT1_1mS 4
+#define CSD_CONFIG_VShunt_CT1_1mS 4
+
+#define CSD_CONFIG_ShuntBus_CON 7
+
+#define CSD_CONFIG_ADDR_A1_GND_A0_GND 64
+#define CSD_CONFIG_ADDR_A1_GND_VS_GND 65
+#define CSD_CONFIG_ADDR_A1_GND_SDA_GND 66
+#define CSD_CONFIG_ADDR_A1_GND_SCL_GND 67
+#define CSD_CONFIG_ADDR_A1_VS_A0_GND 68
+#define CSD_CONFIG_ADDR_A1_VS_A0_VS 69
+#define CSD_CONFIG_ADDR_A1_VS_A0_SDA 70
+#define CSD_CONFIG_ADDR_A1_VS_A0_SCL 71
+#define CSD_CONFIG_ADDR_A1_SDA_A0_GND 72
+#define CSD_CONFIG_ADDR_A1_SDA_A0_VS 73
+#define CSD_CONFIG_ADDR_A1_SDA_A0_SDA 74
+#define CSD_CONFIG_ADDR_A1_SDA_A0_SCL 75
+#define CSD_CONFIG_ADDR_A1_SCL_A0_GND 76
+#define CSD_CONFIG_ADDR_A1_SCL_A0_VS 77
+#define CSD_CONFIG_ADDR_A1_SCL_A0_SDA 78
+#define CSD_CONFIG_ADDR_A1_SCL_A0_SCL 79
+
+/******************/
+/*CSD Alert Option*/
+/******************/
+/*Vshunt Voltage Over Voltage*/
+#define CSD_ALERT_VShunt_OVA_ON 1
+#define CSD_ALERT_VShunt_OVA_OFF 0
+/*Vshunt Voltage Under Voltage*/
+#define CSD_ALERT_VShunt_UVA_ON 1
+#define CSD_ALERT_VShunt_UVA_OFF 0
+/*VBus Voltage Over Voltage*/
+#define CSD_ALERT_VBUS_OVA_ON 1
+#define CSD_ALERT_VBUS_OVA_OFF 0
+/*VBus Voltage Under Voltage*/
+#define CSD_ALERT_VBUS_UVA_ON 1
+#define CSD_ALERT_VBUS_UVA_OFF 0
+/* Power Over Limit */
+#define CSD_ALERT_Power_Over_ON 1
+#define CSD_ALERT_Power_Over_OFF 0
+/* ADC Coversion Ready */
+#define CSD_ALERT_CoversionReady_ON 1
+#define CSD_ALERT_CoversionReady_OFF 0
+#define CSD_ALERT_CNVR_FLAG_ON 1
+#define CSD_ALERT_CNVR_FLAG_OFF 0
+/* ALERT Function Flag and Alert latch Work Together */
+#define CSD_ALERT_ALERT_FLAG_ON 1
+#define CSD_ALERT_ALERT_FLAG_OFF 0
+#define CSD_ALERT_ALERT_Latch_ON 1
+#define CSD_ALERT_ALERT_Latch_OFF 0
+/*Power over flow */
+#define CSD_ALERT_OVF_ON 1
+#define CSD_ALERT_OVF_OFF 0
+/*Alert Pin */
+#define CSD_ALERT_APOL_ActiveLow 1
+#define CSD_ALERT_APOL_ActiveHigh 0
+// clang-format on
+
+/*CSD Basic Configuration struct*/
+typedef struct {
+ uint8_t DeviceADDR;
+ uint8_t RST;
+ uint8_t Average;
+ uint8_t VBUS_Conv_Time;
+ uint8_t VShunt_Conv_Time;
+ uint8_t Mode;
+ uint16_t CurrentLSB;
+ uint16_t Rshunt;
+} CSD_CONFIG;
+/*CSD Basic Configuration struct*/
+
+/*CSD ALERT Configuration struct*/
+typedef struct {
+ uint8_t VShunt_OVA;
+ uint8_t VShuntUVA;
+ uint8_t VBUS_OVA;
+ uint8_t VBUS_UVA;
+ uint8_t Power_OVER_Limit;
+ uint8_t CNVR;
+ uint8_t ALERT_FLAG;
+ uint8_t CNVR_FLAG;
+ uint8_t OVF;
+ uint8_t APOL;
+ uint8_t ALERT_Latch;
+} CSD_ALERT;
+/*CSD ALERT Configuration struct*/
+
+void CSD203_Init(CSD_CONFIG *CSD203_CFG); // Initialise CSD203 config
+uint16_t CSD203_ReadVbus(CSD_CONFIG *CSD203_CFG); // Read Vbus Voltage
+uint16_t CSD203_ReadRshunt(CSD_CONFIG *CSD203_CFG); // Read Rshunt
+uint16_t CSD203_ReadPower(CSD_CONFIG *CSD203_CFG); // Read Power
+uint16_t CSD203_ReadCurrent(CSD_CONFIG *CSD203_CFG); // Read Current
+
+void IIC_DUT_W(uint8_t addr, uint8_t reg, uint16_t data);
+uint16_t IIC_DUT_R(uint8_t addr, uint8_t reg);
+
+bool CSD203MainInitFlag = false;
+bool CSD203InInitFlag = false;
+bool CSD203ExtInitFlag = false;
+
+bool IICReadStatusFlag = false;
+
+static uint16_t csd203extvbus = 0;
+
+static CSD_CONFIG CSD203_MainSensorCFG;
+static CSD_CONFIG CSD203_InSensorCFG;
+static CSD_CONFIG CSD203_ExtSensorCFG;
+
+bool I2C_CSD203_WriteRegister(uint8_t I2C_ADDR, uint8_t reg, uint8_t *buf,
+ uint8_t len)
+{
+ uint8_t uAddrAndBuf[6];
+ uAddrAndBuf[0] = (uint8_t)(reg & 0x00FF);
+
+ if (len > 0) {
+ for (int i = 0; i < len; i++) {
+ uAddrAndBuf[i + 1] = buf[i];
+ }
+ }
+
+ if (stm32_i2c_master_tx(TOUCH_I2C_BUS, I2C_ADDR, uAddrAndBuf, len + 1, 100) <
+ 0) {
+ TRACE("I2C B1 ERROR: WriteRegister failed");
+ return false;
+ }
+ return true;
+}
+
+bool I2C_CSD203_ReadRegister(uint8_t I2C_ADDR, uint8_t reg, uint8_t *buf,
+ uint8_t len)
+{
+ uint8_t uRegAddr[2];
+ // uRegAddr[0] = (uint8_t)((reg & 0xFF00) >> 8);
+ uRegAddr[0] = (uint8_t)(reg & 0x00FF);
+
+ if (stm32_i2c_master_tx(TOUCH_I2C_BUS, I2C_ADDR, uRegAddr, 1, 100) < 0) {
+ TRACE("I2C B1 ERROR: ReadRegister write reg address failed");
+ return false;
+ }
+
+ if (stm32_i2c_master_rx(TOUCH_I2C_BUS, I2C_ADDR, buf, len, 100) < 0) {
+ TRACE("I2C B1 ERROR: ReadRegister read reg address failed");
+ return false;
+ }
+ return true;
+}
+
+void IIC_DUT_W(uint8_t addr, uint8_t reg, uint16_t data)
+{
+ uint8_t buf[2];
+
+ buf[0] = data >> 8;
+ buf[1] = data & 0xff;
+
+ I2C_CSD203_WriteRegister(addr, reg, buf, 2);
+}
+
+uint16_t IIC_DUT_R(uint8_t addr, uint8_t reg)
+{
+ uint8_t buf[2];
+
+ I2C_CSD203_ReadRegister(addr, reg, buf, 2);
+
+ return buf[0] << 8 | buf[1];
+}
+
+void CSD203_Init(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ Data |= (CSD203_CFG->RST) << 15;
+ Data |= (CSD203_CFG->Average) << 9;
+ Data |= (CSD203_CFG->VBUS_Conv_Time) << 5;
+ Data |= (CSD203_CFG->VShunt_Conv_Time) << 2;
+ Data |= CSD203_CFG->Mode;
+
+ ADDR = (CSD203_CFG->DeviceADDR);
+
+ IIC_DUT_W(ADDR, CONFIGURATION, Data);
+
+ Data = CalParam / ((CSD203_CFG->CurrentLSB) * (CSD203_CFG->Rshunt));
+ IIC_DUT_W(ADDR, CALIBRATION, Data);
+}
+
+/*Read Vbus*/
+uint16_t CSD203_ReadVbus(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, BUS_VOLTAGE);
+ return Data;
+}
+
+/*Read Rshunt*/
+uint16_t CSD203_ReadRshunt(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, SHUNT_VOLTAGE);
+ return Data;
+}
+
+/*Read Power*/
+uint16_t CSD203_ReadPower(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, POWER);
+ return Data;
+}
+
+uint16_t CSD203_ReadCurrent(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, CURRENT);
+ return Data;
+}
+
+uint16_t CSD203_ReadCONFIGURATION(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, CONFIGURATION);
+ return Data;
+}
+
+uint16_t CSD203_ReadManufacturerID(CSD_CONFIG *CSD203_CFG)
+{
+ uint16_t Data = 0, ADDR = 0;
+ ADDR = (CSD203_CFG->DeviceADDR);
+ Data = IIC_DUT_R(ADDR, ManufacturerID);
+ return Data;
+}
+
+void initCSD203(void)
+{
+ CSD203MainInitFlag = false;
+ CSD203InInitFlag = false;
+ CSD203ExtInitFlag = false;
+
+ // TRACE("202 test ..."); //A0=CLK A1=SDA RadioSky
+
+ CSD203_MainSensorCFG.RST = CSD_CONFIG_RST;
+ CSD203_MainSensorCFG.Average = CSD_CONFIG_Avg16;
+ CSD203_MainSensorCFG.VBUS_Conv_Time = CSD_CONFIG_VBUS_CT1_1mS;
+ CSD203_MainSensorCFG.VShunt_Conv_Time = CSD_CONFIG_VShunt_CT1_1mS;
+ CSD203_MainSensorCFG.Rshunt = CSD_CONFIG_Rs_10mR;
+ CSD203_MainSensorCFG.CurrentLSB = CSD_CONFIG_CurrentLsb1mA;
+ CSD203_MainSensorCFG.Mode = 7;
+ CSD203_MainSensorCFG.DeviceADDR = CSD_CONFIG_ADDR_A1_VS_A0_GND; // 100 0100
+ // CSD203_MainSensorCFG.DeviceADDR=CSD_CONFIG_ADDR_A1_GND_A0_GND;
+
+ CSD203_InSensorCFG.RST = CSD_CONFIG_RST;
+ CSD203_InSensorCFG.Average = CSD_CONFIG_Avg16;
+ CSD203_InSensorCFG.VBUS_Conv_Time = CSD_CONFIG_VBUS_CT1_1mS;
+ CSD203_InSensorCFG.VShunt_Conv_Time = CSD_CONFIG_VShunt_CT1_1mS;
+ CSD203_InSensorCFG.Rshunt = CSD_CONFIG_Rs_10mR;
+ CSD203_InSensorCFG.CurrentLSB = CSD_CONFIG_CurrentLsb1mA;
+ CSD203_InSensorCFG.Mode = 7;
+ CSD203_InSensorCFG.DeviceADDR = CSD_CONFIG_ADDR_A1_VS_A0_VS; // 100 0101
+ // CSD203_InSensorCFG.DeviceADDR=CSD_CONFIG_ADDR_A1_GND_A0_GND;
+
+ CSD203_ExtSensorCFG.RST = CSD_CONFIG_RST;
+ CSD203_ExtSensorCFG.Average = CSD_CONFIG_Avg16;
+ CSD203_ExtSensorCFG.VBUS_Conv_Time = CSD_CONFIG_VBUS_CT1_1mS;
+ CSD203_ExtSensorCFG.VShunt_Conv_Time = CSD_CONFIG_VShunt_CT1_1mS;
+ CSD203_ExtSensorCFG.Rshunt = CSD_CONFIG_Rs_10mR;
+ CSD203_ExtSensorCFG.CurrentLSB = CSD_CONFIG_CurrentLsb1mA;
+ CSD203_ExtSensorCFG.Mode = 7;
+ CSD203_ExtSensorCFG.DeviceADDR = CSD_CONFIG_ADDR_A1_GND_VS_GND; // 100 0001
+ // CSD203_ExtSensorCFG.DeviceADDR=CSD_CONFIG_ADDR_A1_GND_A0_GND;
+
+ CSD203_Init(&CSD203_MainSensorCFG);
+ delay_ms(1);
+ uint16_t cfg = CSD203_ReadManufacturerID(&CSD203_MainSensorCFG);
+ if (cfg == ManIDCode) {
+ CSD203_ReadCurrent(&CSD203_MainSensorCFG);
+ CSD203MainInitFlag = true;
+ }
+
+ delay_ms(5);
+ CSD203_Init(&CSD203_InSensorCFG);
+ delay_ms(1);
+ cfg = CSD203_ReadManufacturerID(&CSD203_InSensorCFG);
+ if (cfg == ManIDCode) {
+ CSD203_ReadCurrent(&CSD203_InSensorCFG);
+ CSD203InInitFlag = true;
+ }
+
+ delay_ms(5);
+ CSD203_Init(&CSD203_ExtSensorCFG);
+ delay_ms(1);
+ cfg = CSD203_ReadManufacturerID(&CSD203_ExtSensorCFG);
+ if (cfg == ManIDCode) {
+ CSD203_ReadCurrent(&CSD203_ExtSensorCFG);
+ CSD203ExtInitFlag = true;
+ }
+}
+
+uint16_t getCSD203BatteryVoltage(void)
+{ // 1000=1000mV
+ return csd203extvbus;
+}
+
+void readCSD203(void)
+{ // 5ms
+ static uint16_t GetSenSorStep = 0;
+
+ if (IICReadStatusFlag == true) return;
+
+ IICReadStatusFlag = true;
+ if (GetSenSorStep == 0 && CSD203MainInitFlag == true) {
+ CSD203_ReadCurrent(&CSD203_MainSensorCFG);
+ CSD203_ReadVbus(&CSD203_MainSensorCFG);
+ } else if (GetSenSorStep == 1 && CSD203InInitFlag == true) {
+ CSD203_ReadCurrent(&CSD203_InSensorCFG);
+ CSD203_ReadVbus(&CSD203_InSensorCFG);
+ } else if (GetSenSorStep == 2 && CSD203ExtInitFlag == true) {
+ CSD203_ReadCurrent(&CSD203_ExtSensorCFG);
+ csd203extvbus = (CSD203_ReadVbus(&CSD203_ExtSensorCFG) * 1.25);
+ // TRACE("Vbat=%d\r",csd203extvbus);
+ }
+ IICReadStatusFlag = false;
+ if (++GetSenSorStep >= 3) GetSenSorStep = 0;
+}
diff --git a/radio/src/targets/horus/csd203_sensor.h b/radio/src/targets/horus/csd203_sensor.h
new file mode 100644
index 00000000000..4bbe3a88839
--- /dev/null
+++ b/radio/src/targets/horus/csd203_sensor.h
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+void initCSD203(void);
+void readCSD203(void);
diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h
index b93d70936e4..c6eaa959be8 100644
--- a/radio/src/targets/horus/hal.h
+++ b/radio/src/targets/horus/hal.h
@@ -45,7 +45,7 @@
#define KEYS_GPIO_PIN_EXIT LL_GPIO_PIN_6 // PI.06
#define KEYS_GPIO_REG_TELE GPIOC
#define KEYS_GPIO_PIN_TELE LL_GPIO_PIN_4 // PC.04
-#elif defined(RADIO_TX16S) || defined(RADIO_F16)
+#elif defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define KEYS_GPIO_REG_ENTER GPIOI
#define KEYS_GPIO_PIN_ENTER LL_GPIO_PIN_8 // PI.08
#define KEYS_GPIO_REG_PAGEUP GPIOC
@@ -265,6 +265,14 @@
#endif
#endif
+// 6POS SW
+#if defined(RADIO_V16)
+ #define SIXPOS_SWITCH_INDEX 5
+ #define SIXPOS_LED_RED 255
+ #define SIXPOS_LED_GREEN 255
+ #define SIXPOS_LED_BLUE 255
+#endif
+
// Trims
#if defined(RADIO_T15)
#define TRIMS_GPIO_REG_LHL GPIOD
@@ -309,7 +317,7 @@
#define TRIMS_GPIO_REG_LSU GPIOB
#define TRIMS_GPIO_PIN_LSU LL_GPIO_PIN_13 // PB.13
#elif defined(PCBX10)
- #if defined(RADIO_TX16S) || defined(RADIO_F16)
+ #if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define TRIMS_GPIO_REG_LHL GPIOA
#define TRIMS_GPIO_PIN_LHL LL_GPIO_PIN_6 // PA.06
#define TRIMS_GPIO_REG_LHR GPIOC
@@ -392,6 +400,55 @@
#define ADC_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler
#define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_56CYCLES
#define ADC_VREF_PREC2 600
+#elif defined(RADIO_V16)
+ #define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_0 // PA.00
+ #define ADC_GPIO_PIN_STICK_LV LL_GPIO_PIN_1 // PA.01
+ #define ADC_GPIO_PIN_STICK_RV LL_GPIO_PIN_3 // PA.03
+ #define ADC_GPIO_PIN_STICK_RH LL_GPIO_PIN_2 // PA.02
+ #define ADC_GPIO_PIN_POT1 LL_GPIO_PIN_2 // PC.00 // ADC123_IN10 -> ADC3_IN10
+ #define ADC_GPIO_PIN_POT2 LL_GPIO_PIN_1 // PC.02 // ADC123_IN12 -> ADC3_IN12
+ #define ADC_GPIO_PIN_POT3 LL_GPIO_PIN_0 // PC.01 // ADC123_IN11 -> ADC3_IN11
+ #define ADC_GPIO_PIN_SLIDER1 LL_GPIO_PIN_5 // PA.05
+ #define ADC_GPIO_PIN_SLIDER2 LL_GPIO_PIN_3 // PC.03
+ #define ADC_GPIO_PIN_BATT LL_GPIO_PIN_7 // PF.07
+ #define ADC_GPIO_PIN_EXT1 LL_GPIO_PIN_8 // PF.08
+ #define ADC_GPIO_PIN_EXT2 LL_GPIO_PIN_9 // PF.09
+ #define ADC_GPIO_PIN_EXT3 ADC_GPIO_PIN_STICK_RH
+ #define ADC_GPIO_PIN_EXT4 ADC_GPIO_PIN_STICK_RV
+ #define ADC_GPIOA_PINS_FS (LL_GPIO_PIN_2 | LL_GPIO_PIN_3)
+ #define ADC_GPIOA_PINS (ADC_GPIO_PIN_STICK_LH | ADC_GPIO_PIN_STICK_LV | ADC_GPIO_PIN_STICK_RH | ADC_GPIO_PIN_STICK_RV | ADC_GPIO_PIN_SLIDER1)
+ #define ADC_GPIOC_PINS (ADC_GPIO_PIN_POT1 | ADC_GPIO_PIN_POT2 | ADC_GPIO_PIN_POT3 | ADC_GPIO_PIN_SLIDER2)
+ #define ADC_GPIOF_PINS (ADC_GPIO_PIN_EXT1 | ADC_GPIO_PIN_EXT2)
+ #define ADC_CHANNEL_STICK_LH LL_ADC_CHANNEL_0 // ADC123_IN0 -> ADC3_IN0
+ #define ADC_CHANNEL_STICK_LV LL_ADC_CHANNEL_1 // ADC123_IN1 -> ADC3_IN1
+ #define ADC_CHANNEL_STICK_RH LL_ADC_CHANNEL_2 // ADC123_IN2 -> ADC3_IN2
+ #define ADC_CHANNEL_STICK_RV LL_ADC_CHANNEL_3 // ADC123_IN3 -> ADC3_IN3
+ #define ADC_CHANNEL_POT1 LL_ADC_CHANNEL_12 // ADC123_IN10 -> ADC3_IN10
+ #define ADC_CHANNEL_POT2 LL_ADC_CHANNEL_11 // ADC123_IN12 -> ADC3_IN12
+ #define ADC_CHANNEL_POT3 LL_ADC_CHANNEL_10 // ADC123_IN11 -> ADC3_IN11
+ #define ADC_CHANNEL_SLIDER1 LL_ADC_CHANNEL_5 // ADC12_IN5 -> ADC1_IN5
+ #define ADC_CHANNEL_SLIDER2 LL_ADC_CHANNEL_13 // ADC123_IN13 -> ADC1_IN13
+ #define ADC_CHANNEL_EXT1 LL_ADC_CHANNEL_6 // ADC3_IN6 -> ADC3_IN6
+ #define ADC_CHANNEL_EXT2 LL_ADC_CHANNEL_7 // ADC3_IN7 -> ADC3_IN7
+ #define ADC_CHANNEL_EXT3 LL_ADC_CHANNEL_2 // ADC3_IN2: same as RH
+ #define ADC_CHANNEL_EXT4 LL_ADC_CHANNEL_3 // ADC3_IN3: same as RV
+ #define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC1_IN18
+ #define ADC_MAIN ADC3
+ #define ADC_EXT ADC1
+ #define ADC_EXT_CHANNELS { ADC_CHANNEL_SLIDER1, ADC_CHANNEL_SLIDER2, ADC_CHANNEL_RTC_BAT }
+ #define ADC_EXT_DMA DMA2
+ #define ADC_EXT_DMA_CHANNEL LL_DMA_CHANNEL_0
+ #define ADC_EXT_DMA_STREAM LL_DMA_STREAM_4
+ #define ADC_EXT_DMA_STREAM_IRQ DMA2_Stream4_IRQn
+ #define ADC_EXT_DMA_STREAM_IRQHandler DMA2_Stream4_IRQHandler
+ #define ADC_EXT_SAMPTIME LL_ADC_SAMPLINGTIME_56CYCLES
+ #define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_56CYCLES
+ #define ADC_DMA DMA2
+ #define ADC_DMA_CHANNEL LL_DMA_CHANNEL_2
+ #define ADC_DMA_STREAM LL_DMA_STREAM_0
+ #define ADC_DMA_STREAM_IRQ DMA2_Stream0_IRQn
+ #define ADC_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler
+ #define ADC_VREF_PREC2 660
#elif defined(PCBX10)
#if defined(RADIO_T15)
#define ADC_GPIO_PIN_STICK_LH LL_GPIO_PIN_1 // PA.01
@@ -422,7 +479,7 @@
#define ADC_GPIO_PIN_EXT3 ADC_GPIO_PIN_STICK_RH
#define ADC_GPIO_PIN_EXT4 ADC_GPIO_PIN_STICK_RV
#endif
- #if !(defined(RADIO_TX16S) || defined(RADIO_F16)) && !defined(RADIO_T15)
+ #if !(defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_T15) || defined(RADIO_V16))
#define PWM_STICKS
#define PWM_TIMER TIM5
#define PWM_GPIO GPIOA
@@ -470,7 +527,17 @@
#define ADC_CHANNEL_RTC_BAT LL_ADC_CHANNEL_VBAT // ADC1_IN18
#define ADC_MAIN ADC3
#define ADC_EXT ADC1
- #define ADC_EXT_CHANNELS { ADC_CHANNEL_RTC_BAT }
+ #if defined(RADIO_V16)
+ #define ADC_EXT_CHANNELS { ADC_CHANNEL_SLIDER1, ADC_CHANNEL_SLIDER2, ADC_CHANNEL_RTC_BAT }
+ // Required DMA for more than one channel for EXT_ADC
+ #define ADC_EXT_DMA DMA2
+ #define ADC_EXT_DMA_CHANNEL LL_DMA_CHANNEL_0
+ #define ADC_EXT_DMA_STREAM LL_DMA_STREAM_4
+ #define ADC_EXT_DMA_STREAM_IRQ DMA2_Stream4_IRQn
+ #define ADC_EXT_DMA_STREAM_IRQHandler DMA2_Stream4_IRQHandler
+ #else
+ #define ADC_EXT_CHANNELS { ADC_CHANNEL_RTC_BAT }
+ #endif
#define ADC_EXT_SAMPTIME LL_ADC_SAMPLINGTIME_56CYCLES
#define ADC_SAMPTIME LL_ADC_SAMPLINGTIME_56CYCLES
#define ADC_DMA DMA2
@@ -480,7 +547,7 @@
#define ADC_DMA_STREAM_IRQHandler DMA2_Stream0_IRQHandler
// VBat divider is /4 on F42x and F43x devices
- #if defined(RADIO_TX16S) || defined(RADIO_T15) || defined(RADIO_F16)
+ #if defined(RADIO_TX16S) || defined(RADIO_T15) || defined(RADIO_F16) || defined(RADIO_V16)
#define ADC_VREF_PREC2 660
#elif defined(RADIO_T16) || defined(RADIO_T18)
#define ADC_VREF_PREC2 600
@@ -497,6 +564,8 @@
#define ADC_DIRECTION {1,-1,1,-1, -1,1,-1, -1,1,1,1, -1,1 }
#elif defined(RADIO_TX16S) || defined(RADIO_F16)
#define ADC_DIRECTION {1,-1,1,-1, 1,1,1, -1,1,1,1, -1,1 }
+#elif defined(RADIO_V16)
+ #define ADC_DIRECTION {1,-1,1,-1, 1,1,1, -1,1,1,1, -1,1 }
#elif defined(PCBX10)
#define ADC_DIRECTION {1,-1,1,-1, -1,1,-1, 1,-1,1,1, 1,-1 }
#elif defined(PCBX12S)
@@ -511,6 +580,9 @@
#define PWR_ON_GPIO GPIO_PIN(GPIOJ, 1) // PJ.01
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOJ, 0) // PJ.00
#define PWR_EXTRA_SWITCH_GPIO GPIO_PIN(GPIOB, 0) // PB.00
+#elif defined(RADIO_V16)
+ #define PWR_ON_GPIO GPIO_PIN(GPIOB, 2) // PB.02
+ #define PWR_SWITCH_GPIO GPIO_PIN(GPIOJ, 0) // PJ.00
#else
#define PWR_ON_GPIO GPIO_PIN(GPIOJ, 1) // PJ.01
#define PWR_SWITCH_GPIO GPIO_PIN(GPIOJ, 0) // PJ.00
@@ -574,19 +646,34 @@
// Serial Port (DEBUG)
#if defined(AUX_SERIAL)
- #define AUX_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 10) // PB.10
- #define AUX_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 11) // PB.11
- #define AUX_SERIAL_USART USART3
- #define AUX_SERIAL_USART_IRQHandler USART3_IRQHandler
- #define AUX_SERIAL_USART_IRQn USART3_IRQn
- #define AUX_SERIAL_DMA_TX DMA1
- #define AUX_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_3
- #define AUX_SERIAL_DMA_TX_CHANNEL LL_DMA_CHANNEL_4
- #define AUX_SERIAL_DMA_RX DMA1
- #define AUX_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_1
- #define AUX_SERIAL_DMA_RX_CHANNEL LL_DMA_CHANNEL_4
- #if defined(RADIO_TX16S) || defined(RADIO_F16)
+ #if defined(RADIO_V16)
+ #define AUX_SERIAL_TX_GPIO GPIO_PIN(GPIOG, 14) // PG.14
+ #define AUX_SERIAL_RX_GPIO GPIO_PIN(GPIOG, 9) // PG.09
+ #define AUX_SERIAL_USART USART6
+ #define AUX_SERIAL_USART_IRQHandler USART6_IRQHandler
+ #define AUX_SERIAL_USART_IRQn USART6_IRQn
+ #define AUX_SERIAL_DMA_TX DMA2
+ #define AUX_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_7
+ #define AUX_SERIAL_DMA_TX_CHANNEL LL_DMA_CHANNEL_5
+ #define AUX_SERIAL_DMA_RX DMA2
+ #define AUX_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_2
+ #define AUX_SERIAL_DMA_RX_CHANNEL LL_DMA_CHANNEL_5
#define AUX_SERIAL_PWR_GPIO GPIO_PIN(GPIOA, 15) // PA.15
+ #else
+ #define AUX_SERIAL_TX_GPIO GPIO_PIN(GPIOB, 10) // PB.10
+ #define AUX_SERIAL_RX_GPIO GPIO_PIN(GPIOB, 11) // PB.11
+ #define AUX_SERIAL_USART USART3
+ #define AUX_SERIAL_USART_IRQHandler USART3_IRQHandler
+ #define AUX_SERIAL_USART_IRQn USART3_IRQn
+ #define AUX_SERIAL_DMA_TX DMA1
+ #define AUX_SERIAL_DMA_TX_STREAM LL_DMA_STREAM_3
+ #define AUX_SERIAL_DMA_TX_CHANNEL LL_DMA_CHANNEL_4
+ #define AUX_SERIAL_DMA_RX DMA1
+ #define AUX_SERIAL_DMA_RX_STREAM LL_DMA_STREAM_1
+ #define AUX_SERIAL_DMA_RX_CHANNEL LL_DMA_CHANNEL_4
+ #if defined(RADIO_TX16S) || defined(RADIO_F16)
+ #define AUX_SERIAL_PWR_GPIO GPIO_PIN(GPIOA, 15) // PA.15
+ #endif
#endif
#endif
@@ -615,6 +702,24 @@
#endif
// Telemetry
+#if defined(RADIO_V16)
+#define TELEMETRY_RX_REV_GPIO GPIO_PIN(GPIOH, 7) // PH.07
+#define TELEMETRY_TX_REV_GPIO GPIO_PIN(GPIOH, 7) // PH.07
+#define TELEMETRY_DIR_GPIO GPIO_PIN(GPIOD, 4) // PD.04
+#define TELEMETRY_SET_INPUT 0
+#define TELEMETRY_GPIO GPIOD
+#define TELEMETRY_TX_GPIO GPIO_PIN(GPIOD, 5) // PD.05
+#define TELEMETRY_RX_GPIO GPIO_PIN(GPIOD, 6) // PD.06
+#define TELEMETRY_USART USART2
+#define TELEMETRY_DMA DMA1
+#define TELEMETRY_DMA_Stream_TX LL_DMA_STREAM_6
+#define TELEMETRY_DMA_Channel_TX LL_DMA_CHANNEL_4
+#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn
+#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler
+#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6
+#define TELEMETRY_USART_IRQHandler USART2_IRQHandler
+#define TELEMETRY_USART_IRQn USART2_IRQn
+#else
#define TELEMETRY_DIR_GPIO GPIO_PIN(GPIOD, 4) // PD.04
#define TELEMETRY_SET_INPUT 0
#define TELEMETRY_GPIO GPIOD
@@ -648,6 +753,7 @@
#define TELEMETRY_TIMER TIM11
#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn
#define TELEMETRY_TIMER_IRQHandler TIM1_TRG_COM_TIM11_IRQHandler
+#endif
// Software IRQ (Prio 5 -> FreeRTOS compatible)
#define TELEMETRY_RX_FRAME_EXTI_LINE LL_EXTI_LINE_4
@@ -677,7 +783,7 @@
#elif defined(PCBX10)
#define LCD_GPIO_NRST GPIO_PIN(GPIOI, 10) // PI.10
#endif
-#if defined(PCBX10) && !defined(RADIO_T18)
+#if defined(PCBX10) && !defined(RADIO_T18) && !defined(RADIO_V16)
#define LCD_VERTICAL_INVERT
#endif
#define LTDC_IRQ_PRIO 4
@@ -810,7 +916,7 @@
#endif
#if defined(RADIO_FAMILY_T16)
-#if defined(RADIO_TX16S) || defined(RADIO_F16)
+#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define AUDIO_UNMUTE_DELAY 150 // ms
#else
#define AUDIO_UNMUTE_DELAY 120 // ms
@@ -843,7 +949,7 @@
#endif // HARDWARE_TOUCH
// First I2C Bus
-#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(PCBX12S) || defined(RADIO_T15)
+#if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(PCBX12S) || defined(RADIO_T15) || defined(RADIO_V16)
#define I2C_B1 I2C1
#define I2C_B1_SCL_GPIO GPIO_PIN(GPIOB, 8) // PB.08
#define I2C_B1_SDA_GPIO GPIO_PIN(GPIOB, 9) // PB.09
@@ -864,7 +970,7 @@
#define I2C_B2_SDA_GPIO GPIO_PIN(GPIOB, 11) // PB.11
#define I2C_B2_GPIO_AF LL_GPIO_AF_4 // I2C2
#define I2C_B2_CLK_RATE 400000
- #if defined(RADIO_TX16S) || defined(RADIO_F16)
+ #if defined(RADIO_TX16S) || defined(RADIO_F16) || defined(RADIO_V16)
#define I2C_B2_PWR_GPIO GPIO_PIN(GPIOA, 15) // PA.15
#endif
#endif
@@ -913,6 +1019,22 @@
// #define FLYSKY_HALL_DMA_Stream_TX LL_DMA_STREAM_4
#endif
+#if defined(RADIO_V16)
+ // LED Strip
+ #define LED_STRIP_LENGTH 40
+ #define LED_STRIP_GPIO GPIO_PIN(GPIOA, 10) // PA.10 / TIM1_CH3
+ #define LED_STRIP_GPIO_AF LL_GPIO_AF_1 // TIM1/2
+ #define LED_STRIP_TIMER TIM1
+ #define LED_STRIP_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2)
+ #define LED_STRIP_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
+ #define LED_STRIP_TIMER_DMA DMA2
+ #define LED_STRIP_TIMER_DMA_CHANNEL LL_DMA_CHANNEL_6
+ #define LED_STRIP_TIMER_DMA_STREAM LL_DMA_STREAM_5
+ #define LED_STRIP_TIMER_DMA_IRQn DMA2_Stream5_IRQn
+ #define LED_STRIP_TIMER_DMA_IRQHandler DMA2_Stream5_IRQHandler
+ #define LED_STRIP_REFRESH_PERIOD 50 //ms
+#endif
+
// Internal PXX1 Module:
// -> let's assume all internal XJT modules used are either X10 or X12S type
#define EXTERNAL_ANTENNA
@@ -932,15 +1054,21 @@
#define INTMODULE_RX_DMA_CHANNEL LL_DMA_CHANNEL_4
#if defined(PCBX12S)
#define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOC, 2) // PC.02
+#elif defined(RADIO_V16)
+ #define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOB, 0) // PB.00
#elif defined(PCBX10)
#define INTMODULE_BOOTCMD_GPIO GPIO_PIN(GPIOI, 9) // PI.09
#endif
-#define INTMODULE_BOOTCMD_DEFAULT 0 // RESET
+#if defined(RADIO_V16)
+ #define INTMODULE_BOOTCMD_DEFAULT 1 // RESET
+#else
+ #define INTMODULE_BOOTCMD_DEFAULT 0 // RESET
+#endif
// External Module
#define EXTMODULE_PWR_GPIO GPIO_PIN(GPIOB, 3) // PB.03
#define EXTERNAL_MODULE_PWR_OFF() gpio_clear(EXTMODULE_PWR_GPIO)
-#if defined(PCBX10) && defined(PCBREV_EXPRESS)
+#if (defined(PCBX10) && defined(PCBREV_EXPRESS)) || defined(RADIO_V16)
#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOB, 10) // PB.10 (TIM2_CH3)
#define EXTMODULE_RX_GPIO GPIO_PIN(GPIOB, 11) // PB.11
#define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF1
@@ -964,6 +1092,10 @@
#define EXTMODULE_USART_TX_DMA_STREAM LL_DMA_STREAM_3
#define EXTMODULE_USART_RX_DMA_CHANNEL LL_DMA_CHANNEL_4
#define EXTMODULE_USART_RX_DMA_STREAM LL_DMA_STREAM_1
+ #if defined(RADIO_V16)
+ #define EXTMODULE_TX_INVERT_GPIO GPIO_PIN(GPIOI, 2) // PI.02
+ #define EXTMODULE_RX_INVERT_GPIO GPIO_PIN(GPIOI, 9) // PI.09
+ #endif
#elif defined(PCBX10) || PCBREV >= 13
#define EXTMODULE_TX_GPIO GPIO_PIN(GPIOA, 10) // PA.10 (TIM1_CH3)
#define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF1
@@ -995,10 +1127,17 @@
// Heartbeat
#define INTMODULE_HEARTBEAT
-#define INTMODULE_HEARTBEAT_GPIO GPIO_PIN(GPIOD, 12) // PD.12 / TIM4_CH1
-#define INTMODULE_HEARTBEAT_EXTI_PORT LL_SYSCFG_EXTI_PORTH
-#define INTMODULE_HEARTBEAT_EXTI_SYS_LINE LL_SYSCFG_EXTI_LINE12
-#define INTMODULE_HEARTBEAT_EXTI_LINE LL_EXTI_LINE_12
+#if defined(RADIO_V16)
+ #define INTMODULE_HEARTBEAT_GPIO GPIO_PIN(GPIOB, 11) // PB.11 / TIM2_CH4
+ #define INTMODULE_HEARTBEAT_EXTI_PORT LL_SYSCFG_EXTI_PORTB
+ #define INTMODULE_HEARTBEAT_EXTI_SYS_LINE LL_SYSCFG_EXTI_LINE11
+ #define INTMODULE_HEARTBEAT_EXTI_LINE LL_EXTI_LINE_11
+#else
+ #define INTMODULE_HEARTBEAT_GPIO GPIO_PIN(GPIOD, 12) // PD.12 / TIM4_CH1
+ #define INTMODULE_HEARTBEAT_EXTI_PORT LL_SYSCFG_EXTI_PORTH
+ #define INTMODULE_HEARTBEAT_EXTI_SYS_LINE LL_SYSCFG_EXTI_LINE12
+ #define INTMODULE_HEARTBEAT_EXTI_LINE LL_EXTI_LINE_12
+#endif
// INTMODULE_HEARTBEAT_EXTI IRQ
#if !defined(USE_EXTI15_10_IRQ)
#define USE_EXTI15_10_IRQ
diff --git a/radio/src/targets/horus/usb_descriptor.h b/radio/src/targets/horus/usb_descriptor.h
index acd181ce26f..0c18dc257b7 100644
--- a/radio/src/targets/horus/usb_descriptor.h
+++ b/radio/src/targets/horus/usb_descriptor.h
@@ -49,4 +49,8 @@
#define USB_NAME "FrSky X10"
#define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
#define USB_PRODUCT 'X', '1', '0', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */
+#elif defined(RADIO_V16)
+ #define USB_NAME "HelloRadioSky V16"
+ #define USB_MANUFACTURER 'H', 'R', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */
+ #define USB_PRODUCT 'V', '1', '6', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */
#endif
diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py
index 51b86ffe2e3..34b034eb21e 100755
--- a/radio/util/build-firmware.py
+++ b/radio/util/build-firmware.py
@@ -194,6 +194,11 @@ def main():
cmake_options["PCBREV"] = "F16"
firmware_options = options_fatfish_f16
maxsize = 2 * 1024 * 1024
+ elif board_name == "v16":
+ cmake_options["PCB"] = "X10"
+ cmake_options["PCBREV"] = "V16"
+ firmware_options = options_helloradiosky_v16
+ maxsize = 2 * 1024 * 1024
else:
return INVALID_BOARD
diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py
index 466d9ce47ea..016f2dedd07 100755
--- a/radio/util/fwoptions.py
+++ b/radio/util/fwoptions.py
@@ -319,6 +319,19 @@
"externalaccessmod": ("HARDWARE_EXTERNAL_ACCESS_MOD", "YES", "NO"),
}
+options_helloradiosky_v16 = {
+ "noheli": ("HELI", "NO", "YES"),
+ "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"),
+ "nogvars": ("GVARS", "NO", "YES"),
+ "faimode": ("FAI", "YES", None),
+ "faichoice": ("FAI", "CHOICE", None),
+ "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"),
+ "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None),
+ "bluetooth": ("BLUETOOTH", "YES", "NO"),
+ "internalgps": ("INTERNAL_GPS", "YES", "NO"),
+ "externalaccessmod": ("HARDWARE_EXTERNAL_ACCESS_MOD", "YES", "NO"),
+}
+
options_commando8_t8 = {
"noheli": ("HELI", "NO", "YES"),
"lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"),
diff --git a/radio/util/hw_defs/legacy_names.py b/radio/util/hw_defs/legacy_names.py
index 950df19fccb..9df9ff6bbf2 100644
--- a/radio/util/hw_defs/legacy_names.py
+++ b/radio/util/hw_defs/legacy_names.py
@@ -2,7 +2,7 @@
LEGACY_NAMES = [
{
- "targets": {"x10", "x10express", "t16", "tx16s", "t18", "f16"},
+ "targets": {"x10", "x10express", "t16", "tx16s", "t18", "f16", "v16"},
"inputs": {
"LH": {
"yaml": "Rud",
diff --git a/radio/util/hw_defs/pot_config.py b/radio/util/hw_defs/pot_config.py
index 084e7b2cbe6..7ee4447a490 100644
--- a/radio/util/hw_defs/pot_config.py
+++ b/radio/util/hw_defs/pot_config.py
@@ -32,6 +32,13 @@
"EXT3": {"default": "MULTIPOS"},
"EXT4": {"default": "MULTIPOS"}
},
+ "v16": {
+ "P1": {"default": "POT_CENTER"},
+ "P2": {"default": "MULTIPOS"},
+ "P3": {"default": "POT_CENTER"},
+ "SL1": {"default": "SLIDER"},
+ "SL2": {"default": "SLIDER"}
+ },
"mt12": {
"P1": {"default": "POT"},
"P2": {"default": "POT"},
diff --git a/radio/util/hw_defs/switch_config.py b/radio/util/hw_defs/switch_config.py
index 3f91f36fe06..a15cf7482f4 100644
--- a/radio/util/hw_defs/switch_config.py
+++ b/radio/util/hw_defs/switch_config.py
@@ -69,6 +69,16 @@
"SG": {"default": "3POS"},
"SH": {"default": "TOGGLE"}
},
+ "v16": {
+ "SA": {"default": "3POS"},
+ "SB": {"default": "3POS"},
+ "SC": {"default": "3POS"},
+ "SD": {"default": "3POS"},
+ "SE": {"default": "3POS"},
+ "SF": {"default": "2POS"},
+ "SG": {"default": "3POS"},
+ "SH": {"default": "TOGGLE"}
+ },
"mt12": {
# left side
"SA": { "default": "3POS", "display": [ 0, 0 ] },
diff --git a/tools/boards.py b/tools/boards.py
index 063863034ad..31793506ca2 100755
--- a/tools/boards.py
+++ b/tools/boards.py
@@ -68,6 +68,11 @@
"PCBREV": "F16",
"INTERNAL_MODULE_MULTI": "YES"
},
+ "V16": {
+ "PCB": "X10",
+ "PCBREV": "V16",
+ "INTERNAL_MODULE_MULTI": "YES"
+ },
"T12": {
"PCB": "X7",
"PCBREV": "T12",
diff --git a/tools/build-common.sh b/tools/build-common.sh
index 3b18366943f..34c63ee5e0f 100644
--- a/tools/build-common.sh
+++ b/tools/build-common.sh
@@ -116,6 +116,9 @@ get_target_build_options() {
f16)
BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=F16"
;;
+ v16)
+ BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=V16"
+ ;;
nv14)
BUILD_OPTIONS+="-DPCB=NV14"
;;
diff --git a/tools/build-companion.sh b/tools/build-companion.sh
index 19f5c1ea8f9..9f5a0168999 100755
--- a/tools/build-companion.sh
+++ b/tools/build-companion.sh
@@ -75,7 +75,7 @@ declare -a simulator_plugins=(x9lite x9lites
xlite xlites
nv14 el18 pl18 pl18ev
x10 x10express x12s
- t15 t16 t18 t20 t20v2 tx16s f16)
+ t15 t16 t18 t20 t20v2 tx16s f16 v16)
for plugin in "${simulator_plugins[@]}"
do