mirror of https://github.com/arendst/Tasmota.git
Update changelogs
- Add MCP23008 virtual switch/button/relay support
This commit is contained in:
parent
edb2fad6c1
commit
d07d4b06c9
|
@ -12,6 +12,8 @@ All notable changes to this project will be documented in this file.
|
|||
### Changed
|
||||
|
||||
### Fixed
|
||||
- TuyaMcu v1 sequence fix (#17625)
|
||||
- TuyaMcu v1 timer integer overflow (#18048)
|
||||
|
||||
### Removed
|
||||
|
||||
|
|
|
@ -126,8 +126,10 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
|
|||
- Move #define OTA_URL from user_config.h to board files for better inital support [#18008](https://github.com/arendst/Tasmota/issues/18008)
|
||||
|
||||
### Fixed
|
||||
- TuyaMcu v1 sequence fix [#17625](https://github.com/arendst/Tasmota/issues/17625)
|
||||
- SEN5X floats and units [#17961](https://github.com/arendst/Tasmota/issues/17961)
|
||||
- Energytotals cannot be set to negative values [#17965](https://github.com/arendst/Tasmota/issues/17965)
|
||||
- SR04 driver single pin ultrasonic sensor detection [#17966](https://github.com/arendst/Tasmota/issues/17966)
|
||||
- IR panasonic protocol regression from v12.0.2.4 [#18013](https://github.com/arendst/Tasmota/issues/18013)
|
||||
- EnergyTotal divided twice during minimal upgrade step regression from v12.3.1.3 [#18024](https://github.com/arendst/Tasmota/issues/18024)
|
||||
- TuyaMcu v1 timer integer overflow [#18048](https://github.com/arendst/Tasmota/issues/18048)
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
* and handle any input and output as configured GPIOs.
|
||||
*
|
||||
* Restrictions:
|
||||
* - Supports MCP23017 (=I2C) and MCP23S17 (=SPI)
|
||||
* - Uses incremental I2C addresses / SPI Chip select until template pin count reached
|
||||
* - Max support for 28 switches (input), 32 buttons (input), 32 relays (output)
|
||||
*
|
||||
|
@ -38,14 +37,16 @@
|
|||
* Switch_n1..28 Sn 192..219 Switch to Gnd without internal pullup
|
||||
* Relay1..28 R 224..255 Relay
|
||||
* Relay_i1..28 Ri 256..287 Relay inverted
|
||||
* Output_Hi Oh 3840 Fixed output high
|
||||
* Output_lo Ol 3872 Fixed output low
|
||||
*
|
||||
* Prepare a template to be loaded either by:
|
||||
* - a rule like: rule3 on file#mcp23x.dat do {"NAME":"MCP23017 A=Ri8-1, B=B1-8","GPIO":[263,262,261,260,259,258,257,256,32,33,34,35,36,37,38,39]} endon
|
||||
* - a script like: -y{"NAME":"MCP23017 A=Ri8-1, B=B1-8","GPIO":[263,262,261,260,259,258,257,256,32,33,34,35,36,37,38,39]}
|
||||
* - file called mcp23x.dat with contents: {"NAME":"MCP23017 A=Ri8-1, B=B1-8","GPIO":[263,262,261,260,259,258,257,256,32,33,34,35,36,37,38,39]}
|
||||
*
|
||||
* S3 S2 B2 B3 B1 S1 R1 R4 R2 R3 S4
|
||||
* {"NAME":"MCP23S17 Shelly Pro 4PM","GPIO":[194,193,65,66,0,64,192,0,224,0,0,0,227,225,226,195]}
|
||||
* S3 S2 B2 B3 Oh B1 S1 R1 R4 R2 R3 S4
|
||||
* {"NAME":"MCP23S17 Shelly Pro 4PM","GPIO":[194,193,65,66,3840,64,192,0,224,0,0,0,227,225,226,195]}
|
||||
*
|
||||
* Inverted relays and buttons Ri8 Ri7 Ri6 Ri5 Ri4 Ri3 Ri2 Ri1 B1 B2 B3 B4 B5 B6 B7 B8
|
||||
* {"NAME":"MCP23017 A=Ri8-1, B=B1-8","GPIO":[263,262,261,260,259,258,257,256,32,33,34,35,36,37,38,39]}
|
||||
|
@ -71,13 +72,15 @@
|
|||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_67 67
|
||||
#define XI2C_77 77 // See I2CDEVICES.md
|
||||
#define XI2C_77 77 // See I2CDEVICES.md
|
||||
|
||||
#define MCP23XXX_ADDR_START 0x20 // 32
|
||||
#define MCP23XXX_ADDR_END 0x26 // 38
|
||||
#define MCP23XXX_ADDR_START 0x20 // 32
|
||||
#define MCP23XXX_ADDR_END 0x26 // 38
|
||||
|
||||
#define MCP23XXX_MAX_DEVICES 6
|
||||
|
||||
#define MCP23XXX_SPI_CLOCK 1000000 // SPI clock speed set to 1MHz in case of signal interference at higher speed (Max is 10MHz)
|
||||
|
||||
/*********************************************************************************************\
|
||||
* MCP23017 support
|
||||
\*********************************************************************************************/
|
||||
|
@ -133,7 +136,6 @@ typedef struct {
|
|||
uint8_t address;
|
||||
uint8_t interface;
|
||||
uint8_t pins; // 8 (MCP23008) or 16 (MCP23017 / MCP23S17)
|
||||
uint8_t type; // 1 (MCP23008) or 2 (MCP23017) or 3 (MCP23S17)
|
||||
int8_t pin_cs;
|
||||
int8_t pin_int;
|
||||
} tMcp23xDevice;
|
||||
|
@ -162,7 +164,7 @@ uint16_t *Mcp23x_gpio_pin = nullptr;
|
|||
|
||||
#ifdef USE_SPI
|
||||
void MCP23xEnable(void) {
|
||||
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
|
||||
SPI.beginTransaction(SPISettings(MCP23XXX_SPI_CLOCK, MSBFIRST, SPI_MODE0));
|
||||
digitalWrite(Mcp23x.device[Mcp23x.chip].pin_cs, 0);
|
||||
}
|
||||
|
||||
|
@ -175,12 +177,14 @@ void MCP23xDisable(void) {
|
|||
void MCP23xDumpRegs(void) {
|
||||
uint8_t data[22];
|
||||
for (Mcp23x.chip = 0; Mcp23x.chip < Mcp23x.max_devices; Mcp23x.chip++) {
|
||||
uint32_t data_size = sizeof(data);
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) { data_size /= 2; }
|
||||
#ifdef USE_SPI
|
||||
if (MCP23X_SPI == Mcp23x.device[Mcp23x.chip].interface) {
|
||||
MCP23xEnable();
|
||||
SPI.transfer(Mcp23x.device[Mcp23x.chip].address | 1);
|
||||
SPI.transfer(0);
|
||||
for (uint32_t i = 0; i < sizeof(data); i++) {
|
||||
for (uint32_t i = 0; i < data_size; i++) {
|
||||
data[i] = SPI.transfer(0xFF);
|
||||
}
|
||||
MCP23xDisable();
|
||||
|
@ -188,10 +192,10 @@ void MCP23xDumpRegs(void) {
|
|||
#endif
|
||||
#ifdef USE_I2C
|
||||
if (MCP23X_I2C == Mcp23x.device[Mcp23x.chip].interface) {
|
||||
I2cReadBuffer(Mcp23x.device[Mcp23x.chip].address, 0, data, sizeof(data));
|
||||
I2cReadBuffer(Mcp23x.device[Mcp23x.chip].address, 0, data, data_size);
|
||||
}
|
||||
#endif
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP: Intf %d, Address %02X, Regs %*_H"), Mcp23x.device[Mcp23x.chip].interface, Mcp23x.device[Mcp23x.chip].address, sizeof(data), data);
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MCP: Intf %d, Address %02X, Regs %*_H"), Mcp23x.device[Mcp23x.chip].interface, Mcp23x.device[Mcp23x.chip].address, data_size, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,6 +283,9 @@ void MCP23xUpdate(uint8_t pin, bool pin_value, uint8_t reg_addr) {
|
|||
uint8_t reg_value = 0;
|
||||
if (reg_addr == MCP23X17_OLATA) {
|
||||
reg_value = Mcp23x.device[Mcp23x.chip].olata;
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
reg_addr = MCP23X08_OLAT;
|
||||
}
|
||||
} else if (reg_addr == MCP23X17_OLATB) {
|
||||
reg_value = Mcp23x.device[Mcp23x.chip].olatb;
|
||||
} else {
|
||||
|
@ -290,6 +297,9 @@ void MCP23xUpdate(uint8_t pin, bool pin_value, uint8_t reg_addr) {
|
|||
reg_value &= ~(1 << bit);
|
||||
}
|
||||
MCP23xWrite(reg_addr, reg_value);
|
||||
if ((8 == Mcp23x.device[Mcp23x.chip].pins) && (reg_addr == MCP23X08_OLAT)) {
|
||||
reg_addr = MCP23X17_OLATA;
|
||||
}
|
||||
if (reg_addr == MCP23X17_OLATA) {
|
||||
Mcp23x.device[Mcp23x.chip].olata = reg_value;
|
||||
} else if (reg_addr == MCP23X17_OLATB) {
|
||||
|
@ -299,12 +309,28 @@ void MCP23xUpdate(uint8_t pin, bool pin_value, uint8_t reg_addr) {
|
|||
|
||||
/*********************************************************************************************/
|
||||
|
||||
uint32_t MCP23xSetChip(uint8_t pin) {
|
||||
// Calculate chip based on number of pins per chip. 8 for MCP23008, 16 for MCP23x17
|
||||
// pin 0 - 63
|
||||
for (Mcp23x.chip = 0; Mcp23x.chip < Mcp23x.max_devices; Mcp23x.chip++) {
|
||||
if (Mcp23x.device[Mcp23x.chip].pins > pin) { break; }
|
||||
pin -= Mcp23x.device[Mcp23x.chip].pins;
|
||||
}
|
||||
return pin; // relative pin number within chip (0 ... 7 or 0 ... 15)
|
||||
}
|
||||
|
||||
void MCP23xPinMode(uint8_t pin, uint8_t flags) {
|
||||
// pin 0 - 31
|
||||
Mcp23x.chip = pin / 16;
|
||||
pin = pin % 16;
|
||||
uint8_t iodir = pin < 8 ? MCP23X17_IODIRA : MCP23X17_IODIRB;
|
||||
uint8_t gppu = pin < 8 ? MCP23X17_GPPUA : MCP23X17_GPPUB;
|
||||
// pin 0 - 63
|
||||
pin = MCP23xSetChip(pin);
|
||||
uint8_t iodir;
|
||||
uint8_t gppu;
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
iodir = MCP23X08_IODIR;
|
||||
gppu = MCP23X08_GPPU;
|
||||
} else {
|
||||
iodir = pin < 8 ? MCP23X17_IODIRA : MCP23X17_IODIRB;
|
||||
gppu = pin < 8 ? MCP23X17_GPPUA : MCP23X17_GPPUB;
|
||||
}
|
||||
switch (flags) {
|
||||
case INPUT:
|
||||
MCP23xUpdate(pin, true, iodir);
|
||||
|
@ -318,15 +344,25 @@ void MCP23xPinMode(uint8_t pin, uint8_t flags) {
|
|||
MCP23xUpdate(pin, false, iodir);
|
||||
break;
|
||||
}
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: MCP23xPinMode chip %d, pin %d, flags %d, regs %d,%d"), Mcp23x.chip, pin, flags, iodir, gppu);
|
||||
}
|
||||
|
||||
void MCP23xPinInterruptMode(uint8_t pin, uint8_t interrupt_mode) {
|
||||
// pin 0 - 31
|
||||
Mcp23x.chip = pin / 16;
|
||||
pin = pin % 16;
|
||||
uint8_t gpinten = pin < 8 ? MCP23X17_GPINTENA : MCP23X17_GPINTENB;
|
||||
uint8_t intcon = pin < 8 ? MCP23X17_INTCONA : MCP23X17_INTCONB;
|
||||
uint8_t defval = pin < 8 ? MCP23X17_DEFVALA : MCP23X17_DEFVALB;
|
||||
// pin 0 - 63
|
||||
pin = MCP23xSetChip(pin);
|
||||
uint8_t gpinten;
|
||||
uint8_t intcon;
|
||||
uint8_t defval;
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
gpinten = MCP23X08_GPINTEN;
|
||||
intcon = MCP23X08_INTCON;
|
||||
defval = MCP23X08_DEFVAL;
|
||||
} else {
|
||||
gpinten = pin < 8 ? MCP23X17_GPINTENA : MCP23X17_GPINTENB;
|
||||
intcon = pin < 8 ? MCP23X17_INTCONA : MCP23X17_INTCONB;
|
||||
defval = pin < 8 ? MCP23X17_DEFVALA : MCP23X17_DEFVALB;
|
||||
}
|
||||
switch (interrupt_mode) {
|
||||
case MCP23XXX_CHANGE:
|
||||
MCP23xUpdate(pin, true, gpinten);
|
||||
|
@ -348,21 +384,35 @@ void MCP23xPinInterruptMode(uint8_t pin, uint8_t interrupt_mode) {
|
|||
}
|
||||
}
|
||||
|
||||
void MCP23xSetPinModes(uint8_t pin, uint8_t flags) {
|
||||
// pin 0 - 63
|
||||
MCP23xPinMode(pin, flags);
|
||||
if (Mcp23x.device[Mcp23x.chip].pin_int > -1) { // Mcp23x.chip is updated by call to MCP23xPinMode
|
||||
MCP23xPinInterruptMode(pin, MCP23XXX_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
bool MCP23xDigitalRead(uint8_t pin) {
|
||||
// pin 0 - 31
|
||||
Mcp23x.chip = pin / 16;
|
||||
pin = pin % 16;
|
||||
// pin 0 - 63
|
||||
pin = MCP23xSetChip(pin);
|
||||
uint8_t bit = pin % 8;
|
||||
uint8_t reg_addr = pin < 8 ? MCP23X17_GPIOA : MCP23X17_GPIOB;
|
||||
uint8_t reg_addr;
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
reg_addr = MCP23X08_GPIO;
|
||||
} else {
|
||||
reg_addr = pin < 8 ? MCP23X17_GPIOA : MCP23X17_GPIOB;
|
||||
}
|
||||
uint8_t value = MCP23xRead(reg_addr);
|
||||
return value & (1 << bit);
|
||||
}
|
||||
|
||||
void MCP23xDigitalWrite(uint8_t pin, bool value) {
|
||||
// pin 0 - 31
|
||||
Mcp23x.chip = pin / 16;
|
||||
pin = pin % 16;
|
||||
// pin 0 - 63
|
||||
pin = MCP23xSetChip(pin);
|
||||
uint8_t reg_addr = pin < 8 ? MCP23X17_OLATA : MCP23X17_OLATB;
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: MCP23xDigitalWrite chip %d, pin %d, state %d, reg %d"), Mcp23x.chip, pin, value, reg_addr);
|
||||
|
||||
MCP23xUpdate(pin, value, reg_addr);
|
||||
}
|
||||
|
||||
|
@ -370,8 +420,8 @@ void MCP23xDigitalWrite(uint8_t pin, bool value) {
|
|||
* Tasmota
|
||||
\*********************************************************************************************/
|
||||
|
||||
int IRAM_ATTR MCP23xPin(uint32_t gpio, uint32_t index = 0);
|
||||
int IRAM_ATTR MCP23xPin(uint32_t gpio, uint32_t index) {
|
||||
int MCP23xPin(uint32_t gpio, uint32_t index = 0);
|
||||
int MCP23xPin(uint32_t gpio, uint32_t index) {
|
||||
uint16_t real_gpio = gpio << 5;
|
||||
uint16_t mask = 0xFFE0;
|
||||
if (index < GPIO_ANY) {
|
||||
|
@ -419,13 +469,6 @@ String MCP23xTemplateLoadFile(void) {
|
|||
return mcptmplt;
|
||||
}
|
||||
|
||||
void MCP23xSetPinModes(uint8_t pin, uint8_t flags) {
|
||||
MCP23xPinMode(pin, flags);
|
||||
if (Mcp23x.device[Mcp23x.chip].pin_int > -1) { // Mcp23x.chip is updated by call to MCP23xPinMode
|
||||
MCP23xPinInterruptMode(pin, MCP23XXX_CHANGE);
|
||||
}
|
||||
}
|
||||
|
||||
bool MCP23xLoadTemplate(void) {
|
||||
String mcptmplt = MCP23xTemplateLoadFile();
|
||||
uint32_t len = mcptmplt.length() +1;
|
||||
|
@ -494,6 +537,14 @@ bool MCP23xLoadTemplate(void) {
|
|||
Mcp23x.relay_max++;
|
||||
MCP23xPinMode(pin, OUTPUT);
|
||||
}
|
||||
else if (mpin == AGPIO(GPIO_OUTPUT_HI)) {
|
||||
MCP23xPinMode(pin, OUTPUT);
|
||||
MCP23xDigitalWrite(pin, true);
|
||||
}
|
||||
else if (mpin == AGPIO(GPIO_OUTPUT_LO)) {
|
||||
MCP23xPinMode(pin, OUTPUT);
|
||||
MCP23xDigitalWrite(pin, false);
|
||||
}
|
||||
else { mpin = 0; }
|
||||
Mcp23x_gpio_pin[pin] = mpin;
|
||||
}
|
||||
|
@ -552,7 +603,6 @@ void MCP23xModuleInit(void) {
|
|||
Mcp23x.device[Mcp23x.chip].interface = MCP23X_SPI;
|
||||
Mcp23x.device[Mcp23x.chip].address = MCP23XXX_ADDR_START << 1;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("SPI: MCP23S17 found at CS%d"), Mcp23x.chip +1);
|
||||
Mcp23x.device[Mcp23x.chip].type = 3;
|
||||
Mcp23x.device[Mcp23x.chip].pins = 16;
|
||||
MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing
|
||||
Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X17_OLATA);
|
||||
|
@ -578,16 +628,14 @@ void MCP23xModuleInit(void) {
|
|||
uint8_t buffer;
|
||||
if (MCP23xValidRead(MCP23X08_IOCON, &buffer)) {
|
||||
if (0x00 == buffer) {
|
||||
/*
|
||||
I2cSetActiveFound(mcp23xxx_address, "MCP23008");
|
||||
Mcp23x.device[Mcp23x.chip].type = 1;
|
||||
Mcp23x.device[Mcp23x.chip].pins = 8;
|
||||
MCP23xWrite(MCP23X08_IOCON, 0b00011000); // Slew rate disabled, HAEN pins for addressing
|
||||
Mcp23x.device[Mcp23x.chip].olata = MCP23xRead(MCP23X08_OLAT);
|
||||
Mcp23x.max_devices++;
|
||||
*/
|
||||
}
|
||||
else if (0x80 == buffer) {
|
||||
I2cSetActiveFound(mcp23xxx_address, "MCP23017");
|
||||
Mcp23x.device[Mcp23x.chip].type = 2;
|
||||
Mcp23x.device[Mcp23x.chip].pins = 16;
|
||||
MCP23xWrite(MCP23X08_IOCON, 0x00); // Reset bank mode to 0 (MCP23X17_GPINTENB)
|
||||
MCP23xWrite(MCP23X17_IOCONA, 0b01011000); // Enable INT mirror, Slew rate disabled, HAEN pins for addressing
|
||||
|
@ -630,11 +678,16 @@ void MCP23xModuleInit(void) {
|
|||
|
||||
void MCP23xServiceInput(void) {
|
||||
// I found no reliable way to receive interrupts; noise received at undefined moments - unstable usage
|
||||
Mcp23x.interrupt = 0;
|
||||
Mcp23x.interrupt = false;
|
||||
// This works with no interrupt
|
||||
uint32_t pin_offset = 0;
|
||||
uint32_t gpio;
|
||||
for (Mcp23x.chip = 0; Mcp23x.chip < Mcp23x.max_devices; Mcp23x.chip++) {
|
||||
uint32_t gpio = MCP23xRead16(MCP23X17_GPIOA); // Read gpio
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
gpio = MCP23xRead(MCP23X08_GPIO); // Read MCP23008 gpio
|
||||
} else {
|
||||
gpio = MCP23xRead16(MCP23X17_GPIOA); // Read MCP23x17 gpio
|
||||
}
|
||||
|
||||
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("MCP: Chip %d, State %04X"), Mcp23x.chip, gpio);
|
||||
|
||||
|
@ -657,14 +710,19 @@ void MCP23xServiceInput(void) {
|
|||
}
|
||||
|
||||
void IRAM_ATTR MCP23xInputIsr(void) {
|
||||
Mcp23x.interrupt = 1;
|
||||
Mcp23x.interrupt = true;
|
||||
}
|
||||
|
||||
void MCP23xInit(void) {
|
||||
if (Mcp23x.button_max || Mcp23x.switch_max) {
|
||||
uint32_t gpio;
|
||||
for (Mcp23x.chip = 0; Mcp23x.chip < Mcp23x.max_devices; Mcp23x.chip++) {
|
||||
if (Mcp23x.device[Mcp23x.chip].pin_int > -1) {
|
||||
uint32_t gpio = MCP23xRead16(MCP23X17_GPIOA); // Clear interrupt
|
||||
if (8 == Mcp23x.device[Mcp23x.chip].pins) {
|
||||
gpio = MCP23xRead(MCP23X08_GPIO); // Clear MCP23008 interrupt
|
||||
} else {
|
||||
gpio = MCP23xRead16(MCP23X17_GPIOA); // Clear MCP23x17 interrupt
|
||||
}
|
||||
attachInterrupt(Mcp23x.device[Mcp23x.chip].pin_int, MCP23xInputIsr, CHANGE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350"}
|
||||
* {"NAME":"Shelly Pro 2","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"}
|
||||
* {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;AdcParam2 2,5600,4700,3350"}
|
||||
* {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,10272,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,10240,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;rule3 on file#mcp23x.dat do {\"NAME\":\"MCP23S17 Shelly Pro 4PM\",\"GPIO\":[194,193,65,66,0,64,192,0,224,0,0,0,227,225,226,195]} endon"}
|
||||
* {"NAME":"Shelly Pro 4PM","GPIO":[0,6210,0,6214,9568,0,0,0,0,0,9569,0,10272,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,736,704,3461,10240,4736,0,0,672],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,5600,4700,3350;rule3 on file#mcp23x.dat do {\"NAME\":\"MCP23S17 Shelly Pro 4PM\",\"GPIO\":[194,193,65,66,3840,64,192,0,224,0,0,0,227,225,226,195]} endon"}
|
||||
*
|
||||
* Shelly Pro 1/2 uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
|
||||
* Shelly Pro 4 uses an SPI to control one MCP23S17 for buttons/switches/relays/leds and two ADE7953 for energy monitoring and a second SPI for the display
|
||||
|
@ -78,7 +78,7 @@ void ShellyPro4Init(void) {
|
|||
}
|
||||
|
||||
void ShellyPro4Reset(void) {
|
||||
MCP23xPinMode(4, OUTPUT);
|
||||
// MCP23xPinMode(4, OUTPUT); // Performed by MCP23x.dat template as Output_Hi
|
||||
MCP23xDigitalWrite(4, 0); // Reset pin display, ADE7953
|
||||
delay(1); // To initiate a hardware reset, this pin must be brought low for a minimum of 10 μs.
|
||||
MCP23xDigitalWrite(4, 1);
|
||||
|
|
Loading…
Reference in New Issue