[Lua] Add setStickySwitch and getLogicalSwitchValue (#1056)
[Lua] Add setStickySwitch and getLogicalSwitchValue (#1056) * Adds setStickySwitch to set the value of a stick logical switch * Adds getLogicalSwitchValue to get the value of a logical switch by index
This commit is contained in:
@@ -1848,6 +1848,62 @@ static int luaGetShmVar(lua_State * L)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*luadoc
|
||||
@function setStickySwitch(id, value)
|
||||
|
||||
@param id: integer identifying the sticky logical switch (zero for LS1 etc.).
|
||||
|
||||
@param value: true/false. The new value of the sticky logical switch.
|
||||
|
||||
@retval bufferFull: true/false. This function sends a message from Lua to the logical switch processor
|
||||
via a buffer with eight slots that are read 10 times per second. If the buffer is full, then a true value
|
||||
is returned and no messages was sent (i.e. the switch was not changed).
|
||||
|
||||
Sets the value of a sticky logical switch.
|
||||
|
||||
@status current Introduced in 2.6
|
||||
*/
|
||||
|
||||
#if (MAX_LOGICAL_SWITCHES != 64)
|
||||
#warning "The following code assumes that MAX_LOGICAL_SWITCHES == 64!"
|
||||
#endif
|
||||
|
||||
static int luaSetStickySwitch(lua_State * L)
|
||||
{
|
||||
int id = luaL_checkinteger(L, 1);
|
||||
bool value = lua_toboolean(L, 2);
|
||||
|
||||
uint8_t msg = (1 << 6); // This bit is always set to have a non-zero value
|
||||
if (value) msg |= (1 << 7);
|
||||
msg |= (id & 0x3F);
|
||||
|
||||
lua_pushboolean(L, luaSetStickySwitchBuffer.write(msg));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*luadoc
|
||||
@function getLogicalSwitchValue(id)
|
||||
|
||||
@param id: integer identifying the logical switch (zero for LS1 etc.).
|
||||
|
||||
@retval value: true/false.
|
||||
|
||||
Reads the value of a logical switch.
|
||||
|
||||
@status current Introduced in 2.6
|
||||
*/
|
||||
|
||||
static int luaGetLogicalSwitchValue(lua_State * L)
|
||||
{
|
||||
int id = luaL_checkinteger(L, 1);
|
||||
|
||||
if (id >= 0 && id < MAX_LOGICAL_SWITCHES)
|
||||
lua_pushboolean(L, getSwitch(SWSRC_FIRST_LOGICAL_SWITCH + id));
|
||||
else
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const luaL_Reg opentxLib[] = {
|
||||
{ "getTime", luaGetTime },
|
||||
{ "getDateTime", luaGetDateTime },
|
||||
@@ -1907,6 +1963,8 @@ const luaL_Reg opentxLib[] = {
|
||||
{ "setShmVar", luaSetShmVar },
|
||||
{ "getShmVar", luaGetShmVar },
|
||||
#endif
|
||||
{ "setStickySwitch", luaSetStickySwitch },
|
||||
{ "getLogicalSwitchValue", luaGetLogicalSwitchValue },
|
||||
{ nullptr, nullptr } /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
@@ -1310,3 +1310,5 @@ inline bool isAsteriskDisplayed()
|
||||
}
|
||||
|
||||
#include "module.h"
|
||||
|
||||
extern CircularBuffer<uint8_t, 8> luaSetStickySwitchBuffer;
|
||||
|
||||
@@ -56,13 +56,49 @@ inline void SWAP(T & a, T & b)
|
||||
|
||||
inline void memclear(void * p, size_t size)
|
||||
{
|
||||
memset(p, 0, size);
|
||||
memset(p, 0, size);
|
||||
}
|
||||
|
||||
inline bool is_memclear(void * p, size_t size)
|
||||
{
|
||||
uint8_t * buf = (uint8_t *)p;
|
||||
return buf[0] == 0 && memcmp(buf, buf + 1, size - 1) == 0;
|
||||
uint8_t * buf = (uint8_t *)p;
|
||||
return buf[0] == 0 && memcmp(buf, buf + 1, size - 1) == 0;
|
||||
}
|
||||
|
||||
// Circular buffer to send data between two threads
|
||||
template<class T, uint8_t N>
|
||||
class CircularBuffer {
|
||||
protected:
|
||||
volatile T buffer[N] = {0};
|
||||
uint8_t readPos = 0;
|
||||
uint8_t writePos = 0;
|
||||
|
||||
public:
|
||||
void clear()
|
||||
{
|
||||
memclear(this, sizeof(*this));
|
||||
}
|
||||
|
||||
T read()
|
||||
{
|
||||
T value = buffer[readPos];
|
||||
if (value) {
|
||||
buffer[readPos] = 0;
|
||||
readPos = (readPos + 1) % N;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// Values must be non-zero
|
||||
bool write(T value)
|
||||
{
|
||||
if (value && !buffer[writePos]) {
|
||||
buffer[writePos] = value;
|
||||
writePos = (writePos + 1) % N;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -53,6 +53,7 @@ PACK(struct LogicalSwitchesFlightModeContext {
|
||||
LogicalSwitchContext lsw[MAX_LOGICAL_SWITCHES];
|
||||
});
|
||||
LogicalSwitchesFlightModeContext lswFm[MAX_FLIGHT_MODES];
|
||||
CircularBuffer<uint8_t, 8> luaSetStickySwitchBuffer;
|
||||
|
||||
#define LS_LAST_VALUE(fm, idx) lswFm[fm].lsw[idx].lastValue
|
||||
|
||||
@@ -789,6 +790,34 @@ void checkSwitches()
|
||||
|
||||
void logicalSwitchesTimerTick()
|
||||
{
|
||||
#if (MAX_LOGICAL_SWITCHES != 64)
|
||||
#warning "The following code assumes that MAX_LOGICAL_SWITCHES == 64!"
|
||||
#endif
|
||||
// Read messages from Lua in the buffer and flick switches
|
||||
uint8_t msg = luaSetStickySwitchBuffer.read();
|
||||
while(msg) {
|
||||
uint8_t i = msg & 0x3F;
|
||||
uint8_t s = msg >> 7;
|
||||
LogicalSwitchData * ls = lswAddress(i);
|
||||
if (ls->func == LS_FUNC_STICKY) {
|
||||
for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) {
|
||||
ls_sticky_struct & lastValue = (ls_sticky_struct &)LS_LAST_VALUE(fm, i);
|
||||
lastValue.state = s;
|
||||
bool now;
|
||||
if (s)
|
||||
now = getSwitch(ls->v2);
|
||||
else
|
||||
now = getSwitch(ls->v1);
|
||||
if (now)
|
||||
lastValue.last |= 1;
|
||||
else
|
||||
lastValue.last &= ~1;
|
||||
}
|
||||
}
|
||||
msg = luaSetStickySwitchBuffer.read();
|
||||
}
|
||||
|
||||
// Update logical switches
|
||||
for (uint8_t fm=0; fm<MAX_FLIGHT_MODES; fm++) {
|
||||
for (uint8_t i=0; i<MAX_LOGICAL_SWITCHES; i++) {
|
||||
LogicalSwitchData * ls = lswAddress(i);
|
||||
@@ -900,6 +929,8 @@ void logicalSwitchesReset()
|
||||
LS_LAST_VALUE(fm, i) = CS_LAST_VALUE_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
luaSetStickySwitchBuffer.clear();
|
||||
}
|
||||
|
||||
getvalue_t convertLswTelemValue(LogicalSwitchData * ls)
|
||||
|
||||
Reference in New Issue
Block a user