diff --git a/I2CDEVICES.md b/I2CDEVICES.md index 3ef236eeb..69551ee2e 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -9,8 +9,8 @@ The following table lists the supported I2C devices Index | Define | Driver | Device | Address(es) | Description ------|---------------------|----------|----------|-------------|----------------------------------------------- 1 | USE_PCA9685 | xdrv_15 | PCA9685 | 0x40 - 0x47 | 16-channel 12-bit pwm driver - 2 | USE_PCF8574 | xdrv_28 | PCF8574 | 0x20 - 0x26 | 8-bit I/O expander - 2 | USE_PCF8574 | xdrv_28 | PCF8574A | 0x39 - 0x3F | 8-bit I/O expander + 2 | USE_PCF8574 | xdrv_28 | PCF8574 | 0x20 - 0x26 | 8-bit I/O expander (address range overridable) + 2 | USE_PCF8574 | xdrv_28 | PCF8574A | 0x39 - 0x3F | 8-bit I/O expander (address range overridable) 3 | USE_DISPLAY_LCD | xdsp_01 | | 0x27, 0x3F | LCD display 4 | USE_DISPLAY_SSD1306 | xdsp_02 | SSD1306 | 0x3C - 0x3D | Oled display 5 | USE_DISPLAY_MATRIX | xdsp_03 | HT16K33 | 0x70 - 0x77 | 8x8 led matrix diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index 9ecf5ce2e..35296863d 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -251,7 +251,7 @@ #define NTP_SERVER1 "2.pool.ntp.org" // [NtpServer1] Select first NTP server by name or IP address (135.125.104.101, 2001:418:3ff::53) #define NTP_SERVER2 "2.europe.pool.ntp.org" // [NtpServer2] Select second NTP server by name or IP address (192.36.143.134, 2a00:2381:19c6::100) #define NTP_SERVER3 "2.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (46.249.42.13, 2603:c022:c003:c900::4) - // To manually set: + // To manually set: // BackLog NtpServer1 2.pool.ntp.org; NtpServer2 2.europe.pool.ntp.org; NtpServer3 2.nl.pool.ntp.org // -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes @@ -657,6 +657,10 @@ // #define USE_PCF8574_SENSOR // enable PCF8574 inputs and outputs in SENSOR message // #define USE_PCF8574_DISPLAYINPUT // enable PCF8574 inputs display in Web page // #define USE_PCF8574_MQTTINPUT // enable MQTT message & rule process on input change detection : stat/%topic%/PCF8574_INP = {"Time":"2021-03-07T16:19:23+01:00","PCF8574-1_INP":{"D1":1}} +// #define PCF8574_ADDR1 0x20 // First address to search for PCF8574 +// #define PCF8574_ADDR1_COUNT 7 // Number of addresses to search for PCF8574 - Default to 0x20 to 0x26 +// #define PCF8574_ADDR2 0x39 // First address to search for PCF8574A +// #define PCF8574_ADDR2_COUNT 6 // Number of addresses to search for PCF8574A - Default to 0x39 to 0x3E // #define USE_HIH6 // [I2cDriver36] Enable Honeywell HIH Humidity and Temperature sensor (I2C address 0x27) (+0k6) // #define USE_DHT12 // [I2cDriver41] Enable DHT12 humidity and temperature sensor (I2C address 0x5C) (+0k7 code) // #define USE_DS1624 // [I2cDriver42] Enable DS1624, DS1621 temperature sensor (I2C addresses 0x48 - 0x4F) (+1k2 code) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino index 907329992..891e07f44 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_28_pcf8574.ino @@ -29,8 +29,37 @@ #define XDRV_28 28 #define XI2C_02 2 // See I2CDEVICES.md -#define PCF8574_ADDR1 0x20 // PCF8574 -#define PCF8574_ADDR2 0x38 // PCF8574A +// Start address and count can be overriden in user_config_override.h to allow better +// sharing of the I2C address space. Still the covered range must remains valid. +// A count of 0 can be used totaly disable any of the 2 ranges. +// By default, the following addresses are explicitly excluded (as per the docs) : +// - 0x27 and 0x37 are reserved for USE_DISPLAY_LCD in xdsp_01_lcd.ino +// - 0X38 is reserved for other sensors +// If the respective drivers are not used, overrides allows to recover those addresses +// If defined, USE_MCP230xx_ADDR is also always excluded + +// PCF8574 address range from 0x20 to 0x26 +#ifndef PCF8574_ADDR1 +#define PCF8574_ADDR1 0x20 // PCF8574 +#endif +#ifndef PCF8574_ADDR1_COUNT +#define PCF8574_ADDR1_COUNT 7 +#endif +// PCF8574A address range from 0x39 to 0x3E +#ifndef PCF8574_ADDR2 +#define PCF8574_ADDR2 0x39 // PCF8574A +#endif +#ifndef PCF8574_ADDR2_COUNT +#define PCF8574_ADDR2_COUNT 6 +#endif + +// Consitency tests - Checked across the complete range for the PCF8574/PCF8574A to allow override +#if (PCF8574_ADDR1 < 0x20) || ((PCF8574_ADDR1 + PCF8574_ADDR1_COUNT - 1) > 0x27) +#error PCF8574_ADDR1 and/or PCF8574_ADDR1_COUNT badly overriden. Fix your user_config_override +#endif +#if (PCF8574_ADDR2 < 0x38) || ((PCF8574_ADDR2 + PCF8574_ADDR2_COUNT - 1) > 0x3F) +#error PCF8574_ADDR2 and/or PCF8574_ADDR2_COUNT badly overriden. Fix your user_config_override. +#endif struct PCF8574 { int error; @@ -82,15 +111,15 @@ void Pcf8574SwitchRelay(void) void Pcf8574Init(void) { - uint8_t pcf8574_address = PCF8574_ADDR1; - while ((Pcf8574.max_devices < MAX_PCF8574) && (pcf8574_address < PCF8574_ADDR2 +8)) { + uint8_t pcf8574_address = (PCF8574_ADDR1_COUNT > 0) ? PCF8574_ADDR1 : PCF8574_ADDR2; + while ((Pcf8574.max_devices < MAX_PCF8574) && (pcf8574_address < PCF8574_ADDR2 +PCF8574_ADDR2_COUNT)) { -#ifdef USE_MCP230xx_ADDR +#if defined(USE_MCP230xx) && defined(USE_MCP230xx_ADDR) if (USE_MCP230xx_ADDR == pcf8574_address) { AddLog(LOG_LEVEL_INFO, PSTR("PCF: Address 0x%02x reserved for MCP320xx skipped"), pcf8574_address); pcf8574_address++; - if ((PCF8574_ADDR1 +7) == pcf8574_address) { // Support I2C addresses 0x20 to 0x26 and 0x39 to 0x3F - pcf8574_address = PCF8574_ADDR2 +1; + if ((PCF8574_ADDR1 +PCF8574_ADDR1_COUNT) == pcf8574_address) { // See comment on allowed addresses and overrides + pcf8574_address = PCF8574_ADDR2; } } #endif @@ -111,8 +140,8 @@ void Pcf8574Init(void) } pcf8574_address++; - if ((PCF8574_ADDR1 +7) == pcf8574_address) { // Support I2C addresses 0x20 to 0x26 and 0x39 to 0x3F - pcf8574_address = PCF8574_ADDR2 +1; + if ((PCF8574_ADDR1 +PCF8574_ADDR1_COUNT) == pcf8574_address) { // Support I2C addresses 0x20 to 0x26 and 0x39 to 0x3F + pcf8574_address = PCF8574_ADDR2; } } if (Pcf8574.type) {