PCF8574 Overridable address ranges (#17539)

* pcf8574 overridable address ranges

* fix comment

* better test on USE_MCP230xx

* missing change
This commit is contained in:
Barbudor 2022-12-29 21:55:28 +01:00 committed by GitHub
parent d9be488885
commit 99d33e3023
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 12 deletions

View File

@ -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

View File

@ -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)

View File

@ -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) {