From b97825d552a5a55497b0b2baa0e38c6e5ff8620d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 14 Nov 2023 22:30:13 +0100 Subject: [PATCH 01/19] [boards] Add T112_V1.1 board, change scaling of small boards --- boards/_base/pcb/cb1s-test.json | 2 +- boards/_base/pcb/cb2l-test.json | 1 - boards/_base/pcb/cb2s-test.json | 1 - boards/_base/pcb/t102.json | 3 +- boards/_base/pcb/t112.json | 70 ++++++++++++++++ boards/_base/pcb/wa2.json | 2 +- boards/_base/pcb/wb2l-test.json | 1 - boards/_base/pcb/wb2s.json | 1 - boards/_base/pcb/wb3l.json | 2 +- boards/_base/pcb/wr2.json | 4 +- boards/_base/pcb/wr2e.json | 4 +- boards/_base/pcb/wr3n.json | 2 +- boards/t112-v1.1.json | 21 +++++ boards/templates/tuya2.json | 2 +- boards/templates/tuya2l.json | 2 +- boards/templates/tuyau.json | 2 +- boards/variants/t112-v1.1.c | 48 +++++++++++ boards/variants/t112-v1.1.h | 138 ++++++++++++++++++++++++++++++++ 18 files changed, 290 insertions(+), 16 deletions(-) create mode 100644 boards/_base/pcb/t112.json create mode 100644 boards/t112-v1.1.json create mode 100644 boards/variants/t112-v1.1.c create mode 100644 boards/variants/t112-v1.1.h diff --git a/boards/_base/pcb/cb1s-test.json b/boards/_base/pcb/cb1s-test.json index d7b3f9906..05e534208 100644 --- a/boards/_base/pcb/cb1s-test.json +++ b/boards/_base/pcb/cb1s-test.json @@ -1,6 +1,6 @@ { "pcb": { - "scale": 10, + "scale": 14, "test_pads": { "TSCK": "cb1s.back.sck.anchor", "TCSN": "cb1s.back.csn.anchor", diff --git a/boards/_base/pcb/cb2l-test.json b/boards/_base/pcb/cb2l-test.json index 160fcc0d7..4148cf484 100644 --- a/boards/_base/pcb/cb2l-test.json +++ b/boards/_base/pcb/cb2l-test.json @@ -1,6 +1,5 @@ { "pcb": { - "scale": 11, "test_pads": { "TRST": "cb2l.back.rst.anchor", "TRX1": "cb2l.back.u1_rxd.anchor", diff --git a/boards/_base/pcb/cb2s-test.json b/boards/_base/pcb/cb2s-test.json index 321b98080..d22bef664 100644 --- a/boards/_base/pcb/cb2s-test.json +++ b/boards/_base/pcb/cb2s-test.json @@ -1,6 +1,5 @@ { "pcb": { - "scale": 11, "test_pads": { "TTX2": "cb2s.back.u2_txd.anchor", "TRX2": "cb2s.back.u2_rxd.anchor", diff --git a/boards/_base/pcb/t102.json b/boards/_base/pcb/t102.json index b331806dd..58a86ac85 100644 --- a/boards/_base/pcb/t102.json +++ b/boards/_base/pcb/t102.json @@ -6,7 +6,8 @@ "rf-type1" ], "scale": 10.5, - "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI", + "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD", + "drawing_hidden": "SPI", "pinout": { "1": { "PWR": 3.3 diff --git a/boards/_base/pcb/t112.json b/boards/_base/pcb/t112.json new file mode 100644 index 000000000..0bcb3a1ba --- /dev/null +++ b/boards/_base/pcb/t112.json @@ -0,0 +1,70 @@ +{ + "pcb": { + "templates": [ + "esp01m-14", + "pcb-blue-light", + "rf-type1" + ], + "scale": 10.5, + "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD", + "drawing_hidden": "I2C,SPI", + "pinout": { + "1": { + "PWR": 3.3 + }, + "2": { + "IC": 2, + "ARD": "D0" + }, + "3": { + "IC": 30, + "ARD": [ + "D1", + "A0" + ] + }, + "4": { + "IC": 14, + "ARD": "D2" + }, + "5": { + "IC": 13, + "ARD": "D3" + }, + "6": { + "IC": 16, + "ARD": "D4" + }, + "7": { + "NC": null + }, + "8": { + "IC": 28, + "ARD": "D5" + }, + "9": { + "IC": 29, + "ARD": "D6" + }, + "10": { + "IC": 17, + "ARD": "D7" + }, + "11": { + "IC": 32, + "ARD": "D8" + }, + "12": { + "IC": 31, + "ARD": "D9" + }, + "13": { + "IC": 1, + "ARD": "D10" + }, + "14": { + "GND": null + } + } + } +} diff --git a/boards/_base/pcb/wa2.json b/boards/_base/pcb/wa2.json index 181cb80f1..55e1fe7d5 100644 --- a/boards/_base/pcb/wa2.json +++ b/boards/_base/pcb/wa2.json @@ -1,6 +1,6 @@ { "pcb": { - "scale": 10.5, + "scale": 11, "templates": [ "tuya2", "pcb-blue-light", diff --git a/boards/_base/pcb/wb2l-test.json b/boards/_base/pcb/wb2l-test.json index cffdc3f06..265cc9539 100644 --- a/boards/_base/pcb/wb2l-test.json +++ b/boards/_base/pcb/wb2l-test.json @@ -1,6 +1,5 @@ { "pcb": { - "scale": 11, "test_pads": { "TRST": "wb2l.back.rst.anchor", "TRX1": "wb2l.back.u1_rxd.anchor", diff --git a/boards/_base/pcb/wb2s.json b/boards/_base/pcb/wb2s.json index 45d1a7453..a47d327a8 100644 --- a/boards/_base/pcb/wb2s.json +++ b/boards/_base/pcb/wb2s.json @@ -1,6 +1,5 @@ { "pcb": { - "scale": 10.5, "templates": [ "tuya2", "pcb-blue-light", diff --git a/boards/_base/pcb/wb3l.json b/boards/_base/pcb/wb3l.json index 85e197b63..75247f5a0 100644 --- a/boards/_base/pcb/wb3l.json +++ b/boards/_base/pcb/wb3l.json @@ -9,7 +9,7 @@ "vars": { "PINHOLE": 0 }, - "pinout_hidden": "I2S,SD,SPI", + "pinout_hidden": "I2S,SD", "pinout": { "1": { "NC": null diff --git a/boards/_base/pcb/wr2.json b/boards/_base/pcb/wr2.json index ccb957fa7..2988706eb 100644 --- a/boards/_base/pcb/wr2.json +++ b/boards/_base/pcb/wr2.json @@ -1,7 +1,7 @@ { "pcb": { - "scale": 10.5, - "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI", + "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD", + "drawing_hidden": "SPI", "pinout": { "1": { "PWR": 3.3 diff --git a/boards/_base/pcb/wr2e.json b/boards/_base/pcb/wr2e.json index 44f380de2..91316d5a7 100644 --- a/boards/_base/pcb/wr2e.json +++ b/boards/_base/pcb/wr2e.json @@ -1,7 +1,7 @@ { "pcb": { - "scale": 10.5, - "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,SDA0", + "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SDA0", + "drawing_hidden": "SPI", "pinout": { "1": { "PWR": 3.3 diff --git a/boards/_base/pcb/wr3n.json b/boards/_base/pcb/wr3n.json index d93d90878..6686f1b1b 100644 --- a/boards/_base/pcb/wr3n.json +++ b/boards/_base/pcb/wr3n.json @@ -3,7 +3,7 @@ "templates": [ "pcb-black" ], - "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI", + "pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD", "pinout": { "1": { "NC": null diff --git a/boards/t112-v1.1.json b/boards/t112-v1.1.json new file mode 100644 index 000000000..548be1dd3 --- /dev/null +++ b/boards/t112-v1.1.json @@ -0,0 +1,21 @@ +{ + "_base": [ + "realtek-ambz", + "realtek-ambz-2mb-788k", + "ic/rtl8710bn", + "pcb/t112" + ], + "build": { + "mcu": "rtl8710bn", + "variant": "t112-v1.1" + }, + "name": "T112_V1.1", + "url": "https://docs.libretiny.eu/boards/t112-v1.1/", + "vendor": "Unknown", + "doc": { + "fccid": "2AU7O-T102V11" + }, + "pcb": { + "symbol": "T112_V1.1" + } +} diff --git a/boards/templates/tuya2.json b/boards/templates/tuya2.json index ca2f0e705..e7f11a76f 100644 --- a/boards/templates/tuya2.json +++ b/boards/templates/tuya2.json @@ -37,7 +37,7 @@ }, { "type": "text", - "pos": "7.0,5.0", + "pos": "6.0,5.5", "text": "${SYMBOL}", "font_size": 1.0, "fill": { diff --git a/boards/templates/tuya2l.json b/boards/templates/tuya2l.json index c99134239..8098c9301 100644 --- a/boards/templates/tuya2l.json +++ b/boards/templates/tuya2l.json @@ -39,7 +39,7 @@ }, { "type": "text", - "pos": "4.0,5.5", + "pos": "6.0,5.5", "text": "${SYMBOL}", "font_size": 1.0, "fill": { diff --git a/boards/templates/tuyau.json b/boards/templates/tuyau.json index 5ee814e60..7fe5aec89 100644 --- a/boards/templates/tuyau.json +++ b/boards/templates/tuyau.json @@ -79,7 +79,7 @@ }, { "type": "text", - "pos": "4.0,5.5", + "pos": "6.5,5.0", "text": "${SYMBOL}", "font_size": 1.0, "fill": { diff --git a/boards/variants/t112-v1.1.c b/boards/variants/t112-v1.1.c new file mode 100644 index 000000000..03dda234e --- /dev/null +++ b/boards/variants/t112-v1.1.c @@ -0,0 +1,48 @@ +/* This file was auto-generated from t112-v1.1.json using boardgen */ + +#include + +#ifdef LT_VARIANT_INCLUDE +#include LT_VARIANT_INCLUDE +#endif + +// clang-format off +PinInfo lt_arduino_pin_info_list[PINS_COUNT] = { + // D0: PA29, UART2_RX, I2C0_SCL, PWM4 + {PA_29, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0}, + // D1: PA19, ADC1, UART0_CTS, SPI0_CS, SPI1_CS, I2C0_SDA, SD_D3, TMR5_TRIG, I2S0_TX + {PA_19, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0}, + // D2: PA15, PWM1, SWDIO + {PA_15, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0}, + // D3: PA14, PWM0, SWCLK + {PA_14, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0}, + // D4: PA00, PWM2 + {PA_0, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0}, + // D5: PA05, PWM4, WAKE1 + {PA_5, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0}, + // D6: PA18, UART0_RX, SPI0_SCK, SPI1_SCK, I2C1_SCL, SD_D2, TMR4_TRIG, I2S0_MCK, WAKE0 + {PA_18, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0}, + // D7: PA12, PWM3 + {PA_12, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0}, + // D8: PA23, UART0_TX, SPI0_MOSI, SPI1_MOSI, I2C1_SDA, SD_D1, PWM0, WAKE3 + {PA_23, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_SPI | PIN_UART, PIN_NONE, 0}, + // D9: PA22, UART0_RTS, SPI0_MISO, SPI1_MISO, I2C0_SCL, SD_D0, PWM5, I2S0_WS, WAKE2 + {PA_22, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0}, + // D10: PA30, UART2_TX, I2C0_SDA, PWM4 + {PA_30, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0}, +}; + +PinInfo *lt_arduino_pin_gpio_map[] = { + [0] = &(lt_arduino_pin_info_list[4]), // PA_0 (D4) + [5] = &(lt_arduino_pin_info_list[5]), // PA_5 (D5) + [12] = &(lt_arduino_pin_info_list[7]), // PA_12 (D7) + [14] = &(lt_arduino_pin_info_list[3]), // PA_14 (D3) + [15] = &(lt_arduino_pin_info_list[2]), // PA_15 (D2) + [18] = &(lt_arduino_pin_info_list[6]), // PA_18 (D6) + [19] = &(lt_arduino_pin_info_list[1]), // PA_19 (D1) + [22] = &(lt_arduino_pin_info_list[9]), // PA_22 (D9) + [23] = &(lt_arduino_pin_info_list[8]), // PA_23 (D8) + [29] = &(lt_arduino_pin_info_list[0]), // PA_29 (D0) + [30] = &(lt_arduino_pin_info_list[10]), // PA_30 (D10) +}; +// clang-format on diff --git a/boards/variants/t112-v1.1.h b/boards/variants/t112-v1.1.h new file mode 100644 index 000000000..30b548d2c --- /dev/null +++ b/boards/variants/t112-v1.1.h @@ -0,0 +1,138 @@ +/* This file was auto-generated from t112-v1.1.json using boardgen */ + +#pragma once + +// clang-format off + +// Pins +// ---- +#define PINS_COUNT 11 // Total GPIO count +#define NUM_DIGITAL_PINS 11 // Digital inputs/outputs +#define NUM_ANALOG_INPUTS 1 // ADC inputs +#define NUM_ANALOG_OUTPUTS 9 // PWM & DAC outputs +#define PINS_GPIO_MAX 30 // Last usable GPIO number + +// SPI Interfaces +// -------------- +#define PIN_SPI0_CS 19u // PA_19 +#define PIN_SPI0_MISO 22u // PA_22 +#define PIN_SPI0_MOSI 23u // PA_23 +#define PIN_SPI0_SCK 18u // PA_18 +#define PIN_SPI1_CS 19u // PA_19 +#define PIN_SPI1_MISO 22u // PA_22 +#define PIN_SPI1_MOSI 23u // PA_23 +#define PIN_SPI1_SCK 18u // PA_18 +#define PINS_SPI0_CS (pin_size_t[]){19u} +#define PINS_SPI0_MISO (pin_size_t[]){22u} +#define PINS_SPI0_MOSI (pin_size_t[]){23u} +#define PINS_SPI0_SCK (pin_size_t[]){18u} +#define PINS_SPI1_CS (pin_size_t[]){19u} +#define PINS_SPI1_MISO (pin_size_t[]){22u} +#define PINS_SPI1_MOSI (pin_size_t[]){23u} +#define PINS_SPI1_SCK (pin_size_t[]){18u} + +// Wire Interfaces +// --------------- +#define PIN_WIRE0_SCL_0 29u // PA_29 +#define PIN_WIRE0_SCL_1 22u // PA_22 +#define PIN_WIRE0_SDA_0 19u // PA_19 +#define PIN_WIRE0_SDA_1 30u // PA_30 +#define PIN_WIRE1_SCL 18u // PA_18 +#define PIN_WIRE1_SDA 23u // PA_23 +#define PINS_WIRE0_SCL (pin_size_t[]){29u, 22u} +#define PINS_WIRE0_SDA (pin_size_t[]){19u, 30u} +#define PINS_WIRE1_SCL (pin_size_t[]){18u} +#define PINS_WIRE1_SDA (pin_size_t[]){23u} + +// Serial ports +// ------------ +#define PIN_SERIAL0_CTS 19u // PA_19 +#define PIN_SERIAL0_RTS 22u // PA_22 +#define PIN_SERIAL0_RX 18u // PA_18 +#define PIN_SERIAL0_TX 23u // PA_23 +#define PIN_SERIAL2_RX 29u // PA_29 +#define PIN_SERIAL2_TX 30u // PA_30 +#define PINS_SERIAL0_CTS (pin_size_t[]){19u} +#define PINS_SERIAL0_RTS (pin_size_t[]){22u} +#define PINS_SERIAL0_RX (pin_size_t[]){18u} +#define PINS_SERIAL0_TX (pin_size_t[]){23u} +#define PINS_SERIAL2_RX (pin_size_t[]){29u} +#define PINS_SERIAL2_TX (pin_size_t[]){30u} + +// Pin function macros +// ------------------- +#define PIN_ADC1 19u // PA_19 +#define PIN_CS0 19u // PA_19 +#define PIN_CS1 19u // PA_19 +#define PIN_CTS0 19u // PA_19 +#define PIN_MISO0 22u // PA_22 +#define PIN_MISO1 22u // PA_22 +#define PIN_MOSI0 23u // PA_23 +#define PIN_MOSI1 23u // PA_23 +#define PIN_PA00 0u // PA_0 +#define PIN_PA05 5u // PA_5 +#define PIN_PA12 12u // PA_12 +#define PIN_PA14 14u // PA_14 +#define PIN_PA15 15u // PA_15 +#define PIN_PA18 18u // PA_18 +#define PIN_PA19 19u // PA_19 +#define PIN_PA22 22u // PA_22 +#define PIN_PA23 23u // PA_23 +#define PIN_PA29 29u // PA_29 +#define PIN_PA30 30u // PA_30 +#define PIN_PWM1 15u // PA_15 +#define PIN_PWM2 0u // PA_0 +#define PIN_PWM3 12u // PA_12 +#define PIN_PWM4 30u // PA_30 +#define PIN_PWM5 22u // PA_22 +#define PIN_RTS0 22u // PA_22 +#define PIN_RX0 18u // PA_18 +#define PIN_RX2 29u // PA_29 +#define PIN_SCK0 18u // PA_18 +#define PIN_SCK1 18u // PA_18 +#define PIN_SCL1 18u // PA_18 +#define PIN_SDA1 23u // PA_23 +#define PIN_TX0 23u // PA_23 +#define PIN_TX2 30u // PA_30 + +// Port availability +// ----------------- +#define HAS_SERIAL0 1 +#define HAS_SERIAL2 1 +#define HAS_SPI0 1 +#define HAS_SPI1 1 +#define HAS_WIRE0 1 +#define HAS_WIRE1 1 +#define SERIAL_INTERFACES_COUNT 2 +#define SPI_INTERFACES_COUNT 2 +#define WIRE_INTERFACES_COUNT 2 + +// Arduino pin names +// ----------------- +#define PIN_D0 29u // PA_29 +#define PIN_D1 19u // PA_19 +#define PIN_D2 15u // PA_15 +#define PIN_D3 14u // PA_14 +#define PIN_D4 0u // PA_0 +#define PIN_D5 5u // PA_5 +#define PIN_D6 18u // PA_18 +#define PIN_D7 12u // PA_12 +#define PIN_D8 23u // PA_23 +#define PIN_D9 22u // PA_22 +#define PIN_D10 30u // PA_30 +#define PIN_A0 19u // PA_19 + +// Static pin names +// ---------------- +static const unsigned char A0 = PIN_A0; +static const unsigned char D0 = PIN_D0; +static const unsigned char D1 = PIN_D1; +static const unsigned char D2 = PIN_D2; +static const unsigned char D3 = PIN_D3; +static const unsigned char D4 = PIN_D4; +static const unsigned char D5 = PIN_D5; +static const unsigned char D6 = PIN_D6; +static const unsigned char D7 = PIN_D7; +static const unsigned char D8 = PIN_D8; +static const unsigned char D9 = PIN_D9; +static const unsigned char D10 = PIN_D10; From 9b8e00c7fa895888580bb8eb05b85d780b6a9b6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 14 Nov 2023 22:34:07 +0100 Subject: [PATCH 02/19] [boards] Support and validate MCU name aliases --- .github/workflows/push-master.yml | 2 +- boards/t102-v1.1.json | 3 +- boards/t112-v1.1.json | 3 +- docs/scripts/write_boards.py | 67 ++++++++++++++++++++++++------- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/.github/workflows/push-master.yml b/.github/workflows/push-master.yml index a887ba4a1..f7fc1f768 100644 --- a/.github/workflows/push-master.yml +++ b/.github/workflows/push-master.yml @@ -17,7 +17,7 @@ jobs: python-version: '3.10' - name: Install docs dependencies - run: pip install -U ltchiptool boardgen + run: pip install -U ltchiptool "boardgen>=0.11.0" - name: Generate docs and static JSON files run: | diff --git a/boards/t102-v1.1.json b/boards/t102-v1.1.json index b18d55c61..7bb0daf51 100644 --- a/boards/t102-v1.1.json +++ b/boards/t102-v1.1.json @@ -13,7 +13,8 @@ "url": "https://docs.libretiny.eu/boards/t102-v1.1/", "vendor": "Unknown", "doc": { - "fccid": "2AU7O-T102V11" + "fccid": "2AU7O-T102V11", + "mcu": "w302" }, "pcb": { "symbol": "T102_V1.1" diff --git a/boards/t112-v1.1.json b/boards/t112-v1.1.json index 548be1dd3..2d43fe4dd 100644 --- a/boards/t112-v1.1.json +++ b/boards/t112-v1.1.json @@ -13,7 +13,8 @@ "url": "https://docs.libretiny.eu/boards/t112-v1.1/", "vendor": "Unknown", "doc": { - "fccid": "2AU7O-T102V11" + "fccid": "2AU7O-T102V11", + "mcu": "w302" }, "pcb": { "symbol": "T112_V1.1" diff --git a/docs/scripts/write_boards.py b/docs/scripts/write_boards.py index 27f25297c..e40833308 100644 --- a/docs/scripts/write_boards.py +++ b/docs/scripts/write_boards.py @@ -1,5 +1,11 @@ # Copyright (c) Kuba Szczodrzyński 2022-05-31. +import os +import sys + +while os.getcwd() in sys.path: + sys.path.remove(os.getcwd()) + import re from os.path import dirname, isfile, join @@ -48,19 +54,41 @@ def get_families_json() -> dict[str, int]: } -def get_mcus_boards(boards: list[Board]) -> dict[str, str]: +def get_mcus_boards(boards: list[Board], aliases: dict[str, str]) -> dict[str, str]: out = {} - for board in boards: - mcu_name: str = board["build.mcu"].upper() - family_name: str = board.family.short_name + + def check_mcu(mcu_name, family_name): if mcu_name in out and out[mcu_name] != family_name: print( Fore.RED + f"ERROR: MCU '{mcu_name}' of board '{board.name}' belongs to multiple families: '{out[mcu_name]}' and '{family_name}'" - + Style.RESET_ALL + + Style.RESET_ALL, + file=sys.stderr, ) - continue out[mcu_name] = family_name + + for board in boards: + mcu_name: str = board["build.mcu"].upper() + mcu_alias: str = board["doc.mcu"] + family_name: str = board.family.short_name + check_mcu(mcu_name, family_name) + if mcu_alias: + mcu_alias = mcu_alias.upper() + check_mcu(mcu_alias, family_name) + if mcu_alias not in aliases: + print( + Fore.RED + + f"ERROR: MCU alias '{mcu_alias}' of board '{board.name}' is not defined in enum" + + Style.RESET_ALL, + file=sys.stderr, + ) + elif aliases[mcu_alias] != mcu_name: + print( + Fore.RED + + f"ERROR: MCU alias '{mcu_alias}' of board '{board.name}' doesn't match real name '{mcu_name}'" + + Style.RESET_ALL, + file=sys.stderr, + ) return out @@ -315,7 +343,8 @@ def write_boards_list(boards: list[Board]): print( Fore.RED + f"ERROR: Invalid build.variant of '{board['source']}': '{board.name}'" - + Style.RESET_ALL + + Style.RESET_ALL, + file=sys.stderr, ) errors = True @@ -323,8 +352,8 @@ def write_boards_list(boards: list[Board]): families_enum = get_families_enum(code) families_json_keys = set(families_json.keys()) families_enum_keys = set(families_enum.keys()) - mcus_boards = get_mcus_boards(boards) mcus_enum, mcu_aliases = get_mcus_enum(code) + mcus_boards = get_mcus_boards(boards, mcu_aliases) mcus_boards_keys = set(mcus_boards.keys()) mcus_enum_keys = set(mcus_enum.keys()) mcus_missing_in_boards = mcus_enum_keys - mcus_boards_keys @@ -332,14 +361,19 @@ def write_boards_list(boards: list[Board]): # check if all families are defined in lt_types.h and families.json if families_json_keys != families_enum_keys: - print(Fore.RED + f"ERROR: Inconsistent lt_types.h vs families.json:") print( - "- Missing in JSON: " + ", ".join(families_enum_keys - families_json_keys) + Fore.RED + f"ERROR: Inconsistent lt_types.h vs families.json:", + file=sys.stderr, ) print( - "- Missing in enum: " + ", ".join(families_json_keys - families_enum_keys) + "- Missing in JSON: " + ", ".join(families_enum_keys - families_json_keys), + file=sys.stderr, ) - print(Style.RESET_ALL, end="") + print( + "- Missing in enum: " + ", ".join(families_json_keys - families_enum_keys), + file=sys.stderr, + ) + print(Style.RESET_ALL, end="", file=sys.stderr) errors = True # verify that family IDs match @@ -352,7 +386,8 @@ def write_boards_list(boards: list[Board]): print( Fore.RED + f"ERROR: Family ID mismatch for '{family}': 0x{families_json[family]:08X} vs 0x{families_enum[family]:08X}" - + Style.RESET_ALL + + Style.RESET_ALL, + file=sys.stderr, ) errors = True @@ -371,7 +406,8 @@ def write_boards_list(boards: list[Board]): Fore.RED + f"ERROR: Undefined MCUs in lt_types.h: " + ", ".join(mcus_missing_in_enum) - + Style.RESET_ALL + + Style.RESET_ALL, + file=sys.stderr, ) errors = True @@ -385,7 +421,8 @@ def write_boards_list(boards: list[Board]): print( Fore.RED + f"ERROR: MCU family mismatch for '{mcu}': '{mcus_boards[mcu]}' vs '{mcus_enum[mcu]}'" - + Style.RESET_ALL + + Style.RESET_ALL, + file=sys.stderr, ) errors = True From bb7fcd5c4d13ca435c985fd97b4dd5a6acae908b Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Fri, 8 Dec 2023 19:13:15 +0100 Subject: [PATCH 03/19] [docs] Add more UPK key descriptions (#219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added description of some UPK keys * More keys described. This time by experimenting on my PIR-enabled lamp. Motion is reported correctly via GPIO defined as pirin_pin. I am also trying to set the PIR sensitivity by applying PWM to the pirsense_pin, and I _think_ it works. More experiments are needed. * Add UPK2ESPHome link, reformat table * Add descriptions from BK7231N SDK * Update docs/resources/tuya-pin-config.md * Corrected description of cwmaxp * Description of ambient light sensor values --------- Co-authored-by: Kuba Szczodrzyński --- docs/resources/tuya-pin-config.md | 107 +++++++++++++++++------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/docs/resources/tuya-pin-config.md b/docs/resources/tuya-pin-config.md index 86455e041..77c26ad20 100644 --- a/docs/resources/tuya-pin-config.md +++ b/docs/resources/tuya-pin-config.md @@ -2,14 +2,21 @@ Device configuration (`user_param_key`) can be extracted to JSON, using bk7231tools from a full firmware dump. -Originally posted [by @blakadder](https://discord.com/channels/967863521511608370/983843871320580096/1059286760074530947) on Discord channel #resources, modified by me to include more keys and values. +Also see: + +- [UPK2ESPHome](https://upk.libretiny.eu/) + +Sources: + +- [`tuya_demo_light_pwm`](https://github.com/tuya/tuya-iotos-embeded-sdk-wifi-ble-bk7231n/blob/master/apps/tuya_demo_light_pwm/include/common/device_config_load.h) for *Lights/bulbs* +- Original post [by @blakadder](https://discord.com/channels/967863521511608370/983843871320580096/1059286760074530947) on Discord channel #resources Key(s) | Meaning | Possible values ---------------------------------------------|---------------------------------------|--------------------------------------------------------- -`crc` | | -`module` | | -`category` | | -`Jsonver`
`jv` | | +--------------------------------------------|---------------------------------------|--------------------------------------------------------------------------------------- +`crc` | UPK data checksum | +`module` | Tuya module used | `CB3S` / `WB3S` / `CBU`, etc. +`category` | Device type as a number | 0502 - CW light
0505 - RGBCW light +`Jsonver`
`jv` | "JSON" version | **Common** | | `netled_pin`
`netled1_pin`
`wfst_pin` | Status LED for WiFi | `netled_lv`
`netled1_lv`
`wfst_lv` | Status LED Active Level | 0 - Active low
1 - Active high @@ -20,27 +27,30 @@ Key(s) | Meaning `iicsda` | I²C SDA Pin | `net_trig` | | `net_type` | | -`wfcfg` | | `spcl` / `spcl_auto` / `prod` `wfct` | | **Lights/bulbs** | | `cmod` | Color Mode | `rgbcw` / `rgb` / `cw` / `c` / `rgbc` -`cwtype` | | +`dmod` | Light driver type | 0 - PWM
1 - SM16726B
2 - SM2135E
3 - SM2135EH
4 - SM2135EJ
5 - BP1658CJ
6 - BP5758D
7 - SM2235/2335 +`cwtype` | Color temperature driver | 0 - cool and warm white (CW)
1 - correlated color temperature (CCT) +`onoffmode` | On/off gradient enabled | 0 / 1 +`pmemory` | Power-off memory enabled | 0 / 1 +`defcolor` | Default Color | `c` / `r` +`defbright` | Default Brightness | 0%-100% +`deftemp` | Default Color Temperature | 0-100 when defcolor is cool white +`cwmaxp` | Cold-Warm Max Power | 100-200 with a pitch of 10 `brightmin`, `brightmax` | Min/Max Brightness | 0%-100% -`cwmin`, `cwmax` | Cold-Warm Min/Max Brightness | 0%-100% -`cwmaxp` | Cold-Warm Max Power | 0%-100% `colormin`, `colormax` | RGB Min/Max Brightness | 0%-100% +`cwmin`, `cwmax` | Cold-Warm Min/Max Brightness | 0%-100% `colormaxp` | RGB Max Power | 0%-100% +`colorpfun` | Color mixing power limit enabled | 0 / 1 `brightstep`
`bristep` | Brightness Step | -`defbright` | Default Brightness | 0%-100% -`defcolor` | Default Color | `c` / `r` -`deftemp` | Default Color Temperature | +`hsvstep` | | +`rgbt` | Used in prod.tests, not relevant | +`title20` | "title20/T20" supported | 0 / 1 +**Gamma correction** | | +`gmr`, `gmg`, `gmb` | | `gmkr`, `gmkg`, `gmkb` | | `gmwr`, `gmwg`, `gmwb` | | -`hsvstep` | | -`rgbt` | | -`rstbr` | | -`rstcor` | | `c`/`r` -`rsttemp` | | **PWM Lights** | | `r_pin` + `r_lv` | Red Channel Pin + Active Level | `g_pin` + `g_lv` | Green Channel Pin + Active Level | @@ -52,8 +62,8 @@ Key(s) | Meaning `dccur`
`ehccur`
`cjccur` | Cold White Current | `dwcur`
`ehwcur`
`cjwcur` | Warm White Current | `drgbcur` | RGB Current | -`campere` | | -`wampere` | | +`campere` | Max current of SM2135 colored output | 10-45 with a pitch of 5 and defaults to 20 +`wampere` | Max current of SM2135 white output | 10-80 with a pitch of 5 and defaults to 30 `iicr` | Red Channel Number | 0-5 `iicg` | Green Channel Number | 0-5 `iicb` | Blue Channel Number | 0-5 @@ -72,7 +82,7 @@ Key(s) | Meaning `rl_drvtime` | | `total_bt_pin` + `total_bt_lv` | | **Power monitoring** | | -`ele_fun_en` | Power Monitoring Enabled | 1 +`ele_fun_en` | Power Monitoring Enabled | 0 / 1 `chip_type` | Power Monitoring Chip Type | 0 - BL0937
1 - HLW8012
2 - HLW8032
4 - BL0942 `ele_pin` | CF Pin | `vi_pin` | CF1 Pin | @@ -84,7 +94,7 @@ Key(s) | Meaning `vol_def` | Socket operating voltage | 0 - 220V
1 - 110V `work_voltage` | Socket operating voltage | **Infrared** | | -`irfunc` | IR Function | 0, 1 +`irfunc` | IR Function enabled | 0 / 1 `infre` | IR Transmitter Pin | `infrr`
`ir` | IR Receiver Pin | `irkXfun` + `irkXval` | IR Key X Function + Value | X in 1..30 @@ -93,14 +103,20 @@ Key(s) | Meaning `wgmod`, `swgmod`, `scgmod` | | **PIR** | | `pirmod` | | -`pirfreq` | | -`pirlduty` | | -`pirmduty` | | -`pirhduty` | | -`pirin_pin` + `pirin_lv` | | -`pirsense_pin` + `pirsense_lv` | | +`pirfreq` | PWM Operating Frequency (Hz) for PIR | 1000 +`pirlduty` | | 100 +`pirmduty` | | 50 +`pirhduty` | | 0 +`pirin_pin` + `pirin_lv` | Motion reporting GPIO + Active Level | +`pirsense_pin` + `pirsense_lv` | PIR sensitivity (PWM) + Active Level | `pirrange` | | `pirwarn` | | +**Ambient light sensor** | | +`day` | Value to compare against ADC readout | ADC value range (0-3300) +`dusk` | Value to compare against ADC readout | ADC value range (0-3300) +`evenfall` | Value to compare against ADC readout | ADC value range (0-3300) +`evening` | Value to compare against ADC readout | ADC value range (0-3300) +`night` | Value to compare against ADC readout | ADC value range (0-3300) **Key-controlled** | | `key_pin` + `key_lv` | Key Pin + Active Level | `kXpin_pin` + `kXpin_lv` | | @@ -109,9 +125,23 @@ Key(s) | Meaning `keyccfg1`, `keyccfg2` | | `keyfunc`, `keyglobefunc` | | `keylt`, `keynumber` | | +**Pairing-related** | | +`wfcfg` | Wi-Fi pairing config | `spcl` / `spcl_auto` / `prod` / `old` / `low` +`remdmode` | "light reset pairing mode" | 0 / 1 +`rstnum` | On/off cycles to reset | +`rstcor` | Light color while connecting | `c` / `r` +`rstbr` | Light brightness while connecting | 10-100 +`rsttemp` | Light temperature while connecting | 0-100 +`remdtime` | Pairing mode timeout | seconds +`wfptime` | Light pairing time | minutes +`cagt` | Used in prod.tests, not relevant | N/A +`prodagain` | Used in prod.tests, not relevant | 0 / 1 +`rstmode` | Pairing related - not relevant | +`pairt` | Pairing related - not relevant | 6-600 +`wt` | Used in prod.tests, not relevant | N/A **Other** | | `buzzer_pwm` | Buzzer working PWM frequency | -`ismusic` | | 0, 1 +`ismusic` | | 0 / 1 `ledX_pin` + `ledX_lv` | LED X Pin + Active Level | `led_pin` + `led_lv` | LED Pin + Active Level | **Unknown** | | @@ -127,7 +157,6 @@ Key(s) | Meaning `bleonoff` | | `blindt` | | `buzzer` | | -`cagt` | | `cctseg` | | `cd_flag2` | | `cdsval` | | @@ -138,24 +167,18 @@ Key(s) | Meaning `ch_num` | | `clean_t` | | `cntdown1` | | -`colorpfun` | | `ctrl_lv` | | `ctrl_pin` | | `customcode` | | `cyc_dpid` | | -`day` | | `dctrl_select` | | `dimmod` | | `dimt` | | `dimval` | | -`dmod` | | `door1_magt_lv` | | `door1_magt_pin` | | `door_alarm_st1` | | `door_mag1` | | -`dusk` | | -`evenfall` | | -`evening` | | `ffc_select` | | `inch_dp` | | `indep_cfgbt` | | @@ -176,11 +199,10 @@ Key(s) | Meaning `netnc` | | `nety_led` | | `netyc` | | -`night` | | `nightbrig` | | `nightcct` | | `nightled` | | -`notdisturb` | | +`notdisturb` | Do not disturb (DND) mode enabled | 0 / 1 `on_off_cnt` | | `onoff1` | | `onoff_clear_t` | | @@ -188,23 +210,16 @@ Key(s) | Meaning `onoff_rst_m` | | `onoff_rst_type` | | `onoff_type` | | -`onoffmode` | | `onofftime` | | `owm` | | -`pairt` | | -`pmemory` | | `preheatt` | | -`prodagain` | | `rand_dpid` | | -`remdmode` | | `remote_add_dp` | | `remote_list_dp` | | `remote_select` | | `resistor` | | `reuse_led_m` | | `rsthold` | | -`rstmode` | | -`rstnum` | | `scenespct` | | `series_ctrl` | | `sfunc` | | @@ -214,7 +229,6 @@ Key(s) | Meaning `switch1` | | `tempmix` | | `tempstep` | | -`title20` | | `total_stat` | | `tracetime1` | | `trigdelay` | | @@ -223,5 +237,4 @@ Key(s) | Meaning `voice_ctrl1` | | `voice_ctrl_set1` | | `whiteseg` | | -`wt` | | `zero_select` | | From 7bd6d1d815f0544245a28e1b54f08776c4cdc4e3 Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Fri, 8 Dec 2023 19:20:41 +0100 Subject: [PATCH 04/19] [beken-72xx] Fix stopping PWM, use pin-scoped PWM struct (#215) * Fixed stopping PWM * Clang-formatted as required * Use separate memory block for each pwm pin --- cores/beken-72xx/arduino/src/wiring.c | 4 +-- cores/beken-72xx/arduino/src/wiring_analog.c | 35 ++++++++++---------- cores/beken-72xx/arduino/src/wiring_data.h | 2 +- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/cores/beken-72xx/arduino/src/wiring.c b/cores/beken-72xx/arduino/src/wiring.c index 97c9dc0fb..13bb2fa28 100644 --- a/cores/beken-72xx/arduino/src/wiring.c +++ b/cores/beken-72xx/arduino/src/wiring.c @@ -108,9 +108,9 @@ void pinRemoveMode(PinInfo *pin, uint32_t mask) { pinDisable(pin, PIN_IRQ); } if ((mask & PIN_PWM) && (pin->enabled & PIN_PWM)) { - data->pwm->cfg.bits.en = PWM_DISABLE; + data->pwm.cfg.bits.en = PWM_DISABLE; __wrap_bk_printf_disable(); - sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, data->pwm); + sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &data->pwm); __wrap_bk_printf_enable(); pinDisable(pin, PIN_PWM); } diff --git a/cores/beken-72xx/arduino/src/wiring_analog.c b/cores/beken-72xx/arduino/src/wiring_analog.c index 5808b996d..b63d21a4d 100644 --- a/cores/beken-72xx/arduino/src/wiring_analog.c +++ b/cores/beken-72xx/arduino/src/wiring_analog.c @@ -51,7 +51,6 @@ static uint8_t gpioToAdc(GPIO_INDEX gpio) { return 0; } -static pwm_param_t pwm; static uint16_t adcData[1]; uint16_t analogReadVoltage(pin_size_t pinNumber) { @@ -90,35 +89,35 @@ void analogWrite(pin_size_t pinNumber, int value) { float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1); uint32_t frequency = 26 * _analogWritePeriod - 1; uint32_t dutyCycle = percent * frequency; - pwm.channel = gpioToPwm(pin->gpio); + data->pwm.channel = gpioToPwm(pin->gpio); + uint32_t channel = data->pwm.channel; #if CFG_SOC_NAME != SOC_BK7231N - pwm.duty_cycle = dutyCycle; + data->pwm.duty_cycle = dutyCycle; #else - pwm.duty_cycle1 = dutyCycle; - pwm.duty_cycle2 = 0; - pwm.duty_cycle3 = 0; + data->pwm.duty_cycle1 = dutyCycle; + data->pwm.duty_cycle2 = 0; + data->pwm.duty_cycle3 = 0; #endif if (dutyCycle) { if (!pinEnabled(pin, PIN_PWM)) { // enable PWM and set its value - pwm.cfg.bits.en = PWM_ENABLE; - pwm.cfg.bits.int_en = PWM_INT_DIS; - pwm.cfg.bits.mode = PWM_PWM_MODE; - pwm.cfg.bits.clk = PWM_CLK_26M; - pwm.end_value = frequency; - pwm.p_Int_Handler = NULL; + data->pwm.cfg.bits.en = PWM_ENABLE; + data->pwm.cfg.bits.int_en = PWM_INT_DIS; + data->pwm.cfg.bits.mode = PWM_PWM_MODE; + data->pwm.cfg.bits.clk = PWM_CLK_26M; + data->pwm.end_value = frequency; + data->pwm.p_Int_Handler = NULL; __wrap_bk_printf_disable(); - sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, &pwm); - sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &pwm.channel); - sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &pwm.channel); + sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, &data->pwm); + sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &channel); + sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &channel); __wrap_bk_printf_enable(); - // pass global PWM object pointer - data->pwm = &pwm; pinEnable(pin, PIN_PWM); } else { + sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &channel); // update duty cycle - sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &pwm); + sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &data->pwm); } } else { if (pinEnabled(pin, PIN_PWM)) { diff --git a/cores/beken-72xx/arduino/src/wiring_data.h b/cores/beken-72xx/arduino/src/wiring_data.h index c6d521068..20ba3ccc3 100644 --- a/cores/beken-72xx/arduino/src/wiring_data.h +++ b/cores/beken-72xx/arduino/src/wiring_data.h @@ -10,7 +10,7 @@ extern "C" { #endif struct PinData_s { - pwm_param_t *pwm; + pwm_param_t pwm; PinMode gpioMode; PinStatus irqMode; void *irqHandler; From eed39c9cfb75e287bd1c4f746b54112144269939 Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Sat, 16 Dec 2023 13:57:47 +0100 Subject: [PATCH 05/19] [beken-72xx] Pause PWM instead of stopping, track PWM state (#222) * Pause PWM instead of stopping on duty cycle 0. * Merged paused and stopped conditions --- cores/beken-72xx/arduino/src/wiring.c | 11 ++-- cores/beken-72xx/arduino/src/wiring_analog.c | 53 ++++++++++++-------- cores/beken-72xx/arduino/src/wiring_data.h | 3 ++ 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/cores/beken-72xx/arduino/src/wiring.c b/cores/beken-72xx/arduino/src/wiring.c index 13bb2fa28..cc37e37ce 100644 --- a/cores/beken-72xx/arduino/src/wiring.c +++ b/cores/beken-72xx/arduino/src/wiring.c @@ -108,10 +108,13 @@ void pinRemoveMode(PinInfo *pin, uint32_t mask) { pinDisable(pin, PIN_IRQ); } if ((mask & PIN_PWM) && (pin->enabled & PIN_PWM)) { - data->pwm.cfg.bits.en = PWM_DISABLE; - __wrap_bk_printf_disable(); - sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &data->pwm); - __wrap_bk_printf_enable(); + if (data->pwmState != LT_PWM_STOPPED) { + data->pwmState = LT_PWM_STOPPED; + data->pwm.cfg.bits.en = PWM_DISABLE; + __wrap_bk_printf_disable(); + sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &data->pwm); + __wrap_bk_printf_enable(); + } pinDisable(pin, PIN_PWM); } } diff --git a/cores/beken-72xx/arduino/src/wiring_analog.c b/cores/beken-72xx/arduino/src/wiring_analog.c index b63d21a4d..76bbf2756 100644 --- a/cores/beken-72xx/arduino/src/wiring_analog.c +++ b/cores/beken-72xx/arduino/src/wiring_analog.c @@ -86,10 +86,22 @@ void analogWrite(pin_size_t pinNumber, int value) { // GPIO can't be used together with PWM pinRemoveMode(pin, PIN_GPIO | PIN_IRQ); - float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1); uint32_t frequency = 26 * _analogWritePeriod - 1; + + if (!pinEnabled(pin, PIN_PWM)) { + pinEnable(pin, PIN_PWM); + data->pwmState = LT_PWM_STOPPED; + data->pwm.channel = gpioToPwm(pin->gpio); + data->pwm.cfg.bits.en = PWM_ENABLE; + data->pwm.cfg.bits.int_en = PWM_INT_DIS; + data->pwm.cfg.bits.mode = PWM_PWM_MODE; + data->pwm.cfg.bits.clk = PWM_CLK_26M; + data->pwm.end_value = frequency; + data->pwm.p_Int_Handler = NULL; + } + + float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1); uint32_t dutyCycle = percent * frequency; - data->pwm.channel = gpioToPwm(pin->gpio); uint32_t channel = data->pwm.channel; #if CFG_SOC_NAME != SOC_BK7231N data->pwm.duty_cycle = dutyCycle; @@ -99,33 +111,32 @@ void analogWrite(pin_size_t pinNumber, int value) { data->pwm.duty_cycle3 = 0; #endif - if (dutyCycle) { - if (!pinEnabled(pin, PIN_PWM)) { + if ((data->pwmState == LT_PWM_STOPPED) || (data->pwmState == LT_PWM_PAUSED)) { + if (dutyCycle) { // enable PWM and set its value - data->pwm.cfg.bits.en = PWM_ENABLE; - data->pwm.cfg.bits.int_en = PWM_INT_DIS; - data->pwm.cfg.bits.mode = PWM_PWM_MODE; - data->pwm.cfg.bits.clk = PWM_CLK_26M; - data->pwm.end_value = frequency; - data->pwm.p_Int_Handler = NULL; + __wrap_bk_printf_disable(); sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_PARAM, &data->pwm); sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &channel); sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &channel); __wrap_bk_printf_enable(); - pinEnable(pin, PIN_PWM); - } else { + + data->pwmState = LT_PWM_RUNNING; + } + } else if (data->pwmState == LT_PWM_RUNNING) { + if (dutyCycle) { + __wrap_bk_printf_disable(); sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &channel); - // update duty cycle sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &data->pwm); + __wrap_bk_printf_enable(); + } else { + __wrap_bk_printf_disable(); + sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_LOW, &channel); + sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &data->pwm); + sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_DISABLE, &channel); + __wrap_bk_printf_enable(); + + data->pwmState = LT_PWM_PAUSED; } - } else { - if (pinEnabled(pin, PIN_PWM)) { - // disable PWM - pinRemoveMode(pin, PIN_PWM); - } - // force level as LOW - pinMode(pinNumber, OUTPUT); - digitalWrite(pinNumber, LOW); } } diff --git a/cores/beken-72xx/arduino/src/wiring_data.h b/cores/beken-72xx/arduino/src/wiring_data.h index 20ba3ccc3..461eb6220 100644 --- a/cores/beken-72xx/arduino/src/wiring_data.h +++ b/cores/beken-72xx/arduino/src/wiring_data.h @@ -9,8 +9,11 @@ extern "C" { #endif +typedef enum lt_pwm_state_tag { LT_PWM_STOPPED, LT_PWM_RUNNING, LT_PWM_PAUSED } lt_pwm_state_t; + struct PinData_s { pwm_param_t pwm; + lt_pwm_state_t pwmState; PinMode gpioMode; PinStatus irqMode; void *irqHandler; From bad2ffdd07d1e1df3a2004a088558034badb28bb Mon Sep 17 00:00:00 2001 From: Gerard Du Pre <37554513+GerardPolloRebozado@users.noreply.github.com> Date: Mon, 25 Dec 2023 19:42:53 +0100 Subject: [PATCH 06/19] [docs] Update docker compose image name (#225) The docs about using docker compose for libre tuya had an error. When setting what image to use in compose you dont have to put docker pull, just the image you are going to use --- docs/projects/esphome.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/projects/esphome.md b/docs/projects/esphome.md index 1c5364acb..1f0b78207 100644 --- a/docs/projects/esphome.md +++ b/docs/projects/esphome.md @@ -34,7 +34,7 @@ If your board isn't listed, use one of the **Generic** boards, depending on the services: esphome: container_name: esphome-libretiny - image: docker pull ghcr.io/libretiny-eu/libretiny-esphome-docker:latest + image: ghcr.io/libretiny-eu/libretiny-esphome-docker:latest volumes: - ./configs:/config:rw # (1)! - /etc/localtime:/etc/localtime:ro From 03c723c73d1903b176fbe4337a003c981b9543d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sat, 6 Jan 2024 19:20:03 +0100 Subject: [PATCH 07/19] [docs] Add draft Beken key extraction docs --- SUMMARY.md | 1 + docs/inc/flashing-note.md | 4 +++ docs/inc/uart-cen.md | 2 +- docs/platform/beken-72xx/README.md | 17 ++++++++-- docs/platform/beken-72xx/keys.md | 48 ++++++++++++++++++++++++++++ docs/platform/realtek-ambz/README.md | 14 +++++--- mkdocs.yml | 1 + 7 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 docs/inc/flashing-note.md create mode 100644 docs/platform/beken-72xx/keys.md diff --git a/SUMMARY.md b/SUMMARY.md index 6d8fbbbc8..a334256a9 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -14,6 +14,7 @@ * [](SUMMARY.md) * 🍪 Chip family docs & info * [Beken BK72xx](docs/platform/beken-72xx/README.md) + * [Finding encryption keys](docs/platform/beken-72xx/keys.md) * [Realtek Ameba - info](docs/platform/realtek-amb/README.md) * [Realtek AmebaZ](docs/platform/realtek-ambz/README.md) * [Debugging](docs/platform/realtek-ambz/debugging.md) diff --git a/docs/inc/flashing-note.md b/docs/inc/flashing-note.md new file mode 100644 index 000000000..4f23a8130 --- /dev/null +++ b/docs/inc/flashing-note.md @@ -0,0 +1,4 @@ +!!! danger "Read this!" + This is probably the most important part of the docs - flashing firmware to the chip. + + **This is why you're here**. Please read this section carefully, and only then start flashing firmware. diff --git a/docs/inc/uart-cen.md b/docs/inc/uart-cen.md index bebc400ed..48d94177a 100644 --- a/docs/inc/uart-cen.md +++ b/docs/inc/uart-cen.md @@ -1,4 +1,4 @@ -!!! note +!!! note inline end "CEN" pin is the RESET pin - connecting it to GND will keep the chip in "reset" state. Disconnecting it will allow the chip to start back up. If you're having issues with using CEN pin (or if it's not accessible on your device) you can toggle the 3.3V power instead. Removing power will keep it in "reset", and applying it back will start it again. diff --git a/docs/platform/beken-72xx/README.md b/docs/platform/beken-72xx/README.md index faac57886..8ff952efe 100644 --- a/docs/platform/beken-72xx/README.md +++ b/docs/platform/beken-72xx/README.md @@ -2,6 +2,9 @@ ## Introduction +!!! note inline end "Also read" + - [Finding encryption keys](keys.md) - what to do if LibreTiny doesn't boot because of incorrect flash encryption keys + Beken BK7231 is a family of Wi-Fi and BLE microcontrollers, of which most popular are BK7231N and BK7231T. Features: @@ -28,8 +31,14 @@ Resources: include-markdown "../../inc/find-board.md" %} +--- + ## Flashing +{% + include-markdown "../../inc/flashing-note.md" +%} + BK7231 has two UART ports - UART2 (sometimes called LOG_UART) and UART1. The UART1 port is used for flashing (and external components, such as TuyaMCU) and has no text output. The UART2 port is used for log viewing only. You need to find which pins correspond to UART1 TX and RX. If your board is supported, you'll find the pinout on its documentation page. Otherwise (and for generic boards), you'll have to find the pinout online. @@ -53,12 +62,12 @@ GND | GND include-markdown "../../inc/uart-power.md" %} -The download mode is entered when the chip communicates with the flasher program. Hence, the first step is running the flasher program (described below). While the program is trying to establish communication, **the chip has to be rebooted**. In order to do that, you need to bridge CEN pin to GND with a wire. - {% include-markdown "../../inc/uart-cen.md" %} +The download mode is entered when the chip communicates with the flasher program. Hence, the first step is running the flasher program (described below). While the program is trying to establish communication, **the chip has to be rebooted**. In order to do that, you need to bridge CEN pin to GND with a wire. + Keep in mind that BK7231T (not N) will exit the download mode when it can't communicate with the flasher (or when the flasher finishes its work). It's not possible to forcefully enter download mode without it. After linking with the chip, the flasher program will begin writing (or reading) the firmware automatically. If that doesn't happen, try resetting the chip again until it works. @@ -79,7 +88,9 @@ The recommended tool to flash (or dump firmware) is `ltchiptool`. `ltchiptool`'s Beken flashing program is based on [bk7231tools](https://github.com/tuya-cloudcutter/bk7231tools). Refer to the guide for information how to use it, but keep in mind that using the ltchiptool GUI is probably just easier. -### Auto-download-reboot +--- + +## Auto-download-reboot {% include-markdown "../../inc/uart-adr.md" diff --git a/docs/platform/beken-72xx/keys.md b/docs/platform/beken-72xx/keys.md new file mode 100644 index 000000000..c7136e955 --- /dev/null +++ b/docs/platform/beken-72xx/keys.md @@ -0,0 +1,48 @@ +# Finding encryption keys + +## Introduction + +!!! tip inline end + Before proceeding with this method, try using [ltchiptool](../../flashing/tools/ltchiptool.md)'s `Get chip info` + function. It will read eFuse, which may reveal the raw encryption key. If you see all `00000000`s, then the eFuse + is readout-protected and the key cannot be extracted in this simple way. + +3-rd party firmware for Beken chips must be compiled with a flash encryption key matching the one programmed into +the chip. Incorrect keys will make the firmware unable to run. + +The [`bk72xx-bootloader-dump`](https://github.com/libretiny-eu/bk72xx-bootloader-dump) firmware might make it easier +to find the encryption key of BK7231N/BK7231T chips. + +The key is made of four 32-bit integers; the default key is usually `510fb093 a3cbeadc 5993a17e c7adeb03` +(used by Beken and Tuya on most devices), but devices with different keys have been recently discovered +(likely from other manufacturers). + +If your device doesn't use the default keys (i.e. 3-rd party firmware doesn't boot up, or it hangs on bootloader logs), +you can try using this firmware file to extract the keys from the bootloader. + +## Why this works (and when it doesn't) + +The bootloader has its own copy of the keys. It uses that to encrypt firmware on-the-fly when applying OTA updates. + +Files downloaded during an OTA update are *not* encrypted using the main encryption keys, so the bootloader +must encrypt them before flashing to the app partition. **This method works by flashing firmware directly to the** +**OTA partition**. It is then unpacked and encrypted properly by the bootloader. + +However, OTA update packages *are* encrypted using AES - for this method to work, the AES key must be known in advance. + +Most of the time, a simple `0123456789ABCDEF` key is used for OTA AES. We have seen manufacturers using different +keys - this method will not work in that case. + +Additionally, OTA packages **don't have to** be encrypted - some bootloaders allow that, some don't. Using an +unencrypted package is worth trying if your device uses a non-standard OTA AES key. + +## Prerequisites + +1. A working computer with a working UART flashing setup. The preferred flashing tool is +[ltchiptool](../../flashing/tools/ltchiptool.md). You should have at least some prior experience with dumping +or flashing firmware. +2. **A full factory firmware dump** of the device you're working on. This is mostly in case something goes wrong, +but may also be necessary to read OTA partition offsets from. +3. A serial terminal (such as the [`ltchiptool-terminal`](https://github.com/libretiny-eu/ltchiptool-terminal) plugin). + +## To be continued diff --git a/docs/platform/realtek-ambz/README.md b/docs/platform/realtek-ambz/README.md index 30bd49bd4..fc62678c3 100644 --- a/docs/platform/realtek-ambz/README.md +++ b/docs/platform/realtek-ambz/README.md @@ -27,6 +27,8 @@ Resources: include-markdown "../../inc/find-board.md" %} +--- + ## Flashing Realtek RTL8710B has two UART ports - UART2 (sometimes called LOG_UART) and UART0. The port used for flashing and viewing logs is UART2. @@ -54,6 +56,10 @@ GND | GND In order to flash the chip, you need to enable **download mode**. This is done by resetting the chip while pulling down the TX2 pin. +{% + include-markdown "../../inc/uart-cen.md" +%} + Do this, in order: - connect CEN to GND @@ -61,10 +67,6 @@ Do this, in order: - release CEN from GND - release TX2 from GND -{% - include-markdown "../../inc/uart-cen.md" -%} - To find out whether download mode is enabled, open a serial terminal (such as PuTTY) on your PC. You should see a few characters printed to the serial console every second (usually some kind of grey blocks, or other non-letter characters). Note that you will not see any characters before you release TX2 from GND. @@ -86,7 +88,9 @@ The recommended tool to flash (or dump firmware) is `ltchiptool`. !!! tip Because the UART uploading code is programmed in the ROM of the chip, it can't be software-bricked, even if you damage the bootloader. -### Auto-download-reboot +--- + +## Auto-download-reboot {% include-markdown "../../inc/uart-adr.md" diff --git a/mkdocs.yml b/mkdocs.yml index 2a897f9b3..395cc8e8b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,6 +43,7 @@ plugins: "link/config-serial.md": "docs/dev/config.md#serial-output" "link/flashing-beken-72xx.md": "docs/platform/beken-72xx/README.md#flashing" "link/flashing-realtek-ambz.md": "docs/platform/realtek-ambz/README.md#flashing" + "link/bk72xx-keys.md": "docs/platform/beken-72xx/keys.md" "link/kickstart.md": "https://github.com/libretiny-eu/esphome-kickstart/releases/latest" - section-index - include-markdown From c90794e9f52d0845d2167433752f1ed7abc615b7 Mon Sep 17 00:00:00 2001 From: Cossid <83468485+Cossid@users.noreply.github.com> Date: Sat, 6 Jan 2024 12:40:08 -0600 Subject: [PATCH 08/19] [beken-72xx] Allow connecting to specific BSSID if provided (#209) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Switch to bk_wlan_start_sta_adv for specific bssid control. * Allow split sta/adv_sta configs. * Add wifi_mode back for regular STA mode. * Fix apparent bug of setting null/empty wifi key. Reset STA_ADV_CFG.dhcp_mode in reconnect, as it seems to not survive for some reason. Do les _CFG setting in reconnect() * Move all _CFG setting to begin() * Fix dhcp_mode in STA_ADV_CFG. * Remove no longer necessary dhcp_mode re-set. * Formatting cleanups. * Formatting. * Update cores/beken-72xx/arduino/libraries/WiFi/WiFiSTA.cpp * Apply suggestions from code review --------- Co-authored-by: Kuba Szczodrzyński --- .../arduino/libraries/WiFi/WiFi.cpp | 5 +- .../arduino/libraries/WiFi/WiFiPrivate.h | 2 + .../arduino/libraries/WiFi/WiFiSTA.cpp | 55 ++++++++++++++----- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/cores/beken-72xx/arduino/libraries/WiFi/WiFi.cpp b/cores/beken-72xx/arduino/libraries/WiFi/WiFi.cpp index b5e354594..32f7d2e15 100644 --- a/cores/beken-72xx/arduino/libraries/WiFi/WiFi.cpp +++ b/cores/beken-72xx/arduino/libraries/WiFi/WiFi.cpp @@ -5,8 +5,9 @@ WiFiClass::WiFiClass() { data = (WiFiData *)calloc(1, sizeof(WiFiData)); - DATA->scanSem = xSemaphoreCreateBinary(); - STA_CFG.dhcp_mode = DHCP_CLIENT; + DATA->scanSem = xSemaphoreCreateBinary(); + STA_CFG.dhcp_mode = DHCP_CLIENT; + STA_ADV_CFG.dhcp_mode = DHCP_CLIENT; } WiFiClass::~WiFiClass() { diff --git a/cores/beken-72xx/arduino/libraries/WiFi/WiFiPrivate.h b/cores/beken-72xx/arduino/libraries/WiFi/WiFiPrivate.h index 276aeaa38..38ec80c00 100644 --- a/cores/beken-72xx/arduino/libraries/WiFi/WiFiPrivate.h +++ b/cores/beken-72xx/arduino/libraries/WiFi/WiFiPrivate.h @@ -57,6 +57,7 @@ extern void wifiEventHandler(rw_evt_type event); typedef struct { network_InitTypeDef_st configSta; + network_InitTypeDef_adv_st configStaAdv; network_InitTypeDef_ap_st configAp; unsigned long scannedAt; SemaphoreHandle_t scanSem; @@ -73,6 +74,7 @@ typedef struct { #define cDATA ((WiFiData *)cls->data) #define STA_CFG (DATA->configSta) +#define STA_ADV_CFG (DATA->configStaAdv) #define AP_CFG (DATA->configAp) #define IP_STATUS (DATA->statusIp) #define LINK_STATUS (DATA->statusLink) diff --git a/cores/beken-72xx/arduino/libraries/WiFi/WiFiSTA.cpp b/cores/beken-72xx/arduino/libraries/WiFi/WiFiSTA.cpp index 2ac77c6a8..a5558d101 100644 --- a/cores/beken-72xx/arduino/libraries/WiFi/WiFiSTA.cpp +++ b/cores/beken-72xx/arduino/libraries/WiFi/WiFiSTA.cpp @@ -13,11 +13,26 @@ WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, cons disconnect(false); - strcpy(STA_CFG.wifi_ssid, ssid); - if (passphrase) { - strcpy(STA_CFG.wifi_key, passphrase); + if (bssid) { + strcpy(STA_ADV_CFG.ap_info.ssid, ssid); + if (passphrase) { + strcpy(STA_ADV_CFG.key, passphrase); + STA_ADV_CFG.key_len = strlen(passphrase); + } else { + STA_ADV_CFG.key[0] = '\0'; + STA_ADV_CFG.key_len = 0; + } + STA_ADV_CFG.ap_info.channel = channel; + STA_ADV_CFG.wifi_retry_interval = 100; } else { - STA_CFG.wifi_bssid[0] = '\0'; + strcpy(STA_CFG.wifi_ssid, ssid); + if (passphrase) { + strcpy(STA_CFG.wifi_key, passphrase); + } else { + STA_CFG.wifi_key[0] = '\0'; + } + STA_CFG.wifi_retry_interval = 100; + STA_CFG.wifi_mode = BK_STATION; } if (reconnect(bssid)) @@ -27,21 +42,31 @@ WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, cons } bool WiFiClass::config(IPAddress localIP, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) { - STA_CFG.dhcp_mode = localIP ? DHCP_DISABLE : DHCP_CLIENT; + STA_CFG.dhcp_mode = localIP ? DHCP_DISABLE : DHCP_CLIENT; + STA_ADV_CFG.dhcp_mode = localIP ? DHCP_DISABLE : DHCP_CLIENT; if (localIP) { sprintf(STA_CFG.local_ip_addr, IP_FMT, localIP[0], localIP[1], localIP[2], localIP[3]); sprintf(STA_CFG.net_mask, IP_FMT, subnet[0], subnet[1], subnet[2], subnet[3]); sprintf(STA_CFG.gateway_ip_addr, IP_FMT, gateway[0], gateway[1], gateway[2], gateway[3]); + sprintf(STA_ADV_CFG.local_ip_addr, IP_FMT, localIP[0], localIP[1], localIP[2], localIP[3]); + sprintf(STA_ADV_CFG.net_mask, IP_FMT, subnet[0], subnet[1], subnet[2], subnet[3]); + sprintf(STA_ADV_CFG.gateway_ip_addr, IP_FMT, gateway[0], gateway[1], gateway[2], gateway[3]); if (dns1) { sprintf(STA_CFG.dns_server_ip_addr, IP_FMT, dns1[0], dns1[1], dns1[2], dns1[3]); + sprintf(STA_ADV_CFG.dns_server_ip_addr, IP_FMT, dns1[0], dns1[1], dns1[2], dns1[3]); } else { - STA_CFG.dns_server_ip_addr[0] = '\0'; + STA_CFG.dns_server_ip_addr[0] = '\0'; + STA_ADV_CFG.dns_server_ip_addr[0] = '\0'; } } else { - STA_CFG.local_ip_addr[0] = '\0'; - STA_CFG.net_mask[0] = '\0'; - STA_CFG.gateway_ip_addr[0] = '\0'; - STA_CFG.dns_server_ip_addr[0] = '\0'; + STA_CFG.local_ip_addr[0] = '\0'; + STA_CFG.net_mask[0] = '\0'; + STA_CFG.gateway_ip_addr[0] = '\0'; + STA_CFG.dns_server_ip_addr[0] = '\0'; + STA_ADV_CFG.local_ip_addr[0] = '\0'; + STA_ADV_CFG.net_mask[0] = '\0'; + STA_ADV_CFG.gateway_ip_addr[0] = '\0'; + STA_ADV_CFG.dns_server_ip_addr[0] = '\0'; } // from wlan_ui.c:1370 @@ -74,10 +99,8 @@ bool WiFiClass::reconnect(const uint8_t *bssid) { LT_DM(WIFI, "Data = %p", DATA->configSta); - STA_CFG.wifi_mode = BK_STATION; - STA_CFG.wifi_retry_interval = 100; if (bssid) - memcpy(STA_CFG.wifi_bssid, bssid, 6); + memcpy(STA_ADV_CFG.ap_info.bssid, bssid, 6); else memset(STA_CFG.wifi_bssid, 0x00, 6); @@ -91,7 +114,11 @@ bool WiFiClass::reconnect(const uint8_t *bssid) { LT_DM(WIFI, "Starting WiFi..."); __wrap_bk_printf_disable(); - bk_wlan_start_sta(&STA_CFG); + if (bssid) { + bk_wlan_start_sta_adv(&STA_ADV_CFG); + } else { + bk_wlan_start_sta(&STA_CFG); + } __wrap_bk_printf_enable(); LT_DM(WIFI, "Start OK"); From 1e3a82f439851a5d7c7535c07418dcc07088e94b Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Sat, 6 Jan 2024 19:40:33 +0100 Subject: [PATCH 09/19] [beken-72xx] Improve ddev ADC support (#220) --- cores/beken-72xx/arduino/src/wiring_analog.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cores/beken-72xx/arduino/src/wiring_analog.c b/cores/beken-72xx/arduino/src/wiring_analog.c index 76bbf2756..110f33bbf 100644 --- a/cores/beken-72xx/arduino/src/wiring_analog.c +++ b/cores/beken-72xx/arduino/src/wiring_analog.c @@ -65,13 +65,21 @@ uint16_t analogReadVoltage(pin_size_t pinNumber) { adc.pData = adcData; adc.data_buff_size = 1; handle = ddev_open(SARADC_DEV_NAME, &status, (uint32_t)&adc); - if (status) + if (handle == -1) { return 0; + } + + if (status != SARADC_SUCCESS) { + ddev_close(handle); + return 0; + } + // wait for data while (!adc.has_data || adc.current_sample_data_cnt < 1) { delay(1); } - ddev_control(handle, SARADC_CMD_RUN_OR_STOP_ADC, (void *)false); + uint8_t run_stop = 0; // stop + ddev_control(handle, SARADC_CMD_RUN_OR_STOP_ADC, &run_stop); ddev_close(handle); return adcData[0]; } From 140cf07173c757e961bad1256de386c76b54dbe5 Mon Sep 17 00:00:00 2001 From: Cossid <83468485+Cossid@users.noreply.github.com> Date: Sat, 6 Jan 2024 12:40:44 -0600 Subject: [PATCH 10/19] [docs] Use official ESPHome version, add LT dev version guide (#223) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update ESPHome documentation * Update note format * Switch to https github format, give manual PR checkout instructions until a better method is found. * Fix yaml sample spacing * Fix indent * Add addon migration info * Replace spaces with tabs --------- Co-authored-by: Kuba Szczodrzyński --- docs/projects/esphome.md | 79 +++++++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 25 deletions(-) diff --git a/docs/projects/esphome.md b/docs/projects/esphome.md index 1f0b78207..5b169cc2b 100644 --- a/docs/projects/esphome.md +++ b/docs/projects/esphome.md @@ -3,16 +3,18 @@ !!! tip See the [Cloudcutter video guide](https://www.youtube.com/watch?v=sSj8f-HCHQ0) for a complete tutorial on flashing with [Cloudcutter](https://github.com/tuya-cloudcutter/tuya-cloudcutter) and installing LibreTiny-ESPHome. **Includes Home Assistant Add-On setup.** -Because ESPHome does not natively support running on non-ESP chips, you need to use a fork of the project. +LibreTiny is now natively supported by ESPHome in versions 2023.9.0 and later. -There are three basic ways to install and use LibreTiny-ESPHome. You can choose the option that best suits you: +There are three basic ways to install and use ESPHome. You can choose the option that best suits you: - ESPHome Dashboard (GUI) - for new users, might be an easy way to go; config management & compilation using web-based dashboard - command line (CLI) - for more experienced users; compilation using CLI commands, somewhat easier to troubleshoot -- [Home Assistant Add-On](https://github.com/libretiny-eu/esphome-hass-addon/pkgs/container/libretiny-esphome-hassio) - using LibreTiny-ESPHome in Home Assistant, alongside your normal ESPHome installation - click the link for more info +- Home Assistant Add-On - using ESPHome in Home Assistant as an add-on -!!! tip - You can use LibreTiny-ESPHome for ESP32/ESP8266 compilation as well - the forked version *extends* the base, and doesn't remove any existing features. Keep in mind that you might not have latest ESPHome updates until the fork gets updated (which usually happens at most every few weeks). +!!! warning "Important" + If you have the LibreTiny-ESPHome add-on installed in Home Assistant, migrate your YAML files over to the official ESPHome add-on. + + The standalone add-on is now deprecated - after migrating your configs, uninstall the old add-on. ## Find your device's board @@ -33,8 +35,8 @@ If your board isn't listed, use one of the **Generic** boards, depending on the version: "3" services: esphome: - container_name: esphome-libretiny - image: ghcr.io/libretiny-eu/libretiny-esphome-docker:latest + container_name: esphome + image: ghcr.io/esphome/esphome:latest volumes: - ./configs:/config:rw # (1)! - /etc/localtime:/etc/localtime:ro @@ -51,20 +53,15 @@ If your board isn't listed, use one of the **Generic** boards, depending on the !!! important Read [Getting started](../getting-started/README.md) first - most importantly, the first part about installation. - **It is very important that you have the latest version of LibreTiny installed** (not `libretiny-esphome` - this is a different thing!) **so that you don't face issues that are already resolved**. - Assuming you have PlatformIO, git and Python installed: - 1. Open a terminal/cmd.exe, create `esphome` directory and `cd` into it. - 2. `git clone https://github.com/libretiny-eu/libretiny-esphome` - 3. `cd` into the newly created `libretiny-esphome` directory. + 1. Open a terminal/cmd.exe + 2. `git clone https://github.com/esphome/esphome` + 3. `cd` into the newly created `esphome` directory. 4. Check if it works by typing `python -m esphome` !!! tip - For Linux users (or if `python -m esphome` doesn't work for you): - - - uninstall ESPHome first: `pip uninstall esphome` - - install the forked version: `pip install -e .` + You can alternately install ESPHome CLI using pip with `pip install esphome` ## Create your device config @@ -74,11 +71,11 @@ If your board isn't listed, use one of the **Generic** boards, depending on the 2. Go through the wizard steps: - `New Device` - `Continue` - - enter name and WiFi details - - choose `LibreTiny` - - choose the board that you found before + - enter name and WiFi details (first time only) + - LibreTiny will not currently be listed as an option, choose any of the boards and you will overwrite them later - select `Skip` 3. A new config file will be added. Press `Edit` and proceed to the next section. + 4. Delete the entire generated configuration and replace it with the example configuration below or one generated by [UPK2ESPHome](https://upk.libretiny.eu/). === "CLI" @@ -95,17 +92,15 @@ If your board isn't listed, use one of the **Generic** boards, depending on the version: latest logger: + web_server: + captive_portal: api: - password: "" ota: - password: "" wifi: - ssid: "YourWiFiSSID" - password: "SecretPa$$w0rd" + ssid: !secret wifi_ssid + password: !secret wifi_password ap: - ssid: "Yourdevice Fallback Hotspot" - password: "Dv2hZMGZRUvy" ``` ## Automatically generate config @@ -149,6 +144,7 @@ bk72xx: LT_UART_DEFAULT_PORT: 2 LT_UART_SILENT_ALL: 0 ``` + (this is only an example) Additionally, few options have their dedicated keys: @@ -166,4 +162,37 @@ bk72xx: # set to false if you want to attach a debugger gpio_recover: true ``` + (these values are defaults) + +## Advanced: Using development versions with ESPHome + +There are a two ways to use development versions of LibreTiny with ESPHome: + +- `version` is a required field, and must match a specific format, it is recommended to use `"0.0.0"` for custom development +- `source` must point to where your development version of LibreTiny resides. + +=== "Git" + + ```yaml + bk72xx: + framework: + version: "0.0.0" + source: "https://github.com/libretiny-eu/libretiny" + ``` + + Source can be post-fixed to checkout a specified branch or a Pull Request: + + - Branch: add `#branch_name` (ex: `source: "https://github.com/libretiny-eu/libretiny#experimental_branch_name"`) + - Pull Requests: Pull requests currently require you to check out the source branch of the pull request. To get this information, visit the PR, click on the source branch, and copy their git address and apply the branch their PR uses (ex: `https://github.com/pr_user/libretiny#pr_branch`) + +=== "Local" + + Check out with Git (recommended) or download and extract a copy of LibreTiny to your local file system running ESPHome. + + ```yaml + bk72xx: + framework: + version: "0.0.0" + source: "/local_path_to_libretiny" + ``` From 1d80b5fff72cc31cba49f54fe7dd56357842031a Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Sat, 6 Jan 2024 19:41:01 +0100 Subject: [PATCH 11/19] [beken-72xx] Free list returned by wlan_sta_scan_result() (#226) * Free list returned by wlan_sta_scan_result() * scanAlloc improvements There were a few things I didn't like about this function: 1) realloc() was called a bit too often. 2) if realloc() failed, the previous memory was not freed. 3) scanAlloc returned previous count or 255 on error. But there was no real check for error and 255 could've been used as index to null. I think it's better to simple return boolean. 4) scanAlloc was clearing memory only up to (and excluding) the new entries. * Corrected clearing new entries in scanAlloc * scanAlloc() now returns number of allocated items * Fixed compilation issues related to goto. --- .../arduino/libraries/WiFi/WiFiScan.cpp | 16 ++++++++++--- .../arduino/libraries/api/WiFi/WiFiScan.cpp | 24 +++++++++++++------ .../arduino/libraries/WiFi/WiFiScan.cpp | 5 +++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/cores/beken-72xx/arduino/libraries/WiFi/WiFiScan.cpp b/cores/beken-72xx/arduino/libraries/WiFi/WiFiScan.cpp index ca585fa33..fe739658d 100644 --- a/cores/beken-72xx/arduino/libraries/WiFi/WiFiScan.cpp +++ b/cores/beken-72xx/arduino/libraries/WiFi/WiFiScan.cpp @@ -15,20 +15,27 @@ static void scanHandler(void *ctx, uint8_t param) { return; } + uint8_t apNum = 0; ScanResult_adv result; + result.ApNum = 0; + result.ApList = NULL; if (wlan_sta_scan_result(&result)) { LT_EM(WIFI, "Failed to get scan result"); goto end; } LT_IM(WIFI, "Found %d APs", result.ApNum); - cls->scanAlloc(result.ApNum); - if (!scan->ap) { + apNum = cls->scanAlloc(result.ApNum); + if (0 == apNum) { LT_WM(WIFI, "scan->ap alloc failed"); goto end; } - for (uint8_t i = 0; i < result.ApNum; i++) { + if (apNum < result.ApNum) { + LT_WM(WIFI, "alloc failed, only %d APs will be copied"); + } + + for (uint8_t i = 0; i < apNum; i++) { scan->ap[i].ssid = strdup(result.ApList[i].ssid); scan->ap[i].auth = securityTypeToAuthMode(result.ApList[i].security); scan->ap[i].rssi = result.ApList[i].ApPower; @@ -47,6 +54,9 @@ static void scanHandler(void *ctx, uint8_t param) { scan->running = false; xSemaphoreGive(cDATA->scanSem); } + if (result.ApList) { + free(result.ApList); + } LT_HEAP_I(); return; } diff --git a/cores/common/arduino/libraries/api/WiFi/WiFiScan.cpp b/cores/common/arduino/libraries/api/WiFi/WiFiScan.cpp index 6cd295217..20bb83c7c 100644 --- a/cores/common/arduino/libraries/api/WiFi/WiFiScan.cpp +++ b/cores/common/arduino/libraries/api/WiFi/WiFiScan.cpp @@ -39,13 +39,23 @@ void WiFiClass::scanDelete() { } uint8_t WiFiClass::scanAlloc(uint8_t count) { - uint8_t last = scan->count; - scan->count = count; - scan->ap = (WiFiScanAP *)realloc(scan->ap, count * sizeof(WiFiScanAP)); - if (!scan->ap) - return 255; - memset(scan->ap + last, 0, sizeof(WiFiScanAP)); - return last; + if ((!scan->ap) || (count > scan->count)) { + auto newMem = (WiFiScanAP *)realloc(scan->ap, count * sizeof(WiFiScanAP)); + if (!newMem) { + return scan->count; + } + scan->ap = newMem; + } + if (!scan->ap) { + scan->count = 0; + return 0; + } + if (count > scan->count) { + // clear only new entries + memset(scan->ap + scan->count, 0, sizeof(WiFiScanAP) * (count - scan->count)); + } + scan->count = count; + return count; } String WiFiClass::SSID(uint8_t networkItem) { diff --git a/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp b/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp index 75731ef28..95408815d 100644 --- a/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp +++ b/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp @@ -20,7 +20,10 @@ static rtw_result_t scanHandler(rtw_scan_handler_result_t *result) { if (!net->SSID.len) return RTW_SUCCESS; - uint8_t last = cls->scanAlloc(scan->count + 1); + uint8_t last = scan->count + 1; + if (cls->scanAlloc(last) < last) { + return RTW_SUCCESS; + } scan->ap[last].ssid = strdup((char *)net->SSID.val); scan->ap[last].auth = securityTypeToAuthMode(net->security); From 4cddc01f2236dc792aeac998c254e8f7e9ea6e0f Mon Sep 17 00:00:00 2001 From: Hajo Noerenberg Date: Wed, 17 Jan 2024 22:49:33 +0100 Subject: [PATCH 12/19] [libs] Fix MD5 calculation during OTA update (#240) --- cores/common/arduino/libraries/common/Update/Update.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/common/arduino/libraries/common/Update/Update.cpp b/cores/common/arduino/libraries/common/Update/Update.cpp index c094da4b1..9c053909c 100644 --- a/cores/common/arduino/libraries/common/Update/Update.cpp +++ b/cores/common/arduino/libraries/common/Update/Update.cpp @@ -149,8 +149,8 @@ size_t UpdateClass::write(const uint8_t *data, size_t len) { if (!this->ctx) return 0; - size_t written = lt_ota_write(ctx, data, len); MD5Update(this->md5Ctx, data, len); + size_t written = lt_ota_write(ctx, data, len); if (written != len) this->cleanup(/* clearError= */ false); return written; From 9a33fc0a696317d0828bd1438d94d5f9d4aa27f8 Mon Sep 17 00:00:00 2001 From: Anna <16231288+HumbleDeer@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:14:12 +0100 Subject: [PATCH 13/19] [docs] Improve getting started guide (#252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Readme & improve md layout - ESPHome now supports LibreTiny natively - Added extra PIO docs references - Reworded some sections slightly, to accomodate proper grammar - PIO deprecated the `platformio platform install` command, replaced this with the official recommendation/replacement * Use backslash for line break, revert changing indent --------- Co-authored-by: Kuba Szczodrzyński --- docs/getting-started/README.md | 46 ++++++++++++++++++++++------------ mkdocs.yml | 2 ++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/docs/getting-started/README.md b/docs/getting-started/README.md index 634e9d473..734556b68 100644 --- a/docs/getting-started/README.md +++ b/docs/getting-started/README.md @@ -3,46 +3,60 @@ Using LibreTiny is simple, just like every other PlatformIO development platform. 1. [Install PlatformIO](https://platformio.org/platformio-ide) -2. `platformio platform install -f https://github.com/libretiny-eu/libretiny` +2. `pio pkg install --platform libretiny` !!! tip See the [Cloudcutter video guide](https://www.youtube.com/watch?v=sSj8f-HCHQ0) for a complete tutorial on flashing with [Cloudcutter](https://github.com/tuya-cloudcutter/tuya-cloudcutter) and installing [LibreTiny-ESPHome](../projects/esphome.md). **Includes Home Assistant Add-On setup.** + More information on Cloudcutter can be found in the [Tuya Cloudcutter GitHub repository](https://github.com/tuya-cloudcutter/tuya-cloudcutter). + ## Board selection -- Go to [Boards & CPU list](../status/supported.md). -- Find the board your device has (usually, the model number is written on the silkscreen). - - If your board isn't available yet, use one of the "Generic" boards that matches the CPU you have. -- Click on the board name. From the documentation page, note the board code. -- Use this code to create a PlatformIO project. +1. Navigate to the [supported boards & CPUs](../status/supported.md) list. +2. Find the board your device has (usually, the model number is written on the silkscreen). \ + *If your board isn't available yet, use one of the "Generic" boards that matches the CPU you your board has.* +3. Click on the board name. A new page opens with information about the selected board name. +4. Scroll down to the "Usage" section of the page, and copy the configuration section that is relevant to your use case. ## Run community projects -LibreTiny was developed with popular community projects in mind. Currently, unofficial [ESPHome port](../projects/esphome.md) is available ([the PR](https://github.com/esphome/esphome/pull/3509) will hopefully be merged into upstream at some point). +LibreTiny was developed with popular community projects in mind. + +There is an official [ESPHome port](../projects/esphome.md) available and integrated into the ESPHome project. No extra downloads or code compilations are needed to use ESPHome with LibreTiny-supported platforms. ## Develop your own project -If you're developing your own embedded software, and want it to run on LibreTiny-supported chips, create a project. +Developing your own embedded software that runs on LibreTiny-supported platforms. + +To get started with LibreTiny on your chosen platform, create a new project using your preferred method. -- use PlatformIO IDE (PIO Home -> Open -> New Project) -- run `pio project init` in your desired project directory +There's a few ways to create a new PlatformIO Project. For example: -Next, read one of the [flashing guides](../flashing/SUMMARY.md) to run your project! +- using the PlatformIO IDE graphical interface (PIO Home -> Open -> New Project) +- by running the `pio project init` command in your desired project directory \ + *See the [PlatformIO Core (CLI) documentation] for information on `pio project init` and other command line usage.* -### LT configuration +Next, read one of the [flashing guides](../flashing/SUMMARY.md) to upload and run your project! -LibreTiny has a few configuration options that change its behavior or features. Refer to [LT configuration](../dev/config.md) for details. +### Config options (platformio.ini) + +LibreTiny has a few configuration options that allow you to change its behavior or features. These can be defined, specified or changed in the platformio.ini configuration file for your project. + +Refer to the LibreTiny [Configuration](../dev/config.md) manual for details. ### GPIO usage - important change !!! important - Since v1.0.0, GPIOs are no longer meant to be referenced by `D#` numbers. + As of LibreTiny release v1.0.0, references to GPIO pins using their `D#` numbers has been **deprecated** and should **no longer be used** in new projects. - If your program is using Arduino I/O functions, refer to the [Migration guide](../dev/migration_v1.0.0.md) to modify your program accordingly. + If your program is using Arduino I/O functions, please refer to the [migration guide](../dev/migration_v1.0.0.md) on how to modify your code accordingly. ### Examples {% include-markdown "../../examples/SUMMARY.md" - start="# Examples\n" + start="# Examples\n" %} + + +[PlatformIO Core (CLI) documentation]: https://docs.platformio.org/en/stable/core/quickstart.html#setting-up-the-project diff --git a/mkdocs.yml b/mkdocs.yml index 395cc8e8b..ff9c70abd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -67,6 +67,8 @@ markdown_extensions: anchor_linenums: true - pymdownx.tabbed: alternate_style: true + - pymdownx.escapeall: + hardbreak: true - pymdownx.inlinehilite - pymdownx.details - pymdownx.superfences From b748d9943706862f836e66d7c145aeeefcd0a31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 20 Feb 2024 17:16:15 +0100 Subject: [PATCH 14/19] [release] v1.5.0 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index a2729f5a2..473df643e 100644 --- a/platform.json +++ b/platform.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/libretiny-eu/libretiny.git" }, - "version": "1.4.1", + "version": "1.5.0", "frameworks": { "base": { "title": "Base Framework (SDK only)", From b78c9387a6696a34d4f1a58d1d01112de2f528ff Mon Sep 17 00:00:00 2001 From: cap9qd <33727568+cap9qd@users.noreply.github.com> Date: Thu, 22 Feb 2024 13:24:40 -0600 Subject: [PATCH 15/19] [beken-72xx] Fix duration rollover in deep sleep (#253) --- cores/beken-72xx/base/api/lt_sleep.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cores/beken-72xx/base/api/lt_sleep.c b/cores/beken-72xx/base/api/lt_sleep.c index e021225c4..e643ded07 100644 --- a/cores/beken-72xx/base/api/lt_sleep.c +++ b/cores/beken-72xx/base/api/lt_sleep.c @@ -19,14 +19,13 @@ void lt_deep_sleep_unset_gpio(uint32_t gpio_index_map) { deep_sleep_param.gpio_index_map &= (~gpio_index_map); } -void lt_deep_sleep_config_timer(uint32_t sleep_duration) { +void lt_deep_sleep_config_timer(uint32_t sleep_duration_ms) { deep_sleep_param.wake_up_way |= PS_DEEP_WAKEUP_RTC; - uint64_t duration_math = 32768 * sleep_duration; - if (duration_math / 1000 > 0xFFFFFFFF) { - // Sleep forever - deep_sleep_param.sleep_time = 0xFFFFFFFF; + uint64_t sleep_ticks = 32.768 * sleep_duration_ms; + if (sleep_ticks >= 0xFFFFFFFF) { + deep_sleep_param.sleep_time = 0xFFFFFFFE; } else { - deep_sleep_param.sleep_time = (duration_math / 1000) & 0xFFFFFFFF; + deep_sleep_param.sleep_time = sleep_ticks & 0xFFFFFFFF; } } From cf52021d3822d8f62826a846c68b1a46a1a5df4f Mon Sep 17 00:00:00 2001 From: cap9qd <33727568+cap9qd@users.noreply.github.com> Date: Sun, 25 Feb 2024 11:45:22 -0600 Subject: [PATCH 16/19] [core] Split reboot reasons due to wakeup (#254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Updates to break out wakeup reasons. Per https://github.com/libretiny-eu/libretiny/issues/234 * Update cores/common/base/api/lt_device.h Co-authored-by: Kuba Szczodrzyński * fix clang-format * Fix formatting of python files. * Update lt_device.h --------- Co-authored-by: Kuba Szczodrzyński --- builder/utils/cores.py | 20 ++++++------ cores/beken-72xx/base/api/lt_device.c | 6 ++-- cores/common/base/api/lt_device.c | 8 +++-- cores/common/base/api/lt_device.h | 46 ++++++++++++++++----------- docs/scripts/write_boards.py | 38 +++++++++++++--------- 5 files changed, 71 insertions(+), 47 deletions(-) diff --git a/builder/utils/cores.py b/builder/utils/cores.py index 8848e08fd..9e4018466 100644 --- a/builder/utils/cores.py +++ b/builder/utils/cores.py @@ -89,15 +89,17 @@ def env_add_arduino_libraries(env: Environment, queue, name: str, path: str) -> srcs=[ "+<**/*.c*>", ], - includes=[ - "!<*/.>", - "!<*/*>", - ] - if name.startswith("common") - else [ - "!<.>", - "!<*>", - ], + includes=( + [ + "!<*/.>", + "!<*/*>", + ] + if name.startswith("common") + else [ + "!<.>", + "!<*>", + ] + ), ) return True diff --git a/cores/beken-72xx/base/api/lt_device.c b/cores/beken-72xx/base/api/lt_device.c index 200802724..eed4f7e37 100644 --- a/cores/beken-72xx/base/api/lt_device.c +++ b/cores/beken-72xx/base/api/lt_device.c @@ -31,10 +31,12 @@ lt_reboot_reason_t lt_get_reboot_reason() { case RESET_SOURCE_CRASH_UNUSED: case RESET_SOURCE_CRASH_PER_XAT0: return REBOOT_REASON_CRASH; + case RESET_SOURCE_DEEPPS_USB: + return REBOOT_REASON_SLEEP_USB; case RESET_SOURCE_DEEPPS_GPIO: + return REBOOT_REASON_SLEEP_GPIO; case RESET_SOURCE_DEEPPS_RTC: - case RESET_SOURCE_DEEPPS_USB: - return REBOOT_REASON_SLEEP; + return REBOOT_REASON_SLEEP_RTC; default: return REBOOT_REASON_UNKNOWN; } diff --git a/cores/common/base/api/lt_device.c b/cores/common/base/api/lt_device.c index 983ddadad..af8cd6875 100644 --- a/cores/common/base/api/lt_device.c +++ b/cores/common/base/api/lt_device.c @@ -62,8 +62,12 @@ const char *lt_get_reboot_reason_name(lt_reboot_reason_t reason) { return "WDT Reset"; case REBOOT_REASON_CRASH: return "Crash"; - case REBOOT_REASON_SLEEP: - return "Sleep Wakeup"; + case REBOOT_REASON_SLEEP_GPIO: + return "Sleep Wakeup (GPIO)"; + case REBOOT_REASON_SLEEP_RTC: + return "Sleep Wakeup (RTC)"; + case REBOOT_REASON_SLEEP_USB: + return "Sleep Wakeup (USB)"; case REBOOT_REASON_DEBUGGER: return "Debugger"; default: diff --git a/cores/common/base/api/lt_device.h b/cores/common/base/api/lt_device.h index 5074c2820..7e1c4df76 100644 --- a/cores/common/base/api/lt_device.h +++ b/cores/common/base/api/lt_device.h @@ -4,32 +4,40 @@ #include -#define RESET_REASON_UNKNOWN REBOOT_REASON_UNKNOWN -#define RESET_REASON_POWER REBOOT_REASON_POWER -#define RESET_REASON_BROWNOUT REBOOT_REASON_BROWNOUT -#define RESET_REASON_HARDWARE REBOOT_REASON_HARDWARE -#define RESET_REASON_SOFTWARE REBOOT_REASON_SOFTWARE -#define RESET_REASON_WATCHDOG REBOOT_REASON_WATCHDOG -#define RESET_REASON_CRASH REBOOT_REASON_CRASH -#define RESET_REASON_SLEEP REBOOT_REASON_SLEEP -#define RESET_REASON_MAX REBOOT_REASON_MAX +#define RESET_REASON_UNKNOWN REBOOT_REASON_UNKNOWN +#define RESET_REASON_POWER REBOOT_REASON_POWER +#define RESET_REASON_BROWNOUT REBOOT_REASON_BROWNOUT +#define RESET_REASON_HARDWARE REBOOT_REASON_HARDWARE +#define RESET_REASON_SOFTWARE REBOOT_REASON_SOFTWARE +#define RESET_REASON_WATCHDOG REBOOT_REASON_WATCHDOG +#define RESET_REASON_CRASH REBOOT_REASON_CRASH +#define RESET_REASON_SLEEP_GPIO REBOOT_REASON_SLEEP_GPIO +#define RESET_REASON_SLEEP_RTC REBOOT_REASON_SLEEP_RTC +#define RESET_REASON_SLEEP_USB REBOOT_REASON_SLEEP_USB +#define RESET_REASON_MAX REBOOT_REASON_MAX /** * @brief Reset reason enumeration. */ typedef enum { - REBOOT_REASON_UNKNOWN = 1, - REBOOT_REASON_POWER = 2, - REBOOT_REASON_BROWNOUT = 3, - REBOOT_REASON_HARDWARE = 4, - REBOOT_REASON_SOFTWARE = 5, - REBOOT_REASON_WATCHDOG = 6, - REBOOT_REASON_CRASH = 7, - REBOOT_REASON_SLEEP = 8, - REBOOT_REASON_DEBUGGER = 9, - REBOOT_REASON_MAX = 10, + REBOOT_REASON_UNKNOWN = 1, + REBOOT_REASON_POWER = 2, + REBOOT_REASON_BROWNOUT = 3, + REBOOT_REASON_HARDWARE = 4, + REBOOT_REASON_SOFTWARE = 5, + REBOOT_REASON_WATCHDOG = 6, + REBOOT_REASON_CRASH = 7, + REBOOT_REASON_SLEEP_GPIO = 8, + REBOOT_REASON_SLEEP_RTC = 9, + REBOOT_REASON_SLEEP_USB = 10, + REBOOT_REASON_DEBUGGER = 11, + REBOOT_REASON_MAX = 12, } lt_reboot_reason_t; +// RESET_REASON_SLEEP deprecated, kept for compatibility +#define RESET_REASON_SLEEP REBOOT_REASON_SLEEP_GPIO +#define REBOOT_REASON_SLEEP REBOOT_REASON_SLEEP_GPIO + /** * @brief Debugging mode enumeration. */ diff --git a/docs/scripts/write_boards.py b/docs/scripts/write_boards.py index e40833308..fa773e168 100644 --- a/docs/scripts/write_boards.py +++ b/docs/scripts/write_boards.py @@ -285,12 +285,14 @@ def write_families(supported: list[Family]): docs = get_readme_family_link(family) row = [ # Title - "[{}]({})".format( - family.description, - docs, - ) - if docs - else family.description, + ( + "[{}]({})".format( + family.description, + docs, + ) + if docs + else family.description + ), # Name family.is_supported and f"`{family.name}`" or "`-`", # Code @@ -301,16 +303,22 @@ def write_families(supported: list[Family]): family.id, ), # Arduino Core - "✔️" - if family in supported and family.is_supported and family.has_arduino_core - else "❌", + ( + "✔️" + if family in supported + and family.is_supported + and family.has_arduino_core + else "❌" + ), # Source SDK - "[`{}`]({})".format( - family.target_package, - f"https://github.com/libretiny-eu/{family.target_package}", - ) - if family.target_package - else "-", + ( + "[`{}`]({})".format( + family.target_package, + f"https://github.com/libretiny-eu/{family.target_package}", + ) + if family.target_package + else "-" + ), ] rows.append(row) md.add_table(header, *rows) From a1f8516e603c930e3cf288b3f7d60b1031334e68 Mon Sep 17 00:00:00 2001 From: Hajo Noerenberg Date: Mon, 26 Feb 2024 21:35:35 +0100 Subject: [PATCH 17/19] [realtek-ambz] Fix crash after WiFi scan (#258) --- cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp b/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp index 95408815d..52d1cdafc 100644 --- a/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp +++ b/cores/realtek-amb/arduino/libraries/WiFi/WiFiScan.cpp @@ -24,6 +24,7 @@ static rtw_result_t scanHandler(rtw_scan_handler_result_t *result) { if (cls->scanAlloc(last) < last) { return RTW_SUCCESS; } + last--; scan->ap[last].ssid = strdup((char *)net->SSID.val); scan->ap[last].auth = securityTypeToAuthMode(net->security); From 67b92b7f566cd446ca3206ff12f76fbeda25f6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Thu, 29 Feb 2024 14:14:01 +0100 Subject: [PATCH 18/19] [release] v1.5.1 --- platform.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.json b/platform.json index 473df643e..c09423c32 100644 --- a/platform.json +++ b/platform.json @@ -6,7 +6,7 @@ "type": "git", "url": "https://github.com/libretiny-eu/libretiny.git" }, - "version": "1.5.0", + "version": "1.5.1", "frameworks": { "base": { "title": "Base Framework (SDK only)", From d1386a8e9dcdeed4c50dd0628462b14c9295d304 Mon Sep 17 00:00:00 2001 From: Piotr Szulc Date: Fri, 8 Mar 2024 12:21:14 +0100 Subject: [PATCH 19/19] [libs] Fix mDNS string memory corruption, print error on record add failure (#260) * Fixed unsafe conversion to underscore string * Fixed formatting * Save one byte if underscore not needed * Don't allocate new string if already underscored * Fix missing first character while copying * Renamed function and made it inline * Don't use signed index variable when searching for service * Add proper cleanup of LwIPmDNS - Free allocated memory both on end() and in the destructor - Unregister callback from netif * Don't free const pointer * Removed unneeded casting * Don't break the loop if failed to add txt record * Fixed code formatting --- .../libraries/common/mDNS/LwIPmDNS.cpp | 47 +++++++++++++++---- .../arduino/libraries/common/mDNS/mDNS.cpp | 19 ++++++-- .../arduino/libraries/common/mDNS/mDNS.h | 1 + 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/cores/common/arduino/libraries/common/mDNS/LwIPmDNS.cpp b/cores/common/arduino/libraries/common/mDNS/LwIPmDNS.cpp index 0f602dbc5..0b8c435df 100644 --- a/cores/common/arduino/libraries/common/mDNS/LwIPmDNS.cpp +++ b/cores/common/arduino/libraries/common/mDNS/LwIPmDNS.cpp @@ -31,9 +31,34 @@ static const char *hostName; NETIF_DECLARE_EXT_CALLBACK(netif_callback) #endif +static inline void freeAllocatedStrings(const std::vector &strings) { + for (auto &str : strings) { + free(str); + } +} + mDNS::mDNS() {} -mDNS::~mDNS() {} +mDNS::~mDNS() { + cleanup(); +} + +void mDNS::cleanup() { + freeAllocatedStrings(services_name); + services_name.clear(); + freeAllocatedStrings(services); + services.clear(); + for (auto &record : records) { + freeAllocatedStrings(record); + } + records.clear(); + + free((void *)hostName); + hostName = NULL; + + free((void *)instanceName); + instanceName = NULL; +} static void mdnsTxtCallback(struct mdns_service *service, void *userdata) { size_t index = (size_t)userdata; @@ -42,8 +67,9 @@ static void mdnsTxtCallback(struct mdns_service *service, void *userdata) { for (const auto record : records[index]) { err_t err = mdns_resp_add_service_txtitem(service, record, strlen(record)); - if (err != ERR_OK) - return; + if (err != ERR_OK) { + LT_DM(MDNS, "Error %d while adding txt record: %s", err, record); + } } } @@ -136,12 +162,18 @@ bool mDNS::begin(const char *hostname) { } void mDNS::end() { +#ifdef LWIP_NETIF_EXT_STATUS_CALLBACK + netif_remove_ext_callback(&netif_callback); +#endif + struct netif *netif = netif_list; while (netif != NULL) { if (netif_is_up(netif)) mdns_resp_remove_netif(netif); netif = netif->next; } + + cleanup(); } bool mDNS::addServiceImpl(const char *name, const char *service, uint8_t proto, uint16_t port) { @@ -181,18 +213,17 @@ bool mDNS::addServiceImpl(const char *name, const char *service, uint8_t proto, } bool mDNS::addServiceTxtImpl(const char *service, uint8_t proto, const char *item) { - int8_t index = -1; - for (uint8_t i = 0; i < services.size(); i++) { + uint8_t i; + for (i = 0; i < services.size(); i++) { // find a matching service if (strcmp(services[i], service) == 0 && protos[i] == proto) { - index = i; break; } } - if (index == -1) + if (i == services.size()) return false; - records[index].push_back(strdup(item)); + records[i].push_back(strdup(item)); return true; } diff --git a/cores/common/arduino/libraries/common/mDNS/mDNS.cpp b/cores/common/arduino/libraries/common/mDNS/mDNS.cpp index 4de68fdea..75af2a4d1 100644 --- a/cores/common/arduino/libraries/common/mDNS/mDNS.cpp +++ b/cores/common/arduino/libraries/common/mDNS/mDNS.cpp @@ -2,14 +2,23 @@ #include "mDNS.h" -static char *ensureUnderscore(const char *value) { - uint8_t len = strlen(value) + 1; +static char *ensureUnderscore(char *value) { + if (value[0] == '_') { + return value; + } + size_t len = strlen(value) + 1 + 1; // 1 for underscore, 1 for null-terminator char *result = (char *)malloc(len); result[0] = '_'; - strcpy(result + 1, value + (value[0] == '_')); + strcpy(result + 1, value); return result; } +static inline void freeIfCopied(const char *original, char *duplicate) { + if ((duplicate) && (original != duplicate)) { + free(duplicate); + } +} + void mDNS::setInstanceName(const char *name) { if (instanceName) free(instanceName); @@ -21,7 +30,7 @@ bool mDNS::addService(char *service, char *proto, uint16_t port) { uint8_t _proto = strncmp(proto + (proto[0] == '_'), "tcp", 3) == 0 ? MDNS_TCP : MDNS_UDP; bool result = addServiceImpl(instanceName ? instanceName : "LT mDNS", _service, _proto, port); - free(_service); + freeIfCopied(service, _service); return result; } @@ -34,7 +43,7 @@ bool mDNS::addServiceTxt(char *service, char *proto, char *key, char *value) { sprintf(txt, "%s=%s", key, value); bool result = addServiceTxtImpl(_service, _proto, txt); - free(_service); + freeIfCopied(service, _service); free(txt); return result; } diff --git a/cores/common/arduino/libraries/common/mDNS/mDNS.h b/cores/common/arduino/libraries/common/mDNS/mDNS.h index 6a15cd39b..ec45010ca 100644 --- a/cores/common/arduino/libraries/common/mDNS/mDNS.h +++ b/cores/common/arduino/libraries/common/mDNS/mDNS.h @@ -51,6 +51,7 @@ class mDNS { private: bool addServiceImpl(const char *name, const char *service, uint8_t proto, uint16_t port); bool addServiceTxtImpl(const char *service, uint8_t proto, const char *item); + void cleanup(); char *instanceName = NULL;