diff --git a/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp b/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp index 83151bb8e..4a938ec5c 100644 --- a/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp +++ b/companion/src/firmwares/opentx/opentxGruvin9xsimulator.cpp @@ -63,6 +63,7 @@ namespace Open9xGruvin9x { #include "radio/src/eeprom_common.cpp" #include "radio/src/eeprom_rlc.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_avr.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" diff --git a/companion/src/firmwares/opentx/opentxM128simulator.cpp b/companion/src/firmwares/opentx/opentxM128simulator.cpp index e53261380..2a4d9ab95 100644 --- a/companion/src/firmwares/opentx/opentxM128simulator.cpp +++ b/companion/src/firmwares/opentx/opentxM128simulator.cpp @@ -64,6 +64,7 @@ namespace OpenTxM128 { #include "radio/src/eeprom_common.cpp" #include "radio/src/eeprom_rlc.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_avr.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" diff --git a/companion/src/firmwares/opentx/opentxM64simulator.cpp b/companion/src/firmwares/opentx/opentxM64simulator.cpp index a566a4ff2..d35c19ee2 100644 --- a/companion/src/firmwares/opentx/opentxM64simulator.cpp +++ b/companion/src/firmwares/opentx/opentxM64simulator.cpp @@ -69,6 +69,7 @@ namespace OpenTxM64 { #include "radio/src/eeprom_common.cpp" #include "radio/src/eeprom_rlc.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_avr.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" diff --git a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp index 37828abcd..bbb65e624 100644 --- a/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp +++ b/companion/src/firmwares/opentx/opentxSky9xsimulator.cpp @@ -76,6 +76,7 @@ namespace Open9xSky9x { #include "radio/src/eeprom_raw.cpp" #include "radio/src/eeprom_conversions.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_arm.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" diff --git a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp index 1c1f9fbd9..1377f5f08 100644 --- a/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisSimulator.cpp @@ -79,6 +79,7 @@ inline int geteepromsize() { #include "radio/src/eeprom_conversions.cpp" #include "radio/src/eeprom_rlc.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_arm.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" @@ -136,7 +137,7 @@ inline int geteepromsize() { #include "radio/src/translations/tts_sk.cpp" #include "radio/src/translations/tts_pl.cpp" #include "radio/src/translations/tts_hu.cpp" -#include "radio/src/lua.cpp" +#include "radio/src/lua_api.cpp" #include "radio/src/lua/src/lapi.c" #include "radio/src/lua/src/lcode.c" #include "radio/src/lua/src/lctype.c" diff --git a/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp b/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp index 2b83d85ee..b185c9464 100755 --- a/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp +++ b/companion/src/firmwares/opentx/opentxTaranisX9ESimulator.cpp @@ -80,6 +80,7 @@ inline int geteepromsize() { #include "radio/src/eeprom_conversions.cpp" #include "radio/src/eeprom_rlc.cpp" #include "radio/src/opentx.cpp" +#include "radio/src/main_arm.cpp" #include "radio/src/strhelpers.cpp" #include "radio/src/switches.cpp" #include "radio/src/functions.cpp" @@ -138,7 +139,7 @@ inline int geteepromsize() { #include "radio/src/translations/tts_sk.cpp" #include "radio/src/translations/tts_pl.cpp" #include "radio/src/translations/tts_hu.cpp" -#include "radio/src/lua.cpp" +#include "radio/src/lua_api.cpp" #include "radio/src/lua/src/lapi.c" #include "radio/src/lua/src/lcode.c" #include "radio/src/lua/src/lctype.c" diff --git a/radio/src/Makefile b/radio/src/Makefile index 606e77e94..a59cae3ad 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -314,6 +314,15 @@ TRACE_SD_CARD = NO TRACE_FATFS = NO TRACE_AUDIO = NO +# Enable double buffering for LCD. Only for TARANIS PLUS and 9XE targets. +# Activating requires about 6kB of RAM, but it enables menus task to +# immediately start to compose a new LCD image while the current one is +# being written to LCD by DMA. +# If this option is NO, then first function that affects LCD buffer is +# delayed until DMA transfer is finished. +# Values = NO, YES +LCD_DUAL_BUFFER = NO + #------- END BUILD OPTIONS --------------------------- # Define programs and commands. @@ -353,7 +362,7 @@ ifeq ($(PCB), $(filter $(PCB), STD 9X 9XR)) THR_TRACE = NO INCDIRS += targets/stock CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM64 -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) - BOARDSRC = targets/stock/board_stock.cpp + BOARDSRC = main_avr.cpp targets/stock/board_stock.cpp EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp LCDSRC = lcd_common.cpp lcd_default.cpp @@ -417,7 +426,7 @@ ifeq ($(PCB), $(filter $(PCB), STD128 9X128 9XR128)) EEPROM_VARIANT += ${M128_VARIANT} CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM128 -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) INCDIRS += targets/stock - BOARDSRC = targets/stock/board_stock.cpp + BOARDSRC = main_avr.cpp targets/stock/board_stock.cpp EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp LCDSRC = lcd_common.cpp lcd_default.cpp @@ -477,7 +486,7 @@ ifeq ($(PCB), $(filter $(PCB), 9X2561)) EEPROM_VARIANT += ${M2561_VARIANT} CPPDEFS = -DF_CPU=$(F_CPU)UL -DPCBSTD -DCPUM2561 -DEEPROM_VARIANT=$(shell echo ${EEPROM_VARIANT} | bc) INCDIRS += targets/stock - BOARDSRC = targets/stock/board_stock.cpp + BOARDSRC = main_avr.cpp targets/stock/board_stock.cpp EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp LCDSRC = lcd_common.cpp lcd_default.cpp @@ -538,7 +547,7 @@ ifeq ($(PCB), GRUVIN9X) BUZZER = NO THR_TRACE = YES INCDIRS += targets/gruvin9x targets/stock FatFs FatFs/option - BOARDSRC = targets/gruvin9x/board_gruvin9x.cpp + BOARDSRC = main_avr.cpp targets/gruvin9x/board_gruvin9x.cpp EXTRABOARDSRC = targets/stock/lcd_driver.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp LCDSRC = lcd_common.cpp lcd_default.cpp @@ -577,7 +586,7 @@ ifeq ($(PCB), MEGA2560) SDCARD = YES THR_TRACE = YES INCDIRS += targets/mega2560 targets/stock FatFs FatFs/option - BOARDSRC = targets/mega2560/board_mega2560.cpp + BOARDSRC = main_avr.cpp targets/mega2560/board_mega2560.cpp EXTRABOARDSRC = targets/mega2560/lcd_driver_ST7565R.cpp targets/common_avr/telemetry_driver.cpp EEPROMSRC = eeprom_common.cpp eeprom_rlc.cpp LCDSRC = lcd_common.cpp lcd_default.cpp @@ -631,7 +640,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) CPPDEFS += -DSPORT_FILE_LOG endif INCDIRS += targets/sky9x CoOS/kernel CoOS/portable - BOARDSRC = targets/sky9x/board_sky9x.cpp + BOARDSRC = main_arm.cpp targets/sky9x/board_sky9x.cpp EXTRABOARDSRC = targets/sky9x/lcd_driver.cpp SRC += targets/sky9x/core_cm3.c targets/sky9x/board_lowlevel.c targets/sky9x/crt.c targets/sky9x/vectors_sam3s.c SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c @@ -679,10 +688,16 @@ ifeq ($(PCB), TARANIS) SWR = YES else ifeq ($(PCBREV), REVPLUS) CPPDEFS = -DREVPLUS + ifeq ($(LCD_DUAL_BUFFER), YES) + CPPDEFS += -DLCD_DUAL_BUFFER + endif HAPTIC = YES SWR = NO else ifeq ($(PCBREV), REV9E) CPPDEFS = -DREVPLUS -DREV9E + ifeq ($(LCD_DUAL_BUFFER), YES) + CPPDEFS += -DLCD_DUAL_BUFFER + endif HAPTIC = YES SWR = YES else @@ -729,7 +744,7 @@ ifeq ($(PCB), TARANIS) EXTRAINCDIRS += targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/STM32F2xx_StdPeriph_Driver/inc targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Include targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/include EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_OTG_Driver/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Core/inc EXTRAINCDIRS += targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/hid/inc - BOARDSRC = targets/taranis/board_taranis.cpp + BOARDSRC = main_arm.cpp targets/taranis/board_taranis.cpp EXTRABOARDSRC += targets/taranis/configure_pins.cpp targets/taranis/lcd_driver.cpp targets/taranis/flash_driver.cpp targets/taranis/aspi.c targets/taranis/i2c.c targets/taranis/delays.c SRC += CoOS/kernel/core.c CoOS/kernel/hook.c CoOS/kernel/task.c CoOS/kernel/event.c CoOS/kernel/time.c CoOS/kernel/timer.c CoOS/kernel/flag.c CoOS/kernel/mutex.c CoOS/kernel/serviceReq.c CoOS/portable/GCC/port.c CoOS/portable/arch.c SRC += targets/taranis/pwr_driver.c targets/taranis/usb_driver.c @@ -781,7 +796,7 @@ ifeq ($(PCB), TARANIS) endif CPPDEFS += -DLUA INCDIRS += lua/src - CPPSRC += lua.cpp + CPPSRC += lua_api.cpp LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/ldump.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \ lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/lrotable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \ lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/lbitlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c @@ -1217,6 +1232,8 @@ endif MAJ_VER = ${shell sh -c "grep \"MAJ_VERS\" opentx.h | cut -d\ -f3 | egrep -o \"[[:digit:]]\""} MIN_VER = ${shell sh -c "grep \"MIN_VERS\" opentx.h | cut -d\ -f3"} +.SECONDARY: + # Default target. all: begin gccversion sizebefore build sizeafter end diff --git a/radio/src/bootloader/Makefile b/radio/src/bootloader/Makefile index 4d4081b50..1093e59f8 100644 --- a/radio/src/bootloader/Makefile +++ b/radio/src/bootloader/Makefile @@ -124,6 +124,10 @@ else CPPDEFS += -DREV4a else ifeq ($(PCBREV), REVPLUS) CPPDEFS += -DREVPLUS + HAPTIC = YES + else ifeq ($(PCBREV), REV9E) + CPPDEFS += -DREVPLUS -DREV9E + HAPTIC = YES else CPPDEFS += -DREV4 endif @@ -178,6 +182,10 @@ CPPSRC = ../targets/taranis/lcd_driver.cpp \ ../strhelpers.cpp \ boot.cpp +ifeq ($(PCBREV), REV9E) + CPPSRC += ../targets/taranis/rotenc_driver.cpp +endif + # List ASM source files here ASRC = ../targets/taranis/STM32F2xx_StdPeriph_Lib_V1.1.0/Libraries/CMSIS/Device/ST/STM32F2xx/Source/Templates/gcc_ride7/startup_stm32f2xx.s diff --git a/radio/src/eeprom_common.h b/radio/src/eeprom_common.h index 1997c930e..463c1fd65 100644 --- a/radio/src/eeprom_common.h +++ b/radio/src/eeprom_common.h @@ -46,6 +46,8 @@ #define WRITE_DELAY_10MS 200 #endif +#define TIME_TO_WRITE() (s_eeDirtyMsk && (tmr10ms_t)(get_tmr10ms() - s_eeDirtyTime10ms) >= (tmr10ms_t)WRITE_DELAY_10MS) + extern uint8_t s_eeDirtyMsk; extern tmr10ms_t s_eeDirtyTime10ms; diff --git a/radio/src/lcd.h b/radio/src/lcd.h index c6f71e7e1..666651f86 100644 --- a/radio/src/lcd.h +++ b/radio/src/lcd.h @@ -161,10 +161,24 @@ #define DISPLAY_BUF_SIZE (LCD_W*((LCD_H+7)/8)) #endif -extern display_t displayBuf[DISPLAY_BUF_SIZE]; +#if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER) + extern display_t displayBuf1[DISPLAY_BUF_SIZE]; + extern display_t displayBuf2[DISPLAY_BUF_SIZE]; + extern display_t * displayBuf; +#else + extern display_t displayBuf[DISPLAY_BUF_SIZE]; +#endif + +#if defined(PCBTARANIS) && defined(REVPLUS) && !defined(LCD_DUAL_BUFFER) && !defined(SIMU) + void lcdRefreshWait(); +#else + #define lcdRefreshWait() +#endif + extern coord_t lcdLastPos; extern coord_t lcdNextPos; +#define DISPLAY_BUFER_SIZE (sizeof(display_t)*DISPLAY_BUF_SIZE) #define DISPLAY_END (displayBuf + DISPLAY_BUF_SIZE) #define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END) diff --git a/radio/src/lcd_common.cpp b/radio/src/lcd_common.cpp index cd05611a1..01de783b3 100644 --- a/radio/src/lcd_common.cpp +++ b/radio/src/lcd_common.cpp @@ -36,11 +36,18 @@ #include "opentx.h" -display_t displayBuf[DISPLAY_BUF_SIZE]; + +#if defined(PCBTARANIS) && defined(REVPLUS) && defined(LCD_DUAL_BUFFER) + display_t displayBuf1[DISPLAY_BUF_SIZE]; + display_t displayBuf2[DISPLAY_BUF_SIZE]; + display_t * displayBuf = displayBuf1; +#else + display_t displayBuf[DISPLAY_BUF_SIZE]; +#endif void lcd_clear() { - memset(displayBuf, 0, sizeof(displayBuf)); + memset(displayBuf, 0, DISPLAY_BUFER_SIZE); } coord_t lcdLastPos; diff --git a/radio/src/lcd_taranis.cpp b/radio/src/lcd_taranis.cpp index 0caec25e6..56ac02b6c 100644 --- a/radio/src/lcd_taranis.cpp +++ b/radio/src/lcd_taranis.cpp @@ -64,8 +64,7 @@ void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att) void lcd_plot(coord_t x, coord_t y, LcdFlags att) { - if (x<0 || x>=LCD_W || y<0 || y>=LCD_H) - return; + if (x<0 || x>=LCD_W || y<0 || y>=LCD_H) return; uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ]; uint8_t mask = PIXEL_GREY_MASK(y, att); if (p= LCD_H) return; if (x+w > LCD_W) { - if (x >= LCD_W ) { - return; - } + if (x >= LCD_W ) return; w = LCD_W - x; } @@ -159,9 +156,7 @@ void lcd_bmp(coord_t x, coord_t y, const uint8_t * img, coord_t offset, coord_t width = w; } if (x+width > LCD_W) { - if (x >= LCD_W ) { - return; - } + if (x >= LCD_W ) return; width = LCD_W-x; } uint8_t rows = (*q++ + 1) / 2; @@ -170,9 +165,7 @@ void lcd_bmp(coord_t x, coord_t y, const uint8_t * img, coord_t offset, coord_t q = img + 2 + row*w + offset; uint8_t *p = &displayBuf[(row + (y/2)) * LCD_W + x]; for (coord_t i=0; i= DISPLAY_END) { - return; - } + if ((p) >= DISPLAY_END) return; uint8_t b = *q++; if (y & 1) { *p = (*p & 0x0f) + ((b & 0x0f) << 4); diff --git a/radio/src/lua.cpp b/radio/src/lua_api.cpp similarity index 93% rename from radio/src/lua.cpp rename to radio/src/lua_api.cpp index 8890e6392..712876b63 100644 --- a/radio/src/lua.cpp +++ b/radio/src/lua_api.cpp @@ -72,6 +72,7 @@ ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS] = { {0} }; ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 }; uint16_t maxLuaInterval = 0; uint16_t maxLuaDuration = 0; +bool luaLcdAllowed; #define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS (10000/100) #define MANUAL_SCRIPTS_MAX_INSTRUCTIONS (20000/100) @@ -341,14 +342,22 @@ static int luaGetGeneralSettings(lua_State *L) return 1; } +static int luaLcdLock(lua_State *L) +{ + // disabled in opentx 2.1 + // TODO: remove this function completely in opentx 2.2 + return 0; +} + static int luaLcdClear(lua_State *L) { - lcd_clear(); + if (luaLcdAllowed) lcd_clear(); return 0; } static int luaLcdDrawPoint(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); lcd_plot(x, y); @@ -357,6 +366,7 @@ static int luaLcdDrawPoint(lua_State *L) static int luaLcdDrawLine(lua_State *L) { + if (!luaLcdAllowed) return 0; int x1 = luaL_checkinteger(L, 1); int y1 = luaL_checkinteger(L, 2); int x2 = luaL_checkinteger(L, 3); @@ -375,6 +385,7 @@ static int luaLcdGetLastPos(lua_State *L) static int luaLcdDrawText(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * s = luaL_checkstring(L, 3); @@ -385,6 +396,7 @@ static int luaLcdDrawText(lua_State *L) static int luaLcdDrawTimer(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int seconds = luaL_checkinteger(L, 3); @@ -395,6 +407,7 @@ static int luaLcdDrawTimer(lua_State *L) static int luaLcdDrawNumber(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int n = luaL_checkinteger(L, 3); @@ -405,6 +418,7 @@ static int luaLcdDrawNumber(lua_State *L) static int luaLcdDrawChannel(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int channel = -1; @@ -427,6 +441,7 @@ static int luaLcdDrawChannel(lua_State *L) static int luaLcdDrawSwitch(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); @@ -437,6 +452,7 @@ static int luaLcdDrawSwitch(lua_State *L) static int luaLcdDrawSource(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); @@ -447,6 +463,7 @@ static int luaLcdDrawSource(lua_State *L) static int luaLcdDrawPixmap(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * filename = luaL_checkstring(L, 3); @@ -460,6 +477,7 @@ static int luaLcdDrawPixmap(lua_State *L) static int luaLcdDrawRectangle(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -470,6 +488,7 @@ static int luaLcdDrawRectangle(lua_State *L) static int luaLcdDrawFilledRectangle(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -481,6 +500,7 @@ static int luaLcdDrawFilledRectangle(lua_State *L) static int luaLcdDrawGauge(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -498,6 +518,7 @@ static int luaLcdDrawGauge(lua_State *L) static int luaLcdDrawScreenTitle(lua_State *L) { + if (!luaLcdAllowed) return 0; const char * str = luaL_checkstring(L, 1); int idx = luaL_checkinteger(L, 2); int cnt = luaL_checkinteger(L, 3); @@ -511,6 +532,7 @@ static int luaLcdDrawScreenTitle(lua_State *L) static int luaLcdDrawCombobox(lua_State *L) { + if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); @@ -1411,6 +1433,7 @@ const luaL_Reg modelLib[] = { }; const luaL_Reg lcdLib[] = { + { "lock", luaLcdLock }, { "clear", luaLcdClear }, { "getLastPos", luaLcdGetLastPos }, { "drawPoint", luaLcdDrawPoint }, @@ -1810,96 +1833,96 @@ void luaDoOneRunStandalone(uint8_t evt) } } -void luaDoOneRunPermanentScript(uint8_t evt, int i) +bool luaDoOneRunPermanentScript(uint8_t evt, int i, uint32_t scriptType) { ScriptInternalData & sid = scriptInternalData[i]; - if (sid.state == SCRIPT_OK) { - SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS); - int inputsCount = 0; + if (sid.state != SCRIPT_OK) return false; + + SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS); + int inputsCount = 0; #if defined(SIMU) || defined(DEBUG) - const char *filename; + const char *filename; #endif - ScriptInputsOutputs * sio = NULL; + ScriptInputsOutputs * sio = NULL; #if SCRIPT_MIX_FIRST > 0 - if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) { + if ((scriptType & RUN_MIX_SCRIPT) && (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST)) { #else - if (sid.reference <= SCRIPT_MIX_LAST) { + if ((scriptType & RUN_MIX_SCRIPT) && (sid.reference <= SCRIPT_MIX_LAST)) { #endif - ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST]; - sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST]; - inputsCount = sio->inputsCount; + ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST]; + sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST]; + inputsCount = sio->inputsCount; #if defined(SIMU) || defined(DEBUG) - filename = sd.file; + filename = sd.file; #endif - lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); - for (int j=0; jinputsCount; j++) { - if (sio->inputs[j].type == 1) - luaGetValueAndPush((uint8_t)sd.inputs[j]); - else - lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def); - } + lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); + for (int j=0; jinputsCount; j++) { + if (sio->inputs[j].type == 1) + luaGetValueAndPush((uint8_t)sd.inputs[j]); + else + lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def); } - else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) { - CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST]; - if (!getSwitch(fn.swtch)) { - return; - } + } + else if ((scriptType & RUN_FUNC_SCRIPT) && (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST)) { + CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST]; + if (!getSwitch(fn.swtch)) return false; #if defined(SIMU) || defined(DEBUG) - filename = fn.play.name; + filename = fn.play.name; #endif + lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); + } + else { +#if defined(SIMU) || defined(DEBUG) + TelemetryScriptData & script = g_model.frsky.screens[sid.reference-SCRIPT_TELEMETRY_FIRST].script; + filename = script.file; +#endif + if ((scriptType & RUN_TELEM_FG_SCRIPT) && + (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view)) { lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); + lua_pushinteger(L, evt); + inputsCount = 1; + } + else if ((scriptType & RUN_TELEM_BG_SCRIPT) && (sid.background)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background); } else { -#if defined(SIMU) || defined(DEBUG) - TelemetryScriptData & script = g_model.frsky.screens[sid.reference-SCRIPT_TELEMETRY_FIRST].script; - filename = script.file; -#endif - if (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) { - lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); - lua_pushinteger(L, evt); - inputsCount = 1; - } - else if (sid.background) { - lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background); - } - else { - return; - } + return false; } + } - if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) { - if (sio) { - for (int j=sio->outputsCount-1; j>=0; j--) { - if (!lua_isnumber(L, -1)) { - sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR); - TRACE("Script %8s disabled", filename); - break; - } - sio->outputs[j].value = lua_tointeger(L, -1); - lua_pop(L, 1); + if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) { + if (sio) { + for (int j=sio->outputsCount-1; j>=0; j--) { + if (!lua_isnumber(L, -1)) { + sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR); + TRACE("Script %8s disabled", filename); + break; } - } - } - else { - if (instructionsPercent > 100) { - TRACE("Script %8s killed", filename); - sid.state = SCRIPT_KILLED; - } - else { - TRACE("Script %8s error: %s", filename, lua_tostring(L, -1)); - sid.state = SCRIPT_SYNTAX_ERROR; - } - } - - if (sid.state != SCRIPT_OK) { - luaFree(sid); - } - else { - if (instructionsPercent > sid.instructions) { - sid.instructions = instructionsPercent; + sio->outputs[j].value = lua_tointeger(L, -1); + lua_pop(L, 1); } } } + else { + if (instructionsPercent > 100) { + TRACE("Script %8s killed", filename); + sid.state = SCRIPT_KILLED; + } + else { + TRACE("Script %8s error: %s", filename, lua_tostring(L, -1)); + sid.state = SCRIPT_SYNTAX_ERROR; + } + } + + if (sid.state != SCRIPT_OK) { + luaFree(sid); + } + else { + if (instructionsPercent > sid.instructions) { + sid.instructions = instructionsPercent; + } + } + return true; } void luaDoGc() @@ -1924,58 +1947,50 @@ void luaDoGc() } } -void luaTask(uint8_t evt) +bool luaTask(uint8_t evt, uint8_t scriptType, bool allowLcdUsage) { - uint32_t t0 = get_tmr10ms(); - static uint32_t lastLuaTime = 0; - uint16_t interval = (lastLuaTime == 0 ? 0 : (t0 - lastLuaTime)); - lastLuaTime = t0; - if (interval > maxLuaInterval) { - maxLuaInterval = interval; - } - - if (luaState == INTERPRETER_PANIC) { - return; - } + if (luaState == INTERPRETER_PANIC) return false; + luaLcdAllowed = allowLcdUsage; + bool scriptWasRun = false; + // we run either standalone script or permanent scripts if (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) { + // run standalone script + if ((scriptType & RUN_STNDAL_SCRIPT) == 0) return false; PROTECT_LUA() { luaDoOneRunStandalone(evt); + scriptWasRun = true; } else { luaDisable(); - return; + return false; } UNPROTECT_LUA(); } else { - // model scripts + // run permanent scripts if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) { luaState = 0; luaInit(); - if (luaState == INTERPRETER_PANIC) return; + if (luaState == INTERPRETER_PANIC) return false; luaLoadPermanentScripts(); - if (luaState == INTERPRETER_PANIC) return; + if (luaState == INTERPRETER_PANIC) return false; } for (int i=0; i maxLuaDuration) { - maxLuaDuration = t0; - } + return scriptWasRun; } int luaGetMemUsed() diff --git a/radio/src/lua_api.h b/radio/src/lua_api.h new file mode 100644 index 000000000..0dd0bc8ad --- /dev/null +++ b/radio/src/lua_api.h @@ -0,0 +1,126 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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. + * + */ + +#ifndef luaapi_h +#define luaapi_h + + +#define RUN_MIX_SCRIPT (1 << 0) +#define RUN_FUNC_SCRIPT (1 << 1) +#define RUN_TELEM_BG_SCRIPT (1 << 2) +#define RUN_TELEM_FG_SCRIPT (1 << 3) +#define RUN_STNDAL_SCRIPT (1 << 4) + + +#if defined(LUA) + struct ScriptInput { + const char *name; + uint8_t type; + int16_t min; + int16_t max; + int16_t def; + }; + struct ScriptOutput { + const char *name; + int16_t value; + }; + enum ScriptState { + SCRIPT_OK, + SCRIPT_NOFILE, + SCRIPT_SYNTAX_ERROR, + SCRIPT_PANIC, + SCRIPT_KILLED + }; + enum ScriptReference { + SCRIPT_MIX_FIRST, + SCRIPT_MIX_LAST=SCRIPT_MIX_FIRST+MAX_SCRIPTS-1, + SCRIPT_FUNC_FIRST, + SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+NUM_CFN-1, + SCRIPT_TELEMETRY_FIRST, + SCRIPT_TELEMETRY_LAST=SCRIPT_TELEMETRY_FIRST+MAX_SCRIPTS, // telem0 and telem1 .. telem7 + }; + struct ScriptInternalData { + uint8_t reference; + uint8_t state; + int run; + int background; + uint8_t instructions; + }; + struct ScriptInputsOutputs { + uint8_t inputsCount; + ScriptInput inputs[MAX_SCRIPT_INPUTS]; + uint8_t outputsCount; + ScriptOutput outputs[MAX_SCRIPT_OUTPUTS]; + }; + #define INTERPRETER_RUNNING_STANDALONE_SCRIPT 1 + #define INTERPRETER_RELOAD_PERMANENT_SCRIPTS 2 + #define INTERPRETER_PANIC 255 + extern uint8_t luaState; + extern uint8_t luaScriptsCount; + extern ScriptInternalData standaloneScript; + extern ScriptInternalData scriptInternalData[MAX_SCRIPTS]; + extern ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS]; + void luaClose(); + bool luaTask(uint8_t evt, uint8_t scriptType, bool allowLcdUsage); + void luaExec(const char *filename); + int luaGetMemUsed(); + #define luaGetCpuUsed(idx) scriptInternalData[idx].instructions + #define LUA_LOAD_MODEL_SCRIPTS() luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS + #define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS + #define LUA_STANDALONE_SCRIPT_RUNNING() (luaState == INTERPRETER_RUNNING_STANDALONE_SCRIPT) + // Lua PROTECT/UNPROTECT + #include + struct our_longjmp { + struct our_longjmp *previous; + jmp_buf b; + volatile int status; /* error code */ + }; + extern struct our_longjmp * global_lj; + #define PROTECT_LUA() { struct our_longjmp lj; \ + lj.previous = global_lj; /* chain new error handler */ \ + global_lj = &lj; \ + if (setjmp(lj.b) == 0) + #define UNPROTECT_LUA() global_lj = lj.previous; } /* restore old error handler */ + + extern uint16_t maxLuaInterval; + extern uint16_t maxLuaDuration; +#else // #if defined(LUA) + #define LUA_LOAD_MODEL_SCRIPTS() + #define LUA_LOAD_MODEL_SCRIPT(idx) + #define LUA_STANDALONE_SCRIPT_RUNNING() (0) +#endif + +#endif // #ifndef luaapi_h diff --git a/radio/src/main_arm.cpp b/radio/src/main_arm.cpp new file mode 100644 index 000000000..9a9f4e741 --- /dev/null +++ b/radio/src/main_arm.cpp @@ -0,0 +1,188 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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" + +static uint8_t currentSpeakerVolume = 255; +uint8_t requiredSpeakerVolume = 255; + +extern void checkBattery(); + +void handleUsbConnection() +{ +#if defined(PCBTARANIS) && !defined(SIMU) + static bool usbStarted = false; + if (!usbStarted && usbPlugged()) { +#if defined(USB_MASS_STORAGE) + opentxClose(); +#endif + usbStart(); +#if defined(USB_MASS_STORAGE) + usbPluggedIn(); +#endif + usbStarted = true; + } + +#if defined(USB_JOYSTICK) + if (usbStarted) { + if (!usbPlugged()) { + //disable USB + usbStop(); + usbStarted = false; + } + else { + usbJoystickUpdate(); + } + } +#endif +#endif //#if defined(PCBTARANIS) && !defined(SIMU) +} + +void checkSpeakerVolume() +{ + if (currentSpeakerVolume != requiredSpeakerVolume) { + currentSpeakerVolume = requiredSpeakerVolume; + setVolume(currentSpeakerVolume); + } +} + +void checkEeprom() +{ + if (!usbPlugged()) { + // TODO merge these 2 branches +#if defined(PCBSKY9X) + if (Eeprom32_process_state != E32_IDLE) + ee32_process(); + else if (TIME_TO_WRITE()) + eeCheck(false); +#else + if (theFile.isWriting()) + theFile.nextWriteStep(); + else if (TIME_TO_WRITE()) + eeCheck(false); +#endif + } +} + +void perMain() +{ +#if defined(PCBSKY9X) && !defined(REVA) + calcConsumption(); +#endif + checkSpeakerVolume(); + checkEeprom(); + sdMountPoll(); + writeLogs(); + handleUsbConnection(); + checkTrainerSettings(); + checkBattery(); + + uint8_t evt = getEvent(false); + if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on + checkBacklight(); +#if defined(NAVIGATION_STICKS) + uint8_t sticks_evt = getSticksNavigationEvent(); + if (sticks_evt) evt = sticks_evt; +#endif + +#if defined(USB_MASS_STORAGE) + if (usbPlugged()) { + // disable access to menus + lcd_clear(); + menuMainView(0); + lcdRefresh(); + return; + } +#endif + +#if defined(LUA) + + uint32_t t0 = get_tmr10ms(); + static uint32_t lastLuaTime = 0; + uint16_t interval = (lastLuaTime == 0 ? 0 : (t0 - lastLuaTime)); + lastLuaTime = t0; + if (interval > maxLuaInterval) { + maxLuaInterval = interval; + } + + // run Lua scripts that don't use LCD (to use CPU time while LCD DMA is running) + luaTask(0, RUN_MIX_SCRIPT | RUN_FUNC_SCRIPT | RUN_TELEM_BG_SCRIPT, false); + + // wait for LCD DMA to finish before continuing, because code from this point + // is allowed to change the contents of LCD buffer + // + // WARNING: make sure no code above this line does any change to the LCD display buffer! + // + lcdRefreshWait(); + + // draw LCD from menus or from Lua script + // run Lua scripts that use LCD + bool scriptWasRun = luaTask(evt, RUN_TELEM_FG_SCRIPT | RUN_STNDAL_SCRIPT, true); + + t0 = get_tmr10ms() - t0; + if (t0 > maxLuaDuration) { + maxLuaDuration = t0; + } + + if (!scriptWasRun) { +#else + lcdRefreshWait(); // WARNING: make sure no code above this line does any change to the LCD display buffer! + { +#endif + // normal GUI from menus + const char *warn = s_warning; + uint8_t menu = s_menu_count; + lcd_clear(); + if (menuEvent) { + m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; + m_posHorz = 0; + evt = menuEvent; + menuEvent = 0; + AUDIO_MENUS(); + } + g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt); + if (warn) DISPLAY_WARNING(evt); + if (menu) { + const char * result = displayMenu(evt); + if (result) { + menuHandler(result); + putEvent(EVT_MENU_UP); + } + } + drawStatusLine(); + } + lcdRefresh(); +} diff --git a/radio/src/main_avr.cpp b/radio/src/main_avr.cpp new file mode 100644 index 000000000..e0a58f2c5 --- /dev/null +++ b/radio/src/main_avr.cpp @@ -0,0 +1,165 @@ +/* + * Authors (alphabetical order) + * - Andre Bernet + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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" + +extern void checkBattery(); +extern uint8_t checkTrim(uint8_t event); + +void perMain() +{ +#if defined(SIMU) + doMixerCalculations(); +#endif + uint16_t t0 = getTmr16KHz(); + int16_t delta = (nextMixerEndTime - lastMixerDuration) - t0; + if (delta > 0 && delta < MAX_MIXER_DELTA) { +#if defined(PCBSTD) && defined(ROTARY_ENCODER_NAVIGATION) + rotencPoll(); +#endif + + // @@@ open.20.fsguruh + // SLEEP(); // wouldn't that make sense? should save a lot of battery power!!! +/* for future use; currently very very beta... */ +#if defined(POWER_SAVE) + ADCSRA&=0x7F; // disable ADC for power saving + ACSR&=0xF7; // disable ACIE Interrupts + ACSR|=0x80; // disable Analog Comparator + // maybe we disable here a lot more hardware components in future to save even more power + + + + MCUCR|=0x20; // enable Sleep (bit5) + // MCUCR|=0x28; // enable Sleep (bit5) enable ADC Noise Reduction (bit3) + // first tests showed: simple sleep would reduce cpu current from 40.5mA to 32.0mA + // noise reduction sleep would reduce it down to 28.5mA; However this would break pulses in theory + // however with standard module, it will need about 95mA. Therefore the drop to 88mA is not much noticable + do { + asm volatile(" sleep \n\t"); // if _SLEEP() is not defined use this + t0=getTmr16KHz(); + delta= (nextMixerEndTime - lastMixerDuration) - t0; + } while ((delta>0) && (delta maxMixerDuration) maxMixerDuration = t0; + +#if defined(MODULE_ALWAYS_SEND_PULSES) + if (startupWarningState < STARTUP_WARNING_DONE) { + // don't do menu's until throttle and switch warnings are handled + return; + } +#endif + + if (!eeprom_buffer_size) { + if (theFile.isWriting()) + theFile.nextWriteStep(); + else if (TIME_TO_WRITE()) + eeCheck(false); + } + +#if defined(SDCARD) + sdMountPoll(); + writeLogs(); +#endif + + uint8_t evt = getEvent(); + evt = checkTrim(evt); + + if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on + checkBacklight(); + +#if (defined(FRSKY) || defined(MAVLINK)) + telemetryWakeup(); +#endif + +#if defined(NAVIGATION_STICKS) + uint8_t sticks_evt = getSticksNavigationEvent(); + if (sticks_evt) evt = sticks_evt; +#endif + + const char *warn = s_warning; + uint8_t menu = s_menu_count; + + lcd_clear(); + if (menuEvent) { + m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; + m_posHorz = 0; + evt = menuEvent; + menuEvent = 0; + AUDIO_MENUS(); + } + g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt); + + + if (warn) DISPLAY_WARNING(evt); +#if defined(NAVIGATION_MENUS) + if (menu) { + const char * result = displayMenu(evt); + if (result) { + menuHandler(result); + putEvent(EVT_MENU_UP); + } + } +#endif + + drawStatusLine(); + + lcdRefresh(); + + if (SLAVE_MODE()) { + JACK_PPM_OUT(); + } + else { + JACK_PPM_IN(); + } + + checkBattery(); +} diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 86c99c6f4..6751626e9 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -87,56 +87,6 @@ uint8_t g_tmr1Latency_min; uint16_t lastMixerDuration; #endif -#if defined(PCBTARANIS) -uint8_t currentTrainerMode = 0xff; - -void checkTrainerSettings() -{ - uint8_t requiredTrainerMode = g_model.trainerMode; - if (requiredTrainerMode != currentTrainerMode) { - switch (currentTrainerMode) { - case TRAINER_MODE_MASTER: - stop_trainer_capture(); - break; - case TRAINER_MODE_SLAVE: - stop_trainer_ppm(); - break; - case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: - stop_cppm_on_heartbeat_capture() ; - break; - case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: - stop_sbus_on_heartbeat_capture() ; - break; - case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - uart3Stop(); - } - - currentTrainerMode = requiredTrainerMode; - switch (requiredTrainerMode) { - case TRAINER_MODE_SLAVE: - init_trainer_ppm(); - break; - case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: - init_cppm_on_heartbeat_capture() ; - break; - case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: - init_sbus_on_heartbeat_capture() ; - break; - case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - if (g_eeGeneral.uart3Mode == UART_MODE_SBUS_TRAINER) { - uart3SbusInit(); - break; - } - // no break - default: - // master is default - init_trainer_capture(); - break; - } - } -} -#endif - uint8_t unexpectedShutdown = 0; /* AVR: mixer duration in 1/16ms */ @@ -209,7 +159,6 @@ void per10ms() watchdogTimeout -= 1; wdt_reset(); // Retrigger hardware watchdog } - Tenms |= 1 ; // 10 mS has passed #endif if (lightOffCounter) lightOffCounter--; @@ -1403,13 +1352,6 @@ uint8_t checkTrim(uint8_t event) #endif } -#if defined(PCBSKY9X) && !defined(REVA) -uint16_t Current_analogue; -uint16_t Current_max; -uint32_t Current_accumulator; -uint32_t Current_used; -#endif - #if !defined(SIMU) static uint16_t s_anaFilt[NUMBER_ANALOG]; #endif @@ -1699,10 +1641,6 @@ uint8_t mSwitchDuration[1+NUM_ROTARY_ENCODERS] = { 0 }; #define CFN_PRESSLONG_DURATION 100 #endif -#if defined(CPUARM) -uint8_t currentSpeakerVolume = 255; -uint8_t requiredSpeakerVolume; -#endif uint8_t s_mixer_first_run_done = false; @@ -1995,7 +1933,6 @@ void doMixerCalculations() s_mixer_first_run_done = true; } -#define TIME_TO_WRITE() (s_eeDirtyMsk && (tmr10ms_t)(get_tmr10ms() - s_eeDirtyTime10ms) >= (tmr10ms_t)WRITE_DELAY_10MS) #if defined(NAVIGATION_STICKS) @@ -2129,205 +2066,11 @@ void opentxClose() #endif -#if defined(USB_JOYSTICK) && defined(PCBTARANIS) && !defined(SIMU) -extern USB_OTG_CORE_HANDLE USB_OTG_dev; - -/* - Prepare and send new USB data packet - - The format of HID_Buffer is defined by - USB endpoint description can be found in - file usb_hid_joystick.c, variable HID_JOYSTICK_ReportDesc -*/ -void usbJoystickUpdate(void) -{ - static uint8_t HID_Buffer[HID_IN_PACKET]; - - //buttons - HID_Buffer[0] = 0; //buttons - for (int i = 0; i < 8; ++i) { - if ( channelOutputs[i+8] > 0 ) { - HID_Buffer[0] |= (1 << i); - } - } - - //analog values - //uint8_t * p = HID_Buffer + 1; - for (int i = 0; i < 8; ++i) { - int16_t value = channelOutputs[i] / 8; - if ( value > 127 ) value = 127; - else if ( value < -127 ) value = -127; - HID_Buffer[i+1] = static_cast(value); - } - - USBD_HID_SendReport (&USB_OTG_dev, HID_Buffer, HID_IN_PACKET ); -} - -#endif //#if defined(USB_JOYSTICK) && defined(PCBTARANIS) && !defined(SIMU) - - -void perMain() -{ -#if defined(SIMU) - doMixerCalculations(); -#elif !defined(CPUARM) - uint16_t t0 = getTmr16KHz(); - int16_t delta = (nextMixerEndTime - lastMixerDuration) - t0; - if (delta > 0 && delta < MAX_MIXER_DELTA) { -#if defined(PCBSTD) && defined(ROTARY_ENCODER_NAVIGATION) - rotencPoll(); -#endif - - // @@@ open.20.fsguruh - // SLEEP(); // wouldn't that make sense? should save a lot of battery power!!! -/* for future use; currently very very beta... */ -#if defined(POWER_SAVE) - ADCSRA&=0x7F; // disable ADC for power saving - ACSR&=0xF7; // disable ACIE Interrupts - ACSR|=0x80; // disable Analog Comparator - // maybe we disable here a lot more hardware components in future to save even more power - - - - MCUCR|=0x20; // enable Sleep (bit5) - // MCUCR|=0x28; // enable Sleep (bit5) enable ADC Noise Reduction (bit3) - // first tests showed: simple sleep would reduce cpu current from 40.5mA to 32.0mA - // noise reduction sleep would reduce it down to 28.5mA; However this would break pulses in theory - // however with standard module, it will need about 95mA. Therefore the drop to 88mA is not much noticable - do { - asm volatile(" sleep \n\t"); // if _SLEEP() is not defined use this - t0=getTmr16KHz(); - delta= (nextMixerEndTime - lastMixerDuration) - t0; - } while ((delta>0) && (delta maxMixerDuration) maxMixerDuration = t0; -#endif - -// TODO same code here + integrate the timer which could be common -#if defined(CPUARM) - if (!Tenms) return; - Tenms = 0 ; -#endif - -#if defined(PCBSKY9X) - Current_accumulator += Current_analogue ; - static uint32_t OneSecTimer; - if (++OneSecTimer >= 100) { - OneSecTimer -= 100 ; - Current_used += Current_accumulator / 100 ; // milliAmpSeconds (but scaled) - Current_accumulator = 0 ; - } -#endif - -#if defined(CPUARM) - if (currentSpeakerVolume != requiredSpeakerVolume) { - currentSpeakerVolume = requiredSpeakerVolume; - setVolume(currentSpeakerVolume); - } -#endif - -#if defined(MODULE_ALWAYS_SEND_PULSES) - if (startupWarningState < STARTUP_WARNING_DONE) { - // don't do menu's until throttle and switch warnings are handled - return; - } -#endif - - if (!usbPlugged()) { - // TODO merge these 2 branches -#if defined(PCBSKY9X) - if (Eeprom32_process_state != E32_IDLE) - ee32_process(); - else if (TIME_TO_WRITE()) - eeCheck(false); -#elif defined(CPUARM) - if (theFile.isWriting()) - theFile.nextWriteStep(); - else if (TIME_TO_WRITE()) - eeCheck(false); -#else - if (!eeprom_buffer_size) { - if (theFile.isWriting()) - theFile.nextWriteStep(); - else if (TIME_TO_WRITE()) - eeCheck(false); - } -#endif - } - -#if defined(SDCARD) - sdMountPoll(); - writeLogs(); -#endif - -#if defined(CPUARM) && defined(SIMU) - checkTrims(); -#endif - -#if defined(CPUARM) - uint8_t evt = getEvent(false); -#else - uint8_t evt = getEvent(); - evt = checkTrim(evt); -#endif - - if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on - - checkBacklight(); - -#if !defined(CPUARM) && (defined(FRSKY) || defined(MAVLINK)) - telemetryWakeup(); -#endif - -#if defined(PCBTARANIS) - checkTrainerSettings(); -#endif - -#if defined(PCBTARANIS) && !defined(SIMU) - static bool usbStarted = false; - if (!usbStarted && usbPlugged()) { -#if defined(USB_MASS_STORAGE) - opentxClose(); -#endif - usbStart(); -#if defined(USB_MASS_STORAGE) - usbPluggedIn(); -#endif - usbStarted = true; - } - -#if defined(USB_JOYSTICK) - if (usbStarted) { - if (!usbPlugged()) { - //disable USB - usbStop(); - usbStarted = false; - } - else { - usbJoystickUpdate(); - } - } -#endif - -#endif //#if defined(PCBTARANIS) && !defined(SIMU) #if defined(NAVIGATION_STICKS) +uint8_t getSticksNavigationEvent() +{ + uint8_t evt = 0; if (StickScrollAllowed) { if ( StickScrollTimer ) { static uint8_t repeater; @@ -2389,60 +2132,12 @@ void perMain() StickScrollTimer = 0; // Seconds } StickScrollAllowed = 1 ; + return evt; +} #endif -#if defined(USB_MASS_STORAGE) - if (usbPlugged()) { - lcd_clear(); - menuMainView(0); - } - else -#endif - { - const char *warn = s_warning; - uint8_t menu = s_menu_count; - - if (!LUA_STANDALONE_SCRIPT_RUNNING()) { - lcd_clear(); - if (menuEvent) { - m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; - m_posHorz = 0; - evt = menuEvent; - menuEvent = 0; - AUDIO_MENUS(); - } - g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt); - } - -#if defined(LUA) - luaTask(evt); -#endif - - if (!LUA_STANDALONE_SCRIPT_RUNNING()) { - if (warn) DISPLAY_WARNING(evt); -#if defined(NAVIGATION_MENUS) - if (menu) { - const char * result = displayMenu(evt); - if (result) { - menuHandler(result); - putEvent(EVT_MENU_UP); - } - } -#endif - } - } - - drawStatusLine(); - - lcdRefresh(LCD_REFRESH_DONT_WAIT); - - if (SLAVE_MODE()) { - JACK_PPM_OUT(); - } - else { - JACK_PPM_IN(); - } - +void checkBattery() +{ static uint8_t counter = 0; if (g_menuStack[g_menuStackPtr] == menuGeneralDiagAna) { g_vbat100mV = 0; @@ -2506,6 +2201,7 @@ void perMain() #endif } } + } int16_t g_ppmIns[NUM_TRAINER]; @@ -2895,9 +2591,6 @@ void opentxInit(OPENTX_INIT_ARGS) #endif #if defined(VOICE) -#if defined(CPUARM) - currentSpeakerVolume = requiredSpeakerVolume = g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF; -#endif setVolume(g_eeGeneral.speakerVolume+VOLUME_LEVEL_DEF); #endif diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 84394dd05..2d6297d3e 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -726,6 +726,9 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms); void evalMixes(uint8_t tick10ms); void doMixerCalculations(); +#if defined(CPUARM) + void checkTrims(); +#endif void perMain(); NOINLINE void per10ms(); @@ -742,15 +745,15 @@ void logicalSwitchesTimerTick(); void logicalSwitchesReset(); #if defined(CPUARM) -void evalLogicalSwitches(bool isCurrentPhase=true); -void logicalSwitchesCopyState(uint8_t src, uint8_t dst); -#define LS_RECURSIVE_EVALUATION_RESET() + void evalLogicalSwitches(bool isCurrentPhase=true); + void logicalSwitchesCopyState(uint8_t src, uint8_t dst); + #define LS_RECURSIVE_EVALUATION_RESET() #else -#define evalLogicalSwitches(xxx) -#define GETSWITCH_RECURSIVE_TYPE uint16_t -extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_used; -extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_value; -#define LS_RECURSIVE_EVALUATION_RESET() s_last_switch_used = 0 + #define evalLogicalSwitches(xxx) + #define GETSWITCH_RECURSIVE_TYPE uint16_t + extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_used; + extern volatile GETSWITCH_RECURSIVE_TYPE s_last_switch_value; + #define LS_RECURSIVE_EVALUATION_RESET() s_last_switch_used = 0 #endif #if defined(PCBTARANIS) @@ -917,11 +920,6 @@ extern uint8_t g_tmr1Latency_min; extern uint16_t lastMixerDuration; #endif -#if defined(LUA) -extern uint16_t maxLuaInterval; -extern uint16_t maxLuaDuration; -#endif - #if defined(CPUARM) #define DURATION_MS_PREC2(x) ((x)/20) #else @@ -1531,82 +1529,6 @@ enum AUDIO_SOUNDS { #include "rtc.h" #endif -#if defined(LUA) - struct ScriptInput { - const char *name; - uint8_t type; - int16_t min; - int16_t max; - int16_t def; - }; - struct ScriptOutput { - const char *name; - int16_t value; - }; - enum ScriptState { - SCRIPT_OK, - SCRIPT_NOFILE, - SCRIPT_SYNTAX_ERROR, - SCRIPT_PANIC, - SCRIPT_KILLED - }; - enum ScriptReference { - SCRIPT_MIX_FIRST, - SCRIPT_MIX_LAST=SCRIPT_MIX_FIRST+MAX_SCRIPTS-1, - SCRIPT_FUNC_FIRST, - SCRIPT_FUNC_LAST=SCRIPT_FUNC_FIRST+NUM_CFN-1, - SCRIPT_TELEMETRY_FIRST, - SCRIPT_TELEMETRY_LAST=SCRIPT_TELEMETRY_FIRST+MAX_SCRIPTS, // telem0 and telem1 .. telem7 - }; - struct ScriptInternalData { - uint8_t reference; - uint8_t state; - int run; - int background; - uint8_t instructions; - }; - struct ScriptInputsOutputs { - uint8_t inputsCount; - ScriptInput inputs[MAX_SCRIPT_INPUTS]; - uint8_t outputsCount; - ScriptOutput outputs[MAX_SCRIPT_OUTPUTS]; - }; - #define INTERPRETER_RUNNING_STANDALONE_SCRIPT 1 - #define INTERPRETER_RELOAD_PERMANENT_SCRIPTS 2 - #define INTERPRETER_PANIC 255 - extern uint8_t luaState; - extern uint8_t luaScriptsCount; - extern ScriptInternalData standaloneScript; - extern ScriptInternalData scriptInternalData[MAX_SCRIPTS]; - extern ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS]; - void luaClose(); - void luaInit(); - void luaTask(uint8_t evt); - void luaExec(const char *filename); - int luaGetMemUsed(); - #define luaGetCpuUsed(idx) scriptInternalData[idx].instructions - #define LUA_LOAD_MODEL_SCRIPTS() luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS - #define LUA_LOAD_MODEL_SCRIPT(idx) luaState |= INTERPRETER_RELOAD_PERMANENT_SCRIPTS - #define LUA_STANDALONE_SCRIPT_RUNNING() (luaState == INTERPRETER_RUNNING_STANDALONE_SCRIPT) - // Lua PROTECT/UNPROTECT - #include - struct our_longjmp { - struct our_longjmp *previous; - jmp_buf b; - volatile int status; /* error code */ - }; - extern struct our_longjmp * global_lj; - #define PROTECT_LUA() { struct our_longjmp lj; \ - lj.previous = global_lj; /* chain new error handler */ \ - global_lj = &lj; \ - if (setjmp(lj.b) == 0) - #define UNPROTECT_LUA() global_lj = lj.previous; } /* restore old error handler */ -#else - #define LUA_LOAD_MODEL_SCRIPTS() - #define LUA_LOAD_MODEL_SCRIPT(idx) - #define LUA_STANDALONE_SCRIPT_RUNNING() (0) -#endif - #if defined(CPUARM) extern uint8_t requiredSpeakerVolume; #endif @@ -1821,4 +1743,6 @@ void varioWakeup(); extern void usbPluggedIn(); #endif +#include "lua_api.h" + #endif diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index a0618d3e7..abdcd25b7 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -85,7 +85,7 @@ Open9xSim::Open9xSim(FXApp* a): FXMainWindow(a, "OpenTX Simu", NULL, NULL, DECOR_ALL, 20, 90, 0, 0) { firstTime = true; - memset(displayBuf, 0, sizeof(displayBuf)); + memset(displayBuf, 0, DISPLAY_BUFER_SIZE); bmp = new FXPPMImage(getApp(),NULL,IMAGE_OWNED|IMAGE_KEEP|IMAGE_SHMI|IMAGE_SHMP, W2, H2); FXHorizontalFrame *hf11=new FXHorizontalFrame(this,LAYOUT_CENTER_X); diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 71142b53c..c9ea5d762 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -339,6 +339,10 @@ void *main_thread(void *) s_current_protocol[0] = 0; while (main_thread_running) { +#if defined(CPUARM) + doMixerCalculations(); + checkTrims(); +#endif perMain(); sleep(10/*ms*/); } diff --git a/radio/src/targets/simu/simpgmspace.h b/radio/src/targets/simu/simpgmspace.h index 1c7e00585..b6a1be62e 100644 --- a/radio/src/targets/simu/simpgmspace.h +++ b/radio/src/targets/simu/simpgmspace.h @@ -336,7 +336,6 @@ extern void rxPdcUsart( void (*pChProcess)(uint8_t x) ); #define asm(x) #if defined(CPUARM) -extern volatile uint32_t Tenms; extern uint32_t Master_frequency; #define NVIC_EnableIRQ(x) #define NVIC_DisableIRQ(x) diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index 40cb33aa1..dcbdac3bf 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -42,6 +42,13 @@ volatile uint32_t Tenms ; volatile uint8_t lcdLock; volatile uint32_t lcdInputs; +#if !defined(REVA) +uint16_t Current_analogue; +uint16_t Current_max; +uint32_t Current_accumulator; +uint32_t Current_used; +#endif + extern "C" void sam_boot( void ) ; // Prototype @@ -672,3 +679,28 @@ void setSticksGain(uint8_t gains) padc->ADC_CGR = gain; padc->ADC_COR = offset; } + + +#if !defined(REVA) +void calcConsumption() +{ + Current_accumulator += Current_analogue ; + static uint32_t OneSecTimer; + if (++OneSecTimer >= 100) { + OneSecTimer -= 100 ; + Current_used += Current_accumulator / 100 ; // milliAmpSeconds (but scaled) + Current_accumulator = 0 ; + } +} +#endif + +void checkTrainerSettings() +{ + if (SLAVE_MODE()) { + PIOC->PIO_PDR = PIO_PC22; + } + else { + PIOC->PIO_PER = PIO_PC22; + } +} + diff --git a/radio/src/targets/sky9x/board_sky9x.h b/radio/src/targets/sky9x/board_sky9x.h index 5d7e360bc..f0e6078a4 100644 --- a/radio/src/targets/sky9x/board_sky9x.h +++ b/radio/src/targets/sky9x/board_sky9x.h @@ -168,11 +168,14 @@ extern uint16_t Current_max; extern uint32_t Current_accumulator; extern uint32_t Current_used; extern uint16_t sessionTimer; +void calcConsumption(); #endif #define SLAVE_MODE() (pwrCheck() == e_power_trainer) -#define JACK_PPM_OUT() PIOC->PIO_PDR = PIO_PC22 -#define JACK_PPM_IN() PIOC->PIO_PER = PIO_PC22 +// #define JACK_PPM_OUT() PIOC->PIO_PDR = PIO_PC22 +// #define JACK_PPM_IN() PIOC->PIO_PER = PIO_PC22 +void checkTrainerSettings(); + void setSticksGain(uint8_t gains); diff --git a/radio/src/targets/taranis/board_taranis.cpp b/radio/src/targets/taranis/board_taranis.cpp index d162e7a83..3ef899069 100644 --- a/radio/src/targets/taranis/board_taranis.cpp +++ b/radio/src/targets/taranis/board_taranis.cpp @@ -46,8 +46,6 @@ extern "C" { } #endif -volatile uint32_t Tenms ; // TODO to remove everywhere / use a #define - void watchdogInit(unsigned int duration) { IWDG->KR = 0x5555 ; // Unlock registers @@ -150,3 +148,90 @@ void boardInit() } #endif + + +#if defined(USB_JOYSTICK) && !defined(SIMU) +extern USB_OTG_CORE_HANDLE USB_OTG_dev; + +/* + Prepare and send new USB data packet + + The format of HID_Buffer is defined by + USB endpoint description can be found in + file usb_hid_joystick.c, variable HID_JOYSTICK_ReportDesc +*/ +void usbJoystickUpdate(void) +{ + static uint8_t HID_Buffer[HID_IN_PACKET]; + + //buttons + HID_Buffer[0] = 0; //buttons + for (int i = 0; i < 8; ++i) { + if ( channelOutputs[i+8] > 0 ) { + HID_Buffer[0] |= (1 << i); + } + } + + //analog values + //uint8_t * p = HID_Buffer + 1; + for (int i = 0; i < 8; ++i) { + int16_t value = channelOutputs[i] / 8; + if ( value > 127 ) value = 127; + else if ( value < -127 ) value = -127; + HID_Buffer[i+1] = static_cast(value); + } + + USBD_HID_SendReport (&USB_OTG_dev, HID_Buffer, HID_IN_PACKET ); +} + +#endif //#if defined(USB_JOYSTICK) && defined(PCBTARANIS) && !defined(SIMU) + + +uint8_t currentTrainerMode = 0xff; + +void checkTrainerSettings() +{ + uint8_t requiredTrainerMode = g_model.trainerMode; + if (requiredTrainerMode != currentTrainerMode) { + switch (currentTrainerMode) { + case TRAINER_MODE_MASTER: + stop_trainer_capture(); + break; + case TRAINER_MODE_SLAVE: + stop_trainer_ppm(); + break; + case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: + stop_cppm_on_heartbeat_capture() ; + break; + case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: + stop_sbus_on_heartbeat_capture() ; + break; + case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: + uart3Stop(); + } + + currentTrainerMode = requiredTrainerMode; + switch (requiredTrainerMode) { + case TRAINER_MODE_SLAVE: + init_trainer_ppm(); + break; + case TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE: + init_cppm_on_heartbeat_capture() ; + break; + case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: + init_sbus_on_heartbeat_capture() ; + break; + case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: + if (g_eeGeneral.uart3Mode == UART_MODE_SBUS_TRAINER) { + uart3SbusInit(); + break; + } + // no break + default: + // master is default + init_trainer_capture(); + break; + } + } +} + diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index d09e81782..0830bb5a4 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -82,8 +82,8 @@ extern "C" { #define TIMER_MULT_APB1 2 #define TIMER_MULT_APB2 2 -#define JACK_PPM_OUT() -#define JACK_PPM_IN() +// #define JACK_PPM_OUT() +// #define JACK_PPM_IN() #define PIN_MODE_MASK 0x0003 #define PIN_INPUT 0x0000 @@ -174,9 +174,9 @@ uint32_t readTrims(void); #if defined(REV9E) // Rotary Encoder driver -void rotencInit(); -void rotencEnd(); -void checkRotaryEncoder(); +void rotencInit(void); +void rotencEnd(void); +void checkRotaryEncoder(void); #endif // WDT driver @@ -277,5 +277,10 @@ void uart3Stop(void); #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +#if defined(USB_JOYSTICK) && !defined(SIMU) +void usbJoystickUpdate(void); +#endif + +void checkTrainerSettings(); #endif diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp index 7437d2cfb..5a00ca274 100644 --- a/radio/src/targets/taranis/keys_driver.cpp +++ b/radio/src/targets/taranis/keys_driver.cpp @@ -41,13 +41,13 @@ uint32_t readKeys() { register uint32_t d = GPIOD->IDR; -#if !defined(REV9E) register uint32_t e = GPIOE->IDR; -#else register uint32_t f = GPIOF->IDR; -#endif register uint32_t result = 0; + (void)e; + (void)f; + #if defined(REV9E) if (f & PIN_BUTTON_ENTER) #else @@ -55,7 +55,7 @@ uint32_t readKeys() #endif result |= 0x02 << KEY_ENTER; -#if !defined(REV9E) +#if !defined(REV9E) || defined(SIMU) if (e & PIN_BUTTON_PLUS) result |= 0x02 << KEY_PLUS; if (e & PIN_BUTTON_MINUS) @@ -145,7 +145,7 @@ void readKeysAndTrims() #if defined(REV9E) static rotenc_t rePreviousValue; - rotenc_t reNewValue = (x9de_rotenc / ROTARY_ENCODER_GRANULARITY); + rotenc_t reNewValue = (x9de_rotenc / 2); int8_t scrollRE = reNewValue - rePreviousValue; if (scrollRE) { rePreviousValue = reNewValue; diff --git a/radio/src/targets/taranis/lcd_driver.cpp b/radio/src/targets/taranis/lcd_driver.cpp index 77b667970..533c83fb0 100644 --- a/radio/src/targets/taranis/lcd_driver.cpp +++ b/radio/src/targets/taranis/lcd_driver.cpp @@ -17,9 +17,11 @@ #if defined(REVPLUS) #define CONTRAST_OFS 160 #define RESET_WAIT_DELAY_MS 300 //wait time after LCD reset before first command + #define WAIT_FOR_DMA_END() { while(lcd_busy) {}; } #else #define CONTRAST_OFS 5 #define RESET_WAIT_DELAY_MS 1300 //wait time after LCD reset before first command + #define WAIT_FOR_DMA_END() #endif #if defined(BOOT) @@ -42,7 +44,6 @@ static void Delay(uint32_t ms) } #if defined(REVPLUS) -static void LCD_Hardware_Init() ; // New hardware SPI driver for LCD void initLcdSpi() @@ -64,24 +65,25 @@ void initLcdSpi() configure_pins( PIN_LCD_RST, PIN_OUTPUT | PIN_PORTD | PIN_PUSHPULL | PIN_OS25 | PIN_NO_PULLUP ) ; configure_pins( PIN_LCD_A0, PIN_OUTPUT | PIN_PORTC | PIN_PUSHPULL | PIN_OS50 | PIN_NO_PULLUP ) ; configure_pins( PIN_LCD_MOSI|PIN_LCD_CLK, PIN_PORTC | PIN_PUSHPULL | PIN_OS50 | PIN_NO_PULLUP | PIN_PER_6 | PIN_PERIPHERAL ) ; -} -void setupSPIdma() -{ - RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock - // Chan 0, 8-bit wide, Medium priority, memory increments - DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA + + // NVIC_SetPriority( DMA1_Stream7_IRQn, 8 ) ; + NVIC_EnableIRQ(DMA1_Stream7_IRQn) ; + DMA1->HIFCR |= DMA_HIFCR_CTCIF7; //clear interrupt flag + DMA1->LISR |= DMA_HISR_TCIF7; //enable DMA TX end interrupt + + RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock + + DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA DMA1->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CHTIF7 | DMA_HIFCR_CTEIF7 | DMA_HIFCR_CDMEIF7 | DMA_HIFCR_CFEIF7 ; // Write ones to clear bits DMA1_Stream7->CR = DMA_SxCR_PL_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 ; DMA1_Stream7->PAR = (uint32_t) &SPI3->DR ; DMA1_Stream7->M0AR = (uint32_t)displayBuf; DMA1_Stream7->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; DMA1_Stream7->NDTR = LCD_W*LCD_H/8*4 ; - -// NVIC_SetPriority( DMA1_Stream7_IRQn, 2 ) ; // Lower priority interrupt -// NVIC_EnableIRQ(DMA1_Stream7_IRQn) ; } + static void LCD_Init() { WriteCommand(0x2F); //Internal pump control @@ -174,35 +176,59 @@ void Set_Address(u8 x, u8 y) LCD_CLK_HIGH(); #if defined(REVPLUS) + +volatile bool lcd_busy; + +#if !defined(LCD_DUAL_BUFFER) +void lcdRefreshWait() +{ + WAIT_FOR_DMA_END(); +} +#endif + void lcdRefresh(bool wait) { + //wait if previous DMA transfer still active + WAIT_FOR_DMA_END(); + lcd_busy = true; + Set_Address(0, 0); LCD_NCS_LOW(); LCD_A0_HIGH(); - setupSPIdma() ; - DMA1_Stream7->CR |= DMA_SxCR_EN ; // Enable DMA + DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA + DMA1->HIFCR = DMA_HIFCR_CTCIF7 | DMA_HIFCR_CHTIF7 | DMA_HIFCR_CTEIF7 | DMA_HIFCR_CDMEIF7 | DMA_HIFCR_CFEIF7 ; // Write ones to clear bits + +#if defined(LCD_DUAL_BUFFER) + //switch LCD buffer + DMA1_Stream7->M0AR = (uint32_t)displayBuf; + displayBuf = (displayBuf == displayBuf1) ? displayBuf2 : displayBuf1; +#endif + + DMA1_Stream7->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE; // Enable DMA & tXe interrupt SPI3->CR2 |= SPI_CR2_TXDMAEN ; +} - while ( ( DMA1->HISR & DMA_HISR_TCIF7 ) == 0 ) { - // wait - } - +extern "C" void DMA1_Stream7_IRQHandler() +{ + //clear interrupt flag + DMA1_Stream7->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt + DMA1->HIFCR |= DMA_HIFCR_CTCIF7; // Clear interrupt flag SPI3->CR2 &= ~SPI_CR2_TXDMAEN ; - DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA - - while ( ( SPI3->SR & SPI_SR_TXE ) == 0 ) { - // wait - } // Last byte being sent + DMA1_Stream7->CR &= ~DMA_SxCR_EN ; // Disable DMA while ( SPI3->SR & SPI_SR_BSY ) { - // wait + /* Wait for SPI to finish sending data + The DMA TX End interrupt comes two bytes before the end of SPI transmission, + therefore we have to wait here. + */ } - LCD_NCS_HIGH(); + lcd_busy = false; } -#else + +#else // #if defined(REVPLUS) void lcdRefresh() { for (uint32_t y=0; y