1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 16:25:16 +03:00

Refactoring continued: Try to run lua scripts before the first LCD function

This commit is contained in:
Damjan Adamic 2014-12-06 15:12:18 +01:00
parent fac8571c29
commit 8aeb35c912
10 changed files with 371 additions and 190 deletions

View file

@ -781,7 +781,7 @@ ifeq ($(PCB), TARANIS)
endif endif
CPPDEFS += -DLUA CPPDEFS += -DLUA
INCDIRS += lua/src 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 \ 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/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 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

View file

@ -72,6 +72,7 @@ ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS] = { {0} };
ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 }; ScriptInternalData standaloneScript = { SCRIPT_NOFILE, 0 };
uint16_t maxLuaInterval = 0; uint16_t maxLuaInterval = 0;
uint16_t maxLuaDuration = 0; uint16_t maxLuaDuration = 0;
bool luaLcdAllowed;
#define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS (10000/100) #define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS (10000/100)
#define MANUAL_SCRIPTS_MAX_INSTRUCTIONS (20000/100) #define MANUAL_SCRIPTS_MAX_INSTRUCTIONS (20000/100)
@ -341,14 +342,20 @@ static int luaGetGeneralSettings(lua_State *L)
return 1; return 1;
} }
static int luaLcdLock(lua_State *L)
{
return 0;
}
static int luaLcdClear(lua_State *L) static int luaLcdClear(lua_State *L)
{ {
lcd_clear(); if (luaLcdAllowed) lcd_clear();
return 0; return 0;
} }
static int luaLcdDrawPoint(lua_State *L) static int luaLcdDrawPoint(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
lcd_plot(x, y); lcd_plot(x, y);
@ -357,6 +364,7 @@ static int luaLcdDrawPoint(lua_State *L)
static int luaLcdDrawLine(lua_State *L) static int luaLcdDrawLine(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x1 = luaL_checkinteger(L, 1); int x1 = luaL_checkinteger(L, 1);
int y1 = luaL_checkinteger(L, 2); int y1 = luaL_checkinteger(L, 2);
int x2 = luaL_checkinteger(L, 3); int x2 = luaL_checkinteger(L, 3);
@ -375,6 +383,7 @@ static int luaLcdGetLastPos(lua_State *L)
static int luaLcdDrawText(lua_State *L) static int luaLcdDrawText(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
const char * s = luaL_checkstring(L, 3); const char * s = luaL_checkstring(L, 3);
@ -385,6 +394,7 @@ static int luaLcdDrawText(lua_State *L)
static int luaLcdDrawTimer(lua_State *L) static int luaLcdDrawTimer(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int seconds = luaL_checkinteger(L, 3); int seconds = luaL_checkinteger(L, 3);
@ -395,6 +405,7 @@ static int luaLcdDrawTimer(lua_State *L)
static int luaLcdDrawNumber(lua_State *L) static int luaLcdDrawNumber(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int n = luaL_checkinteger(L, 3); int n = luaL_checkinteger(L, 3);
@ -405,6 +416,7 @@ static int luaLcdDrawNumber(lua_State *L)
static int luaLcdDrawChannel(lua_State *L) static int luaLcdDrawChannel(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int channel = -1; int channel = -1;
@ -427,6 +439,7 @@ static int luaLcdDrawChannel(lua_State *L)
static int luaLcdDrawSwitch(lua_State *L) static int luaLcdDrawSwitch(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int s = luaL_checkinteger(L, 3); int s = luaL_checkinteger(L, 3);
@ -437,6 +450,7 @@ static int luaLcdDrawSwitch(lua_State *L)
static int luaLcdDrawSource(lua_State *L) static int luaLcdDrawSource(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int s = luaL_checkinteger(L, 3); int s = luaL_checkinteger(L, 3);
@ -447,6 +461,7 @@ static int luaLcdDrawSource(lua_State *L)
static int luaLcdDrawPixmap(lua_State *L) static int luaLcdDrawPixmap(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
const char * filename = luaL_checkstring(L, 3); const char * filename = luaL_checkstring(L, 3);
@ -460,6 +475,7 @@ static int luaLcdDrawPixmap(lua_State *L)
static int luaLcdDrawRectangle(lua_State *L) static int luaLcdDrawRectangle(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3); int w = luaL_checkinteger(L, 3);
@ -470,6 +486,7 @@ static int luaLcdDrawRectangle(lua_State *L)
static int luaLcdDrawFilledRectangle(lua_State *L) static int luaLcdDrawFilledRectangle(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3); int w = luaL_checkinteger(L, 3);
@ -481,6 +498,7 @@ static int luaLcdDrawFilledRectangle(lua_State *L)
static int luaLcdDrawGauge(lua_State *L) static int luaLcdDrawGauge(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3); int w = luaL_checkinteger(L, 3);
@ -498,6 +516,7 @@ static int luaLcdDrawGauge(lua_State *L)
static int luaLcdDrawScreenTitle(lua_State *L) static int luaLcdDrawScreenTitle(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
const char * str = luaL_checkstring(L, 1); const char * str = luaL_checkstring(L, 1);
int idx = luaL_checkinteger(L, 2); int idx = luaL_checkinteger(L, 2);
int cnt = luaL_checkinteger(L, 3); int cnt = luaL_checkinteger(L, 3);
@ -511,6 +530,7 @@ static int luaLcdDrawScreenTitle(lua_State *L)
static int luaLcdDrawCombobox(lua_State *L) static int luaLcdDrawCombobox(lua_State *L)
{ {
if (! luaLcdAllowed) return 0;
int x = luaL_checkinteger(L, 1); int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2); int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3); int w = luaL_checkinteger(L, 3);
@ -1411,6 +1431,7 @@ const luaL_Reg modelLib[] = {
}; };
const luaL_Reg lcdLib[] = { const luaL_Reg lcdLib[] = {
{ "lock", luaLcdLock },
{ "clear", luaLcdClear }, { "clear", luaLcdClear },
{ "getLastPos", luaLcdGetLastPos }, { "getLastPos", luaLcdGetLastPos },
{ "drawPoint", luaLcdDrawPoint }, { "drawPoint", luaLcdDrawPoint },
@ -1810,96 +1831,99 @@ void luaDoOneRunStandalone(uint8_t evt)
} }
} }
void luaDoOneRunPermanentScript(uint8_t evt, int i) bool luaDoOneRunPermanentScript(uint8_t evt, int i, bool runGuiScripts)
{ {
ScriptInternalData & sid = scriptInternalData[i]; ScriptInternalData & sid = scriptInternalData[i];
if (sid.state == SCRIPT_OK) { if (sid.state != SCRIPT_OK) return false;
SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
int inputsCount = 0; SET_LUA_INSTRUCTIONS_COUNT(PERMANENT_SCRIPTS_MAX_INSTRUCTIONS);
int inputsCount = 0;
#if defined(SIMU) || defined(DEBUG) #if defined(SIMU) || defined(DEBUG)
const char *filename; const char *filename;
#endif #endif
ScriptInputsOutputs * sio = NULL; ScriptInputsOutputs * sio = NULL;
#if SCRIPT_MIX_FIRST > 0 #if SCRIPT_MIX_FIRST > 0
if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) { if (sid.reference >= SCRIPT_MIX_FIRST && sid.reference <= SCRIPT_MIX_LAST) {
#else #else
if (sid.reference <= SCRIPT_MIX_LAST) { if (sid.reference <= SCRIPT_MIX_LAST) {
#endif #endif
ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST]; if (runGuiScripts) return false; //mixer script is not gui script
sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST]; ScriptData & sd = g_model.scriptsData[sid.reference-SCRIPT_MIX_FIRST];
inputsCount = sio->inputsCount; sio = &scriptInputsOutputs[sid.reference-SCRIPT_MIX_FIRST];
inputsCount = sio->inputsCount;
#if defined(SIMU) || defined(DEBUG) #if defined(SIMU) || defined(DEBUG)
filename = sd.file; filename = sd.file;
#endif #endif
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
for (int j=0; j<sio->inputsCount; j++) { for (int j=0; j<sio->inputsCount; j++) {
if (sio->inputs[j].type == 1) if (sio->inputs[j].type == 1)
luaGetValueAndPush((uint8_t)sd.inputs[j]); luaGetValueAndPush((uint8_t)sd.inputs[j]);
else else
lua_pushinteger(L, sd.inputs[j] + sio->inputs[j].def); 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]; else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) {
if (!getSwitch(fn.swtch)) { CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST];
return; if (runGuiScripts) return false; //function script is not gui script
} if (!getSwitch(fn.swtch)) return false;
#if defined(SIMU) || defined(DEBUG) #if defined(SIMU) || defined(DEBUG)
filename = fn.play.name; filename = fn.play.name;
#endif #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 (g_menuStack[0]==menuTelemetryFrsky && sid.reference==SCRIPT_TELEMETRY_FIRST+s_frsky_view) {
if (!runGuiScripts) return false; //telemetry script gui part, do not run this time
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run); lua_rawgeti(L, LUA_REGISTRYINDEX, sid.run);
lua_pushinteger(L, evt);
inputsCount = 1;
}
else if (sid.background) {
if (runGuiScripts) return false; //telemetry script non-gui part, do not run this time
lua_rawgeti(L, LUA_REGISTRYINDEX, sid.background);
} }
else { else {
#if defined(SIMU) || defined(DEBUG) return false;
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;
}
} }
}
if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) { if (lua_pcall(L, inputsCount, sio ? sio->outputsCount : 0, 0) == 0) {
if (sio) { if (sio) {
for (int j=sio->outputsCount-1; j>=0; j--) { for (int j=sio->outputsCount-1; j>=0; j--) {
if (!lua_isnumber(L, -1)) { if (!lua_isnumber(L, -1)) {
sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR); sid.state = (instructionsPercent > 100 ? SCRIPT_KILLED : SCRIPT_SYNTAX_ERROR);
TRACE("Script %8s disabled", filename); TRACE("Script %8s disabled", filename);
break; break;
}
sio->outputs[j].value = lua_tointeger(L, -1);
lua_pop(L, 1);
} }
} 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;
} }
} }
} }
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() void luaDoGc()
@ -1924,6 +1948,103 @@ void luaDoGc()
} }
} }
uint32_t lastRunTime;
void luaRunNonGuiScripts()
{
//execute one cycle of all Lua cripts that don't use LCD (model scripts, function scripts)
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;
}
luaLcdAllowed = false;
if (luaState == INTERPRETER_PANIC) return;
if (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) return;
if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) {
luaState = 0;
luaInit();
if (luaState == INTERPRETER_PANIC) return;
luaLoadPermanentScripts();
if (luaState == INTERPRETER_PANIC) return;
}
for (int i=0; i<luaScriptsCount; i++) {
PROTECT_LUA() {
luaDoOneRunPermanentScript(0, i, false);
}
else {
luaDisable();
return;
}
UNPROTECT_LUA();
//todo gc step between scripts
}
luaDoGc();
lastRunTime = get_tmr10ms() - t0;
}
bool luaRunGuiScripts(uint8_t evt){
//execute one cycle of Lua scripts that use LCD
//either stand-alone or other (telemetry scripts)
uint32_t t0 = get_tmr10ms();
luaLcdAllowed = true;
if (luaState == INTERPRETER_PANIC) return false;
bool scriptWasRun = false;
if (luaState & INTERPRETER_RUNNING_STANDALONE_SCRIPT) {
PROTECT_LUA() {
luaDoOneRunStandalone(evt);
scriptWasRun = true;
}
else {
luaDisable();
return false;
}
UNPROTECT_LUA();
}
else {
// model scripts
if (luaState & INTERPRETER_RELOAD_PERMANENT_SCRIPTS) {
luaState = 0;
luaInit();
if (luaState == INTERPRETER_PANIC) return false;
luaLoadPermanentScripts();
if (luaState == INTERPRETER_PANIC) return false;
}
for (int i=0; i<luaScriptsCount; i++) {
PROTECT_LUA() {
scriptWasRun |= luaDoOneRunPermanentScript(evt, i, true);
}
else {
luaDisable();
return false;
}
UNPROTECT_LUA();
//todo gc step between scripts
}
}
luaDoGc();
lastRunTime += get_tmr10ms() - t0;
if (lastRunTime > maxLuaDuration) {
maxLuaDuration = lastRunTime;
}
return scriptWasRun;
}
#if 0
void luaTask(uint8_t evt) void luaTask(uint8_t evt)
{ {
uint32_t t0 = get_tmr10ms(); uint32_t t0 = get_tmr10ms();
@ -1977,6 +2098,7 @@ void luaTask(uint8_t evt)
maxLuaDuration = t0; maxLuaDuration = t0;
} }
} }
#endif
int luaGetMemUsed() int luaGetMemUsed()
{ {

128
radio/src/lua_api.h Normal file
View file

@ -0,0 +1,128 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - 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
#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 <setjmp.h>
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 */
void luaRunNonGuiScripts();
bool luaRunGuiScripts(uint8_t evt);
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)
#define luaRunNonGuiScripts()
#define luaRunGuiScripts(evt) (false)
#endif
#endif // #ifndef luaapi_h

View file

@ -2136,7 +2136,7 @@ uint8_t getSticksNavigationEvent()
} }
#endif #endif
void batteryCheck() void checkBattery()
{ {
static uint8_t counter = 0; static uint8_t counter = 0;
if (g_menuStack[g_menuStackPtr] == menuGeneralDiagAna) { if (g_menuStack[g_menuStackPtr] == menuGeneralDiagAna) {
@ -2327,7 +2327,7 @@ void perMain()
JACK_PPM_IN(); JACK_PPM_IN();
} }
batteryCheck(); checkBattery();
} }
#endif // #if !defined(CPUARM) #endif // #if !defined(CPUARM)

