diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 14f24ccba..4b6488e1e 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -353,6 +353,8 @@ elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T16) set(FLAVOUR t16) elseif(PCB STREQUAL X10 AND PCBREV STREQUAL TX16S) set(FLAVOUR tx16s) +elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T18) + set(FLAVOUR t18) else() string(TOLOWER ${PCB} FLAVOUR) endif() diff --git a/radio/src/bitmaps/480x272/CMakeLists.txt b/radio/src/bitmaps/480x272/CMakeLists.txt index 9337292af..4ae20e970 100644 --- a/radio/src/bitmaps/480x272/CMakeLists.txt +++ b/radio/src/bitmaps/480x272/CMakeLists.txt @@ -1,6 +1,9 @@ if(PCB STREQUAL X12S) set(BITMAP_TARGET_PREFIX x12s) set(BITMAP_FMT_SUFFIX "") +elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T18) + set(BITMAP_TARGET_PREFIX x10) + set(BITMAP_FMT_SUFFIX "") else() set(BITMAP_TARGET_PREFIX x10) set(BITMAP_FMT_SUFFIX "-R") diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 9c5e1b652..f0f7941e4 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -739,7 +739,12 @@ PACK(struct RadioData { uint8_t backlightMode:3; int8_t antennaMode:2; uint8_t disableRtcWarning:1; +#if defined(KEYS_BACKLIGHT_GPIO) + uint8_t keyBacklight:1; + int8_t spare1:1; +#else int8_t spare1:2; +#endif NOBACKUP(TrainerData trainer); NOBACKUP(uint8_t view); // index of view in main screen NOBACKUP(BUZZER_FIELD); /* 2bits */ diff --git a/radio/src/gui/480x272/bitmapbuffer.h b/radio/src/gui/480x272/bitmapbuffer.h index 760215198..2a77fbaca 100644 --- a/radio/src/gui/480x272/bitmapbuffer.h +++ b/radio/src/gui/480x272/bitmapbuffer.h @@ -25,7 +25,7 @@ #include "colors.h" #include "rle.h" -#if defined(PCBX10) && !defined(SIMU) +#if defined(LCD_VERTICAL_INVERT) #define MOVE_PIXEL_RIGHT(p, count) p -= count #else #define MOVE_PIXEL_RIGHT(p, count) p += count @@ -92,7 +92,7 @@ class BitmapBufferBase inline const display_t * getPixelPtr(coord_t x, coord_t y) const { -#if defined(PCBX10) && !defined(SIMU) +#if defined(LCD_VERTICAL_INVERT) x = width - x - 1; y = height - y - 1; #endif @@ -193,7 +193,7 @@ class BitmapBuffer: public BitmapBufferBase inline const display_t * getPixelPtr(coord_t x, coord_t y) const { -#if defined(PCBX10) && !defined(SIMU) +#if defined(LCD_VERTICAL_INVERT) x = width - x - 1; y = height - y - 1; #endif @@ -202,7 +202,7 @@ class BitmapBuffer: public BitmapBufferBase inline display_t * getPixelPtr(coord_t x, coord_t y) { -#if defined(PCBX10) && !defined(SIMU) +#if defined(LCD_VERTICAL_INVERT) x = width - x - 1; y = height - y - 1; #endif diff --git a/radio/src/gui/480x272/lcd.h b/radio/src/gui/480x272/lcd.h index c66865d85..5d3705546 100644 --- a/radio/src/gui/480x272/lcd.h +++ b/radio/src/gui/480x272/lcd.h @@ -162,7 +162,7 @@ void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); #define DOTTED 0x55 #define STASHED 0x33 -#if defined(PCBX10) && !defined(SIMU) +#if defined(LCD_VERTICAL_INVERT) #define PIXEL_PTR(x, y) &displayBuf[(LCD_H*LCD_W-1) - (y)*LCD_W - (x)] #else #define PIXEL_PTR(x, y) &displayBuf[(y)*LCD_W + (x)] diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 13f8140e6..6fbf9c83e 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -2048,6 +2048,11 @@ int main() inline uint32_t PWR_PRESS_SHUTDOWN_DELAY() { +#if defined(PWR_EXTRA_SWITCH_GPIO) + // Instant off when both power button are pressed + if (GPIO_ReadInputDataBit(PWR_SWITCH_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET && GPIO_ReadInputDataBit(PWR_EXTRA_SWITCH_GPIO, PWR_EXTRA_SWITCH_GPIO_PIN) == Bit_RESET) + return 0; +#endif return (2 - g_eeGeneral.pwrOffSpeed) * 100; } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 0ef8b04c9..98bbb6356 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -546,7 +546,7 @@ bool setTrimValue(uint8_t phase, uint8_t idx, int trim); #if defined(PCBSKY9X) #define ROTARY_ENCODER_GRANULARITY (2 << g_eeGeneral.rotarySteps) -#elif defined(RADIO_FAMILY_T16) +#elif defined(RADIO_FAMILY_T16) && !defined(RADIO_T18) #define ROTARY_ENCODER_GRANULARITY (1) #else #define ROTARY_ENCODER_GRANULARITY (2) diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 91b5e3406..cef09bae2 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -128,6 +128,8 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3478746F // otx for X12S #elif defined(RADIO_T16) #define OTX_FOURCC 0x3F78746F // otx for Jumper T16 +#elif defined(RADIO_T18) + #define OTX_FOURCC 0x4078746F // otx for Jumper T18 #elif defined(RADIO_TX16S) #define OTX_FOURCC 0x3878746F // otx for Radiomaster TX16S #elif defined(PCBX10) diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index 61bfb8e36..618fdcd90 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -24,6 +24,8 @@ // not needed #elif defined(RADIO_T16) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; +#elif defined(RADIO_T18) + const int8_t adcDirection[NUM_ANALOGS] = { 1,-1,1,-1, -1,1,-1, -1,1, -1,1 }; #elif defined(RADIO_TX16S) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; #elif defined(PCBX10) diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index 106734a2f..4d5d09275 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -202,7 +202,7 @@ int main() RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph | LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_xMS_RCC_APB1Periph | I2C_RCC_APB1Periph | - AUX_SERIAL_RCC_APB1Periph | + AUX_SERIAL_RCC_APB1Periph | KEYS_BACKLIGHT_RCC_AHB1Periph | SD_RCC_APB1Periph, ENABLE); RCC_APB2PeriphClockCmd(LCD_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph | RCC_APB2Periph_SYSCFG, ENABLE); diff --git a/radio/src/targets/common/arm/stm32/pwr_driver.cpp b/radio/src/targets/common/arm/stm32/pwr_driver.cpp index f488d19fa..aa0ba7584 100644 --- a/radio/src/targets/common/arm/stm32/pwr_driver.cpp +++ b/radio/src/targets/common/arm/stm32/pwr_driver.cpp @@ -51,6 +51,12 @@ void pwrInit() GPIO_InitStructure.GPIO_Pin = PWR_SWITCH_GPIO_PIN; GPIO_Init(PWR_SWITCH_GPIO, &GPIO_InitStructure); +#if defined(PWR_EXTRA_SWITCH_GPIO) + // PWR Extra switch + GPIO_InitStructure.GPIO_Pin = PWR_EXTRA_SWITCH_GPIO_PIN; + GPIO_Init(PWR_EXTRA_SWITCH_GPIO, &GPIO_InitStructure); +#endif + #if defined(PCBREV_HARDCODED) hardwareOptions.pcbrev = PCBREV_HARDCODED; #elif defined(PCBREV_GPIO_PIN) @@ -103,7 +109,11 @@ void pwrOff() bool pwrPressed() { +#if defined(PWR_EXTRA_SWITCH_GPIO) + return (GPIO_ReadInputDataBit(PWR_SWITCH_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET || GPIO_ReadInputDataBit(PWR_EXTRA_SWITCH_GPIO, PWR_EXTRA_SWITCH_GPIO_PIN) == Bit_RESET); +#else return GPIO_ReadInputDataBit(PWR_SWITCH_GPIO, PWR_SWITCH_GPIO_PIN) == Bit_RESET; +#endif } void pwrResetHandler() diff --git a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp index 436cb0bd7..72bc743ce 100644 --- a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp @@ -71,7 +71,7 @@ void rotaryEncoderInit() void rotaryEncoderCheck() { -#if defined(RADIO_FAMILY_T16) +#if defined(RADIO_FAMILY_T16) && !defined(RADIO_T18) static uint8_t state = 0; uint8_t pins = ROTARY_ENCODER_POSITION(); diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index 21a121737..ceb258199 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -63,6 +63,13 @@ if (PCB STREQUAL X10) option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" OFF) option(BLUETOOTH "Support for bluetooth module" OFF) set(AUX_SERIAL ON) + elseif (PCBREV STREQUAL T18) + set(FLAVOUR t18) + set(LUA_EXPORT lua_export_t16) + add_definitions(-DRADIO_T18) + add_definitions(-DRADIO_FAMILY_T16) + option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" ON) + option(BLUETOOTH "Support for bluetooth module" OFF) else() set(FLAVOUR x10) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) diff --git a/radio/src/targets/horus/backlight_driver.cpp b/radio/src/targets/horus/backlight_driver.cpp index e141cf5dd..08960e272 100644 --- a/radio/src/targets/horus/backlight_driver.cpp +++ b/radio/src/targets/horus/backlight_driver.cpp @@ -32,6 +32,15 @@ void backlightInit() GPIO_Init(BACKLIGHT_GPIO, &GPIO_InitStructure); GPIO_PinAFConfig(BACKLIGHT_GPIO, BACKLIGHT_GPIO_PinSource, BACKLIGHT_GPIO_AF); +#if defined(KEYS_BACKLIGHT_GPIO) + GPIO_InitStructure.GPIO_Pin = KEYS_BACKLIGHT_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_NOPULL; + GPIO_Init(KEYS_BACKLIGHT_GPIO, &GPIO_InitStructure); +#endif + // TIMER init #if defined(PCBX12S) && PCBREV >= 13 BACKLIGHT_TIMER->ARR = 100; @@ -72,6 +81,15 @@ void backlightEnable(uint8_t dutyCycle) BACKLIGHT_TIMER->CCR3 = BACKLIGHT_LEVEL_MAX - dutyCycle; #endif +#if defined(KEYS_BACKLIGHT_GPIO) && !defined(BOOT) + if (dutyCycle == 0 || g_eeGeneral.keyBacklight == 0) { + GPIO_ResetBits(KEYS_BACKLIGHT_GPIO, KEYS_BACKLIGHT_GPIO_PIN); + } + else { + GPIO_SetBits(KEYS_BACKLIGHT_GPIO, KEYS_BACKLIGHT_GPIO_PIN); + } +#endif + if (dutyCycle == 0) { BACKLIGHT_TIMER->BDTR &= ~TIM_BDTR_MOE; } diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index a31add6e7..d8c0f2e24 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -71,6 +71,7 @@ void boardInit() LED_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | + KEYS_BACKLIGHT_RCC_AHB1Periph | SD_RCC_AHB1Periph | AUDIO_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 478a1f6eb..22587abd4 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -544,6 +544,10 @@ void usbJoystickUpdate(); #define USB_NAME "Jumper T16" #define USB_MANUFACTURER 'J', 'u', 'm', 'p', 'e', 'r', ' ', ' ' /* 8 bytes */ #define USB_PRODUCT 'T', '1', '6', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */ +#elif defined(RADIO_T18) + #define USB_NAME "Jumper T18" + #define USB_MANUFACTURER 'J', 'u', 'm', 'p', 'e', 'r', ' ', ' ' /* 8 bytes */ + #define USB_PRODUCT 'T', '1', '8', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */ #elif defined(RADIO_TX16S) #define USB_NAME "RadioMas TX16S" #define USB_MANUFACTURER 'R', 'a', 'd', 'i', 'o', 'M', 'a', 's' /* 8 bytes */ diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 216120821..4f350766f 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -322,7 +322,7 @@ #define ADC_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) #if defined(RADIO_TX16S) #define ADC_VREF_PREC2 330 -#elif defined(RADIO_T16) +#elif defined(RADIO_T16) || defined(RADIO_T18) #define ADC_VREF_PREC2 300 #else #define ADC_VREF_PREC2 250 @@ -330,11 +330,21 @@ #endif // Power -#define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOJ -#define PWR_ON_GPIO GPIOJ -#define PWR_ON_GPIO_PIN GPIO_Pin_1 // PJ.01 -#define PWR_SWITCH_GPIO GPIOJ -#define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 +#if defined(RADIO_T18) + #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOJ | RCC_AHB1Periph_GPIOB + #define PWR_ON_GPIO GPIOJ + #define PWR_ON_GPIO_PIN GPIO_Pin_1 // PJ.01 + #define PWR_SWITCH_GPIO GPIOJ + #define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 + #define PWR_EXTRA_SWITCH_GPIO GPIOB + #define PWR_EXTRA_SWITCH_GPIO_PIN GPIO_Pin_0 // PB.00 +#else + #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOJ + #define PWR_ON_GPIO GPIOJ + #define PWR_ON_GPIO_PIN GPIO_Pin_1 // PJ.01 + #define PWR_SWITCH_GPIO GPIOJ + #define PWR_SWITCH_GPIO_PIN GPIO_Pin_0 // PJ.00 +#endif // S.Port update connector #define SPORT_MAX_BAUDRATE 250000 // < 400000 @@ -450,6 +460,9 @@ #elif defined(PCBX10) #define LCD_GPIO_NRST GPIOI #define LCD_GPIO_PIN_NRST GPIO_Pin_10 // PI.10 +#endif + #if defined(PCBX10) && !defined(RADIO_T18) && !defined(SIMU) + #define LCD_VERTICAL_INVERT #endif #define LTDC_IRQ_PRIO 4 #define DMA_SCREEN_IRQ_PRIO 6 @@ -486,6 +499,14 @@ #define BACKLIGHT_GPIO_AF GPIO_AF_TIM8 #define BACKLIGHT_TIMER_FREQ (PERI2_FREQUENCY * TIMER_MULT_APB2) #endif +#if defined(RADIO_T18) + #define KEYS_BACKLIGHT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC + #define KEYS_BACKLIGHT_GPIO GPIOC + #define KEYS_BACKLIGHT_GPIO_PIN GPIO_Pin_4 // PC.04 + #define KEYS_BACKLIGHT_GPIO_PinSource GPIO_PinSource4 +#else + #define KEYS_BACKLIGHT_RCC_AHB1Periph 0 +#endif // SD #define SD_RCC_AHB1Periph (RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA2) diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index 110db0007..a5c9ef311 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -20,14 +20,25 @@ #include "opentx.h" -#define HBP 42 -#define VBP 12 +#if defined(RADIO_T18) + #define HBP 43 + #define VBP 12 -#define HSW 2 -#define VSW 10 + #define HSW 2 + #define VSW 4 -#define HFP 3 -#define VFP 2 + #define HFP 8 + #define VFP 8 +#else + #define HBP 42 + #define VBP 12 + + #define HSW 2 + #define VSW 10 + + #define HFP 3 + #define VFP 2 +#endif #define LCD_FIRST_LAYER 0 #define LCD_SECOND_LAYER 1 @@ -310,7 +321,11 @@ void LCD_Init(void) { /* Reset the LCD --------------------------------------------------------*/ LCD_NRSTConfig(); +#if defined(RADIO_T18) // T18 seems to have eractic display issue if NRST is ever driven low + NRST_HIGH(); +#else lcd_reset(); +#endif /* Configure the LCD Control pins */ LCD_AF_GPIOConfig(); @@ -378,7 +393,7 @@ void lcdInit(void) 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) { -#if defined(PCBX10) +#if defined(LCD_VERTICAL_INVERT) x = destw - (x + w); y = desth - (y + h); #endif @@ -447,7 +462,7 @@ void DMACopyBitmap(uint16_t * dest, uint16_t destw, uint16_t desth, uint16_t x, 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) { -#if defined(PCBX10) +#if defined(LCD_VERTICAL_INVERT) x = destw - (x + w); y = desth - (y + h); srcx = srcw - (srcx + w); diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 79ce0456b..13e0b550c 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -1636,6 +1636,7 @@ #define BACKLIGHT_GPIO_PinSource GPIO_PinSource8 #define BACKLIGHT_GPIO_AF GPIO_AF_TIM10 #endif +#define KEYS_BACKLIGHT_RCC_AHB1Periph 0 // LCD driver #if defined(PCBX9E) diff --git a/tools/build-tbs.py b/tools/build-tbs.py index 2beb11924..b8f9c9a58 100755 --- a/tools/build-tbs.py +++ b/tools/build-tbs.py @@ -56,6 +56,11 @@ boards = { "PCBREV": "T16", "INTERNAL_MODULE_MULTI": "YES" }, + "T18": { + "PCB": "X10", + "PCBREV": "T18", + "INTERNAL_MODULE_MULTI": "YES" + }, "TX16S": { "PCB": "X10", "PCBREV": "TX16S",