diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index cbd0958f5..4c41c48d8 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -542,9 +542,8 @@ //#define USE_A4988_STEPPER // Add support for A4988/DRV8825 stepper-motor-driver-circuit (+10k5 code) //#define USE_ARDUINO_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) -// #define USE_ARDUINO_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants -// #define USE_ARDUINO_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini -// #define USE_ARDUINO_INVERT_RESET + #define USE_ARDUINO_FLASH_SPEED 57600 // Usually 57600 for 3.3V variants and 115200 for 5V variants + #define USE_ARDUINO_SERIAL_SPEED 57600 // Depends on the sketch that is running on the Uno/Pro Mini // -- End of general directives ------------------- diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 01fc75129..f85543cd0 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -210,7 +210,8 @@ enum UserSelectablePins { GPIO_EXS_ENABLE, // EXS MCU Enable GPIO_ARDUINO_TXD, // Arduino Slave TX GPIO_ARDUINO_RXD, // Arduino Slave RX - GPIO_ARDUINO_RESET, // Arduino Reset Pin + GPIO_ARDUINO_RST, // Arduino Reset Pin + GPIO_ARDUINO_RST_INV, // Arduino Reset Pin inverted GPIO_SENSOR_END }; // Programmer selectable GPIO functionality @@ -289,7 +290,7 @@ const char kSensorNames[] PROGMEM = D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_ARDUINO_TX "|" D_SENSOR_ARDUINO_RX "|" D_SENSOR_ARDUINO_RESET "|" + D_SENSOR_ARDUINO_TX "|" D_SENSOR_ARDUINO_RX "|" D_SENSOR_ARDUINO_RESET "|" D_SENSOR_ARDUINO_RESET "i|" ; const char kSensorNamesFixed[] PROGMEM = @@ -705,7 +706,8 @@ const uint8_t kGpioNiceList[] PROGMEM = { #ifdef USE_ARDUINO_SLAVE GPIO_ARDUINO_TXD, // Arduino Slave TX GPIO_ARDUINO_RXD, // Arduino Slave RX - GPIO_ARDUINO_RESET, // Arduino Reset Pin + GPIO_ARDUINO_RST, // Arduino Reset Pin + GPIO_ARDUINO_RST_INV, // Arduino Reset Pin inverted #endif #ifdef USE_RDM6300 GPIO_RDM6300_RX, diff --git a/sonoff/xdrv_31_arduino_slave.ino b/sonoff/xdrv_31_arduino_slave.ino index 09e434126..497ab28dd 100644 --- a/sonoff/xdrv_31_arduino_slave.ino +++ b/sonoff/xdrv_31_arduino_slave.ino @@ -18,9 +18,11 @@ */ #ifdef USE_ARDUINO_SLAVE +/*********************************************************************************************\ + * Arduino slave +\*********************************************************************************************/ -#include -#include +#define XDRV_31 31 #define CONST_STK_CRC_EOP 0x20 @@ -32,48 +34,47 @@ #define CMND_STK_LOAD_ADDRESS 0x55 #define CMND_STK_PROG_PAGE 0x64 -uint32_t as_spi_hex_size = 0; -uint8_t as_spi_sector_start = 0x96; -uint8_t as_spi_sector_counter = 0x96; -uint8_t as_spi_sector_cursor = 0; -bool as_flashing = false; +#include +#include -uint8_t as_type = 0; +struct ASLAVE { + uint32_t spi_hex_size = 0; + uint32_t spi_sector_counter = 0; + uint8_t spi_sector_cursor = 0; + uint8_t inverted = LOW; + bool type = false; + bool flashing = false; +} ASlave; TasmotaSerial *ArduinoSlave_Serial; -#define XDRV_31 31 +uint32_t ArduinoSlaveFlashStart(void) +{ + return (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 2; // Stay on the safe side +} uint8_t ArduinoSlave_UpdateInit(void) { - as_spi_hex_size = 0; - as_spi_sector_counter = as_spi_sector_start; // Reset the pre-defined write address where firmware will temporarily be stored - as_spi_sector_cursor = 0; + ASlave.spi_hex_size = 0; + ASlave.spi_sector_counter = ArduinoSlaveFlashStart(); // Reset the pre-defined write address where firmware will temporarily be stored + ASlave.spi_sector_cursor = 0; return 0; } void ArduinoSlave_Reset(void) { - if (as_type) { -#ifdef USE_ARDUINO_INVERT_RESET - digitalWrite(pin[GPIO_ARDUINO_RESET], LOW); + if (ASlave.type) { + digitalWrite(pin[GPIO_ARDUINO_RST], !ASlave.inverted); delay(1); - digitalWrite(pin[GPIO_ARDUINO_RESET], HIGH); + digitalWrite(pin[GPIO_ARDUINO_RST], ASlave.inverted); delay(1); - digitalWrite(pin[GPIO_ARDUINO_RESET], LOW); + digitalWrite(pin[GPIO_ARDUINO_RST], !ASlave.inverted); delay(5); -#else - digitalWrite(pin[GPIO_ARDUINO_RESET], HIGH); - delay(1); - digitalWrite(pin[GPIO_ARDUINO_RESET], LOW); - delay(1); - digitalWrite(pin[GPIO_ARDUINO_RESET], HIGH); - delay(5); -#endif } } -uint8_t ArduinoSlave_waitForSerialData(int dataCount, int timeout) { +uint8_t ArduinoSlave_waitForSerialData(int dataCount, int timeout) +{ int timer = 0; while (timer < timeout) { if (ArduinoSlave_Serial->available() >= dataCount) { @@ -85,24 +86,27 @@ uint8_t ArduinoSlave_waitForSerialData(int dataCount, int timeout) { return 0; } -byte ArduinoSlave_sendBytes(byte* bytes, int count) { +uint8_t ArduinoSlave_sendBytes(uint8_t* bytes, int count) +{ ArduinoSlave_Serial->write(bytes, count); ArduinoSlave_waitForSerialData(2, 1000); - byte sync = ArduinoSlave_Serial->read(); - byte ok = ArduinoSlave_Serial->read(); + uint8_t sync = ArduinoSlave_Serial->read(); + uint8_t ok = ArduinoSlave_Serial->read(); if (sync == 0x14 && ok == 0x10) { return 1; } return 0; } -byte ArduinoSlave_execCmd(byte cmd) { - byte bytes[] = { cmd, CONST_STK_CRC_EOP }; +uint8_t ArduinoSlave_execCmd(uint8_t cmd) +{ + uint8_t bytes[] = { cmd, CONST_STK_CRC_EOP }; return ArduinoSlave_sendBytes(bytes, 2); } -byte ArduinoSlave_execParam(byte cmd, byte* params, int count) { - byte bytes[32]; +uint8_t ArduinoSlave_execParam(uint8_t cmd, uint8_t* params, int count) +{ + uint8_t bytes[32]; bytes[0] = cmd; int i = 0; while (i < count) { @@ -120,10 +124,10 @@ uint8_t ArduinoSlave_exitProgMode(void) void ArduinoSlave_SetupFlash(void) { - byte ProgParams[] = {0x86,0x00,0x00,0x01,0x01,0x01,0x01,0x03,0xff,0xff,0xff,0xff,0x00,0x80,0x04,0x00,0x00,0x00,0x80,0x00}; - byte ExtProgParams[] = {0x05,0x04,0xd7,0xc2,0x00}; + uint8_t ProgParams[] = {0x86,0x00,0x00,0x01,0x01,0x01,0x01,0x03,0xff,0xff,0xff,0xff,0x00,0x80,0x04,0x00,0x00,0x00,0x80,0x00}; + uint8_t ExtProgParams[] = {0x05,0x04,0xd7,0xc2,0x00}; ArduinoSlave_Serial->begin(USE_ARDUINO_FLASH_SPEED); - if (ArduinoSlave_Serial->hardwareSerial()) { + if (ArduinoSlave_Serial->hardwareSerial()) { ClaimSerial(); } ArduinoSlave_Reset(); @@ -133,14 +137,15 @@ void ArduinoSlave_SetupFlash(void) ArduinoSlave_execCmd(CMND_STK_ENTER_PROGMODE); // Enter programming mode } -uint8_t ArduinoSlave_loadAddress(byte adrHi, byte adrLo) { - byte params[] = { adrHi, adrLo }; +uint8_t ArduinoSlave_loadAddress(uint8_t adrHi, uint8_t adrLo) +{ + uint8_t params[] = { adrHi, adrLo }; return ArduinoSlave_execParam(CMND_STK_LOAD_ADDRESS, params, sizeof(params)); } -void ArduinoSlave_FlashPage(byte* address, byte* data) +void ArduinoSlave_FlashPage(uint8_t* address, uint8_t* data) { - byte Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; + uint8_t Header[] = {CMND_STK_PROG_PAGE, 0x00, 0x80, 0x46}; ArduinoSlave_loadAddress(address[1], address[0]); ArduinoSlave_Serial->write(Header, 4); for (int i = 0; i < 128; i++) { @@ -165,24 +170,25 @@ void ArduinoSlave_Flash(void) ArduinoSlave_SetupFlash(); flash_buffer = new char[SPI_FLASH_SEC_SIZE]; + uint32_t flash_start = ArduinoSlaveFlashStart() * SPI_FLASH_SEC_SIZE; while (reading) { - ESP.flashRead(0x96000 + read, (uint32_t*)flash_buffer, FLASH_SECTOR_SIZE); - read = read + FLASH_SECTOR_SIZE; - if (read >= as_spi_hex_size) { + ESP.flashRead(flash_start + read, (uint32_t*)flash_buffer, SPI_FLASH_SEC_SIZE); + read = read + SPI_FLASH_SEC_SIZE; + if (read >= ASlave.spi_hex_size) { reading = false; } - for (uint16_t ca=0; cabegin(USE_ARDUINO_SERIAL_SPEED)) { - if (ArduinoSlave_Serial->hardwareSerial()) { + if (ArduinoSlave_Serial->hardwareSerial()) { ClaimSerial(); } - pinMode(pin[GPIO_ARDUINO_RESET], OUTPUT); - as_type = 1; + if (pin[GPIO_ARDUINO_RST_INV] < 99) { + pin[GPIO_ARDUINO_RST] = pin[GPIO_ARDUINO_RST_INV]; + pin[GPIO_ARDUINO_RST_INV] = 99; + ASlave.inverted = HIGH; + } + pinMode(pin[GPIO_ARDUINO_RST], OUTPUT); + ASlave.type = true; ArduinoSlave_Reset(); AddLog_P2(LOG_LEVEL_INFO, PSTR("Arduino Slave Enabled")); } @@ -244,11 +256,11 @@ void ArduinoSlave_Init(void) void ArduinoSlave_Show(bool json) { - if (as_type) { - char buffer[100]; + if (ASlave.type) { ArduinoSlave_Serial->flush(); ArduinoSlave_Serial->print("JSON"); ArduinoSlave_Serial->find(char(0xFE)); + char buffer[100]; uint16_t haveread = ArduinoSlave_Serial->readBytesUntil(char(0xFF), buffer, sizeof(buffer)-1); buffer[haveread] = '\0'; if (json) { @@ -257,9 +269,14 @@ void ArduinoSlave_Show(bool json) } } +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + bool Xdrv31(uint8_t function) { bool result = false; + switch (function) { case FUNC_EVERY_SECOND: ArduinoSlave_Init(); @@ -267,11 +284,8 @@ bool Xdrv31(uint8_t function) case FUNC_JSON_APPEND: ArduinoSlave_Show(1); break; - case FUNC_COMMAND_DRIVER: - break; - default: - break; } + return result; } -#endif // USE_ARDUINO_SLAVE \ No newline at end of file +#endif // USE_ARDUINO_SLAVE \ No newline at end of file