diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 778af80c6..6a4ab7c44 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -66,6 +66,10 @@ { "EVT_"#xxx"_LONG", EVT_KEY_LONG(yyy) }, \ { "EVT_"#xxx"_REPT", EVT_KEY_REPT(yyy) } +#if defined(LUA) && !defined(CLI) +Fifo * luaRxFifo = nullptr; +#endif + /*luadoc @function getVersion() @@ -1615,6 +1619,53 @@ static int luaSerialWrite(lua_State * L) return 0; } +/*luadoc +@function serialRead([num]) +@param num (optional): maximum number of bytes to read. + If non-zero, serialRead will read up to num characters from the buffer. + If 0 or left out, serialRead will read up to and including the first newline character or the end of the buffer. + Note that the returned string may not end in a newline if this character is not present in the buffer. + +@retval str string. Empty if no new characters were available. + +Reads characters from the serial port. The string is allowed to contain any character, including 0. + +@status current Introduced in TODO +*/ +static int luaSerialRead(lua_State * L) +{ + int num = luaL_optunsigned(L, 1, 0); + +#if defined(LUA) && !defined(CLI) + if (!luaRxFifo) { + luaRxFifo = new Fifo(); + if (!luaRxFifo) { + lua_pushlstring(L, "", 0); + return 1; + } + } + uint8_t str[LUA_FIFO_SIZE]; + uint8_t *p = str; + while (luaRxFifo->pop(*p)) { + p++; // increment only when pop was successful + if (p - str >= LUA_FIFO_SIZE) { + break; // Buffer full + } + if (num == 0 && (*(p - 1) == '\n' || *(p - 1) == '\r')) { + break; // Found newline + } + if (num > 0 && p - str >= num) { + break; // Requested number of characters reached + } + } + lua_pushlstring(L, (const char*)str, p - str); +#else + lua_pushlstring(L, "", 0); +#endif + + return 1; +} + const luaL_Reg opentxLib[] = { { "getTime", luaGetTime }, { "getDateTime", luaGetDateTime }, @@ -1662,6 +1713,7 @@ const luaL_Reg opentxLib[] = { { "multiBuffer", luaMultiBuffer }, #endif { "serialWrite", luaSerialWrite }, + { "serialRead", luaSerialRead }, { nullptr, nullptr } /* sentinel */ }; diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 71a1cef01..a0dc8e919 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -41,6 +41,11 @@ extern "C" { #endif #endif +#if !defined(CLI) +#define LUA_FIFO_SIZE 256 +extern Fifo * luaRxFifo; +#endif + extern lua_State * lsScripts; extern lua_State * lsWidgets; extern bool luaLcdAllowed; diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index 35a23073c..4ebef6790 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -192,6 +192,19 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void) } } #endif +#if defined(LUA) && !defined(CLI) + if (luaRxFifo && auxSerialMode == UART_MODE_LUA) { + // Receive + uint32_t status = AUX_SERIAL_USART->SR; + while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { + uint8_t data = AUX_SERIAL_USART->DR; + if (!(status & USART_FLAG_ERRORS)) { + luaRxFifo->push(data); + } + status = AUX_SERIAL_USART->SR; + } + } +#endif } #endif diff --git a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp index dd0233941..4d9409ec8 100644 --- a/radio/src/targets/common/arm/stm32/usbd_cdc.cpp +++ b/radio/src/targets/common/arm/stm32/usbd_cdc.cpp @@ -218,11 +218,18 @@ static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) #if defined(CLI) //copy data to the application FIFO - for (uint32_t i = 0; i < Len; i++) - { + for (uint32_t i = 0; i < Len; i++) { cliRxFifo.push(Buf[i]); } #endif +#if defined(LUA) && !defined(CLI) + // copy data to the LUA FIFO + if (luaRxFifo) { + for (uint32_t i = 0; i < Len; i++) { + luaRxFifo->push(Buf[i]); + } + } +#endif return USBD_OK; }