diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index a951d29b3..9c017603d 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -26,6 +26,7 @@ jobs: strategy: matrix: target: + - NV14 - T12 - T16 - T18 diff --git a/radio/src/audio.cpp b/radio/src/audio.cpp index da1998e4b..bbe59ff34 100644 --- a/radio/src/audio.cpp +++ b/radio/src/audio.cpp @@ -531,6 +531,12 @@ void audioTask(void * pdata) #if defined(PCBX12S) || defined(RADIO_TX16S) // The audio amp needs ~2s to start RTOS_WAIT_MS(1000); // 1s +#elif defined(PCBNV14) + while(!isAudioReady()) + { + audioChipReset(); + RTOS_WAIT_MS(1000); + } #endif if (!globalData.unexpectedShutdown) { diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 86070e89b..3a0c85554 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -183,7 +183,7 @@ enum TrainerMode { #endif TRAINER_MODE_MASTER_TRAINER_JACK, TRAINER_MODE_SLAVE, -#if defined(PCBTARANIS) +#if defined(PCBTARANIS) || defined(PCBNV14) TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, #endif @@ -210,7 +210,7 @@ enum TrainerMode { #define TRAINER_MODE_MAX() TRAINER_MODE_MULTI #elif defined(BLUETOOTH) #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH -#elif defined(PCBX7) || defined(PCBXLITE) +#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBNV14) #define TRAINER_MODE_MAX() TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE #elif defined(PCBTARANIS) #define TRAINER_MODE_MAX() (IS_TRAINER_AUX_SERIAL() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index ad59b8b4a..6ace554bf 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -582,7 +582,7 @@ PACK(struct CustomScreenData { #define TOPBAR_DATA #endif -#if defined(PCBHORUS) || defined(PCBTARANIS) +#if defined(PCBHORUS) || defined(PCBTARANIS) || defined(PCBNV14) #define SCRIPT_DATA \ NOBACKUP(ScriptData scriptsData[MAX_SCRIPTS]); #else diff --git a/radio/src/gui/colorlcd/curveedit.cpp b/radio/src/gui/colorlcd/curveedit.cpp index 9de50061f..4d6412f2b 100644 --- a/radio/src/gui/colorlcd/curveedit.cpp +++ b/radio/src/gui/colorlcd/curveedit.cpp @@ -48,7 +48,7 @@ void CurveDataEdit::update() uint8_t curvePointsCount = 5 + curve.points; // Point number - for (uint8_t i = 0; i < curvePointsCount; i++) { + for (int i = 0; i < curvePointsCount; i++) { auto txt = new StaticText( this, {i * boxWidth + PAGE_PADDING, 10, boxWidth - PAGE_PADDING, boxHeight}, @@ -60,7 +60,7 @@ void CurveDataEdit::update() // x value if (curve.type == CURVE_TYPE_CUSTOM) { // Adjustable points for custom curves - for (uint8_t i = 0; i < curvePointsCount; i++) { + for (int i = 0; i < curvePointsCount; i++) { int8_t* points = curveAddress(index); auto pointEdit = new NumberEdit( this, diff --git a/radio/src/gui/colorlcd/model_curves.cpp b/radio/src/gui/colorlcd/model_curves.cpp index 8d463fe67..19af410a7 100644 --- a/radio/src/gui/colorlcd/model_curves.cpp +++ b/radio/src/gui/colorlcd/model_curves.cpp @@ -174,7 +174,9 @@ class CurveEditWindow : public Page curve.type = newValue; } SET_DIRTY(); - curveEdit->update(); + curveEdit->updatePreview(); + curveDataEdit->clear(); + curveDataEdit->update(); } }); @@ -196,7 +198,9 @@ class CurveEditWindow : public Page } curve.points = newValue; SET_DIRTY(); - curveEdit->update(); + curveEdit->updatePreview(); + curveDataEdit->clear(); + curveDataEdit->update(); } }); edit->setSuffix(STR_PTS); @@ -208,7 +212,7 @@ class CurveEditWindow : public Page [=](int32_t newValue) { g_model.curves[index].smooth = newValue; SET_DIRTY(); - curveEdit->update(); + curveEdit->updatePreview(); }); grid.nextLine(); } diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index ecb737a4b..3e75e8148 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -622,6 +622,16 @@ class ModuleWindow : public FormGroup { rfChoice->setFocus(SET_FOCUS_DEFAULT); }); } + else if (isModuleFlySky(moduleIdx)) { + rfChoice = new Choice(this, grid.getFieldSlot(2, 1), STR_FLYSKY_PROTOCOLS, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_LR12, + GET_DEFAULT(g_model.moduleData[moduleIdx].subType), + [=](int32_t newValue) { + g_model.moduleData[moduleIdx].subType = newValue; + SET_DIRTY(); + update(); + rfChoice->setFocus(SET_FOCUS_DEFAULT); + }); + } #if defined(MULTIMODULE) else if (isModuleMultimodule(moduleIdx)) { Choice * mmSubProtocol = nullptr; diff --git a/radio/src/gui/colorlcd/radio_diaganas.cpp b/radio/src/gui/colorlcd/radio_diaganas.cpp index 939b113b2..9539bfb36 100644 --- a/radio/src/gui/colorlcd/radio_diaganas.cpp +++ b/radio/src/gui/colorlcd/radio_diaganas.cpp @@ -59,7 +59,7 @@ class RadioAnalogsDiagsWindow: public Window { dc->drawLine(touchState.x - 10, touchState.y - 8 - parent->top(), touchState.x + 10, touchState.y + 8 - parent->top(), SOLID, 0); dc->drawLine(touchState.x - 10, touchState.y + 8 - parent->top(), touchState.x + 10, touchState.y - 8- parent->top(), SOLID, 0); } -#if !defined(SIMU) +#if !defined(SIMU) && !defined(PCBNV14) constexpr coord_t y1 = MENU_CONTENT_TOP + 6 * FH; coord_t x1 = MENUS_MARGIN_LEFT; x1 = dc->drawText(x1, y1, "Touch GT911 FW ver:") + 8; diff --git a/radio/src/gui/colorlcd/themes/480_default.cpp b/radio/src/gui/colorlcd/themes/480_default.cpp index c5159c6b4..331c8b7b7 100644 --- a/radio/src/gui/colorlcd/themes/480_default.cpp +++ b/radio/src/gui/colorlcd/themes/480_default.cpp @@ -462,7 +462,7 @@ BitmapBuffer * Theme480::currentMenuBackground = nullptr; Theme480 Theme480; -#if LCD_W == 480 +#if LCD_W == 480 || LCD_H == 480 OpenTxTheme * defaultTheme = &Theme480; Theme * theme = &Theme480; #endif diff --git a/radio/src/gui/colorlcd/themes/flysky.cpp b/radio/src/gui/colorlcd/themes/flysky.cpp index a8c519d41..618a988ad 100644 --- a/radio/src/gui/colorlcd/themes/flysky.cpp +++ b/radio/src/gui/colorlcd/themes/flysky.cpp @@ -454,9 +454,9 @@ BitmapBuffer * FlyskyTheme::menuIconNormal[MENUS_ICONS_COUNT] = { nullptr }; BitmapBuffer * FlyskyTheme::menuIconSelected[MENUS_ICONS_COUNT] = { nullptr }; BitmapBuffer * FlyskyTheme::currentMenuBackground = nullptr; -FlyskyTheme flyskyTheme; +/*FlyskyTheme flyskyTheme; #if defined(PCBFLYSKY) OpenTxTheme * defaultTheme = &flyskyTheme; Theme * theme = &flyskyTheme; -#endif +#endif*/ diff --git a/radio/src/gui/colorlcd/view_text.cpp b/radio/src/gui/colorlcd/view_text.cpp index c3381508d..af2536453 100644 --- a/radio/src/gui/colorlcd/view_text.cpp +++ b/radio/src/gui/colorlcd/view_text.cpp @@ -96,12 +96,15 @@ void ViewTextWindow::checkEvents() coord_t deltaY; event_t event = getWindowEvent(); +#if defined(ROTARY_ENCODER_NAVIGATION) if (event == EVT_ROTARY_LEFT || event == EVT_ROTARY_RIGHT) { deltaY = ROTARY_ENCODER_SPEED() * step; } else { deltaY = step; } - +#else + deltaY = step; +#endif switch (event) { CASE_EVT_KEY_NEXT_LINE: currentPos += deltaY; @@ -259,12 +262,16 @@ void ViewTextWindow::checkEvents() coord_t deltaY; event_t event = getWindowEvent(); +#if defined(ROTARY_ENCODER_NAVIGATION) if (event == EVT_ROTARY_LEFT || event == EVT_ROTARY_RIGHT) { deltaY = ROTARY_ENCODER_SPEED() * step; } else { deltaY = step; } - +#else + deltaY = step; +#endif + int lineStep = deltaY / step; if(lineStep > (maxScreenLines >> 1)) lineStep = maxScreenLines >> 1; /* diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 058c20765..2afe2e6b9 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -628,6 +628,13 @@ bool isInternalModuleAvailable(int moduleType) return true; #endif } + +#if (defined(AFHDS3) || defined(AFHDS2A)) && (defined(INTERNAL_MODULE_AFHDS2A) || defined(INTERNAL_MODULE_AFHDS3)) + if (moduleType == MODULE_TYPE_AFHDS3) { + return true; + } +#endif + return false; } #else diff --git a/radio/src/keys.h b/radio/src/keys.h index 601b0a30f..1fca0bd4d 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -32,7 +32,7 @@ constexpr event_t EVT_ENTRY_UP = 0x1002; constexpr event_t EVT_ROTARY_LEFT = 0x1003; constexpr event_t EVT_ROTARY_RIGHT = 0x1004; -#if defined(PCBHORUS) +#if defined(PCBHORUS) || defined (PCBNV14) constexpr event_t _MSK_KEY_BREAK = 0x0200; constexpr event_t _MSK_KEY_REPT = 0x0400; constexpr event_t _MSK_KEY_FIRST = 0x0600; diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt index c1cd80a12..8325bb2aa 100644 --- a/radio/src/lua/CMakeLists.txt +++ b/radio/src/lua/CMakeLists.txt @@ -33,4 +33,5 @@ if(PYTHONINTERP_FOUND) add_lua_export_target(tx12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_TX12) add_lua_export_target(t8 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T8) add_lua_export_target(t16 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10 -DRADIO_T16) + add_lua_export_target(nv14 ${LUA_INCLUDES} -I${RADIO_SRC_DIR}/targets/nv14 -DPCBNV14) endif() diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index f37484340..0a1c4498c 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -64,6 +64,8 @@ #include "lua/lua_exports_x9d+2019.inc" #elif defined(PCBTARANIS) #include "lua/lua_exports_x9d.inc" +#elif defined(PCBNV14) + #include "lua/lua_exports_nv14.inc" #endif #if defined(SIMU) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index f59c4fa6d..0bb88ac0f 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -538,6 +538,11 @@ void checkBacklight() resetBacklightTimeout(); } } +#if defined(HARDWARE_TOUCH) && defined(PCBNV14) + if (touchPanelEventOccured() && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) { + resetBacklightTimeout(); + } +#endif if (requiredBacklightBright == BACKLIGHT_FORCED_ON) { currentBacklightBright = g_eeGeneral.backlightBright; @@ -551,7 +556,6 @@ void checkBacklight() if (flashCounter) { backlightOn = !backlightOn; } - if (backlightOn) { currentBacklightBright = requiredBacklightBright; BACKLIGHT_ENABLE(); diff --git a/radio/src/pulses/afhds3.h b/radio/src/pulses/afhds3.h index 5d687bc0e..1cf262eee 100644 --- a/radio/src/pulses/afhds3.h +++ b/radio/src/pulses/afhds3.h @@ -93,13 +93,18 @@ struct Data void reset() { +#if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO) +#else pulsesSize = 0; +#endif } #if defined(EXTMODULE_USART) && defined(EXTMODULE_TX_INVERT_GPIO) void sendByte(uint8_t b) { +#if !defined(SIMU) *ptr++ = b; +#endif } const uint8_t* getData() diff --git a/radio/src/pulses/modules_constants.h b/radio/src/pulses/modules_constants.h index b6b7a6abc..4774c3dae 100644 --- a/radio/src/pulses/modules_constants.h +++ b/radio/src/pulses/modules_constants.h @@ -38,6 +38,7 @@ enum ModuleType { MODULE_TYPE_SBUS, MODULE_TYPE_XJT_LITE_PXX2, MODULE_TYPE_AFHDS3, //no more protocols possible because of 4 bits value + //MODULE_TYPE_AFHDS2A, MODULE_TYPE_COUNT, MODULE_TYPE_MAX = MODULE_TYPE_COUNT - 1 }; @@ -222,6 +223,11 @@ enum ModuleSubtypeDSM2 { DSM2_PROTO_DSMX, }; +enum ModuleSubtypeFlysky { + FLYSKY_SUBTYPE_AFHDS3=0, + FLYSKY_SUBTYPE_AFHDS2A +}; + enum FailsafeModes { FAILSAFE_NOT_SET, FAILSAFE_HOLD, diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index 37a8c45c2..23eca3f9f 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -319,9 +319,22 @@ inline bool isModuleSBUS(uint8_t moduleIdx) return g_model.moduleData[moduleIdx].type == MODULE_TYPE_SBUS; } +inline bool isModuleFlySky(uint8_t idx) +{ + return + (g_model.moduleData[idx].type == MODULE_TYPE_AFHDS3); +} + +inline bool isModuleAFHDS2A(uint8_t idx) +{ + return isModuleFlySky(idx) + && (g_model.moduleData[idx].subType == FLYSKY_SUBTYPE_AFHDS2A); +} + inline bool isModuleAFHDS3(uint8_t idx) { - return g_model.moduleData[idx].type == MODULE_TYPE_AFHDS3; + return isModuleFlySky(idx) + && (g_model.moduleData[idx].subType == FLYSKY_SUBTYPE_AFHDS3); } // order is the same as in enum Protocols in myeeprom.h (none, ppm, pxx, pxx2, dsm, crossfire, multi, r9m, r9m2, sbus) diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index 6712526b9..a6888270f 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -187,9 +187,13 @@ uint8_t getRequiredProtocol(uint8_t module) break; #endif -#if defined(AFHDS3) +#if defined(AFHDS3) || defined(AFHDS2) case MODULE_TYPE_AFHDS3: - protocol = PROTOCOL_CHANNELS_AFHDS3; + if (isModuleAFHDS3(module)) { + protocol = PROTOCOL_CHANNELS_AFHDS3; + } else if (isModuleAFHDS2A(module)) { + protocol = PROTOCOL_CHANNELS_AFHDS2A; + } break; #endif @@ -474,6 +478,14 @@ static void enablePulsesInternalModule(uint8_t protocol) break; #endif +#if defined(AFHDS2) + case PROTOCOL_CHANNELS_AFHDS2A: +/* extmodulePulsesData.afhds2.init(INTERNAL_MODULE); + extmoduleSerialStart();*/ + mixerSchedulerSetPeriod(INTERNAL_MODULE, 2 * 1000 /* us */); + break; +#endif + default: // internal module stopped, set internal period to 0 and start the scheduler mixerSchedulerSetPeriod(INTERNAL_MODULE, 0); diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 679bfe419..76d489737 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -273,6 +273,7 @@ union InternalModulePulsesData { #if defined(INTERNAL_MODULE_PPM) PpmPulsesData ppm; #endif + } __ALIGNED(4); union ExternalModulePulsesData { @@ -389,6 +390,7 @@ enum ChannelsProtocols { PROTOCOL_CHANNELS_SBUS, PROTOCOL_CHANNELS_PXX2_LOWSPEED, PROTOCOL_CHANNELS_PXX2_HIGHSPEED, + PROTOCOL_CHANNELS_AFHDS2A, PROTOCOL_CHANNELS_AFHDS3, PROTOCOL_CHANNELS_GHOST }; diff --git a/radio/src/storage/conversions/datastructs_219.h b/radio/src/storage/conversions/datastructs_219.h index ef83d2471..3f30c69b3 100644 --- a/radio/src/storage/conversions/datastructs_219.h +++ b/radio/src/storage/conversions/datastructs_219.h @@ -27,7 +27,7 @@ #define NUM_SWITCHES_219 10 #elif defined(PCBXLITE) ||defined(PCBXLITES) #define NUM_SWITCHES_219 6 -#elif defined(RADIO_TLITE) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_T8) +#elif defined(RADIO_TLITE) || defined(RADIO_FAMILY_JUMPER_T12) || defined(RADIO_T8) || defined(PCBNV14) #define NUM_SWITCHES_219 8 #elif defined(PCBX7) || defined(PCBX7ACCESS) #define NUM_SWITCHES_219 8 @@ -49,7 +49,7 @@ #elif defined(PCBX9LITE) #define NUM_POTS_219 1 #define NUM_SLIDERS_219 0 -#elif defined(RADIO_T8) || defined(RADIO_TLITE) || defined(PCBXLITE) || defined(PCBX7) +#elif defined(RADIO_T8) || defined(RADIO_TLITE) || defined(PCBXLITE) || defined(PCBX7) || defined(PCBNV14) #define NUM_POTS_219 2 #define NUM_SLIDERS_219 0 #elif defined(PCBX9E) @@ -113,7 +113,7 @@ #define MAX_CURVE_POINTS_219 512 #endif -#if defined(PCBHORUS) +#if defined(PCBHORUS) || defined(PCBNV14) #define MAX_MODELS_219 60 #define MAX_OUTPUT_CHANNELS_219 32 // number of real output channels CH1-CH32 #define MAX_FLIGHT_MODES_219 9 diff --git a/radio/src/targets/common/arm/stm32/timers_driver.cpp b/radio/src/targets/common/arm/stm32/timers_driver.cpp index b44d0b051..bae659483 100644 --- a/radio/src/targets/common/arm/stm32/timers_driver.cpp +++ b/radio/src/targets/common/arm/stm32/timers_driver.cpp @@ -31,10 +31,10 @@ void init2MhzTimer() TIMER_2MHz_TIMER->CR1 = TIM_CR1_CEN; } -// Start TIMER at 200Hz -void init5msTimer() +// Start TIMER at 1000Hz +void init1msTimer() { - INTERRUPT_xMS_TIMER->ARR = 4999; // 5mS in uS + INTERRUPT_xMS_TIMER->ARR = 999; // 1mS in uS INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS INTERRUPT_xMS_TIMER->CCER = 0; INTERRUPT_xMS_TIMER->CCMR1 = 0; @@ -45,30 +45,37 @@ void init5msTimer() NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7); } -void stop5msTimer() +void stop1msTimer() { INTERRUPT_xMS_TIMER->CR1 = 0; // stop timer NVIC_DisableIRQ(INTERRUPT_xMS_IRQn); } // TODO use the same than board_sky9x.cpp -void interrupt5ms() +void interrupt1ms() { static uint8_t pre_scale; // Used to get 10 Hz counter ++pre_scale; -#if defined(HAPTIC) - DEBUG_TIMER_START(debugTimerHaptic); - HAPTIC_HEARTBEAT(); - DEBUG_TIMER_STOP(debugTimerHaptic); -#endif - -#if defined(FLYSKY_HALL_STICKS) + // 1 ms loop +#if defined(FLYSKY_HALL_STICKS) && !defined(SIMU) flysky_hall_stick_loop(); // TODO: need to put in 1ms timer loop for best performance #endif - if (pre_scale == 2) { + // 5ms loop + if (pre_scale == 5 || pre_scale == 10) + { +#if defined(HAPTIC) + DEBUG_TIMER_START(debugTimerHaptic); + HAPTIC_HEARTBEAT(); + DEBUG_TIMER_STOP(debugTimerHaptic); +#endif + } + + // 10ms loop + if (pre_scale == 10) + { pre_scale = 0; DEBUG_TIMER_START(debugTimerPer10ms); DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod); @@ -80,6 +87,6 @@ void interrupt5ms() extern "C" void INTERRUPT_xMS_IRQHandler() { INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF; - interrupt5ms(); + interrupt1ms(); DEBUG_INTERRUPT(INT_1MS); } diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index f5a9d0978..f24f8f1bf 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -206,7 +206,7 @@ void boardInit() #endif init2MhzTimer(); - init5msTimer(); + init1msTimer(); usbInit(); hapticInit(); diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index bc1be0d09..504a4d216 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -75,7 +75,7 @@ void boardOff(); // Timers driver void init2MhzTimer(); -void init5msTimer(); +void init1msTimer(); // PCBREV driver enum { diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 80737d3b5..ce7c0e98e 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -166,8 +166,12 @@ void extmoduleSerialStart() EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->EGR = 1; // Restart EXTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; +#else +#if defined(PCBNV14) + EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | TIM_CCER_CC1P; // inverted breaks NV14 build, inverted should be false here? #else EXTMODULE_TIMER->CCER = TIM_CCER_CC1E | (inverted ? 0 : TIM_CCER_CC1P); +#endif EXTMODULE_TIMER->BDTR = TIM_BDTR_MOE; // Enable outputs EXTMODULE_TIMER->CCR1 = 0; EXTMODULE_TIMER->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0; // Force O/P high diff --git a/radio/src/targets/horus/flyskyHallStick_driver.cpp b/radio/src/targets/horus/flyskyHallStick_driver.cpp index 0aa6f3168..6d4b1d0c4 100644 --- a/radio/src/targets/horus/flyskyHallStick_driver.cpp +++ b/radio/src/targets/horus/flyskyHallStick_driver.cpp @@ -534,7 +534,6 @@ void flysky_hall_stick_loop(void) if (log) { - TRACE_NOCRLF("Hall(%0d):", FLYSKY_FLYSKY_HALL_BAUDRATE); for (int idx = 0; idx < HallProtocol.length + 5; idx++) { TRACE_NOCRLF(" %02X", *((uint8_t*)&HallProtocol + idx)); diff --git a/radio/src/targets/nv14/CMakeLists.txt b/radio/src/targets/nv14/CMakeLists.txt index 2bf624a70..a605170b6 100644 --- a/radio/src/targets/nv14/CMakeLists.txt +++ b/radio/src/targets/nv14/CMakeLists.txt @@ -4,6 +4,8 @@ option(FLYSKY_HALL_STICKS "sticks for FlySky hall sticks" ON) option(FLYSKY_HALL_STICKS_REVERSE "Reverse sticks for FlySky hall sticks" OFF) option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON) option(AFHDS2 "Support for AFHDS2" ON) +option(PXX1 "PXX1 protocol support" ON) +option(PXX2 "PXX2 protocol support" OFF) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F4) @@ -14,6 +16,8 @@ set(STORAGE_FORMAT BIN) set(HAPTIC YES) set(GUI_DIR colorlcd) set(BITMAPS_DIR 480x272) +#set(HARDWARE_EXTERNAL_MODULE YES) +#set(AUX_SERIAL ON) # set(NAVIGATION_TYPE touch) set(TARGET_DIR nv14) add_definitions(-DHARDWARE_TRAINER_JACK) @@ -24,7 +28,7 @@ else() set(LINKER_SCRIPT targets/nv14/stm32f4_flash.ld) endif() -set(RAMBACKUP YES) +set(RTC_BACKUP_RAM YES) set(PPM_LIMITS_SYMETRICAL YES) # for size report script set(CPU_TYPE_FULL STM32F429xI) @@ -36,44 +40,56 @@ set(PCB_RF_BAUD 921600 CACHE STRING "INTERNAL_MODULE_BAUDRATE: ${RF_BAUD_RATE}") set_property(CACHE PCB_RF_BAUD PROPERTY STRINGS ${RF_BAUD_RATE}) set(FLAVOUR nv14) -add_definitions(-DPCBNV14 -DPCBFLYSKY -DINTERNAL_MODULE_BAUDRATE=${PCB_RF_BAUD}) +#add_definitions(-DPCBNV14 -DPCBFLYSKY -DINTERNAL_MODULE_BAUDRATE=${PCB_RF_BAUD}) +add_definitions(-DPCBNV14 -DPCBFLYSKY -DINTERNAL_MODULE_SERIAL -DAFHDS2_BAUDRATE=${PCB_RF_BAUD}) add_definitions(-DBATTERY_CHARGE) # -DSOFTWARE_VOLUME +add_definitions(-DINTERNAL_MODULE_AFHDS2A) set(TARGET_SRC ${TARGET_SRC} audio_spi_driver.cpp + adc_driver.cpp +# ../common/arm/stm32/adc_driver.cpp + ../common/arm/stm32/mixer_scheduler_driver.cpp + ../common/arm/stm32/timers_driver.cpp ) -set(FIRMWARE_TARGET_SRC - ${FIRMWARE_TARGET_SRC} - x12s_adc_driver.cpp - ) +#set(FIRMWARE_TARGET_SRC +# ${FIRMWARE_TARGET_SRC} +# x12s_adc_driver.cpp +# ) set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} battery_driver.cpp - hallStick_driver.cpp + ../horus/flyskyHallStick_driver.cpp ) set(BITMAPS_TARGET nv14_bitmaps) set(FONTS_TARGET x12_fonts) set(LCD_DRIVER lcd_driver.cpp) -set(LUA_EXPORT lua_export_x10) +set(LUA_EXPORT lua_export_nv14) set(TOUCH_DRIVER touch_driver.cpp) set(HARDWARE_TOUCH YES) set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET} truetype_fonts) +set(FIRMWARE_DEPENDENCIES datacopy) set(HARDWARE_TOUCH ON) set(SOFTWARE_KEYBOARD ON) +set(FIRMWARE_DEPENDENCIES datacopy) + add_definitions(-DSTM32F429_439xx -DSDRAM -DCOLORLCD -DLIBOPENUI -DHARDWARE_TOUCH -DSOFTWARE_KEYBOARD) add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK) add_definitions(-DGPS_USART_BAUDRATE=${INTERNAL_GPS_BAUDRATE}) add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) add_definitions(-DCROSSFIRE_NATIVE) add_definitions(-DFLYSKY_HALL_STICKS_REVERSE) -add_definitions(-DHALL_STICKS) +add_definitions(-DFLYSKY_HALL_STICKS) +add_definitions(-DAFHDS2) +add_definitions(-DHARDWARE_EXTERNAL_MODULE) +#add_definitions(-DAUX_SERIAL) #add_definitions(-DFLYSKY_AUTO_POWER_DOWN) if(STICKS_DEAD_ZONE) @@ -98,7 +114,7 @@ if(DISK_CACHE) add_definitions(-DDISK_CACHE) endif() -set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) +#set(AUX_SERIAL_DRIVER ../common/arm/stm32/aux_serial_driver.cpp) set(SRC ${SRC} @@ -109,7 +125,9 @@ set(GVAR_SCREEN model_gvars.cpp) set(TARGET_SRC ${TARGET_SRC} - extmodule_driver.cpp +# extmodule_driver.cpp + extmodule_helper.cpp + ../horus/extmodule_driver.cpp trainer_driver.cpp ../common/arm/stm32/intmodule_serial_driver.cpp ) @@ -149,12 +167,51 @@ set(STM32LIB_SRC STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c ) +MACRO(GET_GCC_INCLUDE_PATH gcc_include_path) + if (WIN32) + execute_process(COMMAND arm-none-eabi-gcc -v -x c -E NUL ERROR_VARIABLE _gcc_output OUTPUT_QUIET) + else() + execute_process(COMMAND arm-none-eabi-gcc -v -x c -E - INPUT_FILE /dev/null ERROR_VARIABLE _gcc_output OUTPUT_QUIET) + endif() + + # Build an array of string from the GCC output + string(REPLACE "\n" ";" _gcc_output "${_gcc_output}") + + set(_capture_include FALSE) + set(_include_path "") + + # Go through the lines and capture between '"#include <...> search starts here:"' and 'End of search list.' + foreach(_line ${_gcc_output}) + if(${_line} STREQUAL "End of search list.") + set(_capture_include FALSE) + endif() + + if(_capture_include) + # Remove the leading and trailing empty characters + string(REPLACE "\r" "" _line ${_line}) + string(SUBSTRING "${_line}" 1 -1 _line) + set(_include_path "${_include_path}" "-I${_line}") + endif() + + if(${_line} STREQUAL "#include <...> search starts here:") + set(_capture_include TRUE) + endif() + endforeach() + set(${gcc_include_path} ${_include_path}) +ENDMACRO() + if(PYTHONINTERP_FOUND) - add_custom_target(datacopy + GET_GCC_INCLUDE_PATH(arm_gcc_include_path) + + add_custom_command( + OUTPUT ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp WORKING_DIRECTORY ${RADIO_DIRECTORY}/src - COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBFLYSKY -DPCBNV14 -DCPUARM -DCOLORLCD -DBACKUP > storage/datacopy.cpp + COMMAND ${PYTHON_EXECUTABLE} ${RADIO_DIRECTORY}/util/generate_datacopy.py datastructs.h -DPCBFLYSKY -DPCBNV14 -DCPUARM -DSTM32F4 -DSTM32F429_439xx -DCOLORLCD -DBACKUP -DSIMU -I. -Igui/colorlcd -Itargets/nv14 -Itargets/common/arm/stm32 -I${THIRDPARTY_DIR} -I${THIRDPARTY_DIR}/libopenui/src -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/STM32F4xx_StdPeriph_Driver/inc -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include -I${THIRDPARTY_DIR}/STM32F4xx_DSP_StdPeriph_Lib_V1.8.0/Libraries/CMSIS/Include ${arm_gcc_include_path} -Wno-pragma-once-outside-header > ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py - ) + ) + + add_custom_target(datacopy + DEPENDS ${PROJECT_BINARY_DIR}/radio/src/datacopy.cpp + ) endif() -set(LUA_EXPORT lua_export_nv14) diff --git a/radio/src/targets/nv14/adc_driver.cpp b/radio/src/targets/nv14/adc_driver.cpp index 60cc4a00b..203ee1f34 100644 --- a/radio/src/targets/nv14/adc_driver.cpp +++ b/radio/src/targets/nv14/adc_driver.cpp @@ -68,9 +68,10 @@ #define FIRST_ANALOG_ADC 0 #define NUM_MAIN_ANALOGS_ADC 10 #define NUM_MAIN_ANALOGS_ADC_EXT (NUM_MAIN_ANALOGS - 10) -#elif defined(PCBNV14) && defined(HALL_STICKS) +#elif defined(PCBNV14) && defined(FLYSKY_HALL_STICKS) #define FIRST_ANALOG_ADC 4 #define NUM_MAIN_ANALOGS_ADC 9 + #define NUM_SUB_ANALOGS_ADC 2 #else #define FIRST_ANALOG_ADC 0 #define FIRST_SUB_ANALOG_ADC 0 @@ -147,7 +148,7 @@ void adcInit() ADC_MAIN->SQR2 = (ADC_CHANNEL_SWE<<0) + (ADC_CHANNEL_SWF<<5) + (ADC_CHANNEL_LIBATT<<10) + (ADC_CHANNEL_DRYBATT<<15); // conversions 7 and more ADC_MAIN->SQR3 = (ADC_CHANNEL_POT1<<0) + (ADC_CHANNEL_POT2<<5) + (ADC_CHANNEL_SWA<<10) + (ADC_CHANNEL_SWB<<15) + (ADC_CHANNEL_SWC<<20) + (ADC_CHANNEL_SWD<<25); // conversions 1 to 6 #elif defined(PCBNV14) - #if !defined(HALL_STICKS) + #if !defined(FLYSKY_HALL_STICKS) ADC_MAIN->SQR1 |= (ADC_CHANNEL_BATT <<0 ); ADC_MAIN->SQR2 = (ADC_CHANNEL_SWA << 0) + (ADC_CHANNEL_SWC << 5) + (ADC_CHANNEL_SWE << 10) + (ADC_CHANNEL_SWF << 15) + (ADC_CHANNEL_SWG << 20) + (ADC_CHANNEL_SWH << 25); // conversions 7 and more ADC_MAIN->SQR3 = (ADC_CHANNEL_STICK_LH<<0) + (ADC_CHANNEL_STICK_LV<<5) + (ADC_CHANNEL_STICK_RV<<10) + (ADC_CHANNEL_STICK_RH<<15) + (ADC_CHANNEL_POT1<<20) + (ADC_CHANNEL_POT2<<25); // conversions 1 to 6 @@ -173,7 +174,7 @@ void adcInit() ADC_MAIN_DMA_Stream->NDTR = NUM_MAIN_ANALOGS_ADC; ADC_MAIN_DMA_Stream->FCR = DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0; -#if NUM_SUB_ANALOGS > 0 +#if NUM_SUB_ANALOGS_ADC > 0 ADC_SUB->SMPR1 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24); ADC_SUB->SMPR2 = ADC_SAMPTIME + (ADC_SAMPTIME<<3) + (ADC_SAMPTIME<<6) + (ADC_SAMPTIME<<9) + (ADC_SAMPTIME<<12) + (ADC_SAMPTIME<<15) + (ADC_SAMPTIME<<18) + (ADC_SAMPTIME<<21) + (ADC_SAMPTIME<<24) + (ADC_SAMPTIME<<27); @@ -296,13 +297,13 @@ void adcRead() #endif } +#if !defined(SIMU) uint16_t getRTCBatteryVoltage() { #warning "TODO RTC voltage" return 330; } -#if !defined(SIMU) uint16_t getAnalogValue(uint8_t index) { if (IS_POT(index) && !IS_POT_SLIDER_AVAILABLE(index)) { diff --git a/radio/src/targets/nv14/audio_spi_driver.cpp b/radio/src/targets/nv14/audio_spi_driver.cpp index f21b5c46f..60ec589d9 100644 --- a/radio/src/targets/nv14/audio_spi_driver.cpp +++ b/radio/src/targets/nv14/audio_spi_driver.cpp @@ -276,7 +276,8 @@ uint8_t audioHardReset(void) XDCS_HIGH(); CS_HIGH(); RST_HIGH(); - while (READ_DREQ() == 0 && retry < 200) { + while (READ_DREQ() == 0 && retry < 200) + { retry++; delay_us(50); } diff --git a/radio/src/targets/nv14/battery_driver.cpp b/radio/src/targets/nv14/battery_driver.cpp index 6ef43f042..ca6b11854 100644 --- a/radio/src/targets/nv14/battery_driver.cpp +++ b/radio/src/targets/nv14/battery_driver.cpp @@ -182,7 +182,6 @@ void handle_battery_charge(uint32_t last_press_time) lcdOn(); } updateTime = get_tmr10ms(); - lcdNextLayer(); lcd->clear(); drawChargingInfo(chargeState); lcdRefresh(); diff --git a/radio/src/targets/nv14/board.cpp b/radio/src/targets/nv14/board.cpp index 65ea598e4..627b175a2 100644 --- a/radio/src/targets/nv14/board.cpp +++ b/radio/src/targets/nv14/board.cpp @@ -29,6 +29,8 @@ extern "C" { } #endif +extern void flysky_hall_stick_init( void ); + HardwareOptions hardwareOptions; void watchdogInit(unsigned int duration) @@ -41,69 +43,6 @@ void watchdogInit(unsigned int duration) IWDG->KR = 0xCCCC; // start } -// Start TIMER7 at 2000000Hz -void init2MhzTimer() -{ - TIMER_2MHz_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5 uS, 2 MHz - TIMER_2MHz_TIMER->ARR = 65535; - TIMER_2MHz_TIMER->CR2 = 0; - TIMER_2MHz_TIMER->CR1 = TIM_CR1_CEN; -} - -// Starts TIMER at 1000Hz -void init1msTimer() -{ - INTERRUPT_xMS_TIMER->ARR = 999; // 1mS in uS - INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS - INTERRUPT_xMS_TIMER->CCER = 0; - INTERRUPT_xMS_TIMER->CCMR1 = 0; - INTERRUPT_xMS_TIMER->EGR = 0; - INTERRUPT_xMS_TIMER->CR1 = 5; - INTERRUPT_xMS_TIMER->DIER |= 1; - NVIC_EnableIRQ(INTERRUPT_xMS_IRQn); - NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7); -} -void interrupt1ms() -{ - static uint8_t pre_scale; // Used to get 10 Hz counter - - ++pre_scale; - -#if defined(DEBUG) && !defined(SIMU) - debugCounter1ms++; -#endif - -#if defined(HAPTIC) && !defined(BOOT) - if (pre_scale == 5 || pre_scale == 10) { - DEBUG_TIMER_START(debugTimerHaptic); - HAPTIC_HEARTBEAT(); - DEBUG_TIMER_STOP(debugTimerHaptic); - } -#endif - - if (pre_scale == 10) { - pre_scale = 0; -#if !defined(SIMU) - if (boardState == BOARD_STARTED) hall_stick_loop(); -#endif - DEBUG_TIMER_START(debugTimerPer10ms); - DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod); - per10ms(); - DEBUG_TIMER_STOP(debugTimerPer10ms); - } - - DEBUG_TIMER_START(debugTimerRotEnc); - DEBUG_TIMER_STOP(debugTimerRotEnc); -} -#if !defined(BOOT) -extern "C" void INTERRUPT_xMS_IRQHandler() -{ - INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF; - interrupt1ms(); - DEBUG_INTERRUPT(INT_1MS); -} -#endif - #if defined(SEMIHOSTING) extern "C" void initialise_monitor_handles(); #endif @@ -131,7 +70,7 @@ void delay_self(int count) AUDIO_RCC_AHB1Periph |\ HAPTIC_RCC_AHB1Periph |\ INTMODULE_RCC_AHB1Periph |\ - INTMODULE_RCC_AHB1Periph|\ + FLYSKY_HALL_RCC_AHB1Periph |\ EXTMODULE_RCC_AHB1Periph\ ) #define RCC_AHB3PeriphMinimum (SDRAM_RCC_AHB3Periph) @@ -144,7 +83,7 @@ void delay_self(int count) #define RCC_APB1PeriphOther (TELEMETRY_RCC_APB1Periph |\ TRAINER_RCC_APB1Periph |\ INTMODULE_RCC_APB1Periph |\ - HALL_RCC_APB1Periph |\ + FLYSKY_HALL_RCC_APB1Periph |\ EXTMODULE_RCC_APB1Periph |\ INTMODULE_RCC_APB1Periph |\ AUX_SERIAL_RCC_APB1Periph \ @@ -185,6 +124,9 @@ void boardInit() pwrInit(); extModuleInit(); battery_charge_init(); +#if defined(FLYSKY_HALL_STICKS) + flysky_hall_stick_init(); +#endif init2MhzTimer(); init1msTimer(); TouchInit(); @@ -228,9 +170,6 @@ void boardInit() adcInit(); backlightInit(); lcdInit(); -#if defined(FLYSKY_HALL_STICKS) - hall_stick_init(FLYSKY_HALL_BAUDRATE); -#endif usbInit(); hapticInit(); boardState = BOARD_STARTED; diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index db90d841d..d4bc4e37c 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -21,10 +21,10 @@ #ifndef _BOARD_H_ #define _BOARD_H_ -#include "../definitions.h" -#include "../opentx_constants.h" -#include "hal.h" +#include "definitions.h" +#include "opentx_constants.h" #include "board_common.h" +#include "hal.h" #if !defined(LUA_EXPORT_GENERATION) #include "stm32f4xx_sdio.h" @@ -34,7 +34,7 @@ #endif #include "touch_driver.h" -#include "hallStick_driver.h" +//#include "hallStick_driver.h" #include "lcd_driver.h" #include "battery_driver.h" @@ -69,7 +69,7 @@ void boardOff(); // Timers driver void init2MhzTimer(); -void init5msTimer(); +void init1msTimer(); // CPU Unique ID #define LEN_CPU_UID (3*8+2) @@ -128,7 +128,8 @@ void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, void intmoduleSendBuffer(const uint8_t * data, uint8_t size); void intmoduleSendNextFrame(); -void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted); +//void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted); +void extmoduleSerialStart(); void extmoduleSendNextFrame(); void extmoduleSendInvertedByte(uint8_t byte); @@ -146,6 +147,7 @@ enum EnumKeys KEY_PGUP, KEY_PGDN, KEY_UP, + KEY_MODEL = KEY_UP, // TODO: just fixed for compile error, seems this is quite different from horus definition. KEY_DOWN, KEY_RIGHT, KEY_LEFT, @@ -236,13 +238,6 @@ enum EnumSwitchesPositions }; #define STORAGE_NUM_SWITCHES_POSITIONS (STORAGE_NUM_SWITCHES * 3) -enum EnumPowerupState -{ - BOARD_POWER_OFF = 0xCAFEDEAD, - BOARD_POWER_ON = 0xDEADBEEF, - BOARD_STARTED = 0xBAADF00D, - BOARD_REBOOT = 0xC00010FF, -}; void monitorInit(); void keysInit(); @@ -259,15 +254,6 @@ uint32_t readTrims(); #define DBLKEYS_PRESSED_RGT_UP(in) (false) #define DBLKEYS_PRESSED_LFT_DWN(in) (false) -// WDT driver -extern uint32_t powerupReason; -extern uint32_t boardState; - -#define SHUTDOWN_REQUEST 0xDEADBEEF -#define NO_SHUTDOWN_REQUEST ~SHUTDOWN_REQUEST -#define DIRTY_SHUTDOWN 0xCAFEDEAD -#define NORMAL_POWER_OFF ~DIRTY_SHUTDOWN - #define WDG_DURATION 500 /*ms*/ void watchdogInit(unsigned int duration); #if defined(SIMU) @@ -332,6 +318,8 @@ enum CalibratedAnalogs { CALIBRATED_STICK4, CALIBRATED_POT1, CALIBRATED_POT2, + CALIBRATED_SLIDER_REAR_LEFT, + CALIBRATED_SLIDER_REAR_RIGHT, CALIBRATED_SWA, CALIBRATED_SWB, CALIBRATED_SWC, @@ -357,6 +345,45 @@ uint16_t getBatteryVoltage(); // returns current battery voltage in 10mV steps #define BATTERY_MIN 35 // 3.5V #define BATTERY_MAX 42 // 4.2V +enum EnumPowerupState +{ + BOARD_POWER_OFF = 0xCAFEDEAD, + BOARD_POWER_ON = 0xDEADBEEF, + BOARD_STARTED = 0xBAADF00D, + BOARD_REBOOT = 0xC00010FF, +}; + +extern uint32_t boardState; + +#if defined(__cplusplus) +enum PowerReason { + SHUTDOWN_REQUEST = 0xDEADBEEF, + SOFTRESET_REQUEST = 0xCAFEDEAD, +}; + +constexpr uint32_t POWER_REASON_SIGNATURE = 0x0178746F; + +inline bool UNEXPECTED_SHUTDOWN() +{ +#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN) + return false; +#else + if (WAS_RESET_BY_WATCHDOG()) + return true; + else if (WAS_RESET_BY_SOFTWARE()) + return RTC->BKP0R != SOFTRESET_REQUEST; + else + return RTC->BKP1R == POWER_REASON_SIGNATURE && RTC->BKP0R != SHUTDOWN_REQUEST; +#endif +} + +inline void SET_POWER_REASON(uint32_t value) +{ + RTC->BKP0R = value; + RTC->BKP1R = POWER_REASON_SIGNATURE; +} +#endif + #if defined(__cplusplus) && !defined(SIMU) extern "C" { #endif @@ -374,12 +401,15 @@ void pwrSoftReboot(); void pwrOff(); void pwrResetHandler(); bool pwrPressed(); -uint32_t pwrPressedDuration();; -#if defined(SIMU) || defined(NO_UNEXPECTED_SHUTDOWN) - #define UNEXPECTED_SHUTDOWN() (false) +#if defined(PWR_EXTRA_SWITCH_GPIO) + bool pwrForcePressed(); #else - #define UNEXPECTED_SHUTDOWN() (powerupReason == DIRTY_SHUTDOWN) + #define pwrForcePressed() false #endif +uint32_t pwrPressedDuration();; + +#define AUX_SERIAL_POWER_ON() +#define AUX_SERIAL_POWER_OFF() // LCD driver #define LCD_W 320 @@ -387,20 +417,19 @@ uint32_t pwrPressedDuration();; #define LCD_DEPTH 16 #define LCD_CONTRAST_DEFAULT 20 void lcdInit(); -void lcdNextLayer(); void lcdRefresh(); void lcdCopy(void * dest, void * src); void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color); void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint16_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h); void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t h, uint32_t format); +void lcdStoreBackupBuffer(); +int lcdRestoreBackupBuffer(); void lcdSetContrast(); void lcdOff(); void lcdOn(); #define lcdSetRefVolt(...) #define lcdRefreshWait(...) -void lcdStoreBackupBuffer(); -int lcdRestoreBackupBuffer(); // Backlight driver void backlightInit(); @@ -471,8 +500,8 @@ int32_t getVolume(); void telemetryPortInit(uint32_t baudrate, uint8_t mode); void telemetryPortSetDirectionOutput(); void telemetryPortSetDirectionInput(); -void sportSendBuffer(uint8_t * buffer, uint32_t count); -uint8_t telemetryGetByte(uint8_t * byte); +void sportSendBuffer(const uint8_t * buffer, uint32_t count); +bool telemetryGetByte(uint8_t * byte); void telemetryClearFifo(); void sportSendByte(uint8_t byte); extern uint32_t telemetryErrors; @@ -493,9 +522,13 @@ void hapticOff(); void hapticOn(uint32_t pwmPercent); // Second serial port driver -#define AUX_SERIAL +//#define AUX_SERIAL #define DEBUG_BAUDRATE 115200 +#define LUA_DEFAULT_BAUDRATE 115200 extern uint8_t auxSerialMode; +#if defined __cplusplus +void auxSerialSetup(unsigned int baudrate, bool dma, uint16_t length = USART_WordLength_8b, uint16_t parity = USART_Parity_No, uint16_t stop = USART_StopBits_1); +#endif void auxSerialInit(unsigned int mode, unsigned int protocol); void auxSerialPutc(char c); #define auxSerialTelemetryInit(protocol) auxSerialInit(UART_MODE_TELEMETRY, protocol) diff --git a/radio/src/targets/nv14/bootloader/boot_menu.cpp b/radio/src/targets/nv14/bootloader/boot_menu.cpp index 41d48140a..d6e521850 100644 --- a/radio/src/targets/nv14/bootloader/boot_menu.cpp +++ b/radio/src/targets/nv14/bootloader/boot_menu.cpp @@ -1,12 +1,26 @@ #include "opentx.h" #include "../../common/arm/stm32/bootloader/boot.h" #include "../../common/arm/stm32/bootloader/bin_files.h" + #define SELECTED_COLOR (INVERS | DEFAULT_COLOR) #define DEFAULT_PADDING 28 #define DOUBLE_PADDING 56 #define MESSAGE_TOP (LCD_H - (2*DOUBLE_PADDING)) -//#include "bmp_plug_usb.lbm" -//#include "bmp_usb_plugged.lbm" + +const uint8_t __bmp_plug_usb_rle[] { +#include "bmp_plug_usb.lbm" +}; +RLEBitmap BMP_PLUG_USB(BMP_ARGB4444, __bmp_plug_usb_rle); + +const uint8_t __bmp_usb_plugged_rle[] { +#include "bmp_usb_plugged.lbm" +}; +RLEBitmap BMP_USB_PLUGGED(BMP_ARGB4444, __bmp_usb_plugged_rle); + +const uint8_t __bmp_background_rle[] { +#include "bmp_background.lbm" +}; +RLEBitmap BMP_BACKGROUND(BMP_ARGB4444, __bmp_background_rle); const uint8_t LBM_FLASH[] = { #include "icon_flash.lbm" @@ -32,108 +46,146 @@ const uint8_t LBM_OK[] = { #include "icon_ok.lbm" }; +#define BL_GREEN COLOR2FLAGS(RGB(73, 219, 62)) +#define BL_RED COLOR2FLAGS(RED) +#define BL_BACKGROUND COLOR2FLAGS(BLACK) +#define BL_FOREGROUND COLOR2FLAGS(WHITE) +#define BL_SELECTED COLOR2FLAGS(RGB(11, 65, 244)) // deep blue + void bootloaderInitScreen() { - lcdColorTable[DEFAULT_COLOR_INDEX] = BLACK; - lcdColorTable[DEFAULT_BGCOLOR_INDEX] = WHITE; - lcdColorTable[LINE_COLOR_INDEX] = RED; - lcdColorTable[BARGRAPH1_COLOR_INDEX] = RED; - lcdColorTable[BARGRAPH2_COLOR_INDEX] = RGB(73, 219, 62); // green +// lcdColorTable[DEFAULT_COLOR_INDEX] = WHITE; +// lcdColorTable[DEFAULT_BGCOLOR_INDEX] = BLACK; +// lcdColorTable[LINE_COLOR_INDEX] = RED; +// lcdColorTable[BARGRAPH1_COLOR_INDEX] = RED; +// lcdColorTable[BARGRAPH2_COLOR_INDEX] = RGB(73, 219, 62); // green backlightEnable(BACKLIGHT_LEVEL_MAX); + + // TODO: load/decompress bitmaps + extern void loadFonts(); + loadFonts(); + } static void bootloaderDrawTitle(const char* text) { - lcd->drawText(LCD_W/2, DEFAULT_PADDING, text, CENTERED | DEFAULT_COLOR); - lcd->drawSolidFilledRect(DEFAULT_PADDING, DOUBLE_PADDING, LCD_W - DOUBLE_PADDING, 2, DEFAULT_COLOR); + lcd->drawText(LCD_W/2, DEFAULT_PADDING, text, CENTERED | BL_FOREGROUND); + lcd->drawSolidFilledRect(DEFAULT_PADDING, DOUBLE_PADDING, LCD_W - DOUBLE_PADDING, 2, BL_FOREGROUND); } static void bootloaderDrawFooter() { - lcd->drawSolidFilledRect(DEFAULT_PADDING, LCD_H - (DOUBLE_PADDING + 4), LCD_W - DOUBLE_PADDING, 2, DEFAULT_COLOR); + lcd->drawSolidFilledRect(DEFAULT_PADDING, LCD_H - (DOUBLE_PADDING + 4), LCD_W - DOUBLE_PADDING, 2, BL_FOREGROUND); +} + +static void bootloaderDrawBackground() +{ + // we have plenty of memory, let's cache that background + static BitmapBuffer* _background = nullptr; + + if (!_background) { + _background = new BitmapBuffer(BMP_RGB565, LCD_W, LCD_H); + + for (int i=0; idrawBitmap(i, j, &BMP_BACKGROUND); + } + } + _background->drawFilledRect(0, 0, LCD_W, LCD_H, SOLID, + COLOR2FLAGS(BLACK), OPACITY(4)); + } + + if (_background) { + lcd->drawBitmap(0, 0, _background); + } + else { + lcd->clear(BL_BACKGROUND); + } } void bootloaderDrawScreen(BootloaderState st, int opt, const char* str) { -#if defined(COLORLCD) - lcdNextLayer(); -#endif // clear screen - lcd->drawSolidFilledRect(0, 0, LCD_W-1, LCD_H-1, DEFAULT_BGCOLOR); + bootloaderDrawBackground(); + int center = LCD_W/2; if (st == ST_START) { - bootloaderDrawTitle("NV14 BOOTLOADER"); + bootloaderDrawTitle(BOOTLOADER_TITLE); - lcd->drawBitmapPattern(50, 72, LBM_FLASH, DEFAULT_COLOR); - lcd->drawText(84, 75, "Write Firmware"); + lcd->drawBitmapPattern(50, 72, LBM_FLASH, BL_FOREGROUND); + lcd->drawText(84, 75, "Write Firmware", BL_FOREGROUND); - lcd->drawBitmapPattern(50, 107, LBM_EXIT, DEFAULT_COLOR); - lcd->drawText(84, 110, "Exit"); + lcd->drawBitmapPattern(50, 107, LBM_EXIT, BL_FOREGROUND); + lcd->drawText(84, 110, "Exit", BL_FOREGROUND); - lcd->drawSolidRect(79, (opt == 0) ? 72 : 107, LCD_W - 79 - 28, 26, 2, LINE_COLOR); + lcd->drawSolidRect(79, (opt == 0) ? 72 : 107, LCD_W - 79 - 28, 26, 2, BL_SELECTED); - //lcd->drawBitmap(60, 166, &BMP_PLUG_USB); - lcd->drawText(center, 175, "Or plug in a USB cable", CENTERED | DEFAULT_COLOR); - lcd->drawText(center, 200, "for mass storage", CENTERED | DEFAULT_COLOR); + lcd->drawBitmap(center - 55, 165, &BMP_PLUG_USB); + lcd->drawText(center, 250, "Or plug in a USB cable", CENTERED | BL_FOREGROUND); + lcd->drawText(center, 275, "for mass storage", CENTERED | BL_FOREGROUND); bootloaderDrawFooter(); - lcd->drawText(center, LCD_H - DOUBLE_PADDING, "Current Firmware:", CENTERED | DEFAULT_COLOR); - lcd->drawText(center, LCD_H - DEFAULT_PADDING, getOtherVersion(nullptr), CENTERED | DEFAULT_COLOR); + lcd->drawText(center, LCD_H - DOUBLE_PADDING, "Current Firmware:", CENTERED | BL_FOREGROUND); + lcd->drawText(center, LCD_H - DEFAULT_PADDING, getFirmwareVersion(nullptr), CENTERED | BL_FOREGROUND); } else if (st == ST_USB) { - //lcd->drawBitmap(136, 98, &BMP_USB_PLUGGED); - lcd->drawText(center, 128, "USB Connected", CENTERED | DEFAULT_COLOR); + lcd->drawBitmap(center - 26, 98, &BMP_USB_PLUGGED); + lcd->drawText(center, 168, "USB Connected", CENTERED | BL_FOREGROUND); } else if (st == ST_FILE_LIST || st == ST_DIR_CHECK || st == ST_FLASH_CHECK || st == ST_FLASHING || st == ST_FLASH_DONE) { bootloaderDrawTitle("SD>FIRMWARE"); - lcd->drawBitmapPattern(DEFAULT_PADDING, 16, LBM_SD, DEFAULT_COLOR); + lcd->drawBitmapPattern(DEFAULT_PADDING, 16, LBM_SD, BL_FOREGROUND); if (st == ST_FLASHING || st == ST_FLASH_DONE) { - LcdFlags color = BARGRAPH1_COLOR; // red + LcdFlags color = BL_RED; // red if (st == ST_FLASH_DONE) { - color = BARGRAPH2_COLOR/* green */; + color = BL_GREEN/* green */; opt = 100; // Completed > 100% } - lcd->drawRect(DEFAULT_PADDING, 120, LCD_W - DOUBLE_PADDING, 31, 2); + lcd->drawRect(DEFAULT_PADDING, 120, LCD_W - DOUBLE_PADDING, 31, 2, SOLID, BL_SELECTED); lcd->drawSolidFilledRect(DEFAULT_PADDING+4, 124, ((LCD_W - DOUBLE_PADDING - 8) * opt) / 100, 23, color); } else if (st == ST_DIR_CHECK) { if (opt == FR_NO_PATH) { - lcd->drawText(20, MESSAGE_TOP, "Directory is missing"); + lcd->drawText(20, MESSAGE_TOP, "Directory is missing", BL_FOREGROUND); } else { - lcd->drawText(20, MESSAGE_TOP, "Directory is empty"); + lcd->drawText(20, MESSAGE_TOP, "Directory is empty", BL_FOREGROUND); } - lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BARGRAPH1_COLOR); + lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BL_RED); } else if (st == ST_FLASH_CHECK) { bootloaderDrawFilename(str, 0, true); if (opt == FC_ERROR) { - lcd->drawText(20, MESSAGE_TOP, STR_INVALID_FIRMWARE); - lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BARGRAPH1_COLOR); + lcd->drawText(20, MESSAGE_TOP, STR_INVALID_FIRMWARE, BL_FOREGROUND); + lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_ERROR, BL_RED); } else if (opt == FC_OK) { VersionTag tag; + memset(&tag, 0, sizeof(tag)); extractFirmwareVersion(&tag); - lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP, "Version:", RIGHT); - lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP, tag.version); + lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP - DEFAULT_PADDING, "Fork:", RIGHT | BL_FOREGROUND); + lcd->drawSizedText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP - DEFAULT_PADDING, tag.fork, 6, BL_FOREGROUND); + + lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP, "Version:", RIGHT | BL_FOREGROUND); + lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP, tag.version, BL_FOREGROUND); - lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, "Radio:", RIGHT); - lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, tag.flavour); + lcd->drawText(LCD_W/4 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, "Radio:", RIGHT | BL_FOREGROUND); + lcd->drawText(LCD_W/4 + 6 + DEFAULT_PADDING, MESSAGE_TOP + DEFAULT_PADDING, tag.flavour, BL_FOREGROUND); - lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_OK, BARGRAPH2_COLOR); + lcd->drawBitmapPattern(LCD_W - DOUBLE_PADDING, MESSAGE_TOP-10, LBM_OK, BL_GREEN); } } @@ -141,35 +193,35 @@ void bootloaderDrawScreen(BootloaderState st, int opt, const char* str) if ( st != ST_DIR_CHECK && (st != ST_FLASH_CHECK || opt == FC_OK)) { - lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DOUBLE_PADDING - 2, LBM_FLASH, DEFAULT_COLOR); + lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DOUBLE_PADDING - 2, LBM_FLASH, BL_FOREGROUND); if (st == ST_FILE_LIST) { - lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "[R TRIM] to select file"); + lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "[R TRIM] to select file", BL_FOREGROUND); } else if (st == ST_FLASH_CHECK && opt == FC_OK) { - lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Hold [R TRIM] long to flash"); + lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Hold [R TRIM] long to flash", BL_FOREGROUND); } else if (st == ST_FLASHING) { - lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Firmware ..."); + lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Firmware ...", BL_FOREGROUND); } else if (st == ST_FLASH_DONE) { - lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Completed"); + lcd->drawText(DOUBLE_PADDING, LCD_H - DOUBLE_PADDING, "Writing Completed", BL_FOREGROUND); } } if (st != ST_FLASHING) { - lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING - 2, LBM_EXIT, DEFAULT_COLOR); - lcd->drawText(DOUBLE_PADDING, LCD_H - DEFAULT_PADDING, "[L TRIM] to exit"); + lcd->drawBitmapPattern(DEFAULT_PADDING, LCD_H - DEFAULT_PADDING - 2, LBM_EXIT, BL_FOREGROUND); + lcd->drawText(DOUBLE_PADDING, LCD_H - DEFAULT_PADDING, "[L TRIM] to exit", BL_FOREGROUND); } } } void bootloaderDrawFilename(const char* str, uint8_t line, bool selected) { - lcd->drawBitmapPattern(DEFAULT_PADDING, 76 + (line * 25), LBM_FILE, DEFAULT_COLOR); - lcd->drawText(DEFAULT_PADDING + 30, 75 + (line * 25), str); + lcd->drawBitmapPattern(DEFAULT_PADDING, 76 + (line * 25), LBM_FILE, BL_FOREGROUND); + lcd->drawText(DEFAULT_PADDING + 30, 75 + (line * 25), str, BL_FOREGROUND); if (selected) { - lcd->drawSolidRect(DEFAULT_PADDING + 25, 72 + (line * 25), LCD_W - (DEFAULT_PADDING + 25) - 28, 26, 2, LINE_COLOR); + lcd->drawSolidRect(DEFAULT_PADDING + 25, 72 + (line * 25), LCD_W - (DEFAULT_PADDING + 25) - 28, 26, 2, BL_SELECTED); } } diff --git a/radio/src/targets/nv14/extmodule_driver.cpp b/radio/src/targets/nv14/extmodule_driver.cpp index aacaf9cfd..489f105f4 100644 --- a/radio/src/targets/nv14/extmodule_driver.cpp +++ b/radio/src/targets/nv14/extmodule_driver.cpp @@ -148,7 +148,7 @@ void extmodulePpmStart() NVIC_SetPriority(EXTMODULE_TIMER_IRQn, 7); } -void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted) +void extmoduleSerialStart() { } diff --git a/radio/src/targets/nv14/extmodule_helper.cpp b/radio/src/targets/nv14/extmodule_helper.cpp new file mode 100644 index 000000000..49c2d7d0d --- /dev/null +++ b/radio/src/targets/nv14/extmodule_helper.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * 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 "opentx.h" + +void EXTERNAL_MODULE_ON() +{ + GPIO_SetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN); + GPIO_ResetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN); +} + +void EXTERNAL_MODULE_OFF() +{ + GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN); + GPIO_SetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN); +} + +void extModuleInit() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN); + GPIO_Init(EXTMODULE_PWR_GPIO, &GPIO_InitStructure); + + //for additional transistor to ensuring module is completely disabled + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + //pin must be pulled to V+ (voltage of board - VCC is not enough to fully close transistor) + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_PWR_FIX_GPIO_PIN; + GPIO_SetBits(EXTMODULE_PWR_FIX_GPIO, EXTMODULE_PWR_FIX_GPIO_PIN); + GPIO_Init(EXTMODULE_PWR_FIX_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_INVERT_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(EXTMODULE_TX_INVERT_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = EXTMODULE_RX_INVERT_GPIO_PIN; + GPIO_Init(EXTMODULE_RX_INVERT_GPIO, &GPIO_InitStructure); + + GPIO_ResetBits(EXTMODULE_TX_INVERT_GPIO, EXTMODULE_TX_INVERT_GPIO_PIN); + GPIO_ResetBits(EXTMODULE_RX_INVERT_GPIO, EXTMODULE_RX_INVERT_GPIO_PIN); +} diff --git a/radio/src/targets/nv14/hal.h b/radio/src/targets/nv14/hal.h index a7a57b872..4d8f6f1b6 100644 --- a/radio/src/targets/nv14/hal.h +++ b/radio/src/targets/nv14/hal.h @@ -99,7 +99,7 @@ // ADC #define ADC_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_DMA2) #define ADC_RCC_APB2Periph (RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC3) -#if !defined(HALL_STICKS) +#if !defined(FLYSKY_HALL_STICKS) #define ADC_GPIO_PIN_STICK_LH GPIO_Pin_2 // PA.02 #define ADC_GPIO_PIN_STICK_LV GPIO_Pin_3 // PA.03 #define ADC_GPIO_PIN_STICK_RH GPIO_Pin_4 // PA.04 @@ -127,7 +127,7 @@ #define ADC_GPIOC_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_4 | GPIO_Pin_5) #define ADC_GPIOF_PINS (GPIO_Pin_8 | GPIO_Pin_10) -#if !defined(HALL_STICKS) +#if !defined(FLYSKY_HALL_STICKS) #define ADC_CHANNEL_STICK_LH ADC_Channel_2 // ADC123_IN2 -> ADC1_IN2 #define ADC_CHANNEL_STICK_LV ADC_Channel_3 // ADC123_IN3 -> ADC1_IN3 #define ADC_CHANNEL_STICK_RH ADC_Channel_4 // ADC12_IN4 -> ADC1_IN4 @@ -149,18 +149,29 @@ #define ADC_SUB ADC3 #define ADC_SAMPTIME 2 #define ADC_DMA DMA2 +#define ADC_DMA_SxCR_CHSEL 0 //DMA_SxCR_CHSEL_1 +#define ADC_DMA_Stream DMA2_Stream4 +#define ADC_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) +#define ADC_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) + +// NV14 customized drivers uses this #define ADC_MAIN_DMA_SxCR_CHSEL 0 // DMA_SxCR_CHSEL_1 -#define ADC_SUB_DMA_SxCR_CHSEL DMA_Channel_2 #define ADC_MAIN_DMA_Stream DMA2_Stream4 -#define ADC_SUB_DMA_Stream DMA2_Stream0 #define ADC_MAIN_SET_DMA_FLAGS() ADC_DMA->HIFCR = (DMA_HIFCR_CTCIF4 | DMA_HIFCR_CHTIF4 | DMA_HIFCR_CTEIF4 | DMA_HIFCR_CDMEIF4 | DMA_HIFCR_CFEIF4) -#define ADC_SUB_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_MAIN_TRANSFER_COMPLETE() (ADC_DMA->HISR & DMA_HISR_TCIF4) + +#define ADC_SUB_DMA_SxCR_CHSEL DMA_Channel_2 +#define ADC_SUB_DMA_Stream DMA2_Stream0 +#define ADC_SUB_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_SUB_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) +#define ADC_MAIN_SMPR1 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24); +#define ADC_MAIN_SMPR2 (ADC_SAMPTIME << 0) + (ADC_SAMPTIME << 3) + (ADC_SAMPTIME << 6) + (ADC_SAMPTIME << 9) + (ADC_SAMPTIME << 12) + (ADC_SAMPTIME << 15) + (ADC_SAMPTIME << 18) + (ADC_SAMPTIME << 21) + (ADC_SAMPTIME << 24) + (ADC_SAMPTIME << 27); + // Power #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOI -#define PWR_GPIO GPIOI +#define PWR_ON_GPIO GPIOI +#define PWR_SWITCH_GPIO GPIOI #define PWR_SWITCH_GPIO_REG PWR_GPIO->IDR #define PWR_SWITCH_GPIO_PIN GPIO_Pin_11 // PI.11 #define PWR_ON_GPIO_PIN GPIO_Pin_14 // PI.14 @@ -205,6 +216,11 @@ //used in BOOTLOADER #define SERIAL_RCC_AHB1Periph 0 #define SERIAL_RCC_APB1Periph 0 +#define AUX2_SERIAL_RCC_AHB1Periph 0 +#define AUX2_SERIAL_RCC_APB1Periph 0 +#define AUX2_SERIAL_RCC_APB2Periph 0 +#define KEYS_BACKLIGHT_RCC_AHB1Periph 0 + // Telemetry #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 @@ -357,14 +373,41 @@ #define HAPTIC_TIMER_MODE TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE #define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR1 +// Flysky Hall Stick +#if defined(FLYSKY_HALL_STICKS) + #define FLYSKY_HALL_SERIAL_USART UART4 + #define FLYSKY_HALL_SERIAL_GPIO GPIOA + #define FLYSKY_HALL_DMA_Channel DMA_Channel_4 + #define FLYSKY_HALL_SERIAL_TX_GPIO_PIN GPIO_Pin_0 // PA.00 + #define FLYSKY_HALL_SERIAL_RX_GPIO_PIN GPIO_Pin_1 // PA.01 + #define FLYSKY_HALL_SERIAL_TX_GPIO_PinSource GPIO_PinSource0 + #define FLYSKY_HALL_SERIAL_RX_GPIO_PinSource GPIO_PinSource1 + #define FLYSKY_HALL_SERIAL_GPIO_AF GPIO_AF_UART4 + + #define FLYSKY_HALL_RCC_AHB1Periph RCC_AHB1Periph_DMA1 + #define FLYSKY_HALL_RCC_APB1Periph RCC_APB1Periph_UART4 + + #define FLYSKY_HALL_SERIAL_USART_IRQHandler UART4_IRQHandler + #define FLYSKY_HALL_SERIAL_USART_IRQn UART4_IRQn + #define FLYSKY_HALL_SERIAL_RX_DMA_Stream_IRQn DMA1_Stream2_IRQn + #define FLYSKY_HALL_SERIAL_TX_DMA_Stream_IRQn DMA1_Stream4_IRQn + #define FLYSKY_HALL_DMA_Stream_RX DMA1_Stream2 + #define FLYSKY_HALL_DMA_Stream_TX DMA1_Stream4 + #define FLYSKY_HALL_DMA_TX_FLAG_TC DMA_IT_TCIF4 + + #define FLYSKY_HALL_RX_DMA_Stream_IRQHandler DMA1_Stream2_IRQHandler + #define FLYSKY_HALL_TX_DMA_Stream_IRQHandler DMA1_Stream4_IRQHandler +#endif + // Internal Module #define HARDWARE_INTERNAL_MODULE #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_DMA1) #define INTMODULE_PWR_GPIO GPIOH #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_9 // PH.09 -#define INTMODULE_TX_GPIO GPIOF +#define INTMODULE_GPIO GPIOF +//#define INTMODULE_TX_GPIO GPIOF #define INTMODULE_TX_GPIO_PIN GPIO_Pin_7 // PF.07 -#define INTMODULE_RX_GPIO GPIOF +//#define INTMODULE_RX_GPIO GPIOF #define INTMODULE_RX_GPIO_PIN GPIO_Pin_6 // PF.06 #define INTMODULE_GPIO_PinSource_TX GPIO_PinSource7 #define INTMODULE_GPIO_PinSource_RX GPIO_PinSource6 @@ -372,33 +415,34 @@ #define INTMODULE_GPIO_AF GPIO_AF_UART7 #define INTMODULE_USART_IRQn UART7_IRQn #define INTMODULE_USART_IRQHandler UART7_IRQHandler -#define INTMODULE_RX_DMA_STREAM DMA1_Stream3 +#define INTMODULE_DMA_STREAM DMA1_Stream1 +#define INTMODULE_DMA_STREAM_IRQ DMA1_Stream1_IRQn +#define INTMODULE_DMA_STREAM_IRQHandler DMA2_Stream7_IRQHandler +#define INTMODULE_DMA_FLAG_TC DMA_IT_TCIF1 +#define INTMODULE_DMA_CHANNEL DMA_Channel_5 + +/*#define INTMODULE_RX_DMA_STREAM DMA1_Stream3 #define INTMODULE_RX_DMA_Stream_IRQn DMA1_Stream3_IRQn #define INTMODULE_RX_DMA_Stream_IRQHandler DMA1_Stream3_IRQHandler #define INTMODULE_TX_DMA_STREAM DMA1_Stream1 #define INTMODULE_TX_DMA_Stream_IRQn DMA1_Stream1_IRQn #define INTMODULE_TX_DMA_Stream_IRQHandler DMA1_Stream1_IRQHandler -#define INTMODULE_TX_DMA_FLAG_TC DMA_IT_TCIF1 -//TX new implementation -#define INTMODULE_DMA_STREAM DMA1_Stream1 -#define INTMODULE_DMA_CHANNEL DMA_Channel_5 -#define INTMODULE_GPIO INTMODULE_TX_GPIO -//#define INTMODULE_DMA_STREAM_IRQ INTMODULE_RX_DMA_Stream_IRQHandler -#define INTMODULE_DMA_STREAM_IRQ INTMODULE_TX_DMA_Stream_IRQn - -#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_UART7 | RCC_APB1Periph_TIM3) +#define INTMODULE_TX_DMA_FLAG_TC DMA_IT_TCIF1*/ +#define INTMODULE_RCC_APB1Periph (RCC_APB1Periph_UART7 | RCC_APB1Periph_TIM3) #define INTMODULE_RCC_APB2Periph 0 #define INTMODULE_TIMER TIM3 #define INTMODULE_TIMER_IRQn TIM3_IRQn #define INTMODULE_TIMER_IRQHandler TIM3_IRQHandler #define INTMODULE_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) + // External Module #define EXTMODULE #define EXTMODULE_PULSES #define EXTMODULE_PWR_GPIO GPIOD #define EXTMODULE_PWR_GPIO_PIN GPIO_Pin_11 +#define EXTERNAL_MODULE_PWR_OFF() GPIO_ResetBits(EXTMODULE_PWR_GPIO, EXTMODULE_PWR_GPIO_PIN) #define EXTMODULE_PWR_FIX_GPIO GPIOA #define EXTMODULE_PWR_FIX_GPIO_PIN GPIO_Pin_2 // PA.02 #define EXTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_DMA2) @@ -416,9 +460,14 @@ #define EXTMODULE_RX_GPIO_AF_USART GPIO_AF_USART6 #define EXTMODULE_TIMER TIM8 #define EXTMODULE_TIMER_IRQn TIM8_CC_IRQn +#define EXTMODULE_TIMER_CC_IRQn TIM8_CC_IRQn #define EXTMODULE_TIMER_IRQHandler TIM8_CC_IRQHandler #define EXTMODULE_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) +#define EXTMODULE_TIMER_TX_GPIO_AF GPIO_AF_TIM8 //USART +#define EXTMODULE_USART_GPIO GPIOC +#define EXTMODULE_USART_GPIO_AF GPIO_AF_USART6 + #define EXTMODULE_USART_TX_DMA_CHANNEL DMA_Channel_5 #define EXTMODULE_USART_TX_DMA_STREAM DMA2_Stream7 #define EXTMODULE_USART_TX_DMA_IRQn DMA2_Stream7_IRQn @@ -427,26 +476,39 @@ #define EXTMODULE_USART_RX_DMA_CHANNEL DMA_Channel_5 #define EXTMODULE_USART_RX_DMA_STREAM DMA2_Stream2 -#define EXTMODULE_USART_RX_DMA_IRQn DMA2_Stream5_IRQn -#define EXTMODULE_USART_RX_DMA_IRQHandler DMA2_Stream5_IRQHandler -#define EXTMODULE_USART_RX_DMA_FLAG_TC DMA_IT_TCIF5 +#define EXTMODULE_USART_RX_DMA_IRQn DMA2_Stream2_IRQn +#define EXTMODULE_USART_RX_DMA_IRQHandler DMA2_Stream2_IRQHandler +#define EXTMODULE_USART_RX_DMA_FLAG_TC DMA_IT_TCIF2 #define EXTMODULE_USART_IRQHandler USART6_IRQHandler #define EXTMODULE_USART_IRQn USART6_IRQn +#define EXTMODULE_TIMER_DMA_SIZE (DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0) //TIMER #define EXTMODULE_DMA_CHANNEL DMA_Channel_7 #define EXTMODULE_DMA_STREAM DMA2_Stream1 #define EXTMODULE_DMA_IRQn DMA2_Stream1_IRQn #define EXTMODULE_DMA_IRQHandler DMA2_Stream1_IRQHandler #define EXTMODULE_DMA_FLAG_TC DMA_IT_TCIF1 -#define EXTMODULE_USART USART6 -#define EXTMODULE_TX_INVERT_GPIO GPIOE -#define EXTMODULE_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03 -#define EXTMODULE_RX_INVERT_GPIO GPIOI -#define EXTMODULE_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15 +#define EXTMODULE_TIMER_DMA_CHANNEL DMA_Channel_7 +#define EXTMODULE_TIMER_DMA_STREAM DMA2_Stream1 +#define EXTMODULE_TIMER_DMA_STREAM_IRQn DMA2_Stream1_IRQn +#define EXTMODULE_TIMER_DMA_IRQHandler DMA2_Stream1_IRQHandler +#define EXTMODULE_TIMER_DMA_FLAG_TC DMA_IT_TCIF1 +//#define EXTMODULE_USART USART6 + +#define EXTMODULE_TX_INVERT_GPIO GPIOE +#define EXTMODULE_TX_INVERT_GPIO_PIN GPIO_Pin_3 // PE.03 +#define EXTMODULE_RX_INVERT_GPIO GPIOI +#define EXTMODULE_RX_INVERT_GPIO_PIN GPIO_Pin_15 // PI.15 + + +#define EXTMODULE_TX_NORMAL() EXTMODULE_TX_INVERT_GPIO->BSRRH = EXTMODULE_TX_INVERT_GPIO_PIN +#define EXTMODULE_TX_INVERTED() EXTMODULE_TX_INVERT_GPIO->BSRRL = EXTMODULE_TX_INVERT_GPIO_PIN +#define EXTMODULE_RX_NORMAL() EXTMODULE_TX_INVERT_GPIO->BSRRH = EXTMODULE_RX_INVERT_GPIO_PIN +#define EXTMODULE_RX_INVERTED() EXTMODULE_TX_INVERT_GPIO->BSRRL = EXTMODULE_RX_INVERT_GPIO_PIN // Heartbeat (not used) #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD @@ -519,4 +581,11 @@ #define TIMER_2MHz_RCC_APB1Periph RCC_APB1Periph_TIM7 #define TIMER_2MHz_TIMER TIM7 +// Mixer scheduler timer +#define MIXER_SCHEDULER_TIMER_RCC_APB1Periph RCC_APB1Periph_TIM13 +#define MIXER_SCHEDULER_TIMER TIM13 +#define MIXER_SCHEDULER_TIMER_FREQ (PERI1_FREQUENCY * TIMER_MULT_APB1) +#define MIXER_SCHEDULER_TIMER_IRQn TIM8_UP_TIM13_IRQn +#define MIXER_SCHEDULER_TIMER_IRQHandler TIM8_UP_TIM13_IRQHandler + #endif // _HAL_H_ diff --git a/radio/src/targets/nv14/keys_driver.cpp b/radio/src/targets/nv14/keys_driver.cpp index 98512df67..3e4f530b3 100644 --- a/radio/src/targets/nv14/keys_driver.cpp +++ b/radio/src/targets/nv14/keys_driver.cpp @@ -24,9 +24,9 @@ uint32_t readKeys() { uint32_t result = 0; bool getKeys = true; -#if defined(LUA) +/*#if defined(LUA) getKeys = (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT); -#endif +#endif*/ //TODO: not sure why has LUA condition here, this construct is not in horus target if (getKeys) { if (TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL) result |= 1 << KEY_PGDN; @@ -57,11 +57,11 @@ uint32_t readTrims() { uint32_t result = 0; bool getTrim = true; -#if defined(LUA) +/*#if defined(LUA) if(luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) { getTrim = false; } -#endif +#endif*/ //TODO: not sure why has LUA condition here, this construct is not in horus target if(!getTrim) return result; if (TRIMS_GPIO_REG_LHL & TRIMS_GPIO_PIN_LHL) result |= 1 << (TRM_LH_DWN - TRM_BASE); diff --git a/radio/src/targets/nv14/lcd_driver.cpp b/radio/src/targets/nv14/lcd_driver.cpp index c1b19906f..5f5f89343 100644 --- a/radio/src/targets/nv14/lcd_driver.cpp +++ b/radio/src/targets/nv14/lcd_driver.cpp @@ -20,11 +20,21 @@ #include "opentx.h" +#define LCD_FIRST_LAYER 0 +#define LCD_SECOND_LAYER 1 + uint8_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; +uint8_t LCD_SCRATCH_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t currentLayer = LCD_FIRST_LAYER; +BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER); +BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_SECOND_FRAME_BUFFER); + +BitmapBuffer * lcdFront = &lcdBuffer1; +BitmapBuffer * lcd = &lcdBuffer2; + lcdSpiInitFucPtr lcdInitFunction; lcdSpiInitFucPtr lcdOffFunction; lcdSpiInitFucPtr lcdOnFunction; @@ -1178,24 +1188,37 @@ void LCD_Init_LTDC() { LTDC_Init(<DC_InitStruct); -#if 0 + //Configure IRQ + // LTDC_ITConfig(LTDC_IER_RRIE, ENABLE); + // NVIC_InitTypeDef NVIC_InitStructure; + // NVIC_InitStructure.NVIC_IRQChannel = LTDC_IRQn; + // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = LTDC_IRQ_PRIO; + // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; + // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + // NVIC_Init(&NVIC_InitStructure); + LTDC_ITConfig(LTDC_IER_LIE, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = LTDC_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = LTDC_IRQ_PRIO; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init( &NVIC_InitStructure ); + NVIC_Init(&NVIC_InitStructure); + LTDC_LIPConfig(LCD_H); +#if 0 DMA2D_ITConfig(DMA2D_CR_TCIE, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = DMA2D_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = DMA_SCREEN_IRQ_PRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pr e-emption priority. */; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); - DMA2D->IFCR = (unsigned long)DMA2D_IFSR_CTCIF; #endif + + // Enable LTDC IRQ in NVIC + NVIC_EnableIRQ(LTDC_IRQn); + NVIC_SetPriority(LTDC_IRQn, 7); } void LCD_LayerInit() { @@ -1246,56 +1269,52 @@ void LCD_LayerInit() { /* Initialize LTDC layer 1 */ LTDC_LayerInit(LTDC_Layer1, <DC_Layer_InitStruct); - /* Configure Layer 2 */ +#if defined(LTDC_DOUBLELAYER) + /* Configure Layer 2 */ LTDC_Layer_InitStruct.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA; LTDC_Layer_InitStruct.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA; /* Start Address configuration : the LCD Frame buffer is defined on SDRAM w/ Offset */ - LTDC_Layer_InitStruct.LTDC_CFBStartAdress = - (uint32_t) LCD_SECOND_FRAME_BUFFER; - + LTDC_Layer_InitStruct.LTDC_CFBStartAdress = (uint32_t) LCD_SECOND_FRAME_BUFFER; + /* Initialize LTDC layer 2 */ LTDC_LayerInit(LTDC_Layer2, <DC_Layer_InitStruct); - +#endif /* LTDC configuration reload */ - LTDC_ReloadConfig (LTDC_IMReload); - - LTDC_LayerCmd(LTDC_Layer1, ENABLE); - LTDC_LayerCmd(LTDC_Layer2, ENABLE); - LTDC_ReloadConfig(LTDC_IMReload); + LTDC_LayerCmd(LTDC_Layer1, ENABLE); + LTDC_LayerAlpha(LTDC_Layer1, 255); + +#if defined(LTDC_DOUBLELAYER) + LTDC_LayerCmd(LTDC_Layer2, ENABLE); + LTDC_LayerAlpha(LTDC_Layer2, 0); +#endif + + LTDC_ReloadConfig(LTDC_IMReload); /* dithering activation */ LTDC_DitherCmd(ENABLE); } -BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, - (uint16_t *) LCD_FIRST_FRAME_BUFFER); -BitmapBuffer lcdBuffer2(BMP_RGB565, LCD_W, LCD_H, - (uint16_t *) LCD_SECOND_FRAME_BUFFER); -BitmapBuffer * lcd = &lcdBuffer1; +extern void loadFonts(); -void LCD_SetLayer(uint32_t layer) { +void LCD_SetLayer(uint32_t layer) +{ if (layer == LCD_FIRST_LAYER) { - lcd = &lcdBuffer1; - } else { + lcdFront = &lcdBuffer1; lcd = &lcdBuffer2; } + else { + lcdFront = &lcdBuffer2; + lcd = &lcdBuffer1; + } currentLayer = layer; } -void LCD_SetTransparency(uint8_t transparency) -{ - if (currentLayer == LCD_FIRST_LAYER) { - LTDC_LayerAlpha(LTDC_Layer1, transparency); - } else { - LTDC_LayerAlpha(LTDC_Layer2, transparency); - } - LTDC_ReloadConfig (LTDC_IMReload); -} - -extern void loadFonts(); void lcdInit(void) { + // Clear buffers first + memset(LCD_FIRST_FRAME_BUFFER, 0, sizeof(LCD_FIRST_FRAME_BUFFER)); + memset(LCD_SECOND_FRAME_BUFFER, 0, sizeof(LCD_SECOND_FRAME_BUFFER)); loadFonts(); /* Configure the LCD SPI+RESET pins */ @@ -1306,7 +1325,7 @@ void lcdInit(void) { /* Configure the LCD Control pins */ LCD_AF_GPIOConfig(); - + /* Send LCD initializaiton commands */ if (LCD_ILI9481_ReadID() == LCD_ILI9481_ID) { TRACE("LCD INIT: ILI9481"); @@ -1337,23 +1356,11 @@ void lcdInit(void) { } lcdInitFunction(); - + LCD_Init_LTDC(); - LCD_LayerInit(); - - /* Enable LCD display */ LTDC_Cmd(ENABLE); - - /* Set Background layer */ - LCD_SetLayer (LCD_FIRST_LAYER); - // lcdClear(); - LCD_SetTransparency(0); - - /* Set Foreground layer */ - LCD_SetLayer (LCD_SECOND_LAYER); - lcd->clear(); - LCD_SetTransparency(255); + LTDC_ReloadConfig(LTDC_IMReload); } void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) @@ -1376,6 +1383,10 @@ void DMAFillRect(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, ui /* Start Transfer */ DMA2D_StartTransfer(); + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + /* Wait for CTC Flag activation */ while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } @@ -1409,6 +1420,10 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, /* Start Transfer */ DMA2D_StartTransfer(); + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + /* Wait for CTC Flag activation */ while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } @@ -1451,6 +1466,61 @@ void DMACopyAlphaBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_ /* Start Transfer */ DMA2D_StartTransfer(); + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + + /* Wait for CTC Flag activation */ + while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); +} + +// same as DMACopyAlphaBitmap(), but with an 8 bit mask for each pixel (used by fonts) +void DMACopyAlphaMask(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, uint16_t y, const uint8_t * src, uint16_t srcw, uint16_t srch, uint16_t srcx, uint16_t srcy, uint16_t w, uint16_t h, uint16_t bg_color) +{ + DMA2D_DeInit(); + + DMA2D_InitTypeDef DMA2D_InitStruct; + DMA2D_InitStruct.DMA2D_Mode = DMA2D_M2M_BLEND; + DMA2D_InitStruct.DMA2D_CMode = CM_RGB565; + DMA2D_InitStruct.DMA2D_OutputMemoryAdd = CONVERT_PTR_UINT(dest + y*destw + x); + DMA2D_InitStruct.DMA2D_OutputBlue = 0; + DMA2D_InitStruct.DMA2D_OutputGreen = 0; + DMA2D_InitStruct.DMA2D_OutputRed = 0; + DMA2D_InitStruct.DMA2D_OutputAlpha = 0; + DMA2D_InitStruct.DMA2D_OutputOffset = destw - w; + DMA2D_InitStruct.DMA2D_NumberOfLine = h; + DMA2D_InitStruct.DMA2D_PixelPerLine = w; + DMA2D_Init(&DMA2D_InitStruct); + + DMA2D_FG_InitTypeDef DMA2D_FG_InitStruct; + DMA2D_FG_StructInit(&DMA2D_FG_InitStruct); + DMA2D_FG_InitStruct.DMA2D_FGMA = CONVERT_PTR_UINT(src + srcy*srcw + srcx); + DMA2D_FG_InitStruct.DMA2D_FGO = srcw - w; + DMA2D_FG_InitStruct.DMA2D_FGCM = CM_A8; // 8 bit inputs every time + DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE; + DMA2D_FG_InitStruct.DMA2D_FGPFC_ALPHA_VALUE = 0; + DMA2D_FG_InitStruct.DMA2D_FGC_RED = GET_RED(bg_color); // 8 bit red + DMA2D_FG_InitStruct.DMA2D_FGC_GREEN = GET_GREEN(bg_color); // 8 bit green + DMA2D_FG_InitStruct.DMA2D_FGC_BLUE = GET_BLUE(bg_color); // 8 bit blue + + DMA2D_FGConfig(&DMA2D_FG_InitStruct); + + DMA2D_BG_InitTypeDef DMA2D_BG_InitStruct; + DMA2D_BG_StructInit(&DMA2D_BG_InitStruct); + DMA2D_BG_InitStruct.DMA2D_BGMA = CONVERT_PTR_UINT(dest + y*destw + x); + DMA2D_BG_InitStruct.DMA2D_BGO = destw - w; + DMA2D_BG_InitStruct.DMA2D_BGCM = CM_RGB565; + DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_MODE = NO_MODIF_ALPHA_VALUE; + DMA2D_BG_InitStruct.DMA2D_BGPFC_ALPHA_VALUE = 0; + DMA2D_BGConfig(&DMA2D_BG_InitStruct); + + /* Start Transfer */ + DMA2D_StartTransfer(); + + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + /* Wait for CTC Flag activation */ while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } @@ -1484,6 +1554,10 @@ void DMABitmapConvert(uint16_t * dest, const uint8_t * src, uint16_t w, uint16_t /* Start Transfer */ DMA2D_StartTransfer(); + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + /* Wait for CTC Flag activation */ while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } @@ -1517,6 +1591,10 @@ void lcdCopy(void * dest, void * src) /* Start Transfer */ DMA2D_StartTransfer(); + /* Check configuration error */ + if ((DMA2D_GetFlagStatus(DMA2D_FLAG_CE) == SET) || (DMA2D_GetFlagStatus(DMA2D_FLAG_TE) == SET)) + return; // Exit if configuration or transfer error + /* Wait for CTC Flag activation */ while (DMA2D_GetFlagStatus(DMA2D_FLAG_TC) == RESET); } @@ -1532,27 +1610,46 @@ int lcdRestoreBackupBuffer() return 1; } -void lcdRefresh() +uint16_t* lcdGetBackupBuffer() { - if (currentLayer == LCD_FIRST_LAYER) { - LTDC_LayerAlpha(LTDC_Layer1, 255); - LTDC_LayerAlpha(LTDC_Layer2, 0); - } - else { - LTDC_LayerAlpha(LTDC_Layer1, 0); - LTDC_LayerAlpha(LTDC_Layer2, 255); - } - LTDC_ReloadConfig(LTDC_IMReload); + return (uint16_t*)LCD_BACKUP_FRAME_BUFFER; } -void lcdNextLayer() +uint16_t* lcdGetScratchBuffer() +{ + return (uint16_t*)LCD_SCRATCH_FRAME_BUFFER; +} + +//static volatile uint8_t refreshRequested = 0; +static volatile uint8_t _frameBufferAddressReloaded = 0; + +extern "C" void LTDC_IRQHandler(void) +{ + LTDC_ClearFlag(LTDC_ICR_CLIF); + _frameBufferAddressReloaded = 1; +} + +static void lcdSwitchLayers() { if (currentLayer == LCD_FIRST_LAYER) { + LTDC_Layer1->CFBAR = (uint32_t)LCD_SECOND_FRAME_BUFFER; LCD_SetLayer(LCD_SECOND_LAYER); } else { + LTDC_Layer1->CFBAR = (uint32_t)LCD_FIRST_FRAME_BUFFER; LCD_SetLayer(LCD_FIRST_LAYER); } + + // reload shadow registers on vertical blank + _frameBufferAddressReloaded = 0; + LTDC->SRCR = LTDC_SRCR_VBR; + + // wait for reload + // TODO: replace through some smarter mechanism without busy wait + while(_frameBufferAddressReloaded == 0); } - +void lcdRefresh() +{ + lcdSwitchLayers(); +} diff --git a/radio/src/targets/nv14/lcd_driver.h b/radio/src/targets/nv14/lcd_driver.h index bc348984e..32b9d7079 100644 --- a/radio/src/targets/nv14/lcd_driver.h +++ b/radio/src/targets/nv14/lcd_driver.h @@ -32,9 +32,6 @@ #define HFP ( 140 - HBP ) #define VFP ( 22 - VBP ) -#define LCD_FIRST_LAYER ( 0 ) -#define LCD_SECOND_LAYER ( 1 ) - #define PORT_LCD_CS ( GPIOE ) #define LCD_CS_PIN ( GPIO_Pin_4 ) diff --git a/radio/src/targets/nv14/libopenui_config.h b/radio/src/targets/nv14/libopenui_config.h index 50a1606d5..f23ad216b 100644 --- a/radio/src/targets/nv14/libopenui_config.h +++ b/radio/src/targets/nv14/libopenui_config.h @@ -18,19 +18,34 @@ * GNU General Public License for more details. */ -#ifndef _LIBOPENUI_CONFIG_H_ -#define _LIBOPENUI_CONFIG_H_ +#pragma once #include "debug.h" #include "libopenui_defines.h" + #include "colors.h" #include "board.h" #include "keys.h" +enum FontIndex +{ + FONT_STD_INDEX, +#if !defined(BOLD) + FONT_BOLD_INDEX, + FONT_XXS_INDEX, + FONT_XS_INDEX, + FONT_L_INDEX, + FONT_XL_INDEX, + FONT_XXL_INDEX, +#endif + + FONTS_COUNT +}; + typedef uint16_t pixel_t; constexpr bool WRAP_FORM_FIELDS_WITHIN_PAGE = true; -constexpr uint32_t SLIDE_SPEED_REDUCTION = 5; +constexpr short SLIDE_SPEED_REDUCTION = 5; constexpr uint32_t MENU_HEADER_BUTTON_WIDTH = 60; constexpr uint32_t MENU_HEADER_BUTTONS_LEFT = MENU_HEADER_BUTTON_WIDTH; @@ -45,7 +60,7 @@ constexpr uint32_t MENU_FOOTER_TOP = LCD_H - MENU_FOOTER_HEIGHT; constexpr uint32_t MENU_BODY_HEIGHT = MENU_FOOTER_TOP - MENU_BODY_TOP; constexpr uint32_t MENUS_MARGIN_LEFT = 6; -constexpr uint32_t PAGE_PADDING = 8; +constexpr coord_t PAGE_PADDING = 8; constexpr uint32_t PAGE_LINE_HEIGHT = 26; constexpr uint32_t PAGE_LINE_SPACING = 6; constexpr uint32_t PAGE_INDENT_WIDTH = 10; @@ -86,7 +101,7 @@ constexpr uint32_t ALERT_BUTTON_TOP = 300; constexpr uint32_t PAGE_TITLE_TOP = 4; constexpr uint32_t PAGE_TITLE_LEFT = 70; -enum LcdColorIndex +/*enum LcdColorIndex { DEFAULT_COLOR_INDEX, DEFAULT_BGCOLOR_INDEX, @@ -130,21 +145,8 @@ enum LcdColorIndex TABLE_HEADER_BGCOLOR_INDEX, TABLE_BGCOLOR_INDEX, -}; +};*/ -enum FontIndex -{ - FONT_STD_INDEX, -#if !defined(BOLD) - FONT_BOLD_INDEX, - FONT_XXS_INDEX, - FONT_XS_INDEX, - FONT_L_INDEX, - FONT_XL_INDEX, - FONT_XXL_INDEX, -#endif - FONTS_COUNT -}; constexpr uint32_t INPUT_EDIT_LABELS_WIDTH = 80; constexpr coord_t INPUT_EDIT_CURVE_WIDTH = LCD_W; @@ -175,4 +177,3 @@ constexpr LcdFlags TABLE_BODY_FONT = FONT(STD); constexpr int CJK_FIRST_LETTER_INDEX = 128 - 32 + 21; constexpr coord_t CHAR_SPACING = 0; -#endif // _LIBOPENUI_CONFIG_H_ diff --git a/radio/src/targets/nv14/pwr_driver.cpp b/radio/src/targets/nv14/pwr_driver.cpp index b78cf7f3f..16c447ff3 100644 --- a/radio/src/targets/nv14/pwr_driver.cpp +++ b/radio/src/targets/nv14/pwr_driver.cpp @@ -21,7 +21,6 @@ #include "pwr.h" #include "board.h" -uint32_t powerupReason __NOINIT; // Stores power up reason beyond initialization for emergency mode activation uint32_t boardState __NOINIT; void pwrInit() @@ -32,13 +31,13 @@ void pwrInit() GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(PWR_GPIO, &GPIO_InitStructure); + GPIO_Init(PWR_ON_GPIO, &GPIO_InitStructure); // TODO move this elsewhere! // Init Module PWR - //GPIO_ResetBits(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN); - //GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_GPIO_PIN; - //GPIO_Init(INTMODULE_PWR_GPIO, &GPIO_InitStructure); + //GPIO_ResetBits(INTMODULE_PWR_ON_GPIO, INTMODULE_PWR_ON_GPIO_PIN); + //GPIO_InitStructure.GPIO_Pin = INTMODULE_PWR_ON_GPIO_PIN; + //GPIO_Init(INTMODULE_PWR_ON_GPIO, &GPIO_InitStructure); //Bluetooth GPIO_SetBits(BLUETOOTH_ON_GPIO, BLUETOOTH_ON_GPIO_PIN); @@ -48,7 +47,7 @@ void pwrInit() // Init PWR SWITCH PIN GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_Pin = PWR_SWITCH_GPIO_PIN; - GPIO_Init(PWR_GPIO, &GPIO_InitStructure); + GPIO_Init(PWR_ON_GPIO, &GPIO_InitStructure); // Init SD-DETECT PIN GPIO_ResetBits(SD_PRESENT_GPIO, SD_PRESENT_GPIO_PIN); @@ -56,16 +55,16 @@ void pwrInit() GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure); //turn power off - GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN); + GPIO_ResetBits(PWR_ON_GPIO, PWR_ON_GPIO_PIN); //turn Bluetooth off - GPIO_ResetBits(PWR_GPIO, BLUETOOTH_ON_GPIO_PIN); + GPIO_ResetBits(PWR_ON_GPIO, BLUETOOTH_ON_GPIO_PIN); boardState = BOARD_POWER_OFF; } void pwrOn() { - GPIO_SetBits(PWR_GPIO, PWR_ON_GPIO_PIN); + GPIO_SetBits(PWR_ON_GPIO, PWR_ON_GPIO_PIN); boardState = BOARD_POWER_ON; } @@ -78,21 +77,17 @@ void pwrOff() // Shutdown the Haptic hapticDone(); boardState = BOARD_POWER_OFF; - GPIO_ResetBits(PWR_GPIO, PWR_ON_GPIO_PIN); + GPIO_ResetBits(PWR_ON_GPIO, PWR_ON_GPIO_PIN); } bool pwrPressed() { - return GPIO_ReadInputDataBit(PWR_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET; + return GPIO_ReadInputDataBit(PWR_ON_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET; } void pwrResetHandler() { if (boardState != BOARD_POWER_OFF) { - powerupReason = boardState != BOARD_REBOOT && WAS_RESET_BY_WATCHDOG_OR_SOFTWARE() ? DIRTY_SHUTDOWN : ~DIRTY_SHUTDOWN; RCC->CSR |= RCC_CSR_RMVF; //clear all flags } - else { - powerupReason = ~DIRTY_SHUTDOWN; - } } diff --git a/radio/src/targets/nv14/telemetry_driver.cpp b/radio/src/targets/nv14/telemetry_driver.cpp index 2e440380c..adf82c752 100644 --- a/radio/src/targets/nv14/telemetry_driver.cpp +++ b/radio/src/targets/nv14/telemetry_driver.cpp @@ -94,10 +94,10 @@ void telemetryPortInvertedInit(uint32_t baudrate) #warning "TODO telemetryPortInvertedInit"; } -void extmoduleSendInvertedByte(uint8_t byte) +/*void extmoduleSendInvertedByte(uint8_t byte) { #warning "TODO extmoduleSendInvertedByte"; -} +}*/ void telemetryPortSetDirectionOutput() { @@ -117,7 +117,7 @@ void sportSendByte(uint8_t byte) USART_SendData(TELEMETRY_USART, byte); } -void sportSendBuffer(uint8_t * buffer, uint32_t count) +void sportSendBuffer(const uint8_t * buffer, uint32_t count) { telemetryPortSetDirectionOutput(); @@ -197,7 +197,7 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) } // TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -uint8_t telemetryGetByte(uint8_t * byte) +bool telemetryGetByte(uint8_t * byte) { #if defined(PCBX12S) if (telemetryFifoMode & TELEMETRY_SERIAL_WITHOUT_DMA) diff --git a/radio/src/targets/nv14/touch_driver.cpp b/radio/src/targets/nv14/touch_driver.cpp index d93829674..f92d4c52a 100644 --- a/radio/src/targets/nv14/touch_driver.cpp +++ b/radio/src/targets/nv14/touch_driver.cpp @@ -468,12 +468,10 @@ void handleTouch() touchState.x = touchX; touchState.y = touchY; - if (touchState.event == TE_NONE || touchState.event == TE_UP) { + if (touchState.event == TE_NONE || touchState.event == TE_UP || touchState.event == TE_SLIDE_END) { touchState.startX = touchState.x; touchState.startY = touchState.y; touchState.event = TE_DOWN; - if (g_eeGeneral.backlightMode & e_backlight_mode_keys) - backlightOn(); // TODO is that the best place ? } else if (touchState.event == TE_DOWN) { if (dx >= SLIDE_RANGE || dx <= -SLIDE_RANGE || dy >= SLIDE_RANGE || dy <= -SLIDE_RANGE) { diff --git a/radio/src/targets/taranis/board.cpp b/radio/src/targets/taranis/board.cpp index 69e36d5e8..03b6c4c84 100644 --- a/radio/src/targets/taranis/board.cpp +++ b/radio/src/targets/taranis/board.cpp @@ -163,7 +163,7 @@ void boardInit() lcdInit(); // delaysInit() must be called before audioInit(); init2MhzTimer(); - init5msTimer(); + init1msTimer(); __enable_irq(); i2cInit(); usbInit(); diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index 8e583be73..c01c83046 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -62,7 +62,7 @@ void boardOff(); // Timers driver void init2MhzTimer(); -void init5msTimer(); +void init1msTimer(); // PCBREV driver enum { diff --git a/radio/src/tests/bitmap_320x480.png b/radio/src/tests/bitmap_320x480.png new file mode 100644 index 000000000..f9396282f Binary files /dev/null and b/radio/src/tests/bitmap_320x480.png differ diff --git a/radio/src/tests/bitmap_480x272.png b/radio/src/tests/bitmap_480x272.png index a9148109c..f546ecd6c 100644 Binary files a/radio/src/tests/bitmap_480x272.png and b/radio/src/tests/bitmap_480x272.png differ diff --git a/radio/src/tests/clipping_320x480.png b/radio/src/tests/clipping_320x480.png new file mode 100644 index 000000000..1e74f1478 Binary files /dev/null and b/radio/src/tests/clipping_320x480.png differ diff --git a/radio/src/tests/clipping_480x272.png b/radio/src/tests/clipping_480x272.png index 5a90991cb..c72845365 100644 Binary files a/radio/src/tests/clipping_480x272.png and b/radio/src/tests/clipping_480x272.png differ diff --git a/radio/src/tests/darkmode_EN_320x480.png b/radio/src/tests/darkmode_EN_320x480.png new file mode 100644 index 000000000..7868be171 Binary files /dev/null and b/radio/src/tests/darkmode_EN_320x480.png differ diff --git a/radio/src/tests/lines_320x480.png b/radio/src/tests/lines_320x480.png new file mode 100644 index 000000000..49907b7b0 Binary files /dev/null and b/radio/src/tests/lines_320x480.png differ diff --git a/radio/src/tests/lines_480x272.png b/radio/src/tests/lines_480x272.png index 86c6ceb11..398345c81 100644 Binary files a/radio/src/tests/lines_480x272.png and b/radio/src/tests/lines_480x272.png differ diff --git a/radio/src/tests/masks_320x480.png b/radio/src/tests/masks_320x480.png new file mode 100644 index 000000000..77bdb2191 Binary files /dev/null and b/radio/src/tests/masks_320x480.png differ diff --git a/radio/src/tests/masks_480x272.png b/radio/src/tests/masks_480x272.png index e6a8c0873..e602c58a7 100644 Binary files a/radio/src/tests/masks_480x272.png and b/radio/src/tests/masks_480x272.png differ diff --git a/radio/src/tests/primitives_CN_480x272.png b/radio/src/tests/primitives_CN_480x272.png index b99ee6ff7..94e283bab 100644 Binary files a/radio/src/tests/primitives_CN_480x272.png and b/radio/src/tests/primitives_CN_480x272.png differ diff --git a/radio/src/tests/primitives_EN_320x480.png b/radio/src/tests/primitives_EN_320x480.png new file mode 100644 index 000000000..46c993e01 Binary files /dev/null and b/radio/src/tests/primitives_EN_320x480.png differ diff --git a/radio/src/tests/primitives_EN_480x272.png b/radio/src/tests/primitives_EN_480x272.png index e67c6199c..8a27da53a 100644 Binary files a/radio/src/tests/primitives_EN_480x272.png and b/radio/src/tests/primitives_EN_480x272.png differ diff --git a/radio/src/tests/transparency_CN_480x272.png b/radio/src/tests/transparency_CN_480x272.png index a6ee82449..f35e22130 100644 Binary files a/radio/src/tests/transparency_CN_480x272.png and b/radio/src/tests/transparency_CN_480x272.png differ diff --git a/radio/src/tests/transparency_EN_320x480.png b/radio/src/tests/transparency_EN_320x480.png new file mode 100644 index 000000000..899a7364c Binary files /dev/null and b/radio/src/tests/transparency_EN_320x480.png differ diff --git a/radio/src/tests/transparency_EN_480x272.png b/radio/src/tests/transparency_EN_480x272.png index 301584068..25b69c9d3 100644 Binary files a/radio/src/tests/transparency_EN_480x272.png and b/radio/src/tests/transparency_EN_480x272.png differ diff --git a/radio/src/tests/vline_320x480.png b/radio/src/tests/vline_320x480.png new file mode 100644 index 000000000..9ff6dcf16 Binary files /dev/null and b/radio/src/tests/vline_320x480.png differ diff --git a/radio/src/tests/vline_480x272.png b/radio/src/tests/vline_480x272.png index 7947a4f9b..9357cc152 100644 Binary files a/radio/src/tests/vline_480x272.png and b/radio/src/tests/vline_480x272.png differ diff --git a/radio/src/translations.h b/radio/src/translations.h index 84fa3f02d..74f3d3399 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -166,6 +166,7 @@ extern const char STR_XJT_ACCST_RF_PROTOCOLS[]; extern const char STR_ISRM_RF_PROTOCOLS[]; extern const char STR_R9M_PXX2_RF_PROTOCOLS[]; extern const char STR_DSM_PROTOCOLS[]; +extern const char STR_FLYSKY_PROTOCOLS[]; extern const char STR_CRSF_BAUDRATE[]; extern const char STR_PPM_POL[]; extern const char STR_SBUS_INVERSION_VALUES[]; diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index a734e63c6..cb85b7825 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -111,10 +111,10 @@ #endif #define LEN_EXTERNAL_MODULE_PROTOCOLS "\014" -#define TR_EXTERNAL_MODULE_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""ISRM\0 ""DSM2\0 ""CRSF\0 ""MULTI\0 ""R9M\0 ""R9M ACCESS\0 " TR_MODULE_R9M_LITE "R9ML ACCESS\0""GHST\0 ""R9MLP ACCESS""SBUS\0 ""XJT Lite\0 ""AFHDS3\0 " +#define TR_EXTERNAL_MODULE_PROTOCOLS "OFF\0 ""PPM\0 ""XJT\0 ""ISRM\0 ""DSM2\0 ""CRSF\0 ""MULTI\0 ""R9M\0 ""R9M ACCESS\0 " TR_MODULE_R9M_LITE "R9ML ACCESS\0""GHST\0 ""R9MLP ACCESS""SBUS\0 ""XJT Lite\0 ""FLYSKY\0 " -#define LEN_FLYSKY_PROTOCOLS "\006" -#define TR_FLYSKY_PROTOCOLS +#define LEN_FLYSKY_PROTOCOLS "\007" +#define TR_FLYSKY_PROTOCOLS "AFHDS3\0""AFHDS2A" #define LEN_INTERNAL_MODULE_PROTOCOLS LEN_EXTERNAL_MODULE_PROTOCOLS #define TR_INTERNAL_MODULE_PROTOCOLS TR_EXTERNAL_MODULE_PROTOCOLS diff --git a/tools/build-flysky.py b/tools/build-flysky.py new file mode 100644 index 000000000..0ac9936b2 --- /dev/null +++ b/tools/build-flysky.py @@ -0,0 +1,73 @@ +#!/usr/bin/python3 + +import argparse +import datetime +import os +from builtins import NotADirectoryError +import shutil +import tempfile + + +boards = { + "NV14": { + "PCB": "NV14", + "DEFAULT_MODE": "1", + }, +} + +translations = [ + "EN", +] + + +def timestamp(): + return datetime.datetime.now().strftime("%y%m%d") + + +def build(board, translation, srcdir): + cmake_options = " ".join(["-D%s=%s" % (key, value) for key, value in boards[board].items()]) + cwd = os.getcwd() + if not os.path.exists("output"): + os.mkdir("output") + path = tempfile.mkdtemp() + os.chdir(path) + command = "cmake %s -DTRANSLATIONS=%s %s" % (cmake_options, translation, srcdir) + print(command) + os.system(command) + os.system("make firmware -j16") + os.system("make simu -j16") + os.system("make tests-radio -j16") + os.chdir(cwd) + index = 0 + while 1: + suffix = "" if index == 0 else "_%d" % index + filename = "output/firmware_%s_%s_%s%s.bin" % (board.lower(), translation.lower(), timestamp(), suffix) + if not os.path.exists(filename): + shutil.copy("%s/firmware.bin" % path, filename) + break + index += 1 + shutil.rmtree(path) + + +def dir_path(string): + if os.path.isdir(string): + return string + else: + raise NotADirectoryError(string) + + +def main(): + parser = argparse.ArgumentParser(description="Build Flysky firmware") + parser.add_argument("-b", "--boards", action="append", help="Destination boards", required=True) + parser.add_argument("-t", "--translations", action="append", help="Translations", required=True) + parser.add_argument("srcdir", type=dir_path) + + args = parser.parse_args() + + for board in (boards.keys() if "ALL" in args.boards else args.boards): + for translation in (translations if "ALL" in args.translations else args.translations): + build(board, translation, args.srcdir) + + +if __name__ == "__main__": + main() diff --git a/tools/build-gh.sh b/tools/build-gh.sh index 528024fa8..78e71f6f2 100755 --- a/tools/build-gh.sh +++ b/tools/build-gh.sh @@ -122,7 +122,7 @@ case $FLAVOR in BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T16 -DINTERNAL_MODULE_MULTI=ON" ;; T16_FS) - BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T16 -DFLYSKY_HALL_STICKS=ON" + BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T16 -DINTERNAL_MODULE_MULTI=ON -DFLYSKY_HALL_STICKS=ON" ;; T18) BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=T18" @@ -136,6 +136,9 @@ case $FLAVOR in TX16S_FS) BUILD_OPTIONS+="-DPCB=X10 -DPCBREV=TX16S -DFLYSKY_HALL_STICKS=ON" ;; + NV14) + BUILD_OPTIONS+="-DPCB=NV14" + ;; esac cmake ${BUILD_OPTIONS} "${SRCDIR}" diff --git a/tools/build-jumper.py b/tools/build-jumper.py index b6dd3b8b8..436b2b23d 100755 --- a/tools/build-jumper.py +++ b/tools/build-jumper.py @@ -43,7 +43,7 @@ boards = { "PCBREV": "T18", "INTERNAL_MODULE_MULTI": "YES", "DEFAULT_MODE": "2", - } + }, "T18_FS": { "PCB": "X10", "PCBREV": "T18",