From 2583d679e1e29aea1316732c186bf97f1142ddbb Mon Sep 17 00:00:00 2001 From: gemu2015 Date: Wed, 16 Feb 2022 16:16:27 +0100 Subject: [PATCH] fix break, add spi --- tasmota/xdrv_10_scripter.ino | 162 ++++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 3 deletions(-) diff --git a/tasmota/xdrv_10_scripter.ino b/tasmota/xdrv_10_scripter.ino index 44bf82dd1..e6ad7b749 100755 --- a/tasmota/xdrv_10_scripter.ino +++ b/tasmota/xdrv_10_scripter.ino @@ -373,6 +373,17 @@ struct GVARS { int16_t strind; }; +#ifdef USE_SCRIPT_SPI +struct SCRIPT_SPI { + int8_t sclk; + int8_t mosi; + int8_t miso; + int8_t cs[4]; + SPIClass *spip; + SPISettings settings; +}; +#endif + #define NUM_RES 0xfe #define STR_RES 0xfd @@ -454,6 +465,10 @@ struct SCRIPT_MEM { #endif float retval; char *retstr; +#ifdef USE_SCRIPT_SPI + struct SCRIPT_SPI spi; +#endif + } glob_script_mem; @@ -4005,6 +4020,96 @@ extern char *SML_GetSVal(uint32_t index); goto exit; } #endif //USE_SCRIPT_SERIAL + + +#ifdef USE_SCRIPT_SPI + if (!strncmp(lp, "spi(", 4)) { + lp = GetNumericArgument(lp + 4, OPER_EQU, &fvar, 0); + uint8_t sel = fvar; + uint8_t index; + switch (sel) { + case 0: + // set bus pins + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + glob_script_mem.spi.sclk = fvar; + + if (glob_script_mem.spi.sclk < 0) { + // attach to existing Tasmota SPI + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + fvar *= 1000000; + glob_script_mem.spi.settings = SPISettings(fvar, MSBFIRST, SPI_MODE0); + + if (TasmotaGlobal.spi_enabled) { +#ifdef EPS8266 + SPI.begin(); + glob_script_mem.spi.spip = &SPI; +#endif // EPS8266 + +#ifdef ESP32 + if (glob_script_mem.spi.sclk == -1) { + SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1); + glob_script_mem.spi.spip = &SPI; + } else { + glob_script_mem.spi.spip = new SPIClass(HSPI); + glob_script_mem.spi.spip->begin(Pin(GPIO_SPI_CLK, 1), Pin(GPIO_SPI_MISO, 1), Pin(GPIO_SPI_MOSI, 1), -1); + } + +#endif // ESP32 + } else { + AddLog(LOG_LEVEL_INFO, PSTR("error: spi pins not defined")); + } + break; + } + pinMode(glob_script_mem.spi.sclk , OUTPUT); + digitalWrite(glob_script_mem.spi.sclk , 0); + + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + glob_script_mem.spi.mosi = fvar; + if (glob_script_mem.spi.mosi >= 0) { + pinMode(glob_script_mem.spi.mosi , OUTPUT); + digitalWrite(glob_script_mem.spi.mosi , 0); + } + + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + glob_script_mem.spi.miso = fvar; + if (glob_script_mem.spi.miso >= 0) { + pinMode(glob_script_mem.spi.miso , INPUT_PULLUP); + } + + if (Is_gpio_used(glob_script_mem.spi.mosi) || Is_gpio_used(glob_script_mem.spi.miso) + || Is_gpio_used(glob_script_mem.spi.sclk) ) { + AddLog(LOG_LEVEL_INFO, PSTR("warning: pins already used")); + } + break; + + case 1: + // set cs + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + index = fvar; + index &= 3; + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + glob_script_mem.spi.cs[index] = fvar; + pinMode(glob_script_mem.spi.cs[index] , OUTPUT); + digitalWrite(glob_script_mem.spi.cs[index] , 1); + if (Is_gpio_used(glob_script_mem.spi.cs[index])) { + AddLog(LOG_LEVEL_INFO, PSTR("warning: pins already used")); + } + break; + + case 2: + // transfer bytes + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + uint8_t index = fvar; + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + uint32_t val = fvar; + lp = GetNumericArgument(lp , OPER_EQU, &fvar, 0); + script_sspi_trans(index & 3, val, fvar); + break; + } + len = 0; + goto exit; + } +#endif // USE_SCRIPT_SPI break; case 't': @@ -5402,7 +5507,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { } else { glob_script_mem.retstr = 0; } - section = 0; + section = 99; goto next_line; } else if (!strncmp(lp, "break", 5)) { lp += 5; @@ -5413,7 +5518,8 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { } floop = 0; } else { - section = 0; + section = 99; + // leave immediately } goto next_line; } else if (!strncmp(lp, "dp", 2) && isdigit(*(lp + 2))) { @@ -5973,6 +6079,7 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { } // next line next_line: + if (section == 99) return 0; if (*lp==SCRIPT_EOL) { lp++; } else { @@ -5990,6 +6097,55 @@ int16_t Run_script_sub(const char *type, int8_t tlen, struct GVARS *gv) { return -1; } + +#ifdef USE_SCRIPT_SPI +// transfer 1-3 bytes +uint32_t script_sspi_trans(uint32_t cs_index, uint32_t val, uint32_t size) { + uint32_t out = 0; + + digitalWrite(glob_script_mem.spi.cs[cs_index], 0); + + if (glob_script_mem.spi.sclk < 0) { + // use existing hardware spi + glob_script_mem.spi.spip->beginTransaction(glob_script_mem.spi.settings); + if (size == 1) { + out = glob_script_mem.spi.spip->transfer(val); + } + if (size == 2) { + out = glob_script_mem.spi.spip->transfer16(val); + } + if (size == 3) { + out = glob_script_mem.spi.spip->transfer(val >> 16); + out <<= 16; + out |= glob_script_mem.spi.spip->transfer16(val); + } + //SPI.transferBytes(); + glob_script_mem.spi.spip->endTransaction(); + digitalWrite(glob_script_mem.spi.cs[cs_index], 1); + return out; + } + + if (size < 1 || size > 3) size = 1; + uint32_t bit = 1 << ((size * 8) - 1); + while (bit) { + digitalWrite(glob_script_mem.spi.sclk, 0); + if (glob_script_mem.spi.mosi >= 0) { + if (val & bit) digitalWrite(glob_script_mem.spi.mosi, 1); + else digitalWrite(glob_script_mem.spi.mosi, 0); + } + digitalWrite(glob_script_mem.spi.sclk, 1); + if (glob_script_mem.spi.miso >= 0) { + if (digitalRead(glob_script_mem.spi.miso)) { + out |= bit; + } + } + bit >>= 1; + } + digitalWrite(glob_script_mem.spi.cs[cs_index], 1); + return out; +} +#endif // USE_SCRIPT_SPI + #ifdef USE_SCRIPT_SERIAL bool Script_Close_Serial() { if (glob_script_mem.sp) { @@ -6004,7 +6160,7 @@ bool Script_Close_Serial() { #endif //USE_SCRIPT_SERIAL bool Is_gpio_used(uint8_t gpiopin) { - if ((gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { + if (gpiopin >= 0 && (gpiopin < nitems(TasmotaGlobal.gpio_pin)) && (TasmotaGlobal.gpio_pin[gpiopin] > 0)) { return true; } return false;