diff --git a/boards/SUMMARY.md b/boards/SUMMARY.md
index 9df0ab5..e26cd5d 100644
--- a/boards/SUMMARY.md
+++ b/boards/SUMMARY.md
@@ -3,6 +3,9 @@
- [BW12](../boards/bw12/README.md)
- [CB2S](../boards/cb2s/README.md)
- [WB2L](../boards/wb2l/README.md)
+- [WB2S](../boards/wb2s/README.md)
+- [WB3L](../boards/wb3l/README.md)
+- [WB3S](../boards/wb3s/README.md)
- [WR2](../boards/wr2/README.md)
- [WR2E](../boards/wr2e/README.md)
- [WR3](../boards/wr3/README.md)
diff --git a/boards/_base/pcb/wb2s-test.json b/boards/_base/pcb/wb2s-test.json
new file mode 100644
index 0000000..0d32c26
--- /dev/null
+++ b/boards/_base/pcb/wb2s-test.json
@@ -0,0 +1,158 @@
+{
+ "pcb": {
+ "test_pads": {
+ "TRST": "wb2s.back.cen.anchor",
+ "TRX2": "wb2s.back.2rx.anchor",
+ "TTX2": "wb2s.back.2tx.anchor",
+ "TGND": "wb2s.back.gnd.anchor",
+ "TSCK": "wb2s.back.sck.anchor",
+ "TCSN": "wb2s.back.csn.anchor",
+ "TSI": "wb2s.back.si.anchor",
+ "TSO": "wb2s.back.adc_so.anchor",
+ "TPWM3": "wb2s.back.pwm3.anchor",
+ "TVCC": "wb2s.back.vbat.anchor"
+ },
+ "back": [
+ {
+ "name": "test_pad_1mm",
+ "pos": "2.6,6.2"
+ },
+ {
+ "id": "sck",
+ "name": "label_line_2mm_up",
+ "pos": "2.6,5.4",
+ "vars": {
+ "DIR": "left",
+ "W": 1.3,
+ "H": 2
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "4.6,6.2"
+ },
+ {
+ "id": "pwm3",
+ "name": "label_line_2mm_up",
+ "pos": "4.6,5.4",
+ "vars": {
+ "DIR": "left",
+ "W": 3.3,
+ "H": 4
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "7.0,6.2"
+ },
+ {
+ "id": "2rx",
+ "name": "label_line_2mm_up",
+ "pos": "7.0,5.4",
+ "vars": {
+ "DIR": "right",
+ "W": 2,
+ "H": 4
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "9.0,6.2"
+ },
+ {
+ "id": "2tx",
+ "name": "label_line_2mm_up",
+ "pos": "9.0,5.4",
+ "vars": {
+ "DIR": "right",
+ "W": 0,
+ "H": 2
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "3.0,8.3"
+ },
+ {
+ "id": "csn",
+ "name": "label_line_2mm_up",
+ "pos": "2.2,8.4",
+ "vars": {
+ "DIR": "left",
+ "W": 0.9,
+ "H": 0
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "5.2,8.8"
+ },
+ {
+ "id": "si",
+ "name": "label_line_2mm_up",
+ "pos": "6.0,8.9",
+ "vars": {
+ "DIR": "right",
+ "W": 3,
+ "H": 0
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "2.1,11.6"
+ },
+ {
+ "id": "adc_so",
+ "name": "label_line_2mm_up",
+ "pos": "1.3,11.7",
+ "vars": {
+ "DIR": "left",
+ "W": 0,
+ "H": 0
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "4.3,11.6"
+ },
+ {
+ "id": "cen",
+ "name": "label_line_2mm_up",
+ "pos": "5.1,11.7",
+ "vars": {
+ "DIR": "right",
+ "W": 3.9,
+ "H": 0
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "2.5,14.5"
+ },
+ {
+ "id": "vbat",
+ "name": "label_line_2mm_up",
+ "pos": "1.7,14.6",
+ "vars": {
+ "DIR": "left",
+ "W": 0.4,
+ "H": 0
+ }
+ },
+ {
+ "name": "test_pad_1mm",
+ "pos": "4.8,14.5"
+ },
+ {
+ "id": "gnd",
+ "name": "label_line_2mm_up",
+ "pos": "5.6,14.6",
+ "vars": {
+ "DIR": "right",
+ "W": 3.4,
+ "H": 0
+ }
+ }
+ ]
+ }
+}
diff --git a/boards/_base/pcb/wb2s.json b/boards/_base/pcb/wb2s.json
new file mode 100644
index 0000000..eaf7cc0
--- /dev/null
+++ b/boards/_base/pcb/wb2s.json
@@ -0,0 +1,102 @@
+{
+ "pcb": {
+ "scale": 10.5,
+ "templates": [
+ "tuya2",
+ "rf-15mm-type1",
+ "tuya2-shield"
+ ],
+ "vars": {
+ "MASK_PRESET": "mask_blue_light",
+ "TRACE_COLOR": "#58839B",
+ "SILK_COLOR": "white"
+ },
+ "pinout_hidden": "I2S,FLASH",
+ "pinout": {
+ "1": {
+ "PWR": 3.3
+ },
+ "2": {
+ "IC": 24,
+ "ARD": "D0"
+ },
+ "3": {
+ "GND": null
+ },
+ "4": {
+ "IC": 23,
+ "ARD": "D1"
+ },
+ "5": {
+ "IC": 26,
+ "ARD": "D4"
+ },
+ "6": {
+ "IC": 22,
+ "ARD": "D2"
+ },
+ "7": {
+ "IC": 27,
+ "ARD": "D5"
+ },
+ "8": {
+ "IC": 17,
+ "ARD": [
+ "D3",
+ "A0"
+ ]
+ },
+ "9": {
+ "IC": 16,
+ "ARD": "D6"
+ },
+ "10": {
+ "IC": 21
+ },
+ "11": {
+ "IC": 15,
+ "ARD": "D7"
+ },
+ "TSCK": {
+ "IC": 20,
+ "ARD": "D8"
+ },
+ "TPWM3": {
+ "IC": 25,
+ "ARD": "D9"
+ },
+ "TRX2": {
+ "IC": 28,
+ "ARD": "D10"
+ },
+ "TTX2": {
+ "IC": 29,
+ "ARD": "D11"
+ },
+ "TCSN": {
+ "IC": 19,
+ "ARD": "D12"
+ },
+ "TSI": {
+ "IC": 18,
+ "ARD": "D13"
+ },
+ "TSO": {
+ "IC": 17,
+ "ARD": [
+ "D3",
+ "A0"
+ ]
+ },
+ "TRST": {
+ "CTRL": "^RST"
+ },
+ "TVCC": {
+ "PWR": 3.3
+ },
+ "TGND": {
+ "GND": null
+ }
+ }
+ }
+}
diff --git a/boards/_base/pcb/wb3l.json b/boards/_base/pcb/wb3l.json
new file mode 100644
index 0000000..b257094
--- /dev/null
+++ b/boards/_base/pcb/wb3l.json
@@ -0,0 +1,106 @@
+{
+ "pcb": {
+ "templates": [
+ "esp12e-21",
+ "esp12e-shield-nohole",
+ "tuya-16x24",
+ "rf-16mm-type1"
+ ],
+ "vars": {
+ "MASK_PRESET": "mask_white",
+ "TRACE_COLOR": "#E0E0E0",
+ "SILK_COLOR": "black",
+ "PINTYPE_VERT": "pin_vert_2mm_cast_nohole",
+ "PINTYPE_HORZ": "pin_horz_2mm_cast_nohole"
+ },
+ "pinout_hidden": "I2S,SD,SPI",
+ "pinout": {
+ "1": {
+ "NC": null
+ },
+ "2": {
+ "IC": 17,
+ "ARD": [
+ "D0",
+ "A0"
+ ]
+ },
+ "3": {
+ "IC": 21
+ },
+ "4": {
+ "IC": 11,
+ "ARD": "D1"
+ },
+ "5": {
+ "IC": 15,
+ "ARD": "D2"
+ },
+ "6": {
+ "IC": 16,
+ "ARD": "D3"
+ },
+ "7": {
+ "IC": 22,
+ "ARD": "D4"
+ },
+ "8": {
+ "PWR": 3.3
+ },
+ "9": {
+ "GND": null
+ },
+ "10": {
+ "IC": 25,
+ "ARD": "D5"
+ },
+ "11": {
+ "IC": 29,
+ "ARD": "D6"
+ },
+ "12": {
+ "IC": 12,
+ "ARD": "D7"
+ },
+ "13": {
+ "IC": 24,
+ "ARD": "D8"
+ },
+ "14": {
+ "IC": 23,
+ "ARD": "D9"
+ },
+ "15": {
+ "IC": 26,
+ "ARD": "D10"
+ },
+ "16": {
+ "IC": 27,
+ "ARD": "D11"
+ },
+ "17": {
+ "IC": 17,
+ "ARD": [
+ "D0",
+ "A0"
+ ]
+ },
+ "18": {
+ "IC": 18,
+ "ARD": "D12"
+ },
+ "19": {
+ "IC": 19,
+ "ARD": "D13"
+ },
+ "20": {
+ "IC": 20,
+ "ARD": "D14"
+ },
+ "21": {
+ "IC": 28,
+ "ARD": "D15"
+ }
+ }
+ }
+}
diff --git a/boards/_base/pcb/wb3s.json b/boards/_base/pcb/wb3s.json
new file mode 100644
index 0000000..2d3f136
--- /dev/null
+++ b/boards/_base/pcb/wb3s.json
@@ -0,0 +1,108 @@
+{
+ "pcb": {
+ "templates": [
+ "esp12e-22",
+ "esp12e-shield-nohole",
+ "tuya-16x24",
+ "rf-16mm-type1"
+ ],
+ "vars": {
+ "MASK_PRESET": "mask_blue_light",
+ "TRACE_COLOR": "#58839B",
+ "SILK_COLOR": "white",
+ "PINTYPE_VERT": "pin_vert_2mm_cast_nohole",
+ "PINTYPE_HORZ": "pin_horz_2mm_cast_nohole"
+ },
+ "pinout_hidden": "I2S,SD,SPI",
+ "pinout": {
+ "1": {
+ "IC": 21
+ },
+ "2": {
+ "IC": 17,
+ "ARD": [
+ "D0",
+ "A0"
+ ]
+ },
+ "3": {
+ "NC": null
+ },
+ "4": {
+ "IC": 11,
+ "ARD": "D1"
+ },
+ "5": {
+ "IC": 15,
+ "ARD": "D2"
+ },
+ "6": {
+ "IC": 16,
+ "ARD": "D3"
+ },
+ "7": {
+ "IC": 22,
+ "ARD": "D4"
+ },
+ "8": {
+ "PWR": 3.3
+ },
+ "9": {
+ "GND": null
+ },
+ "10": {
+ "IC": 23,
+ "ARD": "D5"
+ },
+ "11": {
+ "IC": 29,
+ "ARD": "D6"
+ },
+ "12": {
+ "IC": 28,
+ "ARD": "D7"
+ },
+ "13": {
+ "IC": 25,
+ "ARD": "D8"
+ },
+ "14": {
+ "IC": 24,
+ "ARD": "D9"
+ },
+ "15": {
+ "IC": 26,
+ "ARD": "D10"
+ },
+ "16": {
+ "IC": 27,
+ "ARD": "D11"
+ },
+ "17": {
+ "IC": 17,
+ "ARD": [
+ "D0",
+ "A0"
+ ]
+ },
+ "18": {
+ "IC": 18,
+ "ARD": "D12"
+ },
+ "19": {
+ "IC": 19,
+ "ARD": "D13"
+ },
+ "20": {
+ "IC": 20,
+ "ARD": "D14"
+ },
+ "21": {
+ "NC": null
+ },
+ "22": {
+ "NC": null
+ }
+ }
+ }
+}
diff --git a/boards/wb2s.json b/boards/wb2s.json
new file mode 100644
index 0000000..5522857
--- /dev/null
+++ b/boards/wb2s.json
@@ -0,0 +1,20 @@
+{
+ "_base": [
+ "beken-72xx",
+ "beken-7231t",
+ "beken-7231t-tuya",
+ "pcb/ic-bk7231-qfn32",
+ "pcb/wb2s",
+ "pcb/wb2s-test"
+ ],
+ "build": {
+ "mcu": "bk7231t",
+ "variant": "wb2s"
+ },
+ "name": "WB2S Wi-Fi Module",
+ "url": "https://developer.tuya.com/en/docs/iot/wb2s-module-datasheet?id=K9ghecl7kc479",
+ "vendor": "Tuya Inc.",
+ "pcb": {
+ "symbol": "WB2S"
+ }
+}
diff --git a/boards/wb2s/README.md b/boards/wb2s/README.md
new file mode 100644
index 0000000..765d427
--- /dev/null
+++ b/boards/wb2s/README.md
@@ -0,0 +1,64 @@
+# WB2S Wi-Fi Module
+
+*by Tuya Inc.*
+
+[Product page](https://developer.tuya.com/en/docs/iot/wb2s-module-datasheet?id=K9ghecl7kc479)
+
+- [General info](../../docs/platform/beken-72xx/README.md)
+- [Flashing guide](../../docs/platform/beken-72xx/flashing.md)
+- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
+
+Parameter | Value
+-------------|----------------------------------
+MCU | BK7231T
+Manufacturer | Beken
+Series | BK72XX
+Frequency | 120 MHz
+Flash size | 2 MiB
+RAM size | 256 KiB
+Voltage | 3.0V - 3.6V
+I/O | 14x GPIO, 6x PWM, 2x UART, 1x ADC
+Wi-Fi | 802.11 b/g/n
+Bluetooth | BLE v4.2
+
+## Pinout
+
+
+
+## Arduino Core pin mapping
+
+No. | Pin | UART | I²C | SPI | PWM | Other
+----|-----------|----------|----------|-----|------|------
+D0 | P8 | | | | PWM2 |
+D1 | P7 | | | | PWM1 |
+D2 | P6 | | | | PWM0 |
+D3 | P23 | | | | | TDO
+D4 | P10 | UART1_RX | | | |
+D5 | P11 | UART1_TX | | | |
+D6 | P24 | | | | PWM4 |
+D7 | P26 | | | | PWM5 |
+D8 | P20 | | I2C1_SCL | | | TCK
+D9 | P9 | | | | PWM3 |
+D10 | P1 | UART2_RX | I2C2_SDA | | |
+D11 | P0 | UART2_TX | I2C2_SCL | | |
+D12 | P21 | | I2C1_SDA | | | TMS
+D13 | P22 | | | | | TDI
+A0 | P23, ADC3 | | | | |
+
+## Flash memory map
+
+Flash size: 2 MiB / 2,097,152 B / 0x200000
+
+Hex values are in bytes.
+
+Name | Start | Length | End
+----------------|----------|--------------------|---------
+Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
+App Image | 0x011000 | 1.1 MiB / 0x121000 | 0x132000
+OTA Image | 0x132000 | 664 KiB / 0xA6000 | 0x1D8000
+Key-Value Store | 0x1D8000 | 32 KiB / 0x8000 | 0x1E0000
+TLV Store | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
+Network Data | 0x1E1000 | 8 KiB / 0x2000 | 0x1E3000
+User Data | 0x1E3000 | 116 KiB / 0x1D000 | 0x200000
+
+Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes.
diff --git a/boards/wb2s/pinout_wb2s.svg b/boards/wb2s/pinout_wb2s.svg
new file mode 100644
index 0000000..5ecf3d1
--- /dev/null
+++ b/boards/wb2s/pinout_wb2s.svg
@@ -0,0 +1,391 @@
+
+
diff --git a/boards/wb2s/pins_arduino.h b/boards/wb2s/pins_arduino.h
new file mode 100644
index 0000000..1de3ade
--- /dev/null
+++ b/boards/wb2s/pins_arduino.h
@@ -0,0 +1 @@
+#include "variant.h"
diff --git a/boards/wb2s/variant.cpp b/boards/wb2s/variant.cpp
new file mode 100644
index 0000000..d0d6bc3
--- /dev/null
+++ b/boards/wb2s/variant.cpp
@@ -0,0 +1,40 @@
+/* This file was auto-generated from wb2s.json using boardgen */
+
+#include
+
+extern "C" {
+
+// clang-format off
+PinInfo pinTable[PINS_COUNT] = {
+ // D0: P8, PWM2
+ {GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D1: P7, PWM1
+ {GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D2: P6, PWM0
+ {GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D3: P23, ADC3, TDO, FSO
+ {GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
+ // D4: P10, UART1_RX
+ {GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D5: P11, UART1_TX
+ {GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D6: P24, PWM4
+ {GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D7: P26, PWM5, IRDA
+ {GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D8: P20, I2C1_SCL, TCK, FSCK
+ {GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
+ // D9: P9, PWM3
+ {GPIO9, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D10: P1, UART2_RX, I2C2_SDA
+ {GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+ // D11: P0, UART2_TX, I2C2_SCL
+ {GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+ // D12: P21, I2C1_SDA, TMS, MCLK, ^FCS
+ {GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
+ // D13: P22, TDI, FSI
+ {GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
+};
+// clang-format on
+
+} // extern "C"
diff --git a/boards/wb2s/variant.h b/boards/wb2s/variant.h
new file mode 100644
index 0000000..0efe8d0
--- /dev/null
+++ b/boards/wb2s/variant.h
@@ -0,0 +1,41 @@
+/* This file was auto-generated from wb2s.json using boardgen */
+
+#pragma once
+
+#include
+
+// clang-format off
+
+// Pins
+// ----
+#define PINS_COUNT 14
+#define NUM_DIGITAL_PINS 14
+#define NUM_ANALOG_INPUTS 1
+#define NUM_ANALOG_OUTPUTS 0
+
+// Analog pins
+// -----------
+#define PIN_A0 3u // GPIO23
+#define PIN_A0 3u // GPIO23
+#define A0 PIN_A0
+#define A0 PIN_A0
+
+// SPI Interfaces
+// --------------
+#define SPI_INTERFACES_COUNT 0
+
+// Wire Interfaces
+// ---------------
+#define WIRE_INTERFACES_COUNT 2
+#define PIN_WIRE1_SCL 8u // GPIO20
+#define PIN_WIRE1_SDA 12u // GPIO21
+#define PIN_WIRE2_SCL 11u // GPIO0
+#define PIN_WIRE2_SDA 10u // GPIO1
+
+// Serial ports
+// ------------
+#define SERIAL_INTERFACES_COUNT 2
+#define PIN_SERIAL1_RX 4u // GPIO10
+#define PIN_SERIAL1_TX 5u // GPIO11
+#define PIN_SERIAL2_RX 10u // GPIO1
+#define PIN_SERIAL2_TX 11u // GPIO0
diff --git a/boards/wb3l.json b/boards/wb3l.json
new file mode 100644
index 0000000..62d92b2
--- /dev/null
+++ b/boards/wb3l.json
@@ -0,0 +1,19 @@
+{
+ "_base": [
+ "beken-72xx",
+ "beken-7231t",
+ "beken-7231t-tuya",
+ "pcb/ic-bk7231-qfn32",
+ "pcb/wb3l"
+ ],
+ "build": {
+ "mcu": "bk7231t",
+ "variant": "wb3l"
+ },
+ "name": "WB3L Wi-Fi Module",
+ "url": "https://developer.tuya.com/en/docs/iot/wb3l-module-datasheet?id=K9duiggw2v8sp",
+ "vendor": "Tuya Inc.",
+ "pcb": {
+ "symbol": "WB3L"
+ }
+}
diff --git a/boards/wb3l/README.md b/boards/wb3l/README.md
new file mode 100644
index 0000000..eddd905
--- /dev/null
+++ b/boards/wb3l/README.md
@@ -0,0 +1,66 @@
+# WB3L Wi-Fi Module
+
+*by Tuya Inc.*
+
+[Product page](https://developer.tuya.com/en/docs/iot/wb3l-module-datasheet?id=K9duiggw2v8sp)
+
+- [General info](../../docs/platform/beken-72xx/README.md)
+- [Flashing guide](../../docs/platform/beken-72xx/flashing.md)
+- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
+
+Parameter | Value
+-------------|----------------------------------
+MCU | BK7231T
+Manufacturer | Beken
+Series | BK72XX
+Frequency | 120 MHz
+Flash size | 2 MiB
+RAM size | 256 KiB
+Voltage | 3.0V - 3.6V
+I/O | 16x GPIO, 6x PWM, 2x UART, 1x ADC
+Wi-Fi | 802.11 b/g/n
+Bluetooth | BLE v4.2
+
+## Pinout
+
+
+
+## Arduino Core pin mapping
+
+No. | Pin | UART | I²C | SPI | PWM | Other
+----|-----------|----------|----------|------|------|------
+D0 | P23 | | | | | TDO
+D1 | P14 | | | SCK | |
+D2 | P26 | | | | PWM5 |
+D3 | P24 | | | | PWM4 |
+D4 | P6 | | | | PWM0 |
+D5 | P9 | | | | PWM3 |
+D6 | P0 | UART2_TX | I2C2_SCL | | |
+D7 | P16 | | | MOSI | |
+D8 | P8 | | | | PWM2 |
+D9 | P7 | | | | PWM1 |
+D10 | P10 | UART1_RX | | | |
+D11 | P11 | UART1_TX | | | |
+D12 | P22 | | | | | TDI
+D13 | P21 | | I2C1_SDA | | | TMS
+D14 | P20 | | I2C1_SCL | | | TCK
+D15 | P1 | UART2_RX | I2C2_SDA | | |
+A0 | P23, ADC3 | | | | |
+
+## Flash memory map
+
+Flash size: 2 MiB / 2,097,152 B / 0x200000
+
+Hex values are in bytes.
+
+Name | Start | Length | End
+----------------|----------|--------------------|---------
+Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
+App Image | 0x011000 | 1.1 MiB / 0x121000 | 0x132000
+OTA Image | 0x132000 | 664 KiB / 0xA6000 | 0x1D8000
+Key-Value Store | 0x1D8000 | 32 KiB / 0x8000 | 0x1E0000
+TLV Store | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
+Network Data | 0x1E1000 | 8 KiB / 0x2000 | 0x1E3000
+User Data | 0x1E3000 | 116 KiB / 0x1D000 | 0x200000
+
+Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes.
diff --git a/boards/wb3l/pinout_wb3l.svg b/boards/wb3l/pinout_wb3l.svg
new file mode 100644
index 0000000..26cd9a6
--- /dev/null
+++ b/boards/wb3l/pinout_wb3l.svg
@@ -0,0 +1,372 @@
+
+
diff --git a/boards/wb3l/pins_arduino.h b/boards/wb3l/pins_arduino.h
new file mode 100644
index 0000000..1de3ade
--- /dev/null
+++ b/boards/wb3l/pins_arduino.h
@@ -0,0 +1 @@
+#include "variant.h"
diff --git a/boards/wb3l/variant.cpp b/boards/wb3l/variant.cpp
new file mode 100644
index 0000000..41ddfce
--- /dev/null
+++ b/boards/wb3l/variant.cpp
@@ -0,0 +1,44 @@
+/* This file was auto-generated from wb3l.json using boardgen */
+
+#include
+
+extern "C" {
+
+// clang-format off
+PinInfo pinTable[PINS_COUNT] = {
+ // D0: P23, ADC3, TDO, FSO
+ {GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
+ // D1: P14, SD_CLK, SCK
+ {GPIO14, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
+ // D2: P26, PWM5, IRDA
+ {GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D3: P24, PWM4
+ {GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D4: P6, PWM0
+ {GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D5: P9, PWM3
+ {GPIO9, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D6: P0, UART2_TX, I2C2_SCL
+ {GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+ // D7: P16, SD_D0, MOSI
+ {GPIO16, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
+ // D8: P8, PWM2
+ {GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D9: P7, PWM1
+ {GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D10: P10, UART1_RX
+ {GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D11: P11, UART1_TX
+ {GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D12: P22, TDI, FSI
+ {GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
+ // D13: P21, I2C1_SDA, TMS, MCLK, ^FCS
+ {GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
+ // D14: P20, I2C1_SCL, TCK, FSCK
+ {GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
+ // D15: P1, UART2_RX, I2C2_SDA
+ {GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+};
+// clang-format on
+
+} // extern "C"
diff --git a/boards/wb3l/variant.h b/boards/wb3l/variant.h
new file mode 100644
index 0000000..0b945a3
--- /dev/null
+++ b/boards/wb3l/variant.h
@@ -0,0 +1,41 @@
+/* This file was auto-generated from wb3l.json using boardgen */
+
+#pragma once
+
+#include
+
+// clang-format off
+
+// Pins
+// ----
+#define PINS_COUNT 16
+#define NUM_DIGITAL_PINS 16
+#define NUM_ANALOG_INPUTS 1
+#define NUM_ANALOG_OUTPUTS 0
+
+// Analog pins
+// -----------
+#define PIN_A0 0u // GPIO23
+#define PIN_A0 0u // GPIO23
+#define A0 PIN_A0
+#define A0 PIN_A0
+
+// SPI Interfaces
+// --------------
+#define SPI_INTERFACES_COUNT 0
+
+// Wire Interfaces
+// ---------------
+#define WIRE_INTERFACES_COUNT 2
+#define PIN_WIRE1_SCL 14u // GPIO20
+#define PIN_WIRE1_SDA 13u // GPIO21
+#define PIN_WIRE2_SCL 6u // GPIO0
+#define PIN_WIRE2_SDA 15u // GPIO1
+
+// Serial ports
+// ------------
+#define SERIAL_INTERFACES_COUNT 2
+#define PIN_SERIAL1_RX 10u // GPIO10
+#define PIN_SERIAL1_TX 11u // GPIO11
+#define PIN_SERIAL2_RX 15u // GPIO1
+#define PIN_SERIAL2_TX 6u // GPIO0
diff --git a/boards/wb3s.json b/boards/wb3s.json
new file mode 100644
index 0000000..61a91c0
--- /dev/null
+++ b/boards/wb3s.json
@@ -0,0 +1,19 @@
+{
+ "_base": [
+ "beken-72xx",
+ "beken-7231t",
+ "beken-7231t-tuya",
+ "pcb/ic-bk7231-qfn32",
+ "pcb/wb3s"
+ ],
+ "build": {
+ "mcu": "bk7231t",
+ "variant": "wb3s"
+ },
+ "name": "WB3S Wi-Fi Module",
+ "url": "https://developer.tuya.com/en/docs/iot/wb3s-module-datasheet?id=K9dx20n6hz5n4",
+ "vendor": "Tuya Inc.",
+ "pcb": {
+ "symbol": "WB3S"
+ }
+}
diff --git a/boards/wb3s/README.md b/boards/wb3s/README.md
new file mode 100644
index 0000000..b103cf6
--- /dev/null
+++ b/boards/wb3s/README.md
@@ -0,0 +1,65 @@
+# WB3S Wi-Fi Module
+
+*by Tuya Inc.*
+
+[Product page](https://developer.tuya.com/en/docs/iot/wb3s-module-datasheet?id=K9dx20n6hz5n4)
+
+- [General info](../../docs/platform/beken-72xx/README.md)
+- [Flashing guide](../../docs/platform/beken-72xx/flashing.md)
+- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
+
+Parameter | Value
+-------------|----------------------------------
+MCU | BK7231T
+Manufacturer | Beken
+Series | BK72XX
+Frequency | 120 MHz
+Flash size | 2 MiB
+RAM size | 256 KiB
+Voltage | 3.0V - 3.6V
+I/O | 15x GPIO, 6x PWM, 2x UART, 1x ADC
+Wi-Fi | 802.11 b/g/n
+Bluetooth | BLE v4.2
+
+## Pinout
+
+
+
+## Arduino Core pin mapping
+
+No. | Pin | UART | I²C | SPI | PWM | Other
+----|-----------|----------|----------|-----|------|------
+D0 | P23 | | | | | TDO
+D1 | P14 | | | SCK | |
+D2 | P26 | | | | PWM5 |
+D3 | P24 | | | | PWM4 |
+D4 | P6 | | | | PWM0 |
+D5 | P7 | | | | PWM1 |
+D6 | P0 | UART2_TX | I2C2_SCL | | |
+D7 | P1 | UART2_RX | I2C2_SDA | | |
+D8 | P9 | | | | PWM3 |
+D9 | P8 | | | | PWM2 |
+D10 | P10 | UART1_RX | | | |
+D11 | P11 | UART1_TX | | | |
+D12 | P22 | | | | | TDI
+D13 | P21 | | I2C1_SDA | | | TMS
+D14 | P20 | | I2C1_SCL | | | TCK
+A0 | P23, ADC3 | | | | |
+
+## Flash memory map
+
+Flash size: 2 MiB / 2,097,152 B / 0x200000
+
+Hex values are in bytes.
+
+Name | Start | Length | End
+----------------|----------|--------------------|---------
+Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
+App Image | 0x011000 | 1.1 MiB / 0x121000 | 0x132000
+OTA Image | 0x132000 | 664 KiB / 0xA6000 | 0x1D8000
+Key-Value Store | 0x1D8000 | 32 KiB / 0x8000 | 0x1E0000
+TLV Store | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
+Network Data | 0x1E1000 | 8 KiB / 0x2000 | 0x1E3000
+User Data | 0x1E3000 | 116 KiB / 0x1D000 | 0x200000
+
+Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes.
diff --git a/boards/wb3s/pinout_wb3s.svg b/boards/wb3s/pinout_wb3s.svg
new file mode 100644
index 0000000..9533b88
--- /dev/null
+++ b/boards/wb3s/pinout_wb3s.svg
@@ -0,0 +1,370 @@
+
+
diff --git a/boards/wb3s/pins_arduino.h b/boards/wb3s/pins_arduino.h
new file mode 100644
index 0000000..1de3ade
--- /dev/null
+++ b/boards/wb3s/pins_arduino.h
@@ -0,0 +1 @@
+#include "variant.h"
diff --git a/boards/wb3s/variant.cpp b/boards/wb3s/variant.cpp
new file mode 100644
index 0000000..3b4e22b
--- /dev/null
+++ b/boards/wb3s/variant.cpp
@@ -0,0 +1,42 @@
+/* This file was auto-generated from wb3s.json using boardgen */
+
+#include
+
+extern "C" {
+
+// clang-format off
+PinInfo pinTable[PINS_COUNT] = {
+ // D0: P23, ADC3, TDO, FSO
+ {GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
+ // D1: P14, SD_CLK, SCK
+ {GPIO14, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
+ // D2: P26, PWM5, IRDA
+ {GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D3: P24, PWM4
+ {GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D4: P6, PWM0
+ {GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D5: P7, PWM1
+ {GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D6: P0, UART2_TX, I2C2_SCL
+ {GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+ // D7: P1, UART2_RX, I2C2_SDA
+ {GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
+ // D8: P9, PWM3
+ {GPIO9, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D9: P8, PWM2
+ {GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
+ // D10: P10, UART1_RX
+ {GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D11: P11, UART1_TX
+ {GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
+ // D12: P22, TDI, FSI
+ {GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
+ // D13: P21, I2C1_SDA, TMS, MCLK, ^FCS
+ {GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
+ // D14: P20, I2C1_SCL, TCK, FSCK
+ {GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
+};
+// clang-format on
+
+} // extern "C"
diff --git a/boards/wb3s/variant.h b/boards/wb3s/variant.h
new file mode 100644
index 0000000..2fe27b3
--- /dev/null
+++ b/boards/wb3s/variant.h
@@ -0,0 +1,41 @@
+/* This file was auto-generated from wb3s.json using boardgen */
+
+#pragma once
+
+#include
+
+// clang-format off
+
+// Pins
+// ----
+#define PINS_COUNT 15
+#define NUM_DIGITAL_PINS 15
+#define NUM_ANALOG_INPUTS 1
+#define NUM_ANALOG_OUTPUTS 0
+
+// Analog pins
+// -----------
+#define PIN_A0 0u // GPIO23
+#define PIN_A0 0u // GPIO23
+#define A0 PIN_A0
+#define A0 PIN_A0
+
+// SPI Interfaces
+// --------------
+#define SPI_INTERFACES_COUNT 0
+
+// Wire Interfaces
+// ---------------
+#define WIRE_INTERFACES_COUNT 2
+#define PIN_WIRE1_SCL 14u // GPIO20
+#define PIN_WIRE1_SDA 13u // GPIO21
+#define PIN_WIRE2_SCL 6u // GPIO0
+#define PIN_WIRE2_SDA 7u // GPIO1
+
+// Serial ports
+// ------------
+#define SERIAL_INTERFACES_COUNT 2
+#define PIN_SERIAL1_RX 10u // GPIO10
+#define PIN_SERIAL1_TX 11u // GPIO11
+#define PIN_SERIAL2_RX 7u // GPIO1
+#define PIN_SERIAL2_TX 6u // GPIO0
diff --git a/docs/supported_boards.md b/docs/supported_boards.md
index 7fe23ae..6e21e11 100644
--- a/docs/supported_boards.md
+++ b/docs/supported_boards.md
@@ -7,6 +7,9 @@ Name | MCU | Flash | RAM | Pin
**Tuya Inc.** | | | | | | | |
[CB2S](../boards/cb2s/README.md) | BK7231N | 2 MiB | 256 KiB | 11 (8 I/O) | ✔️ | ✔️ | ❌ | `beken-7231n`
[WB2L](../boards/wb2l/README.md) | BK7231T | 2 MiB | 256 KiB | 7 (5 I/O) | ✔️ | ✔️ | ❌ | `beken-7231t`
+[WB2S](../boards/wb2s/README.md) | BK7231T | 2 MiB | 256 KiB | 11 (8 I/O) | ✔️ | ✔️ | ❌ | `beken-7231t`
+[WB3L](../boards/wb3l/README.md) | BK7231T | 2 MiB | 256 KiB | 21 (17 I/O) | ✔️ | ✔️ | ❌ | `beken-7231t`
+[WB3S](../boards/wb3s/README.md) | BK7231T | 2 MiB | 256 KiB | 22 (16 I/O) | ✔️ | ✔️ | ❌ | `beken-7231t`
[WR2](../boards/wr2/README.md) | RTL8710BN | 2 MiB | 256 KiB | 11 (8 I/O) | ✔️ | ❌ | ❌ | `realtek-ambz`
[WR2E](../boards/wr2e/README.md) | RTL8710BN | 2 MiB | 256 KiB | 11 (8 I/O) | ✔️ | ❌ | ❌ | `realtek-ambz`
[WR3](../boards/wr3/README.md) | RTL8710BN | 2 MiB | 256 KiB | 16 (12 I/O) | ✔️ | ❌ | ❌ | `realtek-ambz`
diff --git a/docs/unsupported_boards_tuya_all.md b/docs/unsupported_boards_tuya_all.md
index c34bb45..735f966 100644
--- a/docs/unsupported_boards_tuya_all.md
+++ b/docs/unsupported_boards_tuya_all.md
@@ -19,9 +19,6 @@ CR2S | RTL8720CM | 4 MiB | 4 MiB | 11 | ✔️ | ✔️ | ❌
CR3L | RTL8720CM | 4 MiB | 4 MiB | 18 | ✔️ | ✔️ | ❌
**WB Series** | | | | | | |
WB1S | BK7231T | 2 MiB | 256 KiB | 18 | ✔️ | ✔️ | ❌
-WB2S | BK7231T | 2 MiB | 256 KiB | 11 | ✔️ | ✔️ | ❌
-WB3L | BK7231T | 2 MiB | 256 KiB | 18 | ✔️ | ✔️ | ❌
-WB3S | BK7231T | 2 MiB | 256 KiB | 22 | ✔️ | ✔️ | ❌
WB8P | BK7231T | 2 MiB | 256 KiB | 10 | ✔️ | ✔️ | ❌
WBLC5 | BK7231T | 2 MiB | 256 KiB | 15 | ✔️ | ✔️ | ❌
WBLC9 | BK7231T | 2 MiB | 256 KiB | 8 | ✔️ | ✔️ | ❌
diff --git a/tools/boardgen b/tools/boardgen
index cff42b3..76d89af 160000
--- a/tools/boardgen
+++ b/tools/boardgen
@@ -1 +1 @@
-Subproject commit cff42b3da821c191a5df307fb76e5fe04d2b704e
+Subproject commit 76d89af332a4eef56cd181e9df0c79548aad77ba