diff --git a/src/Makefile b/src/Makefile index 56bc5f1871..225ba80bf3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -14,7 +14,7 @@ default: $(TARGET) ALLTARGETS = $(filter-out common,$(notdir $(wildcard target/tx/*/*))) # The supported transmitters -TXS ?= devo6 devo7e devo7e-256 devo8 devo10 devo12e devo12 devof7 devof7-XMS devof4 devof4-XMS devof12e devof12e-XMS at9 at10 t8sg t8sg_v2 t8sg_v2_plus ir8m +TXS ?= devo6 devo7e devo7e-256 devo8 devo10 devo12e devo12 devof7 devof7-XMS devof4 devof4-XMS devof12e devof12e-XMS at9 at10 t8sg_v1 t8sg_v2 t8sg_v2_plus ir8m #Filter non-existant emus EMUS = $(foreach dir,$(TXS:%=emu_%),$(if $(wildcard target/$(dir)),$(dir),)) diff --git a/src/pages/128x64x1/tx_configure.c b/src/pages/128x64x1/tx_configure.c index c39af0c063..31fea33a04 100644 --- a/src/pages/128x64x1/tx_configure.c +++ b/src/pages/128x64x1/tx_configure.c @@ -52,6 +52,10 @@ static u16 current_selected = 0; // do not put current_selected into pagemem as static int size_cb(int absrow, void *data) { (void)data; + if (absrow >= ITEM_BACKLIGHT && HAS_OLED_DISPLAY) { + // This will hide the backlight row + absrow++; + } switch(absrow) { #if SUPPORT_MULTI_LANGUAGE case ITEM_LANG: @@ -59,11 +63,7 @@ static int size_cb(int absrow, void *data) case ITEM_MODE: #endif case ITEM_BUZZ: -#if !HAS_OLED_DISPLAY - case ITEM_BACKLIGHT: -#else case ITEM_CONTRAST: -#endif case ITEM_PREALERT: case ITEM_TELEMTEMP: return 2; @@ -88,6 +88,10 @@ static int row_cb(int absrow, int relrow, int y, void *data) void *but_str = NULL; u8 x = LARGE_SEL_X_OFFSET; + if (absrow >= ITEM_BACKLIGHT && HAS_OLED_DISPLAY) { + // This will hide the backlight row + absrow++; + } switch(absrow) { #if SUPPORT_MULTI_LANGUAGE case ITEM_LANG: @@ -142,20 +146,15 @@ static int row_cb(int absrow, int relrow, int y, void *data) label = _tr_noop("PwrDn alert"); value = _music_shutdown_cb; x = MED_SEL_X_OFFSET; break; -#if !HAS_OLED_DISPLAY - case ITEM_BACKLIGHT: - title = _tr_noop("LCD settings"); - label = _tr_noop("Backlight"); - value = backlight_select_cb; x = SMALL_SEL_X_OFFSET; - break; -#endif case ITEM_CONTRAST: -#if HAS_OLED_DISPLAY title = _tr_noop("LCD settings"); -#endif label = _tr_noop("Contrast"); value = _contrast_select_cb; x = SMALL_SEL_X_OFFSET; break; + case ITEM_BACKLIGHT: + label = _tr_noop("Backlight"); + value = backlight_select_cb; x = SMALL_SEL_X_OFFSET; + break; case ITEM_DIMTIME: label = _tr_noop("Dimmer time"); value = auto_dimmer_time_cb; x = SMALL_SEL_X_OFFSET; @@ -229,9 +228,9 @@ static const char *_contrast_select_cb(guiObject_t *obj, int dir, void *data) 0, 10, dir, 1, 1, &changed); if (changed) { LCD_Contrast(Transmitter.contrast); -#if HAS_OLED_DISPLAY - Transmitter.backlight = Transmitter.contrast; -#endif + if (HAS_OLED_DISPLAY) { + Transmitter.backlight = Transmitter.contrast; + } } if (Transmitter.contrast == 0) return _tr("Off"); diff --git a/src/pages/common/_tx_configure.c b/src/pages/common/_tx_configure.c index 12d988e50a..cc72fbcf6f 100644 --- a/src/pages/common/_tx_configure.c +++ b/src/pages/common/_tx_configure.c @@ -31,10 +31,8 @@ enum { ITEM_BATT, ITEM_ALARM_INTV, ITEM_PWRDN_ALARM, -#if !HAS_OLED_DISPLAY - ITEM_BACKLIGHT, -#endif ITEM_CONTRAST, + ITEM_BACKLIGHT, ITEM_DIMTIME, ITEM_DIMVAL, ITEM_PREALERT, @@ -184,7 +182,6 @@ static const char *modeselect_cb(guiObject_t *obj, int dir, void *data) return tempstring; } -#if !HAS_OLED_DISPLAY static const char *backlight_select_cb(guiObject_t *obj, int dir, void *data) { (void)data; @@ -199,7 +196,6 @@ static const char *backlight_select_cb(guiObject_t *obj, int dir, void *data) sprintf(tempstring, "%d", Transmitter.backlight); return tempstring; } -#endif static const char *common_select_cb(guiObject_t *obj, int dir, void *data) { diff --git a/src/target/drivers/backlight/backlight.c b/src/target/drivers/backlight/backlight.c index 0984fe67a8..f1c2f60009 100644 --- a/src/target/drivers/backlight/backlight.c +++ b/src/target/drivers/backlight/backlight.c @@ -15,47 +15,25 @@ #include "common.h" -#if !HAS_OLED_DISPLAY #include "target/drivers/mcu/stm32/rcc.h" #include "target/drivers/mcu/stm32/tim.h" +#include "oled.h" +#include "lcd.h" void BACKLIGHT_Init() { - rcc_periph_clock_enable(get_rcc_from_pin(BACKLIGHT_TIM.pin)); - GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); - - // Configure Backlight PWM - rcc_periph_clock_enable(get_rcc_from_port(BACKLIGHT_TIM.tim)); - timer_set_mode(BACKLIGHT_TIM.tim, TIM_CR1_CKD_CK_INT, - TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); - timer_set_period(BACKLIGHT_TIM.tim, 0x2CF); - timer_set_prescaler(BACKLIGHT_TIM.tim, 0); - timer_generate_event(BACKLIGHT_TIM.tim, TIM_EGR_UG); - timer_set_oc_mode(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch), TIM_OCM_PWM1); - timer_enable_oc_preload(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); - - timer_set_oc_polarity_high(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); - timer_enable_oc_output(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); - - timer_enable_preload(BACKLIGHT_TIM.tim); + if (HAS_OLED_DISPLAY) { + _oled_backlight_init(); + } else { + _lcd_backlight_init(); + } } void BACKLIGHT_Brightness(unsigned brightness) { - timer_disable_counter(BACKLIGHT_TIM.tim); - if (brightness == 0) { - // Turn off Backlight - GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); - } else if (brightness > 9) { - // Turn on Backlight full - GPIO_setup_output(BACKLIGHT_TIM.pin, OTYPE_PUSHPULL); - GPIO_pin_set(BACKLIGHT_TIM.pin); + if (HAS_OLED_DISPLAY) { + _oled_backlight_brightness(brightness); } else { - GPIO_setup_output_af(BACKLIGHT_TIM.pin, OTYPE_PUSHPULL, BACKLIGHT_TIM.tim); - u32 duty_cycle = 720 * brightness / 10; - timer_set_oc_value(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch), duty_cycle); - timer_enable_counter(BACKLIGHT_TIM.tim); + _lcd_backlight_brightness(brightness); } } - -#endif // !HAS_OLED_DISPLAY diff --git a/src/target/drivers/backlight/lcd.h b/src/target/drivers/backlight/lcd.h new file mode 100644 index 0000000000..1b5084b0c9 --- /dev/null +++ b/src/target/drivers/backlight/lcd.h @@ -0,0 +1,39 @@ + +static void _lcd_backlight_init() +{ + rcc_periph_clock_enable(get_rcc_from_pin(BACKLIGHT_TIM.pin)); + GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); + + // Configure Backlight PWM + rcc_periph_clock_enable(get_rcc_from_port(BACKLIGHT_TIM.tim)); + timer_set_mode(BACKLIGHT_TIM.tim, TIM_CR1_CKD_CK_INT, + TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); + timer_set_period(BACKLIGHT_TIM.tim, 0x2CF); + timer_set_prescaler(BACKLIGHT_TIM.tim, 0); + timer_generate_event(BACKLIGHT_TIM.tim, TIM_EGR_UG); + timer_set_oc_mode(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch), TIM_OCM_PWM1); + timer_enable_oc_preload(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); + + timer_set_oc_polarity_high(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); + timer_enable_oc_output(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch)); + + timer_enable_preload(BACKLIGHT_TIM.tim); +} + +static void _lcd_backlight_brightness(unsigned brightness) +{ + timer_disable_counter(BACKLIGHT_TIM.tim); + if (brightness == 0) { + // Turn off Backlight + GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); + } else if (brightness > 9) { + // Turn on Backlight full + GPIO_setup_output(BACKLIGHT_TIM.pin, OTYPE_PUSHPULL); + GPIO_pin_set(BACKLIGHT_TIM.pin); + } else { + GPIO_setup_output_af(BACKLIGHT_TIM.pin, OTYPE_PUSHPULL, BACKLIGHT_TIM.tim); + u32 duty_cycle = 720 * brightness / 10; + timer_set_oc_value(BACKLIGHT_TIM.tim, TIM_OCx(BACKLIGHT_TIM.ch), duty_cycle); + timer_enable_counter(BACKLIGHT_TIM.tim); + } +} diff --git a/src/target/drivers/backlight/oled.h b/src/target/drivers/backlight/oled.h new file mode 100644 index 0000000000..8058726c20 --- /dev/null +++ b/src/target/drivers/backlight/oled.h @@ -0,0 +1,28 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ + +/* These are defined in 128x64x1_oled_ssd1306.h */ +void OLED_Backlight(); +void OLED_Backlight_Brightness(unsigned brightness); + +static void _oled_backlight_init() +{ + OLED_Backlight(); +} + +static void _oled_backlight_brightness(unsigned brightness) +{ + OLED_Backlight_Brightness(brightness); +} diff --git a/src/target/drivers/display/8080/128x64x1.c b/src/target/drivers/display/8080/128x64x1.c new file mode 100644 index 0000000000..6e040f4f3b --- /dev/null +++ b/src/target/drivers/display/8080/128x64x1.c @@ -0,0 +1,55 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ +#include +#include +#include "common.h" +#include "gui/gui.h" +#include "target/drivers/mcu/stm32/fsmc.h" + +#define LCD_CONTRAST_FUNC(contrast) (0x20 + contrast * 0xC / 10) + +#define LCD_CMD_ADDR ((uint32_t)FSMC_BANK1_BASE) /* Register Address */ +#define LCD_DATA_ADDR ((uint32_t)FSMC_BANK1_BASE + 0x10000) /* Data Address */ + +#define LCD_CMD *(volatile uint8_t *)(LCD_CMD_ADDR) +#define LCD_DATA *(volatile uint8_t *)(LCD_DATA_ADDR) + +inline static void LCD_Cmd(unsigned cmd) +{ + LCD_CMD = cmd; +} + +inline static void LCD_Data(unsigned data) +{ + LCD_DATA = data; +} +#define LCD_CONTRAST_FUNC(contrast) (0x20 + contrast * 0xC / 10) + +static void lcd_init_ports() +{ + _fsmc_init( + 8, + 0x10000, /*only bit 16 of addr */ + FSMC_NOE | FSMC_NWE | FSMC_NE1, /* Not connected */ + FSMC_BANK1, + /* Normal mode, write enable, 8 bit access, SRAM, bank enabled */ + FSMC_BCR_FACCEN | FSMC_BCR_WREN | FSMC_BCR_MBKEN, + /* Data Setup > 90ns, Address Setup = 2xHCLK to ensure no output collision in 6800 + mode since LCD E and !CS always active */ + FSMC_BTR_DATASTx(7) | FSMC_BTR_ADDHLDx(0) | FSMC_BTR_ADDSETx(2), + 0); +} + +#include "../spi/128x64x1_common.h" diff --git a/src/target/drivers/display/8080/128x64x1_nt7538.c b/src/target/drivers/display/8080/128x64x1_nt7538.c deleted file mode 100644 index 2a971f2a32..0000000000 --- a/src/target/drivers/display/8080/128x64x1_nt7538.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - This project is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Deviation 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. - - You should have received a copy of the GNU General Public License - along with Deviation. If not, see . -*/ -#include -#include -#include "common.h" -#include "gui/gui.h" -#include "target/drivers/mcu/stm32/fsmc.h" - -#define LCD_CMD_ADDR ((uint32_t)FSMC_BANK1_BASE) /* Register Address */ -#define LCD_DATA_ADDR ((uint32_t)FSMC_BANK1_BASE + 0x10000) /* Data Address */ - -#define LCD_CMD *(volatile uint8_t *)(LCD_CMD_ADDR) -#define LCD_DATA *(volatile uint8_t *)(LCD_DATA_ADDR) - -//The screen is 129 characters, but we'll only expoise 128 of them -#define PHY_LCD_WIDTH 129 -#define LCD_PAGES 8 -static u8 img[PHY_LCD_WIDTH * LCD_PAGES]; -static u8 dirty[PHY_LCD_WIDTH]; -static unsigned int xstart, xend; // After introducing logical view for devo10, the coordinate can be >= 5000 -static unsigned int xpos, ypos; -static s8 dir; - -static void lcd_display(uint8_t on) -{ - LCD_CMD = 0xAE | (on ? 1 : 0); -} - -static void lcd_set_page_address(uint8_t page) -{ - LCD_CMD = 0xB0 | (page & 0x07); -} - -static void lcd_set_column_address(uint8_t column) -{ - LCD_CMD = 0x10 | ((column >> 4) & 0x0F); //MSB - LCD_CMD = column & 0x0F; //LSB -} - -static void lcd_set_start_line(int line) -{ - LCD_CMD = (line & 0x3F) | 0x40; -} - -void LCD_Contrast(unsigned contrast) -{ - int data = 0x20 + contrast * 0xC / 10; - LCD_CMD = 0x81; - LCD_CMD = data & 0x3F; -} - -void LCD_Init() -{ - _fsmc_init( - 8, - 0x10000, /*only bit 16 of addr */ - FSMC_NOE | FSMC_NWE | FSMC_NE1, /* Not connected */ - FSMC_BANK1, - /* Normal mode, write enable, 8 bit access, SRAM, bank enabled */ - FSMC_BCR_FACCEN | FSMC_BCR_WREN | FSMC_BCR_MBKEN, - /* Data Setup > 90ns, Address Setup = 2xHCLK to ensure no output collision in 6800 - mode since LCD E and !CS always active */ - FSMC_BTR_DATASTx(7) | FSMC_BTR_ADDHLDx(0) | FSMC_BTR_ADDSETx(2), - 0); - - - - // LCD bias setting (11); 0xA2; 1/9 - LCD_CMD = 0xA2; - - // ADC selection (8) -> ADdressCounter; 0xA0; inc - LCD_CMD = 0xA0; - - //Common output mode selection (15); 0xC0; normal scan - LCD_CMD = 0xC0; - Delay(5); - - //Setting built-in resistance ratio (17); 0x24; default=7.50 - LCD_CMD = 0x24; - - //Electronic volume control (18) -> LCD brightness; 0x20; default=32d - LCD_CMD = 0x81; - LCD_CMD = 0x25 & 0x3F; // = LCD_Contrast(5); - Delay(5); - - //Power control setting (16); V/B, V/R, V/F are used - LCD_CMD = 0x2F; - Delay(5); - - // Read-Modify-Write (12); let read data does not increment column address - LCD_CMD = 0xE0; - - lcd_set_start_line(0); - lcd_set_page_address(0); - lcd_set_column_address(0); - // Display data write (6) - lcd_display(1); - memset(img, 0, sizeof(img)); - memset(dirty, 0, sizeof(dirty)); -} - -void LCD_Clear(unsigned int val) -{ - val = (val & 0xFF) ? 0xff : 0x00; - memset(img, val, sizeof(img)); - memset(dirty, 0xFF, sizeof(dirty)); -} - -void LCD_DrawStart(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, enum DrawDir _dir) -{ - if (_dir == DRAW_SWNE) { - ypos = y1; // bug fix: must do it this way to draw bmp - dir = -1; - } else { - ypos = y0; - dir = 1; - } - xstart = x0; - xend = x1; - xpos = x0; -} -/* Screen coordinates are as follows: - * (128, 32) .... (0, 32) - * ... .... ... - * (128, 63) .... (0, 63) - * (128, 0) .... (0, 0) - * ... .... ... - * (128, 31) .... (0, 31) - */ -void LCD_DrawStop(void) -{ - int col = 0; - int p, c; - for (p = 0; p < LCD_PAGES; p++) { - int init = 0; - for (c = 0; c < PHY_LCD_WIDTH; c++) { - if(dirty[c] & (1 << p)) { - if(! init) { - lcd_set_page_address(p); - lcd_set_column_address(c); - } else if(col+1 != c) { - lcd_set_column_address(c); - } - LCD_DATA = img[p * PHY_LCD_WIDTH + c]; - col = c; - } - } - } - memset(dirty, 0, sizeof(dirty)); -} - -/* - * 2. -Display Start Line Set -Specifies line address (refer to Figure 6) to determine the initial display line, or COM0. The RAM -display data becomes the top line of LCD screen. The higher number of -lines in ascending order, -corresponding to the duty cycle follows it. When this command changes the line address, smooth -scrolling or a page change takes place. -A0 (E /RD) (R/W /WR) D7 D6 D5 D4 D3 D2 D1 D0 Hex -0 1 0 0 1 A5 A4 A3 A2 A1 A0 40h to 7Fh - -8. -ADC Select -Changes the relationship between RAM column address and segment driver. The order of -segment driver output pads could be reversed by software. This allows flexi -ble IC layout during -LCD module assembly. For details, refer to the column address section of Figure 4. When display -data is written or read, the column address is incremented by 1 as shown in Figure 4. -A0 (E /RD) (R/W /WR) D7 D6 D5 D4 D3 D2 D1 D0 Hex Setting - 0 1 0 1 0 1 0 0 0 0 0 A0h Normal - 1 A1h Reverse - */ - - -void LCD_DrawPixel(unsigned int color) -{ - if (xpos < LCD_WIDTH && ypos < LCD_HEIGHT) { // both are unsigned, can not be < 0 - int y; - int x = PHY_LCD_WIDTH - 1 - xpos; //We want to map 0 -> 128 and 128 -> 0 - - if (ypos > 31) - y = ypos - 32; - else - y = ypos + 32; - - - int ycol = y / 8; - int ybit = y & 0x07; - if(color) { - img[ycol * PHY_LCD_WIDTH + x] |= 1 << ybit; - } else { - img[ycol * PHY_LCD_WIDTH + x] &= ~(1 << ybit); - } - dirty[x] |= 1 << ycol; - } - // this must be executed to continue drawing in the next row - xpos++; - if (xpos > xend) { - xpos = xstart; - ypos += dir; - } -} - -void LCD_DrawPixelXY(unsigned int x, unsigned int y, unsigned int color) -{ - xpos = x; - ypos = y; - LCD_DrawPixel(color); -} diff --git a/src/target/drivers/display/spi/128x64x1.c b/src/target/drivers/display/spi/128x64x1.c new file mode 100644 index 0000000000..87679cb8ab --- /dev/null +++ b/src/target/drivers/display/spi/128x64x1.c @@ -0,0 +1,57 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ +#include +#include +#include +#include "common.h" +#include "gui/gui.h" +#include "target/drivers/mcu/stm32/rcc.h" + +#define CS_HI() GPIO_pin_set(LCD_SPI.csn) +#define CS_LO() GPIO_pin_clear(LCD_SPI.csn) +#define CMD_MODE() GPIO_pin_clear(LCD_SPI_MODE) +#define DATA_MODE() GPIO_pin_set(LCD_SPI_MODE) + +static void LCD_Cmd(unsigned cmd) { + CMD_MODE(); + CS_LO(); + spi_xfer(LCD_SPI.spi, cmd); + CS_HI(); +} + +static void LCD_Data(unsigned cmd) { + DATA_MODE(); + CS_LO(); + spi_xfer(LCD_SPI.spi, cmd); + CS_HI(); +} + +static void lcd_init_ports() +{ + // Initialization is mostly done in SPI Flash + // Setup CS as B.0 Data/Control = C.5 + rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI.csn)); + rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI_MODE)); + GPIO_setup_output(LCD_SPI.csn, OTYPE_PUSHPULL); + GPIO_setup_output(LCD_SPI_MODE, OTYPE_PUSHPULL); + if (HAS_OLED_DISPLAY) { + // We >> 3 because spi_set_baudrate_prescaler takes a value of 0-7, + // Whereas spi_init_master uses SPI_CR1_BAUDRATE_FPCLK_DIV_xx which + // is pre-shifted + spi_set_baudrate_prescaler(LCD_SPI.spi, (OLED_SPI_RATE) >> 3); + } +} + +#include "128x64x1_common.h" diff --git a/src/target/drivers/display/spi/128x64x1_nt7538.c b/src/target/drivers/display/spi/128x64x1_common.h similarity index 65% rename from src/target/drivers/display/spi/128x64x1_nt7538.c rename to src/target/drivers/display/spi/128x64x1_common.h index 64078d3e96..783d2eae8e 100644 --- a/src/target/drivers/display/spi/128x64x1_nt7538.c +++ b/src/target/drivers/display/spi/128x64x1_common.h @@ -12,25 +12,17 @@ You should have received a copy of the GNU General Public License along with Deviation. If not, see . */ -#include -#include -#include "common.h" -#include "gui/gui.h" -#include "target/drivers/mcu/stm32/rcc.h" -#include "target/drivers/mcu/stm32/spi.h" - -#define CS_HI() GPIO_pin_set(LCD_SPI.csn) -#define CS_LO() GPIO_pin_clear(LCD_SPI.csn) -#define CMD_MODE() GPIO_pin_clear(LCD_SPI_MODE) -#define DATA_MODE() GPIO_pin_set(LCD_SPI_MODE) #ifndef HAS_LCD_FLIPPED #define HAS_LCD_FLIPPED 0 #endif - -#ifndef LCD_CONTRAST_FUNC - #define LCD_CONTRAST_FUNC(x) ((x) * 12 + 76) // Contrsat function for devo radios +#ifndef HAS_LCD_SWAPPED_PAGES + #define HAS_LCD_SWAPPED_PAGES 0 #endif + +#include "128x64x1_nt7538.h" +#include "128x64x1_oled_ssd1306.h" + //The screen is 129 characters, but we'll only expoise 128 of them #define PHY_LCD_WIDTH 129 #define LCD_PAGES 8 @@ -40,20 +32,6 @@ static u16 xstart, xend; // After introducing logical view for devo10, the coor static u16 xpos, ypos; static s8 dir; -void LCD_Cmd(unsigned cmd) { - CMD_MODE(); - CS_LO(); - spi_xfer(LCD_SPI.spi, cmd); - CS_HI(); -} - -void LCD_Data(unsigned cmd) { - DATA_MODE(); - CS_LO(); - spi_xfer(LCD_SPI.spi, cmd); - CS_HI(); -} - void lcd_display(uint8_t on) { LCD_Cmd(0xAE | (on ? 1 : 0)); @@ -79,44 +57,27 @@ void LCD_Contrast(unsigned contrast) { //int data = 0x20 + contrast * 0xC / 10; LCD_Cmd(0x81); - int c = LCD_CONTRAST_FUNC(contrast); - LCD_Cmd(c); + if (HAS_OLED_DISPLAY) { + contrast = _oled_contrast_func(contrast); + } else { + contrast = _lcd_contrast_func(contrast); + } + LCD_Cmd(contrast); } void LCD_Init() { - //Initialization is mostly done in SPI Flash - //Setup CS as B.0 Data/Control = C.5 -#ifndef FLASH_SPI_CFG - _spi_init(LCD_SPI_CFG); -#endif - rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI.csn)); - rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI_MODE)); - GPIO_setup_output(LCD_SPI.csn, OTYPE_PUSHPULL); - GPIO_setup_output(LCD_SPI_MODE, OTYPE_PUSHPULL); - LCD_Cmd(0xE2); //Reset - volatile int i = 0x8000; - while(i) i--; - lcd_display(0); // Display Off - LCD_Cmd(0xA6); // Normal display - LCD_Cmd(0xA4); // All Points Normal - LCD_Cmd(0xA0); // Set SEG Direction (Normal) - if (HAS_LCD_FLIPPED) { - LCD_Cmd(0xC8); // Set COM Direction (Reversed) - LCD_Cmd(0xA2); // Set The LCD Display Driver Voltage Bias Ratio (1/9) + lcd_init_ports(); + if (HAS_OLED_DISPLAY) { + _oled_reset(); + _oled_init(); } else { - LCD_Cmd(0xEA); // ?? - LCD_Cmd(0xC4); // Common Output Mode Scan Rate + _lcd_reset(); + _lcd_init(); } - LCD_Cmd(0x2C); // Power Controller:Booster ON - i = 0x8000; - while(i) i--; - LCD_Cmd(0x2E); // Power Controller: VReg ON - i = 0x8000; - while(i) i--; - LCD_Cmd(0x2F); // Power Controller: VFollower ON - i = 0x8000; + volatile int i = 0x8000; while(i) i--; + lcd_display(0); // Display Off lcd_set_start_line(0); // Display data write (6) // Clear the screen @@ -182,13 +143,42 @@ void LCD_DrawStop(void) memset(dirty, 0, sizeof(dirty)); } +/* + * 2. +Display Start Line Set +Specifies line address (refer to Figure 6) to determine the initial display line, or COM0. The RAM +display data becomes the top line of LCD screen. The higher number of +lines in ascending order, +corresponding to the duty cycle follows it. When this command changes the line address, smooth +scrolling or a page change takes place. +A0 (E /RD) (R/W /WR) D7 D6 D5 D4 D3 D2 D1 D0 Hex +0 1 0 0 1 A5 A4 A3 A2 A1 A0 40h to 7Fh + +8. +ADC Select +Changes the relationship between RAM column address and segment driver. The order of +segment driver output pads could be reversed by software. This allows flexi +ble IC layout during +LCD module assembly. For details, refer to the column address section of Figure 4. When display +data is written or read, the column address is incremented by 1 as shown in Figure 4. +A0 (E /RD) (R/W /WR) D7 D6 D5 D4 D3 D2 D1 D0 Hex Setting + 0 1 0 1 0 1 0 0 0 0 0 A0h Normal + 1 A1h Reverse + */ void LCD_DrawPixel(unsigned int color) { - if (xpos < LCD_WIDTH && ypos < LCD_HEIGHT) { // both are unsigned, can not be < 0 - int y = ypos; - int x = xpos; - int ycol = y / 8; - int ybit = y & 0x07; + if (xpos < LCD_WIDTH && ypos < LCD_HEIGHT) { // both are unsigned, can not be < 0 + int y = ypos; + int x = xpos; + if (HAS_LCD_SWAPPED_PAGES) { + x = PHY_LCD_WIDTH - 1 - xpos; // We want to map 0 -> 128 and 128 -> 0 + if (ypos > 31) + y = ypos - 32; + else + y = ypos + 32; + } + int ycol = y / 8; + int ybit = y & 0x07; if (color) { img[ycol * PHY_LCD_WIDTH + x] |= 1 << ybit; } else { @@ -196,7 +186,7 @@ void LCD_DrawPixel(unsigned int color) } dirty[x] |= 1 << ycol; } - // this must be executed to continue drawing in the next row + // this must be executed to continue drawing in the next row xpos++; if (xpos > xend) { xpos = xstart; diff --git a/src/target/drivers/display/spi/128x64x1_nt7538.h b/src/target/drivers/display/spi/128x64x1_nt7538.h new file mode 100644 index 0000000000..f8a4110f94 --- /dev/null +++ b/src/target/drivers/display/spi/128x64x1_nt7538.h @@ -0,0 +1,52 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ + +#ifndef LCD_CONTRAST_FUNC + #define LCD_CONTRAST_FUNC(contrast) ((contrast) * 12 + 76) +#endif + +inline static unsigned _lcd_contrast_func(unsigned contrast) { + return LCD_CONTRAST_FUNC(contrast); + // Devo contrast function +} + +inline static void _lcd_reset() +{ + LCD_Cmd(0xE2); // Reset +} + +inline static void _lcd_init() +{ + volatile int i; + LCD_Cmd(0xA6); // Normal display + LCD_Cmd(0xA4); // All Points Normal + LCD_Cmd(0xA0); // Set SEG Direction (Normal) + if (HAS_LCD_FLIPPED) { + LCD_Cmd(0xC8); // Set COM Direction (Reversed) + LCD_Cmd(0xA2); // Set The LCD Display Driver Voltage Bias Ratio (1/9) + } else { + LCD_Cmd(0xEA); // ?? + LCD_Cmd(0xC4); // Common Output Mode Scan Rate + } + LCD_Cmd(0x2C); // Power Controller:Booster ON + i = 0x8000; + while (i) i--; + LCD_Cmd(0x2E); // Power Controller: VReg ON + i = 0x8000; + while (i) i--; + LCD_Cmd(0x2F); // Power Controller: VFollower ON + i = 0x8000; + while (i) i--; +} diff --git a/src/target/drivers/display/spi/128x64x1_oled_ssd1306.c b/src/target/drivers/display/spi/128x64x1_oled_ssd1306.c deleted file mode 100644 index d6df5a589e..0000000000 --- a/src/target/drivers/display/spi/128x64x1_oled_ssd1306.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - This project is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Deviation 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. - - You should have received a copy of the GNU General Public License - along with Deviation. If not, see . -*/ -#include -#include -#include -#include "common.h" -#include "gui/gui.h" -#include "target/drivers/mcu/stm32/rcc.h" - -#define CS_HI() GPIO_pin_set(LCD_SPI.csn) -#define CS_LO() GPIO_pin_clear(LCD_SPI.csn) -#define CMD_MODE() GPIO_pin_clear(LCD_SPI_MODE) -#define DATA_MODE() GPIO_pin_set(LCD_SPI_MODE) - -#define PHY_LCD_WIDTH 128 -#define LCD_PAGES 8 -static u8 img[PHY_LCD_WIDTH * LCD_PAGES]; -static u8 dirty[PHY_LCD_WIDTH]; -static u16 xstart, xend; // After introducing logical view for devo10, the coordinate can be >= 5000 -static u16 xpos, ypos; -static s8 dir; - -void LCD_Cmd(unsigned cmd) { - CMD_MODE(); - CS_LO(); - spi_xfer(LCD_SPI.spi, cmd); - CS_HI(); -} - -void LCD_Data(unsigned cmd) { - DATA_MODE(); - CS_LO(); - spi_xfer(LCD_SPI.spi, cmd); - CS_HI(); -} - -void lcd_display(uint8_t on) -{ - LCD_Cmd(0xAE | (on ? 1 : 0)); -} - -void lcd_set_page_address(uint8_t page) -{ - LCD_Cmd(0xB0 | (page & 0x07)); -} - -void lcd_set_column_address(uint8_t column) -{ - LCD_Cmd(0x10 | ((column >> 4) & 0x0F)); //MSB - LCD_Cmd(column & 0x0F); //LSB -} - -void lcd_set_start_line(int line) -{ - LCD_Cmd((line & 0x3F) | 0x40); -} - -void LCD_Contrast(unsigned contrast) -{ - LCD_Cmd(0x81); - int c = contrast * contrast * 255 / 100; //contrast should range from 0 to 255 - LCD_Cmd(c); -} - -void LCD_Init() -{ - //Initialization is mostly done in SPI Flash - //Setup CS as B.0 Data/Control = C.5 - rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI.csn)); - rcc_periph_clock_enable(get_rcc_from_pin(LCD_SPI_MODE)); - GPIO_setup_output(LCD_SPI.csn, OTYPE_PUSHPULL); - GPIO_setup_output(LCD_SPI_MODE, OTYPE_PUSHPULL); - _msleep(100); - lcd_display(0); //Display Off - LCD_Cmd(0xD5); //Set Display Clock Divide Ratio / OSC Frequency - LCD_Cmd(0x80); //Display Clock Divide Ratio / OSC Frequency - LCD_Cmd(0xA8); //Set Multiplex Ratio - LCD_Cmd(0x3F); //Multiplex Ratio for 128x64 (LCD_HEIGHT - 1) - LCD_Cmd(0xD3); //Set Display Offset - LCD_Cmd(0x00); //Display Offset (0) - LCD_Cmd(0x40); //Set Display Start Line (0) - LCD_Cmd(0x8D); //Set Charge Pump - LCD_Cmd(0x10); //Charge Pump (0x10 External, 0x14 Internal DC/DC) - LCD_Cmd(0xA1); //Set Segment Re-Map (Reversed) - LCD_Cmd(0xC8); //Set Com Output Scan Direction (Reversed) - LCD_Cmd(0xDA); //Set COM Hardware Configuration - LCD_Cmd(0x12); //COM Hardware Configuration - LCD_Cmd(0xD9); //Set Pre-Charge Period - LCD_Cmd(0x4F); //Set Pre-Charge Period (A[7:4]:Phase 2, A[3:0]:Phase 1) - LCD_Cmd(0xDB); //Set VCOMH Deselect Level - LCD_Cmd(0x20); //VCOMH Deselect Level (0x00 ~ 0.65 x VCC, 0x10 ~ 0.71 x VCC, 0x20 ~ 0.77 x VCC, 0x30 ~ 0.83 x VCC) - LCD_Cmd(0xA4); //Disable Entire Display On - LCD_Cmd(0xA6); //Set Normal Display (not inverted) - LCD_Cmd(0x2E); //Deactivate scroll - //Clear the screen - for(int page = 0; page < LCD_PAGES; page++) { - lcd_set_page_address(page); - lcd_set_column_address(0); - for(int col = 0; col < PHY_LCD_WIDTH; col++) - LCD_Data(0x00); - } - lcd_display(1); //Display On - LCD_Contrast(5); - memset(img, 0, sizeof(img)); - memset(dirty, 0, sizeof(dirty)); - _msleep(100); -} - -void BACKLIGHT_Init() -{ - rcc_periph_clock_enable(get_rcc_from_pin(BACKLIGHT_TIM.pin)); - //Turn off backlight - GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); -} - -void BACKLIGHT_Brightness(unsigned brightness) -{ - LCD_Contrast(brightness); - if (brightness == 0) { - lcd_display(0); //Display Off - //Charge Pump disable - //LCD_Cmd(0x8D); //Set Charge Pump - //LCD_Cmd(0x10); //Charge Pump (0x10 External, 0x14 Internal DC/DC) - } else { - //Charge Pump enable - //LCD_Cmd(0x8D); //Set Charge Pump - //LCD_Cmd(0x14); //Charge Pump (0x10 External, 0x14 Internal DC/DC) - lcd_display(1); //Display On - } -} - -void LCD_Clear(unsigned int val) -{ - val = (val & 0xFF) ? 0xff : 0x00; - memset(img, val, sizeof(img)); - memset(dirty, 0xFF, sizeof(dirty)); -} - -void LCD_DrawStart(unsigned int x0, unsigned int y0, unsigned int x1, unsigned int y1, enum DrawDir _dir) -{ - if (_dir == DRAW_SWNE) { - ypos = y1; // bug fix: must do it this way to draw bmp - dir = -1; - } else { - ypos = y0; - dir = 1; - } - xstart = x0; - xend = x1; - xpos = x0; -} -/* Screen coordinates are as follows: - * (128, 32) .... (0, 32) - * ... .... ... - * (128, 63) .... (0, 63) - * (128, 0) .... (0, 0) - * ... .... ... - * (128, 31) .... (0, 31) - */ -void LCD_DrawStop(void) -{ - int col = 0; - int p, c; - for (p = 0; p < LCD_PAGES; p++) { - int init = 0; - for (c = 0; c < PHY_LCD_WIDTH; c++) { - if(dirty[c] & (1 << p)) { - if(! init) { - lcd_set_page_address(p); - lcd_set_column_address(c); - } else if(col+1 != c) { - lcd_set_column_address(c); - } - LCD_Data(img[p * PHY_LCD_WIDTH + c]); - col = c; - } - } - } - memset(dirty, 0, sizeof(dirty)); -} - -void LCD_DrawPixel(unsigned int color) -{ - if (xpos < LCD_WIDTH && ypos < LCD_HEIGHT) { // both are unsigned, can not be < 0 - int y = ypos; - int x = xpos; - int ycol = y / 8; - int ybit = y & 0x07; - if (color) { - img[ycol * PHY_LCD_WIDTH + x] |= 1 << ybit; - } else { - img[ycol * PHY_LCD_WIDTH + x] &= ~(1 << ybit); - } - dirty[x] |= 1 << ycol; - } - // this must be executed to continue drawing in the next row - xpos++; - if (xpos > xend) { - xpos = xstart; - ypos += dir; - } -} - -void LCD_DrawPixelXY(unsigned int x, unsigned int y, unsigned int color) -{ - xpos = x; - ypos = y; - LCD_DrawPixel(color); -} diff --git a/src/target/drivers/display/spi/128x64x1_oled_ssd1306.h b/src/target/drivers/display/spi/128x64x1_oled_ssd1306.h new file mode 100644 index 0000000000..0633617cf5 --- /dev/null +++ b/src/target/drivers/display/spi/128x64x1_oled_ssd1306.h @@ -0,0 +1,74 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ + +#include "target/drivers/mcu/stm32/rcc.h" + +void lcd_display(uint8_t on); + +inline static unsigned _oled_contrast_func(unsigned contrast) { + return contrast * contrast * 255 / 100; // contrast should range from 0 to 255 +} + +inline static void _oled_reset() +{ + // No reset for OLED +} + +inline static void _oled_init() +{ + LCD_Cmd(0xD5); // Set Display Clock Divide Ratio / OSC Frequency + LCD_Cmd(0x80); // Display Clock Divide Ratio / OSC Frequency + LCD_Cmd(0xA8); // Set Multiplex Ratio + LCD_Cmd(0x3F); // Multiplex Ratio for 128x64 (LCD_HEIGHT - 1) + LCD_Cmd(0xD3); // Set Display Offset + LCD_Cmd(0x00); // Display Offset (0) + LCD_Cmd(0x40); // Set Display Start Line (0) + LCD_Cmd(0x8D); // Set Charge Pump + LCD_Cmd(0x10); // Charge Pump (0x10 External, 0x14 Internal DC/DC) + LCD_Cmd(0xA1); // Set Segment Re-Map (Reversed) + LCD_Cmd(0xC8); // Set Com Output Scan Direction (Reversed) + LCD_Cmd(0xDA); // Set COM Hardware Configuration + LCD_Cmd(0x12); // COM Hardware Configuration + LCD_Cmd(0xD9); // Set Pre-Charge Period + LCD_Cmd(0x4F); // Set Pre-Charge Period (A[7:4]:Phase 2, A[3:0]:Phase 1) + LCD_Cmd(0xDB); // Set VCOMH Deselect Level + LCD_Cmd(0x20); // VCOMH Deselect Level (0x00 ~ 0.65 x VCC, 0x10 ~ 0.71 x VCC, 0x20 ~ 0.77 x VCC, 0x30 ~ 0.83 x VCC) + LCD_Cmd(0xA4); // Disable Entire Display On + LCD_Cmd(0xA6); // Set Normal Display (not inverted) + LCD_Cmd(0x2E); // Deactivate scroll +} + +/* These are called by backlight.c */ +void OLED_Backlight() { + rcc_periph_clock_enable(get_rcc_from_pin(BACKLIGHT_TIM.pin)); + // Turn off backlight + GPIO_setup_input(BACKLIGHT_TIM.pin, ITYPE_FLOAT); +} + +void OLED_Backlight_Brightness(unsigned brightness) +{ + LCD_Contrast(brightness); + if (brightness == 0) { + lcd_display(0); // Display Off + // Charge Pump disable + // LCD_Cmd(0x8D); // Set Charge Pump + // LCD_Cmd(0x10); // Charge Pump (0x10 External, 0x14 Internal DC/DC) + } else { + // Charge Pump enable + // LCD_Cmd(0x8D); // Set Charge Pump + // LCD_Cmd(0x14); // Charge Pump (0x10 External, 0x14 Internal DC/DC) + lcd_display(1); // Display On + } +} diff --git a/src/target/tx/devo/common/Makefile.inc b/src/target/tx/devo/common/Makefile.inc index e2faf0b06d..3c96450887 100644 --- a/src/target/tx/devo/common/Makefile.inc +++ b/src/target/tx/devo/common/Makefile.inc @@ -1,6 +1,7 @@ HAS_4IN1_FLASH ?= 0 HAS_FLASH_DETECT ?= 0 USE_JTAG ?= 0 +DFU_STRING ?= "$(HGVERSION) Firmware" ifndef BUILD_TARGET @@ -117,7 +118,7 @@ $(LIBOPENCM3): +$(FLOCKS) $(MAKE) -C $(SDIR)/libopencm3 TARGETS=stm32/f1 lib $(TARGET).dfu: $(TARGET).bin - $(SDIR)/../utils/dfu.py --name "$(HGVERSION) Firmware" $(DFU_ARGS):$< $@ + $(SDIR)/../utils/dfu.py --name $(DFU_STRING) $(DFU_ARGS):$< $@ $(SDIR)/../utils/get_mem_usage.pl $(TARGET).map ################################### diff --git a/src/target/tx/devo/common/common_devo.h b/src/target/tx/devo/common/common_devo.h index 20fe43402f..d13b945620 100644 --- a/src/target/tx/devo/common/common_devo.h +++ b/src/target/tx/devo/common/common_devo.h @@ -40,4 +40,9 @@ static inline void LCD_ForceUpdate() {} #ifndef HAS_PWR_SWITCH_INVERTED #define HAS_PWR_SWITCH_INVERTED 0 #endif + +#ifndef HAS_OLED_DISPLAY + #define HAS_OLED_DISPLAY 0 + #define TXTYPE "" +#endif #endif //_COMMON_DEVO_H_ diff --git a/src/target/tx/devo/common/hardware.h b/src/target/tx/devo/common/hardware.h index 546d6b1561..2a26f176b0 100644 --- a/src/target/tx/devo/common/hardware.h +++ b/src/target/tx/devo/common/hardware.h @@ -49,6 +49,10 @@ }) #endif +// This will be overridden by the OLED driver if needed +#define LCD_SPI_RATE SPI_CR1_BR_FPCLK_DIV_4 +#define OLED_SPI_RATE SPI_CR1_BR_FPCLK_DIV_8 + #ifndef FLASH_SPI #define FLASH_SPI ((struct spi_csn) { \ .spi = SPI1, \ @@ -65,9 +69,7 @@ .sck = {GPIOA, GPIO5}, \ .miso = {GPIOA, GPIO6}, \ .mosi = {GPIOA, GPIO7}, \ - .rate = HAS_OLED_DISPLAY \ - ? SPI_CR1_BR_FPCLK_DIV_8 \ - : SPI_CR1_BR_FPCLK_DIV_4, \ + .rate = LCD_SPI_RATE, \ DEFAULT_SPI_SETTINGS, \ }) #endif // SPI1_CFG @@ -86,9 +88,7 @@ .sck = {GPIOA, GPIO5}, \ .miso = {GPIOA, GPIO6}, \ .mosi = {GPIOA, GPIO7}, \ - .rate = HAS_OLED_DISPLAY \ - ? SPI_CR1_BR_FPCLK_DIV_8 \ - : SPI_CR1_BR_FPCLK_DIV_4, \ + .rate = LCD_SPI_RATE \ DEFAULT_SPI_SETTINGS, \ }) #endif // SPI1_CFG diff --git a/src/target/tx/devo/devo10/Makefile.inc b/src/target/tx/devo/devo10/Makefile.inc index c53ad3faa6..72d48651ab 100644 --- a/src/target/tx/devo/devo10/Makefile.inc +++ b/src/target/tx/devo/devo10/Makefile.inc @@ -1,6 +1,6 @@ FILESYSTEMS := common base_fonts 128x64x1 SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := 8080/128x64x1_nt7538.c +DISPLAY_DRIVER := 8080/128x64x1.c DFU_ARGS := -c 10 -b 0x08004000 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ filesystem/$(FILESYSTEM)/media/04b03.fon diff --git a/src/target/tx/devo/devo10/target_defs.h b/src/target/tx/devo/devo10/target_defs.h index 9ec0e495c0..6236a43d46 100644 --- a/src/target/tx/devo/devo10/target_defs.h +++ b/src/target/tx/devo/devo10/target_defs.h @@ -32,6 +32,8 @@ #define DEBUG_WINDOW_SIZE 0 #endif +#define HAS_LCD_SWAPPED_PAGES 1 + #define MIN_BRIGHTNESS 0 #define DEFAULT_BATTERY_ALARM 8000 #define DEFAULT_BATTERY_CRITICAL 7500 diff --git a/src/target/tx/devo/devo7e-256/Makefile.inc b/src/target/tx/devo/devo7e-256/Makefile.inc index 8b4451ea24..661da88f02 100644 --- a/src/target/tx/devo/devo7e-256/Makefile.inc +++ b/src/target/tx/devo/devo7e-256/Makefile.inc @@ -1,5 +1,5 @@ SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := spi/128x64x1_nt7538.c +DISPLAY_DRIVER := spi/128x64x1.c FILESYSTEMS := common base_fonts 128x64x1 DFU_ARGS := -c 7 -b 0x08003000 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ diff --git a/src/target/tx/devo/devo7e/Makefile.inc b/src/target/tx/devo/devo7e/Makefile.inc index 3f601efe46..39617d27c3 100644 --- a/src/target/tx/devo/devo7e/Makefile.inc +++ b/src/target/tx/devo/devo7e/Makefile.inc @@ -1,5 +1,5 @@ SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := spi/128x64x1_nt7538.c +DISPLAY_DRIVER := spi/128x64x1.c FILESYSTEMS := common base_fonts 128x64x1 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ filesystem/$(FILESYSTEM)/media/04b03.fon diff --git a/src/target/tx/devo/emu_t8sg/target_defs.h b/src/target/tx/devo/emu_t8sg/target_defs.h index 9fe3f846ac..d44146460e 100644 --- a/src/target/tx/devo/emu_t8sg/target_defs.h +++ b/src/target/tx/devo/emu_t8sg/target_defs.h @@ -1,5 +1,11 @@ #include "target/drivers/mcu/emu/common_emu.h" #include "../t8sg/target_defs.h" +#undef HAS_OLED_DISPLAY +char *getenv(const char *); +static inline int _HAS_OLED_DISPLAY() { + return getenv("OLED") ? 1 : 0; +} +#define HAS_OLED_DISPLAY _HAS_OLED_DISPLAY() #define BUTTON_MAP { 'A', 'Q', 'D', 'E', 'S', 'W', 'F', 'R', FL_Left, FL_Right, FL_Down, FL_Up, 13/*FL_Enter*/, FL_Escape, 0 } diff --git a/src/target/tx/devo/t8sg/Makefile.inc b/src/target/tx/devo/t8sg/Makefile.inc index 469f09d1ac..9eaa395c68 100644 --- a/src/target/tx/devo/t8sg/Makefile.inc +++ b/src/target/tx/devo/t8sg/Makefile.inc @@ -1,13 +1,12 @@ SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := spi/128x64x1_nt7538.c +DISPLAY_DRIVER := spi/128x64x1.c FILESYSTEMS := common base_fonts 128x64x1 -DFU_ARGS := -c 7 -b 0x08003000 +DFU_STRING := "$(HGVERSION) Unified Firmware" +DFU_ARGS := -c 0 -b 0x08006000 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ filesystem/$(FILESYSTEM)/media/04b03.fon LANGUAGE := devo10 -OPTIMIZE_DFU := 1 - include $(SDIR)/target/tx/devo/common/Makefile.inc ifdef BUILD_TARGET @@ -20,7 +19,7 @@ $(TARGET).fs_wrapper: $(LAST_MODEL) perl -p -i -e 's/; enable-nrf24l01 = A14/ enable-nrf24l01 = A15/' filesystem/$(FILESYSTEM)/hardware.ini perl -p -i -e 's/; has_pa-nrf24l01 = 1/ has_pa-nrf24l01 = 1/' filesystem/$(FILESYSTEM)/hardware.ini perl -p -i -e 's/;switch_types: 3x2, 3x1, 2x2/;switch_types: 3x4, 3x3, 3x2, 3x1, 2x8, 2x7, 2x6, 2x5, 2x4, 2x3, 2x2, 2x1, potx2, potx1\n;May occur more than once if necessary.\n;Add nostock if stock FMOD and HOLD switches have been removed./' filesystem/$(FILESYSTEM)/hardware.ini - perl -p -i -e 's/;extra-switches=/ extra-switches = nostock\n extra-switches = 3x4\n; extra-switches = 2x2\n extra-switches = potx2/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/;extra-switches=/ extra-switches = nostock\n extra-switches = 3x4\n extra-switches = 2x2\n extra-switches = potx2/' filesystem/$(FILESYSTEM)/hardware.ini rm -f filesystem/$(FILESYSTEM)/hardware.ini.bak endif diff --git a/src/target/tx/devo/t8sg/channels.c b/src/target/tx/devo/t8sg/channels.c index 80b9eca842..49ca74e6f3 100644 --- a/src/target/tx/devo/t8sg/channels.c +++ b/src/target/tx/devo/t8sg/channels.c @@ -10,7 +10,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with Deviation. If not, see . + along with Deviation. If not, see . */ #include #include @@ -19,7 +19,7 @@ #include "config/tx.h" #include "../common/devo.h" -//Duplicated in tx_buttons.c +// Duplicated in tx_buttons.c #define IGNORE_MASK ((1 << INP_AILERON) | (1 << INP_ELEVATOR) | (1 << INP_THROTTLE) | (1 << INP_RUDDER) | (1 << INP_NONE) | (1 << INP_LAST)) #define SWITCH_3x4 ((1 << INP_SWA0) | (1 << INP_SWA1) | (1 << INP_SWA2) \ | (1 << INP_SWB0) | (1 << INP_SWB1) | (1 << INP_SWB2) \ @@ -70,7 +70,7 @@ #define SWITCH_STOCK ((1 << INP_HOLD0) | (1 << INP_HOLD1) \ | (1 << INP_FMOD0) | (1 << INP_FMOD1)) -//Duplicated in tx_buttons.c +// Duplicated in tx_buttons.c enum { SW_01 = 23, SW_02, @@ -93,6 +93,7 @@ void CHAN_Init() ADC_Init(); rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + /* configure switches for digital I/O */ gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO10 | GPIO11); @@ -103,11 +104,11 @@ s32 CHAN_ReadRawInput(int channel) { s32 value = 0; if ((~Transmitter.ignore_src & SWITCH_STOCK) == SWITCH_STOCK) { - switch(channel) { + switch (channel) { case INP_HOLD0: value = gpio_get(GPIOC, GPIO11); break; - case INP_HOLD1: value = ! gpio_get(GPIOC, GPIO11); break; + case INP_HOLD1: value = !gpio_get(GPIOC, GPIO11); break; case INP_FMOD0: value = gpio_get(GPIOC, GPIO10); break; - case INP_FMOD1: value = ! gpio_get(GPIOC, GPIO10); break; + case INP_FMOD1: value = !gpio_get(GPIOC, GPIO10); break; case INP_SWA0: value = global_extra_switches & 0x04; break; case INP_SWA1: value = !(global_extra_switches & 0x0c); break; case INP_SWA2: value = global_extra_switches & 0x08; break; @@ -121,89 +122,89 @@ s32 CHAN_ReadRawInput(int channel) } } else { if ((~Transmitter.ignore_src & SWITCH_3x1) == SWITCH_3x1) { - switch(channel) { + switch (channel) { case INP_SWA0: value = (global_extra_switches & (1 << (SW_02 - 1))); break; case INP_SWA1: value = (!(global_extra_switches & (1 << (SW_01 - 1))) && !(global_extra_switches & (1 << (SW_02 - 1)))); break; case INP_SWA2: value = (global_extra_switches & (1 << (SW_01 - 1))); break; } } else if ((~Transmitter.ignore_src & SWITCH_2x8) == SWITCH_2x8) { - switch(channel) { + switch (channel) { case INP_SWA0: value = !(global_extra_switches & (1 << (SW_03 - 1))); break; case INP_SWA1: value = (global_extra_switches & (1 << (SW_03 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_3x2) == SWITCH_3x2) { - switch(channel) { + switch (channel) { case INP_SWB0: value = (global_extra_switches & (1 << (SW_04 - 1))); break; case INP_SWB1: value = (!(global_extra_switches & (1 << (SW_03 - 1))) && !(global_extra_switches & (1 << (SW_04 - 1)))); break; case INP_SWB2: value = (global_extra_switches & (1 << (SW_03 - 1))); break; } } else if ((~Transmitter.ignore_src & SWITCH_2x7) == SWITCH_2x7) { - switch(channel) { + switch (channel) { case INP_SWB0: value = !(global_extra_switches & (1 << (SW_04 - 1))); break; case INP_SWB1: value = (global_extra_switches & (1 << (SW_04 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_3x3) == SWITCH_3x3) { - switch(channel) { + switch (channel) { case INP_SWC0: value = (global_extra_switches & (1 << (SW_06 - 1))); break; case INP_SWC1: value = (!(global_extra_switches & (1 << (SW_05 - 1))) && !(global_extra_switches & (1 << (SW_06 - 1)))); break; case INP_SWC2: value = (global_extra_switches & (1 << (SW_05 - 1))); break; } } else if ((~Transmitter.ignore_src & SWITCH_2x6) == SWITCH_2x6) { - switch(channel) { + switch (channel) { case INP_SWC0: value = !(global_extra_switches & (1 << (SW_05 - 1))); break; case INP_SWC1: value = (global_extra_switches & (1 << (SW_05 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_3x4) == SWITCH_3x4) { - switch(channel) { + switch (channel) { case INP_SWD0: value = (global_extra_switches & (1 << (SW_08 - 1))); break; case INP_SWD1: value = (!(global_extra_switches & (1 << (SW_07 - 1))) && !(global_extra_switches & (1 << (SW_08 - 1)))); break; case INP_SWD2: value = (global_extra_switches & (1 << (SW_07 - 1))); break; } } else if ((~Transmitter.ignore_src & SWITCH_2x5) == SWITCH_2x5) { - switch(channel) { + switch (channel) { case INP_SWD0: value = !(global_extra_switches & (1 << (SW_06 - 1))); break; case INP_SWD1: value = (global_extra_switches & (1 << (SW_06 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_2x4) == SWITCH_2x4) { - switch(channel) { + switch (channel) { case INP_SWE0: value = !(global_extra_switches & (1 << (SW_07 - 1))); break; case INP_SWE1: value = (global_extra_switches & (1 << (SW_07 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_2x3) == SWITCH_2x3) { - switch(channel) { + switch (channel) { case INP_SWF0: value = !(global_extra_switches & (1 << (SW_08 - 1))); break; case INP_SWF1: value = (global_extra_switches & (1 << (SW_08 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_2x2) == SWITCH_2x2) { - switch(channel) { + switch (channel) { case INP_SWG0: value = !(global_extra_switches & (1 << (SW_09 - 1))); break; case INP_SWG1: value = (global_extra_switches & (1 << (SW_09 - 1))); break; } } if ((~Transmitter.ignore_src & SWITCH_2x1) == SWITCH_2x1) { - switch(channel) { + switch (channel) { case INP_SWH0: value = !(global_extra_switches & (1 << (SW_10 - 1))); break; case INP_SWH1: value = (global_extra_switches & (1 << (SW_10 - 1))); break; } } } if ((~Transmitter.ignore_src & POT_1) == POT_1) { - switch(channel) { + switch (channel) { case INP_AUX4: value = adc_array_raw[4]; break; } } if ((~Transmitter.ignore_src & POT_2) == POT_2) { - switch(channel) { + switch (channel) { case INP_AUX5: value = adc_array_raw[5]; break; } } - switch(channel) { + switch (channel) { case INP_THROTTLE: value = adc_array_raw[0]; break; // bug fix: right vertical case INP_AILERON: value = adc_array_raw[1]; break; // bug fix: right horizon case INP_RUDDER: value = adc_array_raw[2]; break; // bug fix: left horizon @@ -214,23 +215,23 @@ s32 CHAN_ReadRawInput(int channel) s32 CHAN_ReadInput(int channel) { s32 value = CHAN_ReadRawInput(channel); - if(channel <= INP_HAS_CALIBRATION) { + if (channel <= INP_HAS_CALIBRATION) { s32 max = Transmitter.calibration[channel - 1].max; s32 min = Transmitter.calibration[channel - 1].min; s32 zero = Transmitter.calibration[channel - 1].zero; - if(! zero) { - //If this input doesn't have a zero, calculate from max/min + if (!zero) { + // If this input doesn't have a zero, calculate from max/min zero = ((u32)max + min) / 2; } // Derate min and max by 1% to ensure we can get all the way to 100% max = (max - zero) * 99 / 100; min = (min - zero) * 99 / 100; - if(value >= zero) { + if (value >= zero) { value = (value - zero) * CHAN_MAX_VALUE / max; } else { value = (value - zero) * CHAN_MIN_VALUE / min; } - //Bound output + // Bound output if (value > CHAN_MAX_VALUE) value = CHAN_MAX_VALUE; if (value < CHAN_MIN_VALUE) @@ -238,42 +239,42 @@ s32 CHAN_ReadInput(int channel) } else { value = value ? CHAN_MAX_VALUE : CHAN_MIN_VALUE; } - if (channel == INP_THROTTLE || channel == INP_AILERON || channel == INP_AUX4 || channel == INP_AUX5) + if (channel == INP_THROTTLE || channel == INP_AILERON || channel == INP_AUX4) value = -value; return value; } void CHAN_SetSwitchCfg(const char *str) { - if(strcmp(str, "3x4") == 0) { + if (strcmp(str, "3x4") == 0) { Transmitter.ignore_src &= ~SWITCH_3x4; - } else if(strcmp(str, "3x3") == 0) { + } else if (strcmp(str, "3x3") == 0) { Transmitter.ignore_src &= ~SWITCH_3x3; - } else if(strcmp(str, "3x2") == 0) { + } else if (strcmp(str, "3x2") == 0) { Transmitter.ignore_src &= ~SWITCH_3x2; - } else if(strcmp(str, "3x1") == 0) { + } else if (strcmp(str, "3x1") == 0) { Transmitter.ignore_src &= ~SWITCH_3x1; - } else if(strcmp(str, "2x8") == 0) { + } else if (strcmp(str, "2x8") == 0) { Transmitter.ignore_src &= ~SWITCH_2x8; - } else if(strcmp(str, "2x7") == 0) { + } else if (strcmp(str, "2x7") == 0) { Transmitter.ignore_src &= ~SWITCH_2x7; - } else if(strcmp(str, "2x6") == 0) { + } else if (strcmp(str, "2x6") == 0) { Transmitter.ignore_src &= ~SWITCH_2x6; - } else if(strcmp(str, "2x5") == 0) { + } else if (strcmp(str, "2x5") == 0) { Transmitter.ignore_src &= ~SWITCH_2x5; - } else if(strcmp(str, "2x4") == 0) { + } else if (strcmp(str, "2x4") == 0) { Transmitter.ignore_src &= ~SWITCH_2x4; - } else if(strcmp(str, "2x3") == 0) { + } else if (strcmp(str, "2x3") == 0) { Transmitter.ignore_src &= ~SWITCH_2x3; - } else if(strcmp(str, "2x2") == 0) { + } else if (strcmp(str, "2x2") == 0) { Transmitter.ignore_src &= ~SWITCH_2x2; - } else if(strcmp(str, "2x1") == 0) { + } else if (strcmp(str, "2x1") == 0) { Transmitter.ignore_src &= ~SWITCH_2x1; - } else if(strcmp(str, "potx2") == 0) { + } else if (strcmp(str, "potx2") == 0) { Transmitter.ignore_src &= ~POT_2; - } else if(strcmp(str, "potx1") == 0) { + } else if (strcmp(str, "potx1") == 0) { Transmitter.ignore_src &= ~POT_1; - } else if(strcmp(str, "nostock") == 0) { + } else if (strcmp(str, "nostock") == 0) { Transmitter.ignore_src |= SWITCH_STOCK; } else { Transmitter.ignore_src = ~IGNORE_MASK & ~SWITCH_STOCK; diff --git a/src/target/tx/devo/t8sg/hardware.h b/src/target/tx/devo/t8sg/hardware.h index 9afd7ab08e..98243bceec 100644 --- a/src/target/tx/devo/t8sg/hardware.h +++ b/src/target/tx/devo/t8sg/hardware.h @@ -26,4 +26,5 @@ ADC_CHAN(GPIOC, GPIO4), /* ADC12_14 */ \ } #endif // HAS_EXTRA_POTS + #endif // _DEVO7E256_HARDWARE_H_ diff --git a/src/target/tx/devo/t8sg/t8sg.common.ld b/src/target/tx/devo/t8sg/t8sg.common.ld new file mode 100644 index 0000000000..b2b50e48af --- /dev/null +++ b/src/target/tx/devo/t8sg/t8sg.common.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + } >rom + .rodata :{ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + } >rom + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/src/target/tx/devo/t8sg/t8sg.ld b/src/target/tx/devo/t8sg/t8sg.ld index b15aa4df03..b9b26da64d 100644 --- a/src/target/tx/devo/t8sg/t8sg.ld +++ b/src/target/tx/devo/t8sg/t8sg.ld @@ -1,8 +1,7 @@ MEMORY { /* Devo7e-256 has 256K, and bootloader takes up 12K */ - rom (rx) : ORIGIN = 0x08003000, LENGTH = 244K + rom (rx) : ORIGIN = 0x08006000, LENGTH = 232K ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K } -_crc_offset = 0x2000; /* CRC is located at 0x08005000 */ -INCLUDE target/tx/devo/common/devo.ld +INCLUDE target/tx/devo/t8sg/t8sg.common.ld diff --git a/src/target/tx/devo/t8sg/target_defs.h b/src/target/tx/devo/t8sg/target_defs.h index 2ebda82797..e81d01349a 100644 --- a/src/target/tx/devo/t8sg/target_defs.h +++ b/src/target/tx/devo/t8sg/target_defs.h @@ -1,13 +1,10 @@ -#ifndef _T8SG_TARGET_H_ -#define _T8SG_TARGET_H_ +#ifndef _T8SG_V2_PLUS_TARGET_H_ +#define _T8SG_V2_PLUS_TARGET_H_ -#define TXID 0x18 -#define VECTOR_TABLE_LOCATION 0x3000 +#define TXID 0x7e +#define VECTOR_TABLE_LOCATION 0x6000 +#define HAS_FLASH_DETECT 1 #define SPIFLASH_SECTOR_OFFSET 0 -#define SPIFLASH_SECTORS 512 - -#define HAS_LCD_FLIPPED 1 -#define LCD_CONTRAST_FUNC(x) (x) #define HAS_STANDARD_GUI 1 #define HAS_ADVANCED_GUI 1 @@ -31,6 +28,16 @@ #define HAS_AUDIO_UART 1 #define HAS_MUSIC_CONFIG 1 +// TXTYPE points at a memory address inside the bootloader that +// contains the tx model name. Only Transmitters using deviation-bootloader +// will have this string. It is always located right after the jump table, +// And is 12 bytes long. Current valid values are: +// T8SGV1, T8SGV2, T8SGV2+, T8SGV3, T8SGV3+ +#define TXTYPE ((char *)(0x08000000 + VECTOR_TABLE_LOCATION - 0x3000 + 0x400)) +#define HAS_OLED_DISPLAY (TXTYPE[6] == '+') +#define LCD_CONTRAST_FUNC(x) (x) +#define HAS_LCD_FLIPPED 1 + #ifdef BUILDTYPE_DEV #define DEBUG_WINDOW_SIZE 200 #else @@ -38,8 +45,8 @@ #endif #define MIN_BRIGHTNESS 0 -#define DEFAULT_BATTERY_ALARM 7400 -#define DEFAULT_BATTERY_CRITICAL 7100 +#define DEFAULT_BATTERY_ALARM 4100 +#define DEFAULT_BATTERY_CRITICAL 3900 #define MAX_BATTERY_ALARM 12000 #define MIN_BATTERY_ALARM 3300 #define MAX_POWER_ALARM 60 @@ -64,4 +71,4 @@ #include "hardware.h" #include "../common/common_devo.h" -#endif //_T8SG_TARGET_H_ +#endif // _T8SG_V2_PLUS_TARGET_H_ diff --git a/src/target/tx/devo/t8sg_v1/Makefile.inc b/src/target/tx/devo/t8sg_v1/Makefile.inc new file mode 100644 index 0000000000..0dc9bf5801 --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/Makefile.inc @@ -0,0 +1,26 @@ +SCREENSIZE := 128x64x1 +DISPLAY_DRIVER := spi/128x64x1.c +FILESYSTEMS := common base_fonts 128x64x1 +DFU_ARGS := -c 7 -b 0x08003000 +FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ + filesystem/$(FILESYSTEM)/media/04b03.fon +LANGUAGE := devo10 + +OPTIMIZE_DFU := 1 + +include $(SDIR)/target/tx/devo/common/Makefile.inc + +ifdef BUILD_TARGET + +$(TARGET).fs_wrapper: $(LAST_MODEL) + perl -p -i -e 's/; enable-a7105 = A13/ enable-a7105 = A13/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/; has_pa-a7105 = 1/ has_pa-a7105 = 1/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/; enable-cc2500 = A14/ enable-cc2500 = A14/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/; has_pa-cc2500 = 1/ has_pa-cc2500 = 1/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/; enable-nrf24l01 = A14/ enable-nrf24l01 = A15/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/; has_pa-nrf24l01 = 1/ has_pa-nrf24l01 = 1/' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/;switch_types: 3x2, 3x1, 2x2/;switch_types: 3x4, 3x3, 3x2, 3x1, 2x8, 2x7, 2x6, 2x5, 2x4, 2x3, 2x2, 2x1, potx2, potx1\n;May occur more than once if necessary.\n;Add nostock if stock FMOD and HOLD switches have been removed./' filesystem/$(FILESYSTEM)/hardware.ini + perl -p -i -e 's/;extra-switches=/ extra-switches = nostock\n extra-switches = 3x4\n; extra-switches = 2x2\n extra-switches = potx2/' filesystem/$(FILESYSTEM)/hardware.ini + rm -f filesystem/$(FILESYSTEM)/hardware.ini.bak + +endif diff --git a/src/target/tx/devo/t8sg_v1/capabilities.h b/src/target/tx/devo/t8sg_v1/capabilities.h new file mode 100644 index 0000000000..3a7a95ae48 --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/capabilities.h @@ -0,0 +1,92 @@ +#ifdef CHANDEF + CHANDEF(AILERON) + CHANDEF(ELEVATOR) + CHANDEF(THROTTLE) + CHANDEF(RUDDER) + CHANDEF(AUX4) + CHANDEF(AUX5) + CHANDEF(HOLD0) + CHANDEF(HOLD1) + CHANDEF(FMOD0) + CHANDEF(FMOD1) + CHANDEF(SWA0) + CHANDEF(SWA1) + CHANDEF(SWA2) + CHANDEF(SWB0) + CHANDEF(SWB1) + CHANDEF(SWB2) + CHANDEF(SWC0) + CHANDEF(SWC1) + CHANDEF(SWC2) + CHANDEF(SWD0) + CHANDEF(SWD1) + CHANDEF(SWD2) + CHANDEF(SWE0) + CHANDEF(SWE1) + CHANDEF(SWF0) + CHANDEF(SWF1) + CHANDEF(SWG0) + CHANDEF(SWG1) + CHANDEF(SWH0) + CHANDEF(SWH1) +#endif + +#ifdef UNDEF_INP +#define INP_RUD_DR0 INP_SWD0 +#define INP_RUD_DR1 INP_SWD1 +#define INP_ELE_DR0 INP_SWD0 +#define INP_ELE_DR1 INP_SWD1 +#define INP_AIL_DR0 INP_SWD0 +#define INP_AIL_DR1 INP_SWD1 +#define INP_FMOD2 INP_SWA2 +#define INP_MIX0 INP_SWC0 +#define INP_MIX1 INP_SWC1 +#define INP_MIX2 INP_SWC2 +#define INP_GEAR0 INP_SWB0 +#define INP_GEAR1 INP_SWB1 +#endif + +#ifdef CHANMAP +// These are legacy mappings + CHANMAP("DR", SWD1) + CHANMAP("RUD DR", SWD1) + CHANMAP("ELE_DR", SWD1) + CHANMAP("AIL_DR", SWD1) + CHANMAP("GEAR", SWB1) +// Current mappings + CHANMAP("DR0", SWD0) + CHANMAP("DR1", SWD1) + CHANMAP("RUD DR0", SWD0) + CHANMAP("RUD DR1", SWD1) + CHANMAP("ELE DR0", SWD0) + CHANMAP("ELE DR1", SWD1) + CHANMAP("AIL DR0", SWD0) + CHANMAP("AIL DR1", SWD1) + CHANMAP("HOLD0", SWD0) + CHANMAP("HOLD1", SWD1) + CHANMAP("FMODE0", SWA0) + CHANMAP("FMODE1", SWA1) + CHANMAP("FMODE2", SWA2) + CHANMAP("MIX0", SWC0) + CHANMAP("MIX1", SWC1) + CHANMAP("MIX2", SWC2) + CHANMAP("GEAR0", SWB0) + CHANMAP("GEAR1", SWB1) +#endif + +#ifdef BUTTONDEF + BUTTONDEF(TRIM_LV_NEG) /* LEFT-VERTICAL */ + BUTTONDEF(TRIM_LV_POS) + BUTTONDEF(TRIM_RV_NEG) /* RIGHT-VERTICAL */ + BUTTONDEF(TRIM_RV_POS) + BUTTONDEF(TRIM_LH_NEG) /* LEFT-HORIZONTAL */ + BUTTONDEF(TRIM_LH_POS) + BUTTONDEF(TRIM_RH_NEG) /* RIGHT-HORIZONTAL */ + BUTTONDEF(TRIM_RH_POS) + BUTTONDEF(LEFT) + BUTTONDEF(RIGHT) + BUTTONDEF(DOWN) + BUTTONDEF(UP) + BUTTONDEF(ENTER) + BUTTONDEF(EXIT) +#endif diff --git a/src/target/tx/devo/t8sg_v1/channels.c b/src/target/tx/devo/t8sg_v1/channels.c new file mode 100644 index 0000000000..49ca74e6f3 --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/channels.c @@ -0,0 +1,282 @@ +/* + This project is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Deviation 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. + + You should have received a copy of the GNU General Public License + along with Deviation. If not, see . +*/ +#include +#include +#include "common.h" +#include "mixer.h" +#include "config/tx.h" +#include "../common/devo.h" + +// Duplicated in tx_buttons.c +#define IGNORE_MASK ((1 << INP_AILERON) | (1 << INP_ELEVATOR) | (1 << INP_THROTTLE) | (1 << INP_RUDDER) | (1 << INP_NONE) | (1 << INP_LAST)) +#define SWITCH_3x4 ((1 << INP_SWA0) | (1 << INP_SWA1) | (1 << INP_SWA2) \ + | (1 << INP_SWB0) | (1 << INP_SWB1) | (1 << INP_SWB2) \ + | (1 << INP_SWC0) | (1 << INP_SWC1) | (1 << INP_SWC2) \ + | (1 << INP_SWD0) | (1 << INP_SWD1) | (1 << INP_SWD2)) +#define SWITCH_3x3 ((1 << INP_SWA0) | (1 << INP_SWA1) | (1 << INP_SWA2) \ + | (1 << INP_SWB0) | (1 << INP_SWB1) | (1 << INP_SWB2) \ + | (1 << INP_SWC0) | (1 << INP_SWC1) | (1 << INP_SWC2)) +#define SWITCH_3x2 ((1 << INP_SWA0) | (1 << INP_SWA1) | (1 << INP_SWA2) \ + | (1 << INP_SWB0) | (1 << INP_SWB1) | (1 << INP_SWB2)) +#define SWITCH_3x1 ((1 << INP_SWA0) | (1 << INP_SWA1) | (1 << INP_SWA2)) +#define SWITCH_2x8 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1) \ + | (1 << INP_SWE0) | (1 << INP_SWE1) \ + | (1 << INP_SWD0) | (1 << INP_SWD1) \ + | (1 << INP_SWC0) | (1 << INP_SWC1) \ + | (1 << INP_SWB0) | (1 << INP_SWB1) \ + | (1 << INP_SWA0) | (1 << INP_SWA1)) +#define SWITCH_2x7 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1) \ + | (1 << INP_SWE0) | (1 << INP_SWE1) \ + | (1 << INP_SWD0) | (1 << INP_SWD1) \ + | (1 << INP_SWC0) | (1 << INP_SWC1) \ + | (1 << INP_SWB0) | (1 << INP_SWB1)) +#define SWITCH_2x6 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1) \ + | (1 << INP_SWE0) | (1 << INP_SWE1) \ + | (1 << INP_SWD0) | (1 << INP_SWD1) \ + | (1 << INP_SWC0) | (1 << INP_SWC1)) +#define SWITCH_2x5 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1) \ + | (1 << INP_SWE0) | (1 << INP_SWE1) \ + | (1 << INP_SWD0) | (1 << INP_SWD1)) +#define SWITCH_2x4 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1) \ + | (1 << INP_SWE0) | (1 << INP_SWE1)) +#define SWITCH_2x3 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1) \ + | (1 << INP_SWF0) | (1 << INP_SWF1)) +#define SWITCH_2x2 ((1 << INP_SWH0) | (1 << INP_SWH1) \ + | (1 << INP_SWG0) | (1 << INP_SWG1)) +#define SWITCH_2x1 ((1 << INP_SWH0) | (1 << INP_SWH1)) +#define SWITCH_STOCK ((1 << INP_HOLD0) | (1 << INP_HOLD1) \ + | (1 << INP_FMOD0) | (1 << INP_FMOD1)) + +// Duplicated in tx_buttons.c +enum { + SW_01 = 23, + SW_02, + SW_03, + SW_04, + SW_05, + SW_06, + SW_07, + SW_08, + SW_09, + SW_10 +}; + +#define POT_2 ((1 << INP_AUX4) | (1 << INP_AUX5)) +#define POT_1 (1 << INP_AUX4) + +extern u32 global_extra_switches; +void CHAN_Init() +{ + ADC_Init(); + + rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_IOPCEN); + + /* configure switches for digital I/O */ + gpio_set_mode(GPIOC, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, + GPIO10 | GPIO11); + gpio_set(GPIOC, GPIO10 | GPIO11); +} + +s32 CHAN_ReadRawInput(int channel) +{ + s32 value = 0; + if ((~Transmitter.ignore_src & SWITCH_STOCK) == SWITCH_STOCK) { + switch (channel) { + case INP_HOLD0: value = gpio_get(GPIOC, GPIO11); break; + case INP_HOLD1: value = !gpio_get(GPIOC, GPIO11); break; + case INP_FMOD0: value = gpio_get(GPIOC, GPIO10); break; + case INP_FMOD1: value = !gpio_get(GPIOC, GPIO10); break; + case INP_SWA0: value = global_extra_switches & 0x04; break; + case INP_SWA1: value = !(global_extra_switches & 0x0c); break; + case INP_SWA2: value = global_extra_switches & 0x08; break; + case INP_SWB0: value = global_extra_switches & 0x01; break; + case INP_SWB1: value = !(global_extra_switches & 0x03); break; + case INP_SWB2: value = global_extra_switches & 0x02; break; + case INP_SWG0: value = global_extra_switches & 0x04; break; + case INP_SWG1: value = !(global_extra_switches & 0x0c); break; + case INP_SWH0: value = global_extra_switches & 0x01; break; + case INP_SWH1: value = !(global_extra_switches & 0x03); break; + } + } else { + if ((~Transmitter.ignore_src & SWITCH_3x1) == SWITCH_3x1) { + switch (channel) { + case INP_SWA0: value = (global_extra_switches & (1 << (SW_02 - 1))); break; + case INP_SWA1: value = (!(global_extra_switches & (1 << (SW_01 - 1))) && !(global_extra_switches & (1 << (SW_02 - 1)))); break; + case INP_SWA2: value = (global_extra_switches & (1 << (SW_01 - 1))); break; + } + } else if ((~Transmitter.ignore_src & SWITCH_2x8) == SWITCH_2x8) { + switch (channel) { + case INP_SWA0: value = !(global_extra_switches & (1 << (SW_03 - 1))); break; + case INP_SWA1: value = (global_extra_switches & (1 << (SW_03 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_3x2) == SWITCH_3x2) { + switch (channel) { + case INP_SWB0: value = (global_extra_switches & (1 << (SW_04 - 1))); break; + case INP_SWB1: value = (!(global_extra_switches & (1 << (SW_03 - 1))) && !(global_extra_switches & (1 << (SW_04 - 1)))); break; + case INP_SWB2: value = (global_extra_switches & (1 << (SW_03 - 1))); break; + } + } else if ((~Transmitter.ignore_src & SWITCH_2x7) == SWITCH_2x7) { + switch (channel) { + case INP_SWB0: value = !(global_extra_switches & (1 << (SW_04 - 1))); break; + case INP_SWB1: value = (global_extra_switches & (1 << (SW_04 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_3x3) == SWITCH_3x3) { + switch (channel) { + case INP_SWC0: value = (global_extra_switches & (1 << (SW_06 - 1))); break; + case INP_SWC1: value = (!(global_extra_switches & (1 << (SW_05 - 1))) && !(global_extra_switches & (1 << (SW_06 - 1)))); break; + case INP_SWC2: value = (global_extra_switches & (1 << (SW_05 - 1))); break; + } + } else if ((~Transmitter.ignore_src & SWITCH_2x6) == SWITCH_2x6) { + switch (channel) { + case INP_SWC0: value = !(global_extra_switches & (1 << (SW_05 - 1))); break; + case INP_SWC1: value = (global_extra_switches & (1 << (SW_05 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_3x4) == SWITCH_3x4) { + switch (channel) { + case INP_SWD0: value = (global_extra_switches & (1 << (SW_08 - 1))); break; + case INP_SWD1: value = (!(global_extra_switches & (1 << (SW_07 - 1))) && !(global_extra_switches & (1 << (SW_08 - 1)))); break; + case INP_SWD2: value = (global_extra_switches & (1 << (SW_07 - 1))); break; + } + } else if ((~Transmitter.ignore_src & SWITCH_2x5) == SWITCH_2x5) { + switch (channel) { + case INP_SWD0: value = !(global_extra_switches & (1 << (SW_06 - 1))); break; + case INP_SWD1: value = (global_extra_switches & (1 << (SW_06 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_2x4) == SWITCH_2x4) { + switch (channel) { + case INP_SWE0: value = !(global_extra_switches & (1 << (SW_07 - 1))); break; + case INP_SWE1: value = (global_extra_switches & (1 << (SW_07 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_2x3) == SWITCH_2x3) { + switch (channel) { + case INP_SWF0: value = !(global_extra_switches & (1 << (SW_08 - 1))); break; + case INP_SWF1: value = (global_extra_switches & (1 << (SW_08 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_2x2) == SWITCH_2x2) { + switch (channel) { + case INP_SWG0: value = !(global_extra_switches & (1 << (SW_09 - 1))); break; + case INP_SWG1: value = (global_extra_switches & (1 << (SW_09 - 1))); break; + } + } + if ((~Transmitter.ignore_src & SWITCH_2x1) == SWITCH_2x1) { + switch (channel) { + case INP_SWH0: value = !(global_extra_switches & (1 << (SW_10 - 1))); break; + case INP_SWH1: value = (global_extra_switches & (1 << (SW_10 - 1))); break; + } + } + } + if ((~Transmitter.ignore_src & POT_1) == POT_1) { + switch (channel) { + case INP_AUX4: value = adc_array_raw[4]; break; + } + } + if ((~Transmitter.ignore_src & POT_2) == POT_2) { + switch (channel) { + case INP_AUX5: value = adc_array_raw[5]; break; + } + } + switch (channel) { + case INP_THROTTLE: value = adc_array_raw[0]; break; // bug fix: right vertical + case INP_AILERON: value = adc_array_raw[1]; break; // bug fix: right horizon + case INP_RUDDER: value = adc_array_raw[2]; break; // bug fix: left horizon + case INP_ELEVATOR: value = adc_array_raw[3]; break; // bug fix: left vertical + } + return value; +} +s32 CHAN_ReadInput(int channel) +{ + s32 value = CHAN_ReadRawInput(channel); + if (channel <= INP_HAS_CALIBRATION) { + s32 max = Transmitter.calibration[channel - 1].max; + s32 min = Transmitter.calibration[channel - 1].min; + s32 zero = Transmitter.calibration[channel - 1].zero; + if (!zero) { + // If this input doesn't have a zero, calculate from max/min + zero = ((u32)max + min) / 2; + } + // Derate min and max by 1% to ensure we can get all the way to 100% + max = (max - zero) * 99 / 100; + min = (min - zero) * 99 / 100; + if (value >= zero) { + value = (value - zero) * CHAN_MAX_VALUE / max; + } else { + value = (value - zero) * CHAN_MIN_VALUE / min; + } + // Bound output + if (value > CHAN_MAX_VALUE) + value = CHAN_MAX_VALUE; + if (value < CHAN_MIN_VALUE) + value = CHAN_MIN_VALUE; + } else { + value = value ? CHAN_MAX_VALUE : CHAN_MIN_VALUE; + } + if (channel == INP_THROTTLE || channel == INP_AILERON || channel == INP_AUX4) + value = -value; + return value; +} + +void CHAN_SetSwitchCfg(const char *str) +{ + if (strcmp(str, "3x4") == 0) { + Transmitter.ignore_src &= ~SWITCH_3x4; + } else if (strcmp(str, "3x3") == 0) { + Transmitter.ignore_src &= ~SWITCH_3x3; + } else if (strcmp(str, "3x2") == 0) { + Transmitter.ignore_src &= ~SWITCH_3x2; + } else if (strcmp(str, "3x1") == 0) { + Transmitter.ignore_src &= ~SWITCH_3x1; + } else if (strcmp(str, "2x8") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x8; + } else if (strcmp(str, "2x7") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x7; + } else if (strcmp(str, "2x6") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x6; + } else if (strcmp(str, "2x5") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x5; + } else if (strcmp(str, "2x4") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x4; + } else if (strcmp(str, "2x3") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x3; + } else if (strcmp(str, "2x2") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x2; + } else if (strcmp(str, "2x1") == 0) { + Transmitter.ignore_src &= ~SWITCH_2x1; + } else if (strcmp(str, "potx2") == 0) { + Transmitter.ignore_src &= ~POT_2; + } else if (strcmp(str, "potx1") == 0) { + Transmitter.ignore_src &= ~POT_1; + } else if (strcmp(str, "nostock") == 0) { + Transmitter.ignore_src |= SWITCH_STOCK; + } else { + Transmitter.ignore_src = ~IGNORE_MASK & ~SWITCH_STOCK; + } +} diff --git a/src/target/tx/devo/t8sg/crc.c b/src/target/tx/devo/t8sg_v1/crc.c similarity index 100% rename from src/target/tx/devo/t8sg/crc.c rename to src/target/tx/devo/t8sg_v1/crc.c diff --git a/src/target/tx/devo/t8sg_v1/hardware.h b/src/target/tx/devo/t8sg_v1/hardware.h new file mode 100644 index 0000000000..9afd7ab08e --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/hardware.h @@ -0,0 +1,29 @@ +#ifndef _DEVO7E256_HARDWARE_H_ +#define _DEVO7E256_HARDWARE_H_ + +#include "target/drivers/mcu/stm32/gpio.h" +#include "../common/hardware_t8sg_buttonmatrix.h" + +// Analog inputs +#if HAS_EXTRA_POTS + #define ADC_CHANNELS { \ + ADC_CHAN(GPIOC, GPIO0), /* ADC123_10 */ \ + ADC_CHAN(GPIOC, GPIO2), /* ADC123_12 */ \ + ADC_CHAN(GPIOC, GPIO3), /* ADC123_13 */ \ + ADC_CHAN(GPIOC, GPIO1), /* ADC123_11 */ \ + ADC_CHAN(GPIOA, GPIO0), /* ADC123_0 */ \ + ADC_CHAN(GPIOA, GPIO4), /* ADC12_4 */ \ + ADC_CHAN(0, 16), /* TEMPERATURE */ \ + ADC_CHAN(GPIOC, GPIO4), /* ADC12_14 */ \ + } +#else + #define ADC_CHANNELS { \ + ADC_CHAN(GPIOC, GPIO0), /* ADC123_10 */ \ + ADC_CHAN(GPIOC, GPIO2), /* ADC123_12 */ \ + ADC_CHAN(GPIOC, GPIO3), /* ADC123_13 */ \ + ADC_CHAN(GPIOC, GPIO1), /* ADC123_11 */ \ + ADC_CHAN(0, 16), /* TEMPERATURE */ \ + ADC_CHAN(GPIOC, GPIO4), /* ADC12_14 */ \ + } +#endif // HAS_EXTRA_POTS +#endif // _DEVO7E256_HARDWARE_H_ diff --git a/src/target/tx/devo/t8sg_v1/t8sg_v1.ld b/src/target/tx/devo/t8sg_v1/t8sg_v1.ld new file mode 100644 index 0000000000..b15aa4df03 --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/t8sg_v1.ld @@ -0,0 +1,8 @@ +MEMORY +{ + /* Devo7e-256 has 256K, and bootloader takes up 12K */ + rom (rx) : ORIGIN = 0x08003000, LENGTH = 244K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K +} +_crc_offset = 0x2000; /* CRC is located at 0x08005000 */ +INCLUDE target/tx/devo/common/devo.ld diff --git a/src/target/tx/devo/t8sg_v1/target_defs.h b/src/target/tx/devo/t8sg_v1/target_defs.h new file mode 100644 index 0000000000..3930eeb014 --- /dev/null +++ b/src/target/tx/devo/t8sg_v1/target_defs.h @@ -0,0 +1,67 @@ +#ifndef _T8SG_TARGET_H_ +#define _T8SG_TARGET_H_ + +#define TXID 0x18 +#define VECTOR_TABLE_LOCATION 0x3000 +#define SPIFLASH_SECTOR_OFFSET 0 +#define SPIFLASH_SECTORS 512 + +#define HAS_LCD_FLIPPED 1 +#define LCD_CONTRAST_FUNC(x) (x) + +#define HAS_STANDARD_GUI 1 +#define HAS_ADVANCED_GUI 1 +#define HAS_PERMANENT_TIMER 1 +#define HAS_TELEMETRY 1 +#define HAS_EXTENDED_TELEMETRY 1 +#define HAS_TOUCH 0 +#define HAS_RTC 0 +#define HAS_VIBRATINGMOTOR 1 +#define HAS_DATALOG 1 +#define HAS_SCANNER 1 +#define HAS_LAYOUT_EDITOR 1 +#define HAS_EXTRA_SWITCHES OPTIONAL +#define HAS_SWITCHES_NOSTOCK 1 +#define HAS_EXTRA_BUTTONS 0 +#define HAS_EXTRA_POTS OPTIONAL +#define HAS_MULTIMOD_SUPPORT 1 +#define HAS_VIDEO 0 +#define HAS_4IN1_FLASH 0 +#define HAS_EXTENDED_AUDIO 1 +#define HAS_AUDIO_UART 1 +#define HAS_MUSIC_CONFIG 1 + +#ifdef BUILDTYPE_DEV + #define DEBUG_WINDOW_SIZE 200 +#else + #define DEBUG_WINDOW_SIZE 0 +#endif + +#define MIN_BRIGHTNESS 0 +#define DEFAULT_BATTERY_ALARM 7400 +#define DEFAULT_BATTERY_CRITICAL 7100 +#define MAX_BATTERY_ALARM 12000 +#define MIN_BATTERY_ALARM 3300 +#define MAX_POWER_ALARM 60 + +#define NUM_OUT_CHANNELS 16 +#define NUM_VIRT_CHANNELS 10 + +#define NUM_TRIMS 6 +#define MAX_POINTS 13 +#define NUM_MIXERS ((NUM_OUT_CHANNELS + NUM_VIRT_CHANNELS) * 4) + +#if HAS_EXTRA_POTS + #define INP_HAS_CALIBRATION 6 +#else + #define INP_HAS_CALIBRATION 4 +#endif + +/* Compute voltage from y = 2.1592x + 0.2493 */ +#define VOLTAGE_NUMERATOR 216 +#define VOLTAGE_OFFSET 249 + +#include "hardware.h" +#include "../common/common_devo.h" + +#endif // _T8SG_TARGET_H_ diff --git a/src/target/tx/devo/t8sg_v2/Makefile.inc b/src/target/tx/devo/t8sg_v2/Makefile.inc index 2bebf9a46e..360ae2daac 100644 --- a/src/target/tx/devo/t8sg_v2/Makefile.inc +++ b/src/target/tx/devo/t8sg_v2/Makefile.inc @@ -1,5 +1,5 @@ SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := spi/128x64x1_nt7538.c +DISPLAY_DRIVER := spi/128x64x1.c FILESYSTEMS := common base_fonts 128x64x1 DFU_ARGS := -c 7 -b 0x08003000 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ diff --git a/src/target/tx/devo/t8sg_v2_plus/Makefile.inc b/src/target/tx/devo/t8sg_v2_plus/Makefile.inc index 04b33d1c12..360ae2daac 100644 --- a/src/target/tx/devo/t8sg_v2_plus/Makefile.inc +++ b/src/target/tx/devo/t8sg_v2_plus/Makefile.inc @@ -1,5 +1,5 @@ SCREENSIZE := 128x64x1 -DISPLAY_DRIVER := spi/128x64x1_oled_ssd1306.c +DISPLAY_DRIVER := spi/128x64x1.c FILESYSTEMS := common base_fonts 128x64x1 DFU_ARGS := -c 7 -b 0x08003000 FONTS = filesystem/$(FILESYSTEM)/media/12normal.fon \ diff --git a/src/target/tx/devo/t8sg_v2_plus/target_defs.h b/src/target/tx/devo/t8sg_v2_plus/target_defs.h index d6d4145942..1116b8024f 100644 --- a/src/target/tx/devo/t8sg_v2_plus/target_defs.h +++ b/src/target/tx/devo/t8sg_v2_plus/target_defs.h @@ -6,6 +6,8 @@ #define HAS_FLASH_DETECT 1 #define SPIFLASH_SECTOR_OFFSET 0 +#define HAS_LCD_OLED 1 + #define HAS_STANDARD_GUI 1 #define HAS_ADVANCED_GUI 1 #define HAS_PERMANENT_TIMER 1