View file

@ -922,11 +922,6 @@ extern uint8_t g_tmr1Latency_min;
extern uint16_t lastMixerDuration; extern uint16_t lastMixerDuration;
#endif #endif
#if defined(LUA)
extern uint16_t maxLuaInterval;
extern uint16_t maxLuaDuration;
#endif
#if defined(CPUARM) #if defined(CPUARM)
#define DURATION_MS_PREC2(x) ((x)/20) #define DURATION_MS_PREC2(x) ((x)/20)
#else #else
@ -1536,82 +1531,6 @@ enum AUDIO_SOUNDS {
#include "rtc.h" #include "rtc.h"
#endif #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 <setjmp.h>
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) #if defined(CPUARM)
extern uint8_t requiredSpeakerVolume; extern uint8_t requiredSpeakerVolume;
#endif #endif
@ -1826,4 +1745,6 @@ void varioWakeup();
extern void usbPluggedIn(); extern void usbPluggedIn();
#endif #endif
#include "lua_api.h"
#endif #endif

View file

@ -41,11 +41,8 @@
uint32_t readKeys() uint32_t readKeys()
{ {
register uint32_t d = GPIOD->IDR; register uint32_t d = GPIOD->IDR;
#if !defined(REV9E)
register uint32_t e = GPIOE->IDR; register uint32_t e = GPIOE->IDR;
#else
register uint32_t f = GPIOF->IDR; register uint32_t f = GPIOF->IDR;
#endif
register uint32_t result = 0; register uint32_t result = 0;
#if defined(REV9E) #if defined(REV9E)
@ -55,7 +52,7 @@ uint32_t readKeys()
#endif #endif
result |= 0x02 << KEY_ENTER; result |= 0x02 << KEY_ENTER;
#if !defined(REV9E) #if !defined(REV9E) || defined(SIMU)
if (e & PIN_BUTTON_PLUS) if (e & PIN_BUTTON_PLUS)
result |= 0x02 << KEY_PLUS; result |= 0x02 << KEY_PLUS;
if (e & PIN_BUTTON_MINUS) if (e & PIN_BUTTON_MINUS)

View file

@ -36,11 +36,10 @@
#include "opentx.h" #include "opentx.h"
static uint8_t currentSpeakerVolume = 255; static uint8_t currentSpeakerVolume = 255;
uint8_t requiredSpeakerVolume; uint8_t requiredSpeakerVolume;
extern void batteryCheck(); extern void checkBattery();
void handleUsbConnection() void handleUsbConnection()
{ {
@ -109,6 +108,7 @@ void perMainArm()
writeLogs(); writeLogs();
handleUsbConnection(); handleUsbConnection();
checkTrainerSettings(); checkTrainerSettings();
checkBattery();
uint8_t evt = getEvent(false); uint8_t evt = getEvent(false);
if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on if (evt && (g_eeGeneral.backlightMode & e_backlight_mode_keys)) backlightOn(); // on keypress turn the light on
@ -118,49 +118,47 @@ void perMainArm()
if (sticks_evt) evt = sticks_evt; if (sticks_evt) evt = sticks_evt;
#endif #endif
#if defined(USB_MASS_STORAGE) #if defined(USB_MASS_STORAGE)
if (usbPlugged()) { if (usbPlugged()) {
// disable access to menus
lcd_clear(); lcd_clear();
menuMainView(0); menuMainView(0);
lcdRefresh();
return;
} }
else
#endif #endif
{
// run Lua scripts that don't use LCD (to use CPU time while LCD DMA is running)
luaRunNonGuiScripts();
// draw LCD from menus or from Lua script
if (luaRunGuiScripts(evt)) { // either stand-alone or telemetry scripts
// let Lua manage LCD fully
}
else {
// normal GUI from menus
const char *warn = s_warning; const char *warn = s_warning;
uint8_t menu = s_menu_count; uint8_t menu = s_menu_count;
lcd_clear();
if (!LUA_STANDALONE_SCRIPT_RUNNING()) { if (menuEvent) {
lcd_clear(); m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0;
if (menuEvent) { m_posHorz = 0;
m_posVert = menuEvent == EVT_ENTRY_UP ? g_menuPos[g_menuStackPtr] : 0; evt = menuEvent;
m_posHorz = 0; menuEvent = 0;
evt = menuEvent; AUDIO_MENUS();
menuEvent = 0;
AUDIO_MENUS();
}
g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt);
} }
g_menuStack[g_menuStackPtr]((warn || menu) ? 0 : evt);
#if defined(LUA) if (warn) DISPLAY_WARNING(evt);
luaTask(evt); if (menu) {
#endif const char * result = displayMenu(evt);
if (result) {
if (!LUA_STANDALONE_SCRIPT_RUNNING()) { menuHandler(result);
if (warn) DISPLAY_WARNING(evt); putEvent(EVT_MENU_UP);
if (menu) {
const char * result = displayMenu(evt);
if (result) {
menuHandler(result);
putEvent(EVT_MENU_UP);
}
} }
} }
drawStatusLine();
} }
drawStatusLine();
lcdRefresh(); lcdRefresh();
batteryCheck();
} }
#define MENUS_STACK_SIZE 2000 #define MENUS_STACK_SIZE 2000

View file

@ -42,8 +42,10 @@ inline void MIXER_RESET()
inline void TELEMETRY_RESET() inline void TELEMETRY_RESET()
{ {
#if defined(FRSKY)
memclear(&frskyData, sizeof(frskyData)); memclear(&frskyData, sizeof(frskyData));
TELEMETRY_RSSI() = 100; TELEMETRY_RSSI() = 100;
#endif
} }
void MIXER_RESET(); void MIXER_RESET();

View file

@ -48,6 +48,7 @@
extern const char * zchar2string(const char * zstring, int size); extern const char * zchar2string(const char * zstring, int size);
#define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string))) #define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string)))
extern void luaInit();
void luaExecStr(const char * str) void luaExecStr(const char * str)
{ {

View file

@ -391,7 +391,11 @@ TEST(Trims, CopySticksToOffset)
MODEL_RESET(); MODEL_RESET();
modelDefault(0); modelDefault(0);
anaInValues[ELE_STICK] = -100; anaInValues[ELE_STICK] = -100;
#if defined(CPUARM)
doMixerCalculations();
#else
perMain(); perMain();
#endif
copySticksToOffset(1); copySticksToOffset(1);
EXPECT_EQ(g_model.limitData[1].offset, -97); EXPECT_EQ(g_model.limitData[1].offset, -97);
} }
@ -618,11 +622,19 @@ TEST(Mixer, RecursiveAddChannelAfterInactivePhase)
g_model.mixData[2].srcRaw = MIXSRC_MAX; g_model.mixData[2].srcRaw = MIXSRC_MAX;
g_model.mixData[2].weight = 100; g_model.mixData[2].weight = 100;
simuSetSwitch(3, -1); simuSetSwitch(3, -1);
#if defined(CPUARM)
doMixerCalculations();
#else
perMain(); perMain();
#endif
EXPECT_EQ(chans[0], CHANNEL_MAX/2); EXPECT_EQ(chans[0], CHANNEL_MAX/2);
EXPECT_EQ(chans[1], CHANNEL_MAX); EXPECT_EQ(chans[1], CHANNEL_MAX);
simuSetSwitch(3, 0); simuSetSwitch(3, 0);
#if defined(CPUARM)
doMixerCalculations();
#else
perMain(); perMain();
#endif
EXPECT_EQ(chans[0], CHANNEL_MAX/2); EXPECT_EQ(chans[0], CHANNEL_MAX/2);
EXPECT_EQ(chans[1], CHANNEL_MAX); EXPECT_EQ(chans[1], CHANNEL_MAX);
} }