48 Commits

Author SHA1 Message Date
Kuba Szczodrzyński
71dfea1904 [release] v0.11.0
Some checks failed
Lint check / Lint with clang-format (push) Has been cancelled
Lint check / Lint with black (push) Has been cancelled
PlatformIO Publish / publish (push) Has been cancelled
2022-12-07 17:43:19 +01:00
Kuba Szczodrzyński
4fa7457423 [boards] Update boardgen and generated board files 2022-12-07 17:03:41 +01:00
kolos
9583bb35f5 [core] Include SNTP app from lwIP (#38) 2022-12-06 22:47:22 +01:00
Kuba Szczodrzyński
e806c4db3a [docs] Output boards.json to site/ directory 2022-12-06 21:37:26 +01:00
Kuba Szczodrzyński
665ab22de5 [docs] Generate JSON file with supported boards 2022-12-06 21:34:46 +01:00
Kuba Szczodrzyński
ec4e946643 [core] Add restartDownloadMode() method 2022-11-26 19:36:10 +01:00
Kuba Szczodrzyński
9e4bbe3e36 [realtek-ambz] Fix software rebooting 2022-11-26 19:35:40 +01:00
Kuba Szczodrzyński
1172c1a852 [realtek-ambz] Update lwIP to v2.1.3 2022-11-26 15:32:33 +01:00
Stroe Andrei Catalin
8a4392bb22 [beken-72xx] Add support for CHANGE interrupts (#34)
* [beken-72xx] Added support for ANY_EDGE interrupts

* clang format

* PR comments

* Update wiring_irq.c

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2022-10-21 22:19:10 +02:00
Stroe Andrei Catalin
a79a2d60d3 [core] Use mDNS hostname as instance name by default (#32) 2022-10-15 16:39:54 +02:00
blakadder
9553ff66a3 [docs] Update docs URL in basic README (#31) 2022-10-08 22:35:08 +02:00
blakadder
79c6f05291 [docs] Update site_url (#30)
* update site url to new one

* Update mkdocs.yml

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2022-10-08 22:34:50 +02:00
David Buezas
3e691de24a [beken-72xx] Fix micros() usage with disabled interrupts (#28)
* Workaround for micros when used inside interruptLock blocks

* Fix comment formatting

* Cover case when millis overflows

* Improve variable names.
2022-10-05 12:51:20 +02:00
David Buezas
303def49cb [beken-72xx] Implement accurate delayMicroseconds() (#26)
* Implements accurate delayMicroseconds

* renamed to cammelCase, moved #defines and clang-formatted
2022-10-03 15:14:31 +02:00
Kuba Szczodrzyński
18653781d5 [beken-72xx] Replace delay() define with inline function 2022-10-03 15:12:15 +02:00
Kuba Szczodrzyński
2a75bdbeda [beken-72xx] Update TLV and calibration flash layout 2022-10-01 15:01:38 +02:00
Kuba Szczodrzyński
4a6926eb6c [beken-72xx] Fix restarting AP with shorter password 2022-10-01 15:00:08 +02:00
Kuba Szczodrzyński
3dc4007fa7 [core] Update ltchiptool to fix realtek-ambz OTA issue 2022-09-30 18:42:09 +02:00
Kuba Szczodrzyński
9c3833d66c [realtek-ambz] Provide unknown reset reason 2022-09-27 12:53:08 +02:00
Kuba Szczodrzyński
41966f33c2 [github] Add FUNDING.yml 2022-09-25 22:26:25 +02:00
Kuba Szczodrzyński
50fea2a8f0 [boards] Add RTL8710BX board with 4 MiB flash 2022-09-23 12:25:30 +02:00
Kuba Szczodrzyński
05cb7f7947 [realtek-ambz] Implement watchdog API 2022-09-21 21:46:11 +02:00
Kuba Szczodrzyński
5b6b80e3cd [tools] Migrate to bk7231tools from PyPI 2022-09-21 21:41:08 +02:00
Kuba Szczodrzyński
2c59af8399 [docs] Add Beken flash support list 2022-09-21 21:24:59 +02:00
Kuba Szczodrzyński
b404f9fa42 [core] Append revision info to version string 2022-09-15 19:59:34 +02:00
Kuba Szczodrzyński
8dc8340ce4 [realtek-ambz] Use GCC 5.2.1 to fix ranlib missing 2022-09-15 18:37:19 +02:00
Kuba Szczodrzyński
30f08a145e [realtek-ambz] Export SoftwareSerial availability macro 2022-09-15 18:31:20 +02:00
Kuba Szczodrzyński
d3d140fa60 [builder] Fix Python lint 2022-09-15 17:38:08 +02:00
Kuba Szczodrzyński
5f8e687e68 [core] Fix getResetReasonName() API 2022-09-15 14:51:14 +02:00
Kuba Szczodrzyński
fab640901d [core] Add textual reset reason API 2022-09-15 13:55:16 +02:00
Kuba Szczodrzyński
9a053fb6ff [core] Export LT class as ESP alias 2022-09-15 13:53:12 +02:00
Kuba Szczodrzyński
24e4b0b376 [builder] Use ranlib from the toolchain 2022-09-15 12:16:22 +02:00
Kuba Szczodrzyński
b8eee999e2 [docs] Add remaining config options, add warning about latest version 2022-09-15 11:47:25 +02:00
Kuba Szczodrzyński
7fe9a114b7 [beken-72xx] Auto-reboot after detecting download-mode commands 2022-09-14 19:57:23 +02:00
Kuba Szczodrzyński
05b2fb4fcb [beken-72xx] Implement micros() properly; use high-res timer for OS 2022-09-14 19:56:51 +02:00
Kuba Szczodrzyński
830d8762cd [beken-72xx] Disable watchdog feeding in BDK 2022-09-14 19:55:10 +02:00
Kuba Szczodrzyński
3f81666369 [beken-72xx] Implement watchdog & reset reason APIs 2022-09-13 17:42:13 +02:00
Kuba Szczodrzyński
d40f4003b5 [boards] Add FCC ID to board docs 2022-09-11 16:39:15 +02:00
Kuba Szczodrzyński
1585e425ce [boards] Add CB2L board 2022-09-11 16:20:48 +02:00
Kuba Szczodrzyński
bbc7613079 [boards] Add remaining CB3x series boards 2022-09-11 14:26:02 +02:00
Kuba Szczodrzyński
ec54745174 [docs] Update Tuya all boards list 2022-09-11 14:24:51 +02:00
Kuba Szczodrzyński
a29453de12 [docs] Add 3-rd party libs used in ESPHome 2022-09-10 19:08:57 +02:00
Kuba Szczodrzyński
db5bf4fc46 [docs] Add dumping instructions 2022-09-10 18:24:10 +02:00
Kuba Szczodrzyński
9495e3418c [beken-72xx] Fake enabling AP to fix connection issues, set default IP 2022-09-10 16:44:45 +02:00
Kuba Szczodrzyński
83573a743b [core] Implement WiFiUDP based on lwIP 2022-09-10 16:15:28 +02:00
Kuba Szczodrzyński
f5dcd82747 [core] Add printf format attribute to lt_log() 2022-09-10 16:14:38 +02:00
Kuba Szczodrzyński
070ec2f48f [core] Update ArduinoCore-API to support Print::printf() 2022-09-10 16:14:10 +02:00
Kuba Szczodrzyński
96c7fdc02c [beken-72xx] Reset scan state after timeout 2022-09-09 20:21:33 +02:00
164 changed files with 5651 additions and 144 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
ko_fi: kuba2k2
custom:
- "https://paypal.me/kuba2k2"

View File

@@ -13,6 +13,20 @@ jobs:
- name: Checkout main
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install ltchiptool
run: pip install ltchiptool
- name: Generate static JSON files
run: |
mkdir -p site/
python docs/build_json.py
cp *.json site/
- name: Set custom domain
run: |
mkdir -p site/

View File

@@ -6,16 +6,19 @@
* Examples
* [PinScan](examples/PinScan/README.md)
* [ESPHome port](docs/projects/esphome.md)
* [Using tuya-cloudcutter](docs/cloudcutter.md)
* [Using tuya-cloudcutter](docs/getting-started/cloudcutter.md)
* [Auto-download-reboot](docs/getting-started/adr.md)
* [💻 Boards & CPU list](docs/status/supported.md)
* [✔️ Implementation status](docs/status/arduino.md)
* Supported chip families
* Beken BK72xx
* [General info](docs/platform/beken-72xx/README.md)
* [Flashing](docs/platform/beken-72xx/flashing.md)
* [Dumping](docs/platform/beken-72xx/dumping.md)
* Realtek AmebaZ Series
* [General info](docs/platform/realtek/README.md)
* [Flashing (AmebaZ)](docs/platform/realtek-ambz/flashing.md)
* [Dumping (AmebaZ)](docs/platform/realtek-ambz/dumping.md)
* [Debugging](docs/platform/realtek/debugging.md)
* [Exception decoder](docs/platform/realtek/exception-decoder.md)
* C library

View File

@@ -6,8 +6,10 @@
#include "WCharacterFixup.h"
#endif
#define delay delayMilliseconds // change delay()'s signature - it's defined as static inline in WVariant.h
#include <api/ArduinoAPI.h>
#include <core/LibreTuyaAPI.h>
#undef delay
// Include family-specific code
#include "WVariant.h"

View File

@@ -17,11 +17,14 @@ extern "C" {
#include <flash_pub.h>
#include <param_config.h>
#include <start_type_pub.h>
#include <sys_ctrl.h>
#include <sys_rtos.h>
#include <wdt_pub.h>
#include <wlan_ui_pub.h>
extern uint8_t system_mac[];
extern uint32_t wdt_ctrl(uint32_t cmd, void *param);
} // extern "C"
@@ -29,6 +32,36 @@ void LibreTuya::restart() {
bk_reboot();
}
void LibreTuya::restartDownloadMode() {
bk_reboot();
}
ResetReason LibreTuya::getResetReason() {
switch (bk_misc_get_start_type()) {
case RESET_SOURCE_POWERON:
return RESET_REASON_POWER;
case RESET_SOURCE_REBOOT:
return RESET_REASON_SOFTWARE;
case RESET_SOURCE_WATCHDOG:
return RESET_REASON_WATCHDOG;
case RESET_SOURCE_CRASH_XAT0:
case RESET_SOURCE_CRASH_UNDEFINED:
case RESET_SOURCE_CRASH_PREFETCH_ABORT:
case RESET_SOURCE_CRASH_DATA_ABORT:
case RESET_SOURCE_CRASH_UNUSED:
case RESET_SOURCE_CRASH_PER_XAT0:
return RESET_REASON_CRASH;
case RESET_SOURCE_DEEPPS_GPIO:
case RESET_SOURCE_DEEPPS_RTC:
return RESET_REASON_SLEEP;
}
return RESET_REASON_UNKNOWN;
}
/* CPU-related */
ChipType LibreTuya::getChipType() {
@@ -154,6 +187,22 @@ bool LibreTuya::otaSwitch(bool force) {
return otaHasImage2(); // false if second image is not valid
}
/* Watchdog */
bool LibreTuya::wdtEnable(uint32_t timeout) {
wdt_ctrl(WCMD_SET_PERIOD, &timeout);
wdt_ctrl(WCMD_POWER_UP, NULL);
}
void LibreTuya::wdtDisable() {
wdt_ctrl(WCMD_POWER_DOWN, NULL);
}
void LibreTuya::wdtFeed() {
wdt_ctrl(WCMD_RELOAD_PERIOD, NULL);
}
/* Global instance */
LibreTuya LT;
LibreTuya ESP = LT;

View File

@@ -24,10 +24,29 @@ SerialClass::SerialClass(uint8_t port) {
this->buf = NULL;
}
#if LT_AUTO_DOWNLOAD_REBOOT
static uint8_t adrState = 0;
static const uint8_t adrCmd[] = {0x01, 0xE0, 0xFC, 0x01, 0x00};
static void adrParse(uint8_t c) {
// parse and respond to link check command (CMD_LinkCheck=0)
adrState = (adrState + 1) * (c == adrCmd[adrState]);
if (adrState == 5) {
LT_I("Auto download mode: rebooting");
LT.restart();
}
}
#endif
static void callback(int port, void *param) {
RingBuffer *buf = (RingBuffer *)param;
int ch;
while ((ch = uart_read_byte(port)) != -1) {
#if LT_AUTO_DOWNLOAD_REBOOT && defined(PIN_SERIAL1_RX)
// parse UART protocol commands on UART1
if (port == UART1_PORT)
adrParse(ch);
#endif
buf->store_char(ch);
}
}

View File

@@ -9,9 +9,10 @@ extern "C" {
#include "sdk_extern.h"
#include "sdk_mem.h"
// allow BDK use its own delay() and let Arduino code use delayMilliseconds()
void delayMilliseconds(unsigned long);
#define delay delayMilliseconds
// define an inline delay() which overrides BDK's delay()
static inline __attribute__((always_inline)) void delay(unsigned long ms) {
delayMilliseconds(ms);
}
// from fixups/arch_main.c
extern unsigned char __bk_rf_is_init;

View File

@@ -16,6 +16,10 @@ beken_thread_t mainThread;
void initArduino() {
// set default UART output port
uart_print_port = LT_UART_DEFAULT_PORT - 1;
#if LT_AUTO_DOWNLOAD_REBOOT && defined(PIN_SERIAL1_RX) && defined(PIN_SERIAL1_TX)
// initialize auto-download-reboot parser
Serial1.begin(115200);
#endif
}
bool startMainTask() {

View File

@@ -1,20 +1,56 @@
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
#include <Arduino.h>
#include <arm_arch.h>
#include <bk_timer.h>
#include <bk_timer_pub.h>
#include <rtos_pub.h>
#include <sys_rtos.h>
#define TICKS_PER_US (CFG_XTAL_FREQUENCE / 1000 / 1000)
#define US_PER_OVERFLOW (portTICK_PERIOD_MS * 1000)
#define TICKS_PER_OVERFLOW (TICKS_PER_US * US_PER_OVERFLOW)
void delayMilliseconds(unsigned long ms) {
rtos_delay_milliseconds(ms);
}
static uint32_t getTicksCount() {
uint32_t timeout = 0;
REG_WRITE(TIMER0_2_READ_CTL, (BKTIMER0 << 2) | 1);
while (REG_READ(TIMER0_2_READ_CTL) & 1) {
timeout++;
if (timeout > (120 * 1000))
return 0;
}
return REG_READ(TIMER0_2_READ_VALUE);
}
void delayMicroseconds(unsigned int us) {
// TODO implement this properly
us /= 10;
#if LT_MICROS_HIGH_RES
if (us == 0)
return;
us--;
uint32_t startTick = getTicksCount();
/* startTick2 accounts for the case where the timer counter overflows */
uint32_t startTick2 = startTick - TICKS_PER_OVERFLOW;
uint32_t delayTicks = TICKS_PER_US * us;
while (delayTicks > TICKS_PER_OVERFLOW) {
// The delay is longer than what the timer can count.
// Let it overflow until only a fraction of TICKS_PER_OVERFLOW remain.
while (getTicksCount() > startTick) {}
while (getTicksCount() < startTick) {}
delayTicks -= TICKS_PER_OVERFLOW;
}
while ((getTicksCount() - startTick < delayTicks) || // normal case
(getTicksCount() - startTick2 < delayTicks) // counter overflow case
) {}
#else
volatile uint32_t i, j;
for (i = 0; i < us; i++) {
for (j = 0; j < 100; j++) {}
for (j = 0; j < 6; j++) {}
}
#endif
}
unsigned long millis() {
@@ -22,8 +58,49 @@ unsigned long millis() {
}
unsigned long micros() {
// TODO implement this properly
// copied from bk_timer_ctrl(), for speeds
uint32_t timeout = 0;
#if (CFG_SOC_NAME == SOC_BK7231)
#error "Not implemented"
#endif
#if LT_MICROS_HIGH_RES
static uint32_t lastMillis = 0;
static uint32_t correctedMillis = 0;
static uint32_t lastTicks = 0;
uint32_t nowMillis = millis();
uint32_t nowTicks = getTicksCount();
bool tickOverflow = nowTicks < lastTicks;
bool millisUpdated = nowMillis != lastMillis;
if (millisUpdated) {
/* reset artificially corrected millis */
correctedMillis = nowMillis;
} else if (tickOverflow) {
/*
This can happen if micros is called from within a interruptLock block (interrupts disabled).
In this case, if the tick counter rolls over, millis() won't be updated, and micros will
lag by US_PER_OVERFLOW milliseconds (one rollover).
The workaround only works as long as micros() calls happen within 2ms of eachother.
WARNING: if interrupts are disabled for more than 2ms, micros() and millis() will temporarily get out of sync.
*/
correctedMillis += portTICK_PERIOD_MS;
}
lastMillis = nowMillis;
lastTicks = nowTicks;
return correctedMillis * 1000 + nowTicks / (CFG_XTAL_FREQUENCE / 1000 / 1000);
#else
#if 0
REG_WRITE(TIMER3_5_READ_CTL, (BKTIMER3 << 2) | 1);
while (REG_READ(TIMER3_5_READ_CTL) & 1) {
timeout++;
if (timeout > (120 * 1000))
return 0;
}
return millis() * 1000 + REG_READ(TIMER3_5_READ_VALUE) / 32;
#endif
return millis() * 1000;
#endif
}
void yield() {

View File

@@ -4,6 +4,7 @@
static void *irqHandlerList[PINS_COUNT] = {NULL};
static void *irqHandlerArgs[PINS_COUNT] = {NULL};
static bool irqChangeList[PINS_COUNT];
static void irqHandler(unsigned char gpio) {
int pin = -1;
@@ -17,6 +18,15 @@ static void irqHandler(unsigned char gpio) {
return;
if (!irqHandlerList[pin])
return;
if (irqChangeList[pin]) {
if (pinTable[pin].mode == INPUT_PULLDOWN) {
pinTable[pin].mode = INPUT_PULLUP;
gpio_int_enable(pinTable[pin].gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
} else if (pinTable[pin].mode == INPUT_PULLUP) {
pinTable[pin].mode = INPUT_PULLDOWN;
gpio_int_enable(pinTable[pin].gpio, GPIO_INT_LEVEL_RISING, irqHandler);
}
}
if (irqHandlerArgs[pin] == NULL) {
((voidFuncPtr)irqHandlerList[pin])();
} else {
@@ -36,28 +46,40 @@ void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback,
return;
uint32_t event = 0;
PinMode modeNew = 0;
bool change = 0;
switch (mode) {
case LOW:
event = GPIO_INT_LEVEL_LOW;
modeNew = INPUT_PULLUP;
change = false;
break;
case HIGH:
event = GPIO_INT_LEVEL_HIGH;
modeNew = INPUT_PULLDOWN;
change = false;
break;
case FALLING:
event = GPIO_INT_LEVEL_FALLING;
modeNew = INPUT_PULLUP;
change = false;
break;
case RISING:
event = GPIO_INT_LEVEL_RISING;
modeNew = INPUT_PULLDOWN;
change = false;
break;
case CHANGE:
event = GPIO_INT_LEVEL_FALLING;
modeNew = INPUT_PULLUP;
change = true;
break;
default:
return;
}
irqHandlerList[interruptNumber] = callback;
irqHandlerArgs[interruptNumber] = param;
irqChangeList[interruptNumber] = change;
gpio_int_enable(pin->gpio, event, irqHandler);
pin->enabled |= PIN_IRQ | PIN_GPIO;
pin->mode = modeNew;
@@ -71,6 +93,7 @@ void detachInterrupt(pin_size_t interruptNumber) {
return;
irqHandlerList[interruptNumber] = NULL;
irqHandlerArgs[interruptNumber] = NULL;
irqChangeList[interruptNumber] = false;
gpio_int_disable(pin->gpio);
pin->enabled &= ~PIN_IRQ;
}

View File

@@ -10,6 +10,9 @@ bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bo
LT_HEAP_I();
// Beken SDK bug: bk_wlan_ap_init_adv() doesn't null-terminate the passphrase
memset(g_ap_param_ptr->key, '\0', 65);
strcpy(AP_CFG->wifi_ssid, ssid);
if (passphrase) {
strcpy(AP_CFG->wifi_key, passphrase);
@@ -27,6 +30,13 @@ bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bo
LT_IM(WIFI, "Creating SoftAP %s", ssid);
if (!AP_CFG->local_ip_addr[0]) {
LT_DM(WIFI, "Setting default IP config");
softAPConfig((uint32_t)0, (uint32_t)0, (uint32_t)0);
}
LT_DM(WIFI, "Static IP: %s / %s / %s", AP_CFG->local_ip_addr, AP_CFG->net_mask, AP_CFG->gateway_ip_addr);
__wrap_bk_printf_disable();
OSStatus ret = bk_wlan_start_ap_adv(AP_CFG);
__wrap_bk_printf_enable();
@@ -65,6 +75,9 @@ bool WiFiClass::softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress sub
}
bool WiFiClass::softAPdisconnect(bool wifiOff) {
if (!(getMode() & WIFI_MODE_AP))
// do not call SDK methods before even initializing WiFi first
return true;
return bk_wlan_stop(BK_SOFT_AP) == kNoErr;
}

View File

@@ -21,4 +21,5 @@ typedef struct {
void *statusLink;
rw_evt_type lastStaEvent;
rw_evt_type lastApEvent;
bool apEnabled;
} WiFiData;

View File

@@ -44,16 +44,13 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
if (ap == WLMODE_ENABLE) {
LT_DM(WIFI, "Enabling AP");
bk_wlan_ap_init(NULL);
#if CFG_WPA_CTRL_IFACE
wlan_ap_enable();
wlan_ap_reload();
uap_ip_down();
#endif
// fake it - on BK7231, enabling the AP without starting it breaks all connection attempts
data.apEnabled = true;
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_START);
} else if (ap == WLMODE_DISABLE) {
LT_DM(WIFI, "Disabling AP");
bk_wlan_stop(BK_SOFT_AP);
data.apEnabled = false;
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_STOP);
}
@@ -71,7 +68,7 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
WiFiMode WiFiClass::getMode() {
uint8_t sta = !!bk_wlan_has_role(VIF_STA) * WIFI_MODE_STA;
uint8_t ap = !!bk_wlan_has_role(VIF_AP) * WIFI_MODE_AP;
uint8_t ap = data.apEnabled * WIFI_MODE_AP; // report the faked value
return (WiFiMode)(sta | ap);
}

View File

@@ -41,15 +41,25 @@ static void scanHandler(void *ctx, uint8_t param) {
wifiEventSendArduino(ARDUINO_EVENT_WIFI_SCAN_DONE);
end:
scan->running = false;
xSemaphoreGive(cls->data.scanSem);
scan->timeout = 0;
if (scan->running) {
// running == false means it was discarded (timeout)
scan->running = false;
xSemaphoreGive(cls->data.scanSem);
}
LT_HEAP_I();
return;
}
int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint32_t maxMsPerChannel, uint8_t channel) {
if (scan && scan->running)
return WIFI_SCAN_RUNNING;
if (scan && scan->running) {
if (scan->timeout && millis() > scan->timeout) {
LT_WM(WIFI, "Scan timeout, discarding");
scan->running = false;
} else {
return WIFI_SCAN_RUNNING;
}
}
enableSTA(true);
scanDelete();
scanInit();
@@ -63,6 +73,7 @@ int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint3
LT_HEAP_I();
scan->running = true;
scan->timeout = millis() + maxMsPerChannel * 20 + 1000;
int16_t ret = WIFI_SCAN_RUNNING;
if (!async) {

View File

@@ -0,0 +1,8 @@
/* Copyright (c) Kuba Szczodrzyński 2022-09-10. */
#pragma once
#include <api/WiFi/WiFi.h>
#include <lwip/LwIPUdp.h>
typedef LwIPUDP WiFiUDP;

View File

@@ -2,6 +2,8 @@
#include "SoftwareSerial.h"
#ifdef LT_ARD_HAS_SOFTSERIAL
SoftwareSerial::SoftwareSerial(pin_size_t receivePin, pin_size_t transmitPin, bool inverted) {
data.rx.buf = NULL;
data.tx.buf = NULL;
@@ -39,3 +41,5 @@ size_t SoftwareSerial::write(uint8_t c) {
}
return 1;
}
#endif

View File

@@ -2,6 +2,8 @@
#pragma once
#ifdef LT_ARD_HAS_SOFTSERIAL
#include <Arduino.h>
#include <api/HardwareSerial.h>
#include <api/RingBuffer.h>
@@ -71,4 +73,4 @@ class SoftwareSerial : public HardwareSerial {
using Print::write;
};
#define HAS_SERIAL_CLASS 1
#endif

View File

@@ -137,9 +137,10 @@ typedef struct {
} WiFiScanAP;
typedef struct {
bool running = false;
uint8_t count = 0;
WiFiScanAP *ap = NULL;
bool running = false;
unsigned long timeout = 0;
uint8_t count = 0;
WiFiScanAP *ap = NULL;
} WiFiScanData;
typedef enum {

View File

@@ -5,7 +5,28 @@
class IWiFiUDP : public UDP {
public:
uint8_t beginMulticast(IPAddress ip, uint16_t port);
int beginMulticastPacket();
int beginPacket();
IWiFiUDP() {}
~IWiFiUDP() {}
virtual uint8_t begin(IPAddress ip, uint16_t port) = 0;
virtual uint8_t begin(uint16_t port) = 0;
virtual uint8_t beginMulticast(IPAddress ip, uint16_t port) = 0;
virtual void stop() = 0;
virtual int beginMulticastPacket() = 0;
virtual int beginPacket() = 0;
virtual int beginPacket(IPAddress ip, uint16_t port) = 0;
virtual int beginPacket(const char *host, uint16_t port) = 0;
virtual int endPacket() = 0;
virtual size_t write(uint8_t) = 0;
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
virtual int parsePacket() = 0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(unsigned char *buffer, size_t len) = 0;
virtual int read(char *buffer, size_t len) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual IPAddress remoteIP() = 0;
virtual uint16_t remotePort() = 0;
};

View File

@@ -50,6 +50,33 @@ const char *LibreTuya::getDeviceName() {
return deviceName;
}
/**
* @brief Get a textual representation of a reset reason.
*
* @param reason value to convert to text, uses getResetReason() by default
*/
const char *LibreTuya::getResetReasonName(ResetReason reason) {
if (reason >= RESET_REASON_MAX)
reason = getResetReason();
switch (reason) {
case RESET_REASON_POWER:
return "Power-On";
case RESET_REASON_BROWNOUT:
return "Brownout";
case RESET_REASON_HARDWARE:
return "HW Reboot";
case RESET_REASON_SOFTWARE:
return "SW Reboot";
case RESET_REASON_WATCHDOG:
return "WDT Reset";
case RESET_REASON_CRASH:
return "Crash";
case RESET_REASON_SLEEP:
return "Sleep Wakeup";
}
return "Unknown";
}
/**
* @brief Get CPU frequency in MHz.
*/

View File

@@ -7,6 +7,18 @@
#include "LibreTuyaAPI.h"
#include <core/ChipType.h>
typedef enum {
RESET_REASON_UNKNOWN = 0,
RESET_REASON_POWER = 1,
RESET_REASON_BROWNOUT = 2,
RESET_REASON_HARDWARE = 3,
RESET_REASON_SOFTWARE = 4,
RESET_REASON_WATCHDOG = 5,
RESET_REASON_CRASH = 6,
RESET_REASON_SLEEP = 7,
RESET_REASON_MAX = 8,
} ResetReason;
/**
* @brief Flash chip ID structure.
*/
@@ -31,17 +43,34 @@ class LibreTuya {
ChipFamily getChipFamily();
const char *getChipFamilyName();
const char *getDeviceName();
const char *getResetReasonName(ResetReason reason = RESET_REASON_MAX);
uint32_t getCpuFreqMHz();
uint32_t getFlashChipSize();
uint8_t otaGetTarget();
bool otaRollback();
bool otaCanRollback();
public: /* Compatibility methods */
/**
* @brief Alias of getMaxAllocHeap().
*/
inline uint32_t getMaxFreeBlockSize() {
return getMaxAllocHeap();
}
public: /* Family-defined methods */
/**
* @brief Reboot the CPU.
*/
void restart();
/**
* @brief Reboot the CPU and stay in download mode (if possible).
*/
void restartDownloadMode();
/**
* @brief Get the reason of last chip reset.
*/
ResetReason getResetReason();
/**
* @brief Reconfigure GPIO pins used for debugging
* (SWD/JTAG), so that they can be used as normal I/O.
@@ -139,6 +168,23 @@ class LibreTuya {
* @return false if writing failed; true otherwise
*/
bool otaSwitch(bool force = false);
public: /* Watchdog */
/**
* @brief Enable the hardware watchdog.
*
* @param timeout watchdog timeout, milliseconds (defaults to 10s)
* @return whether the chip has a hardware watchdog
*/
bool wdtEnable(uint32_t timeout = 10000);
/**
* @brief Disable the hardware watchdog.
*/
void wdtDisable();
/**
* @brief Feed/reset the hardware watchdog timer.
*/
void wdtFeed();
};
extern LibreTuya LT;

View File

@@ -82,6 +82,14 @@
#define LT_USE_TIME 0
#endif
#ifndef LT_MICROS_HIGH_RES // NOTE: this is also defined in fixups/clock_rtos.c
#define LT_MICROS_HIGH_RES 1
#endif
#ifndef LT_AUTO_DOWNLOAD_REBOOT
#define LT_AUTO_DOWNLOAD_REBOOT 1
#endif
// Per-module logging output - applies to all loglevels
#ifndef LT_DEBUG_ALL
#define LT_DEBUG_ALL 0

View File

@@ -13,7 +13,8 @@
lt_log(level, caller, line, #module ": " __VA_ARGS__); \
} \
} while (0)
void lt_log(const uint8_t level, const char *caller, const unsigned short line, const char *format, ...);
void lt_log(const uint8_t level, const char *caller, const unsigned short line, const char *format, ...)
__attribute__((format(printf, 4, 5)));
#else
#define LT_LOG(level, caller, line, ...) lt_log(level, __VA_ARGS__)
#define LT_LOGM(level, module, caller, line, ...) \
@@ -22,7 +23,7 @@ void lt_log(const uint8_t level, const char *caller, const unsigned short line,
lt_log(level, #module ": " __VA_ARGS__); \
} \
} while (0)
void lt_log(const uint8_t level, const char *format, ...);
void lt_log(const uint8_t level, const char *format, ...) __attribute__((format(printf, 2, 3)));
#endif
/**

View File

@@ -52,10 +52,12 @@ void runPeriodicTasks() {
int main(void) {
// print a startup banner
LT_BANNER();
// initialize Arduino framework
initArduino();
// initialize C library
__libc_init_array();
// inform about the reset reason
LT_I("Reset reason: %u", LT.getResetReason());
// initialize Arduino framework
initArduino();
// optionally initialize per-variant code
initVariant();
// initialize FAL

View File

@@ -0,0 +1,286 @@
/*
Udp.cpp - UDP class for Raspberry Pi
Copyright (c) 2016 Hristo Gochkov All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#if LT_ARD_HAS_WIFI && LT_HAS_LWIP
#include "LwIPUdp.h"
#include <errno.h>
extern "C" {
#include <lwip/netdb.h>
#include <lwip/sockets.h>
} // extern "C"
#undef write
#undef read
LwIPUDP::LwIPUDP() : udp_server(-1), server_port(0), remote_port(0), tx_buffer(0), tx_buffer_len(0), rx_buffer(0) {}
LwIPUDP::~LwIPUDP() {
stop();
}
uint8_t LwIPUDP::begin(IPAddress address, uint16_t port) {
stop();
server_port = port;
tx_buffer = new char[1460];
if (!tx_buffer) {
log_e("could not create tx buffer: %d", errno);
return 0;
}
if ((udp_server = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
log_e("could not create socket: %d", errno);
return 0;
}
int yes = 1;
if (setsockopt(udp_server, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
log_e("could not set socket option: %d", errno);
stop();
return 0;
}
struct sockaddr_in addr;
memset((char *)&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(server_port);
addr.sin_addr.s_addr = (in_addr_t)address;
if (bind(udp_server, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
log_e("could not bind socket: %d", errno);
stop();
return 0;
}
fcntl(udp_server, F_SETFL, O_NONBLOCK);
return 1;
}
uint8_t LwIPUDP::begin(uint16_t p) {
return begin(IPAddress(INADDR_ANY), p);
}
uint8_t LwIPUDP::beginMulticast(IPAddress a, uint16_t p) {
if (begin(IPAddress(INADDR_ANY), p)) {
if ((uint32_t)a != 0) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = (in_addr_t)a;
mreq.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(udp_server, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
log_e("could not join igmp: %d", errno);
stop();
return 0;
}
multicast_ip = a;
}
return 1;
}
return 0;
}
void LwIPUDP::stop() {
if (tx_buffer) {
delete[] tx_buffer;
tx_buffer = NULL;
}
tx_buffer_len = 0;
if (rx_buffer) {
cbuf *b = rx_buffer;
rx_buffer = NULL;
delete b;
}
if (udp_server == -1)
return;
if ((uint32_t)multicast_ip != 0) {
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = (in_addr_t)multicast_ip;
mreq.imr_interface.s_addr = (in_addr_t)0;
setsockopt(udp_server, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq));
multicast_ip = IPAddress(INADDR_ANY);
}
close(udp_server);
udp_server = -1;
}
int LwIPUDP::beginMulticastPacket() {
if (!server_port || multicast_ip == IPAddress(INADDR_ANY))
return 0;
remote_ip = multicast_ip;
remote_port = server_port;
return beginPacket();
}
int LwIPUDP::beginPacket() {
if (!remote_port)
return 0;
// allocate tx_buffer if is necessary
if (!tx_buffer) {
tx_buffer = new char[1460];
if (!tx_buffer) {
log_e("could not create tx buffer: %d", errno);
return 0;
}
}
tx_buffer_len = 0;
// check whereas socket is already open
if (udp_server != -1)
return 1;
if ((udp_server = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
log_e("could not create socket: %d", errno);
return 0;
}
fcntl(udp_server, F_SETFL, O_NONBLOCK);
return 1;
}
int LwIPUDP::beginPacket(IPAddress ip, uint16_t port) {
remote_ip = ip;
remote_port = port;
return beginPacket();
}
int LwIPUDP::beginPacket(const char *host, uint16_t port) {
struct hostent *server;
server = gethostbyname(host);
if (server == NULL) {
log_e("could not get host from dns: %d", errno);
return 0;
}
return beginPacket(IPAddress((const uint8_t *)(server->h_addr_list[0])), port);
}
int LwIPUDP::endPacket() {
struct sockaddr_in recipient;
recipient.sin_addr.s_addr = (uint32_t)remote_ip;
recipient.sin_family = AF_INET;
recipient.sin_port = htons(remote_port);
int sent = sendto(udp_server, tx_buffer, tx_buffer_len, 0, (struct sockaddr *)&recipient, sizeof(recipient));
if (sent < 0) {
log_e("could not send data: %d", errno);
return 0;
}
return 1;
}
size_t LwIPUDP::write(uint8_t data) {
if (tx_buffer_len == 1460) {
endPacket();
tx_buffer_len = 0;
}
tx_buffer[tx_buffer_len++] = data;
return 1;
}
size_t LwIPUDP::write(const uint8_t *buffer, size_t size) {
size_t i;
for (i = 0; i < size; i++)
write(buffer[i]);
return i;
}
int LwIPUDP::parsePacket() {
if (rx_buffer)
return 0;
struct sockaddr_in si_other;
int slen = sizeof(si_other), len;
char *buf = new char[1460];
if (!buf) {
return 0;
}
if ((len = recvfrom(udp_server, buf, 1460, MSG_DONTWAIT, (struct sockaddr *)&si_other, (socklen_t *)&slen)) == -1) {
delete[] buf;
if (errno == EWOULDBLOCK) {
return 0;
}
log_e("could not receive data: %d", errno);
return 0;
}
remote_ip = IPAddress(si_other.sin_addr.s_addr);
remote_port = ntohs(si_other.sin_port);
if (len > 0) {
rx_buffer = new cbuf(len);
rx_buffer->write(buf, len);
}
delete[] buf;
return len;
}
int LwIPUDP::available() {
if (!rx_buffer)
return 0;
return rx_buffer->available();
}
int LwIPUDP::read() {
if (!rx_buffer)
return -1;
int out = rx_buffer->read();
if (!rx_buffer->available()) {
cbuf *b = rx_buffer;
rx_buffer = 0;
delete b;
}
return out;
}
int LwIPUDP::read(unsigned char *buffer, size_t len) {
return read((char *)buffer, len);
}
int LwIPUDP::read(char *buffer, size_t len) {
if (!rx_buffer)
return 0;
int out = rx_buffer->read(buffer, len);
if (!rx_buffer->available()) {
cbuf *b = rx_buffer;
rx_buffer = 0;
delete b;
}
return out;
}
int LwIPUDP::peek() {
if (!rx_buffer)
return -1;
return rx_buffer->peek();
}
void LwIPUDP::flush() {
if (!rx_buffer)
return;
cbuf *b = rx_buffer;
rx_buffer = 0;
delete b;
}
IPAddress LwIPUDP::remoteIP() {
return remote_ip;
}
uint16_t LwIPUDP::remotePort() {
return remote_port;
}
#endif

View File

@@ -0,0 +1,43 @@
/* Copyright (c) Kuba Szczodrzyński 2022-09-10. */
#pragma once
#include <api/WiFi/WiFi.h>
#include <api/WiFiUdp.h>
#include <cbuf.h>
class LwIPUDP : public IWiFiUDP {
private:
int udp_server;
IPAddress multicast_ip;
IPAddress remote_ip;
uint16_t server_port;
uint16_t remote_port;
char *tx_buffer;
size_t tx_buffer_len;
cbuf *rx_buffer;
public:
LwIPUDP();
~LwIPUDP();
uint8_t begin(IPAddress ip, uint16_t port);
uint8_t begin(uint16_t port);
uint8_t beginMulticast(IPAddress ip, uint16_t port);
void stop();
int beginMulticastPacket();
int beginPacket();
int beginPacket(IPAddress ip, uint16_t port);
int beginPacket(const char *host, uint16_t port);
int endPacket();
size_t write(uint8_t);
size_t write(const uint8_t *buffer, size_t size);
int parsePacket();
int available();
int read();
int read(unsigned char *buffer, size_t len);
int read(char *buffer, size_t len);
int peek();
void flush();
IPAddress remoteIP();
uint16_t remotePort();
};

View File

@@ -38,6 +38,7 @@ static void mdnsStatusCallback(struct netif *netif, uint8_t result) {
}
bool mDNS::begin(const char *hostname) {
setInstanceName(hostname);
LT_DM(MDNS, "Starting (%s)", hostname);
#if LWIP_VERSION_MAJOR >= 2 && LWIP_VERSION_MINOR >= 1
mdns_resp_register_name_result_cb(mdnsStatusCallback);

View File

@@ -6,10 +6,25 @@ extern "C" {
#include <flash_api.h>
#include <rtl8710b.h>
#include <sys_api.h>
#include <wdt_api.h>
}
void LibreTuya::restart() {
// The Watchdog Way
wdtEnable(1L);
while (1) {}
}
void LibreTuya::restartDownloadMode() {
// mww 0x40000138 0x8
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_NORESET_FF, 0x08);
// reboot it the ugly way
sys_reset();
while (1) {}
}
ResetReason LibreTuya::getResetReason() {
return RESET_REASON_UNKNOWN;
}
void LibreTuya::gpioRecover() {
@@ -172,6 +187,22 @@ bool LibreTuya::otaSwitch(bool force) {
return true;
}
/* Watchdog */
bool LibreTuya::wdtEnable(uint32_t timeout) {
watchdog_init(timeout);
watchdog_start();
}
void LibreTuya::wdtDisable() {
watchdog_stop();
}
void LibreTuya::wdtFeed() {
watchdog_refresh();
}
/* Global instance */
LibreTuya LT;
LibreTuya ESP = LT;

View File

@@ -0,0 +1,8 @@
/* Copyright (c) Kuba Szczodrzyński 2022-09-10. */
#pragma once
#include <api/WiFi/WiFi.h>
#include <lwip/LwIPUdp.h>
typedef LwIPUDP WiFiUDP;

View File

@@ -4,10 +4,15 @@
- [Generic - BK7231T (Tuya QFN32)](../boards/generic-bk7231t-qfn32-tuya/README.md)
- [Generic - RTL8710BN (2M/468k)](../boards/generic-rtl8710bn-2mb-468k/README.md)
- [Generic - RTL8710BN (2M/788k)](../boards/generic-rtl8710bn-2mb-788k/README.md)
- [Generic - RTL8710BX (4M/980k)](../boards/generic-rtl8710bx-4mb-980k/README.md)
- [Generic - RTL8720CF (2M/992k)](../boards/generic-rtl8720cf-2mb-992k/README.md)
- [BW12](../boards/bw12/README.md)
- [BW15](../boards/bw15/README.md)
- [CB2L](../boards/cb2l/README.md)
- [CB2S](../boards/cb2s/README.md)
- [CB3L](../boards/cb3l/README.md)
- [CB3S](../boards/cb3s/README.md)
- [CB3SE](../boards/cb3se/README.md)
- [WB2L](../boards/wb2l/README.md)
- [WB2S](../boards/wb2s/README.md)
- [WB3L](../boards/wb3l/README.md)

View File

@@ -8,8 +8,9 @@
"bootloader": "0x000000+0x11000",
"app": "0x011000+0x119000",
"download": "0x12A000+0xA6000",
"tlv": "0x1D0000+0x1000",
"net": "0x1D1000+0x2000",
"calibration": "0x1D0000+0x1000",
"net": "0x1D1000+0x1000",
"tlv": "0x1D2000+0x1000",
"kvs": "0x1D3000+0x8000",
"userdata": "0x1DB000+0x25000"
},

View File

@@ -9,8 +9,9 @@
"app": "0x011000+0x121000",
"download": "0x132000+0xA6000",
"kvs": "0x1D8000+0x8000",
"tlv": "0x1E0000+0x1000",
"net": "0x1E1000+0x2000",
"calibration": "0x1E0000+0x1000",
"tlv": "0x1E1000+0x1000",
"net": "0x1E2000+0x1000",
"userdata": "0x1E3000+0x1D000"
},
"upload": {

View File

@@ -0,0 +1,120 @@
{
"pcb": {
"scale": 11,
"test_pads": {
"TRST": "cb2l.back.rst.anchor",
"TRX1": "cb2l.back.u1_rxd.anchor",
"TTX1": "cb2l.back.u1_txd.anchor",
"TTX2": "cb2l.back.u2_txd.anchor",
"TGND": "cb2l.back.gnd.anchor",
"TCSN": "cb2l.back.f_csn.anchor"
},
"back": [
{
"type": "rect",
"pos": "0,0",
"size": "15,17.3",
"preset": "${MASK_PRESET}"
},
{
"name": "pins_horz7_2mm_0.7mm",
"pos": "1.15,17.3",
"vars": {
"PINTYPE": "${PINTYPE_HORZ}",
"PINDIR": "down"
}
},
{
"name": "test_pad_1mm",
"pos": "1.5,7.5"
},
{
"name": "label_line_2mm_down",
"pos": "0.4,4.7",
"vars": {
"DIR": "right",
"W": 0.2,
"H": 2.7
}
},
{
"id": "u1_rxd.anchor",
"type": "rect",
"pos": "0.9,5.0",
"size": "0,0",
"label_dir": "left",
"label_size": 2
},
{
"name": "test_pad_1mm",
"pos": "2.2,5.9"
},
{
"id": "u2_txd",
"name": "label_line_2mm_up",
"pos": "2.2,5.1",
"vars": {
"DIR": "left",
"W": 1.5,
"H": 2
}
},
{
"name": "test_pad_1mm",
"pos": "4.0,5.9"
},
{
"id": "u1_txd",
"name": "label_line_2mm_up",
"pos": "4.0,5.1",
"vars": {
"DIR": "left",
"W": 3.3,
"H": 4
}
},
{
"name": "test_pad_1mm",
"pos": "9.2,5.9"
},
{
"id": "gnd",
"name": "label_line_2mm_up",
"pos": "9.2,5.1",
"vars": {
"DIR": "left",
"W": 8.5,
"H": 6
}
},
{
"name": "test_pad_1mm",
"pos": "2.2,10.7"
},
{
"id": "rst",
"name": "label_line_2mm_up",
"pos": "2.2,9.9",
"vars": {
"DIR": "left",
"W": 1.5,
"H": 1.0
}
},
{
"name": "test_pad_1mm",
"pos": "2.2,12.0"
},
{
"id": "f_csn",
"name": "label_line_2mm_down",
"pos": "2.2,12.8",
"vars": {
"DIR": "left",
"W": 1.5,
"H": 1.0
}
}
]
}
}

View File

@@ -0,0 +1,66 @@
{
"pcb": {
"templates": [
"tuya2l",
"rf-15mm-type1",
"tuya2l-shield"
],
"vars": {
"MASK_PRESET": "mask_white",
"TRACE_COLOR": "#E0E0E0",
"SILK_COLOR": "black",
"PINTYPE_HORZ": "pin_horz_2mm_cast_hole"
},
"pinout_hidden": "I2S,I2C,JTAG,FLASH",
"pinout": {
"1": {
"IC": 24,
"ARD": "D0"
},
"2": {
"IC": 23,
"ARD": "D1"
},
"3": {
"IC": 22,
"ARD": "D2"
},
"4": {
"IC": 15,
"ARD": "D3"
},
"5": {
"IC": 16,
"ARD": "D4"
},
"6": {
"GND": null
},
"7": {
"PWR": 3.3
},
"TGND": {
"GND": null
},
"TRST": {
"CTRL": "CEN"
},
"TRX1": {
"IC": 26,
"ARD": "D5"
},
"TTX2": {
"IC": 29,
"ARD": "D6"
},
"TTX1": {
"IC": 27,
"ARD": "D7"
},
"TCSN": {
"IC": 19,
"ARD": "D8"
}
}
}
}

View File

@@ -0,0 +1,83 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12e-shield",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white",
"PINTYPE_VERT": "pin_vert_2mm_cast_hole",
"PINTYPE_HORZ": "pin_horz_2mm_cast_hole"
},
"pinout_hidden": "I2S,SD,SPI,I2C,JTAG,FLASH",
"pinout": {
"1": {
"IC": 21
},
"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": 19,
"ARD": "D7"
},
"13": {
"IC": 24,
"ARD": "D8"
},
"14": {
"IC": 23,
"ARD": "D9"
},
"15": {
"IC": 26,
"ARD": "D10"
},
"16": {
"IC": 27,
"ARD": "D11"
}
}
}
}

108
boards/_base/pcb/cb3s.json Normal file
View File

@@ -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,SCL2",
"pinout": {
"1": {
"IC": 21
},
"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": 19,
"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": "D7"
},
"20": {
"IC": 20,
"ARD": "D13"
},
"21": {
"NC": null
},
"22": {
"NC": null
}
}
}
}

106
boards/_base/pcb/cb3se.json Normal file
View File

@@ -0,0 +1,106 @@
{
"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,JTAG,FLASH,SCL1",
"pinout": {
"1": {
"IC": 21
},
"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": 28,
"ARD": "D7"
},
"13": {
"IC": 24,
"ARD": "D8"
},
"14": {
"IC": 23,
"ARD": "D9"
},
"15": {
"IC": 26,
"ARD": "D10"
},
"16": {
"IC": 27,
"ARD": "D11"
},
"17": {
"IC": 13,
"ARD": "D12"
},
"18": {
"IC": 18,
"ARD": "D13"
},
"19": {
"GND": null
},
"20": {
"IC": 20,
"ARD": "D14"
},
"21": {
"IC": 14,
"ARD": "D15"
},
"22": {
"IC": 12,
"ARD": "D16"
}
}
}
}

View File

@@ -0,0 +1,18 @@
{
"build": {
"ldscript_sdk": "rlx8711B-symbol-v02-img2_xip1_4M_cpp.ld",
"ldscript_arduino": "rlx8711B-symbol-v02-img2_xip1_4M_cpp.ld",
"amb_boot_all": "boot_all_C556.bin"
},
"flash": {
"ota1": "0x00B000+0xF5000",
"ota2": "0x100000+0xF5000",
"kvs": "0x1F5000+0x8000",
"userdata": "0x1FD000+0x202000",
"rdp": "0x3FF000+0x1000"
},
"upload": {
"flash_size": 4194304,
"maximum_size": 1003520
}
}

View File

@@ -17,6 +17,7 @@
"symbol": "BW12"
},
"doc": {
"fccid": "2ARI3-BW1X",
"links": {
"Vendor datasheet": "https://docs.ai-thinker.com/_media/rtl8710/hardware/bw12_datasheet_en.pdf"
}

View File

@@ -11,7 +11,7 @@
- [Vendor datasheet](https://docs.ai-thinker.com/_media/rtl8710/hardware/bw12_datasheet_en.pdf)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `bw12`
MCU | RTL8710BX
Manufacturer | Realtek
@@ -22,6 +22,7 @@ RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 11x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
FCC ID | [2ARI3-BW1X](https://fccid.io/2ARI3-BW1X)
## Usage
@@ -36,6 +37,15 @@ board = bw12
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: bw12
framework:
version: dev
```
## Pinout
![Pinout](pinout_bw12.svg)

View File

@@ -49,3 +49,32 @@
#define PIN_SERIAL0_TX 10u // PA_23
#define PIN_SERIAL2_RX 1u // PA_29
#define PIN_SERIAL2_TX 5u // PA_30
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC1 3u // PA_19
#define PIN_FUNCTION_CS0 3u // PA_19
#define PIN_FUNCTION_CS1 3u // PA_19
#define PIN_FUNCTION_CTS0 3u // PA_19
#define PIN_FUNCTION_MISO0 4u // PA_22
#define PIN_FUNCTION_MISO1 4u // PA_22
#define PIN_FUNCTION_MOSI0 10u // PA_23
#define PIN_FUNCTION_MOSI1 10u // PA_23
#define PIN_FUNCTION_PA00 2u // PA_0
#define PIN_FUNCTION_PA05 0u // PA_5
#define PIN_FUNCTION_PA12 7u // PA_12
#define PIN_FUNCTION_PA14 6u // PA_14
#define PIN_FUNCTION_PA15 8u // PA_15
#define PIN_FUNCTION_PA18 9u // PA_18
#define PIN_FUNCTION_PA19 3u // PA_19
#define PIN_FUNCTION_PA22 4u // PA_22
#define PIN_FUNCTION_PA23 10u // PA_23
#define PIN_FUNCTION_PA29 1u // PA_29
#define PIN_FUNCTION_PA30 5u // PA_30
#define PIN_FUNCTION_RTS0 4u // PA_22
#define PIN_FUNCTION_RX0 9u // PA_18
#define PIN_FUNCTION_RX2 1u // PA_29
#define PIN_FUNCTION_SCK0 9u // PA_18
#define PIN_FUNCTION_SCK1 9u // PA_18
#define PIN_FUNCTION_TX0 10u // PA_23
#define PIN_FUNCTION_TX2 5u // PA_30

View File

@@ -17,6 +17,7 @@
"symbol": "BW15"
},
"doc": {
"fccid": "2AXVG-BW15",
"links": {
"Vendor datasheet": "https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf"
}

View File

@@ -8,7 +8,7 @@
- [Vendor datasheet](https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf)
Parameter | Value
-------------|--------------------------
-------------|------------------------------------------
Board code | `bw15`
MCU | RTL8720CF
Manufacturer | Realtek
@@ -20,6 +20,7 @@ Voltage | 3.0V - 3.6V
I/O | 13x GPIO, 8x PWM, 3x UART
Wi-Fi | 802.11 b/g/n
BLE | v4.2
FCC ID | [2AXVG-BW15](https://fccid.io/2AXVG-BW15)
## Usage
@@ -34,6 +35,15 @@ board = bw15
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: bw15
framework:
version: dev
```
## Pinout
![Pinout](pinout_bw15.svg)

23
boards/cb2l.json Normal file
View File

@@ -0,0 +1,23 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/cb2l",
"pcb/cb2l-test"
],
"build": {
"mcu": "bk7231n",
"variant": "cb2l"
},
"name": "CB2L Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/cb2l-module-datasheet?id=Kai2eku1m3pyl",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-CB2L"
},
"pcb": {
"symbol": "CB2L"
}
}

83
boards/cb2l/README.md Normal file
View File

@@ -0,0 +1,83 @@
# CB2L Wi-Fi Module
*by Tuya Inc.*
[Product page](https://developer.tuya.com/en/docs/iot/cb2l-module-datasheet?id=Kai2eku1m3pyl)
- [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
-------------|------------------------------------------
Board code | `cb2l`
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 9x GPIO, 5x PWM, 2x UART
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
FCC ID | [2ANDL-CB2L](https://fccid.io/2ANDL-CB2L)
## Usage
**Board code:** `cb2l`
In `platformio.ini`:
```ini
[env:cb2l]
platform = libretuya
board = cb2l
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: cb2l
framework:
version: dev
```
## Pinout
![Pinout](pinout_cb2l.svg)
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
----|-----|----------|----------|-----|------|------
D0 | P8 | | | | PWM2 |
D1 | P7 | | | | PWM1 |
D2 | P6 | | | | PWM0 |
D3 | P26 | | | | PWM5 |
D4 | P24 | | | | PWM4 |
D5 | P10 | UART1_RX | | | |
D6 | P0 | UART2_TX | I2C2_SCL | | |
D7 | P11 | UART1_TX | | | |
D8 | P21 | | I2C1_SDA | | | TMS
## 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 / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 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.

258
boards/cb2l/pinout_cb2l.svg Normal file
View File

@@ -0,0 +1,258 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" height="500" version="1.1" viewBox="0,0,93.0909090909091,45.45454545454545" width="1024">
<defs/>
<rect fill="white" height="45.45454545454545" stroke="black" stroke-width="0.1" width="93.0909090909091" x="0" y="0"/>
<linearGradient gradientUnits="objectBoundingBox" id="id1" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#f9f9f9"/>
<stop offset="100%" stop-color="#ededed"/>
</linearGradient>
<rect fill="url(#id1) none" height="17.2" stroke="#b5a739" stroke-width="0.1" width="14.9" x="17.622727272727275" y="9.677272727272728"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin1.trace" width="1.2" x="18.472727272727273" y="25.227272727272727"/>
<circle cx="19.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin1.cast" r="0.35"/>
<circle cx="19.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin1.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin2.trace" width="1.2" x="20.472727272727273" y="25.227272727272727"/>
<circle cx="21.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin2.cast" r="0.35"/>
<circle cx="21.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin2.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin3.trace" width="1.2" x="22.472727272727273" y="25.227272727272727"/>
<circle cx="23.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin3.cast" r="0.35"/>
<circle cx="23.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin3.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin4.trace" width="1.2" x="24.472727272727276" y="25.227272727272727"/>
<circle cx="25.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin4.cast" r="0.35"/>
<circle cx="25.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin4.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin5.trace" width="1.2" x="26.472727272727276" y="25.227272727272727"/>
<circle cx="27.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin5.cast" r="0.35"/>
<circle cx="27.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin5.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin6.trace" width="1.2" x="28.472727272727276" y="25.227272727272727"/>
<circle cx="29.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin6.cast" r="0.35"/>
<circle cx="29.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin6.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin7.trace" width="1.2" x="30.472727272727276" y="25.227272727272727"/>
<circle cx="31.072727272727274" cy="26.92727272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin7.cast" r="0.35"/>
<circle cx="31.072727272727274" cy="25.877272727272725" fill="#fff" id="pins_horz7_2mm_0.7mm.pin7.hole" r="0.35"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="18.972727272727273" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="18.772727272727273" y="28.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label1.anchor" width="0.0" x="19.272727272727273" y="29.02727272727273"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="20.972727272727273" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="18.772727272727273" y="30.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label2.anchor" width="0.0" x="19.272727272727273" y="31.027272727272724"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="22.972727272727276" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="18.772727272727273" y="32.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label3.anchor" width="0.0" x="19.272727272727273" y="33.027272727272724"/>
<rect fill="#4e4c4c" height="8.0" width="0.2" x="24.972727272727276" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="6.2" x="18.772727272727273" y="34.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label4.anchor" width="0.0" x="19.272727272727273" y="35.027272727272724"/>
<rect fill="#4e4c4c" height="8.0" width="0.2" x="26.972727272727276" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="27.072727272727274" y="34.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label5.anchor" width="0.0" x="30.772727272727273" y="35.027272727272724"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="28.972727272727276" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="29.072727272727274" y="32.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label6.anchor" width="0.0" x="30.772727272727273" y="33.027272727272724"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="30.972727272727276" y="27.127272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="31.072727272727274" y="30.92727272727273"/>
<rect height="0.0" id="tuya2l.front.pins.label7.anchor" width="0.0" x="30.772727272727273" y="31.027272727272724"/>
<text fill="#000" font-family="Consolas" font-size="1.0" x="21.572727272727274" y="15.127272727272727">CB2L</text>
<rect fill="#e0e0e0" height="5.2" width="0.5" x="18.372727272727275" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="0.5" width="4.6" x="18.372727272727275" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="5.2" width="0.5" x="20.572727272727274" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="3.0" width="0.5" x="22.472727272727276" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="0.5" width="3.0" x="22.472727272727276" y="12.627272727272727"/>
<rect fill="#e0e0e0" height="3.0" width="0.5" x="24.972727272727276" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="0.5" width="2.7" x="24.972727272727276" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="3.0" width="0.5" x="27.172727272727272" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="0.5" width="3.0" x="27.172727272727272" y="12.627272727272727"/>
<rect fill="#e0e0e0" height="3.0" width="0.5" x="29.672727272727272" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="0.5" width="2.5" x="29.672727272727272" y="10.127272727272727"/>
<rect fill="#e0e0e0" height="4.4" width="0.5" x="31.672727272727272" y="10.127272727272727"/>
<linearGradient gradientUnits="objectBoundingBox" id="id2" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="whitesmoke"/>
<stop offset="100%" stop-color="#999"/>
</linearGradient>
<rect fill="url(#id2) none" height="9.0" rx="0.5" ry="0.5" width="13.6" x="18.272727272727273" y="15.627272727272727"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.172727272727272" y="28.92727272727273"/>
<g transform="translate(12.387086626672172,28.22727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="13.872727272727273" y="29.02727272727273">P8</text>
<g transform="translate(9.387086626672172,28.22727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="10.572727272727274" y="29.02727272727273">D0</text>
<g transform="translate(5.787086626672172,28.22727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.272727272727274" y="29.02727272727273">PWM2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.172727272727272" y="30.927272727272722"/>
<g transform="translate(12.387086626672172,30.227272727272723)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="13.872727272727273" y="31.027272727272724">P7</text>
<g transform="translate(9.387086626672172,30.227272727272723)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="10.572727272727274" y="31.027272727272724">D1</text>
<g transform="translate(5.787086626672172,30.227272727272723)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.272727272727274" y="31.027272727272724">PWM1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.172727272727272" y="32.92727272727272"/>
<g transform="translate(12.387086626672172,32.22727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="13.872727272727273" y="33.027272727272724">P6</text>
<g transform="translate(9.387086626672172,32.22727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="10.572727272727274" y="33.027272727272724">D2</text>
<g transform="translate(5.787086626672172,32.22727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.272727272727274" y="33.027272727272724">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.172727272727272" y="34.92727272727272"/>
<g transform="translate(12.387086626672172,34.22727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="13.872727272727273" y="35.027272727272724">P26</text>
<g transform="translate(9.387086626672172,34.22727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="10.572727272727274" y="35.027272727272724">D3</text>
<g transform="translate(5.787086626672172,34.22727272727273)">
<rect fill="#aeafc1" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.272727272727274" y="35.027272727272724">IRDA</text>
<g transform="translate(2.1870866266721727,34.22727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="3.6727272727272746" y="35.027272727272724">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.272727272727273" y="34.92727272727272"/>
<g transform="translate(34.687086626672176,34.22727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="36.17272727272728" y="35.027272727272724">P24</text>
<g transform="translate(38.28708662667218,34.22727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="39.472727272727276" y="35.027272727272724">D4</text>
<g transform="translate(41.28708662667218,34.22727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="42.77272727272728" y="35.027272727272724">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.272727272727273" y="32.92727272727272"/>
<g transform="translate(34.687086626672176,32.22727272727273)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="36.17272727272728" y="33.027272727272724">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.272727272727273" y="30.927272727272722"/>
<g transform="translate(34.687086626672176,30.227272727272723)">
<rect fill="#cd3c24" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="36.17272727272728" y="31.027272727272724">3V3</text>
<linearGradient gradientUnits="objectBoundingBox" id="id3" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#f9f9f9"/>
<stop offset="100%" stop-color="#ededed"/>
</linearGradient>
<rect fill="url(#id3) none" height="17.2" stroke="#b5a739" stroke-width="0.1" width="14.9" x="68.71818181818182" y="14.852272727272727"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin1.trace" width="1.2" x="69.56818181818183" y="30.402272727272727"/>
<circle cx="70.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin1.cast" r="0.35"/>
<circle cx="70.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin1.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin2.trace" width="1.2" x="71.56818181818183" y="30.402272727272727"/>
<circle cx="72.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin2.cast" r="0.35"/>
<circle cx="72.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin2.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin3.trace" width="1.2" x="73.56818181818183" y="30.402272727272727"/>
<circle cx="74.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin3.cast" r="0.35"/>
<circle cx="74.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin3.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin4.trace" width="1.2" x="75.56818181818183" y="30.402272727272727"/>
<circle cx="76.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin4.cast" r="0.35"/>
<circle cx="76.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin4.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin5.trace" width="1.2" x="77.56818181818183" y="30.402272727272727"/>
<circle cx="78.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin5.cast" r="0.35"/>
<circle cx="78.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin5.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin6.trace" width="1.2" x="79.56818181818183" y="30.402272727272727"/>
<circle cx="80.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin6.cast" r="0.35"/>
<circle cx="80.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin6.hole" r="0.35"/>
<rect fill="#e5b472" height="1.7" id="pins_horz7_2mm_0.7mm.pin7.trace" width="1.2" x="81.56818181818183" y="30.402272727272727"/>
<circle cx="82.16818181818182" cy="32.10227272727273" fill="#fff" id="pins_horz7_2mm_0.7mm.pin7.cast" r="0.35"/>
<circle cx="82.16818181818182" cy="31.052272727272726" fill="#fff" id="pins_horz7_2mm_0.7mm.pin7.hole" r="0.35"/>
<circle cx="70.16818181818182" cy="22.302272727272726" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="2.7" width="0.2" x="68.96818181818182" y="19.702272727272728"/>
<rect fill="#4e4c4c" height="0.2" width="0.4" x="69.06818181818183" y="22.202272727272728"/>
<rect height="0.0" id="label_line_2mm_down.anchor" width="0.0" x="68.96818181818182" y="22.302272727272726"/>
<rect height="0.0" id="cb2l.back.u1_rxd.anchor" width="0.0" x="69.56818181818183" y="19.802272727272726"/>
<circle cx="70.86818181818182" cy="20.702272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="70.76818181818182" y="17.702272727272724"/>
<rect fill="#4e4c4c" height="0.2" width="1.7" x="69.06818181818183" y="17.702272727272724"/>
<rect height="0.0" id="cb2l.back.u2_txd.anchor" width="0.0" x="69.56818181818183" y="17.802272727272726"/>
<circle cx="72.66818181818182" cy="20.702272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="72.56818181818183" y="15.702272727272724"/>
<rect fill="#4e4c4c" height="0.2" width="3.5" x="69.06818181818183" y="15.702272727272724"/>
<rect height="0.0" id="cb2l.back.u1_txd.anchor" width="0.0" x="69.56818181818183" y="15.802272727272726"/>
<circle cx="77.86818181818182" cy="20.702272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="77.76818181818182" y="13.702272727272724"/>
<rect fill="#4e4c4c" height="0.2" width="8.7" x="69.06818181818181" y="13.702272727272724"/>
<rect height="0.0" id="cb2l.back.gnd.anchor" width="0.0" x="69.56818181818181" y="13.802272727272726"/>
<circle cx="70.86818181818182" cy="25.502272727272725" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="1.0" width="0.2" x="70.76818181818182" y="23.502272727272725"/>
<rect fill="#4e4c4c" height="0.2" width="1.7" x="69.06818181818183" y="23.502272727272725"/>
<rect height="0.0" id="cb2l.back.rst.anchor" width="0.0" x="69.56818181818183" y="23.602272727272727"/>
<circle cx="70.86818181818182" cy="26.802272727272726" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="1.0" width="0.2" x="70.76818181818182" y="27.802272727272726"/>
<rect fill="#4e4c4c" height="0.2" width="1.7" x="69.06818181818183" y="28.602272727272727"/>
<rect height="0.0" id="cb2l.back.f_csn.anchor" width="0.0" x="69.56818181818183" y="28.702272727272728"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818182" y="13.702272727272726"/>
<g transform="translate(62.68254117212672,13.002272727272725)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="13.802272727272726">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818183" y="23.502272727272725"/>
<g transform="translate(62.68254117212672,22.802272727272726)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="23.602272727272727">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818183" y="19.702272727272724"/>
<g transform="translate(62.68254117212672,19.002272727272725)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="19.802272727272726">P10</text>
<g transform="translate(59.682541172126726,19.002272727272725)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.868181818181824" y="19.802272727272726">D5</text>
<g transform="translate(56.082541172126724,19.002272727272725)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.56818181818183" y="19.802272727272726">RX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818183" y="17.702272727272724"/>
<g transform="translate(62.68254117212672,17.002272727272725)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="17.802272727272726">P0</text>
<g transform="translate(59.682541172126726,17.002272727272725)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.868181818181824" y="17.802272727272726">D6</text>
<g transform="translate(56.082541172126724,17.002272727272725)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.56818181818183" y="17.802272727272726">TX2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818183" y="15.702272727272726"/>
<g transform="translate(62.68254117212672,15.002272727272725)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="15.802272727272726">P11</text>
<g transform="translate(59.682541172126726,15.002272727272725)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.868181818181824" y="15.802272727272726">D7</text>
<g transform="translate(56.082541172126724,15.002272727272725)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.56818181818183" y="15.802272727272726">TX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="66.46818181818183" y="28.602272727272727"/>
<g transform="translate(62.68254117212672,27.902272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.16818181818182" y="28.702272727272728">P21</text>
<g transform="translate(59.682541172126726,27.902272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.868181818181824" y="28.702272727272728">D8</text>
</svg>

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1 @@
#include "variant.h"

30
boards/cb2l/variant.cpp Normal file
View File

@@ -0,0 +1,30 @@
/* This file was auto-generated from cb2l.json using boardgen */
#include <Arduino.h>
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: P26, PWM5, IRDA
{GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D4: P24, PWM4
{GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D5: P10, UART1_RX
{GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D6: P0, UART2_TX, I2C2_SCL
{GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D7: P11, UART1_TX
{GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D8: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

49
boards/cb2l/variant.h Normal file
View File

@@ -0,0 +1,49 @@
/* This file was auto-generated from cb2l.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 9
#define NUM_DIGITAL_PINS 9
#define NUM_ANALOG_OUTPUTS 0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 0
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 1
#define PIN_SERIAL1_RX 5u // GPIO10
#define PIN_SERIAL1_TX 7u // GPIO11
// Pin function macros
// -------------------
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P6 2u // GPIO6
#define PIN_FUNCTION_P7 1u // GPIO7
#define PIN_FUNCTION_P8 0u // GPIO8
#define PIN_FUNCTION_P10 5u // GPIO10
#define PIN_FUNCTION_P11 7u // GPIO11
#define PIN_FUNCTION_P21 8u // GPIO21
#define PIN_FUNCTION_P24 4u // GPIO24
#define PIN_FUNCTION_P26 3u // GPIO26
#define PIN_FUNCTION_PWM0 2u // GPIO6
#define PIN_FUNCTION_PWM1 1u // GPIO7
#define PIN_FUNCTION_PWM2 0u // GPIO8
#define PIN_FUNCTION_PWM4 4u // GPIO24
#define PIN_FUNCTION_PWM5 3u // GPIO26
#define PIN_FUNCTION_RX1 5u // GPIO10
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA1 8u // GPIO21
#define PIN_FUNCTION_TX1 7u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

View File

@@ -14,6 +14,9 @@
"name": "CB2S Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/cb2s-module-datasheet?id=Kafgfsa2aaypq",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-CB2S"
},
"pcb": {
"symbol": "CB2S"
}

View File

@@ -9,7 +9,7 @@
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `cb2s`
MCU | BK7231N
Manufacturer | Beken
@@ -21,6 +21,7 @@ Voltage | 3.0V - 3.6V
I/O | 11x GPIO, 5x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
FCC ID | [2ANDL-CB2S](https://fccid.io/2ANDL-CB2S)
## Usage
@@ -35,6 +36,15 @@ board = cb2s
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: cb2s
framework:
version: dev
```
## Pinout
![Pinout](pinout_cb2s.svg)
@@ -67,8 +77,9 @@ Name | Start | Length | End
Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
App Image | 0x011000 | 1.1 MiB / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
TLV Store | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 8 KiB / 0x2000 | 0x1D3000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 0x200000

View File

@@ -35,3 +35,30 @@
#define PIN_SERIAL1_TX 5u // GPIO11
#define PIN_SERIAL2_RX 9u // GPIO1
#define PIN_SERIAL2_TX 8u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 3u // GPIO23
#define PIN_FUNCTION_P0 8u // GPIO0
#define PIN_FUNCTION_P1 9u // GPIO1
#define PIN_FUNCTION_P6 0u // GPIO6
#define PIN_FUNCTION_P7 1u // GPIO7
#define PIN_FUNCTION_P8 2u // GPIO8
#define PIN_FUNCTION_P10 4u // GPIO10
#define PIN_FUNCTION_P11 5u // GPIO11
#define PIN_FUNCTION_P21 10u // GPIO21
#define PIN_FUNCTION_P23 3u // GPIO23
#define PIN_FUNCTION_P24 6u // GPIO24
#define PIN_FUNCTION_P26 7u // GPIO26
#define PIN_FUNCTION_PWM0 0u // GPIO6
#define PIN_FUNCTION_PWM1 1u // GPIO7
#define PIN_FUNCTION_PWM2 2u // GPIO8
#define PIN_FUNCTION_PWM4 6u // GPIO24
#define PIN_FUNCTION_PWM5 7u // GPIO26
#define PIN_FUNCTION_RX1 4u // GPIO10
#define PIN_FUNCTION_RX2 9u // GPIO1
#define PIN_FUNCTION_SCL2 8u // GPIO0
#define PIN_FUNCTION_SDA1 10u // GPIO21
#define PIN_FUNCTION_SDA2 9u // GPIO1
#define PIN_FUNCTION_TX1 5u // GPIO11
#define PIN_FUNCTION_TX2 8u // GPIO0

22
boards/cb3l.json Normal file
View File

@@ -0,0 +1,22 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/cb3l"
],
"build": {
"mcu": "bk7231n",
"variant": "cb3l"
},
"name": "CB3L Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/cb3l-module-datasheet?id=Kai51ngmrh3qm",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-CB3L"
},
"pcb": {
"symbol": "CB3L"
}
}

87
boards/cb3l/README.md Normal file
View File

@@ -0,0 +1,87 @@
# CB3L Wi-Fi Module
*by Tuya Inc.*
[Product page](https://developer.tuya.com/en/docs/iot/cb3l-module-datasheet?id=Kai51ngmrh3qm)
- [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
-------------|------------------------------------------
Board code | `cb3l`
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 12x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
FCC ID | [2ANDL-CB3L](https://fccid.io/2ANDL-CB3L)
## Usage
**Board code:** `cb3l`
In `platformio.ini`:
```ini
[env:cb3l]
platform = libretuya
board = cb3l
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: cb3l
framework:
version: dev
```
## Pinout
![Pinout](pinout_cb3l.svg)
## 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 | P21 | | I2C1_SDA | | | TMS
D8 | P8 | | | | PWM2 |
D9 | P7 | | | | PWM1 |
D10 | P10 | UART1_RX | | | |
D11 | P11 | UART1_TX | | | |
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 / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 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.

253
boards/cb3l/pinout_cb3l.svg Normal file
View File

@@ -0,0 +1,253 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" height="500" version="1.1" viewBox="0,0,85.33333333333333,41.666666666666664" width="1024">
<defs/>
<rect fill="white" height="41.666666666666664" stroke="black" stroke-width="0.1" width="85.33333333333333" x="0" y="0"/>
<linearGradient gradientUnits="objectBoundingBox" id="id1" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#47a8cd"/>
<stop offset="100%" stop-color="#008fb5"/>
</linearGradient>
<rect fill="url(#id1) none" height="23.9" stroke="#b5a739" stroke-width="0.1" width="15.9" x="36.46666666666666" y="8.883333333333333"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin1.trace" width="1.7" x="36.416666666666664" y="16.583333333333332"/>
<circle cx="36.416666666666664" cy="17.18333333333333" fill="#fff" id="esp12s.front.left.pin1.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="17.18333333333333" fill="#fff" id="esp12s.front.left.pin1.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin2.trace" width="1.7" x="36.416666666666664" y="18.583333333333332"/>
<circle cx="36.416666666666664" cy="19.18333333333333" fill="#fff" id="esp12s.front.left.pin2.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="19.18333333333333" fill="#fff" id="esp12s.front.left.pin2.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin3.trace" width="1.7" x="36.416666666666664" y="20.583333333333332"/>
<circle cx="36.416666666666664" cy="21.18333333333333" fill="#fff" id="esp12s.front.left.pin3.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="21.18333333333333" fill="#fff" id="esp12s.front.left.pin3.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin4.trace" width="1.7" x="36.416666666666664" y="22.583333333333332"/>
<circle cx="36.416666666666664" cy="23.18333333333333" fill="#fff" id="esp12s.front.left.pin4.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="23.18333333333333" fill="#fff" id="esp12s.front.left.pin4.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin5.trace" width="1.7" x="36.416666666666664" y="24.583333333333332"/>
<circle cx="36.416666666666664" cy="25.183333333333334" fill="#fff" id="esp12s.front.left.pin5.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="25.183333333333334" fill="#fff" id="esp12s.front.left.pin5.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin6.trace" width="1.7" x="36.416666666666664" y="26.583333333333332"/>
<circle cx="36.416666666666664" cy="27.183333333333334" fill="#fff" id="esp12s.front.left.pin6.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="27.183333333333334" fill="#fff" id="esp12s.front.left.pin6.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin7.trace" width="1.7" x="36.416666666666664" y="28.583333333333332"/>
<circle cx="36.416666666666664" cy="29.183333333333334" fill="#fff" id="esp12s.front.left.pin7.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="29.183333333333334" fill="#fff" id="esp12s.front.left.pin7.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin8.trace" width="1.7" x="36.416666666666664" y="30.583333333333332"/>
<circle cx="36.416666666666664" cy="31.183333333333334" fill="#fff" id="esp12s.front.left.pin8.cast" r="0.35"/>
<circle cx="37.46666666666666" cy="31.183333333333334" fill="#fff" id="esp12s.front.left.pin8.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin1.trace" width="1.7" x="50.71666666666667" y="16.583333333333332"/>
<circle cx="52.416666666666664" cy="17.18333333333333" fill="#fff" id="esp12s.front.right.pin1.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="17.18333333333333" fill="#fff" id="esp12s.front.right.pin1.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin2.trace" width="1.7" x="50.71666666666667" y="18.583333333333332"/>
<circle cx="52.416666666666664" cy="19.18333333333333" fill="#fff" id="esp12s.front.right.pin2.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="19.18333333333333" fill="#fff" id="esp12s.front.right.pin2.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin3.trace" width="1.7" x="50.71666666666667" y="20.583333333333332"/>
<circle cx="52.416666666666664" cy="21.18333333333333" fill="#fff" id="esp12s.front.right.pin3.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="21.18333333333333" fill="#fff" id="esp12s.front.right.pin3.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin4.trace" width="1.7" x="50.71666666666667" y="22.583333333333332"/>
<circle cx="52.416666666666664" cy="23.18333333333333" fill="#fff" id="esp12s.front.right.pin4.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="23.18333333333333" fill="#fff" id="esp12s.front.right.pin4.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin5.trace" width="1.7" x="50.71666666666667" y="24.583333333333332"/>
<circle cx="52.416666666666664" cy="25.183333333333334" fill="#fff" id="esp12s.front.right.pin5.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="25.183333333333334" fill="#fff" id="esp12s.front.right.pin5.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin6.trace" width="1.7" x="50.71666666666667" y="26.583333333333332"/>
<circle cx="52.416666666666664" cy="27.183333333333334" fill="#fff" id="esp12s.front.right.pin6.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="27.183333333333334" fill="#fff" id="esp12s.front.right.pin6.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin7.trace" width="1.7" x="50.71666666666667" y="28.583333333333332"/>
<circle cx="52.416666666666664" cy="29.183333333333334" fill="#fff" id="esp12s.front.right.pin7.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="29.183333333333334" fill="#fff" id="esp12s.front.right.pin7.hole" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin8.trace" width="1.7" x="50.71666666666667" y="30.583333333333332"/>
<circle cx="52.416666666666664" cy="31.183333333333334" fill="#fff" id="esp12s.front.right.pin8.cast" r="0.35"/>
<circle cx="51.36666666666666" cy="31.183333333333334" fill="#fff" id="esp12s.front.right.pin8.hole" r="0.35"/>
<linearGradient gradientUnits="objectBoundingBox" id="id2" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="whitesmoke"/>
<stop offset="100%" stop-color="#999"/>
</linearGradient>
<rect fill="url(#id2) none" height="15.8" rx="0.5" ry="0.5" width="12.0" x="38.416666666666664" y="15.783333333333331"/>
<rect fill="#fff" height="0.15" width="15.0" x="36.916666666666664" y="15.033333333333331"/>
<text fill="#fff" font-family="Consolas" font-size="1.0" x="43.416666666666664" y="14.333333333333332">CB3L</text>
<rect fill="#58839b" height="5.2" width="0.5" x="37.516666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="0.5" width="4.6" x="37.516666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="5.2" width="0.5" x="39.71666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="41.61666666666667" y="9.633333333333333"/>
<rect fill="#58839b" height="0.5" width="3.0" x="41.61666666666667" y="12.133333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="44.11666666666667" y="9.633333333333333"/>
<rect fill="#58839b" height="0.5" width="2.7" x="44.11666666666667" y="9.633333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="46.31666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="0.5" width="3.0" x="46.31666666666666" y="12.133333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="48.81666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="0.5" width="2.5" x="48.81666666666666" y="9.633333333333333"/>
<rect fill="#58839b" height="4.4" width="0.5" x="50.81666666666666" y="9.633333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="17.08333333333333"/>
<g transform="translate(29.53102602061156,16.38333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="17.18333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="19.08333333333333"/>
<g transform="translate(29.53102602061156,18.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="19.18333333333333">P23</text>
<g transform="translate(25.93102602061156,18.38333333333333)">
<rect fill="#8ad039" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.416666666666664" y="19.18333333333333">ADC3</text>
<g transform="translate(22.93102602061156,18.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.116666666666664" y="19.18333333333333">D0</text>
<g transform="translate(19.93102602061156,18.38333333333333)">
<rect fill="#16a352" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="21.116666666666664" y="19.18333333333333">A0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="21.08333333333333"/>
<g transform="translate(29.53102602061156,20.38333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="21.18333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="23.08333333333333"/>
<g transform="translate(29.53102602061156,22.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="23.18333333333333">P14</text>
<g transform="translate(26.531026020611563,22.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.716666666666665" y="23.18333333333333">D1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="25.083333333333332"/>
<g transform="translate(29.53102602061156,24.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="25.183333333333334">P26</text>
<g transform="translate(26.531026020611563,24.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.716666666666665" y="25.183333333333334">D2</text>
<g transform="translate(22.93102602061156,24.383333333333333)">
<rect fill="#aeafc1" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.416666666666664" y="25.183333333333334">IRDA</text>
<g transform="translate(19.331026020611564,24.383333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.816666666666666" y="25.183333333333334">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="27.083333333333332"/>
<g transform="translate(29.53102602061156,26.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="27.183333333333334">P24</text>
<g transform="translate(26.531026020611563,26.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.716666666666665" y="27.183333333333334">D3</text>
<g transform="translate(22.93102602061156,26.383333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.416666666666664" y="27.183333333333334">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="29.083333333333332"/>
<g transform="translate(29.53102602061156,28.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="29.183333333333334">P6</text>
<g transform="translate(26.531026020611563,28.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.716666666666665" y="29.183333333333334">D4</text>
<g transform="translate(22.93102602061156,28.383333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.416666666666664" y="29.183333333333334">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.31666666666666" y="31.083333333333332"/>
<g transform="translate(29.53102602061156,30.383333333333333)">
<rect fill="#cd3c24" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="31.016666666666662" y="31.183333333333334">3V3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="31.083333333333332"/>
<g transform="translate(56.33102602061157,30.383333333333333)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="31.183333333333334">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="29.083333333333332"/>
<g transform="translate(56.33102602061157,28.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="29.183333333333334">P9</text>
<g transform="translate(59.93102602061157,28.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="29.183333333333334">D5</text>
<g transform="translate(62.93102602061157,28.383333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="29.183333333333334">PWM3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="27.083333333333332"/>
<g transform="translate(56.33102602061157,26.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="27.183333333333334">P0</text>
<g transform="translate(59.93102602061157,26.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="27.183333333333334">D6</text>
<g transform="translate(62.93102602061157,26.383333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="27.183333333333334">TX2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="25.083333333333332"/>
<g transform="translate(56.33102602061157,24.383333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="25.183333333333334">P21</text>
<g transform="translate(59.93102602061157,24.383333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="25.183333333333334">D7</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="23.08333333333333"/>
<g transform="translate(56.33102602061157,22.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="23.18333333333333">P8</text>
<g transform="translate(59.93102602061157,22.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="23.18333333333333">D8</text>
<g transform="translate(62.93102602061157,22.38333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="23.18333333333333">PWM2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="21.08333333333333"/>
<g transform="translate(56.33102602061157,20.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="21.18333333333333">P7</text>
<g transform="translate(59.93102602061157,20.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="21.18333333333333">D9</text>
<g transform="translate(62.93102602061157,20.38333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="21.18333333333333">PWM1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="19.08333333333333"/>
<g transform="translate(56.33102602061157,18.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="19.18333333333333">P10</text>
<g transform="translate(59.93102602061157,18.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="19.18333333333333">D10</text>
<g transform="translate(62.93102602061157,18.38333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="19.18333333333333">RX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.916666666666664" y="17.08333333333333"/>
<g transform="translate(56.33102602061157,16.38333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.81666666666667" y="17.18333333333333">P11</text>
<g transform="translate(59.93102602061157,16.38333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="61.11666666666667" y="17.18333333333333">D11</text>
<g transform="translate(62.93102602061157,16.38333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.41666666666667" y="17.18333333333333">TX1</text>
</svg>

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1 @@
#include "variant.h"

36
boards/cb3l/variant.cpp Normal file
View File

@@ -0,0 +1,36 @@
/* This file was auto-generated from cb3l.json using boardgen */
#include <Arduino.h>
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: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, 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},
};
// clang-format on
} // extern "C"

61
boards/cb3l/variant.h Normal file
View File

@@ -0,0 +1,61 @@
/* This file was auto-generated from cb3l.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 12
#define NUM_DIGITAL_PINS 12
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 0u // GPIO23
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 0
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 1
#define PIN_SERIAL1_RX 10u // GPIO10
#define PIN_SERIAL1_TX 11u // GPIO11
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 0u // GPIO23
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P6 4u // GPIO6
#define PIN_FUNCTION_P7 9u // GPIO7
#define PIN_FUNCTION_P8 8u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 10u // GPIO10
#define PIN_FUNCTION_P11 11u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P21 7u // GPIO21
#define PIN_FUNCTION_P23 0u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 2u // GPIO26
#define PIN_FUNCTION_PWM0 4u // GPIO6
#define PIN_FUNCTION_PWM1 9u // GPIO7
#define PIN_FUNCTION_PWM2 8u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 2u // GPIO26
#define PIN_FUNCTION_RX1 10u // GPIO10
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA1 7u // GPIO21
#define PIN_FUNCTION_TX1 11u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

22
boards/cb3s.json Normal file
View File

@@ -0,0 +1,22 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/cb3s"
],
"build": {
"mcu": "bk7231n",
"variant": "cb3s"
},
"name": "CB3S Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/cb3s?id=Kai94mec0s076",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-CB3S"
},
"pcb": {
"symbol": "CB3S"
}
}

89
boards/cb3s/README.md Normal file
View File

@@ -0,0 +1,89 @@
# CB3S Wi-Fi Module
*by Tuya Inc.*
[Product page](https://developer.tuya.com/en/docs/iot/cb3s?id=Kai94mec0s076)
- [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
-------------|------------------------------------------
Board code | `cb3s`
MCU | BK7231N
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 v5.1
FCC ID | [2ANDL-CB3S](https://fccid.io/2ANDL-CB3S)
## Usage
**Board code:** `cb3s`
In `platformio.ini`:
```ini
[env:cb3s]
platform = libretuya
board = cb3s
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: cb3s
framework:
version: dev
```
## Pinout
![Pinout](pinout_cb3s.svg)
## 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 | P21 | | I2C1_SDA | | | TMS
D8 | P8 | | | | PWM2 |
D9 | P7 | | | | PWM1 |
D10 | P10 | UART1_RX | | | |
D11 | P11 | UART1_TX | | | |
D12 | P22 | | | | | TDI
D13 | 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 / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 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.

375
boards/cb3s/pinout_cb3s.svg Normal file
View File

@@ -0,0 +1,375 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" height="500" version="1.1" viewBox="0,0,85.33333333333333,41.666666666666664" width="1024">
<defs/>
<rect fill="white" height="41.666666666666664" stroke="black" stroke-width="0.1" width="85.33333333333333" x="0" y="0"/>
<linearGradient gradientUnits="objectBoundingBox" id="id1" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#47a8cd"/>
<stop offset="100%" stop-color="#008fb5"/>
</linearGradient>
<rect fill="url(#id1) none" height="23.9" stroke="#b5a739" stroke-width="0.1" width="15.9" x="36.16666666666666" y="5.433333333333331"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin1.trace" width="0.7" x="36.11666666666666" y="13.133333333333331"/>
<circle cx="36.11666666666666" cy="13.73333333333333" fill="#fff" id="esp12e-22.front.left.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin2.trace" width="0.7" x="36.11666666666666" y="15.133333333333331"/>
<circle cx="36.11666666666666" cy="15.73333333333333" fill="#fff" id="esp12e-22.front.left.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin3.trace" width="0.7" x="36.11666666666666" y="17.133333333333333"/>
<circle cx="36.11666666666666" cy="17.73333333333333" fill="#fff" id="esp12e-22.front.left.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin4.trace" width="0.7" x="36.11666666666666" y="19.133333333333333"/>
<circle cx="36.11666666666666" cy="19.73333333333333" fill="#fff" id="esp12e-22.front.left.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin5.trace" width="0.7" x="36.11666666666666" y="21.133333333333333"/>
<circle cx="36.11666666666666" cy="21.733333333333334" fill="#fff" id="esp12e-22.front.left.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin6.trace" width="0.7" x="36.11666666666666" y="23.133333333333333"/>
<circle cx="36.11666666666666" cy="23.733333333333334" fill="#fff" id="esp12e-22.front.left.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin7.trace" width="0.7" x="36.11666666666666" y="25.133333333333333"/>
<circle cx="36.11666666666666" cy="25.733333333333334" fill="#fff" id="esp12e-22.front.left.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin8.trace" width="0.7" x="36.11666666666666" y="27.133333333333333"/>
<circle cx="36.11666666666666" cy="27.733333333333334" fill="#fff" id="esp12e-22.front.left.pin8.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin1.trace" width="0.7" x="51.41666666666666" y="13.133333333333331"/>
<circle cx="52.11666666666666" cy="13.73333333333333" fill="#fff" id="esp12e-22.front.right.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin2.trace" width="0.7" x="51.41666666666666" y="15.133333333333331"/>
<circle cx="52.11666666666666" cy="15.73333333333333" fill="#fff" id="esp12e-22.front.right.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin3.trace" width="0.7" x="51.41666666666666" y="17.133333333333333"/>
<circle cx="52.11666666666666" cy="17.73333333333333" fill="#fff" id="esp12e-22.front.right.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin4.trace" width="0.7" x="51.41666666666666" y="19.133333333333333"/>
<circle cx="52.11666666666666" cy="19.73333333333333" fill="#fff" id="esp12e-22.front.right.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin5.trace" width="0.7" x="51.41666666666666" y="21.133333333333333"/>
<circle cx="52.11666666666666" cy="21.733333333333334" fill="#fff" id="esp12e-22.front.right.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin6.trace" width="0.7" x="51.41666666666666" y="23.133333333333333"/>
<circle cx="52.11666666666666" cy="23.733333333333334" fill="#fff" id="esp12e-22.front.right.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin7.trace" width="0.7" x="51.41666666666666" y="25.133333333333333"/>
<circle cx="52.11666666666666" cy="25.733333333333334" fill="#fff" id="esp12e-22.front.right.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin8.trace" width="0.7" x="51.41666666666666" y="27.133333333333333"/>
<circle cx="52.11666666666666" cy="27.733333333333334" fill="#fff" id="esp12e-22.front.right.pin8.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin1.trace" width="1.2" x="38.56666666666666" y="28.68333333333333"/>
<circle cx="39.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin2.trace" width="1.2" x="40.56666666666666" y="28.68333333333333"/>
<circle cx="41.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin3.trace" width="1.2" x="42.56666666666666" y="28.68333333333333"/>
<circle cx="43.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin4.trace" width="1.2" x="44.56666666666666" y="28.68333333333333"/>
<circle cx="45.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin5.trace" width="1.2" x="46.56666666666666" y="28.68333333333333"/>
<circle cx="47.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin6.trace" width="1.2" x="48.56666666666666" y="28.68333333333333"/>
<circle cx="49.16666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin6.cast" r="0.35"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="39.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="38.86666666666666" y="31.383333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label1.anchor" width="0.0" x="39.36666666666666" y="31.483333333333334"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="41.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="38.86666666666666" y="33.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label2.anchor" width="0.0" x="39.36666666666666" y="33.483333333333334"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="43.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="38.86666666666666" y="35.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label3.anchor" width="0.0" x="39.36666666666666" y="35.483333333333334"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="45.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="45.16666666666666" y="35.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label4.anchor" width="0.0" x="48.86666666666666" y="35.483333333333334"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="47.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="47.16666666666666" y="33.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label5.anchor" width="0.0" x="48.86666666666666" y="33.483333333333334"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="49.06666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="49.16666666666666" y="31.383333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label6.anchor" width="0.0" x="48.86666666666666" y="31.483333333333334"/>
<linearGradient gradientUnits="objectBoundingBox" id="id2" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="whitesmoke"/>
<stop offset="100%" stop-color="#999"/>
</linearGradient>
<rect fill="url(#id2) none" height="15.8" rx="0.5" ry="0.5" width="13.6" x="37.31666666666666" y="12.333333333333332"/>
<rect fill="#fff" height="0.15" width="15.0" x="36.61666666666666" y="11.583333333333332"/>
<text fill="#fff" font-family="Consolas" font-size="1.0" x="43.11666666666666" y="10.883333333333331">CB3S</text>
<rect fill="#58839b" height="5.2" width="0.5" x="37.21666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="4.6" x="37.21666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="5.2" width="0.5" x="39.41666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="3.0" width="0.5" x="41.31666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="3.0" x="41.31666666666666" y="8.68333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="43.81666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="2.7" x="43.81666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="3.0" width="0.5" x="46.01666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="3.0" x="46.01666666666666" y="8.68333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="48.51666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="2.5" x="48.51666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="4.4" width="0.5" x="50.51666666666666" y="6.183333333333331"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="13.633333333333331"/>
<g transform="translate(29.231026020611555,12.93333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="13.73333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="15.633333333333331"/>
<g transform="translate(29.231026020611555,14.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="15.73333333333333">P23</text>
<g transform="translate(25.631026020611557,14.93333333333333)">
<rect fill="#8ad039" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.11666666666666" y="15.73333333333333">ADC3</text>
<g transform="translate(22.631026020611557,14.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="23.81666666666666" y="15.73333333333333">D0</text>
<g transform="translate(19.631026020611557,14.93333333333333)">
<rect fill="#16a352" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.81666666666666" y="15.73333333333333">A0</text>
<g transform="translate(16.031026020611556,14.93333333333333)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="17.51666666666666" y="15.73333333333333">TDO</text>
<g transform="translate(12.431026020611556,14.93333333333333)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="13.916666666666657" y="15.73333333333333">FSO</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="17.63333333333333"/>
<g transform="translate(29.231026020611555,16.93333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="17.73333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="19.63333333333333"/>
<g transform="translate(29.231026020611555,18.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="19.73333333333333">P14</text>
<g transform="translate(26.23102602061156,18.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.41666666666666" y="19.73333333333333">D1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="21.633333333333333"/>
<g transform="translate(29.231026020611555,20.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="21.733333333333334">P26</text>
<g transform="translate(26.23102602061156,20.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.41666666666666" y="21.733333333333334">D2</text>
<g transform="translate(22.631026020611557,20.933333333333334)">
<rect fill="#aeafc1" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.11666666666666" y="21.733333333333334">IRDA</text>
<g transform="translate(19.03102602061156,20.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.516666666666662" y="21.733333333333334">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="23.633333333333333"/>
<g transform="translate(29.231026020611555,22.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="23.733333333333334">P24</text>
<g transform="translate(26.23102602061156,22.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.41666666666666" y="23.733333333333334">D3</text>
<g transform="translate(22.631026020611557,22.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.11666666666666" y="23.733333333333334">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="25.633333333333333"/>
<g transform="translate(29.231026020611555,24.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="25.733333333333334">P6</text>
<g transform="translate(26.23102602061156,24.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.41666666666666" y="25.733333333333334">D4</text>
<g transform="translate(22.631026020611557,24.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.11666666666666" y="25.733333333333334">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="33.01666666666666" y="27.633333333333333"/>
<g transform="translate(29.231026020611555,26.933333333333334)">
<rect fill="#cd3c24" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.716666666666658" y="27.733333333333334">3V3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="27.633333333333333"/>
<g transform="translate(56.03102602061156,26.933333333333334)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="27.733333333333334">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="25.633333333333333"/>
<g transform="translate(56.03102602061156,24.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="25.733333333333334">P9</text>
<g transform="translate(59.631026020611564,24.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="25.733333333333334">D5</text>
<g transform="translate(62.631026020611564,24.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="25.733333333333334">PWM3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="23.633333333333333"/>
<g transform="translate(56.03102602061156,22.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="23.733333333333334">P0</text>
<g transform="translate(59.631026020611564,22.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="23.733333333333334">D6</text>
<g transform="translate(62.631026020611564,22.933333333333334)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="23.733333333333334">TX2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="21.633333333333333"/>
<g transform="translate(56.03102602061156,20.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="21.733333333333334">P21</text>
<g transform="translate(59.631026020611564,20.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="21.733333333333334">D7</text>
<g transform="translate(62.631026020611564,20.933333333333334)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="21.733333333333334">SDA1</text>
<g transform="translate(66.23102602061155,20.933333333333334)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="67.71666666666665" y="21.733333333333334">TMS</text>
<g transform="translate(69.83102602061156,20.933333333333334)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="middle" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="71.31666666666666" y="20.720833333333335">___</text>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="71.31666666666666" y="21.839583333333334">FCS</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="19.63333333333333"/>
<g transform="translate(56.03102602061156,18.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="19.73333333333333">P8</text>
<g transform="translate(59.631026020611564,18.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="19.73333333333333">D8</text>
<g transform="translate(62.631026020611564,18.93333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="19.73333333333333">PWM2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="17.63333333333333"/>
<g transform="translate(56.03102602061156,16.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="17.73333333333333">P7</text>
<g transform="translate(59.631026020611564,16.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="17.73333333333333">D9</text>
<g transform="translate(62.631026020611564,16.93333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="17.73333333333333">PWM1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="15.633333333333331"/>
<g transform="translate(56.03102602061156,14.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="15.73333333333333">P10</text>
<g transform="translate(59.631026020611564,14.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="15.73333333333333">D10</text>
<g transform="translate(62.631026020611564,14.93333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="15.73333333333333">RX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="52.61666666666666" y="13.633333333333331"/>
<g transform="translate(56.03102602061156,12.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.516666666666666" y="13.73333333333333">P11</text>
<g transform="translate(59.631026020611564,12.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.81666666666666" y="13.73333333333333">D11</text>
<g transform="translate(62.631026020611564,12.93333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.11666666666666" y="13.73333333333333">TX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="36.26666666666666" y="31.383333333333333"/>
<g transform="translate(32.48102602061156,30.683333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="33.96666666666666" y="31.483333333333334">P23</text>
<g transform="translate(28.881026020611554,30.683333333333334)">
<rect fill="#8ad039" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.366666666666656" y="31.483333333333334">ADC3</text>
<g transform="translate(25.881026020611557,30.683333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.06666666666666" y="31.483333333333334">D0</text>
<g transform="translate(22.881026020611557,30.683333333333334)">
<rect fill="#16a352" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="24.06666666666666" y="31.483333333333334">A0</text>
<g transform="translate(19.281026020611556,30.683333333333334)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.76666666666666" y="31.483333333333334">TDO</text>
<g transform="translate(15.681026020611556,30.683333333333334)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="17.166666666666657" y="31.483333333333334">FSO</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="36.26666666666666" y="33.38333333333333"/>
<g transform="translate(32.48102602061156,32.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="33.96666666666666" y="33.483333333333334">P22</text>
<g transform="translate(29.481026020611555,32.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.666666666666657" y="33.483333333333334">D12</text>
<g transform="translate(25.881026020611557,32.68333333333334)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.36666666666666" y="33.483333333333334">TDI</text>
<g transform="translate(22.281026020611556,32.68333333333334)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="23.76666666666666" y="33.483333333333334">FSI</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="36.26666666666666" y="35.38333333333333"/>
<g transform="translate(32.48102602061156,34.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="33.96666666666666" y="35.483333333333334">P21</text>
<g transform="translate(29.481026020611555,34.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="30.666666666666657" y="35.483333333333334">D7</text>
<g transform="translate(25.881026020611557,34.68333333333334)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="27.36666666666666" y="35.483333333333334">SDA1</text>
<g transform="translate(22.281026020611556,34.68333333333334)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="23.76666666666666" y="35.483333333333334">TMS</text>
<g transform="translate(18.681026020611558,34.68333333333334)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="middle" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.16666666666666" y="34.47083333333334">___</text>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="20.16666666666666" y="35.58958333333334">FCS</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="49.36666666666666" y="35.38333333333333"/>
<g transform="translate(52.78102602061156,34.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="54.266666666666666" y="35.483333333333334">P20</text>
<g transform="translate(56.381026020611564,34.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.56666666666666" y="35.483333333333334">D13</text>
<g transform="translate(59.381026020611564,34.68333333333334)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.86666666666667" y="35.483333333333334">SCL1</text>
<g transform="translate(62.981026020611566,34.68333333333334)">
<rect fill="#ffe680" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="64.46666666666667" y="35.483333333333334">TCK</text>
<g transform="translate(66.58102602061156,34.68333333333334)">
<rect fill="#f68a1e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="68.06666666666666" y="35.483333333333334">FSCK</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="49.36666666666666" y="33.38333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="49.36666666666666" y="31.383333333333333"/>
</svg>

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1 @@
#include "variant.h"

40
boards/cb3s/variant.cpp Normal file
View File

@@ -0,0 +1,40 @@
/* This file was auto-generated from cb3s.json using boardgen */
#include <Arduino.h>
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: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, 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: P20, I2C1_SCL, TCK, FSCK
{GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

69
boards/cb3s/variant.h Normal file
View File

@@ -0,0 +1,69 @@
/* This file was auto-generated from cb3s.json using boardgen */
#pragma once
#include <WVariant.h>
// 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 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 1
#define PIN_WIRE1_SCL 13u // GPIO20
#define PIN_WIRE1_SDA_0 7u // GPIO21
#define PIN_WIRE1_SDA_1 7u // GPIO21
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 1
#define PIN_SERIAL1_RX 10u // GPIO10
#define PIN_SERIAL1_TX 11u // GPIO11
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 0u // GPIO23
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P6 4u // GPIO6
#define PIN_FUNCTION_P7 9u // GPIO7
#define PIN_FUNCTION_P8 8u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 10u // GPIO10
#define PIN_FUNCTION_P11 11u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P20 13u // GPIO20
#define PIN_FUNCTION_P21 7u // GPIO21
#define PIN_FUNCTION_P22 12u // GPIO22
#define PIN_FUNCTION_P23 0u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 2u // GPIO26
#define PIN_FUNCTION_PWM0 4u // GPIO6
#define PIN_FUNCTION_PWM1 9u // GPIO7
#define PIN_FUNCTION_PWM2 8u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 2u // GPIO26
#define PIN_FUNCTION_RX1 10u // GPIO10
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL1 13u // GPIO20
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA1 7u // GPIO21
#define PIN_FUNCTION_TX1 11u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

22
boards/cb3se.json Normal file
View File

@@ -0,0 +1,22 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/cb3se"
],
"build": {
"mcu": "bk7231n",
"variant": "cb3se"
},
"name": "CB3SE Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/CB3SE-Module-Datasheet?id=Kanoiluul7nl2",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-CB3SE"
},
"pcb": {
"symbol": "CB3SE"
}
}

92
boards/cb3se/README.md Normal file
View File

@@ -0,0 +1,92 @@
# CB3SE Wi-Fi Module
*by Tuya Inc.*
[Product page](https://developer.tuya.com/en/docs/iot/CB3SE-Module-Datasheet?id=Kanoiluul7nl2)
- [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
-------------|--------------------------------------------
Board code | `cb3se`
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 17x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
FCC ID | [2ANDL-CB3SE](https://fccid.io/2ANDL-CB3SE)
## Usage
**Board code:** `cb3se`
In `platformio.ini`:
```ini
[env:cb3se]
platform = libretuya
board = cb3se
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: cb3se
framework:
version: dev
```
## Pinout
![Pinout](pinout_cb3se.svg)
## 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 | P1 | UART2_RX | I2C2_SDA | | |
D8 | P8 | | | | PWM2 |
D9 | P7 | | | | PWM1 |
D10 | P10 | UART1_RX | | | |
D11 | P11 | UART1_TX | | | |
D12 | P15 | | | CS | |
D13 | P22 | | | | | TDI
D14 | P20 | | I2C1_SCL | | | TCK
D15 | P17 | | | MISO | |
D16 | P16 | | | MOSI | |
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 / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 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.

View File

@@ -0,0 +1,345 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" height="500" version="1.1" viewBox="0,0,85.33333333333333,41.666666666666664" width="1024">
<defs/>
<rect fill="white" height="41.666666666666664" stroke="black" stroke-width="0.1" width="85.33333333333333" x="0" y="0"/>
<linearGradient gradientUnits="objectBoundingBox" id="id1" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#47a8cd"/>
<stop offset="100%" stop-color="#008fb5"/>
</linearGradient>
<rect fill="url(#id1) none" height="23.9" stroke="#b5a739" stroke-width="0.1" width="15.9" x="34.66666666666666" y="5.433333333333331"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin1.trace" width="0.7" x="34.61666666666666" y="13.133333333333331"/>
<circle cx="34.61666666666666" cy="13.73333333333333" fill="#fff" id="esp12e-22.front.left.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin2.trace" width="0.7" x="34.61666666666666" y="15.133333333333331"/>
<circle cx="34.61666666666666" cy="15.73333333333333" fill="#fff" id="esp12e-22.front.left.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin3.trace" width="0.7" x="34.61666666666666" y="17.133333333333333"/>
<circle cx="34.61666666666666" cy="17.73333333333333" fill="#fff" id="esp12e-22.front.left.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin4.trace" width="0.7" x="34.61666666666666" y="19.133333333333333"/>
<circle cx="34.61666666666666" cy="19.73333333333333" fill="#fff" id="esp12e-22.front.left.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin5.trace" width="0.7" x="34.61666666666666" y="21.133333333333333"/>
<circle cx="34.61666666666666" cy="21.733333333333334" fill="#fff" id="esp12e-22.front.left.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin6.trace" width="0.7" x="34.61666666666666" y="23.133333333333333"/>
<circle cx="34.61666666666666" cy="23.733333333333334" fill="#fff" id="esp12e-22.front.left.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin7.trace" width="0.7" x="34.61666666666666" y="25.133333333333333"/>
<circle cx="34.61666666666666" cy="25.733333333333334" fill="#fff" id="esp12e-22.front.left.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.left.pin8.trace" width="0.7" x="34.61666666666666" y="27.133333333333333"/>
<circle cx="34.61666666666666" cy="27.733333333333334" fill="#fff" id="esp12e-22.front.left.pin8.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin1.trace" width="0.7" x="49.91666666666666" y="13.133333333333331"/>
<circle cx="50.61666666666666" cy="13.73333333333333" fill="#fff" id="esp12e-22.front.right.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin2.trace" width="0.7" x="49.91666666666666" y="15.133333333333331"/>
<circle cx="50.61666666666666" cy="15.73333333333333" fill="#fff" id="esp12e-22.front.right.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin3.trace" width="0.7" x="49.91666666666666" y="17.133333333333333"/>
<circle cx="50.61666666666666" cy="17.73333333333333" fill="#fff" id="esp12e-22.front.right.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin4.trace" width="0.7" x="49.91666666666666" y="19.133333333333333"/>
<circle cx="50.61666666666666" cy="19.73333333333333" fill="#fff" id="esp12e-22.front.right.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin5.trace" width="0.7" x="49.91666666666666" y="21.133333333333333"/>
<circle cx="50.61666666666666" cy="21.733333333333334" fill="#fff" id="esp12e-22.front.right.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin6.trace" width="0.7" x="49.91666666666666" y="23.133333333333333"/>
<circle cx="50.61666666666666" cy="23.733333333333334" fill="#fff" id="esp12e-22.front.right.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin7.trace" width="0.7" x="49.91666666666666" y="25.133333333333333"/>
<circle cx="50.61666666666666" cy="25.733333333333334" fill="#fff" id="esp12e-22.front.right.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12e-22.front.right.pin8.trace" width="0.7" x="49.91666666666666" y="27.133333333333333"/>
<circle cx="50.61666666666666" cy="27.733333333333334" fill="#fff" id="esp12e-22.front.right.pin8.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin1.trace" width="1.2" x="37.06666666666666" y="28.68333333333333"/>
<circle cx="37.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin2.trace" width="1.2" x="39.06666666666666" y="28.68333333333333"/>
<circle cx="39.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin3.trace" width="1.2" x="41.06666666666666" y="28.68333333333333"/>
<circle cx="41.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin4.trace" width="1.2" x="43.06666666666666" y="28.68333333333333"/>
<circle cx="43.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin5.trace" width="1.2" x="45.06666666666666" y="28.68333333333333"/>
<circle cx="45.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="0.7" id="pins_horz6_2mm_0.7mm.pin6.trace" width="1.2" x="47.06666666666666" y="28.68333333333333"/>
<circle cx="47.66666666666666" cy="29.383333333333333" fill="#fff" id="pins_horz6_2mm_0.7mm.pin6.cast" r="0.35"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="37.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="37.36666666666666" y="31.383333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label1.anchor" width="0.0" x="37.86666666666666" y="31.483333333333334"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="39.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="37.36666666666666" y="33.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label2.anchor" width="0.0" x="37.86666666666666" y="33.483333333333334"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="41.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="37.36666666666666" y="35.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label3.anchor" width="0.0" x="37.86666666666666" y="35.483333333333334"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="43.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="43.66666666666666" y="35.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label4.anchor" width="0.0" x="47.36666666666666" y="35.483333333333334"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="45.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="45.66666666666666" y="33.38333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label5.anchor" width="0.0" x="47.36666666666666" y="33.483333333333334"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="47.56666666666666" y="29.58333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="47.66666666666666" y="31.383333333333333"/>
<rect height="0.0" id="esp12e-22.front.down.label6.anchor" width="0.0" x="47.36666666666666" y="31.483333333333334"/>
<linearGradient gradientUnits="objectBoundingBox" id="id2" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="whitesmoke"/>
<stop offset="100%" stop-color="#999"/>
</linearGradient>
<rect fill="url(#id2) none" height="15.8" rx="0.5" ry="0.5" width="13.6" x="35.81666666666666" y="12.333333333333332"/>
<rect fill="#fff" height="0.15" width="15.0" x="35.11666666666666" y="11.583333333333332"/>
<text fill="#fff" font-family="Consolas" font-size="1.0" x="41.61666666666666" y="10.883333333333331">CB3SE</text>
<rect fill="#58839b" height="5.2" width="0.5" x="35.71666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="4.6" x="35.71666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="5.2" width="0.5" x="37.91666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="3.0" width="0.5" x="39.81666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="3.0" x="39.81666666666666" y="8.68333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="42.31666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="2.7" x="42.31666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="3.0" width="0.5" x="44.51666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="3.0" x="44.51666666666666" y="8.68333333333333"/>
<rect fill="#58839b" height="3.0" width="0.5" x="47.01666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="0.5" width="2.5" x="47.01666666666666" y="6.183333333333331"/>
<rect fill="#58839b" height="4.4" width="0.5" x="49.01666666666666" y="6.183333333333331"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="13.633333333333331"/>
<g transform="translate(27.731026020611555,12.93333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="13.73333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="15.633333333333331"/>
<g transform="translate(27.731026020611555,14.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="15.73333333333333">P23</text>
<g transform="translate(24.131026020611557,14.93333333333333)">
<rect fill="#8ad039" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.61666666666666" y="15.73333333333333">ADC3</text>
<g transform="translate(21.131026020611557,14.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="22.31666666666666" y="15.73333333333333">D0</text>
<g transform="translate(18.131026020611557,14.93333333333333)">
<rect fill="#16a352" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="19.31666666666666" y="15.73333333333333">A0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="17.63333333333333"/>
<g transform="translate(27.731026020611555,16.93333333333333)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="17.73333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="19.63333333333333"/>
<g transform="translate(27.731026020611555,18.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="19.73333333333333">P14</text>
<g transform="translate(24.73102602061156,18.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.91666666666666" y="19.73333333333333">D1</text>
<g transform="translate(21.131026020611557,18.93333333333333)">
<rect fill="#e9ba33" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="22.61666666666666" y="19.73333333333333">SCK</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="21.633333333333333"/>
<g transform="translate(27.731026020611555,20.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="21.733333333333334">P26</text>
<g transform="translate(24.73102602061156,20.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.91666666666666" y="21.733333333333334">D2</text>
<g transform="translate(21.131026020611557,20.933333333333334)">
<rect fill="#aeafc1" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="22.61666666666666" y="21.733333333333334">IRDA</text>
<g transform="translate(17.53102602061156,20.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="19.016666666666662" y="21.733333333333334">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="23.633333333333333"/>
<g transform="translate(27.731026020611555,22.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="23.733333333333334">P24</text>
<g transform="translate(24.73102602061156,22.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.91666666666666" y="23.733333333333334">D3</text>
<g transform="translate(21.131026020611557,22.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="22.61666666666666" y="23.733333333333334">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="25.633333333333333"/>
<g transform="translate(27.731026020611555,24.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="25.733333333333334">P6</text>
<g transform="translate(24.73102602061156,24.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.91666666666666" y="25.733333333333334">D4</text>
<g transform="translate(21.131026020611557,24.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="22.61666666666666" y="25.733333333333334">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="27.633333333333333"/>
<g transform="translate(27.731026020611555,26.933333333333334)">
<rect fill="#cd3c24" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.216666666666658" y="27.733333333333334">3V3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="27.633333333333333"/>
<g transform="translate(54.53102602061156,26.933333333333334)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="27.733333333333334">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="25.633333333333333"/>
<g transform="translate(54.53102602061156,24.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="25.733333333333334">P9</text>
<g transform="translate(58.131026020611564,24.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="25.733333333333334">D5</text>
<g transform="translate(61.131026020611564,24.933333333333334)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="25.733333333333334">PWM3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="23.633333333333333"/>
<g transform="translate(54.53102602061156,22.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="23.733333333333334">P0</text>
<g transform="translate(58.131026020611564,22.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="23.733333333333334">D6</text>
<g transform="translate(61.131026020611564,22.933333333333334)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="23.733333333333334">TX2</text>
<g transform="translate(64.73102602061155,22.933333333333334)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="66.21666666666665" y="23.733333333333334">SCL2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="21.633333333333333"/>
<g transform="translate(54.53102602061156,20.933333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="21.733333333333334">P1</text>
<g transform="translate(58.131026020611564,20.933333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="21.733333333333334">D7</text>
<g transform="translate(61.131026020611564,20.933333333333334)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="21.733333333333334">RX2</text>
<g transform="translate(64.73102602061155,20.933333333333334)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="66.21666666666665" y="21.733333333333334">SDA2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="19.63333333333333"/>
<g transform="translate(54.53102602061156,18.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="19.73333333333333">P8</text>
<g transform="translate(58.131026020611564,18.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="19.73333333333333">D8</text>
<g transform="translate(61.131026020611564,18.93333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="19.73333333333333">PWM2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="17.63333333333333"/>
<g transform="translate(54.53102602061156,16.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="17.73333333333333">P7</text>
<g transform="translate(58.131026020611564,16.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="17.73333333333333">D9</text>
<g transform="translate(61.131026020611564,16.93333333333333)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="17.73333333333333">PWM1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="15.633333333333331"/>
<g transform="translate(54.53102602061156,14.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="15.73333333333333">P10</text>
<g transform="translate(58.131026020611564,14.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="15.73333333333333">D10</text>
<g transform="translate(61.131026020611564,14.93333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="15.73333333333333">RX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="13.633333333333331"/>
<g transform="translate(54.53102602061156,12.93333333333333)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.016666666666666" y="13.73333333333333">P11</text>
<g transform="translate(58.131026020611564,12.93333333333333)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.31666666666666" y="13.73333333333333">D11</text>
<g transform="translate(61.131026020611564,12.93333333333333)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="62.61666666666667" y="13.73333333333333">TX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="34.76666666666666" y="31.383333333333333"/>
<g transform="translate(30.981026020611555,30.683333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="32.46666666666666" y="31.483333333333334">P15</text>
<g transform="translate(27.98102602061156,30.683333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.16666666666666" y="31.483333333333334">D12</text>
<g transform="translate(24.381026020611557,30.683333333333334)">
<rect fill="#e9ba33" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="25.86666666666666" y="31.483333333333334">CS</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="34.76666666666666" y="33.38333333333333"/>
<g transform="translate(30.981026020611555,32.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="32.46666666666666" y="33.483333333333334">P22</text>
<g transform="translate(27.98102602061156,32.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="29.16666666666666" y="33.483333333333334">D13</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="34.76666666666666" y="35.38333333333333"/>
<g transform="translate(30.981026020611555,34.68333333333334)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="32.46666666666666" y="35.483333333333334">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="47.86666666666666" y="35.38333333333333"/>
<g transform="translate(51.28102602061156,34.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="52.766666666666666" y="35.483333333333334">P20</text>
<g transform="translate(54.881026020611564,34.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.06666666666666" y="35.483333333333334">D14</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="47.86666666666666" y="33.38333333333333"/>
<g transform="translate(51.28102602061156,32.68333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="52.766666666666666" y="33.483333333333334">P17</text>
<g transform="translate(54.881026020611564,32.68333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.06666666666666" y="33.483333333333334">D15</text>
<g transform="translate(57.881026020611564,32.68333333333334)">
<rect fill="#e9ba33" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.36666666666667" y="33.483333333333334">MISO</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="47.86666666666666" y="31.383333333333333"/>
<g transform="translate(51.28102602061156,30.683333333333334)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="52.766666666666666" y="31.483333333333334">P16</text>
<g transform="translate(54.881026020611564,30.683333333333334)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="56.06666666666666" y="31.483333333333334">D16</text>
<g transform="translate(57.881026020611564,30.683333333333334)">
<rect fill="#e9ba33" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="59.36666666666667" y="31.483333333333334">MOSI</text>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1 @@
#include "variant.h"

46
boards/cb3se/variant.cpp Normal file
View File

@@ -0,0 +1,46 @@
/* This file was auto-generated from cb3se.json using boardgen */
#include <Arduino.h>
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: P1, UART2_RX, I2C2_SDA
{GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, 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: P15, SD_CMD, CS
{GPIO15, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D13: P22, TDI, FSI
{GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
// D14: P20, I2C1_SCL, TCK, FSCK
{GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
// D15: P17, SD_D1, MISO
{GPIO17, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D16: P16, SD_D0, MOSI
{GPIO16, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

75
boards/cb3se/variant.h Normal file
View File

@@ -0,0 +1,75 @@
/* This file was auto-generated from cb3se.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 17
#define NUM_DIGITAL_PINS 17
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 0u // GPIO23
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 1
#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
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 0u // GPIO23
#define PIN_FUNCTION_CS 12u // GPIO15
#define PIN_FUNCTION_MISO 15u // GPIO17
#define PIN_FUNCTION_MOSI 16u // GPIO16
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P1 7u // GPIO1
#define PIN_FUNCTION_P6 4u // GPIO6
#define PIN_FUNCTION_P7 9u // GPIO7
#define PIN_FUNCTION_P8 8u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 10u // GPIO10
#define PIN_FUNCTION_P11 11u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P15 12u // GPIO15
#define PIN_FUNCTION_P16 16u // GPIO16
#define PIN_FUNCTION_P17 15u // GPIO17
#define PIN_FUNCTION_P20 14u // GPIO20
#define PIN_FUNCTION_P22 13u // GPIO22
#define PIN_FUNCTION_P23 0u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 2u // GPIO26
#define PIN_FUNCTION_PWM0 4u // GPIO6
#define PIN_FUNCTION_PWM1 9u // GPIO7
#define PIN_FUNCTION_PWM2 8u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 2u // GPIO26
#define PIN_FUNCTION_RX1 10u // GPIO10
#define PIN_FUNCTION_RX2 7u // GPIO1
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL1 14u // GPIO20
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA2 7u // GPIO1
#define PIN_FUNCTION_TX1 11u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

View File

@@ -35,6 +35,15 @@ board = generic-bk7231n-qfn32-tuya
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-bk7231n-qfn32-tuya
framework:
version: dev
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
@@ -71,8 +80,9 @@ Name | Start | Length | End
Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
App Image | 0x011000 | 1.1 MiB / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
TLV Store | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 8 KiB / 0x2000 | 0x1D3000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 0x200000

View File

@@ -37,3 +37,44 @@
#define PIN_SERIAL1_TX 7u // GPIO11
#define PIN_SERIAL2_RX 1u // GPIO1
#define PIN_SERIAL2_TX 0u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 15u // GPIO23
#define PIN_FUNCTION_CS 9u // GPIO15
#define PIN_FUNCTION_MISO 11u // GPIO17
#define PIN_FUNCTION_MOSI 10u // GPIO16
#define PIN_FUNCTION_P0 0u // GPIO0
#define PIN_FUNCTION_P1 1u // GPIO1
#define PIN_FUNCTION_P6 2u // GPIO6
#define PIN_FUNCTION_P7 3u // GPIO7
#define PIN_FUNCTION_P8 4u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 6u // GPIO10
#define PIN_FUNCTION_P11 7u // GPIO11
#define PIN_FUNCTION_P14 8u // GPIO14
#define PIN_FUNCTION_P15 9u // GPIO15
#define PIN_FUNCTION_P16 10u // GPIO16
#define PIN_FUNCTION_P17 11u // GPIO17
#define PIN_FUNCTION_P20 12u // GPIO20
#define PIN_FUNCTION_P21 13u // GPIO21
#define PIN_FUNCTION_P22 14u // GPIO22
#define PIN_FUNCTION_P23 15u // GPIO23
#define PIN_FUNCTION_P24 16u // GPIO24
#define PIN_FUNCTION_P26 17u // GPIO26
#define PIN_FUNCTION_P28 18u // GPIO28
#define PIN_FUNCTION_PWM0 2u // GPIO6
#define PIN_FUNCTION_PWM1 3u // GPIO7
#define PIN_FUNCTION_PWM2 4u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 16u // GPIO24
#define PIN_FUNCTION_PWM5 17u // GPIO26
#define PIN_FUNCTION_RX1 6u // GPIO10
#define PIN_FUNCTION_RX2 1u // GPIO1
#define PIN_FUNCTION_SCK 8u // GPIO14
#define PIN_FUNCTION_SCL1 12u // GPIO20
#define PIN_FUNCTION_SCL2 0u // GPIO0
#define PIN_FUNCTION_SDA1 13u // GPIO21
#define PIN_FUNCTION_SDA2 1u // GPIO1
#define PIN_FUNCTION_TX1 7u // GPIO11
#define PIN_FUNCTION_TX2 0u // GPIO0

View File

@@ -35,6 +35,15 @@ board = generic-bk7231t-qfn32-tuya
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-bk7231t-qfn32-tuya
framework:
version: dev
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
@@ -72,8 +81,9 @@ 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
Calibration | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
TLV Store | 0x1E1000 | 4 KiB / 0x1000 | 0x1E2000
Network Data | 0x1E2000 | 4 KiB / 0x1000 | 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.

View File

@@ -37,3 +37,44 @@
#define PIN_SERIAL1_TX 7u // GPIO11
#define PIN_SERIAL2_RX 1u // GPIO1
#define PIN_SERIAL2_TX 0u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 15u // GPIO23
#define PIN_FUNCTION_CS 9u // GPIO15
#define PIN_FUNCTION_MISO 11u // GPIO17
#define PIN_FUNCTION_MOSI 10u // GPIO16
#define PIN_FUNCTION_P0 0u // GPIO0
#define PIN_FUNCTION_P1 1u // GPIO1
#define PIN_FUNCTION_P6 2u // GPIO6
#define PIN_FUNCTION_P7 3u // GPIO7
#define PIN_FUNCTION_P8 4u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 6u // GPIO10
#define PIN_FUNCTION_P11 7u // GPIO11
#define PIN_FUNCTION_P14 8u // GPIO14
#define PIN_FUNCTION_P15 9u // GPIO15
#define PIN_FUNCTION_P16 10u // GPIO16
#define PIN_FUNCTION_P17 11u // GPIO17
#define PIN_FUNCTION_P20 12u // GPIO20
#define PIN_FUNCTION_P21 13u // GPIO21
#define PIN_FUNCTION_P22 14u // GPIO22
#define PIN_FUNCTION_P23 15u // GPIO23
#define PIN_FUNCTION_P24 16u // GPIO24
#define PIN_FUNCTION_P26 17u // GPIO26
#define PIN_FUNCTION_P28 18u // GPIO28
#define PIN_FUNCTION_PWM0 2u // GPIO6
#define PIN_FUNCTION_PWM1 3u // GPIO7
#define PIN_FUNCTION_PWM2 4u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 16u // GPIO24
#define PIN_FUNCTION_PWM5 17u // GPIO26
#define PIN_FUNCTION_RX1 6u // GPIO10
#define PIN_FUNCTION_RX2 1u // GPIO1
#define PIN_FUNCTION_SCK 8u // GPIO14
#define PIN_FUNCTION_SCL1 12u // GPIO20
#define PIN_FUNCTION_SCL2 0u // GPIO0
#define PIN_FUNCTION_SDA1 13u // GPIO21
#define PIN_FUNCTION_SDA2 1u // GPIO1
#define PIN_FUNCTION_TX1 7u // GPIO11
#define PIN_FUNCTION_TX2 0u // GPIO0

View File

@@ -28,6 +28,15 @@ board = generic-native
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-native
framework:
version: dev
```
## Flash memory map
Flash size: 4 MiB / 4,194,304 B / 0x400000

View File

@@ -35,6 +35,15 @@ board = generic-rtl8710bn-2mb-468k
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-rtl8710bn-2mb-468k
framework:
version: dev
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other

View File

@@ -51,3 +51,45 @@
#define PIN_SERIAL0_TX 14u // PA_23
#define PIN_SERIAL2_RX 15u // PA_29
#define PIN_SERIAL2_TX 16u // PA_30
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC1 12u // PA_19
#define PIN_FUNCTION_ADC2 17u // AD_2
#define PIN_FUNCTION_CS0 12u // PA_19
#define PIN_FUNCTION_CS1 12u // PA_19
#define PIN_FUNCTION_CTS0 12u // PA_19
#define PIN_FUNCTION_FCS 2u // PA_6
#define PIN_FUNCTION_FD0 5u // PA_9
#define PIN_FUNCTION_FD1 3u // PA_7
#define PIN_FUNCTION_FD2 4u // PA_8
#define PIN_FUNCTION_FD3 7u // PA_11
#define PIN_FUNCTION_FSCK 6u // PA_10
#define PIN_FUNCTION_MISO0 13u // PA_22
#define PIN_FUNCTION_MISO1 13u // PA_22
#define PIN_FUNCTION_MOSI0 14u // PA_23
#define PIN_FUNCTION_MOSI1 14u // PA_23
#define PIN_FUNCTION_PA00 0u // PA_0
#define PIN_FUNCTION_PA05 1u // PA_5
#define PIN_FUNCTION_PA06 2u // PA_6
#define PIN_FUNCTION_PA07 3u // PA_7
#define PIN_FUNCTION_PA08 4u // PA_8
#define PIN_FUNCTION_PA09 5u // PA_9
#define PIN_FUNCTION_PA10 6u // PA_10
#define PIN_FUNCTION_PA11 7u // PA_11
#define PIN_FUNCTION_PA12 8u // PA_12
#define PIN_FUNCTION_PA14 9u // PA_14
#define PIN_FUNCTION_PA15 10u // PA_15
#define PIN_FUNCTION_PA18 11u // PA_18
#define PIN_FUNCTION_PA19 12u // PA_19
#define PIN_FUNCTION_PA22 13u // PA_22
#define PIN_FUNCTION_PA23 14u // PA_23
#define PIN_FUNCTION_PA29 15u // PA_29
#define PIN_FUNCTION_PA30 16u // PA_30
#define PIN_FUNCTION_RTS0 13u // PA_22
#define PIN_FUNCTION_RX0 11u // PA_18
#define PIN_FUNCTION_RX2 15u // PA_29
#define PIN_FUNCTION_SCK0 11u // PA_18
#define PIN_FUNCTION_SCK1 11u // PA_18
#define PIN_FUNCTION_TX0 14u // PA_23
#define PIN_FUNCTION_TX2 16u // PA_30

View File

@@ -35,6 +35,15 @@ board = generic-rtl8710bn-2mb-788k
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-rtl8710bn-2mb-788k
framework:
version: dev
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other

View File

@@ -51,3 +51,45 @@
#define PIN_SERIAL0_TX 14u // PA_23
#define PIN_SERIAL2_RX 15u // PA_29
#define PIN_SERIAL2_TX 16u // PA_30
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC1 12u // PA_19
#define PIN_FUNCTION_ADC2 17u // AD_2
#define PIN_FUNCTION_CS0 12u // PA_19
#define PIN_FUNCTION_CS1 12u // PA_19
#define PIN_FUNCTION_CTS0 12u // PA_19
#define PIN_FUNCTION_FCS 2u // PA_6
#define PIN_FUNCTION_FD0 5u // PA_9
#define PIN_FUNCTION_FD1 3u // PA_7
#define PIN_FUNCTION_FD2 4u // PA_8
#define PIN_FUNCTION_FD3 7u // PA_11
#define PIN_FUNCTION_FSCK 6u // PA_10
#define PIN_FUNCTION_MISO0 13u // PA_22
#define PIN_FUNCTION_MISO1 13u // PA_22
#define PIN_FUNCTION_MOSI0 14u // PA_23
#define PIN_FUNCTION_MOSI1 14u // PA_23
#define PIN_FUNCTION_PA00 0u // PA_0
#define PIN_FUNCTION_PA05 1u // PA_5
#define PIN_FUNCTION_PA06 2u // PA_6
#define PIN_FUNCTION_PA07 3u // PA_7
#define PIN_FUNCTION_PA08 4u // PA_8
#define PIN_FUNCTION_PA09 5u // PA_9
#define PIN_FUNCTION_PA10 6u // PA_10
#define PIN_FUNCTION_PA11 7u // PA_11
#define PIN_FUNCTION_PA12 8u // PA_12
#define PIN_FUNCTION_PA14 9u // PA_14
#define PIN_FUNCTION_PA15 10u // PA_15
#define PIN_FUNCTION_PA18 11u // PA_18
#define PIN_FUNCTION_PA19 12u // PA_19
#define PIN_FUNCTION_PA22 13u // PA_22
#define PIN_FUNCTION_PA23 14u // PA_23
#define PIN_FUNCTION_PA29 15u // PA_29
#define PIN_FUNCTION_PA30 16u // PA_30
#define PIN_FUNCTION_RTS0 13u // PA_22
#define PIN_FUNCTION_RX0 11u // PA_18
#define PIN_FUNCTION_RX2 15u // PA_29
#define PIN_FUNCTION_SCK0 11u // PA_18
#define PIN_FUNCTION_SCK1 11u // PA_18
#define PIN_FUNCTION_TX0 14u // PA_23
#define PIN_FUNCTION_TX2 16u // PA_30

View File

@@ -0,0 +1,100 @@
{
"_base": [
"generic",
"realtek-ambz",
"realtek-ambz-4mb-980k",
"realtek-ambz-bx",
"pcb/ic-rtl8710bn"
],
"build": {
"mcu": "rtl8710bx",
"variant": "generic-rtl8710bx-4mb-980k"
},
"name": "Generic - RTL8710BX (4M/980k)",
"symbol": "RTL8710BX (4M/980k)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bx-4mb-980k/",
"vendor": "Generic",
"doc": {
"extra": [
"## Information",
"This is a generic board definition for RTL8710BX with 4 MiB of flash. It has a bigger application partition size (980 KiB). The used bootloader is also different from the standard Tuya one.",
"It can be found in [Ezviz T31 smart plug](https://www.ezviz.com/product/T31/2021) - bare chip soldered onto the manufacturer-made PCB. The plug is not Tuya/SmartLife-compatible and has a 25Q32CSIG flash chip. Refer to [libretuya#23](https://github.com/kuba2k2/libretuya/issues/23) for photos and more information.",
"Note that stock firmware seems to use smaller app images (0x80000 / 512 KiB). After 0x180000 some product-test data and device logs can be found. Because the OTA2 offset is 0x100000, the board definition was configured to use all available space."
]
},
"pcb": {
"pinout": {
"1": {
"IC": 16,
"ARD": "D0"
},
"2": {
"IC": 28,
"ARD": "D1"
},
"3": {
"IC": 18,
"ARD": "D2"
},
"4": {
"IC": 19,
"ARD": "D3"
},
"5": {
"IC": 20,
"ARD": "D4"
},
"6": {
"IC": 21,
"ARD": "D5"
},
"7": {
"IC": 22,
"ARD": "D6"
},
"8": {
"IC": 23,
"ARD": "D7"
},
"9": {
"IC": 17,
"ARD": "D8"
},
"10": {
"IC": 13,
"ARD": "D9"
},
"11": {
"IC": 14,
"ARD": "D10"
},
"12": {
"IC": 29,
"ARD": "D11"
},
"13": {
"IC": 30,
"ARD": [
"D12",
"A0"
]
},
"14": {
"IC": 31,
"ARD": "D13"
},
"15": {
"IC": 32,
"ARD": "D14"
},
"16": {
"IC": 2,
"ARD": "D15"
},
"17": {
"IC": 1,
"ARD": "D16"
}
}
}
}

View File

@@ -0,0 +1,99 @@
# Generic - RTL8710BX (4M/980k)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bx-4mb-980k/)
- [General info](../../docs/platform/realtek/README.md)
- [Debugging](../../docs/platform/realtek/debugging.md)
- [Flashing guide](../../docs/platform/realtek-ambz/flashing.md)
- [ImageTool (AmebaZ/AmebaD)](https://images.tuyacn.com/smart/Image_Tool/Image_Tool.zip)
Parameter | Value
-------------|----------------------------------
Board code | `generic-rtl8710bx-4mb-980k`
MCU | RTL8710BX
Manufacturer | Realtek
Series | AmebaZ
Frequency | 62.5 MHz
Flash size | 4 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 17x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
## Usage
**Board code:** `generic-rtl8710bx-4mb-980k`
In `platformio.ini`:
```ini
[env:generic-rtl8710bx-4mb-980k]
platform = libretuya
board = generic-rtl8710bx-4mb-980k
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-rtl8710bx-4mb-980k
framework:
version: dev
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
----|------------|-----------|----------|----------------------|------|------
D0 | PA00 | | | | PWM2 |
D1 | PA05 | | | | PWM4 |
D2 | PA06 | | | FCS | |
D3 | PA07 | | | FD1 | |
D4 | PA08 | | | FD2 | |
D5 | PA09 | | | FD0 | |
D6 | PA10 | | | FSCK | |
D7 | PA11 | | | FD3 | |
D8 | PA12 | | | | PWM3 |
D9 | PA14 | | | | PWM0 | SWCLK
D10 | PA15 | | | | PWM1 | SWDIO
D11 | PA18 | UART0_RX | I2C1_SCL | SPI0_SCK, SPI1_SCK | |
D12 | PA19 | UART0_CTS | I2C0_SDA | SPI0_CS, SPI1_CS | |
D13 | PA22 | UART0_RTS | I2C0_SCL | SPI0_MISO, SPI1_MISO | PWM5 |
D14 | PA23 | UART0_TX | I2C1_SDA | SPI0_MOSI, SPI1_MOSI | PWM0 |
D15 | PA29 | UART2_RX | I2C0_SCL | | PWM4 |
D16 | PA30 | UART2_TX | I2C0_SDA | | PWM4 |
A0 | PA19, ADC1 | | | | |
## Flash memory map
Flash size: 4 MiB / 4,194,304 B / 0x400000
Hex values are in bytes.
Name | Start | Length | End
----------------|----------|-------------------|---------
Boot XIP | 0x000000 | 16 KiB / 0x4000 | 0x004000
Boot RAM | 0x004000 | 16 KiB / 0x4000 | 0x008000
(reserved) | 0x008000 | 4 KiB / 0x1000 | 0x009000
System Data | 0x009000 | 4 KiB / 0x1000 | 0x00A000
Calibration | 0x00A000 | 4 KiB / 0x1000 | 0x00B000
OTA1 Image | 0x00B000 | 980 KiB / 0xF5000 | 0x100000
OTA2 Image | 0x100000 | 980 KiB / 0xF5000 | 0x1F5000
Key-Value Store | 0x1F5000 | 32 KiB / 0x8000 | 0x1FD000
User Data | 0x1FD000 | 2 MiB / 0x202000 | 0x3FF000
RDP | 0x3FF000 | 4 KiB / 0x1000 | 0x400000
RDP is most likely not used in Tuya firmwares, as the System Data partition contains an incorrect offset 0xFF000 for RDP, which is in the middle of OTA2 image.
Additionally, Tuya firmware uses an encrypted KV or file storage, which resides at the end of flash memory. This seems to overlap system RDP area.
## Information
This is a generic board definition for RTL8710BX with 4 MiB of flash. It has a bigger application partition size (980 KiB). The used bootloader is also different from the standard Tuya one.
It can be found in [Ezviz T31 smart plug](https://www.ezviz.com/product/T31/2021) - bare chip soldered onto the manufacturer-made PCB. The plug is not Tuya/SmartLife-compatible and has a 25Q32CSIG flash chip. Refer to [libretuya#23](https://github.com/kuba2k2/libretuya/issues/23) for photos and more information.
Note that stock firmware seems to use smaller app images (0x80000 / 512 KiB). After 0x180000 some product-test data and device logs can be found. Because the OTA2 offset is 0x100000, the board definition was configured to use all available space.

View File

@@ -0,0 +1 @@
#include "variant.h"

View File

@@ -0,0 +1,46 @@
/* This file was auto-generated from generic-rtl8710bx-4mb-980k.json using boardgen */
#include <Arduino.h>
extern "C" {
// clang-format off
PinInfo pinTable[PINS_COUNT] = {
// D0: PA00, PWM2
{PA_0, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D1: PA05, PWM4, WAKE1
{PA_5, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D2: PA06, FCS, SD_D2
{PA_6, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D3: PA07, FD1, SD_D3
{PA_7, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D4: PA08, FD2, SD_CMD
{PA_8, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D5: PA09, FD0, SD_CLK
{PA_9, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D6: PA10, FSCK, SD_D0
{PA_10, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D7: PA11, FD3, SD_D1
{PA_11, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D8: PA12, PWM3
{PA_12, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D9: PA14, PWM0, SWCLK
{PA_14, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
// D10: PA15, PWM1, SWDIO
{PA_15, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
// D11: 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},
// D12: 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},
// D13: 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},
// D14: 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},
// D15: PA29, UART2_RX, I2C0_SCL, PWM4
{PA_29, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D16: PA30, UART2_TX, I2C0_SDA, PWM4
{PA_30, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

View File

@@ -0,0 +1,92 @@
/* This file was auto-generated from generic-rtl8710bx-4mb-980k.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 17
#define NUM_DIGITAL_PINS 17
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 12u // PA_19
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 2
#define PIN_SPI0_CS 12u // PA_19
#define PIN_SPI0_MISO 13u // PA_22
#define PIN_SPI0_MOSI 14u // PA_23
#define PIN_SPI0_SCK 11u // PA_18
#define PIN_SPI1_CS 12u // PA_19
#define PIN_SPI1_MISO 13u // PA_22
#define PIN_SPI1_MOSI 14u // PA_23
#define PIN_SPI1_SCK 11u // PA_18
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 2
#define PIN_WIRE0_SCL_0 13u // PA_22
#define PIN_WIRE0_SCL_1 15u // PA_29
#define PIN_WIRE0_SDA_0 12u // PA_19
#define PIN_WIRE0_SDA_1 16u // PA_30
#define PIN_WIRE1_SCL 11u // PA_18
#define PIN_WIRE1_SDA 14u // PA_23
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 2
#define PIN_SERIAL0_CTS 12u // PA_19
#define PIN_SERIAL0_RTS 13u // PA_22
#define PIN_SERIAL0_RX 11u // PA_18
#define PIN_SERIAL0_TX 14u // PA_23
#define PIN_SERIAL2_RX 15u // PA_29
#define PIN_SERIAL2_TX 16u // PA_30
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC1 12u // PA_19
#define PIN_FUNCTION_CS0 12u // PA_19
#define PIN_FUNCTION_CS1 12u // PA_19
#define PIN_FUNCTION_CTS0 12u // PA_19
#define PIN_FUNCTION_FCS 2u // PA_6
#define PIN_FUNCTION_FD0 5u // PA_9
#define PIN_FUNCTION_FD1 3u // PA_7
#define PIN_FUNCTION_FD2 4u // PA_8
#define PIN_FUNCTION_FD3 7u // PA_11
#define PIN_FUNCTION_FSCK 6u // PA_10
#define PIN_FUNCTION_MISO0 13u // PA_22
#define PIN_FUNCTION_MISO1 13u // PA_22
#define PIN_FUNCTION_MOSI0 14u // PA_23
#define PIN_FUNCTION_MOSI1 14u // PA_23
#define PIN_FUNCTION_PA00 0u // PA_0
#define PIN_FUNCTION_PA05 1u // PA_5
#define PIN_FUNCTION_PA06 2u // PA_6
#define PIN_FUNCTION_PA07 3u // PA_7
#define PIN_FUNCTION_PA08 4u // PA_8
#define PIN_FUNCTION_PA09 5u // PA_9
#define PIN_FUNCTION_PA10 6u // PA_10
#define PIN_FUNCTION_PA11 7u // PA_11
#define PIN_FUNCTION_PA12 8u // PA_12
#define PIN_FUNCTION_PA14 9u // PA_14
#define PIN_FUNCTION_PA15 10u // PA_15
#define PIN_FUNCTION_PA18 11u // PA_18
#define PIN_FUNCTION_PA19 12u // PA_19
#define PIN_FUNCTION_PA22 13u // PA_22
#define PIN_FUNCTION_PA23 14u // PA_23
#define PIN_FUNCTION_PA29 15u // PA_29
#define PIN_FUNCTION_PA30 16u // PA_30
#define PIN_FUNCTION_RTS0 13u // PA_22
#define PIN_FUNCTION_RX0 11u // PA_18
#define PIN_FUNCTION_RX2 15u // PA_29
#define PIN_FUNCTION_SCK0 11u // PA_18
#define PIN_FUNCTION_SCK1 11u // PA_18
#define PIN_FUNCTION_TX0 14u // PA_23
#define PIN_FUNCTION_TX2 16u // PA_30

View File

@@ -33,6 +33,15 @@ board = generic-rtl8720cf-2mb-992k
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: generic-rtl8720cf-2mb-992k
framework:
version: dev
```
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000

View File

@@ -35,6 +35,15 @@ board = lsc-lma35
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: lsc-lma35
framework:
version: dev
```
## Pinout
![Pinout](pinout_lsc-lma35.svg)
@@ -71,8 +80,9 @@ Name | Start | Length | End
Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
App Image | 0x011000 | 1.1 MiB / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
TLV Store | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 8 KiB / 0x2000 | 0x1D3000
Calibration | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 4 KiB / 0x1000 | 0x1D2000
TLV Store | 0x1D2000 | 4 KiB / 0x1000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 0x200000

View File

@@ -35,3 +35,37 @@
#define PIN_SERIAL1_TX 13u // GPIO11
#define PIN_SERIAL2_RX 14u // GPIO1
#define PIN_SERIAL2_TX 5u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 6u // GPIO23
#define PIN_FUNCTION_MOSI 2u // GPIO16
#define PIN_FUNCTION_P0 5u // GPIO0
#define PIN_FUNCTION_P1 14u // GPIO1
#define PIN_FUNCTION_P6 10u // GPIO6
#define PIN_FUNCTION_P7 11u // GPIO7
#define PIN_FUNCTION_P8 7u // GPIO8
#define PIN_FUNCTION_P9 8u // GPIO9
#define PIN_FUNCTION_P10 12u // GPIO10
#define PIN_FUNCTION_P11 13u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P16 2u // GPIO16
#define PIN_FUNCTION_P21 9u // GPIO21
#define PIN_FUNCTION_P22 4u // GPIO22
#define PIN_FUNCTION_P23 6u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 0u // GPIO26
#define PIN_FUNCTION_PWM0 10u // GPIO6
#define PIN_FUNCTION_PWM1 11u // GPIO7
#define PIN_FUNCTION_PWM2 7u // GPIO8
#define PIN_FUNCTION_PWM3 8u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 0u // GPIO26
#define PIN_FUNCTION_RX1 12u // GPIO10
#define PIN_FUNCTION_RX2 14u // GPIO1
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL2 5u // GPIO0
#define PIN_FUNCTION_SDA1 9u // GPIO21
#define PIN_FUNCTION_SDA2 14u // GPIO1
#define PIN_FUNCTION_TX1 13u // GPIO11
#define PIN_FUNCTION_TX2 5u // GPIO0

View File

@@ -14,6 +14,9 @@
"name": "WB2L Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/wb2l-datasheet?id=K9duegc9bualu",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-WB2L"
},
"pcb": {
"symbol": "WB2L"
}

View File

@@ -9,7 +9,7 @@
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `wb2l`
MCU | BK7231T
Manufacturer | Beken
@@ -21,6 +21,7 @@ Voltage | 3.0V - 3.6V
I/O | 13x GPIO, 5x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v4.2
FCC ID | [2ANDL-WB2L](https://fccid.io/2ANDL-WB2L)
## Usage
@@ -35,6 +36,15 @@ board = wb2l
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: wb2l
framework:
version: dev
```
## Pinout
![Pinout](pinout_wb2l.svg)
@@ -70,8 +80,9 @@ 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
Calibration | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
TLV Store | 0x1E1000 | 4 KiB / 0x1000 | 0x1E2000
Network Data | 0x1E2000 | 4 KiB / 0x1000 | 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.

View File

@@ -37,3 +37,33 @@
#define PIN_SERIAL1_TX 6u // GPIO11
#define PIN_SERIAL2_RX 7u // GPIO1
#define PIN_SERIAL2_TX 8u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 11u // GPIO23
#define PIN_FUNCTION_P0 8u // GPIO0
#define PIN_FUNCTION_P1 7u // GPIO1
#define PIN_FUNCTION_P6 2u // GPIO6
#define PIN_FUNCTION_P7 1u // GPIO7
#define PIN_FUNCTION_P8 0u // GPIO8
#define PIN_FUNCTION_P10 5u // GPIO10
#define PIN_FUNCTION_P11 6u // GPIO11
#define PIN_FUNCTION_P20 9u // GPIO20
#define PIN_FUNCTION_P21 10u // GPIO21
#define PIN_FUNCTION_P22 12u // GPIO22
#define PIN_FUNCTION_P23 11u // GPIO23
#define PIN_FUNCTION_P24 4u // GPIO24
#define PIN_FUNCTION_P26 3u // GPIO26
#define PIN_FUNCTION_PWM0 2u // GPIO6
#define PIN_FUNCTION_PWM1 1u // GPIO7
#define PIN_FUNCTION_PWM2 0u // GPIO8
#define PIN_FUNCTION_PWM4 4u // GPIO24
#define PIN_FUNCTION_PWM5 3u // GPIO26
#define PIN_FUNCTION_RX1 5u // GPIO10
#define PIN_FUNCTION_RX2 7u // GPIO1
#define PIN_FUNCTION_SCL1 9u // GPIO20
#define PIN_FUNCTION_SCL2 8u // GPIO0
#define PIN_FUNCTION_SDA1 10u // GPIO21
#define PIN_FUNCTION_SDA2 7u // GPIO1
#define PIN_FUNCTION_TX1 6u // GPIO11
#define PIN_FUNCTION_TX2 8u // GPIO0

View File

@@ -14,6 +14,9 @@
"name": "WB2S Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/wb2s-module-datasheet?id=K9ghecl7kc479",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-WB2S"
},
"pcb": {
"symbol": "WB2S"
}

View File

@@ -9,7 +9,7 @@
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `wb2s`
MCU | BK7231T
Manufacturer | Beken
@@ -21,6 +21,7 @@ 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
FCC ID | [2ANDL-WB2S](https://fccid.io/2ANDL-WB2S)
## Usage
@@ -35,6 +36,15 @@ board = wb2s
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: wb2s
framework:
version: dev
```
## Pinout
![Pinout](pinout_wb2s.svg)
@@ -71,8 +81,9 @@ 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
Calibration | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
TLV Store | 0x1E1000 | 4 KiB / 0x1000 | 0x1E2000
Network Data | 0x1E2000 | 4 KiB / 0x1000 | 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.

View File

@@ -39,3 +39,35 @@
#define PIN_SERIAL1_TX 5u // GPIO11
#define PIN_SERIAL2_RX 10u // GPIO1
#define PIN_SERIAL2_TX 11u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 3u // GPIO23
#define PIN_FUNCTION_P0 11u // GPIO0
#define PIN_FUNCTION_P1 10u // GPIO1
#define PIN_FUNCTION_P6 2u // GPIO6
#define PIN_FUNCTION_P7 1u // GPIO7
#define PIN_FUNCTION_P8 0u // GPIO8
#define PIN_FUNCTION_P9 9u // GPIO9
#define PIN_FUNCTION_P10 4u // GPIO10
#define PIN_FUNCTION_P11 5u // GPIO11
#define PIN_FUNCTION_P20 8u // GPIO20
#define PIN_FUNCTION_P21 12u // GPIO21
#define PIN_FUNCTION_P22 13u // GPIO22
#define PIN_FUNCTION_P23 3u // GPIO23
#define PIN_FUNCTION_P24 6u // GPIO24
#define PIN_FUNCTION_P26 7u // GPIO26
#define PIN_FUNCTION_PWM0 2u // GPIO6
#define PIN_FUNCTION_PWM1 1u // GPIO7
#define PIN_FUNCTION_PWM2 0u // GPIO8
#define PIN_FUNCTION_PWM3 9u // GPIO9
#define PIN_FUNCTION_PWM4 6u // GPIO24
#define PIN_FUNCTION_PWM5 7u // GPIO26
#define PIN_FUNCTION_RX1 4u // GPIO10
#define PIN_FUNCTION_RX2 10u // GPIO1
#define PIN_FUNCTION_SCL1 8u // GPIO20
#define PIN_FUNCTION_SCL2 11u // GPIO0
#define PIN_FUNCTION_SDA1 12u // GPIO21
#define PIN_FUNCTION_SDA2 10u // GPIO1
#define PIN_FUNCTION_TX1 5u // GPIO11
#define PIN_FUNCTION_TX2 11u // GPIO0

View File

@@ -13,6 +13,9 @@
"name": "WB3L Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/wb3l-module-datasheet?id=K9duiggw2v8sp",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-WB3L"
},
"pcb": {
"symbol": "WB3L"
}

View File

@@ -9,7 +9,7 @@
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `wb3l`
MCU | BK7231T
Manufacturer | Beken
@@ -21,6 +21,7 @@ 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
FCC ID | [2ANDL-WB3L](https://fccid.io/2ANDL-WB3L)
## Usage
@@ -35,6 +36,15 @@ board = wb3l
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: wb3l
framework:
version: dev
```
## Pinout
![Pinout](pinout_wb3l.svg)
@@ -73,8 +83,9 @@ 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
Calibration | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
TLV Store | 0x1E1000 | 4 KiB / 0x1000 | 0x1E2000
Network Data | 0x1E2000 | 4 KiB / 0x1000 | 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.

View File

@@ -39,3 +39,39 @@
#define PIN_SERIAL1_TX 11u // GPIO11
#define PIN_SERIAL2_RX 15u // GPIO1
#define PIN_SERIAL2_TX 6u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 0u // GPIO23
#define PIN_FUNCTION_MOSI 7u // GPIO16
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P1 15u // GPIO1
#define PIN_FUNCTION_P6 4u // GPIO6
#define PIN_FUNCTION_P7 9u // GPIO7
#define PIN_FUNCTION_P8 8u // GPIO8
#define PIN_FUNCTION_P9 5u // GPIO9
#define PIN_FUNCTION_P10 10u // GPIO10
#define PIN_FUNCTION_P11 11u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P16 7u // GPIO16
#define PIN_FUNCTION_P20 14u // GPIO20
#define PIN_FUNCTION_P21 13u // GPIO21
#define PIN_FUNCTION_P22 12u // GPIO22
#define PIN_FUNCTION_P23 0u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 2u // GPIO26
#define PIN_FUNCTION_PWM0 4u // GPIO6
#define PIN_FUNCTION_PWM1 9u // GPIO7
#define PIN_FUNCTION_PWM2 8u // GPIO8
#define PIN_FUNCTION_PWM3 5u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 2u // GPIO26
#define PIN_FUNCTION_RX1 10u // GPIO10
#define PIN_FUNCTION_RX2 15u // GPIO1
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL1 14u // GPIO20
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA1 13u // GPIO21
#define PIN_FUNCTION_SDA2 15u // GPIO1
#define PIN_FUNCTION_TX1 11u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

View File

@@ -13,6 +13,9 @@
"name": "WB3S Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/wb3s-module-datasheet?id=K9dx20n6hz5n4",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-WB3S"
},
"pcb": {
"symbol": "WB3S"
}

View File

@@ -9,7 +9,7 @@
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
-------------|------------------------------------------
Board code | `wb3s`
MCU | BK7231T
Manufacturer | Beken
@@ -21,6 +21,7 @@ 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
FCC ID | [2ANDL-WB3S](https://fccid.io/2ANDL-WB3S)
## Usage
@@ -35,6 +36,15 @@ board = wb3s
framework = arduino
```
In ESPHome YAML:
```yaml
libretuya:
board: wb3s
framework:
version: dev
```
## Pinout
![Pinout](pinout_wb3s.svg)
@@ -72,8 +82,9 @@ 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
Calibration | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
TLV Store | 0x1E1000 | 4 KiB / 0x1000 | 0x1E2000
Network Data | 0x1E2000 | 4 KiB / 0x1000 | 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.

View File

@@ -39,3 +39,37 @@
#define PIN_SERIAL1_TX 11u // GPIO11
#define PIN_SERIAL2_RX 7u // GPIO1
#define PIN_SERIAL2_TX 6u // GPIO0
// Pin function macros
// -------------------
#define PIN_FUNCTION_ADC3 0u // GPIO23
#define PIN_FUNCTION_P0 6u // GPIO0
#define PIN_FUNCTION_P1 7u // GPIO1
#define PIN_FUNCTION_P6 4u // GPIO6
#define PIN_FUNCTION_P7 5u // GPIO7
#define PIN_FUNCTION_P8 9u // GPIO8
#define PIN_FUNCTION_P9 8u // GPIO9
#define PIN_FUNCTION_P10 10u // GPIO10
#define PIN_FUNCTION_P11 11u // GPIO11
#define PIN_FUNCTION_P14 1u // GPIO14
#define PIN_FUNCTION_P20 14u // GPIO20
#define PIN_FUNCTION_P21 13u // GPIO21
#define PIN_FUNCTION_P22 12u // GPIO22
#define PIN_FUNCTION_P23 0u // GPIO23
#define PIN_FUNCTION_P24 3u // GPIO24
#define PIN_FUNCTION_P26 2u // GPIO26
#define PIN_FUNCTION_PWM0 4u // GPIO6
#define PIN_FUNCTION_PWM1 5u // GPIO7
#define PIN_FUNCTION_PWM2 9u // GPIO8
#define PIN_FUNCTION_PWM3 8u // GPIO9
#define PIN_FUNCTION_PWM4 3u // GPIO24
#define PIN_FUNCTION_PWM5 2u // GPIO26
#define PIN_FUNCTION_RX1 10u // GPIO10
#define PIN_FUNCTION_RX2 7u // GPIO1
#define PIN_FUNCTION_SCK 1u // GPIO14
#define PIN_FUNCTION_SCL1 14u // GPIO20
#define PIN_FUNCTION_SCL2 6u // GPIO0
#define PIN_FUNCTION_SDA1 13u // GPIO21
#define PIN_FUNCTION_SDA2 7u // GPIO1
#define PIN_FUNCTION_TX1 11u // GPIO11
#define PIN_FUNCTION_TX2 6u // GPIO0

View File

@@ -13,6 +13,9 @@
"name": "WR2 Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/wifiwr2module?id=K9605tko0juc3",
"vendor": "Tuya Inc.",
"doc": {
"fccid": "2ANDL-WR2"
},
"pcb": {
"symbol": "WR2"
}

Some files were not shown because too many files have changed in this diff Show More