diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 41dd02458e..d1ef3bd822 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -27,6 +27,7 @@ - [ ] RP2040 - [ ] BK72xx - [ ] RTL87xx +- [ ] LN882x - [ ] nRF52840 ## Example entry for `config.yaml`: diff --git a/esphome/components/bk72xx/__init__.py b/esphome/components/bk72xx/__init__.py index 5b14d0529d..7fed742d2e 100644 --- a/esphome/components/bk72xx/__init__.py +++ b/esphome/components/bk72xx/__init__.py @@ -1,9 +1,23 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. -# For custom pin validators, put validate_pin() or validate_usage() -# in gpio.py file in this directory. -# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA -# in schema.py file in this directory. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. + +To customize this component: + - Pin validators: Create gpio.py with validate_pin() or validate_usage() + - Schema extensions: Create schema.py with COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA + +Platform-specific code should be added to the main libretiny component +(__init__.py in esphome/components/libretiny/) rather than here. +""" from esphome import pins from esphome.components import libretiny @@ -27,6 +41,7 @@ COMPONENT_DATA = LibreTinyComponent( board_pins=BK72XX_BOARD_PINS, pin_validation=None, usage_validation=None, + supports_atomics=False, ) diff --git a/esphome/components/bk72xx/boards.py b/esphome/components/bk72xx/boards.py index 8e3e8a97a2..3850dbe266 100644 --- a/esphome/components/bk72xx/boards.py +++ b/esphome/components/bk72xx/boards.py @@ -1,5 +1,16 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. +""" from esphome.components.libretiny.const import ( FAMILY_BK7231N, @@ -9,6 +20,22 @@ from esphome.components.libretiny.const import ( ) BK72XX_BOARDS = { + "wb2l-m1": { + "name": "WB2L_M1 Wi-Fi Module", + "family": FAMILY_BK7231N, + }, + "cbu": { + "name": "CBU Wi-Fi Module", + "family": FAMILY_BK7231N, + }, + "generic-bk7231t-qfn32-tuya": { + "name": "Generic - BK7231T (Tuya QFN32)", + "family": FAMILY_BK7231T, + }, + "generic-bk7231n-qfn32-tuya": { + "name": "Generic - BK7231N (Tuya QFN32)", + "family": FAMILY_BK7231N, + }, "cb1s": { "name": "CB1S Wi-Fi Module", "family": FAMILY_BK7231N, @@ -17,85 +44,324 @@ BK72XX_BOARDS = { "name": "CB2L Wi-Fi Module", "family": FAMILY_BK7231N, }, - "cb2s": { - "name": "CB2S Wi-Fi Module", - "family": FAMILY_BK7231N, - }, - "cb3l": { - "name": "CB3L Wi-Fi Module", + "cblc5": { + "name": "CBLC5 Wi-Fi Module", "family": FAMILY_BK7231N, }, "cb3s": { "name": "CB3S Wi-Fi Module", "family": FAMILY_BK7231N, }, - "cb3se": { - "name": "CB3SE Wi-Fi Module", - "family": FAMILY_BK7231N, - }, - "cblc5": { - "name": "CBLC5 Wi-Fi Module", - "family": FAMILY_BK7231N, - }, - "cbu": { - "name": "CBU Wi-Fi Module", - "family": FAMILY_BK7231N, - }, - "generic-bk7231n-qfn32-tuya": { - "name": "Generic - BK7231N (Tuya QFN32)", - "family": FAMILY_BK7231N, - }, - "generic-bk7231t-qfn32-tuya": { - "name": "Generic - BK7231T (Tuya QFN32)", - "family": FAMILY_BK7231T, - }, - "generic-bk7252": { - "name": "Generic - BK7252", - "family": FAMILY_BK7251, - }, - "lsc-lma35-t": { - "name": "LSC LMA35 BK7231T", + "wb3s": { + "name": "WB3S Wi-Fi Module", "family": FAMILY_BK7231T, }, "lsc-lma35": { "name": "LSC LMA35 BK7231N", "family": FAMILY_BK7231N, }, - "wa2": { - "name": "WA2 Wi-Fi Module", - "family": FAMILY_BK7231Q, - }, - "wb1s": { - "name": "WB1S Wi-Fi Module", - "family": FAMILY_BK7231T, - }, - "wb2l-m1": { - "name": "WB2L_M1 Wi-Fi Module", - "family": FAMILY_BK7231N, + "generic-bk7252": { + "name": "Generic - BK7252", + "family": FAMILY_BK7251, }, "wb2l": { "name": "WB2L Wi-Fi Module", "family": FAMILY_BK7231T, }, - "wb2s": { - "name": "WB2S Wi-Fi Module", - "family": FAMILY_BK7231T, - }, - "wb3l": { - "name": "WB3L Wi-Fi Module", - "family": FAMILY_BK7231T, - }, - "wb3s": { - "name": "WB3S Wi-Fi Module", + "wb1s": { + "name": "WB1S Wi-Fi Module", "family": FAMILY_BK7231T, }, "wblc5": { "name": "WBLC5 Wi-Fi Module", "family": FAMILY_BK7231T, }, + "cb2s": { + "name": "CB2S Wi-Fi Module", + "family": FAMILY_BK7231N, + }, + "wa2": { + "name": "WA2 Wi-Fi Module", + "family": FAMILY_BK7231Q, + }, + "cb3l": { + "name": "CB3L Wi-Fi Module", + "family": FAMILY_BK7231N, + }, + "lsc-lma35-t": { + "name": "LSC LMA35 BK7231T", + "family": FAMILY_BK7231T, + }, + "cb3se": { + "name": "CB3SE Wi-Fi Module", + "family": FAMILY_BK7231N, + }, + "wb3l": { + "name": "WB3L Wi-Fi Module", + "family": FAMILY_BK7231T, + }, + "wb2s": { + "name": "WB2S Wi-Fi Module", + "family": FAMILY_BK7231T, + }, } BK72XX_BOARD_PINS = { + "wb2l-m1": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P10": 10, + "P11": 11, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 8, + "D1": 7, + "D2": 6, + "D3": 26, + "D4": 24, + "D5": 10, + "D6": 11, + "D7": 1, + "D8": 0, + "D9": 20, + "D10": 21, + "D11": 23, + "D12": 22, + "A0": 23, + }, + "cbu": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "CS": 15, + "MISO": 17, + "MOSI": 16, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P9": 9, + "P10": 10, + "P11": 11, + "P14": 14, + "P15": 15, + "P16": 16, + "P17": 17, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "P28": 28, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM3": 9, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCK": 14, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 14, + "D1": 16, + "D2": 20, + "D3": 22, + "D4": 23, + "D5": 1, + "D6": 0, + "D7": 8, + "D8": 7, + "D9": 6, + "D10": 26, + "D11": 24, + "D12": 11, + "D13": 10, + "D14": 28, + "D15": 9, + "D16": 17, + "D17": 15, + "D18": 21, + "A0": 23, + }, + "generic-bk7231t-qfn32-tuya": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "CS": 15, + "MISO": 17, + "MOSI": 16, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P9": 9, + "P10": 10, + "P11": 11, + "P14": 14, + "P15": 15, + "P16": 16, + "P17": 17, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "P28": 28, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM3": 9, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCK": 14, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 0, + "D1": 1, + "D2": 6, + "D3": 7, + "D4": 8, + "D5": 9, + "D6": 10, + "D7": 11, + "D8": 14, + "D9": 15, + "D10": 16, + "D11": 17, + "D12": 20, + "D13": 21, + "D14": 22, + "D15": 23, + "D16": 24, + "D17": 26, + "D18": 28, + "A0": 23, + }, + "generic-bk7231n-qfn32-tuya": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "CS": 15, + "MISO": 17, + "MOSI": 16, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P9": 9, + "P10": 10, + "P11": 11, + "P14": 14, + "P15": 15, + "P16": 16, + "P17": 17, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "P28": 28, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM3": 9, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCK": 14, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 0, + "D1": 1, + "D2": 6, + "D3": 7, + "D4": 8, + "D5": 9, + "D6": 10, + "D7": 11, + "D8": 14, + "D9": 15, + "D10": 16, + "D11": 17, + "D12": 20, + "D13": 21, + "D14": 22, + "D15": 23, + "D16": 24, + "D17": 26, + "D18": 28, + "A0": 23, + }, "cb1s": { "WIRE1_SCL": 20, "WIRE1_SDA": 21, @@ -183,28 +449,22 @@ BK72XX_BOARD_PINS = { "D7": 11, "D8": 21, }, - "cb2s": { + "cblc5": { "WIRE2_SCL": 0, "WIRE2_SDA": 1, "SERIAL1_RX": 10, "SERIAL1_TX": 11, "SERIAL2_RX": 1, "SERIAL2_TX": 0, - "ADC3": 23, "P0": 0, "P1": 1, "P6": 6, - "P7": 7, - "P8": 8, "P10": 10, "P11": 11, "P21": 21, - "P23": 23, "P24": 24, "P26": 26, "PWM0": 6, - "PWM1": 7, - "PWM2": 8, "PWM4": 24, "PWM5": 26, "RX1": 10, @@ -214,61 +474,14 @@ BK72XX_BOARD_PINS = { "SDA2": 1, "TX1": 11, "TX2": 0, - "D0": 6, - "D1": 7, - "D2": 8, - "D3": 23, - "D4": 10, - "D5": 11, - "D6": 24, - "D7": 26, - "D8": 0, - "D9": 1, - "D10": 21, - "A0": 23, - }, - "cb3l": { - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P6": 6, - "P7": 7, - "P8": 8, - "P9": 9, - "P10": 10, - "P11": 11, - "P14": 14, - "P21": 21, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM3": 9, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "SCK": 14, - "SCL2": 0, - "SDA1": 21, - "TX1": 11, - "TX2": 0, - "D0": 23, - "D1": 14, + "D0": 24, + "D1": 6, "D2": 26, - "D3": 24, - "D4": 6, - "D5": 9, + "D3": 11, + "D4": 10, + "D5": 1, "D6": 0, "D7": 21, - "D8": 8, - "D9": 7, - "D10": 10, - "D11": 11, - "A0": 23, }, "cb3s": { "WIRE1_SCL": 20, @@ -321,7 +534,9 @@ BK72XX_BOARD_PINS = { "D13": 20, "A0": 23, }, - "cb3se": { + "wb3s": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, "WIRE2_SCL": 0, "WIRE2_SDA": 1, "SERIAL1_RX": 10, @@ -329,9 +544,6 @@ BK72XX_BOARD_PINS = { "SERIAL2_RX": 1, "SERIAL2_TX": 0, "ADC3": 23, - "CS": 15, - "MISO": 17, - "MOSI": 16, "P0": 0, "P1": 1, "P6": 6, @@ -341,10 +553,8 @@ BK72XX_BOARD_PINS = { "P10": 10, "P11": 11, "P14": 14, - "P15": 15, - "P16": 16, - "P17": 17, "P20": 20, + "P21": 21, "P22": 22, "P23": 23, "P24": 24, @@ -360,6 +570,7 @@ BK72XX_BOARD_PINS = { "SCK": 14, "SCL1": 20, "SCL2": 0, + "SDA1": 21, "SDA2": 1, "TX1": 11, "TX2": 0, @@ -368,57 +579,19 @@ BK72XX_BOARD_PINS = { "D2": 26, "D3": 24, "D4": 6, - "D5": 9, + "D5": 7, "D6": 0, "D7": 1, - "D8": 8, - "D9": 7, + "D8": 9, + "D9": 8, "D10": 10, "D11": 11, - "D12": 15, - "D13": 22, + "D12": 22, + "D13": 21, "D14": 20, - "D15": 17, - "D16": 16, "A0": 23, }, - "cblc5": { - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "P0": 0, - "P1": 1, - "P6": 6, - "P10": 10, - "P11": 11, - "P21": 21, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 24, - "D1": 6, - "D2": 26, - "D3": 11, - "D4": 10, - "D5": 1, - "D6": 0, - "D7": 21, - }, - "cbu": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, + "lsc-lma35": { "WIRE2_SCL": 0, "WIRE2_SDA": 1, "SERIAL1_RX": 10, @@ -426,8 +599,6 @@ BK72XX_BOARD_PINS = { "SERIAL2_RX": 1, "SERIAL2_TX": 0, "ADC3": 23, - "CS": 15, - "MISO": 17, "MOSI": 16, "P0": 0, "P1": 1, @@ -438,16 +609,12 @@ BK72XX_BOARD_PINS = { "P10": 10, "P11": 11, "P14": 14, - "P15": 15, "P16": 16, - "P17": 17, - "P20": 20, "P21": 21, "P22": 22, "P23": 23, "P24": 24, "P26": 26, - "P28": 28, "PWM0": 6, "PWM1": 7, "PWM2": 8, @@ -457,167 +624,26 @@ BK72XX_BOARD_PINS = { "RX1": 10, "RX2": 1, "SCK": 14, - "SCL1": 20, "SCL2": 0, "SDA1": 21, "SDA2": 1, "TX1": 11, "TX2": 0, - "D0": 14, - "D1": 16, - "D2": 20, - "D3": 22, - "D4": 23, - "D5": 1, - "D6": 0, + "D0": 26, + "D1": 14, + "D2": 16, + "D3": 24, + "D4": 22, + "D5": 0, + "D6": 23, "D7": 8, - "D8": 7, - "D9": 6, - "D10": 26, - "D11": 24, - "D12": 11, - "D13": 10, - "D14": 28, - "D15": 9, - "D16": 17, - "D17": 15, - "D18": 21, - "A0": 23, - }, - "generic-bk7231n-qfn32-tuya": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "CS": 15, - "MISO": 17, - "MOSI": 16, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P9": 9, - "P10": 10, - "P11": 11, - "P14": 14, - "P15": 15, - "P16": 16, - "P17": 17, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "P28": 28, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM3": 9, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCK": 14, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 0, - "D1": 1, - "D2": 6, - "D3": 7, - "D4": 8, - "D5": 9, - "D6": 10, - "D7": 11, - "D8": 14, - "D9": 15, - "D10": 16, - "D11": 17, - "D12": 20, - "D13": 21, - "D14": 22, - "D15": 23, - "D16": 24, - "D17": 26, - "D18": 28, - "A0": 23, - }, - "generic-bk7231t-qfn32-tuya": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "CS": 15, - "MISO": 17, - "MOSI": 16, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P9": 9, - "P10": 10, - "P11": 11, - "P14": 14, - "P15": 15, - "P16": 16, - "P17": 17, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "P28": 28, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM3": 9, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCK": 14, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 0, - "D1": 1, - "D2": 6, - "D3": 7, - "D4": 8, - "D5": 9, - "D6": 10, - "D7": 11, - "D8": 14, - "D9": 15, - "D10": 16, - "D11": 17, - "D12": 20, - "D13": 21, - "D14": 22, - "D15": 23, - "D16": 24, - "D17": 26, - "D18": 28, + "D8": 9, + "D9": 21, + "D10": 6, + "D11": 7, + "D12": 10, + "D13": 11, + "D14": 1, "A0": 23, }, "generic-bk7252": { @@ -740,6 +766,280 @@ BK72XX_BOARD_PINS = { "A6": 12, "A7": 13, }, + "wb2l": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P10": 10, + "P11": 11, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 8, + "D1": 7, + "D2": 6, + "D3": 26, + "D4": 24, + "D5": 10, + "D6": 11, + "D7": 1, + "D8": 0, + "D9": 20, + "D10": 21, + "D11": 23, + "D12": 22, + "A0": 23, + }, + "wb1s": { + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P9": 9, + "P10": 10, + "P11": 11, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM3": 9, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCL2": 0, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 11, + "D1": 10, + "D2": 26, + "D3": 24, + "D4": 0, + "D5": 8, + "D6": 7, + "D7": 1, + "D8": 9, + "D9": 6, + "D10": 23, + "A0": 23, + }, + "wblc5": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P1": 1, + "P6": 6, + "P10": 10, + "P11": 11, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 24, + "D1": 6, + "D2": 26, + "D3": 10, + "D4": 11, + "D5": 1, + "D6": 0, + "D7": 20, + "D8": 21, + "D9": 22, + "D10": 23, + "A0": 23, + }, + "cb2s": { + "WIRE2_SCL": 0, + "WIRE2_SDA": 1, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_RX": 1, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P1": 1, + "P6": 6, + "P7": 7, + "P8": 8, + "P10": 10, + "P11": 11, + "P21": 21, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "RX2": 1, + "SCL2": 0, + "SDA1": 21, + "SDA2": 1, + "TX1": 11, + "TX2": 0, + "D0": 6, + "D1": 7, + "D2": 8, + "D3": 23, + "D4": 10, + "D5": 11, + "D6": 24, + "D7": 26, + "D8": 0, + "D9": 1, + "D10": 21, + "A0": 23, + }, + "wa2": { + "WIRE1_SCL": 20, + "WIRE1_SDA": 21, + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_TX": 0, + "ADC1": 4, + "ADC3": 23, + "P0": 0, + "P4": 4, + "P6": 6, + "P7": 7, + "P8": 8, + "P10": 10, + "P11": 11, + "P18": 18, + "P19": 19, + "P20": 20, + "P21": 21, + "P22": 22, + "P23": 23, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM4": 18, + "PWM5": 19, + "RX1": 10, + "SCL1": 20, + "SCL2": 0, + "SDA1": 21, + "TX1": 11, + "TX2": 0, + "D0": 8, + "D1": 7, + "D2": 6, + "D3": 23, + "D4": 10, + "D5": 11, + "D6": 18, + "D7": 19, + "D8": 20, + "D9": 4, + "D10": 0, + "D11": 21, + "D12": 22, + "A0": 23, + }, + "cb3l": { + "SERIAL1_RX": 10, + "SERIAL1_TX": 11, + "SERIAL2_TX": 0, + "ADC3": 23, + "P0": 0, + "P6": 6, + "P7": 7, + "P8": 8, + "P9": 9, + "P10": 10, + "P11": 11, + "P14": 14, + "P21": 21, + "P23": 23, + "P24": 24, + "P26": 26, + "PWM0": 6, + "PWM1": 7, + "PWM2": 8, + "PWM3": 9, + "PWM4": 24, + "PWM5": 26, + "RX1": 10, + "SCK": 14, + "SCL2": 0, + "SDA1": 21, + "TX1": 11, + "TX2": 0, + "D0": 23, + "D1": 14, + "D2": 26, + "D3": 24, + "D4": 6, + "D5": 9, + "D6": 0, + "D7": 21, + "D8": 8, + "D9": 7, + "D10": 10, + "D11": 11, + "A0": 23, + }, "lsc-lma35-t": { "WIRE2_SCL": 0, "WIRE2_SDA": 1, @@ -795,7 +1095,7 @@ BK72XX_BOARD_PINS = { "D14": 1, "A0": 23, }, - "lsc-lma35": { + "cb3se": { "WIRE2_SCL": 0, "WIRE2_SDA": 1, "SERIAL1_RX": 10, @@ -803,6 +1103,8 @@ BK72XX_BOARD_PINS = { "SERIAL2_RX": 1, "SERIAL2_TX": 0, "ADC3": 23, + "CS": 15, + "MISO": 17, "MOSI": 16, "P0": 0, "P1": 1, @@ -813,8 +1115,10 @@ BK72XX_BOARD_PINS = { "P10": 10, "P11": 11, "P14": 14, + "P15": 15, "P16": 16, - "P21": 21, + "P17": 17, + "P20": 20, "P22": 22, "P23": 23, "P24": 24, @@ -828,273 +1132,28 @@ BK72XX_BOARD_PINS = { "RX1": 10, "RX2": 1, "SCK": 14, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 26, - "D1": 14, - "D2": 16, - "D3": 24, - "D4": 22, - "D5": 0, - "D6": 23, - "D7": 8, - "D8": 9, - "D9": 21, - "D10": 6, - "D11": 7, - "D12": 10, - "D13": 11, - "D14": 1, - "A0": 23, - }, - "wa2": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_TX": 0, - "ADC1": 4, - "ADC3": 23, - "P0": 0, - "P4": 4, - "P6": 6, - "P7": 7, - "P8": 8, - "P10": 10, - "P11": 11, - "P18": 18, - "P19": 19, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM4": 18, - "PWM5": 19, - "RX1": 10, "SCL1": 20, "SCL2": 0, - "SDA1": 21, - "TX1": 11, - "TX2": 0, - "D0": 8, - "D1": 7, - "D2": 6, - "D3": 23, - "D4": 10, - "D5": 11, - "D6": 18, - "D7": 19, - "D8": 20, - "D9": 4, - "D10": 0, - "D11": 21, - "D12": 22, - "A0": 23, - }, - "wb1s": { - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P9": 9, - "P10": 10, - "P11": 11, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM3": 9, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL2": 0, "SDA2": 1, "TX1": 11, "TX2": 0, - "D0": 11, - "D1": 10, + "D0": 23, + "D1": 14, "D2": 26, "D3": 24, - "D4": 0, - "D5": 8, - "D6": 7, + "D4": 6, + "D5": 9, + "D6": 0, "D7": 1, - "D8": 9, - "D9": 6, - "D10": 23, - "A0": 23, - }, - "wb2l-m1": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P10": 10, - "P11": 11, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 8, - "D1": 7, - "D2": 6, - "D3": 26, - "D4": 24, - "D5": 10, - "D6": 11, - "D7": 1, - "D8": 0, - "D9": 20, - "D10": 21, - "D11": 23, - "D12": 22, - "A0": 23, - }, - "wb2l": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P10": 10, - "P11": 11, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 8, - "D1": 7, - "D2": 6, - "D3": 26, - "D4": 24, - "D5": 10, - "D6": 11, - "D7": 1, - "D8": 0, - "D9": 20, - "D10": 21, - "D11": 23, - "D12": 22, - "A0": 23, - }, - "wb2s": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P1": 1, - "P6": 6, - "P7": 7, - "P8": 8, - "P9": 9, - "P10": 10, - "P11": 11, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM1": 7, - "PWM2": 8, - "PWM3": 9, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 8, - "D1": 7, - "D2": 6, - "D3": 23, - "D4": 10, - "D5": 11, - "D6": 24, - "D7": 26, - "D8": 20, - "D9": 9, - "D10": 1, - "D11": 0, - "D12": 21, + "D8": 8, + "D9": 7, + "D10": 10, + "D11": 11, + "D12": 15, "D13": 22, + "D14": 20, + "D15": 17, + "D16": 16, "A0": 23, }, "wb3l": { @@ -1157,7 +1216,7 @@ BK72XX_BOARD_PINS = { "D15": 1, "A0": 23, }, - "wb3s": { + "wb2s": { "WIRE1_SCL": 20, "WIRE1_SDA": 21, "WIRE2_SCL": 0, @@ -1175,7 +1234,6 @@ BK72XX_BOARD_PINS = { "P9": 9, "P10": 10, "P11": 11, - "P14": 14, "P20": 20, "P21": 21, "P22": 22, @@ -1190,73 +1248,26 @@ BK72XX_BOARD_PINS = { "PWM5": 26, "RX1": 10, "RX2": 1, - "SCK": 14, "SCL1": 20, "SCL2": 0, "SDA1": 21, "SDA2": 1, "TX1": 11, "TX2": 0, - "D0": 23, - "D1": 14, - "D2": 26, - "D3": 24, - "D4": 6, - "D5": 7, - "D6": 0, - "D7": 1, - "D8": 9, - "D9": 8, - "D10": 10, - "D11": 11, - "D12": 22, - "D13": 21, - "D14": 20, - "A0": 23, - }, - "wblc5": { - "WIRE1_SCL": 20, - "WIRE1_SDA": 21, - "WIRE2_SCL": 0, - "WIRE2_SDA": 1, - "SERIAL1_RX": 10, - "SERIAL1_TX": 11, - "SERIAL2_RX": 1, - "SERIAL2_TX": 0, - "ADC3": 23, - "P0": 0, - "P1": 1, - "P6": 6, - "P10": 10, - "P11": 11, - "P20": 20, - "P21": 21, - "P22": 22, - "P23": 23, - "P24": 24, - "P26": 26, - "PWM0": 6, - "PWM4": 24, - "PWM5": 26, - "RX1": 10, - "RX2": 1, - "SCL1": 20, - "SCL2": 0, - "SDA1": 21, - "SDA2": 1, - "TX1": 11, - "TX2": 0, - "D0": 24, - "D1": 6, - "D2": 26, - "D3": 10, - "D4": 11, - "D5": 1, - "D6": 0, - "D7": 20, - "D8": 21, - "D9": 22, - "D10": 23, + "D0": 8, + "D1": 7, + "D2": 6, + "D3": 23, + "D4": 10, + "D5": 11, + "D6": 24, + "D7": 26, + "D8": 20, + "D9": 9, + "D10": 1, + "D11": 0, + "D12": 21, + "D13": 22, "A0": 23, }, } diff --git a/esphome/components/epaper_spi/display.py b/esphome/components/epaper_spi/display.py index b7e71a3cae..a77e291237 100644 --- a/esphome/components/epaper_spi/display.py +++ b/esphome/components/epaper_spi/display.py @@ -184,6 +184,7 @@ async def to_code(config): height, init_sequence_id, init_sequence_length, + *model.get_constructor_args(config), ) # Rotation is handled by setting the transform diff --git a/esphome/components/epaper_spi/epaper_spi.cpp b/esphome/components/epaper_spi/epaper_spi.cpp index 0b600feeae..db803305a5 100644 --- a/esphome/components/epaper_spi/epaper_spi.cpp +++ b/esphome/components/epaper_spi/epaper_spi.cpp @@ -54,20 +54,14 @@ void EPaperBase::setup_pins_() const { float EPaperBase::get_setup_priority() const { return setup_priority::PROCESSOR; } void EPaperBase::command(uint8_t value) { - this->start_command_(); + ESP_LOGV(TAG, "Command: 0x%02X", value); + this->dc_pin_->digital_write(false); + this->enable(); this->write_byte(value); - this->end_command_(); -} - -void EPaperBase::data(uint8_t value) { - this->start_data_(); - this->write_byte(value); - this->end_data_(); + this->disable(); } // write a command followed by zero or more bytes of data. -// The command is the first byte, length is the length of data only in the second byte, followed by the data. -// [COMMAND, LENGTH, DATA...] void EPaperBase::cmd_data(uint8_t command, const uint8_t *ptr, size_t length) { #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE char hex_buf[format_hex_pretty_size(EPAPER_MAX_CMD_LOG_BYTES)]; @@ -130,14 +124,10 @@ void EPaperBase::wait_for_idle_(bool should_wait) { void EPaperBase::loop() { auto now = millis(); - if (this->delay_until_ != 0) { - // using modulus arithmetic to handle wrap-around - int diff = now - this->delay_until_; - if (diff < 0) { - return; - } - this->delay_until_ = 0; - } + // using modulus arithmetic to handle wrap-around + int diff = now - this->delay_until_; + if (diff < 0) + return; if (this->waiting_for_idle_) { if (this->is_idle_()) { this->waiting_for_idle_ = false; @@ -192,7 +182,7 @@ void EPaperBase::process_state_() { this->set_state_(EPaperState::RESET); break; case EPaperState::INITIALISE: - this->initialise_(); + this->initialise(this->update_count_ != 0); this->set_state_(EPaperState::TRANSFER_DATA); break; case EPaperState::TRANSFER_DATA: @@ -230,11 +220,11 @@ void EPaperBase::set_state_(EPaperState state, uint16_t delay) { ESP_LOGV(TAG, "Exit state %s", this->epaper_state_to_string_()); this->state_ = state; this->wait_for_idle_(state > EPaperState::SHOULD_WAIT); - if (delay != 0) { - this->delay_until_ = millis() + delay; - } else { - this->delay_until_ = 0; - } + // allow subclasses to nominate delays + if (delay == 0) + delay = this->next_delay_; + this->next_delay_ = 0; + this->delay_until_ = millis() + delay; ESP_LOGV(TAG, "Enter state %s, delay %u, wait_for_idle=%s", this->epaper_state_to_string_(), delay, TRUEFALSE(this->waiting_for_idle_)); if (state == EPaperState::IDLE) { @@ -242,22 +232,14 @@ void EPaperBase::set_state_(EPaperState state, uint16_t delay) { } } -void EPaperBase::start_command_() { - this->dc_pin_->digital_write(false); - this->enable(); -} - -void EPaperBase::end_command_() { this->disable(); } - void EPaperBase::start_data_() { this->dc_pin_->digital_write(true); this->enable(); } -void EPaperBase::end_data_() { this->disable(); } void EPaperBase::on_safe_shutdown() { this->deep_sleep(); } -void EPaperBase::initialise_() { +void EPaperBase::initialise(bool partial) { size_t index = 0; auto *sequence = this->init_sequence_; @@ -317,9 +299,8 @@ bool EPaperBase::rotate_coordinates_(int &x, int &y) { void HOT EPaperBase::draw_pixel_at(int x, int y, Color color) { if (!rotate_coordinates_(x, y)) return; - const size_t pixel_position = y * this->width_ + x; - const size_t byte_position = pixel_position / 8; - const uint8_t bit_position = pixel_position % 8; + const size_t byte_position = y * this->row_width_ + x / 8; + const uint8_t bit_position = x % 8; const uint8_t pixel_bit = 0x80 >> bit_position; const auto original = this->buffer_[byte_position]; if ((color_to_bit(color) == 0)) { diff --git a/esphome/components/epaper_spi/epaper_spi.h b/esphome/components/epaper_spi/epaper_spi.h index b587b07e8f..521543f026 100644 --- a/esphome/components/epaper_spi/epaper_spi.h +++ b/esphome/components/epaper_spi/epaper_spi.h @@ -36,14 +36,16 @@ class EPaperBase : public Display, public spi::SPIDevice { public: - EPaperBase(const char *name, uint16_t width, uint16_t height, const uint8_t *init_sequence, - size_t init_sequence_length, DisplayType display_type = DISPLAY_TYPE_BINARY) + EPaperBase(const char *name, uint16_t width, uint16_t height, const uint8_t *init_sequence = nullptr, + size_t init_sequence_length = 0, DisplayType display_type = DISPLAY_TYPE_BINARY) : name_(name), width_(width), height_(height), init_sequence_(init_sequence), init_sequence_length_(init_sequence_length), - display_type_(display_type) {} + display_type_(display_type) { + this->row_width_ = (this->width_ + 7) / 8; // width of a row in bytes + } void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; } float get_setup_priority() const override; void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; } @@ -54,9 +56,13 @@ class EPaperBase : public Display, void dump_config() override; void command(uint8_t value); - void data(uint8_t value); void cmd_data(uint8_t command, const uint8_t *ptr, size_t length); + // variant with in-place initializer list + void cmd_data(uint8_t command, std::initializer_list data) { + this->cmd_data(command, data.begin(), data.size()); + } + void update() override; void loop() override; @@ -109,7 +115,7 @@ class EPaperBase : public Display, bool is_idle_() const; void setup_pins_() const; virtual bool reset(); - void initialise_(); + virtual void initialise(bool partial); void wait_for_idle_(bool should_wait); bool init_buffer_(size_t buffer_length); bool rotate_coordinates_(int &x, int &y); @@ -143,14 +149,12 @@ class EPaperBase : public Display, void set_state_(EPaperState state, uint16_t delay = 0); - void start_command_(); - void end_command_(); void start_data_(); - void end_data_(); // properties initialised in the constructor const char *name_; uint16_t width_; + uint16_t row_width_; // width of a row in bytes uint16_t height_; const uint8_t *init_sequence_; size_t init_sequence_length_; @@ -163,7 +167,8 @@ class EPaperBase : public Display, GPIOPin *busy_pin_{}; GPIOPin *reset_pin_{}; bool waiting_for_idle_{}; - uint32_t delay_until_{}; + uint32_t delay_until_{}; // timestamp until which to delay processing + uint16_t next_delay_{}; // milliseconds to delay before next state uint8_t transform_{}; uint8_t update_count_{}; // these values represent the bounds of the updated buffer. Note that x_high and y_high diff --git a/esphome/components/epaper_spi/epaper_spi_ssd1677.cpp b/esphome/components/epaper_spi/epaper_spi_mono.cpp similarity index 53% rename from esphome/components/epaper_spi/epaper_spi_ssd1677.cpp rename to esphome/components/epaper_spi/epaper_spi_mono.cpp index e4f04657ad..d10022c4ac 100644 --- a/esphome/components/epaper_spi/epaper_spi_ssd1677.cpp +++ b/esphome/components/epaper_spi/epaper_spi_mono.cpp @@ -1,25 +1,24 @@ -#include "epaper_spi_ssd1677.h" +#include "epaper_spi_mono.h" #include #include "esphome/core/log.h" namespace esphome::epaper_spi { -static constexpr const char *const TAG = "epaper_spi.ssd1677"; +static constexpr const char *const TAG = "epaper_spi.mono"; -void EPaperSSD1677::refresh_screen(bool partial) { +void EPaperMono::refresh_screen(bool partial) { ESP_LOGV(TAG, "Refresh screen"); - this->command(0x22); - this->data(partial ? 0xFF : 0xF7); + this->cmd_data(0x22, {partial ? (uint8_t) 0xFF : (uint8_t) 0xF7}); this->command(0x20); } -void EPaperSSD1677::deep_sleep() { +void EPaperMono::deep_sleep() { ESP_LOGV(TAG, "Deep sleep"); this->command(0x10); } -bool EPaperSSD1677::reset() { +bool EPaperMono::reset() { if (EPaperBase::reset()) { this->command(0x12); return true; @@ -27,29 +26,24 @@ bool EPaperSSD1677::reset() { return false; } -bool HOT EPaperSSD1677::transfer_data() { +void EPaperMono::set_window() { + // round x-coordinates to byte boundaries + this->x_low_ &= ~7; + this->x_high_ += 7; + this->x_high_ &= ~7; + this->cmd_data(0x44, {(uint8_t) this->x_low_, (uint8_t) (this->x_low_ / 256), (uint8_t) (this->x_high_ - 1), + (uint8_t) ((this->x_high_ - 1) / 256)}); + this->cmd_data(0x4E, {(uint8_t) this->x_low_, (uint8_t) (this->x_low_ / 256)}); + this->cmd_data(0x45, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256), (uint8_t) (this->y_high_ - 1), + (uint8_t) ((this->y_high_ - 1) / 256)}); + this->cmd_data(0x4F, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256)}); +} + +bool HOT EPaperMono::transfer_data() { auto start_time = millis(); if (this->current_data_index_ == 0) { - uint8_t data[4]{}; // round to byte boundaries - this->x_low_ &= ~7; - this->y_low_ &= ~7; - this->x_high_ += 7; - this->x_high_ &= ~7; - this->y_high_ += 7; - this->y_high_ &= ~7; - data[0] = this->x_low_; - data[1] = this->x_low_ / 256; - data[2] = this->x_high_ - 1; - data[3] = (this->x_high_ - 1) / 256; - cmd_data(0x4E, data, 2); - cmd_data(0x44, data, sizeof(data)); - data[0] = this->y_low_; - data[1] = this->y_low_ / 256; - data[2] = this->y_high_ - 1; - data[3] = (this->y_high_ - 1) / 256; - cmd_data(0x4F, data, 2); - this->cmd_data(0x45, data, sizeof(data)); + this->set_window(); // for monochrome, we still need to clear the red data buffer at least once to prevent it // causing dirty pixels after partial refresh. this->command(this->send_red_ ? 0x26 : 0x24); @@ -58,10 +52,10 @@ bool HOT EPaperSSD1677::transfer_data() { size_t row_length = (this->x_high_ - this->x_low_) / 8; FixedVector bytes_to_send{}; bytes_to_send.init(row_length); - ESP_LOGV(TAG, "Writing bytes at line %zu at %ums", this->current_data_index_, (unsigned) millis()); + ESP_LOGV(TAG, "Writing %u bytes at line %zu at %ums", row_length, this->current_data_index_, (unsigned) millis()); this->start_data_(); while (this->current_data_index_ != this->y_high_) { - size_t data_idx = (this->current_data_index_ * this->width_ + this->x_low_) / 8; + size_t data_idx = this->current_data_index_ * this->row_width_ + this->x_low_ / 8; for (size_t i = 0; i != row_length; i++) { bytes_to_send[i] = this->send_red_ ? 0 : this->buffer_[data_idx++]; } @@ -69,12 +63,12 @@ bool HOT EPaperSSD1677::transfer_data() { this->write_array(&bytes_to_send.front(), row_length); // NOLINT if (millis() - start_time > MAX_TRANSFER_TIME) { // Let the main loop run and come back next loop - this->end_data_(); + this->disable(); return false; } } - this->end_data_(); + this->disable(); this->current_data_index_ = 0; if (this->send_red_) { this->send_red_ = false; diff --git a/esphome/components/epaper_spi/epaper_spi_ssd1677.h b/esphome/components/epaper_spi/epaper_spi_mono.h similarity index 57% rename from esphome/components/epaper_spi/epaper_spi_ssd1677.h rename to esphome/components/epaper_spi/epaper_spi_mono.h index 47584d24c0..f44b59e803 100644 --- a/esphome/components/epaper_spi/epaper_spi_ssd1677.h +++ b/esphome/components/epaper_spi/epaper_spi_mono.h @@ -3,13 +3,15 @@ #include "epaper_spi.h" namespace esphome::epaper_spi { - -class EPaperSSD1677 : public EPaperBase { +/** + * A class for monochrome epaper displays. + */ +class EPaperMono : public EPaperBase { public: - EPaperSSD1677(const char *name, uint16_t width, uint16_t height, const uint8_t *init_sequence, - size_t init_sequence_length) + EPaperMono(const char *name, uint16_t width, uint16_t height, const uint8_t *init_sequence, + size_t init_sequence_length) : EPaperBase(name, width, height, init_sequence, init_sequence_length, DISPLAY_TYPE_BINARY) { - this->buffer_length_ = width * height / 8; // 8 pixels per byte + this->buffer_length_ = (width + 7) / 8 * height; // 8 pixels per byte, rounded up } protected: @@ -18,6 +20,7 @@ class EPaperSSD1677 : public EPaperBase { void power_off() override{}; void deep_sleep() override; bool reset() override; + virtual void set_window(); bool transfer_data() override; bool send_red_{true}; }; diff --git a/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp b/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp index be243145fc..1ef2dd12c3 100644 --- a/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +++ b/esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp @@ -80,20 +80,17 @@ void EPaperSpectraE6::power_on() { void EPaperSpectraE6::power_off() { ESP_LOGV(TAG, "Power off"); - this->command(0x02); - this->data(0x00); + this->cmd_data(0x02, {0x00}); } void EPaperSpectraE6::refresh_screen(bool partial) { ESP_LOGV(TAG, "Refresh"); - this->command(0x12); - this->data(0x00); + this->cmd_data(0x12, {0x00}); } void EPaperSpectraE6::deep_sleep() { ESP_LOGV(TAG, "Deep sleep"); - this->command(0x07); - this->data(0xA5); + this->cmd_data(0x07, {0xA5}); } void EPaperSpectraE6::fill(Color color) { @@ -143,7 +140,7 @@ bool HOT EPaperSpectraE6::transfer_data() { if (buf_idx == sizeof bytes_to_send) { this->start_data_(); this->write_array(bytes_to_send, buf_idx); - this->end_data_(); + this->disable(); ESP_LOGV(TAG, "Wrote %d bytes at %ums", buf_idx, (unsigned) millis()); buf_idx = 0; @@ -157,7 +154,7 @@ bool HOT EPaperSpectraE6::transfer_data() { if (buf_idx != 0) { this->start_data_(); this->write_array(bytes_to_send, buf_idx); - this->end_data_(); + this->disable(); } this->current_data_index_ = 0; return true; diff --git a/esphome/components/epaper_spi/epaper_waveshare.cpp b/esphome/components/epaper_spi/epaper_waveshare.cpp new file mode 100644 index 0000000000..8d382d86e7 --- /dev/null +++ b/esphome/components/epaper_spi/epaper_waveshare.cpp @@ -0,0 +1,47 @@ +#include "epaper_waveshare.h" + +namespace esphome::epaper_spi { + +static const char *const TAG = "epaper_spi.waveshare"; + +void EpaperWaveshare::initialise(bool partial) { + EPaperBase::initialise(partial); + if (partial) { + this->cmd_data(0x32, this->partial_lut_, this->partial_lut_length_); + this->cmd_data(0x3C, {0x80}); + this->cmd_data(0x22, {0xC0}); + this->command(0x20); + this->next_delay_ = 100; + } else { + this->cmd_data(0x32, this->lut_, this->lut_length_); + this->cmd_data(0x3C, {0x05}); + } + this->send_red_ = true; +} + +void EpaperWaveshare::set_window() { + this->x_low_ &= ~7; + this->x_high_ += 7; + this->x_high_ &= ~7; + uint16_t x_start = this->x_low_ / 8; + uint16_t x_end = (this->x_high_ - 1) / 8; + this->cmd_data(0x44, {(uint8_t) x_start, (uint8_t) (x_end)}); + this->cmd_data(0x4E, {(uint8_t) x_start}); + this->cmd_data(0x45, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256), (uint8_t) (this->y_high_ - 1), + (uint8_t) ((this->y_high_ - 1) / 256)}); + this->cmd_data(0x4F, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256)}); + ESP_LOGV(TAG, "Set window X: %u-%u, Y: %u-%u", this->x_low_, this->x_high_, this->y_low_, this->y_high_); +} + +void EpaperWaveshare::refresh_screen(bool partial) { + if (partial) { + this->cmd_data(0x22, {0x0F}); + } else { + this->cmd_data(0x22, {0xC7}); + } + this->command(0x20); + this->next_delay_ = partial ? 100 : 3000; +} + +void EpaperWaveshare::deep_sleep() { this->cmd_data(0x10, {0x01}); } +} // namespace esphome::epaper_spi diff --git a/esphome/components/epaper_spi/epaper_waveshare.h b/esphome/components/epaper_spi/epaper_waveshare.h new file mode 100644 index 0000000000..6b894cfd09 --- /dev/null +++ b/esphome/components/epaper_spi/epaper_waveshare.h @@ -0,0 +1,30 @@ +#pragma once +#include "epaper_spi.h" +#include "epaper_spi_mono.h" + +namespace esphome::epaper_spi { +/** + * An epaper display that needs LUTs to be sent to it. + */ +class EpaperWaveshare : public EPaperMono { + public: + EpaperWaveshare(const char *name, uint16_t width, uint16_t height, const uint8_t *init_sequence, + size_t init_sequence_length, const uint8_t *lut, size_t lut_length, const uint8_t *partial_lut, + uint16_t partial_lut_length) + : EPaperMono(name, width, height, init_sequence, init_sequence_length), + lut_(lut), + lut_length_(lut_length), + partial_lut_(partial_lut), + partial_lut_length_(partial_lut_length) {} + + protected: + void initialise(bool partial) override; + void set_window() override; + void refresh_screen(bool partial) override; + void deep_sleep() override; + const uint8_t *lut_; + size_t lut_length_; + const uint8_t *partial_lut_; + uint16_t partial_lut_length_; +}; +} // namespace esphome::epaper_spi diff --git a/esphome/components/epaper_spi/models/__init__.py b/esphome/components/epaper_spi/models/__init__.py index 019eb31d18..3fcf3217ec 100644 --- a/esphome/components/epaper_spi/models/__init__.py +++ b/esphome/components/epaper_spi/models/__init__.py @@ -32,6 +32,9 @@ class EpaperModel: return cv.Required(name) return cv.Optional(name, default=self.get_default(name, fallback)) + def get_constructor_args(self, config) -> tuple: + return () + def get_dimensions(self, config) -> tuple[int, int]: if CONF_DIMENSIONS in config: # Explicit dimensions, just use as is diff --git a/esphome/components/epaper_spi/models/ssd1677.py b/esphome/components/epaper_spi/models/ssd1677.py index 3eb53d650e..f7e012f162 100644 --- a/esphome/components/epaper_spi/models/ssd1677.py +++ b/esphome/components/epaper_spi/models/ssd1677.py @@ -4,10 +4,9 @@ from . import EpaperModel class SSD1677(EpaperModel): - def __init__(self, name, class_name="EPaperSSD1677", **kwargs): - if CONF_DATA_RATE not in kwargs: - kwargs[CONF_DATA_RATE] = "20MHz" - super().__init__(name, class_name, **kwargs) + def __init__(self, name, class_name="EPaperMono", data_rate="20MHz", **defaults): + defaults[CONF_DATA_RATE] = data_rate + super().__init__(name, class_name, **defaults) # fmt: off def get_init_sequence(self, config: dict): @@ -23,11 +22,15 @@ class SSD1677(EpaperModel): ssd1677 = SSD1677("ssd1677") -ssd1677.extend( - "seeed-ee04-mono-4.26", +wave_4_26 = ssd1677.extend( + "waveshare-4.26in", width=800, height=480, mirror_x=True, +) + +wave_4_26.extend( + "seeed-ee04-mono-4.26", cs_pin=44, dc_pin=10, reset_pin=38, diff --git a/esphome/components/epaper_spi/models/waveshare.py b/esphome/components/epaper_spi/models/waveshare.py new file mode 100644 index 0000000000..74a288977d --- /dev/null +++ b/esphome/components/epaper_spi/models/waveshare.py @@ -0,0 +1,88 @@ +import esphome.codegen as cg +from esphome.core import ID + +from ..display import CONF_INIT_SEQUENCE_ID +from . import EpaperModel + + +class WaveshareModel(EpaperModel): + def __init__(self, name, lut, lut_partial=None, **defaults): + super().__init__(name, "EpaperWaveshare", **defaults) + self.lut = lut + self.lut_partial = lut_partial + + def get_constructor_args(self, config) -> tuple: + lut = ( + cg.static_const_array( + ID(config[CONF_INIT_SEQUENCE_ID].id + "_lut", type=cg.uint8), self.lut + ), + len(self.lut), + ) + if self.lut_partial is None: + lut_partial = cg.nullptr, 0 + else: + lut_partial = ( + cg.static_const_array( + ID( + config[CONF_INIT_SEQUENCE_ID].id + "_lut_partial", type=cg.uint8 + ), + self.lut_partial, + ), + len(self.lut_partial), + ) + return *lut, *lut_partial + + +# fmt: off +WaveshareModel( + "waveshare-2.13in-v3", + width=122, + height=250, + initsequence=( + (0x01, 0x27, 0x01, 0x00), # driver output control + (0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00), + (0x11, 0x03), # Data entry mode + (0x3F, 0x22), # Undocumented command + (0x2C, 0x36), # write VCOM register + (0x04, 0x41, 0x0C, 0x32), # SRC voltage + (0x03, 0x17), # Gate voltage + (0x21, 0x00, 0x80), # Display update control + (0x18, 0x80), # Select internal temperature sensor + ), + lut=( + 0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x40, 0x4A, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x80, 0x4A, 0x40, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x4A, 0x80, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0, 0x0, + 0xF, 0x0, 0x0, 0x2, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x0, 0x0, 0x0, + ), + lut_partial=( + 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x0, 0x0, 0x0, + ), +) diff --git a/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp b/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp index fcec1a5f20..9f8ae3277e 100644 --- a/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp +++ b/esphome/components/esp32_hosted/update/esp32_hosted_update.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef USE_ESP32_HOSTED_HTTP_UPDATE #include "esphome/components/json/json_util.h" @@ -442,6 +443,12 @@ void Esp32HostedUpdate::perform(bool force) { this->status_clear_error(); this->publish_state(); +#ifdef USE_OTA_ROLLBACK + // Mark the host partition as valid before rebooting, in case the safe mode + // timer hasn't expired yet. + esp_ota_mark_app_valid_cancel_rollback(); +#endif + // Schedule a restart to ensure everything is in sync ESP_LOGI(TAG, "Restarting in 1 second"); this->set_timeout(1000, []() { App.safe_reboot(); }); diff --git a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp index 53e378c41e..c934d12d65 100644 --- a/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +++ b/esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp @@ -340,8 +340,8 @@ void I2SAudioSpeaker::speaker_task(void *params) { const uint32_t read_delay = (this_speaker->current_stream_info_.frames_to_microseconds(frames_written) / 1000) / 2; - uint8_t *new_data = transfer_buffer->get_buffer_end(); // track start of any newly copied bytes size_t bytes_read = transfer_buffer->transfer_data_from_source(pdMS_TO_TICKS(read_delay)); + uint8_t *new_data = transfer_buffer->get_buffer_end() - bytes_read; if (bytes_read > 0) { if (this_speaker->q15_volume_factor_ < INT16_MAX) { diff --git a/esphome/components/libretiny/__init__.py b/esphome/components/libretiny/__init__.py index 4fbbcde6c3..8318722b80 100644 --- a/esphome/components/libretiny/__init__.py +++ b/esphome/components/libretiny/__init__.py @@ -35,6 +35,7 @@ from .const import ( FAMILY_BK7231N, FAMILY_COMPONENT, FAMILY_FRIENDLY, + FAMILY_RTL8710B, KEY_BOARD, KEY_COMPONENT, KEY_COMPONENT_DATA, @@ -278,11 +279,23 @@ async def component_to_code(config): cg.add_build_flag(f"-DUSE_LIBRETINY_VARIANT_{config[CONF_FAMILY]}") cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) cg.add_define("ESPHOME_VARIANT", FAMILY_FRIENDLY[config[CONF_FAMILY]]) - # LibreTiny uses MULTI_NO_ATOMICS because platforms like BK7231N (ARM968E-S) lack - # exclusive load/store (no LDREX/STREX). std::atomic RMW operations require libatomic, - # which is not linked to save flash (4-8KB). Even if linked, libatomic would use locks - # (ATOMIC_INT_LOCK_FREE=1), so explicit FreeRTOS mutexes are simpler and equivalent. - cg.add_define(ThreadModel.MULTI_NO_ATOMICS) + # Set threading model based on chip architecture + component: LibreTinyComponent = CORE.data[KEY_LIBRETINY][KEY_COMPONENT_DATA] + if component.supports_atomics: + # RTL87xx (Cortex-M4) and LN882x (Cortex-M4F) have LDREX/STREX + cg.add_define(ThreadModel.MULTI_ATOMICS) + else: + # BK72xx uses ARM968E-S (ARMv5TE) which lacks LDREX/STREX. + # std::atomic RMW operations would require libatomic (not linked to save + # 4-8KB flash). Even if linked, it would use locks, so explicit FreeRTOS + # mutexes are simpler and equivalent. + cg.add_define(ThreadModel.MULTI_NO_ATOMICS) + + # RTL8710B needs FreeRTOS 8.2.3+ for xTaskNotifyGive/ulTaskNotifyTake + # required by AsyncTCP 3.4.3+ (https://github.com/esphome/esphome/issues/10220) + # RTL8720C (ambz2) requires FreeRTOS 10.x so this only applies to RTL8710B + if config[CONF_FAMILY] == FAMILY_RTL8710B: + cg.add_platformio_option("custom_versions.freertos", "8.2.3") # force using arduino framework cg.add_platformio_option("framework", "arduino") diff --git a/esphome/components/libretiny/const.py b/esphome/components/libretiny/const.py index 671992f8bd..bc4ca99ab4 100644 --- a/esphome/components/libretiny/const.py +++ b/esphome/components/libretiny/const.py @@ -11,6 +11,7 @@ class LibreTinyComponent: board_pins: dict[str, dict[str, int]] pin_validation: Callable[[int], int] usage_validation: Callable[[dict], dict] + supports_atomics: bool = False # True for Cortex-M4(F) with LDREX/STREX CONF_LIBRETINY = "libretiny" diff --git a/esphome/components/libretiny/generate_components.py b/esphome/components/libretiny/generate_components.py index c750b79317..41b4389446 100644 --- a/esphome/components/libretiny/generate_components.py +++ b/esphome/components/libretiny/generate_components.py @@ -11,13 +11,27 @@ from black import FileMode, format_str from ltchiptool import Board, Family from ltchiptool.util.lvm import LVM -BASE_CODE_INIT = """ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. -# For custom pin validators, put validate_pin() or validate_usage() -# in gpio.py file in this directory. -# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA -# in schema.py file in this directory. +BASE_CODE_INIT = ''' +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. + +To customize this component: + - Pin validators: Create gpio.py with validate_pin() or validate_usage() + - Schema extensions: Create schema.py with COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA + +Platform-specific code should be added to the main libretiny component +(__init__.py in esphome/components/libretiny/) rather than here. +""" from esphome import pins from esphome.components import libretiny @@ -31,8 +45,9 @@ from esphome.core import CORE {IMPORTS} -CODEOWNERS = ["@kuba2k2"] +CODEOWNERS = {CODEOWNERS} AUTO_LOAD = ["libretiny"] +IS_TARGET_PLATFORM = True COMPONENT_DATA = LibreTinyComponent( name=COMPONENT_{COMPONENT}, @@ -40,6 +55,7 @@ COMPONENT_DATA = LibreTinyComponent( board_pins={COMPONENT}_BOARD_PINS, pin_validation={PIN_VALIDATION}, usage_validation={USAGE_VALIDATION}, + supports_atomics={SUPPORTS_ATOMICS}, ) @@ -63,11 +79,22 @@ async def to_code(config): @pins.PIN_SCHEMA_REGISTRY.register("{COMPONENT_LOWER}", PIN_SCHEMA) async def pin_to_code(config): return await libretiny.gpio.component_pin_to_code(config) -""" +''' -BASE_CODE_BOARDS = """ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. +BASE_CODE_BOARDS = ''' +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. +""" from esphome.components.libretiny.const import {FAMILIES} @@ -76,7 +103,7 @@ from esphome.components.libretiny.const import {FAMILIES} {COMPONENT}_BOARD_PINS = {PINS_JSON} BOARDS = {COMPONENT}_BOARDS -""" +''' # variable names in component extension code VAR_SCHEMA = "COMPONENT_SCHEMA" @@ -97,6 +124,19 @@ COMPONENT_MAP = { "ln882x": "lightning-ln882x", } +# Components with Cortex-M4(F) have LDREX/STREX for native atomic support. +# BK72xx uses ARM968E-S (ARMv5TE) which lacks these instructions. +COMPONENT_SUPPORTS_ATOMICS = { + "rtl87xx": True, # Cortex-M4 + "ln882x": True, # Cortex-M4F + "bk72xx": False, # ARM968E-S +} + +# CODEOWNERS for each component. If not specified, defaults to @kuba2k2. +COMPONENT_CODEOWNERS = { + "ln882x": ["@lamauny"], +} + def subst(code: str, key: str, value: str) -> str: return code.replace(f"{{{key}}}", value) @@ -140,6 +180,7 @@ def write_component_code( "boards": {"{COMPONENT}_BOARDS", "{COMPONENT}_BOARD_PINS"}, } # substitution values + codeowners = COMPONENT_CODEOWNERS.get(component, ["@kuba2k2"]) values = dict( COMPONENT=component.upper(), COMPONENT_LOWER=component.lower(), @@ -147,6 +188,8 @@ def write_component_code( PIN_SCHEMA=PIN_SCHEMA_BASE, PIN_VALIDATION="None", USAGE_VALIDATION="None", + SUPPORTS_ATOMICS=str(COMPONENT_SUPPORTS_ATOMICS.get(component, False)), + CODEOWNERS=repr(codeowners), ) # parse gpio.py file to find custom validators diff --git a/esphome/components/ln882x/__init__.py b/esphome/components/ln882x/__init__.py index 6a76218f87..5c637bdf62 100644 --- a/esphome/components/ln882x/__init__.py +++ b/esphome/components/ln882x/__init__.py @@ -1,9 +1,23 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. -# For custom pin validators, put validate_pin() or validate_usage() -# in gpio.py file in this directory. -# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA -# in schema.py file in this directory. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. + +To customize this component: + - Pin validators: Create gpio.py with validate_pin() or validate_usage() + - Schema extensions: Create schema.py with COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA + +Platform-specific code should be added to the main libretiny component +(__init__.py in esphome/components/libretiny/) rather than here. +""" from esphome import pins from esphome.components import libretiny @@ -27,6 +41,7 @@ COMPONENT_DATA = LibreTinyComponent( board_pins=LN882X_BOARD_PINS, pin_validation=None, usage_validation=None, + supports_atomics=True, ) diff --git a/esphome/components/ln882x/boards.py b/esphome/components/ln882x/boards.py index 43f25994a7..600371951d 100644 --- a/esphome/components/ln882x/boards.py +++ b/esphome/components/ln882x/boards.py @@ -1,9 +1,28 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. +""" from esphome.components.libretiny.const import FAMILY_LN882H LN882X_BOARDS = { + "generic-ln882hki": { + "name": "Generic - LN882HKI", + "family": FAMILY_LN882H, + }, + "wb02a": { + "name": "WB02A Wi-Fi/BLE Module", + "family": FAMILY_LN882H, + }, "wl2s": { "name": "WL2S Wi-Fi/BLE Module", "family": FAMILY_LN882H, @@ -12,13 +31,195 @@ LN882X_BOARDS = { "name": "LN-02 Wi-Fi/BLE Module", "family": FAMILY_LN882H, }, - "generic-ln882hki": { - "name": "Generic - LN882HKI", - "family": FAMILY_LN882H, - }, } LN882X_BOARD_PINS = { + "generic-ln882hki": { + "WIRE0_SCL_0": 0, + "WIRE0_SCL_1": 1, + "WIRE0_SCL_2": 2, + "WIRE0_SCL_3": 3, + "WIRE0_SCL_4": 4, + "WIRE0_SCL_5": 5, + "WIRE0_SCL_6": 6, + "WIRE0_SCL_7": 7, + "WIRE0_SCL_8": 8, + "WIRE0_SCL_9": 9, + "WIRE0_SCL_10": 10, + "WIRE0_SCL_11": 11, + "WIRE0_SCL_12": 12, + "WIRE0_SCL_13": 19, + "WIRE0_SCL_14": 20, + "WIRE0_SCL_15": 21, + "WIRE0_SCL_16": 22, + "WIRE0_SCL_17": 23, + "WIRE0_SCL_18": 24, + "WIRE0_SCL_19": 25, + "WIRE0_SDA_0": 0, + "WIRE0_SDA_1": 1, + "WIRE0_SDA_2": 2, + "WIRE0_SDA_3": 3, + "WIRE0_SDA_4": 4, + "WIRE0_SDA_5": 5, + "WIRE0_SDA_6": 6, + "WIRE0_SDA_7": 7, + "WIRE0_SDA_8": 8, + "WIRE0_SDA_9": 9, + "WIRE0_SDA_10": 10, + "WIRE0_SDA_11": 11, + "WIRE0_SDA_12": 12, + "WIRE0_SDA_13": 19, + "WIRE0_SDA_14": 20, + "WIRE0_SDA_15": 21, + "WIRE0_SDA_16": 22, + "WIRE0_SDA_17": 23, + "WIRE0_SDA_18": 24, + "WIRE0_SDA_19": 25, + "SERIAL0_RX": 3, + "SERIAL0_TX": 2, + "SERIAL1_RX": 24, + "SERIAL1_TX": 25, + "ADC2": 0, + "ADC3": 1, + "ADC4": 4, + "ADC5": 19, + "ADC6": 20, + "ADC7": 21, + "PA00": 0, + "PA0": 0, + "PA01": 1, + "PA1": 1, + "PA02": 2, + "PA2": 2, + "PA03": 3, + "PA3": 3, + "PA04": 4, + "PA4": 4, + "PA05": 5, + "PA5": 5, + "PA06": 6, + "PA6": 6, + "PA07": 7, + "PA7": 7, + "PA08": 8, + "PA8": 8, + "PA09": 9, + "PA9": 9, + "PA10": 10, + "PA11": 11, + "PA12": 12, + "PB03": 19, + "PB3": 19, + "PB04": 20, + "PB4": 20, + "PB05": 21, + "PB5": 21, + "PB06": 22, + "PB6": 22, + "PB07": 23, + "PB7": 23, + "PB08": 24, + "PB8": 24, + "PB09": 25, + "PB9": 25, + "RX0": 3, + "RX1": 24, + "TX0": 2, + "TX1": 25, + "D0": 0, + "D1": 1, + "D2": 2, + "D3": 3, + "D4": 4, + "D5": 5, + "D6": 6, + "D7": 7, + "D8": 8, + "D9": 9, + "D10": 10, + "D11": 11, + "D12": 12, + "D13": 19, + "D14": 20, + "D15": 21, + "D16": 22, + "D17": 23, + "D18": 24, + "D19": 25, + "A2": 0, + "A3": 1, + "A4": 4, + "A5": 19, + "A6": 20, + "A7": 21, + }, + "wb02a": { + "WIRE0_SCL_0": 7, + "WIRE0_SCL_1": 5, + "WIRE0_SCL_2": 3, + "WIRE0_SCL_3": 10, + "WIRE0_SCL_4": 2, + "WIRE0_SCL_5": 1, + "WIRE0_SCL_6": 4, + "WIRE0_SCL_7": 5, + "WIRE0_SCL_8": 9, + "WIRE0_SCL_9": 24, + "WIRE0_SCL_10": 25, + "WIRE0_SDA_0": 7, + "WIRE0_SDA_1": 5, + "WIRE0_SDA_2": 3, + "WIRE0_SDA_3": 10, + "WIRE0_SDA_4": 2, + "WIRE0_SDA_5": 1, + "WIRE0_SDA_6": 4, + "WIRE0_SDA_7": 5, + "WIRE0_SDA_8": 9, + "WIRE0_SDA_9": 24, + "WIRE0_SDA_10": 25, + "SERIAL0_RX": 3, + "SERIAL0_TX": 2, + "SERIAL1_RX": 24, + "SERIAL1_TX": 25, + "ADC3": 1, + "ADC4": 4, + "PA01": 1, + "PA1": 1, + "PA02": 2, + "PA2": 2, + "PA03": 3, + "PA3": 3, + "PA04": 4, + "PA4": 4, + "PA05": 5, + "PA5": 5, + "PA07": 7, + "PA7": 7, + "PA09": 9, + "PA9": 9, + "PA10": 10, + "PB08": 24, + "PB8": 24, + "PB09": 25, + "PB9": 25, + "RX0": 3, + "RX1": 24, + "SCL0": 25, + "SDA0": 25, + "TX0": 2, + "TX1": 25, + "D0": 7, + "D1": 5, + "D2": 3, + "D3": 10, + "D4": 2, + "D5": 1, + "D6": 4, + "D7": 9, + "D8": 24, + "D9": 25, + "A0": 1, + "A1": 4, + }, "wl2s": { "WIRE0_SCL_0": 7, "WIRE0_SCL_1": 12, @@ -161,125 +362,6 @@ LN882X_BOARD_PINS = { "A1": 1, "A2": 0, }, - "generic-ln882hki": { - "WIRE0_SCL_0": 0, - "WIRE0_SCL_1": 1, - "WIRE0_SCL_2": 2, - "WIRE0_SCL_3": 3, - "WIRE0_SCL_4": 4, - "WIRE0_SCL_5": 5, - "WIRE0_SCL_6": 6, - "WIRE0_SCL_7": 7, - "WIRE0_SCL_8": 8, - "WIRE0_SCL_9": 9, - "WIRE0_SCL_10": 10, - "WIRE0_SCL_11": 11, - "WIRE0_SCL_12": 12, - "WIRE0_SCL_13": 19, - "WIRE0_SCL_14": 20, - "WIRE0_SCL_15": 21, - "WIRE0_SCL_16": 22, - "WIRE0_SCL_17": 23, - "WIRE0_SCL_18": 24, - "WIRE0_SCL_19": 25, - "WIRE0_SDA_0": 0, - "WIRE0_SDA_1": 1, - "WIRE0_SDA_2": 2, - "WIRE0_SDA_3": 3, - "WIRE0_SDA_4": 4, - "WIRE0_SDA_5": 5, - "WIRE0_SDA_6": 6, - "WIRE0_SDA_7": 7, - "WIRE0_SDA_8": 8, - "WIRE0_SDA_9": 9, - "WIRE0_SDA_10": 10, - "WIRE0_SDA_11": 11, - "WIRE0_SDA_12": 12, - "WIRE0_SDA_13": 19, - "WIRE0_SDA_14": 20, - "WIRE0_SDA_15": 21, - "WIRE0_SDA_16": 22, - "WIRE0_SDA_17": 23, - "WIRE0_SDA_18": 24, - "WIRE0_SDA_19": 25, - "SERIAL0_RX": 3, - "SERIAL0_TX": 2, - "SERIAL1_RX": 24, - "SERIAL1_TX": 25, - "ADC2": 0, - "ADC3": 1, - "ADC4": 4, - "ADC5": 19, - "ADC6": 20, - "ADC7": 21, - "PA00": 0, - "PA0": 0, - "PA01": 1, - "PA1": 1, - "PA02": 2, - "PA2": 2, - "PA03": 3, - "PA3": 3, - "PA04": 4, - "PA4": 4, - "PA05": 5, - "PA5": 5, - "PA06": 6, - "PA6": 6, - "PA07": 7, - "PA7": 7, - "PA08": 8, - "PA8": 8, - "PA09": 9, - "PA9": 9, - "PA10": 10, - "PA11": 11, - "PA12": 12, - "PB03": 19, - "PB3": 19, - "PB04": 20, - "PB4": 20, - "PB05": 21, - "PB5": 21, - "PB06": 22, - "PB6": 22, - "PB07": 23, - "PB7": 23, - "PB08": 24, - "PB8": 24, - "PB09": 25, - "PB9": 25, - "RX0": 3, - "RX1": 24, - "TX0": 2, - "TX1": 25, - "D0": 0, - "D1": 1, - "D2": 2, - "D3": 3, - "D4": 4, - "D5": 5, - "D6": 6, - "D7": 7, - "D8": 8, - "D9": 9, - "D10": 10, - "D11": 11, - "D12": 12, - "D13": 19, - "D14": 20, - "D15": 21, - "D16": 22, - "D17": 23, - "D18": 24, - "D19": 25, - "A2": 0, - "A3": 1, - "A4": 4, - "A5": 19, - "A6": 20, - "A7": 21, - }, } BOARDS = LN882X_BOARDS diff --git a/esphome/components/ota/ota_backend_esp_idf.cpp b/esphome/components/ota/ota_backend_esp_idf.cpp index f278c3741f..93c65a9624 100644 --- a/esphome/components/ota/ota_backend_esp_idf.cpp +++ b/esphome/components/ota/ota_backend_esp_idf.cpp @@ -14,6 +14,13 @@ namespace ota { std::unique_ptr make_ota_backend() { return make_unique(); } OTAResponseTypes IDFOTABackend::begin(size_t image_size) { +#ifdef USE_OTA_ROLLBACK + // If we're starting an OTA, the current boot is good enough - mark it valid + // to prevent rollback and allow the OTA to proceed even if the safe mode + // timer hasn't expired yet. + esp_ota_mark_app_valid_cancel_rollback(); +#endif + this->partition_ = esp_ota_get_next_update_partition(nullptr); if (this->partition_ == nullptr) { return OTA_RESPONSE_ERROR_NO_UPDATE_PARTITION; diff --git a/esphome/components/rtl87xx/__init__.py b/esphome/components/rtl87xx/__init__.py index 8f27544108..6fd750d51e 100644 --- a/esphome/components/rtl87xx/__init__.py +++ b/esphome/components/rtl87xx/__init__.py @@ -1,18 +1,29 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. -# For custom pin validators, put validate_pin() or validate_usage() -# in gpio.py file in this directory. -# For changing schema/pin schema, put COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA -# in schema.py file in this directory. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. + +To customize this component: + - Pin validators: Create gpio.py with validate_pin() or validate_usage() + - Schema extensions: Create schema.py with COMPONENT_SCHEMA or COMPONENT_PIN_SCHEMA + +Platform-specific code should be added to the main libretiny component +(__init__.py in esphome/components/libretiny/) rather than here. +""" from esphome import pins -import esphome.codegen as cg from esphome.components import libretiny from esphome.components.libretiny.const import ( COMPONENT_RTL87XX, - FAMILY_RTL8710B, KEY_COMPONENT_DATA, - KEY_FAMILY, KEY_LIBRETINY, LibreTinyComponent, ) @@ -24,13 +35,13 @@ CODEOWNERS = ["@kuba2k2"] AUTO_LOAD = ["libretiny"] IS_TARGET_PLATFORM = True - COMPONENT_DATA = LibreTinyComponent( name=COMPONENT_RTL87XX, boards=RTL87XX_BOARDS, board_pins=RTL87XX_BOARD_PINS, pin_validation=None, usage_validation=None, + supports_atomics=True, ) @@ -48,11 +59,6 @@ CONFIG_SCHEMA.prepend_extra(_set_core_data) async def to_code(config): - # Use FreeRTOS 8.2.3+ for xTaskNotifyGive/ulTaskNotifyTake required by AsyncTCP 3.4.3+ - # https://github.com/esphome/esphome/issues/10220 - # Only for RTL8710B (ambz) - RTL8720C (ambz2) requires FreeRTOS 10.x - if CORE.data[KEY_LIBRETINY][KEY_FAMILY] == FAMILY_RTL8710B: - cg.add_platformio_option("custom_versions.freertos", "8.2.3") return await libretiny.component_to_code(config) diff --git a/esphome/components/rtl87xx/boards.py b/esphome/components/rtl87xx/boards.py index e737767a56..5a3228fb1d 100644 --- a/esphome/components/rtl87xx/boards.py +++ b/esphome/components/rtl87xx/boards.py @@ -1,21 +1,52 @@ -# This file was auto-generated by libretiny/generate_components.py -# Do not modify its contents. +""" +██╗ ██╗ █████╗ ██████╗ ███╗ ██╗██╗███╗ ██╗ ██████╗ +██║ ██║██╔══██╗██╔══██╗████╗ ██║██║████╗ ██║██╔════╝ +██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ +██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║ ██║ +╚███╔███╔╝██║ ██║██║ ██║██║ ╚████║██║██║ ╚████║╚██████╔╝ + ╚══╝╚══╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ + + AUTO-GENERATED FILE - DO NOT EDIT! + +This file was auto-generated by libretiny/generate_components.py. +Any manual changes WILL BE LOST on regeneration. +""" from esphome.components.libretiny.const import FAMILY_RTL8710B, FAMILY_RTL8720C RTL87XX_BOARDS = { - "bw12": { - "name": "BW12", + "wr3le": { + "name": "WR3LE Wi-Fi Module", "family": FAMILY_RTL8710B, }, - "bw15": { - "name": "BW15", - "family": FAMILY_RTL8720C, + "wr2": { + "name": "WR2 Wi-Fi Module", + "family": FAMILY_RTL8710B, }, "generic-rtl8710bn-2mb-468k": { "name": "Generic - RTL8710BN (2M/468k)", "family": FAMILY_RTL8710B, }, + "wr1e": { + "name": "WR1E Wi-Fi Module", + "family": FAMILY_RTL8710B, + }, + "wr3e": { + "name": "WR3E Wi-Fi Module", + "family": FAMILY_RTL8710B, + }, + "wr3": { + "name": "WR3 Wi-Fi Module", + "family": FAMILY_RTL8710B, + }, + "afw121t": { + "name": "AFW121T", + "family": FAMILY_RTL8710B, + }, + "wr3n": { + "name": "WR3N Wi-Fi Module", + "family": FAMILY_RTL8710B, + }, "generic-rtl8710bn-2mb-788k": { "name": "Generic - RTL8710BN (2M/788k)", "family": FAMILY_RTL8710B, @@ -24,70 +55,827 @@ RTL87XX_BOARDS = { "name": "Generic - RTL8710BX (4M/980k)", "family": FAMILY_RTL8710B, }, - "generic-rtl8720cf-2mb-992k": { - "name": "Generic - RTL8720CF (2M/992k)", - "family": FAMILY_RTL8720C, - }, - "t102-v1.1": { - "name": "T102_V1.1", - "family": FAMILY_RTL8710B, - }, - "t103-v1.0": { - "name": "T103_V1.0", + "wr2e": { + "name": "WR2E Wi-Fi Module", "family": FAMILY_RTL8710B, }, "t112-v1.1": { "name": "T112_V1.1", "family": FAMILY_RTL8710B, }, - "wr1": { - "name": "WR1 Wi-Fi Module", - "family": FAMILY_RTL8710B, - }, - "wr1e": { - "name": "WR1E Wi-Fi Module", - "family": FAMILY_RTL8710B, - }, - "wr2": { - "name": "WR2 Wi-Fi Module", - "family": FAMILY_RTL8710B, - }, - "wr2e": { - "name": "WR2E Wi-Fi Module", - "family": FAMILY_RTL8710B, - }, - "wr2l": { - "name": "WR2L Wi-Fi Module", + "wr3l": { + "name": "WR3L Wi-Fi Module", "family": FAMILY_RTL8710B, }, "wr2le": { "name": "WR2LE Wi-Fi Module", "family": FAMILY_RTL8710B, }, - "wr3": { - "name": "WR3 Wi-Fi Module", + "bw15": { + "name": "BW15", + "family": FAMILY_RTL8720C, + }, + "t103-v1.0": { + "name": "T103_V1.0", "family": FAMILY_RTL8710B, }, - "wr3e": { - "name": "WR3E Wi-Fi Module", + "generic-rtl8720cf-2mb-992k": { + "name": "Generic - RTL8720CF (2M/992k)", + "family": FAMILY_RTL8720C, + }, + "bw12": { + "name": "BW12", "family": FAMILY_RTL8710B, }, - "wr3l": { - "name": "WR3L Wi-Fi Module", + "t102-v1.1": { + "name": "T102_V1.1", "family": FAMILY_RTL8710B, }, - "wr3le": { - "name": "WR3LE Wi-Fi Module", + "wr2l": { + "name": "WR2L Wi-Fi Module", "family": FAMILY_RTL8710B, }, - "wr3n": { - "name": "WR3N Wi-Fi Module", + "wr1": { + "name": "WR1 Wi-Fi Module", "family": FAMILY_RTL8710B, }, } RTL87XX_BOARD_PINS = { - "bw12": { + "wr3le": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 29, + "WIRE0_SCL_1": 22, + "WIRE0_SDA_0": 30, + "WIRE0_SDA_1": 19, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 5, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 29, + "D1": 14, + "D2": 15, + "D3": 22, + "D4": 0, + "D5": 30, + "D6": 19, + "D7": 5, + "D8": 12, + "D9": 18, + "D10": 23, + "A0": 19, + "A1": 41, + }, + "wr2": { + "WIRE0_SCL": 29, + "WIRE0_SDA": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC2": 41, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 29, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL0": 29, + "SCL1": 18, + "SDA0": 30, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 12, + "D1": 0, + "D2": 5, + "D4": 18, + "D5": 23, + "D6": 14, + "D7": 15, + "D8": 30, + "D9": 29, + "A1": 41, + }, + "generic-rtl8710bn-2mb-468k": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "FCS": 6, + "FD0": 9, + "FD1": 7, + "FD2": 8, + "FD3": 11, + "FSCK": 10, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA06": 6, + "PA6": 6, + "PA07": 7, + "PA7": 7, + "PA08": 8, + "PA8": 8, + "PA09": 9, + "PA9": 9, + "PA10": 10, + "PA11": 11, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 30, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 0, + "D1": 5, + "D2": 6, + "D3": 7, + "D4": 8, + "D5": 9, + "D6": 10, + "D7": 11, + "D8": 12, + "D9": 14, + "D10": 15, + "D11": 18, + "D12": 19, + "D13": 22, + "D14": 23, + "D15": 29, + "D16": 30, + "A0": 19, + "A1": 41, + }, + "wr1e": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 29, + "WIRE0_SCL_1": 22, + "WIRE0_SDA_0": 30, + "WIRE0_SDA_1": 19, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM3": 12, + "PWM4": 29, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 23, + "D1": 18, + "D2": 14, + "D3": 15, + "D4": 30, + "D5": 12, + "D6": 5, + "D7": 29, + "D8": 19, + "D9": 22, + "A0": 19, + "A1": 41, + }, + "wr3e": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 29, + "WIRE0_SCL_1": 22, + "WIRE0_SDA_0": 30, + "WIRE0_SDA_1": 19, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 5, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 29, + "D1": 14, + "D2": 15, + "D3": 22, + "D4": 0, + "D5": 30, + "D6": 19, + "D7": 5, + "D8": 12, + "D9": 18, + "D10": 23, + "A0": 19, + "A1": 41, + }, + "wr3": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 5, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 22, + "D1": 19, + "D2": 14, + "D3": 15, + "D4": 0, + "D5": 29, + "D6": 30, + "D7": 5, + "D8": 12, + "D9": 18, + "D10": 23, + "A0": 19, + "A1": 41, + }, + "afw121t": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 29, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 14, + "D1": 15, + "D2": 0, + "D3": 12, + "D4": 29, + "D5": 5, + "D6": 18, + "D7": 19, + "D8": 22, + "D9": 23, + "D10": 30, + }, + "wr3n": { + "WIRE0_SCL": 29, + "WIRE0_SDA": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC2": 41, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 5, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL0": 29, + "SCL1": 18, + "SDA0": 30, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 29, + "D1": 14, + "D2": 15, + "D3": 0, + "D4": 30, + "D5": 5, + "D6": 12, + "D7": 18, + "D8": 23, + "A1": 41, + }, + "generic-rtl8710bn-2mb-788k": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "FCS": 6, + "FD0": 9, + "FD1": 7, + "FD2": 8, + "FD3": 11, + "FSCK": 10, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA06": 6, + "PA6": 6, + "PA07": 7, + "PA7": 7, + "PA08": 8, + "PA8": 8, + "PA09": 9, + "PA9": 9, + "PA10": 10, + "PA11": 11, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 30, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 0, + "D1": 5, + "D2": 6, + "D3": 7, + "D4": 8, + "D5": 9, + "D6": 10, + "D7": 11, + "D8": 12, + "D9": 14, + "D10": 15, + "D11": 18, + "D12": 19, + "D13": 22, + "D14": 23, + "D15": 29, + "D16": 30, + "A0": 19, + "A1": 41, + }, + "generic-rtl8710bx-4mb-980k": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "FCS": 6, + "FD0": 9, + "FD1": 7, + "FD2": 8, + "FD3": 11, + "FSCK": 10, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA06": 6, + "PA6": 6, + "PA07": 7, + "PA7": 7, + "PA08": 8, + "PA8": 8, + "PA09": 9, + "PA9": 9, + "PA10": 10, + "PA11": 11, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 30, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 0, + "D1": 5, + "D2": 6, + "D3": 7, + "D4": 8, + "D5": 9, + "D6": 10, + "D7": 11, + "D8": 12, + "D9": 14, + "D10": 15, + "D11": 18, + "D12": 19, + "D13": 22, + "D14": 23, + "D15": 29, + "D16": 30, + "A0": 19, + }, + "wr2e": { + "WIRE0_SCL": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MOSI0": 23, + "MOSI1": 23, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM3": 12, + "PWM4": 29, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL0": 29, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 12, + "D1": 19, + "D2": 5, + "D3": 18, + "D4": 23, + "D5": 14, + "D6": 15, + "D7": 30, + "D8": 29, + "A0": 19, + "A1": 41, + }, + "t112-v1.1": { "SPI0_CS": 19, "SPI0_MISO": 22, "SPI0_MOSI": 23, @@ -143,18 +931,111 @@ RTL87XX_BOARD_PINS = { "SDA1": 23, "TX0": 23, "TX2": 30, - "D0": 5, - "D1": 29, - "D2": 0, - "D3": 19, - "D4": 22, - "D5": 30, - "D6": 14, + "D0": 29, + "D1": 19, + "D2": 15, + "D3": 14, + "D4": 0, + "D5": 5, + "D6": 18, "D7": 12, - "D8": 15, + "D8": 23, + "D9": 22, + "D10": 30, + "A0": 19, + }, + "wr3l": { + "SPI0_CS": 19, + "SPI0_MISO": 22, + "SPI0_MOSI": 23, + "SPI0_SCK": 18, + "SPI1_CS": 19, + "SPI1_MISO": 22, + "SPI1_MOSI": 23, + "SPI1_SCK": 18, + "WIRE0_SCL_0": 22, + "WIRE0_SCL_1": 29, + "WIRE0_SDA_0": 19, + "WIRE0_SDA_1": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_CTS": 19, + "SERIAL0_RTS": 22, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "ADC1": 19, + "ADC2": 41, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "MISO0": 22, + "MISO1": 22, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA19": 19, + "PA22": 22, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 5, + "PWM5": 22, + "RTS0": 22, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL1": 18, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 22, + "D1": 19, + "D2": 14, + "D3": 15, + "D4": 0, + "D5": 29, + "D6": 30, + "D7": 5, + "D8": 12, "D9": 18, "D10": 23, "A0": 19, + "A1": 41, + }, + "wr2le": { + "MISO0": 22, + "MISO1": 22, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA22": 22, + "PWM0": 14, + "PWM1": 15, + "PWM3": 12, + "PWM4": 5, + "PWM5": 22, + "RTS0": 22, + "SCL0": 22, + "D0": 15, + "D1": 14, + "D2": 5, + "D3": 22, + "D4": 12, }, "bw15": { "SPI0_CS_0": 2, @@ -226,7 +1107,7 @@ RTL87XX_BOARD_PINS = { "D11": 13, "D12": 14, }, - "generic-rtl8710bn-2mb-468k": { + "t103-v1.0": { "SPI0_CS": 19, "SPI0_MISO": 22, "SPI0_MOSI": 23, @@ -252,12 +1133,6 @@ RTL87XX_BOARD_PINS = { "CS0": 19, "CS1": 19, "CTS0": 19, - "FCS": 6, - "FD0": 9, - "FD1": 7, - "FD2": 8, - "FD3": 11, - "FSCK": 10, "MISO0": 22, "MISO1": 22, "MOSI0": 23, @@ -266,16 +1141,6 @@ RTL87XX_BOARD_PINS = { "PA0": 0, "PA05": 5, "PA5": 5, - "PA06": 6, - "PA6": 6, - "PA07": 7, - "PA7": 7, - "PA08": 8, - "PA8": 8, - "PA09": 9, - "PA9": 9, - "PA10": 10, - "PA11": 11, "PA12": 12, "PA14": 14, "PA15": 15, @@ -288,7 +1153,7 @@ RTL87XX_BOARD_PINS = { "PWM1": 15, "PWM2": 0, "PWM3": 12, - "PWM4": 30, + "PWM4": 5, "PWM5": 22, "RTS0": 22, "RX0": 18, @@ -299,210 +1164,20 @@ RTL87XX_BOARD_PINS = { "SDA1": 23, "TX0": 23, "TX2": 30, - "D0": 0, - "D1": 5, - "D2": 6, - "D3": 7, - "D4": 8, - "D5": 9, - "D6": 10, - "D7": 11, + "D0": 19, + "D1": 14, + "D2": 15, + "D3": 0, + "D4": 22, + "D5": 29, + "D6": 30, + "D7": 5, "D8": 12, - "D9": 14, - "D10": 15, - "D11": 18, - "D12": 19, - "D13": 22, - "D14": 23, - "D15": 29, - "D16": 30, + "D9": 18, + "D10": 23, "A0": 19, "A1": 41, }, - "generic-rtl8710bn-2mb-788k": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 22, - "WIRE0_SCL_1": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "FCS": 6, - "FD0": 9, - "FD1": 7, - "FD2": 8, - "FD3": 11, - "FSCK": 10, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA06": 6, - "PA6": 6, - "PA07": 7, - "PA7": 7, - "PA08": 8, - "PA8": 8, - "PA09": 9, - "PA9": 9, - "PA10": 10, - "PA11": 11, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 30, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 0, - "D1": 5, - "D2": 6, - "D3": 7, - "D4": 8, - "D5": 9, - "D6": 10, - "D7": 11, - "D8": 12, - "D9": 14, - "D10": 15, - "D11": 18, - "D12": 19, - "D13": 22, - "D14": 23, - "D15": 29, - "D16": 30, - "A0": 19, - "A1": 41, - }, - "generic-rtl8710bx-4mb-980k": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 22, - "WIRE0_SCL_1": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "FCS": 6, - "FD0": 9, - "FD1": 7, - "FD2": 8, - "FD3": 11, - "FSCK": 10, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA06": 6, - "PA6": 6, - "PA07": 7, - "PA7": 7, - "PA08": 8, - "PA8": 8, - "PA09": 9, - "PA9": 9, - "PA10": 10, - "PA11": 11, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 30, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 0, - "D1": 5, - "D2": 6, - "D3": 7, - "D4": 8, - "D5": 9, - "D6": 10, - "D7": 11, - "D8": 12, - "D9": 14, - "D10": 15, - "D11": 18, - "D12": 19, - "D13": 22, - "D14": 23, - "D15": 29, - "D16": 30, - "A0": 19, - }, "generic-rtl8720cf-2mb-992k": { "SPI0_CS_0": 2, "SPI0_CS_1": 7, @@ -601,124 +1276,7 @@ RTL87XX_BOARD_PINS = { "D18": 20, "D19": 23, }, - "t102-v1.1": { - "WIRE0_SCL": 29, - "WIRE0_SDA": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 29, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL0": 29, - "SCL1": 18, - "SDA0": 30, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 12, - "D1": 0, - "D2": 5, - "D3": 30, - "D4": 29, - "D5": 18, - "D6": 23, - "D7": 14, - "D8": 15, - }, - "t103-v1.0": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 22, - "WIRE0_SCL_1": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 19, - "D1": 14, - "D2": 15, - "D3": 0, - "D4": 22, - "D5": 29, - "D6": 30, - "D7": 5, - "D8": 12, - "D9": 18, - "D10": 23, - "A0": 19, - "A1": 41, - }, - "t112-v1.1": { + "bw12": { "SPI0_CS": 19, "SPI0_MISO": 22, "SPI0_MOSI": 23, @@ -774,17 +1332,86 @@ RTL87XX_BOARD_PINS = { "SDA1": 23, "TX0": 23, "TX2": 30, - "D0": 29, - "D1": 19, - "D2": 15, - "D3": 14, - "D4": 0, - "D5": 5, - "D6": 18, + "D0": 5, + "D1": 29, + "D2": 0, + "D3": 19, + "D4": 22, + "D5": 30, + "D6": 14, "D7": 12, - "D8": 23, - "D9": 22, - "D10": 30, + "D8": 15, + "D9": 18, + "D10": 23, + "A0": 19, + }, + "t102-v1.1": { + "WIRE0_SCL": 29, + "WIRE0_SDA": 30, + "WIRE1_SCL": 18, + "WIRE1_SDA": 23, + "SERIAL0_RX": 18, + "SERIAL0_TX": 23, + "SERIAL2_RX": 29, + "SERIAL2_TX": 30, + "MOSI0": 23, + "MOSI1": 23, + "PA00": 0, + "PA0": 0, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA18": 18, + "PA23": 23, + "PA29": 29, + "PA30": 30, + "PWM1": 15, + "PWM2": 0, + "PWM3": 12, + "PWM4": 29, + "RX0": 18, + "RX2": 29, + "SCK0": 18, + "SCK1": 18, + "SCL0": 29, + "SCL1": 18, + "SDA0": 30, + "SDA1": 23, + "TX0": 23, + "TX2": 30, + "D0": 12, + "D1": 0, + "D2": 5, + "D3": 30, + "D4": 29, + "D5": 18, + "D6": 23, + "D7": 14, + "D8": 15, + }, + "wr2l": { + "ADC1": 19, + "CS0": 19, + "CS1": 19, + "CTS0": 19, + "PA05": 5, + "PA5": 5, + "PA12": 12, + "PA14": 14, + "PA15": 15, + "PA19": 19, + "PWM0": 14, + "PWM1": 15, + "PWM3": 12, + "PWM4": 5, + "SDA0": 19, + "D0": 15, + "D1": 14, + "D2": 5, + "D3": 19, + "D4": 12, "A0": 19, }, "wr1": { @@ -855,550 +1482,6 @@ RTL87XX_BOARD_PINS = { "A0": 19, "A1": 41, }, - "wr1e": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 29, - "WIRE0_SCL_1": 22, - "WIRE0_SDA_0": 30, - "WIRE0_SDA_1": 19, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM3": 12, - "PWM4": 29, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 23, - "D1": 18, - "D2": 14, - "D3": 15, - "D4": 30, - "D5": 12, - "D6": 5, - "D7": 29, - "D8": 19, - "D9": 22, - "A0": 19, - "A1": 41, - }, - "wr2": { - "WIRE0_SCL": 29, - "WIRE0_SDA": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC2": 41, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 29, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL0": 29, - "SCL1": 18, - "SDA0": 30, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 12, - "D1": 0, - "D2": 5, - "D4": 18, - "D5": 23, - "D6": 14, - "D7": 15, - "D8": 30, - "D9": 29, - "A1": 41, - }, - "wr2e": { - "WIRE0_SCL": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MOSI0": 23, - "MOSI1": 23, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM3": 12, - "PWM4": 29, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL0": 29, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 12, - "D1": 19, - "D2": 5, - "D3": 18, - "D4": 23, - "D5": 14, - "D6": 15, - "D7": 30, - "D8": 29, - "A0": 19, - "A1": 41, - }, - "wr2l": { - "ADC1": 19, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA19": 19, - "PWM0": 14, - "PWM1": 15, - "PWM3": 12, - "PWM4": 5, - "SDA0": 19, - "D0": 15, - "D1": 14, - "D2": 5, - "D3": 19, - "D4": 12, - "A0": 19, - }, - "wr2le": { - "MISO0": 22, - "MISO1": 22, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA22": 22, - "PWM0": 14, - "PWM1": 15, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "SCL0": 22, - "D0": 15, - "D1": 14, - "D2": 5, - "D3": 22, - "D4": 12, - }, - "wr3": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 22, - "WIRE0_SCL_1": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 22, - "D1": 19, - "D2": 14, - "D3": 15, - "D4": 0, - "D5": 29, - "D6": 30, - "D7": 5, - "D8": 12, - "D9": 18, - "D10": 23, - "A0": 19, - "A1": 41, - }, - "wr3e": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 29, - "WIRE0_SCL_1": 22, - "WIRE0_SDA_0": 30, - "WIRE0_SDA_1": 19, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 29, - "D1": 14, - "D2": 15, - "D3": 22, - "D4": 0, - "D5": 30, - "D6": 19, - "D7": 5, - "D8": 12, - "D9": 18, - "D10": 23, - "A0": 19, - "A1": 41, - }, - "wr3l": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 22, - "WIRE0_SCL_1": 29, - "WIRE0_SDA_0": 19, - "WIRE0_SDA_1": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 22, - "D1": 19, - "D2": 14, - "D3": 15, - "D4": 0, - "D5": 29, - "D6": 30, - "D7": 5, - "D8": 12, - "D9": 18, - "D10": 23, - "A0": 19, - "A1": 41, - }, - "wr3le": { - "SPI0_CS": 19, - "SPI0_MISO": 22, - "SPI0_MOSI": 23, - "SPI0_SCK": 18, - "SPI1_CS": 19, - "SPI1_MISO": 22, - "SPI1_MOSI": 23, - "SPI1_SCK": 18, - "WIRE0_SCL_0": 29, - "WIRE0_SCL_1": 22, - "WIRE0_SDA_0": 30, - "WIRE0_SDA_1": 19, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_CTS": 19, - "SERIAL0_RTS": 22, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC1": 19, - "ADC2": 41, - "CS0": 19, - "CS1": 19, - "CTS0": 19, - "MISO0": 22, - "MISO1": 22, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA19": 19, - "PA22": 22, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "PWM5": 22, - "RTS0": 22, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL1": 18, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 29, - "D1": 14, - "D2": 15, - "D3": 22, - "D4": 0, - "D5": 30, - "D6": 19, - "D7": 5, - "D8": 12, - "D9": 18, - "D10": 23, - "A0": 19, - "A1": 41, - }, - "wr3n": { - "WIRE0_SCL": 29, - "WIRE0_SDA": 30, - "WIRE1_SCL": 18, - "WIRE1_SDA": 23, - "SERIAL0_RX": 18, - "SERIAL0_TX": 23, - "SERIAL2_RX": 29, - "SERIAL2_TX": 30, - "ADC2": 41, - "MOSI0": 23, - "MOSI1": 23, - "PA00": 0, - "PA0": 0, - "PA05": 5, - "PA5": 5, - "PA12": 12, - "PA14": 14, - "PA15": 15, - "PA18": 18, - "PA23": 23, - "PA29": 29, - "PA30": 30, - "PWM1": 15, - "PWM2": 0, - "PWM3": 12, - "PWM4": 5, - "RX0": 18, - "RX2": 29, - "SCK0": 18, - "SCK1": 18, - "SCL0": 29, - "SCL1": 18, - "SDA0": 30, - "SDA1": 23, - "TX0": 23, - "TX2": 30, - "D0": 29, - "D1": 14, - "D2": 15, - "D3": 0, - "D4": 30, - "D5": 5, - "D6": 12, - "D7": 18, - "D8": 23, - "A1": 41, - }, } BOARDS = RTL87XX_BOARDS diff --git a/esphome/components/switch/__init__.py b/esphome/components/switch/__init__.py index e9473012cf..7424d7c92f 100644 --- a/esphome/components/switch/__init__.py +++ b/esphome/components/switch/__init__.py @@ -1,7 +1,7 @@ from esphome import automation from esphome.automation import Condition, maybe_simple_id import esphome.codegen as cg -from esphome.components import mqtt, web_server +from esphome.components import mqtt, web_server, zigbee import esphome.config_validation as cv from esphome.const import ( CONF_DEVICE_CLASS, @@ -74,6 +74,7 @@ validate_device_class = cv.one_of(*DEVICE_CLASSES, lower=True) _SWITCH_SCHEMA = ( cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA) .extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA) + .extend(zigbee.SWITCH_SCHEMA) .extend( { cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTSwitchComponent), @@ -103,6 +104,7 @@ _SWITCH_SCHEMA = ( _SWITCH_SCHEMA.add_extra(entity_duplicate_validator("switch")) +_SWITCH_SCHEMA.add_extra(zigbee.validate_switch) def switch_schema( @@ -165,6 +167,7 @@ async def setup_switch_core_(var, config): cg.add(var.set_device_class(device_class)) cg.add(var.set_restore_mode(config[CONF_RESTORE_MODE])) + await zigbee.setup_switch(var, config) async def register_switch(var, config): diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index b7d820413c..61c4584d09 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -543,7 +543,12 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { } s_sta_connected = false; s_sta_connecting = false; + // IMPORTANT: Set error flag BEFORE notifying listeners. + // This ensures is_connected() returns false during listener callbacks, + // which is critical for proper reconnection logic (e.g., roaming). + global_wifi_component->error_from_callback_ = true; #ifdef USE_WIFI_LISTENERS + // Notify listeners AFTER setting error flag so they see correct state static constexpr uint8_t EMPTY_BSSID[6] = {}; for (auto *listener : global_wifi_component->connect_state_listeners_) { listener->on_wifi_connect_state(StringRef(), EMPTY_BSSID); @@ -635,10 +640,6 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { break; } - if (event->event == EVENT_STAMODE_DISCONNECTED) { - global_wifi_component->error_from_callback_ = true; - } - WiFiMockClass::_event_callback(event); } diff --git a/esphome/components/zigbee/__init__.py b/esphome/components/zigbee/__init__.py index e363164997..2281dd38a9 100644 --- a/esphome/components/zigbee/__init__.py +++ b/esphome/components/zigbee/__init__.py @@ -23,7 +23,7 @@ from .const_zephyr import ( ZigbeeComponent, zigbee_ns, ) -from .zigbee_zephyr import zephyr_binary_sensor, zephyr_sensor +from .zigbee_zephyr import zephyr_binary_sensor, zephyr_sensor, zephyr_switch _LOGGER = logging.getLogger(__name__) @@ -41,6 +41,7 @@ def zigbee_set_core_data(config: ConfigType) -> ConfigType: BINARY_SENSOR_SCHEMA = cv.Schema({}).extend(zephyr_binary_sensor) SENSOR_SCHEMA = cv.Schema({}).extend(zephyr_sensor) +SWITCH_SCHEMA = cv.Schema({}).extend(zephyr_switch) CONFIG_SCHEMA = cv.All( cv.Schema( @@ -107,6 +108,15 @@ async def setup_sensor(entity: cg.MockObj, config: ConfigType) -> None: await zephyr_setup_sensor(entity, config) +async def setup_switch(entity: cg.MockObj, config: ConfigType) -> None: + if not config.get(CONF_ZIGBEE_ID) or config.get(CONF_INTERNAL): + return + if CORE.using_zephyr: + from .zigbee_zephyr import zephyr_setup_switch + + await zephyr_setup_switch(entity, config) + + def consume_endpoint(config: ConfigType) -> ConfigType: if not config.get(CONF_ZIGBEE_ID) or config.get(CONF_INTERNAL): return config @@ -130,6 +140,10 @@ def validate_sensor(config: ConfigType) -> ConfigType: return consume_endpoint(config) +def validate_switch(config: ConfigType) -> ConfigType: + return consume_endpoint(config) + + ZIGBEE_ACTION_SCHEMA = automation.maybe_simple_id( cv.Schema( { diff --git a/esphome/components/zigbee/const_zephyr.py b/esphome/components/zigbee/const_zephyr.py index 8d1f229b6e..0372f22593 100644 --- a/esphome/components/zigbee/const_zephyr.py +++ b/esphome/components/zigbee/const_zephyr.py @@ -11,6 +11,7 @@ CONF_ON_JOIN = "on_join" CONF_WIPE_ON_BOOT = "wipe_on_boot" CONF_ZIGBEE_BINARY_SENSOR = "zigbee_binary_sensor" CONF_ZIGBEE_SENSOR = "zigbee_sensor" +CONF_ZIGBEE_SWITCH = "zigbee_switch" CONF_POWER_SOURCE = "power_source" POWER_SOURCE = { "UNKNOWN": "ZB_ZCL_BASIC_POWER_SOURCE_UNKNOWN", @@ -35,3 +36,4 @@ ZB_ZCL_CLUSTER_ID_BASIC = "ZB_ZCL_CLUSTER_ID_BASIC" ZB_ZCL_CLUSTER_ID_IDENTIFY = "ZB_ZCL_CLUSTER_ID_IDENTIFY" ZB_ZCL_CLUSTER_ID_BINARY_INPUT = "ZB_ZCL_CLUSTER_ID_BINARY_INPUT" ZB_ZCL_CLUSTER_ID_ANALOG_INPUT = "ZB_ZCL_CLUSTER_ID_ANALOG_INPUT" +ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT = "ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT" diff --git a/esphome/components/zigbee/zigbee_switch_zephyr.cpp b/esphome/components/zigbee/zigbee_switch_zephyr.cpp new file mode 100644 index 0000000000..5454f262f9 --- /dev/null +++ b/esphome/components/zigbee/zigbee_switch_zephyr.cpp @@ -0,0 +1,111 @@ +#include "zigbee_switch_zephyr.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) && defined(USE_SWITCH) +#include "esphome/core/log.h" +#include + +extern "C" { +#include +#include +#include +#include +#include +} + +namespace esphome::zigbee { + +static const char *const TAG = "zigbee_on_off.switch"; + +void ZigbeeSwitch::dump_config() { + ESP_LOGCONFIG(TAG, + "Zigbee Switch\n" + " Endpoint: %d, present_value %u", + this->endpoint_, this->cluster_attributes_->present_value); +} + +void ZigbeeSwitch::setup() { + this->parent_->add_callback(this->endpoint_, [this](zb_bufid_t bufid) { this->zcl_device_cb_(bufid); }); + this->switch_->add_on_state_callback([this](bool state) { + this->cluster_attributes_->present_value = state ? ZB_TRUE : ZB_FALSE; + ESP_LOGD(TAG, "Set attribute endpoint: %d, present_value %d", this->endpoint_, + this->cluster_attributes_->present_value); + ZB_ZCL_SET_ATTRIBUTE(this->endpoint_, ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT, ZB_ZCL_CLUSTER_SERVER_ROLE, + ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID, &this->cluster_attributes_->present_value, + ZB_FALSE); + this->parent_->flush(); + }); +} + +void ZigbeeSwitch::zcl_device_cb_(zb_bufid_t bufid) { + zb_zcl_device_callback_param_t *p_device_cb_param = ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t); + zb_zcl_device_callback_id_t device_cb_id = p_device_cb_param->device_cb_id; + zb_uint16_t cluster_id = p_device_cb_param->cb_param.set_attr_value_param.cluster_id; + zb_uint16_t attr_id = p_device_cb_param->cb_param.set_attr_value_param.attr_id; + + p_device_cb_param->status = RET_OK; + + switch (device_cb_id) { + /* ZCL set attribute value */ + case ZB_ZCL_SET_ATTR_VALUE_CB_ID: + if (cluster_id == ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT) { + uint8_t value = p_device_cb_param->cb_param.set_attr_value_param.values.data8; + ESP_LOGI(TAG, "Binary output attribute setting to %hd", value); + if (attr_id == ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID) { + this->defer([this, value]() { + this->cluster_attributes_->present_value = value ? ZB_TRUE : ZB_FALSE; + this->switch_->publish_state(value); + }); + } + } else { + /* other clusters attribute handled here */ + ESP_LOGI(TAG, "Unhandled cluster attribute id: %d", cluster_id); + } + break; + default: + p_device_cb_param->status = RET_ERROR; + break; + } + + ESP_LOGD(TAG, "%s status: %hd", __func__, p_device_cb_param->status); +} + +const zb_uint8_t ZB_ZCL_BINARY_OUTPUT_STATUS_FLAG_MAX_VALUE = 0x0F; + +static zb_ret_t check_value_binary_output_server(zb_uint16_t attr_id, zb_uint8_t endpoint, + zb_uint8_t *value) { // NOLINT(readability-non-const-parameter) + zb_ret_t ret = RET_OK; + ZVUNUSED(endpoint); + + switch (attr_id) { + case ZB_ZCL_ATTR_BINARY_OUTPUT_OUT_OF_SERVICE_ID: + case ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID: + ret = ZB_ZCL_CHECK_BOOL_VALUE(*value) ? RET_OK : RET_ERROR; + break; + + case ZB_ZCL_ATTR_BINARY_OUTPUT_STATUS_FLAG_ID: + if (*value > ZB_ZCL_BINARY_OUTPUT_STATUS_FLAG_MAX_VALUE) { + ret = RET_ERROR; + } + break; + + default: + break; + } + + return ret; +} + +} // namespace esphome::zigbee + +void zb_zcl_binary_output_init_server() { + zb_zcl_add_cluster_handlers(ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT, ZB_ZCL_CLUSTER_SERVER_ROLE, + esphome::zigbee::check_value_binary_output_server, + (zb_zcl_cluster_write_attr_hook_t) NULL, (zb_zcl_cluster_handler_t) NULL); +} + +void zb_zcl_binary_output_init_client() { + zb_zcl_add_cluster_handlers(ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT, ZB_ZCL_CLUSTER_CLIENT_ROLE, + (zb_zcl_cluster_check_value_t) NULL, (zb_zcl_cluster_write_attr_hook_t) NULL, + (zb_zcl_cluster_handler_t) NULL); +} + +#endif diff --git a/esphome/components/zigbee/zigbee_switch_zephyr.h b/esphome/components/zigbee/zigbee_switch_zephyr.h new file mode 100644 index 0000000000..b774c23b3c --- /dev/null +++ b/esphome/components/zigbee/zigbee_switch_zephyr.h @@ -0,0 +1,83 @@ +#pragma once + +#include "esphome/components/zigbee/zigbee_zephyr.h" +#if defined(USE_ZIGBEE) && defined(USE_NRF52) && defined(USE_SWITCH) +#include "esphome/core/component.h" +#include "esphome/components/switch/switch.h" +extern "C" { +#include +#include +} + +#define ZB_ZCL_BINARY_OUTPUT_CLUSTER_REVISION_DEFAULT ((zb_uint16_t) 0x0001u) + +// NOLINTNEXTLINE(readability-identifier-naming) +enum zb_zcl_binary_output_attr_e { + ZB_ZCL_ATTR_BINARY_OUTPUT_DESCRIPTION_ID = 0x001C, + ZB_ZCL_ATTR_BINARY_OUTPUT_OUT_OF_SERVICE_ID = 0x0051, + ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID = 0x0055, + ZB_ZCL_ATTR_BINARY_OUTPUT_STATUS_FLAG_ID = 0x006F, +}; + +#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_BINARY_OUTPUT_OUT_OF_SERVICE_ID(data_ptr) \ + { \ + ZB_ZCL_ATTR_BINARY_OUTPUT_OUT_OF_SERVICE_ID, ZB_ZCL_ATTR_TYPE_BOOL, \ + ZB_ZCL_ATTR_ACCESS_READ_ONLY | ZB_ZCL_ATTR_ACCESS_WRITE_OPTIONAL, (ZB_ZCL_NON_MANUFACTURER_SPECIFIC), \ + (void *) (data_ptr) \ + } + +#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID(data_ptr) \ + { \ + ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID, ZB_ZCL_ATTR_TYPE_BOOL, \ + ZB_ZCL_ATTR_ACCESS_READ_WRITE | ZB_ZCL_ATTR_ACCESS_REPORTING, (ZB_ZCL_NON_MANUFACTURER_SPECIFIC), \ + (void *) (data_ptr) \ + } + +#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_BINARY_OUTPUT_STATUS_FLAG_ID(data_ptr) \ + { \ + ZB_ZCL_ATTR_BINARY_OUTPUT_STATUS_FLAG_ID, ZB_ZCL_ATTR_TYPE_8BITMAP, \ + ZB_ZCL_ATTR_ACCESS_READ_ONLY | ZB_ZCL_ATTR_ACCESS_REPORTING, (ZB_ZCL_NON_MANUFACTURER_SPECIFIC), \ + (void *) (data_ptr) \ + } + +#define ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_BINARY_OUTPUT_DESCRIPTION_ID(data_ptr) \ + { \ + ZB_ZCL_ATTR_BINARY_OUTPUT_DESCRIPTION_ID, ZB_ZCL_ATTR_TYPE_CHAR_STRING, ZB_ZCL_ATTR_ACCESS_READ_ONLY, \ + (ZB_ZCL_NON_MANUFACTURER_SPECIFIC), (void *) (data_ptr) \ + } + +#define ESPHOME_ZB_ZCL_DECLARE_BINARY_OUTPUT_ATTRIB_LIST(attr_list, out_of_service, present_value, status_flag, \ + description) \ + ZB_ZCL_START_DECLARE_ATTRIB_LIST_CLUSTER_REVISION(attr_list, ZB_ZCL_BINARY_OUTPUT) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_OUTPUT_OUT_OF_SERVICE_ID, (out_of_service)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_OUTPUT_PRESENT_VALUE_ID, (present_value)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_OUTPUT_STATUS_FLAG_ID, (status_flag)) \ + ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_BINARY_OUTPUT_DESCRIPTION_ID, (description)) \ + ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST + +void zb_zcl_binary_output_init_server(); +void zb_zcl_binary_output_init_client(); + +#define ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT_SERVER_ROLE_INIT zb_zcl_binary_output_init_server +#define ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT_CLIENT_ROLE_INIT zb_zcl_binary_output_init_client + +namespace esphome::zigbee { + +class ZigbeeSwitch : public ZigbeeEntity, public Component { + public: + ZigbeeSwitch(switch_::Switch *s) : switch_(s) {} + void set_cluster_attributes(BinaryAttrs &cluster_attributes) { this->cluster_attributes_ = &cluster_attributes; } + + void setup() override; + + void dump_config() override; + + protected: + void zcl_device_cb_(zb_bufid_t bufid); + + BinaryAttrs *cluster_attributes_{nullptr}; + switch_::Switch *switch_; +}; + +} // namespace esphome::zigbee +#endif diff --git a/esphome/components/zigbee/zigbee_zephyr.cpp b/esphome/components/zigbee/zigbee_zephyr.cpp index 9a421aaec1..e43ab8f84d 100644 --- a/esphome/components/zigbee/zigbee_zephyr.cpp +++ b/esphome/components/zigbee/zigbee_zephyr.cpp @@ -104,9 +104,15 @@ void ZigbeeComponent::zcl_device_cb(zb_bufid_t bufid) { ESP_LOGI(TAG, "Zcl_device_cb %s id %hd, cluster_id %d, attr_id %d, endpoint: %d", __func__, device_cb_id, cluster_id, attr_id, endpoint); + /* Set default response value. */ + p_device_cb_param->status = RET_OK; + // endpoints are enumerated from 1 if (global_zigbee->callbacks_.size() >= endpoint) { - global_zigbee->callbacks_[endpoint - 1](bufid); + const auto &cb = global_zigbee->callbacks_[endpoint - 1]; + if (cb) { + cb(bufid); + } return; } p_device_cb_param->status = RET_ERROR; diff --git a/esphome/components/zigbee/zigbee_zephyr.h b/esphome/components/zigbee/zigbee_zephyr.h index fa23907bf4..d5f1257f9c 100644 --- a/esphome/components/zigbee/zigbee_zephyr.h +++ b/esphome/components/zigbee/zigbee_zephyr.h @@ -81,7 +81,7 @@ class ZigbeeComponent : public Component { #ifdef USE_ZIGBEE_WIPE_ON_BOOT void erase_flash_(int area); #endif - StaticVector, ZIGBEE_ENDPOINTS_COUNT> callbacks_; + std::array, ZIGBEE_ENDPOINTS_COUNT> callbacks_{}; CallbackManager join_cb_; Trigger<> join_trigger_; bool need_flush_{false}; diff --git a/esphome/components/zigbee/zigbee_zephyr.py b/esphome/components/zigbee/zigbee_zephyr.py index 71ea0da6a7..7f1f7dc57f 100644 --- a/esphome/components/zigbee/zigbee_zephyr.py +++ b/esphome/components/zigbee/zigbee_zephyr.py @@ -55,6 +55,7 @@ from .const_zephyr import ( CONF_ZIGBEE_BINARY_SENSOR, CONF_ZIGBEE_ID, CONF_ZIGBEE_SENSOR, + CONF_ZIGBEE_SWITCH, KEY_EP_NUMBER, KEY_ZIGBEE, POWER_SOURCE, @@ -62,6 +63,7 @@ from .const_zephyr import ( ZB_ZCL_CLUSTER_ID_ANALOG_INPUT, ZB_ZCL_CLUSTER_ID_BASIC, ZB_ZCL_CLUSTER_ID_BINARY_INPUT, + ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT, ZB_ZCL_CLUSTER_ID_IDENTIFY, ZB_ZCL_IDENTIFY_ATTRS_T, AnalogAttrs, @@ -72,6 +74,7 @@ from .const_zephyr import ( ZigbeeBinarySensor = zigbee_ns.class_("ZigbeeBinarySensor", cg.Component) ZigbeeSensor = zigbee_ns.class_("ZigbeeSensor", cg.Component) +ZigbeeSwitch = zigbee_ns.class_("ZigbeeSwitch", cg.Component) # BACnet engineering units mapping (ZCL uses BACnet unit codes) # See: https://github.com/zigpy/zha/blob/dev/zha/application/platforms/number/bacnet.py @@ -126,6 +129,15 @@ zephyr_sensor = cv.Schema( } ) +zephyr_switch = cv.Schema( + { + cv.OnlyWith(CONF_ZIGBEE_ID, ["nrf52", "zigbee"]): cv.use_id(ZigbeeComponent), + cv.OnlyWith(CONF_ZIGBEE_SWITCH, ["nrf52", "zigbee"]): cv.declare_id( + ZigbeeSwitch + ), + } +) + async def zephyr_to_code(config: ConfigType) -> None: zephyr_add_prj_conf("ZIGBEE", True) @@ -320,6 +332,10 @@ async def zephyr_setup_sensor(entity: cg.MockObj, config: ConfigType) -> None: CORE.add_job(_add_sensor, entity, config) +async def zephyr_setup_switch(entity: cg.MockObj, config: ConfigType) -> None: + CORE.add_job(_add_switch, entity, config) + + def _slot_index() -> int: """Find the next available endpoint slot""" slot = next( @@ -332,7 +348,7 @@ def _slot_index() -> int: return slot -async def _add_zigbee_input( +async def _add_zigbee_ep( entity: cg.MockObj, config: ConfigType, component_key, @@ -389,7 +405,7 @@ async def _add_zigbee_input( async def _add_binary_sensor(entity: cg.MockObj, config: ConfigType) -> None: - await _add_zigbee_input( + await _add_zigbee_ep( entity, config, CONF_ZIGBEE_BINARY_SENSOR, @@ -405,7 +421,7 @@ async def _add_sensor(entity: cg.MockObj, config: ConfigType) -> None: unit = config.get(CONF_UNIT_OF_MEASUREMENT, "") bacnet_unit = BACNET_UNITS.get(unit, BACNET_UNIT_NO_UNITS) - await _add_zigbee_input( + await _add_zigbee_ep( entity, config, CONF_ZIGBEE_SENSOR, @@ -415,3 +431,15 @@ async def _add_sensor(entity: cg.MockObj, config: ConfigType) -> None: "ZB_HA_CUSTOM_ATTR_DEVICE_ID", extra_field_values={"engineering_units": bacnet_unit}, ) + + +async def _add_switch(entity: cg.MockObj, config: ConfigType) -> None: + await _add_zigbee_ep( + entity, + config, + CONF_ZIGBEE_SWITCH, + BinaryAttrs, + "ESPHOME_ZB_ZCL_DECLARE_BINARY_OUTPUT_ATTRIB_LIST", + ZB_ZCL_CLUSTER_ID_BINARY_OUTPUT, + "ZB_HA_CUSTOM_ATTR_DEVICE_ID", + ) diff --git a/esphome/core/scheduler.cpp b/esphome/core/scheduler.cpp index 8b713523b6..b28cb947c7 100644 --- a/esphome/core/scheduler.cpp +++ b/esphome/core/scheduler.cpp @@ -612,8 +612,9 @@ uint64_t Scheduler::millis_64_(uint32_t now) { // THREAD SAFETY NOTE: // This function has three implementations, based on the precompiler flags // - ESPHOME_THREAD_SINGLE - Runs on single-threaded platforms (ESP8266, RP2040, etc.) - // - ESPHOME_THREAD_MULTI_NO_ATOMICS - Runs on multi-threaded platforms without atomics (LibreTiny) - // - ESPHOME_THREAD_MULTI_ATOMICS - Runs on multi-threaded platforms with atomics (ESP32, HOST, etc.) + // - ESPHOME_THREAD_MULTI_NO_ATOMICS - Runs on multi-threaded platforms without atomics (LibreTiny BK72xx) + // - ESPHOME_THREAD_MULTI_ATOMICS - Runs on multi-threaded platforms with atomics (ESP32, HOST, LibreTiny + // RTL87xx/LN882x, etc.) // // Make sure all changes are synchronized if you edit this function. // diff --git a/requirements_dev.txt b/requirements_dev.txt index 16e051fcd7..0884e5b5e4 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,4 +1,4 @@ # Useful stuff when working in a development environment clang-format==13.0.1 # also change in .pre-commit-config.yaml and Dockerfile when updating clang-tidy==18.1.8 # When updating clang-tidy, also update Dockerfile -yamllint==1.37.1 # also change in .pre-commit-config.yaml when updating +yamllint==1.38.0 # also change in .pre-commit-config.yaml when updating diff --git a/tests/component_tests/epaper_spi/__init__.py b/tests/component_tests/epaper_spi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/component_tests/epaper_spi/test_init.py b/tests/component_tests/epaper_spi/test_init.py new file mode 100644 index 0000000000..71e66cd043 --- /dev/null +++ b/tests/component_tests/epaper_spi/test_init.py @@ -0,0 +1,291 @@ +"""Tests for epaper_spi configuration validation.""" + +from collections.abc import Callable +from typing import Any + +import pytest + +from esphome import config_validation as cv +from esphome.components.epaper_spi.display import ( + CONFIG_SCHEMA, + FINAL_VALIDATE_SCHEMA, + MODELS, +) +from esphome.components.esp32 import ( + KEY_BOARD, + KEY_VARIANT, + VARIANT_ESP32, + VARIANT_ESP32S3, +) +from esphome.const import ( + CONF_BUSY_PIN, + CONF_CS_PIN, + CONF_DC_PIN, + CONF_DIMENSIONS, + CONF_HEIGHT, + CONF_INIT_SEQUENCE, + CONF_RESET_PIN, + CONF_WIDTH, + PlatformFramework, +) +from esphome.types import ConfigType +from tests.component_tests.types import SetCoreConfigCallable + + +def run_schema_validation( + config: ConfigType, with_final_validate: bool = False +) -> None: + """Run schema validation on a configuration. + + Args: + config: The configuration to validate + with_final_validate: If True, also run final validation (requires full config setup) + """ + result = CONFIG_SCHEMA(config) + if with_final_validate: + FINAL_VALIDATE_SCHEMA(result) + return result + + +@pytest.mark.parametrize( + ("config", "error_match"), + [ + pytest.param( + "a string", + "expected a dictionary", + id="invalid_string_config", + ), + pytest.param( + {"id": "display_id"}, + r"required key not provided @ data\['model'\]", + id="missing_model", + ), + pytest.param( + { + "id": "display_id", + "model": "ssd1677", + "dimensions": {"width": 200, "height": 200}, + }, + r"required key not provided @ data\['dc_pin'\]", + id="missing_dc_pin", + ), + ], +) +def test_basic_configuration_errors( + config: str | ConfigType, + error_match: str, + set_core_config: SetCoreConfigCallable, +) -> None: + """Test basic configuration validation errors""" + + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + with pytest.raises(cv.Invalid, match=error_match): + CONFIG_SCHEMA(config) + + +def test_all_predefined_models( + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """Test all predefined epaper models validate successfully with appropriate defaults.""" + + # Test all models, providing default values where necessary + for name, model in MODELS.items(): + # SEEED models are designed for ESP32-S3 hardware + if name in ("SEEED-EE04-MONO-4.26", "SEEED-RETERMINAL-E1002"): + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={ + KEY_BOARD: "esp32-s3-devkitc-1", + KEY_VARIANT: VARIANT_ESP32S3, + }, + ) + else: + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + # Configure SPI component which is required by epaper_spi + set_component_config("spi", {"id": "spi_bus", "clk_pin": 18, "mosi_pin": 19}) + + config = {"model": name} + + # Add ID field + config["id"] = "test_display" + + # Add required fields that don't have defaults + # Use safe GPIO pins that work on ESP32 (avoiding flash pins 6-11) + if not model.get_default(CONF_DC_PIN): + config[CONF_DC_PIN] = 21 + + # Add dimensions if not provided by model + if not model.get_default(CONF_WIDTH): + config[CONF_DIMENSIONS] = {CONF_HEIGHT: 240, CONF_WIDTH: 320} + + # Add init sequence if model doesn't provide one + if model.initsequence is None: + config[CONF_INIT_SEQUENCE] = [[0xA0, 0x01]] + + # Add other optional pins that some models might require + if not model.get_default(CONF_BUSY_PIN): + config[CONF_BUSY_PIN] = 22 + + if not model.get_default(CONF_RESET_PIN): + config[CONF_RESET_PIN] = 23 + + if not model.get_default(CONF_CS_PIN): + config[CONF_CS_PIN] = 5 + + run_schema_validation(config) + + +@pytest.mark.parametrize( + "model_name", + [pytest.param(name, id=name.lower()) for name in sorted(MODELS.keys())], +) +def test_individual_models( + model_name: str, + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """Test each epaper model individually to ensure it validates correctly.""" + # SEEED models are designed for ESP32-S3 hardware + if model_name in ("SEEED-EE04-MONO-4.26", "SEEED-RETERMINAL-E1002"): + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={ + KEY_BOARD: "esp32-s3-devkitc-1", + KEY_VARIANT: VARIANT_ESP32S3, + }, + ) + else: + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + # Configure SPI component which is required by epaper_spi + set_component_config("spi", {"id": "spi_bus", "clk_pin": 18, "mosi_pin": 19}) + + model = MODELS[model_name] + config: dict[str, Any] = {"model": model_name, "id": "test_display"} + + # Add required fields based on model defaults + # Use safe GPIO pins that work on ESP32 + if not model.get_default(CONF_DC_PIN): + config[CONF_DC_PIN] = 21 + + if not model.get_default(CONF_WIDTH): + config[CONF_DIMENSIONS] = {CONF_HEIGHT: 240, CONF_WIDTH: 320} + + if model.initsequence is None: + config[CONF_INIT_SEQUENCE] = [[0xA0, 0x01]] + + if not model.get_default(CONF_BUSY_PIN): + config[CONF_BUSY_PIN] = 22 + + if not model.get_default(CONF_RESET_PIN): + config[CONF_RESET_PIN] = 23 + + if not model.get_default(CONF_CS_PIN): + config[CONF_CS_PIN] = 5 + + # This should not raise any exceptions + run_schema_validation(config) + + +def test_model_with_explicit_dimensions( + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """Test model configuration with explicitly provided dimensions.""" + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + # Configure SPI component which is required by epaper_spi + set_component_config("spi", {"id": "spi_bus", "clk_pin": 18, "mosi_pin": 19}) + + run_schema_validation( + { + "id": "test_display", + "model": "ssd1677", + "dc_pin": 21, + "busy_pin": 22, + "reset_pin": 23, + "cs_pin": 5, + "dimensions": { + "width": 200, + "height": 200, + }, + } + ) + + +def test_model_with_transform( + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """Test model configuration with transform options.""" + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + # Configure SPI component which is required by epaper_spi + set_component_config("spi", {"id": "spi_bus", "clk_pin": 18, "mosi_pin": 19}) + + run_schema_validation( + { + "id": "test_display", + "model": "ssd1677", + "dc_pin": 21, + "busy_pin": 22, + "reset_pin": 23, + "cs_pin": 5, + "dimensions": { + "width": 200, + "height": 200, + }, + "transform": { + "mirror_x": True, + "mirror_y": False, + }, + } + ) + + +def test_model_with_full_update_every( + set_core_config: SetCoreConfigCallable, + set_component_config: Callable[[str, Any], None], +) -> None: + """Test model configuration with full_update_every option.""" + set_core_config( + PlatformFramework.ESP32_IDF, + platform_data={KEY_BOARD: "esp32dev", KEY_VARIANT: VARIANT_ESP32}, + ) + + # Configure SPI component which is required by epaper_spi + set_component_config("spi", {"id": "spi_bus", "clk_pin": 18, "mosi_pin": 19}) + + run_schema_validation( + { + "id": "test_display", + "model": "ssd1677", + "dc_pin": 21, + "busy_pin": 22, + "reset_pin": 23, + "cs_pin": 5, + "dimensions": { + "width": 200, + "height": 200, + }, + "full_update_every": 10, + } + ) diff --git a/tests/components/epaper_spi/test.esp32-s3-idf.yaml b/tests/components/epaper_spi/test.esp32-s3-idf.yaml index d330b4127d..621a819c3c 100644 --- a/tests/components/epaper_spi/test.esp32-s3-idf.yaml +++ b/tests/components/epaper_spi/test.esp32-s3-idf.yaml @@ -8,15 +8,39 @@ display: dimensions: width: 800 height: 480 - cs_pin: GPIO5 - dc_pin: GPIO17 - reset_pin: GPIO16 - busy_pin: GPIO4 + cs_pin: + allow_other_uses: true + number: GPIO5 + dc_pin: + allow_other_uses: true + number: GPIO17 + reset_pin: + allow_other_uses: true + number: GPIO16 + busy_pin: + allow_other_uses: true + number: GPIO4 rotation: 0 update_interval: 60s lambda: |- it.circle(64, 64, 50, Color::BLACK); + - platform: epaper_spi + spi_id: spi_bus + model: waveshare-2.13in-v3 + cs_pin: + allow_other_uses: true + number: GPIO5 + dc_pin: + allow_other_uses: true + number: GPIO17 + reset_pin: + allow_other_uses: true + number: GPIO16 + busy_pin: + allow_other_uses: true + number: GPIO4 + - platform: epaper_spi model: seeed-reterminal-e1002 - platform: epaper_spi diff --git a/tests/components/libretiny/test.ln882x-ard.yaml b/tests/components/libretiny/test.ln882x-ard.yaml new file mode 100644 index 0000000000..fa33431b92 --- /dev/null +++ b/tests/components/libretiny/test.ln882x-ard.yaml @@ -0,0 +1,2 @@ +logger: + level: VERBOSE diff --git a/tests/components/libretiny/test.rtl87xx-ard.yaml b/tests/components/libretiny/test.rtl87xx-ard.yaml new file mode 100644 index 0000000000..fa33431b92 --- /dev/null +++ b/tests/components/libretiny/test.rtl87xx-ard.yaml @@ -0,0 +1,2 @@ +logger: + level: VERBOSE diff --git a/tests/components/zigbee/common.yaml b/tests/components/zigbee/common.yaml index c91569bdbe..11100e1e0c 100644 --- a/tests/components/zigbee/common.yaml +++ b/tests/components/zigbee/common.yaml @@ -11,9 +11,7 @@ binary_sensor: - platform: template name: "Garage Door Open 5" - platform: template - name: "Garage Door Open 6" - - platform: template - name: "Garage Door Open 7" + name: "Garage Door Internal" internal: True sensor: @@ -36,3 +34,8 @@ output: type: binary write_action: - zigbee.factory_reset + +switch: + - platform: template + name: "Template Switch" + optimistic: true