44 Commits

Author SHA1 Message Date
Kuba Szczodrzyński
aae2f65b9e [release] v0.9.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-08-06 13:42:37 +02:00
Kuba Szczodrzyński
d02197474e [docs] Update ESPHome docs, add cloudcutter guide 2022-08-06 13:37:47 +02:00
Kuba Szczodrzyński
41b37e9c24 [core] Update ltchiptool to v1.4.0 2022-08-06 13:06:44 +02:00
Kuba Szczodrzyński
b03400fac2 [beken-72xx] Implement OTA API, add Update debugging 2022-08-06 11:36:53 +02:00
Kuba Szczodrzyński
3e808f7b6b [beken-72xx] Write OTA package to UF2 image 2022-08-05 20:29:48 +02:00
Kuba Szczodrzyński
1e3a8971fb [core] Migrate tools to ltchiptool 2022-08-05 20:29:45 +02:00
Kuba Szczodrzyński
d8c0105b97 [examples] Fix PinScan compilation on realtek-ambz 2022-08-03 12:48:50 +02:00
Kuba Szczodrzyński
b3689cbac8 [beken-72xx] Specify keys for OTA packaging 2022-08-01 19:56:34 +02:00
Kuba Szczodrzyński
1b5d6472f7 [examples] Fix PinScan telnet functionality 2022-08-01 11:28:56 +02:00
Kuba Szczodrzyński
e9511c507a [core] Allow disabling LT logger programmatically 2022-08-01 11:28:16 +02:00
Kuba Szczodrzyński
365f64ded5 [beken-72xx] Make Serial.end() disable hardware UART 2022-08-01 11:27:57 +02:00
Kuba Szczodrzyński
3601fa63d8 [examples] Add PinScan example 2022-08-01 10:52:58 +02:00
Kuba Szczodrzyński
5d00ddf516 [beken-72xx] Fix detaching interrupt handler 2022-07-31 23:25:12 +02:00
Kuba Szczodrzyński
0051453cad [beken-72xx] Implement interrupts 2022-07-31 21:35:02 +02:00
Kuba Szczodrzyński
7920ea2dda [beken-72xx] Fix SerialClass character reading 2022-07-31 14:52:09 +02:00
Kuba Szczodrzyński
9416e45a75 [docs] Restructure documentation, clarify some parts 2022-07-31 13:05:24 +02:00
Kuba Szczodrzyński
98a65c81af [boards] Add usage info to board README 2022-07-31 12:47:24 +02:00
Kuba Szczodrzyński
8e1f06e79b [boards] Add LSC LMA35 board, update boardgen 2022-07-30 19:48:58 +02:00
Kuba Szczodrzyński
58a09f453d [realtek-ambz] Fix errors related to lwIP 2022-07-30 17:18:46 +02:00
Kuba Szczodrzyński
7dc69982b6 [beken-72xx] Fix putchar_p UART index 2022-07-30 15:42:30 +02:00
Kuba Szczodrzyński
46e4041ed8 [beken-72xx] Mark mDNS as broken 2022-07-28 22:18:04 +02:00
Kuba Szczodrzyński
0e129130b1 [core] Print errors about starting main task 2022-07-28 20:29:53 +02:00
Kuba Szczodrzyński
33c9868f90 [core] Remove duplicated WMath functions 2022-07-28 13:46:42 +02:00
Kuba Szczodrzyński
fb04b1830e [release] v0.8.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-07-26 11:11:52 +02:00
Kuba Szczodrzyński
9509194bd0 [beken-72xx] Correct sys_config.h path 2022-07-26 11:11:14 +02:00
Kuba Szczodrzyński
60322a243a [boards] Fix missing vendor field in generic boards 2022-07-26 11:10:45 +02:00
Kuba Szczodrzyński
4ed7067537 [boards] Add generic definitions for each family 2022-07-25 19:59:53 +02:00
Kuba Szczodrzyński
69086e8fba [boards] Rename small/large base boards to show size 2022-07-25 19:58:16 +02:00
Kuba Szczodrzyński
a4b63bb037 [tools] Make util/markdown.py pre-Python 3.10 compatible 2022-07-21 23:08:53 +02:00
Kuba Szczodrzyński
5ffb2f6619 [boards] Add BW15 board definition, update boardgen 2022-07-21 23:08:49 +02:00
Kuba Szczodrzyński
41eaf9b9e4 [realtek-ambz2] Add initial AmebaZ2 support 2022-07-21 23:08:45 +02:00
Kuba Szczodrzyński
28bb777399 [core] Move family config to separate dir, define Realtek parent 2022-07-21 23:08:39 +02:00
Kuba Szczodrzyński
f375a35cc8 [core] Move library include wrappers to common 2022-07-21 23:08:39 +02:00
Kuba Szczodrzyński
1d41d84083 [boards] Move common partitions to base JSON 2022-07-21 23:08:28 +02:00
Kuba Szczodrzyński
357be177fc [core] Make WiFi sleep & TX power methods weak 2022-07-12 21:12:54 +02:00
Kuba Szczodrzyński
23c3335de8 [beken-72xx] Use Hostapd MD5 implementation 2022-07-12 13:05:02 +02:00
Kuba Szczodrzyński
963b164783 [beken-72xx] Define struct ip_addr as IPv4 2022-07-12 13:01:46 +02:00
Kuba Szczodrzyński
0c22a02641 [beken-72xx] Use mbedTLS MD5 implementation 2022-07-12 12:48:27 +02:00
Kuba Szczodrzyński
10cb5c2c76 [core] Add missing C++ stdlib includes 2022-07-12 12:48:02 +02:00
Kuba Szczodrzyński
6d36c9ef7b [boards] Add remaining WB2x and WB3x boards 2022-07-11 16:42:45 +02:00
Kuba Szczodrzyński
aed97a5e92 [boards] Add remaining WR2x and WR3x boards 2022-07-11 14:23:10 +02:00
Kuba Szczodrzyński
b6008fc9bb [docs] Add family flashing guides 2022-07-11 12:03:28 +02:00
Kuba Szczodrzyński
f9359679ad [docs] Add Getting started guide 2022-07-11 10:54:16 +02:00
Kuba Szczodrzyński
052d7be1a9 [beken-72xx] Move to GNU++11 2022-07-10 20:18:12 +02:00
272 changed files with 11806 additions and 4596 deletions

View File

@@ -35,7 +35,7 @@ LibreTuya also provides a common interface for all family implementations. The i
## Board List
See [Boards & CPU list](https://kuba2k2.github.io/libretuya/docs/supported/).
See [Boards & CPU list](https://kuba2k2.github.io/libretuya/docs/status/supported/).
## Arduino Core support status
@@ -44,7 +44,7 @@ Note: this list will probably change with each functionality update.
  | `realtek-ambz` | `beken-72xx`
--------------------|----------------|-------------
Core functions | ✔️ | ✔️
GPIO/PWM/IRQ | ✔️/✔️/✔️ | /✔️/
GPIO/PWM/IRQ | ✔️/✔️/✔️ | ✔️/✔️/✔️
Analog input (ADC) | ✔️ | ✔️
Serial | ✔️ | ✔️
Serial (extra) | 0, 1, 2 | 1, 2
@@ -65,8 +65,8 @@ NVS / Preferences | ❌ | ❌
SPIFFS | ❌ | ❌
BLE | - | ❌
NTP | ❌ | ❌
OTA | ✔️ |
MDNS | ✔️ | ✔️
OTA | ✔️ | ✔️
MDNS | ✔️ | BK7231T only
MQTT | ✅ | ❌
SD | ❌ | ❌

View File

@@ -1,9 +1,29 @@
* [Home](README.md)
* [💻 Boards & CPU list](docs/supported.md)
* [✔️ Implementation status](docs/implementation-status.md)
* [🔧 Configuration](docs/config.md)
* [📁 Project structure](docs/project-structure.md)
* 🔖 Code reference
* 😊 Getting started
* [Start here](docs/getting-started/README.md)
* [Uploading](docs/getting-started/uploading.md)
* [Options & config](docs/reference/config.md)
* Examples
* [PinScan](examples/PinScan/README.md)
* [ESPHome port](docs/projects/esphome.md)
* [Using tuya-cloudcutter](docs/cloudcutter.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)
* Realtek AmebaZ Series
* [General info](docs/platform/realtek/README.md)
* [Flashing (AmebaZ)](docs/platform/realtek-ambz/flashing.md)
* [Debugging](docs/platform/realtek/debugging.md)
* [Exception decoder](docs/platform/realtek/exception-decoder.md)
* C library
* [Built-in functions](docs/platform/realtek-ambz/stdlib.md)
* [Memory management](docs/platform/realtek-ambz/memory-management.md)
* [All supported boards](boards/)
* API & libraries
* [Options & config](docs/reference/config.md)
* [LibreTuya API](docs/reference/lt-api.md)
* [LT class reference](ltapi/class_libre_tuya.md)
* [Common methods](ltapi/_libre_tuya_a_p_i_8h.md)
@@ -37,19 +57,10 @@
* [Functions](ltapi/functions.md)
* [Macros](ltapi/macros.md)
* [File list](ltapi/files.md)
* [✈️ OTA format](docs/ota/README.md)
* [uf2ota.py tool](docs/ota/uf2ota.md)
* [uf2ota.h library](docs/ota/library.md)
* [uf2ota.h reference](ltapi/uf2ota_8h.md)
* Families
* [Realtek - notes](docs/platform/realtek/README.md)
* [Beken 72xx - notes](docs/platform/beken-72xx/README.md)
* Realtek AmebaZ Series
* C library
* [Built-in functions](docs/platform/realtek-ambz/stdlib.md)
* [Memory management](docs/platform/realtek-ambz/memory-management.md)
* [Debugging](docs/platform/realtek/debugging.md)
* [Exception decoder](docs/platform/realtek/exception-decoder.md)
* [All supported boards](boards/)
* [📁 Project structure](docs/reference/project-structure.md)
* [✈️ OTA format](docs/ota/README.md)
* [uf2ota.py tool](docs/ota/uf2ota.md)
* [uf2ota.h library](docs/ota/library.md)
* [uf2ota.h reference](ltapi/uf2ota_8h.md)
* [📓 TODO](TODO.md)
* [🔗 Resources](docs/resources.md)

View File

@@ -14,8 +14,7 @@
### Tools
- move all UF2 assembling/uploading/processing tools (as well as `uf2ota` C library) to a separate repository, possibly rewriting parts of it again. Make these tools CLI-usable
- write OpenOCD flashers, using uf2ota library + FAL for partitions (same repo as above)
- write OpenOCD flashers, using uf2ota library + FAL for partitions (in ltchiptool repository)
### Serial
@@ -31,10 +30,8 @@
## BK7231
- WiFi events
- implement OTA
- fix WiFi on BK7231N, test other functionality
- add generic board definition
- fix SSL (mbedTLS)
- I2C (Wire)
- SPI
@@ -42,5 +39,5 @@
## RTL8710B
- add generic board definition
- move to GNU++11 (and verify that it works) - take all stdio functions from stdio.h
- rewrite most of Wiring (it was copied from `ambd_arduino`, and is ugly)

View File

@@ -1,6 +1,7 @@
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
#include <LibreTuyaAPI.h>
#include <libraries/Flash/Flash.h>
// can't include <flash.h> as it collides with <Flash.h> on Windows -_-
#define REG_FLASH_BASE 0x00803000
@@ -109,12 +110,14 @@ uint32_t LibreTuya::getMaxAllocHeap() {
/* OTA-related */
static int8_t otaImage2Valid = -1;
uint8_t LibreTuya::otaGetStoredIndex() {
return 1;
return otaHasImage2() ? 2 : 1;
}
bool LibreTuya::otaSupportsDual() {
return false;
return true;
}
bool LibreTuya::otaHasImage1() {
@@ -122,11 +125,28 @@ bool LibreTuya::otaHasImage1() {
}
bool LibreTuya::otaHasImage2() {
return false;
if (otaImage2Valid != -1)
return otaImage2Valid;
// check download RBL
// TODO: maybe check header CRC or even binary hashes
uint32_t magic;
Flash.readBlock(FLASH_DOWNLOAD_OFFSET, (uint8_t *)&magic, 4);
otaImage2Valid = magic == 0x004C4252; // "RBL\0", little-endian
return otaImage2Valid;
}
bool LibreTuya::otaSwitch(bool force) {
return true;
// no need to check otaGetStoredIndex() as it does the same as otaHasImage2()
// force checking validity again
otaImage2Valid = -1;
if (otaHasImage2() && force) {
// "rollback" - abort bootloader upgrade operation by wiping first sector
return Flash.eraseSector(FLASH_DOWNLOAD_OFFSET);
}
return otaHasImage2(); // false if second image is not valid
}
/* Global instance */

View File

@@ -26,7 +26,10 @@ SerialClass::SerialClass(uint8_t port) {
static void callback(int port, void *param) {
RingBuffer *buf = (RingBuffer *)param;
buf->store_char(uart_read_byte(port));
int ch;
while ((ch = uart_read_byte(port)) != -1) {
buf->store_char(ch);
}
}
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
@@ -54,6 +57,14 @@ void SerialClass::begin(unsigned long baudrate, uint16_t config) {
void SerialClass::end() {
uart_rx_callback_set(port, NULL, NULL);
switch (port) {
case 1:
uart1_exit();
break;
case 2:
uart2_exit();
break;
}
delete this->buf;
}

View File

@@ -23,7 +23,7 @@ bool startMainTask() {
&mainThread,
THD_APPLICATION_PRIORITY,
"main",
(beken_thread_function_t)main_task,
(beken_thread_function_t)mainTask,
8192,
NULL
);

View File

@@ -0,0 +1,76 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-31. */
#include <Arduino.h>
static void *irqHandlerList[PINS_COUNT] = {NULL};
static void *irqHandlerArgs[PINS_COUNT] = {NULL};
static void irqHandler(unsigned char gpio) {
int pin = -1;
for (pin_size_t i = 0; i < PINS_COUNT; i++) {
if (pinTable[i].gpio == gpio) {
pin = i;
break;
}
}
if (pin == -1)
return;
if (!irqHandlerList[pin])
return;
if (irqHandlerArgs[pin] == NULL) {
((voidFuncPtr)irqHandlerList[pin])();
} else {
((voidFuncPtrParam)irqHandlerList[pin])(irqHandlerArgs[pin]);
}
}
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL);
}
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
PinInfo *pin = pinInfo(interruptNumber);
if (!pin)
return;
if (!pinSupported(pin, PIN_IRQ))
return;
uint32_t event = 0;
PinMode modeNew = 0;
switch (mode) {
case LOW:
event = GPIO_INT_LEVEL_LOW;
modeNew = INPUT_PULLUP;
break;
case HIGH:
event = GPIO_INT_LEVEL_HIGH;
modeNew = INPUT_PULLDOWN;
break;
case FALLING:
event = GPIO_INT_LEVEL_FALLING;
modeNew = INPUT_PULLUP;
break;
case RISING:
event = GPIO_INT_LEVEL_RISING;
modeNew = INPUT_PULLDOWN;
break;
default:
return;
}
irqHandlerList[interruptNumber] = callback;
irqHandlerArgs[interruptNumber] = param;
gpio_int_enable(pin->gpio, event, irqHandler);
pin->enabled |= PIN_IRQ | PIN_GPIO;
pin->mode = modeNew;
}
void detachInterrupt(pin_size_t interruptNumber) {
PinInfo *pin = pinInfo(interruptNumber);
if (!pin)
return;
if (!pinSupported(pin, PIN_IRQ))
return;
irqHandlerList[interruptNumber] = NULL;
irqHandlerArgs[interruptNumber] = NULL;
gpio_int_disable(pin->gpio);
pin->enabled &= ~PIN_IRQ;
}

View File

@@ -0,0 +1,5 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-11. */
#pragma once
#define LT_MD5_USE_HOSTAPD 1

View File

@@ -15,7 +15,7 @@ void putchar_(char c) {
}
void putchar_p(char c, unsigned long port) {
bk_send_byte(port & 0xFF, c);
bk_send_byte((port & 0xFF) - 1, c);
}
WRAP_PRINTF(bk_printf);

View File

@@ -38,6 +38,22 @@ bool WiFiClass::enableAP(bool enable) {
return true;
}
__attribute__((weak)) bool WiFiClass::setSleep(bool enable) {
return false;
}
__attribute__((weak)) bool WiFiClass::getSleep() {
return false;
}
__attribute__((weak)) bool WiFiClass::setTxPower(int power) {
return false;
}
__attribute__((weak)) int WiFiClass::getTxPower() {
return 0;
}
int WiFiClass::hostByName(const char *hostname, IPAddress &aResult) {
aResult = hostByName(hostname);
return true;

View File

@@ -41,15 +41,3 @@ long random(long howsmall, long howbig) {
return random(diff) + howsmall;
}
extern long map(long x, long in_min, long in_max, long out_min, long out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
extern uint16_t makeWord(uint16_t w) {
return w;
}
extern uint16_t makeWord(uint8_t h, uint8_t l) {
return (h << 8) | l;
}

View File

@@ -21,7 +21,7 @@ void initVariant() __attribute__((weak));
// Initialize C library
extern "C" void __libc_init_array(void);
void main_task(const void *arg) {
void mainTask(const void *arg) {
setup();
for (;;) {
@@ -46,7 +46,9 @@ int main(void) {
// provide root partition
fal_root_part = (fal_partition_t)fal_partition_find("root");
// start the main task and OS kernel
startMainTask();
if (!startMainTask()) {
LT_E("Couldn't start the main task");
}
while (1) {}
return 0;

View File

@@ -1,5 +1,7 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-28. */
#pragma once
#define CHIP_TYPE(family, chip_id) (((family >> 24) << 8) | chip_id)
#define CHIP_TYPE_ENUM(family, chip_id) (ChipType) CHIP_TYPE(family, chip_id)

View File

@@ -3,9 +3,26 @@
#pragma once
// C standard libraries
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// C++ standard libraries
#ifdef __cplusplus
#include <algorithm>
#include <cmath>
using ::round;
using std::abs;
using std::isinf;
using std::isnan;
using std::max;
using std::min;
#endif
// LibreTuya version macros
#ifndef LT_VERSION

View File

@@ -98,7 +98,8 @@ uint8_t LibreTuya::otaGetTarget() {
}
/**
* @brief Perform OTA rollback.
* @brief Perform OTA rollback: switch to the previous image, or abort current
* switched OTA update, if not rebooted yet.
*
* @return false if no second image to run, writing failed or dual-OTA not supported
*/

View File

@@ -114,7 +114,9 @@ class LibreTuya {
*/
uint8_t otaGetStoredIndex();
/**
* @brief Check if the chip supports dual-OTA.
* @brief Check if the chip supports dual-OTA (i.e. OTA is flashed to a different partition).
*
* TODO: make this work for actual dual-OTA chips; remove checking this in otaGetTarget() etc.
*/
bool otaSupportsDual();
/**

View File

@@ -95,3 +95,7 @@
#ifndef LT_DEBUG_SSL
#define LT_DEBUG_SSL 0
#endif
#ifndef LT_DEBUG_OTA
#define LT_DEBUG_OTA 0
#endif

View File

@@ -9,7 +9,9 @@ extern "C" {
#endif
/**
* @brief Run main_task & start OS kernel (family-defined)
* @brief Run mainTask & start OS kernel (family-defined).
* Return false if an error occured; else do not return and
* and keep the OS kernel running.
*/
extern bool startMainTask();
@@ -17,7 +19,7 @@ extern bool startMainTask();
* @brief Main setup() and loop() task.
* Not to be called directly.
*/
extern void main_task(const void *arg);
extern void mainTask(const void *arg);
#define PIN_NONE (1 << 0)
#define PIN_GPIO (1 << 1)

View File

@@ -50,6 +50,9 @@ void lt_log(const uint8_t level, const char *caller, const unsigned short line,
void lt_log(const uint8_t level, const char *format, ...) {
#endif
if (uart_port == 0xFF)
return;
#if LT_LOGGER_TIMESTAMP
float seconds = millis() / 1000.0f;
#if LT_PRINTF_BROKEN
@@ -136,3 +139,7 @@ void lt_log(const uint8_t level, const char *format, ...) {
void lt_log_set_port(uint8_t port) {
uart_port = port;
}
void lt_log_disable() {
uart_port = 0xFF;
}

View File

@@ -20,6 +20,11 @@ void lt_log(const uint8_t level, const char *format, ...);
*/
void lt_log_set_port(uint8_t port);
/**
* @brief Disable LT logger. Enable it back using lt_log_set_port(LT_UART_DEFAULT_LOGGER).
*/
void lt_log_disable();
#if LT_LEVEL_TRACE >= LT_LOGLEVEL
#define LT_T(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LT_V(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)
@@ -180,3 +185,8 @@ void lt_log_set_port(uint8_t port);
#define LT_T_SSL(...) LT_T_MOD(LT_DEBUG_SSL, __VA_ARGS__)
#define LT_V_SSL(...) LT_T_MOD(LT_DEBUG_SSL, __VA_ARGS__)
#define LT_D_SSL(...) LT_D_MOD(LT_DEBUG_SSL, __VA_ARGS__)
// Update.cpp
#define LT_T_OTA(...) LT_T_MOD(LT_DEBUG_OTA, __VA_ARGS__)
#define LT_V_OTA(...) LT_T_MOD(LT_DEBUG_OTA, __VA_ARGS__)
#define LT_D_OTA(...) LT_D_MOD(LT_DEBUG_OTA, __VA_ARGS__)

View File

@@ -9,6 +9,12 @@
#if LT_MD5_USE_POLARSSL
#include "MD5PolarSSLImpl.h"
#endif
#if LT_MD5_USE_MBEDTLS
#include "MD5MbedTLSImpl.h"
#endif
#if LT_MD5_USE_HOSTAPD
#include "MD5HostapdImpl.h"
#endif
// common API
#ifdef __cplusplus

View File

@@ -0,0 +1,14 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-12. */
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <crypto/md5_i.h>
#define LT_MD5_CTX_T struct MD5Context
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,28 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-11. */
#if LT_ARD_HAS_MD5
#include "MD5.h"
#if LT_MD5_USE_MBEDTLS
extern "C" {
void MD5Init(LT_MD5_CTX_T *context) {
mbedtls_md5_init(context);
mbedtls_md5_starts(context);
}
void MD5Update(LT_MD5_CTX_T *context, const unsigned char *buf, unsigned len) {
mbedtls_md5_update(context, buf, len);
}
void MD5Final(unsigned char digest[16], LT_MD5_CTX_T *context) {
mbedtls_md5_finish(context, digest);
}
} // extern "C"
#endif // LT_MD5_USE_MBEDTLS
#endif // LT_ARD_HAS_MD5

View File

@@ -0,0 +1,14 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-11. */
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <mbedtls/md5.h>
#define LT_MD5_CTX_T mbedtls_md5_context
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -18,6 +18,8 @@ bool UpdateClass::begin(size_t size, int command, int unused2, uint8_t unused3,
return false;
cleanup();
LT_D_OTA("begin(%u, ...) / OTA curr: %u, trgt: %u", size, LT.otaGetRunning(), LT.otaGetTarget());
ctx = uf2_ctx_init(LT.otaGetTarget(), FAMILY);
info = uf2_info_init();
@@ -70,6 +72,8 @@ size_t UpdateClass::write(uint8_t *data, size_t len) {
// 0 if not running
return 0;
LT_D_OTA("write(%u) / buf %u/512", len, bufSize());
/* while (buf == bufPos && len >= UF2_BLOCK_SIZE) {
// buffer empty and entire block is in data
if (!tryWriteData(data, UF2_BLOCK_SIZE)) {
@@ -82,7 +86,7 @@ size_t UpdateClass::write(uint8_t *data, size_t len) {
} */
// write until buffer space is available
uint16_t toWrite;
uint16_t toWrite; // 1..512
while (len && (toWrite = min(len, bufLeft()))) {
tryWriteData(data, toWrite);
if (hasError())
@@ -141,6 +145,8 @@ size_t UpdateClass::writeStream(Stream &data) {
size_t UpdateClass::tryWriteData(uint8_t *data, size_t len) {
uf2_block_t *block = NULL;
LT_V_OTA("Writing %u to buffer (%u/512)", len, bufSize());
if (len == UF2_BLOCK_SIZE) {
// data has a complete block
block = (uf2_block_t *)data;
@@ -172,11 +178,14 @@ size_t UpdateClass::tryWriteData(uint8_t *data, size_t len) {
// header is invalid
return 0;
LT_I("OTA: %s v%s - LT v%s @ %s", info->fw_name, info->fw_version, info->lt_version, info->board);
if (bytesTotal == UPDATE_SIZE_UNKNOWN) {
// set total update size from block count info
bytesTotal = block->block_count * UF2_BLOCK_SIZE;
} else if (bytesTotal != block->block_count * UF2_BLOCK_SIZE) {
// given update size does not match the block count
LT_D_OTA("Image size wrong; got %u, calculated %u", bytesTotal, block->block_count * UF2_BLOCK_SIZE);
return errorArd(UPDATE_ERROR_SIZE);
}
} else {

View File

@@ -2,8 +2,7 @@
#include <Arduino.h>
#include <functional>
#include "uf2ota/uf2ota.h"
#include <uf2ota/uf2ota.h>
// No Error
#define UPDATE_ERROR_OK (0)
@@ -119,7 +118,7 @@ class UpdateClass {
}
void clearError() {
errorUf2(UF2_ERR_OK);
errorArd(UPDATE_ERROR_OK);
}
bool hasError() {

View File

@@ -52,6 +52,8 @@ void UpdateClass::cleanup() {
* @return true if err is not OK, false otherwise
*/
bool UpdateClass::errorUf2(uf2_err_t err) {
if (err)
LT_D_OTA("[%4d] errorUf2(%d)", ctx ? ctx->seq : 0, err);
if (err <= UF2_ERR_IGNORE)
return false;
cleanup();
@@ -67,6 +69,8 @@ bool UpdateClass::errorUf2(uf2_err_t err) {
* @return false - always
*/
bool UpdateClass::errorArd(uint8_t err) {
if (err)
LT_D_OTA("[%4d] errorArd(%d)", ctx ? ctx->seq : 0, err);
cleanup();
errUf2 = UF2_ERR_OK;
errArd = err;
@@ -77,6 +81,7 @@ bool UpdateClass::errorArd(uint8_t err) {
* @brief Abort the update with UPDATE_ERROR_ABORT reason.
*/
void UpdateClass::abort() {
LT_D_OTA("Aborting update");
errorArd(UPDATE_ERROR_ABORT);
}
@@ -105,7 +110,7 @@ void UpdateClass::printError(Print &out) {
* "ard=..,uf2=..". Returns "" if no error.
*/
const char *UpdateClass::errorString() {
if (!errArd)
if (!errArd && !errUf2)
return "";
sprintf(errorStr, "ard=%u,uf2=%u", errArd, errUf2);
return errorStr;

View File

@@ -1,32 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-29. */
#include "uf2priv.h"
uf2_err_t uf2_binpatch(uint8_t *data, const uint8_t *binpatch, uint8_t binpatch_len) {
const uint8_t *binpatch_end = binpatch + binpatch_len;
// +2 to make sure opcode and length is present
while ((binpatch + 2) < binpatch_end) {
uf2_opcode_t opcode = binpatch[0];
uint8_t len = binpatch[1];
switch (opcode) {
case UF2_OPC_DIFF32:
uf2_binpatch_diff32(data, binpatch + 1);
break;
}
// advance by opcode + length + data
binpatch += len + 2;
}
return UF2_ERR_OK;
}
void uf2_binpatch_diff32(uint8_t *data, const uint8_t *patch) {
uint8_t num_offs = patch[0] - 4; // read offset count
uint32_t diff = *((uint32_t *)(patch + 1)); // read diff value
patch += 5; // skip num_offs and diff value
for (uint8_t i = 0; i < num_offs; i++) {
// patch the data
uint8_t offs = patch[i];
uint32_t *value = (uint32_t *)(data + offs);
*(value) += diff;
}
}

View File

@@ -1,26 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-29. */
#pragma once
#include "uf2types.h"
/**
* @brief Apply binary patch to data.
*
* @param data input data
* @param data_len input data length
* @param binpatch binary patch data
* @param binpatch_len binary patch data length
* @return uf2_err_t error code
*/
uf2_err_t uf2_binpatch(uint8_t *data, const uint8_t *binpatch, uint8_t binpatch_len);
/**
* Apply DIFF32 binary patch.
*
* @param data input data
* @param len input data length
* @param patch patch data, incl. length byte
* @return uf2_err_t error code
*/
void uf2_binpatch_diff32(uint8_t *data, const uint8_t *patch);

View File

@@ -1,100 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-29. */
#include "uf2priv.h"
uf2_ota_t *uf2_ctx_init(uint8_t ota_idx, uint32_t family_id) {
uf2_ota_t *ctx = (uf2_ota_t *)zalloc(sizeof(uf2_ota_t));
ctx->ota_idx = ota_idx;
ctx->family_id = family_id;
return ctx;
}
uf2_info_t *uf2_info_init() {
uf2_info_t *info = (uf2_info_t *)zalloc(sizeof(uf2_info_t));
return info;
}
void uf2_info_free(uf2_info_t *info) {
if (!info)
return;
free(info->fw_name);
free(info->fw_version);
free(info->lt_version);
free(info->board);
free(info);
}
uf2_err_t uf2_check_block(uf2_ota_t *ctx, uf2_block_t *block) {
if (block->magic1 != UF2_MAGIC_1)
return UF2_ERR_MAGIC;
if (block->magic2 != UF2_MAGIC_2)
return UF2_ERR_MAGIC;
if (block->magic3 != UF2_MAGIC_3)
return UF2_ERR_MAGIC;
if (block->file_container)
// ignore file containers, for now
return UF2_ERR_IGNORE;
if (!block->has_family_id || block->file_size != ctx->family_id)
// require family_id
return UF2_ERR_FAMILY;
return UF2_ERR_OK;
}
uf2_err_t uf2_parse_header(uf2_ota_t *ctx, uf2_block_t *block, uf2_info_t *info) {
if (!block->has_tags || block->file_container || block->len)
// header must have tags and no data
return UF2_ERR_NOT_HEADER;
uf2_err_t err = uf2_parse_block(ctx, block, info);
if (err)
return err;
if ((ctx->ota_idx == 1 && !ctx->has_ota1) || !ctx->has_ota2)
return UF2_ERR_OTA_WRONG;
return UF2_ERR_OK;
}
uf2_err_t uf2_write(uf2_ota_t *ctx, uf2_block_t *block) {
if (ctx->seq == 0)
return uf2_parse_header(ctx, block, NULL);
if (block->not_main_flash || !block->len)
// ignore blocks not meant for flashing
return UF2_ERR_IGNORE;
uf2_err_t err = uf2_parse_block(ctx, block, NULL);
if (err)
return err;
if (!ctx->part1 && !ctx->part2)
// no partitions set at all
return UF2_ERR_PART_UNSET;
fal_partition_t part = uf2_get_target_part(ctx);
if (!part)
// image is not for current OTA scheme
return UF2_ERR_IGNORE;
if (ctx->ota_idx == 2 && ctx->binpatch_len) {
// apply binpatch
err = uf2_binpatch(block->data, ctx->binpatch, ctx->binpatch_len);
if (err)
return err;
}
int ret;
// erase sectors if needed
if (!uf2_is_erased(ctx, block->addr, block->len)) {
ret = fal_partition_erase(part, block->addr, block->len);
if (ret < 0)
return UF2_ERR_ERASE_FAILED;
ctx->erased_offset = block->addr;
ctx->erased_length = ret;
}
// write data to flash
ret = fal_partition_write(part, block->addr, block->data, block->len);
if (ret < 0)
return UF2_ERR_WRITE_FAILED;
if (ret != block->len)
return UF2_ERR_WRITE_LENGTH;
return UF2_ERR_OK;
}

View File

@@ -1,68 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-28. */
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "uf2types.h"
/**
* @brief Create an UF2 OTA context.
*
* @param ota_idx target OTA index
* @param family_id expected family ID
* @return uf2_ota_t* heap-allocated structure
*/
uf2_ota_t *uf2_ctx_init(uint8_t ota_idx, uint32_t family_id);
/**
* @brief Create an UF2 Info structure.
*
* @return uf2_info_t* heap-allocated structure
*/
uf2_info_t *uf2_info_init();
/**
* @brief Free values in the info structure AND the structure itself.
*
* @param info structure to free; may be NULL
*/
void uf2_info_free(uf2_info_t *info);
/**
* @brief Check if block is valid.
*
* @param ctx context
* @param block block to check
* @return uf2_err_t error code; UF2_ERR_OK and UF2_ERR_IGNORE denote valid blocks
*/
uf2_err_t uf2_check_block(uf2_ota_t *ctx, uf2_block_t *block);
/**
* @brief Parse header block (LibreTuya UF2 first block).
*
* Note: caller should call uf2_check_block() first.
*
* @param ctx context
* @param block block to parse
* @param info structure to write firmware info, NULL if not used
* @return uf2_err_t error code
*/
uf2_err_t uf2_parse_header(uf2_ota_t *ctx, uf2_block_t *block, uf2_info_t *info);
/**
* @brief Write the block to flash memory.
*
* Note: caller should call uf2_check_block() first.
*
* @param ctx context
* @param block block to write
* @return uf2_err_t error code
*/
uf2_err_t uf2_write(uf2_ota_t *ctx, uf2_block_t *block);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -1,146 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-29. */
#include "uf2priv.h"
uf2_err_t uf2_parse_block(uf2_ota_t *ctx, uf2_block_t *block, uf2_info_t *info) {
if (block->block_seq != ctx->seq)
// sequence number must match
return UF2_ERR_SEQ_MISMATCH;
ctx->seq++; // increment sequence number after checking it
if (!block->has_tags)
// no tags in this block, no further processing needed
return UF2_ERR_OK;
if (block->len > (476 - 4 - 4))
// at least one tag + last tag must fit
return UF2_ERR_DATA_TOO_LONG;
uint8_t *tags_start = block->data + block->len;
uint8_t tags_len = 476 - block->len;
uint8_t tags_pos = 0;
if (block->has_md5)
tags_len -= 24;
ctx->binpatch_len = 0; // binpatch applies to one block only
char *part1 = NULL;
char *part2 = NULL;
uf2_tag_type_t type;
while (tags_pos < tags_len) {
uint8_t len = uf2_read_tag(tags_start + tags_pos, &type);
if (!len)
break;
tags_pos += 4; // skip tag header
uint8_t *tag = tags_start + tags_pos;
char **str_dest = NULL; // char* to copy the tag into
switch (type) {
case UF2_TAG_OTA_VERSION:
if (tag[0] != 1)
return UF2_ERR_OTA_VER;
break;
case UF2_TAG_FIRMWARE:
if (info)
str_dest = &(info->fw_name);
break;
case UF2_TAG_VERSION:
if (info)
str_dest = &(info->fw_version);
break;
case UF2_TAG_LT_VERSION:
if (info)
str_dest = &(info->lt_version);
break;
case UF2_TAG_BOARD:
if (info)
str_dest = &(info->board);
break;
case UF2_TAG_HAS_OTA1:
ctx->has_ota1 = tag[0];
break;
case UF2_TAG_HAS_OTA2:
ctx->has_ota2 = tag[0];
break;
case UF2_TAG_PART_1:
str_dest = &(part1);
break;
case UF2_TAG_PART_2:
str_dest = &(part2);
break;
case UF2_TAG_BINPATCH:
ctx->binpatch = tag;
ctx->binpatch_len = len;
break;
default:
break;
}
if (str_dest) {
*str_dest = (char *)zalloc(len + 1);
memcpy(*str_dest, tag, len);
}
// align position to 4 bytes
tags_pos += (((len - 1) / 4) + 1) * 4;
}
if (part1 && part2) {
// update current target partition
uf2_err_t err = uf2_update_parts(ctx, part1, part2);
if (err)
return err;
} else if (part1 || part2) {
// only none or both partitions can be specified
return UF2_ERR_PART_ONE;
}
return UF2_ERR_OK;
}
uint8_t uf2_read_tag(const uint8_t *data, uf2_tag_type_t *type) {
uint8_t len = data[0];
if (!len)
return 0;
uint32_t tag_type = *((uint32_t *)data);
if (!tag_type)
return 0;
*type = tag_type >> 8; // remove tag length byte
return len - 4;
}
uf2_err_t uf2_update_parts(uf2_ota_t *ctx, char *part1, char *part2) {
// reset both target partitions
ctx->part1 = NULL;
ctx->part2 = NULL;
// reset offsets as they probably don't apply to this partition
ctx->erased_offset = 0;
ctx->erased_length = 0;
if (part1[0]) {
ctx->part1 = (fal_partition_t)fal_partition_find(part1);
if (!ctx->part1)
return UF2_ERR_PART_404;
}
if (part2[0]) {
ctx->part2 = (fal_partition_t)fal_partition_find(part2);
if (!ctx->part2)
return UF2_ERR_PART_404;
}
return UF2_ERR_OK;
}
fal_partition_t uf2_get_target_part(uf2_ota_t *ctx) {
if (ctx->ota_idx == 1)
return ctx->part1;
if (ctx->ota_idx == 2)
return ctx->part2;
return NULL;
}
bool uf2_is_erased(uf2_ota_t *ctx, uint32_t offset, uint32_t length) {
uint32_t erased_end = ctx->erased_offset + ctx->erased_length;
uint32_t end = offset + length;
return (offset >= ctx->erased_offset) && (end <= erased_end);
}

View File

@@ -1,61 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-28. */
#pragma once
// include family stdlib APIs
#include <WVariant.h>
#include "uf2binpatch.h"
#include "uf2types.h"
/**
* @brief Parse a block and extract information from tags.
*
* @param ctx context
* @param block block to parse
* @param info structure to write firmware info, NULL if not used
* @return uf2_err_t error code
*/
uf2_err_t uf2_parse_block(uf2_ota_t *ctx, uf2_block_t *block, uf2_info_t *info);
/**
* @brief Parse a tag.
*
* @param data pointer to tag header beginning
* @param type [out] parsed tag type
* @return uint8_t parsed tag data length (excl. header); 0 if invalid/last tag
*/
uint8_t uf2_read_tag(const uint8_t *data, uf2_tag_type_t *type);
/**
* @brief Update destination partitions in context.
*
* Partition names cannot be NULL.
*
* Returns UF2_ERR_IGNORE if specified partitions don't match the
* current OTA index.
*
* @param ctx context
* @param part1 partition 1 name or empty string
* @param part2 partition 2 name or empty string
* @return uf2_err_t error code
*/
uf2_err_t uf2_update_parts(uf2_ota_t *ctx, char *part1, char *part2);
/**
* @brief Get target flashing partition, depending on OTA index.
*
* @param ctx context
* @return fal_partition_t target partition or NULL if not set
*/
fal_partition_t uf2_get_target_part(uf2_ota_t *ctx);
/**
* Check if specified flash memory region was already erased during update.
*
* @param ctx context
* @param offset offset to check
* @param length length to check
* @return bool true/false
*/
bool uf2_is_erased(uf2_ota_t *ctx, uint32_t offset, uint32_t length);

View File

@@ -1,104 +0,0 @@
/* Copyright (c) Kuba Szczodrzyński 2022-05-28. */
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <fal.h>
#define UF2_MAGIC_1 0x0A324655
#define UF2_MAGIC_2 0x9E5D5157
#define UF2_MAGIC_3 0x0AB16F30
#define UF2_BLOCK_SIZE sizeof(uf2_block_t)
typedef struct __attribute__((packed)) {
// 32 byte header
uint32_t magic1;
uint32_t magic2;
// flags split as bitfields
bool not_main_flash : 1;
uint16_t dummy1 : 11;
bool file_container : 1;
bool has_family_id : 1;
bool has_md5 : 1;
bool has_tags : 1;
uint16_t dummy2 : 16;
uint32_t addr;
uint32_t len;
uint32_t block_seq;
uint32_t block_count;
uint32_t file_size; // or familyID;
uint8_t data[476];
uint32_t magic3;
} uf2_block_t;
typedef struct {
uint32_t seq; // current block sequence number
uint8_t *binpatch; // current block's binpatch (if any) -> pointer inside block->data
uint8_t binpatch_len; // binpatch length
bool has_ota1; // image has any data for OTA1
bool has_ota2; // image has any data for OTA2
uint8_t ota_idx; // target OTA index
uint32_t family_id; // expected family ID
uint32_t erased_offset; // offset of region erased during update
uint32_t erased_length; // length of erased region
fal_partition_t part1; // OTA1 target partition
fal_partition_t part2; // OTA2 target partition
} uf2_ota_t;
typedef struct {
char *fw_name;
char *fw_version;
char *lt_version;
char *board;
} uf2_info_t;
typedef enum {
UF2_TAG_VERSION = 0x9FC7BC, // version of firmware file - UTF8 semver string
UF2_TAG_PAGE_SIZE = 0x0BE9F7, // page size of target device (32 bit unsigned number)
UF2_TAG_SHA2 = 0xB46DB0, // SHA-2 checksum of firmware (can be of various size)
UF2_TAG_DEVICE = 0x650D9D, // description of device (UTF8)
UF2_TAG_DEVICE_ID = 0xC8A729, // device type identifier
// LibreTuya custom, tags
UF2_TAG_OTA_VERSION = 0x5D57D0, // format version
UF2_TAG_BOARD = 0xCA25C8, // board name (lowercase code)
UF2_TAG_FIRMWARE = 0x00DE43, // firmware description / name
UF2_TAG_BUILD_DATE = 0x822F30, // build date/time as Unix timestamp
UF2_TAG_LT_VERSION = 0x59563D, // LT version (semver)
UF2_TAG_PART_1 = 0x805946, // OTA1 partition name
UF2_TAG_PART_2 = 0xA1E4D7, // OTA2 partition name
UF2_TAG_HAS_OTA1 = 0xBBD965, // image has any data for OTA1
UF2_TAG_HAS_OTA2 = 0x92280E, // image has any data for OTA2
UF2_TAG_BINPATCH = 0xB948DE, // binary patch to convert OTA1->OTA2
} uf2_tag_type_t;
typedef enum {
UF2_OPC_DIFF32 = 0xFE,
} uf2_opcode_t;
typedef enum {
UF2_ERR_OK = 0,
UF2_ERR_IGNORE, // block should be ignored
UF2_ERR_MAGIC, // wrong magic numbers
UF2_ERR_FAMILY, // family ID mismatched
UF2_ERR_NOT_HEADER, // block is not a header
UF2_ERR_OTA_VER, // unknown/invalid OTA format version
UF2_ERR_OTA_WRONG, // no data for current OTA index
UF2_ERR_PART_404, // no partition with that name
UF2_ERR_PART_ONE, // only one partition tag in a block
UF2_ERR_PART_UNSET, // image broken - attempted to write without target partition
UF2_ERR_DATA_TOO_LONG, // data too long - tags won't fit
UF2_ERR_SEQ_MISMATCH, // sequence number mismatched
UF2_ERR_ERASE_FAILED, // erasing flash failed
UF2_ERR_WRITE_FAILED, // writing to flash failed
UF2_ERR_WRITE_LENGTH, // wrote fewer data than requested
} uf2_err_t;

View File

@@ -61,6 +61,7 @@ bool mDNS::begin(const char *hostname) {
struct netif *netif = netif_list;
uint8_t enabled = 0;
while (netif != NULL) {
netif->flags |= NETIF_FLAG_IGMP;
// TODO: detect mdns_netif_client_id by checking netif_get_client_data()
// and finding the requested hostname in struct mdns_host
if (netif_is_up(netif) && mdns_resp_add_netif(netif, hostname, 255) == ERR_OK) {
@@ -100,7 +101,7 @@ bool mDNS::addService(char *service, char *proto, uint16_t port) {
struct netif *netif = netif_list;
while (netif != NULL) {
if (netif_is_up(netif)) {
mdns_resp_add_service(netif, mdnsInstanceName.c_str(), service, protocol, port, 255, NULL, NULL);
mdns_resp_add_service(netif, mdnsInstanceName.c_str(), _service, protocol, port, 255, NULL, NULL);
}
netif = netif->next;
}

View File

@@ -10,9 +10,9 @@ static void *gpio_irq_handler_args[PINS_COUNT] = {NULL};
extern bool pinInvalid(pin_size_t pinNumber);
extern void pinRemoveMode(pin_size_t pinNumber);
void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
static void gpioIrqHandler(uint32_t id, gpio_irq_event event) {
if (gpio_irq_handler_list[id] != NULL) {
if (gpio_irq_handler_args[id] != NULL)
if (gpio_irq_handler_args[id] == NULL)
((voidFuncPtr)gpio_irq_handler_list[id])();
else
((voidFuncPtrParam)gpio_irq_handler_list[id])(gpio_irq_handler_args[id]);

View File

@@ -23,8 +23,8 @@ void initArduino() {
}
bool startMainTask() {
osThreadDef(main_task, osPriorityRealtime, 1, 4096 * 4);
main_tid = osThreadCreate(osThread(main_task), NULL);
osThreadDef(mainTask, osPriorityRealtime, 1, 4096 * 4);
main_tid = osThreadCreate(osThread(mainTask), NULL);
osKernelStart();
return true;
}

View File

@@ -1,7 +1,25 @@
<!-- This file is auto-generated -->
- [Generic - BK7231N (Tuya QFN32)](../boards/generic-bk7231n-qfn32-tuya/README.md)
- [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 - RTL8720CF (2M/992k)](../boards/generic-rtl8720cf-2mb-992k/README.md)
- [BW12](../boards/bw12/README.md)
- [CB2S Wi-Fi Module](../boards/cb2s/README.md)
- [WB2L Wi-Fi Module](../boards/wb2l/README.md)
- [WR3 Wi-Fi Module](../boards/wr3/README.md)
- [BW15](../boards/bw15/README.md)
- [CB2S](../boards/cb2s/README.md)
- [WB2L](../boards/wb2l/README.md)
- [WB2S](../boards/wb2s/README.md)
- [WB3L](../boards/wb3l/README.md)
- [WB3S](../boards/wb3s/README.md)
- [WR2](../boards/wr2/README.md)
- [WR2E](../boards/wr2e/README.md)
- [WR3](../boards/wr3/README.md)
- [WR3E](../boards/wr3e/README.md)
- [WR3N](../boards/wr3n/README.md)
- [WR2L](../boards/wr2l/README.md)
- [WR2LE](../boards/wr2le/README.md)
- [WR3L](../boards/wr3l/README.md)
- [WR3LE](../boards/wr3le/README.md)
- [LSC LMA35](../boards/lsc-lma35/README.md)
- [Generic - Host-native](../boards/generic-native/README.md)

View File

@@ -1,7 +1,13 @@
{
"build": {
"f_cpu": "120000000L",
"prefix": "arm-none-eabi-"
"prefix": "arm-none-eabi-",
"bkota": {
"encryption": "aes256",
"compression": "gzip",
"key": "0123456789ABCDEF0123456789ABCDEF",
"iv": "0123456789ABCDEF"
}
},
"connectivity": [
"wifi",
@@ -41,7 +47,7 @@
},
"links": {
"General info": "../../docs/platform/beken-72xx/README.md",
"Flashing (Tuya manual)": "https://developer.tuya.com/en/docs/iot/burn-and-authorize-wb-series-modules?id=Ka78f4pttsytd",
"Flashing guide": "../../docs/platform/beken-72xx/flashing.md",
"BkWriter v1.6.0": "https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe"
}
}

View File

@@ -0,0 +1,7 @@
{
"pcb": {
"symbol": "GENERIC",
"templates": [],
"vars": {}
}
}

View File

@@ -0,0 +1,79 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12s-shield",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_black",
"TRACE_COLOR": "#FAFD9D",
"SILK_COLOR": "white",
"PINTYPE_VERT": "pin_vert_2mm_cast_nohole"
},
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD",
"pinout": {
"1": {
"IC": 38,
"ARD": "D0"
},
"2": {
"IC": 39,
"ARD": "D1"
},
"3": {
"IC": 14
},
"4": {
"IC": 18,
"ARD": "D2"
},
"5": {
"IC": 36,
"ARD": "D3"
},
"6": {
"IC": 20,
"ARD": "D4"
},
"7": {
"IC": 40,
"ARD": "D5"
},
"8": {
"PWR": 3.3
},
"9": {
"GND": null
},
"10": {
"IC": 1,
"ARD": "D6"
},
"11": {
"IC": 37,
"ARD": "D7"
},
"12": {
"IC": 15,
"ARD": "D8"
},
"13": {
"IC": 19,
"ARD": "D9"
},
"14": {
"IC": 16,
"ARD": "D10"
},
"15": {
"IC": 33,
"ARD": "D11"
},
"16": {
"IC": 34,
"ARD": "D12"
}
}
}
}

View File

@@ -8,8 +8,7 @@
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white",
"PINTYPE_HORZ": "pin_horz_2mm_cast_hole"
"SILK_COLOR": "white"
},
"pinout_hidden": "I2S,JTAG,FLASH",
"pinout": {

View File

@@ -0,0 +1,186 @@
{
"pcb": {
"ic": {
"1": {
"C_NAME": "PIN_A20",
"GPIO": "PA20",
"IRQ": null,
"SD": "D1",
"SPI":
"0_MISO"
,
"UART": "2_RTS",
"I2C": "0_SDA",
"PWM": 0
},
"3": {
"C_NAME": "PIN_A23",
"GPIO": "PA23",
"IRQ": null,
"PWM": 7
},
"14": {
"IO": "I",
"CTRL": "CEN"
},
"15": {
"C_NAME": "PIN_A0",
"GPIO": "PA00",
"IRQ": null,
"JTAG": "TCK",
"UART": "1_RX",
"PWM": 0,
"SWD": "CLK"
},
"16": {
"C_NAME": "PIN_A1",
"GPIO": "PA01",
"IRQ": null,
"JTAG": "TMS",
"UART": "1_TX",
"PWM": 1,
"SWD": "DIO"
},
"18": {
"C_NAME": "PIN_A2",
"GPIO": "PA02",
"IRQ": null,
"JTAG": "TDO",
"UART": "1_RX",
"SPI": "0_CS",
"I2C": "0_SCL",
"PWM": 2
},
"19": {
"C_NAME": "PIN_A3",
"GPIO": "PA03",
"IRQ": null,
"JTAG": "TDI",
"UART": "1_TX",
"SPI": "0_SCK",
"I2C": "0_SDA",
"PWM": 3
},
"20": {
"C_NAME": "PIN_A4",
"GPIO": "PA04",
"IRQ": null,
"JTAG": "tRST",
"UART": "1_CTS",
"SPI": "0_MOSI",
"PWM": 4
},
"21": {
"C_NAME": "PIN_A7",
"GPIO": "PA07",
"IRQ": null,
"FLASH": "^FCS",
"SPI": "0_CS"
},
"22": {
"C_NAME": "PIN_A8",
"GPIO": "PA08",
"IRQ": null,
"FLASH": "FSCK",
"SPI": "0_SCK"
},
"23": {
"C_NAME": "PIN_A9",
"GPIO": "PA09",
"IRQ": null,
"FLASH": "FD2",
"SPI": "0_MOSI",
"UART": "0_RTS"
},
"24": {
"C_NAME": "PIN_A10",
"GPIO": "PA10",
"IRQ": null,
"FLASH": "FD1",
"SPI": "0_MISO",
"UART": "0_CTS"
},
"25": {
"C_NAME": "PIN_A11",
"GPIO": "PA11",
"IRQ": null,
"FLASH": "FD0",
"UART": "0_TX",
"I2C": "0_SCL",
"PWM": 0
},
"26": {
"C_NAME": "PIN_A12",
"GPIO": "PA12",
"IRQ": null,
"FLASH": "FD3",
"UART": "0_RX",
"I2C": "0_SDA",
"PWM": 1
},
"30": {
"IO": "I",
"C_NAME": "VBAT_IN"
},
"33": {
"C_NAME": "PIN_A13",
"GPIO": "PA13",
"IRQ": null,
"UART": "0_RX",
"PWM": 7
},
"34": {
"C_NAME": "PIN_A14",
"GPIO": "PA14",
"IRQ": null,
"SD": "INT",
"UART": "0_TX",
"PWM": 2
},
"36": {
"C_NAME": "PIN_A15",
"GPIO": "PA15",
"IRQ": null,
"SD": "D2",
"SPI": "0_CS",
"UART": "2_RX",
"I2C": "0_SCL",
"PWM": 3
},
"37": {
"C_NAME": "PIN_A16",
"GPIO": "PA16",
"IRQ": null,
"SD": "D3",
"SPI": "0_SCK",
"UART": "2_TX",
"I2C": "0_SDA",
"PWM": 4
},
"38": {
"C_NAME": "PIN_A17",
"GPIO": "PA17",
"IRQ": null,
"SD": "CMD",
"PWM": 5
},
"39": {
"C_NAME": "PIN_A18",
"GPIO": "PA18",
"IRQ": null,
"SD": "CLK",
"PWM": 6
},
"40": {
"C_NAME": "PIN_A19",
"GPIO": "PA19",
"IRQ": null,
"SD": "D0",
"SPI": "0_MOSI",
"UART": "2_CTS",
"I2C": "0_SCL",
"PWM": 7
}
}
}
}

View File

@@ -0,0 +1,102 @@
{
"pcb": {
"templates": [
"custom-20x24-22",
"rf-20mm-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,JTAG,FLASH,SD,SPI,SDA1",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 15,
"ARD": "D0"
},
"3": {
"IC": 11,
"ARD": "D1"
},
"4": {
"IC": 12,
"ARD": "D2"
},
"5": {
"IC": 16,
"ARD": "D3"
},
"6": {
"GND": null
},
"7": {
"IC": 18,
"ARD": "D4"
},
"8": {
"IC": 29,
"ARD": "D5"
},
"9": {
"IC": 17,
"ARD": [
"D6",
"A0"
]
},
"10": {
"CTRL": "?"
},
"11": {
"GND": null
},
"12": {
"IC": 24,
"ARD": "D7"
},
"13": {
"IC": 25,
"ARD": "D8"
},
"14": {
"GND": null
},
"15": {
"IC": 19,
"ARD": "D9"
},
"16": {
"IC": 22,
"ARD": "D10"
},
"17": {
"IC": 23,
"ARD": "D11"
},
"18": {
"IC": 26,
"ARD": "D12"
},
"19": {
"GND": null
},
"20": {
"IC": 27,
"ARD": "D13"
},
"21": {
"CTRL": "?"
},
"22": {
"IC": 28,
"ARD": "D14"
}
}
}
}

View File

@@ -0,0 +1,158 @@
{
"pcb": {
"test_pads": {
"TRST": "wb2s.back.cen.anchor",
"TRX2": "wb2s.back.2rx.anchor",
"TTX2": "wb2s.back.2tx.anchor",
"TGND": "wb2s.back.gnd.anchor",
"TSCK": "wb2s.back.sck.anchor",
"TCSN": "wb2s.back.csn.anchor",
"TSI": "wb2s.back.si.anchor",
"TSO": "wb2s.back.adc_so.anchor",
"TPWM3": "wb2s.back.pwm3.anchor",
"TVCC": "wb2s.back.vbat.anchor"
},
"back": [
{
"name": "test_pad_1mm",
"pos": "2.6,6.2"
},
{
"id": "sck",
"name": "label_line_2mm_up",
"pos": "2.6,5.4",
"vars": {
"DIR": "left",
"W": 1.3,
"H": 2
}
},
{
"name": "test_pad_1mm",
"pos": "4.6,6.2"
},
{
"id": "pwm3",
"name": "label_line_2mm_up",
"pos": "4.6,5.4",
"vars": {
"DIR": "left",
"W": 3.3,
"H": 4
}
},
{
"name": "test_pad_1mm",
"pos": "7.0,6.2"
},
{
"id": "2rx",
"name": "label_line_2mm_up",
"pos": "7.0,5.4",
"vars": {
"DIR": "right",
"W": 2,
"H": 4
}
},
{
"name": "test_pad_1mm",
"pos": "9.0,6.2"
},
{
"id": "2tx",
"name": "label_line_2mm_up",
"pos": "9.0,5.4",
"vars": {
"DIR": "right",
"W": 0,
"H": 2
}
},
{
"name": "test_pad_1mm",
"pos": "3.0,8.3"
},
{
"id": "csn",
"name": "label_line_2mm_up",
"pos": "2.2,8.4",
"vars": {
"DIR": "left",
"W": 0.9,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "5.2,8.8"
},
{
"id": "si",
"name": "label_line_2mm_up",
"pos": "6.0,8.9",
"vars": {
"DIR": "right",
"W": 3,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "2.1,11.6"
},
{
"id": "adc_so",
"name": "label_line_2mm_up",
"pos": "1.3,11.7",
"vars": {
"DIR": "left",
"W": 0,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "4.3,11.6"
},
{
"id": "cen",
"name": "label_line_2mm_up",
"pos": "5.1,11.7",
"vars": {
"DIR": "right",
"W": 3.9,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "2.5,14.5"
},
{
"id": "vbat",
"name": "label_line_2mm_up",
"pos": "1.7,14.6",
"vars": {
"DIR": "left",
"W": 0.4,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "4.8,14.5"
},
{
"id": "gnd",
"name": "label_line_2mm_up",
"pos": "5.6,14.6",
"vars": {
"DIR": "right",
"W": 3.4,
"H": 0
}
}
]
}
}

102
boards/_base/pcb/wb2s.json Normal file
View File

@@ -0,0 +1,102 @@
{
"pcb": {
"scale": 10.5,
"templates": [
"tuya2",
"rf-15mm-type1",
"tuya2-shield"
],
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white"
},
"pinout_hidden": "I2S,FLASH",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 24,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 23,
"ARD": "D1"
},
"5": {
"IC": 26,
"ARD": "D4"
},
"6": {
"IC": 22,
"ARD": "D2"
},
"7": {
"IC": 27,
"ARD": "D5"
},
"8": {
"IC": 17,
"ARD": [
"D3",
"A0"
]
},
"9": {
"IC": 16,
"ARD": "D6"
},
"10": {
"IC": 21
},
"11": {
"IC": 15,
"ARD": "D7"
},
"TSCK": {
"IC": 20,
"ARD": "D8"
},
"TPWM3": {
"IC": 25,
"ARD": "D9"
},
"TRX2": {
"IC": 28,
"ARD": "D10"
},
"TTX2": {
"IC": 29,
"ARD": "D11"
},
"TCSN": {
"IC": 19,
"ARD": "D12"
},
"TSI": {
"IC": 18,
"ARD": "D13"
},
"TSO": {
"IC": 17,
"ARD": [
"D3",
"A0"
]
},
"TRST": {
"CTRL": "^RST"
},
"TVCC": {
"PWR": 3.3
},
"TGND": {
"GND": null
}
}
}
}

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

@@ -0,0 +1,106 @@
{
"pcb": {
"templates": [
"esp12e-21",
"esp12e-shield-nohole",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_white",
"TRACE_COLOR": "#E0E0E0",
"SILK_COLOR": "black",
"PINTYPE_VERT": "pin_vert_2mm_cast_nohole",
"PINTYPE_HORZ": "pin_horz_2mm_cast_nohole"
},
"pinout_hidden": "I2S,SD,SPI",
"pinout": {
"1": {
"NC": null
},
"2": {
"IC": 17,
"ARD": [
"D0",
"A0"
]
},
"3": {
"IC": 21
},
"4": {
"IC": 11,
"ARD": "D1"
},
"5": {
"IC": 15,
"ARD": "D2"
},
"6": {
"IC": 16,
"ARD": "D3"
},
"7": {
"IC": 22,
"ARD": "D4"
},
"8": {
"PWR": 3.3
},
"9": {
"GND": null
},
"10": {
"IC": 25,
"ARD": "D5"
},
"11": {
"IC": 29,
"ARD": "D6"
},
"12": {
"IC": 12,
"ARD": "D7"
},
"13": {
"IC": 24,
"ARD": "D8"
},
"14": {
"IC": 23,
"ARD": "D9"
},
"15": {
"IC": 26,
"ARD": "D10"
},
"16": {
"IC": 27,
"ARD": "D11"
},
"17": {
"IC": 17,
"ARD": [
"D0",
"A0"
]
},
"18": {
"IC": 18,
"ARD": "D12"
},
"19": {
"IC": 19,
"ARD": "D13"
},
"20": {
"IC": 20,
"ARD": "D14"
},
"21": {
"IC": 28,
"ARD": "D15"
}
}
}
}

108
boards/_base/pcb/wb3s.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",
"pinout": {
"1": {
"IC": 21
},
"2": {
"IC": 17,
"ARD": [
"D0",
"A0"
]
},
"3": {
"NC": null
},
"4": {
"IC": 11,
"ARD": "D1"
},
"5": {
"IC": 15,
"ARD": "D2"
},
"6": {
"IC": 16,
"ARD": "D3"
},
"7": {
"IC": 22,
"ARD": "D4"
},
"8": {
"PWR": 3.3
},
"9": {
"GND": null
},
"10": {
"IC": 23,
"ARD": "D5"
},
"11": {
"IC": 29,
"ARD": "D6"
},
"12": {
"IC": 28,
"ARD": "D7"
},
"13": {
"IC": 25,
"ARD": "D8"
},
"14": {
"IC": 24,
"ARD": "D9"
},
"15": {
"IC": 26,
"ARD": "D10"
},
"16": {
"IC": 27,
"ARD": "D11"
},
"17": {
"IC": 17,
"ARD": [
"D0",
"A0"
]
},
"18": {
"IC": 18,
"ARD": "D12"
},
"19": {
"IC": 19,
"ARD": "D13"
},
"20": {
"IC": 20,
"ARD": "D14"
},
"21": {
"NC": null
},
"22": {
"NC": null
}
}
}
}

View File

@@ -0,0 +1,14 @@
{
"pcb": {
"templates": [
"tuya2",
"rf-15mm-type1",
"tuya2-shield"
],
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white"
}
}
}

49
boards/_base/pcb/wr2.json Normal file
View File

@@ -0,0 +1,49 @@
{
"pcb": {
"scale": 10.5,
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 17,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 16,
"ARD": "D1"
},
"5": {
"IC": 29,
"ARD": "D4"
},
"6": {
"IC": 28,
"ARD": "D2"
},
"7": {
"IC": 32,
"ARD": "D5"
},
"8": {
"IC": 27,
"ARD": "A1"
},
"9": {
"IC": 13,
"ARD": "D6"
},
"10": {
"IC": 12
},
"11": {
"IC": 14,
"ARD": "D7"
}
}
}
}

View File

@@ -0,0 +1,52 @@
{
"pcb": {
"scale": 10.5,
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,SDA0",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 17,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 30,
"ARD": [
"D1",
"A0"
]
},
"5": {
"IC": 29,
"ARD": "D3"
},
"6": {
"IC": 28,
"ARD": "D2"
},
"7": {
"IC": 32,
"ARD": "D4"
},
"8": {
"IC": 27,
"ARD": "A1"
},
"9": {
"IC": 13,
"ARD": "D5"
},
"10": {
"IC": 12
},
"11": {
"IC": 14,
"ARD": "D6"
}
}
}
}

View File

@@ -0,0 +1,15 @@
{
"pcb": {
"templates": [
"tuya2l",
"rf-15mm-type1",
"tuya2l-shield"
],
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white",
"PINTYPE_HORZ": "pin_horz_2mm_cast_hole"
}
}
}

View File

@@ -0,0 +1,36 @@
{
"pcb": {
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,I2C",
"pinout": {
"1": {
"IC": 14,
"ARD": "D0"
},
"2": {
"IC": 13,
"ARD": "D1"
},
"3": {
"IC": 28,
"ARD": "D2"
},
"4": {
"IC": 30,
"ARD": [
"D3",
"A0"
]
},
"5": {
"IC": 17,
"ARD": "D4"
},
"6": {
"GND": null
},
"7": {
"PWR": 3.3
}
}
}
}

View File

@@ -0,0 +1,33 @@
{
"pcb": {
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,I2C",
"pinout": {
"1": {
"IC": 14,
"ARD": "D0"
},
"2": {
"IC": 13,
"ARD": "D1"
},
"3": {
"IC": 28,
"ARD": "D2"
},
"4": {
"IC": 31,
"ARD": "D3"
},
"5": {
"IC": 17,
"ARD": "D4"
},
"6": {
"GND": null
},
"7": {
"PWR": 3.3
}
}
}
}

View File

@@ -0,0 +1,16 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12s-shield",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_black",
"TRACE_COLOR": "#505050",
"SILK_COLOR": "white",
"PINTYPE_VERT": "pin_vert_2mm_cast_nohole"
}
}
}

View File

@@ -1,17 +1,5 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12s-shield",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_black",
"TRACE_COLOR": "#505050",
"SILK_COLOR": "white",
"PINTYPE_VERT": "pin_vert_2mm_cast_nohole"
},
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD",
"pinout": {
"1": {

View File

@@ -1,16 +1,9 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12s-shield",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_black",
"TRACE_COLOR": "#505050",
"SILK_COLOR": "white",
"PINTYPE_VERT": "pin_vert_2mm_cast_nohole"
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white"
},
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD",
"pinout": {
@@ -26,19 +19,19 @@
},
"4": {
"IC": 2,
"ARD": "D5"
"ARD": "D0"
},
"5": {
"IC": 13,
"ARD": "D2"
"ARD": "D1"
},
"6": {
"IC": 14,
"ARD": "D3"
"ARD": "D2"
},
"7": {
"IC": 31,
"ARD": "D0"
"ARD": "D3"
},
"8": {
"PWR": 3.3
@@ -52,12 +45,12 @@
},
"11": {
"IC": 1,
"ARD": "D6"
"ARD": "D5"
},
"12": {
"IC": 30,
"ARD": [
"D1",
"D6",
"A0"
]
},

View File

@@ -0,0 +1,16 @@
{
"pcb": {
"templates": [
"esp12s",
"esp12e-shield",
"tuya-16x24",
"rf-16mm-type1"
],
"vars": {
"MASK_PRESET": "mask_white",
"TRACE_COLOR": "#E0E0E0",
"SILK_COLOR": "black",
"PINTYPE_VERT": "pin_vert_2mm_cast_hole"
}
}
}

View File

@@ -0,0 +1,65 @@
{
"pcb": {
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI",
"pinout": {
"1": {
"NC": null
},
"2": {
"IC": 27,
"ARD": "A1"
},
"3": {
"IC": 12
},
"4": {
"IC": 2,
"ARD": "D0"
},
"5": {
"IC": 13,
"ARD": "D1"
},
"6": {
"IC": 14,
"ARD": "D2"
},
"7": {
"IC": 16,
"ARD": "D3"
},
"8": {
"PWR": 3.3
},
"9": {
"GND": null
},
"10": {
"NC": null
},
"11": {
"IC": 1,
"ARD": "D4"
},
"12": {
"NC": null
},
"13": {
"IC": 28,
"ARD": "D5"
},
"14": {
"IC": 17,
"ARD": "D6"
},
"15": {
"IC": 29,
"ARD": "D7"
},
"16": {
"IC": 32,
"ARD": "D8"
}
}
}
}

View File

@@ -5,10 +5,6 @@
"amb_boot_all": "boot_all_77F7.bin"
},
"flash": {
"boot_xip": "0x000000+0x4000",
"boot_ram": "0x004000+0x4000",
"system": "0x009000+0x1000",
"calibration": "0x00A000+0x1000",
"ota1": "0x00B000+0x75000",
"ota2": "0x080000+0x75000",
"kvs": "0xF5000+0x6000",

View File

@@ -5,10 +5,6 @@
"amb_boot_all": "boot_all_77F7.bin"
},
"flash": {
"boot_xip": "0x000000+0x4000",
"boot_ram": "0x004000+0x4000",
"system": "0x009000+0x1000",
"calibration": "0x00A000+0x1000",
"ota1": "0x00B000+0xC5000",
"ota2": "0x0D0000+0xC5000",
"kvs": "0x195000+0x6000",

View File

@@ -5,6 +5,12 @@
"prefix": "arm-none-eabi-",
"amb_flash_addr": "0x08000000"
},
"flash": {
"boot_xip": "0x000000+0x4000",
"boot_ram": "0x004000+0x4000",
"system": "0x009000+0x1000",
"calibration": "0x00A000+0x1000"
},
"connectivity": [
"wifi"
],
@@ -43,7 +49,8 @@
"links": {
"General info": "../../docs/platform/realtek/README.md",
"Debugging": "../../docs/platform/realtek/debugging.md",
"Flashing (Tuya manual)": "https://developer.tuya.com/en/docs/iot/burn-and-authorize-wr-series-modules?id=Ka789pjc581u8"
"Flashing guide": "../../docs/platform/realtek-ambz/flashing.md",
"ImageTool (AmebaZ/AmebaD)": "https://images.tuyacn.com/smart/Image_Tool/Image_Tool.zip"
},
"extra": [
"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.",

View File

@@ -0,0 +1,12 @@
{
"flash": {
"ota1": "0x00C000+0xF8000",
"ota2": "0x104000+0xF8000",
"kvs": "0x1FC000+0x2000",
"userdata": "0x1FE000+0x2000"
},
"upload": {
"flash_size": 2097152,
"maximum_size": 1015808
}
}

View File

@@ -0,0 +1,12 @@
{
"connectivity": [
"wifi"
],
"doc": {
"params": {
"extra": {
"Wi-Fi": "802.11 b/g/n"
}
}
}
}

View File

@@ -0,0 +1,14 @@
{
"connectivity": [
"wifi",
"ble"
],
"doc": {
"params": {
"extra": {
"Wi-Fi": "802.11 b/g/n",
"BLE": "v4.2"
}
}
}
}

View File

@@ -0,0 +1,35 @@
{
"build": {
"family": "RTL8720C",
"f_cpu": "100000000L",
"prefix": "arm-none-eabi-",
"ldscript_sdk": "rtl8710c_ram.ld",
"ldscript_arduino": "rtl8710c_ram.ld"
},
"flash": {
"part_table": "0x000000+0x1000",
"system": "0x001000+0x1000",
"calibration": "0x002000+0x1000",
"boot": "0x004000+0x8000"
},
"debug": {
"protocol": "openocd",
"protocols": []
},
"frameworks": [
"realtek-ambz2-sdk"
],
"upload": {
"maximum_ram_size": 262144
},
"doc": {
"params": {
"manufacturer": "Realtek",
"series": "AmebaZ2",
"voltage": "3.0V - 3.6V"
},
"links": {
"General info": "../../docs/platform/realtek/README.md"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"_base": [
"realtek-ambz",
"realtek-ambz-2mb-small",
"realtek-ambz-2mb-468k",
"realtek-ambz-bx",
"pcb/ic-rtl8710bn",
"pcb/bw12"

View File

@@ -6,11 +6,13 @@
- [General info](../../docs/platform/realtek/README.md)
- [Debugging](../../docs/platform/realtek/debugging.md)
- [Flashing (Tuya manual)](https://developer.tuya.com/en/docs/iot/burn-and-authorize-wr-series-modules?id=Ka789pjc581u8)
- [Flashing guide](../../docs/platform/realtek-ambz/flashing.md)
- [ImageTool (AmebaZ/AmebaD)](https://images.tuyacn.com/smart/Image_Tool/Image_Tool.zip)
- [Vendor datasheet](https://docs.ai-thinker.com/_media/rtl8710/hardware/bw12_datasheet_en.pdf)
Parameter | Value
-------------|----------------------------------
Board code | `bw12`
MCU | RTL8710BX
Manufacturer | Realtek
Series | AmebaZ
@@ -21,6 +23,19 @@ Voltage | 3.0V - 3.6V
I/O | 11x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
## Usage
**Board code:** `bw12`
In `platformio.ini`:
```ini
[env:bw12]
platform = libretuya
board = bw12
framework = arduino
```
## Pinout
![Pinout](pinout_bw12.svg)

24
boards/bw15.json Normal file
View File

@@ -0,0 +1,24 @@
{
"_base": [
"realtek-ambz2",
"realtek-ambz2-8720",
"realtek-ambz2-2mb-992k",
"pcb/ic-rtl8720cf",
"pcb/bw15"
],
"build": {
"mcu": "rtl8720cf",
"variant": "bw15"
},
"name": "BW15",
"url": "https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf",
"vendor": "Ai-Thinker Co., Ltd.",
"pcb": {
"symbol": "BW15"
},
"doc": {
"links": {
"Vendor datasheet": "https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf"
}
}
}

57
boards/bw15/README.md Normal file
View File

@@ -0,0 +1,57 @@
# BW15
*by Ai-Thinker Co., Ltd.*
[Product page](https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf)
- [General info](../../docs/platform/realtek/README.md)
- [Vendor datasheet](https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf)
Parameter | Value
-------------|--------------------------
Board code | `bw15`
MCU | RTL8720CF
Manufacturer | Realtek
Series | AmebaZ2
Frequency | 100 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 13x GPIO, 8x PWM, 3x UART
Wi-Fi | 802.11 b/g/n
BLE | v4.2
## Usage
**Board code:** `bw15`
In `platformio.ini`:
```ini
[env:bw15]
platform = libretuya
board = bw15
framework = arduino
```
## Pinout
![Pinout](pinout_bw15.svg)
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
Hex values are in bytes.
Name | Start | Length | End
----------------|----------|-------------------|---------
Partition Table | 0x000000 | 4 KiB / 0x1000 | 0x001000
System Data | 0x001000 | 4 KiB / 0x1000 | 0x002000
Calibration | 0x002000 | 4 KiB / 0x1000 | 0x003000
(reserved) | 0x003000 | 4 KiB / 0x1000 | 0x004000
Boot Image | 0x004000 | 32 KiB / 0x8000 | 0x00C000
OTA1 Image | 0x00C000 | 992 KiB / 0xF8000 | 0x104000
OTA2 Image | 0x104000 | 992 KiB / 0xF8000 | 0x1FC000
Key-Value Store | 0x1FC000 | 8 KiB / 0x2000 | 0x1FE000
User Data | 0x1FE000 | 8 KiB / 0x2000 | 0x200000

355
boards/bw15/pinout_bw15.svg Normal file
View File

@@ -0,0 +1,355 @@
<?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="#4d4d4d"/>
<stop offset="100%" stop-color="#0f0f0f"/>
</linearGradient>
<rect fill="url(#id1) none" height="23.9" stroke="#b5a739" stroke-width="0.1" width="15.9" x="34.66666666666666" y="8.883333333333333"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin1.trace" width="0.7" x="34.61666666666666" y="16.583333333333332"/>
<circle cx="34.61666666666666" cy="17.18333333333333" fill="#fff" id="esp12s.front.left.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin2.trace" width="0.7" x="34.61666666666666" y="18.583333333333332"/>
<circle cx="34.61666666666666" cy="19.18333333333333" fill="#fff" id="esp12s.front.left.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin3.trace" width="0.7" x="34.61666666666666" y="20.583333333333332"/>
<circle cx="34.61666666666666" cy="21.18333333333333" fill="#fff" id="esp12s.front.left.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin4.trace" width="0.7" x="34.61666666666666" y="22.583333333333332"/>
<circle cx="34.61666666666666" cy="23.18333333333333" fill="#fff" id="esp12s.front.left.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin5.trace" width="0.7" x="34.61666666666666" y="24.583333333333332"/>
<circle cx="34.61666666666666" cy="25.183333333333334" fill="#fff" id="esp12s.front.left.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin6.trace" width="0.7" x="34.61666666666666" y="26.583333333333332"/>
<circle cx="34.61666666666666" cy="27.183333333333334" fill="#fff" id="esp12s.front.left.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin7.trace" width="0.7" x="34.61666666666666" y="28.583333333333332"/>
<circle cx="34.61666666666666" cy="29.183333333333334" fill="#fff" id="esp12s.front.left.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.left.pin8.trace" width="0.7" x="34.61666666666666" y="30.583333333333332"/>
<circle cx="34.61666666666666" cy="31.183333333333334" fill="#fff" id="esp12s.front.left.pin8.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin1.trace" width="0.7" x="49.91666666666666" y="16.583333333333332"/>
<circle cx="50.61666666666666" cy="17.18333333333333" fill="#fff" id="esp12s.front.right.pin1.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin2.trace" width="0.7" x="49.91666666666666" y="18.583333333333332"/>
<circle cx="50.61666666666666" cy="19.18333333333333" fill="#fff" id="esp12s.front.right.pin2.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin3.trace" width="0.7" x="49.91666666666666" y="20.583333333333332"/>
<circle cx="50.61666666666666" cy="21.18333333333333" fill="#fff" id="esp12s.front.right.pin3.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin4.trace" width="0.7" x="49.91666666666666" y="22.583333333333332"/>
<circle cx="50.61666666666666" cy="23.18333333333333" fill="#fff" id="esp12s.front.right.pin4.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin5.trace" width="0.7" x="49.91666666666666" y="24.583333333333332"/>
<circle cx="50.61666666666666" cy="25.183333333333334" fill="#fff" id="esp12s.front.right.pin5.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin6.trace" width="0.7" x="49.91666666666666" y="26.583333333333332"/>
<circle cx="50.61666666666666" cy="27.183333333333334" fill="#fff" id="esp12s.front.right.pin6.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin7.trace" width="0.7" x="49.91666666666666" y="28.583333333333332"/>
<circle cx="50.61666666666666" cy="29.183333333333334" fill="#fff" id="esp12s.front.right.pin7.cast" r="0.35"/>
<rect fill="#e5b472" height="1.2" id="esp12s.front.right.pin8.trace" width="0.7" x="49.91666666666666" y="30.583333333333332"/>
<circle cx="50.61666666666666" cy="31.183333333333334" fill="#fff" id="esp12s.front.right.pin8.cast" 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="16.8" rx="0.5" ry="0.5" width="13.6" x="35.81666666666666" y="15.783333333333331"/>
<rect fill="#fafd9d" height="5.2" width="0.5" x="35.71666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="0.5" width="4.6" x="35.71666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="5.2" width="0.5" x="37.91666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="3.0" width="0.5" x="39.81666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="0.5" width="3.0" x="39.81666666666666" y="12.133333333333333"/>
<rect fill="#fafd9d" height="3.0" width="0.5" x="42.31666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="0.5" width="2.7" x="42.31666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="3.0" width="0.5" x="44.51666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="0.5" width="3.0" x="44.51666666666666" y="12.133333333333333"/>
<rect fill="#fafd9d" height="3.0" width="0.5" x="47.01666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="0.5" width="2.5" x="47.01666666666666" y="9.633333333333333"/>
<rect fill="#fafd9d" height="4.4" width="0.5" x="49.01666666666666" y="9.633333333333333"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="17.08333333333333"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="17.18333333333333">PA17</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="17.18333333333333">D0</text>
<g transform="translate(21.131026020611557,16.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="22.61666666666666" y="17.18333333333333">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="19.08333333333333"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="19.18333333333333">PA18</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="19.18333333333333">D1</text>
<g transform="translate(21.131026020611557,18.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="22.61666666666666" y="19.18333333333333">PWM6</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="21.08333333333333"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="21.18333333333333">CEN</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="23.08333333333333"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="23.18333333333333">PA02</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="23.18333333333333">D2</text>
<g transform="translate(21.131026020611557,22.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="22.61666666666666" y="23.18333333333333">RX1</text>
<g transform="translate(17.53102602061156,22.38333333333333)">
<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="19.016666666666662" y="23.18333333333333">SCL0</text>
<g transform="translate(13.93102602061156,22.38333333333333)">
<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="15.41666666666666" y="23.18333333333333">CS0</text>
<g transform="translate(10.331026020611558,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="11.81666666666666" y="23.18333333333333">PWM2</text>
<g transform="translate(6.731026020611557,22.38333333333333)">
<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="8.216666666666658" y="23.18333333333333">TDO</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="25.083333333333332"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="25.183333333333334">PA15</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="25.183333333333334">D3</text>
<g transform="translate(21.131026020611557,24.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="22.61666666666666" y="25.183333333333334">RX2</text>
<g transform="translate(17.53102602061156,24.383333333333333)">
<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="19.016666666666662" y="25.183333333333334">SCL0</text>
<g transform="translate(13.93102602061156,24.383333333333333)">
<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="15.41666666666666" y="25.183333333333334">CS0</text>
<g transform="translate(10.331026020611558,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="11.81666666666666" y="25.183333333333334">PWM3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="27.083333333333332"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="27.183333333333334">PA04</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="27.183333333333334">D4</text>
<g transform="translate(21.131026020611557,26.383333333333333)">
<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="27.183333333333334">MOSI0</text>
<g transform="translate(17.53102602061156,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="19.016666666666662" y="27.183333333333334">PWM4</text>
<g transform="translate(13.93102602061156,26.383333333333333)">
<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="15.41666666666666" y="27.183333333333334">tRST</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="29.083333333333332"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="29.183333333333334">PA19</text>
<g transform="translate(24.73102602061156,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="25.91666666666666" y="29.183333333333334">D5</text>
<g transform="translate(21.131026020611557,28.383333333333333)">
<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="22.61666666666666" y="29.183333333333334">SCL0</text>
<g transform="translate(17.53102602061156,28.383333333333333)">
<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="19.016666666666662" y="29.183333333333334">MOSI0</text>
<g transform="translate(13.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="15.41666666666666" y="29.183333333333334">PWM7</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="31.51666666666666" y="31.083333333333332"/>
<g transform="translate(27.731026020611555,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="29.216666666666658" y="31.183333333333334">3V3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="31.083333333333332"/>
<g transform="translate(54.53102602061156,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="56.016666666666666" y="31.183333333333334">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="29.083333333333332"/>
<g transform="translate(54.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="56.016666666666666" y="29.183333333333334">PA20</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="29.183333333333334">D6</text>
<g transform="translate(61.131026020611564,28.383333333333333)">
<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="62.61666666666667" y="29.183333333333334">SDA0</text>
<g transform="translate(64.73102602061155,28.383333333333333)">
<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="66.21666666666665" y="29.183333333333334">MISO0</text>
<g transform="translate(68.33102602061156,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="69.81666666666666" y="29.183333333333334">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="27.083333333333332"/>
<g transform="translate(54.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="56.016666666666666" y="27.183333333333334">PA16</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="27.183333333333334">D7</text>
<g transform="translate(61.131026020611564,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="62.61666666666667" y="27.183333333333334">TX2</text>
<g transform="translate(64.73102602061155,26.383333333333333)">
<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="27.183333333333334">SDA0</text>
<g transform="translate(68.33102602061156,26.383333333333333)">
<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="69.81666666666666" y="27.183333333333334">SCK0</text>
<g transform="translate(71.93102602061157,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="73.41666666666667" y="27.183333333333334">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="25.083333333333332"/>
<g transform="translate(54.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="56.016666666666666" y="25.183333333333334">PA00</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="25.183333333333334">D8</text>
<g transform="translate(61.131026020611564,24.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="62.61666666666667" y="25.183333333333334">RX1</text>
<g transform="translate(64.73102602061155,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="66.21666666666665" y="25.183333333333334">PWM0</text>
<g transform="translate(68.33102602061156,24.383333333333333)">
<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="69.81666666666666" y="25.183333333333334">TCK</text>
<g transform="translate(71.93102602061157,24.383333333333333)">
<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="73.41666666666667" y="25.183333333333334">SWCLK</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="23.08333333333333"/>
<g transform="translate(54.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="56.016666666666666" y="23.18333333333333">PA03</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="23.18333333333333">D9</text>
<g transform="translate(61.131026020611564,22.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="62.61666666666667" y="23.18333333333333">TX1</text>
<g transform="translate(64.73102602061155,22.38333333333333)">
<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.18333333333333">SDA0</text>
<g transform="translate(68.33102602061156,22.38333333333333)">
<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="69.81666666666666" y="23.18333333333333">SCK0</text>
<g transform="translate(71.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="73.41666666666667" y="23.18333333333333">PWM3</text>
<g transform="translate(75.53102602061156,22.38333333333333)">
<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="77.01666666666667" y="23.18333333333333">TDI</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="21.08333333333333"/>
<g transform="translate(54.53102602061156,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="56.016666666666666" y="21.18333333333333">PA01</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="21.18333333333333">D10</text>
<g transform="translate(61.131026020611564,20.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="62.61666666666667" y="21.18333333333333">TX1</text>
<g transform="translate(64.73102602061155,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="66.21666666666665" y="21.18333333333333">PWM1</text>
<g transform="translate(68.33102602061156,20.38333333333333)">
<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="69.81666666666666" y="21.18333333333333">TMS</text>
<g transform="translate(71.93102602061157,20.38333333333333)">
<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="73.41666666666667" y="21.18333333333333">SWDIO</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="19.08333333333333"/>
<g transform="translate(54.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="56.016666666666666" y="19.18333333333333">PA13</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="19.18333333333333">D11</text>
<g transform="translate(61.131026020611564,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="62.61666666666667" y="19.18333333333333">RX0</text>
<g transform="translate(64.73102602061155,18.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="66.21666666666665" y="19.18333333333333">PWM7</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="51.11666666666666" y="17.08333333333333"/>
<g transform="translate(54.53102602061156,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="56.016666666666666" y="17.18333333333333">PA14</text>
<g transform="translate(58.131026020611564,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="59.31666666666666" y="17.18333333333333">D12</text>
<g transform="translate(61.131026020611564,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="62.61666666666667" y="17.18333333333333">TX0</text>
<g transform="translate(64.73102602061155,16.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="66.21666666666665" y="17.18333333333333">PWM2</text>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

View File

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

7
boards/bw15/variant.h Normal file
View File

@@ -0,0 +1,7 @@
/* This file was auto-generated from bw15.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off

View File

@@ -5,11 +5,12 @@
[Product page](https://developer.tuya.com/en/docs/iot/cb2s-module-datasheet?id=Kafgfsa2aaypq)
- [General info](../../docs/platform/beken-72xx/README.md)
- [Flashing (Tuya manual)](https://developer.tuya.com/en/docs/iot/burn-and-authorize-wb-series-modules?id=Ka78f4pttsytd)
- [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 | `cb2s`
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
@@ -21,6 +22,19 @@ I/O | 11x GPIO, 5x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
## Usage
**Board code:** `cb2s`
In `platformio.ini`:
```ini
[env:cb2s]
platform = libretuya
board = cb2s
framework = arduino
```
## Pinout
![Pinout](pinout_cb2s.svg)

View File

@@ -0,0 +1,100 @@
{
"_base": [
"generic",
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32"
],
"build": {
"mcu": "bk7231n",
"variant": "generic-bk7231n-qfn32-tuya"
},
"name": "Generic - BK7231N (Tuya QFN32)",
"symbol": "BK7231N (Tuya QFN32)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-bk7231n-qfn32-tuya/",
"vendor": "Generic",
"pcb": {
"pinout": {
"1": {
"IC": 29,
"ARD": "D0"
},
"2": {
"IC": 28,
"ARD": "D1"
},
"3": {
"IC": 22,
"ARD": "D2"
},
"4": {
"IC": 23,
"ARD": "D3"
},
"5": {
"IC": 24,
"ARD": "D4"
},
"6": {
"IC": 25,
"ARD": "D5"
},
"7": {
"IC": 26,
"ARD": "D6"
},
"8": {
"IC": 27,
"ARD": "D7"
},
"9": {
"IC": 11,
"ARD": "D8"
},
"10": {
"IC": 13,
"ARD": "D9"
},
"11": {
"IC": 12,
"ARD": "D10"
},
"12": {
"IC": 14,
"ARD": "D11"
},
"13": {
"IC": 20,
"ARD": "D12"
},
"14": {
"IC": 19,
"ARD": "D13"
},
"15": {
"IC": 18,
"ARD": "D14"
},
"16": {
"IC": 17,
"ARD": [
"D15",
"A0"
]
},
"17": {
"IC": 16,
"ARD": "D16"
},
"18": {
"IC": 15,
"ARD": "D17"
},
"19": {
"IC": 10,
"ARD": "D18"
}
}
}
}

View File

@@ -0,0 +1,79 @@
# Generic - BK7231N (Tuya QFN32)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-bk7231n-qfn32-tuya/)
- [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 | `generic-bk7231n-qfn32-tuya`
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 19x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
## Usage
**Board code:** `generic-bk7231n-qfn32-tuya`
In `platformio.ini`:
```ini
[env:generic-bk7231n-qfn32-tuya]
platform = libretuya
board = generic-bk7231n-qfn32-tuya
framework = arduino
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
----|-----------|----------|----------|------|------|------
D0 | P0 | UART2_TX | I2C2_SCL | | |
D1 | P1 | UART2_RX | I2C2_SDA | | |
D2 | P6 | | | | PWM0 |
D3 | P7 | | | | PWM1 |
D4 | P8 | | | | PWM2 |
D5 | P9 | | | | PWM3 |
D6 | P10 | UART1_RX | | | |
D7 | P11 | UART1_TX | | | |
D8 | P14 | | | SCK | |
D9 | P15 | | | CS | |
D10 | P16 | | | MOSI | |
D11 | P17 | | | MISO | |
D12 | P20 | | I2C1_SCL | | | TCK
D13 | P21 | | I2C1_SDA | | | TMS
D14 | P22 | | | | | TDI
D15 | P23 | | | | | TDO
D16 | P24 | | | | PWM4 |
D17 | P26 | | | | PWM5 |
D18 | P28 | | | | |
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
TLV Store | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 8 KiB / 0x2000 | 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 @@
#include "variant.h"

View File

@@ -0,0 +1,50 @@
/* This file was auto-generated from generic-bk7231n-qfn32-tuya.json using boardgen */
#include <Arduino.h>
extern "C" {
// clang-format off
PinInfo pinTable[PINS_COUNT] = {
// D0: P0, UART2_TX, I2C2_SCL
{GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D1: P1, UART2_RX, I2C2_SDA
{GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D2: P6, PWM0
{GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D3: P7, PWM1
{GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D4: P8, PWM2
{GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D5: P9, PWM3
{GPIO9, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D6: P10, UART1_RX
{GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D7: P11, UART1_TX
{GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D8: P14, SD_CLK, SCK
{GPIO14, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D9: P15, SD_CMD, CS
{GPIO15, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D10: P16, SD_D0, MOSI
{GPIO16, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D11: P17, SD_D1, MISO
{GPIO17, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D12: P20, I2C1_SCL, TCK, FSCK
{GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
// D13: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
// D14: P22, TDI, FSI
{GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
// D15: P23, ADC3, TDO, FSO
{GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
// D16: P24, PWM4
{GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D17: P26, PWM5, IRDA
{GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D18: P28, DN
{GPIO28, PIN_GPIO | PIN_IRQ, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

View File

@@ -0,0 +1,39 @@
/* This file was auto-generated from generic-bk7231n-qfn32-tuya.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 19
#define NUM_DIGITAL_PINS 19
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 15u // GPIO23
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 2
#define PIN_WIRE1_SCL 12u // GPIO20
#define PIN_WIRE1_SDA 13u // GPIO21
#define PIN_WIRE2_SCL 0u // GPIO0
#define PIN_WIRE2_SDA 1u // GPIO1
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 2
#define PIN_SERIAL1_RX 6u // GPIO10
#define PIN_SERIAL1_TX 7u // GPIO11
#define PIN_SERIAL2_RX 1u // GPIO1
#define PIN_SERIAL2_TX 0u // GPIO0

View File

@@ -0,0 +1,100 @@
{
"_base": [
"generic",
"beken-72xx",
"beken-7231t",
"beken-7231t-tuya",
"pcb/ic-bk7231-qfn32"
],
"build": {
"mcu": "bk7231t",
"variant": "generic-bk7231t-qfn32-tuya"
},
"name": "Generic - BK7231T (Tuya QFN32)",
"symbol": "BK7231T (Tuya QFN32)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-bk7231t-qfn32-tuya/",
"vendor": "Generic",
"pcb": {
"pinout": {
"1": {
"IC": 29,
"ARD": "D0"
},
"2": {
"IC": 28,
"ARD": "D1"
},
"3": {
"IC": 22,
"ARD": "D2"
},
"4": {
"IC": 23,
"ARD": "D3"
},
"5": {
"IC": 24,
"ARD": "D4"
},
"6": {
"IC": 25,
"ARD": "D5"
},
"7": {
"IC": 26,
"ARD": "D6"
},
"8": {
"IC": 27,
"ARD": "D7"
},
"9": {
"IC": 11,
"ARD": "D8"
},
"10": {
"IC": 13,
"ARD": "D9"
},
"11": {
"IC": 12,
"ARD": "D10"
},
"12": {
"IC": 14,
"ARD": "D11"
},
"13": {
"IC": 20,
"ARD": "D12"
},
"14": {
"IC": 19,
"ARD": "D13"
},
"15": {
"IC": 18,
"ARD": "D14"
},
"16": {
"IC": 17,
"ARD": [
"D15",
"A0"
]
},
"17": {
"IC": 16,
"ARD": "D16"
},
"18": {
"IC": 15,
"ARD": "D17"
},
"19": {
"IC": 10,
"ARD": "D18"
}
}
}
}

View File

@@ -0,0 +1,79 @@
# Generic - BK7231T (Tuya QFN32)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-bk7231t-qfn32-tuya/)
- [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 | `generic-bk7231t-qfn32-tuya`
MCU | BK7231T
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 19x GPIO, 6x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v4.2
## Usage
**Board code:** `generic-bk7231t-qfn32-tuya`
In `platformio.ini`:
```ini
[env:generic-bk7231t-qfn32-tuya]
platform = libretuya
board = generic-bk7231t-qfn32-tuya
framework = arduino
```
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
----|-----------|----------|----------|------|------|------
D0 | P0 | UART2_TX | I2C2_SCL | | |
D1 | P1 | UART2_RX | I2C2_SDA | | |
D2 | P6 | | | | PWM0 |
D3 | P7 | | | | PWM1 |
D4 | P8 | | | | PWM2 |
D5 | P9 | | | | PWM3 |
D6 | P10 | UART1_RX | | | |
D7 | P11 | UART1_TX | | | |
D8 | P14 | | | SCK | |
D9 | P15 | | | CS | |
D10 | P16 | | | MOSI | |
D11 | P17 | | | MISO | |
D12 | P20 | | I2C1_SCL | | | TCK
D13 | P21 | | I2C1_SDA | | | TMS
D14 | P22 | | | | | TDI
D15 | P23 | | | | | TDO
D16 | P24 | | | | PWM4 |
D17 | P26 | | | | PWM5 |
D18 | P28 | | | | |
A0 | P23, ADC3 | | | | |
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
Hex values are in bytes.
Name | Start | Length | End
----------------|----------|--------------------|---------
Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
App Image | 0x011000 | 1.1 MiB / 0x121000 | 0x132000
OTA Image | 0x132000 | 664 KiB / 0xA6000 | 0x1D8000
Key-Value Store | 0x1D8000 | 32 KiB / 0x8000 | 0x1E0000
TLV Store | 0x1E0000 | 4 KiB / 0x1000 | 0x1E1000
Network Data | 0x1E1000 | 8 KiB / 0x2000 | 0x1E3000
User Data | 0x1E3000 | 116 KiB / 0x1D000 | 0x200000
Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes.

View File

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

View File

@@ -0,0 +1,50 @@
/* This file was auto-generated from generic-bk7231t-qfn32-tuya.json using boardgen */
#include <Arduino.h>
extern "C" {
// clang-format off
PinInfo pinTable[PINS_COUNT] = {
// D0: P0, UART2_TX, I2C2_SCL
{GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D1: P1, UART2_RX, I2C2_SDA
{GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D2: P6, PWM0
{GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D3: P7, PWM1
{GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D4: P8, PWM2
{GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D5: P9, PWM3
{GPIO9, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D6: P10, UART1_RX
{GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D7: P11, UART1_TX
{GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D8: P14, SD_CLK, SCK
{GPIO14, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D9: P15, SD_CMD, CS
{GPIO15, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D10: P16, SD_D0, MOSI
{GPIO16, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D11: P17, SD_D1, MISO
{GPIO17, PIN_GPIO | PIN_IRQ | PIN_SPI, PIN_NONE, 0},
// D12: P20, I2C1_SCL, TCK, FSCK
{GPIO20, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_JTAG, PIN_NONE, 0},
// D13: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
// D14: P22, TDI, FSI
{GPIO22, PIN_GPIO | PIN_IRQ | PIN_JTAG, PIN_NONE, 0},
// D15: P23, ADC3, TDO, FSO
{GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
// D16: P24, PWM4
{GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D17: P26, PWM5, IRDA
{GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D18: P28, DN
{GPIO28, PIN_GPIO | PIN_IRQ, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

View File

@@ -0,0 +1,39 @@
/* This file was auto-generated from generic-bk7231t-qfn32-tuya.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 19
#define NUM_DIGITAL_PINS 19
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 15u // GPIO23
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 2
#define PIN_WIRE1_SCL 12u // GPIO20
#define PIN_WIRE1_SDA 13u // GPIO21
#define PIN_WIRE2_SCL 0u // GPIO0
#define PIN_WIRE2_SDA 1u // GPIO1
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 2
#define PIN_SERIAL1_RX 6u // GPIO10
#define PIN_SERIAL1_TX 7u // GPIO11
#define PIN_SERIAL2_RX 1u // GPIO1
#define PIN_SERIAL2_TX 0u // GPIO0

View File

@@ -5,7 +5,8 @@
[Product page](https://kuba2k2.github.io/libretuya/)
Parameter | Value
-------------|-------
-------------|-----------------
Board code | `generic-native`
MCU | NATIVE
Manufacturer | N/A
Series | N/A
@@ -14,6 +15,19 @@ Flash size | 4 MiB
RAM size | 4 MiB
Voltage | 5V
## Usage
**Board code:** `generic-native`
In `platformio.ini`:
```ini
[env:generic-native]
platform = libretuya
board = generic-native
framework = arduino
```
## Flash memory map
Flash size: 4 MiB / 4,194,304 B / 0x400000

View File

@@ -0,0 +1,95 @@
{
"_base": [
"generic",
"realtek-ambz",
"realtek-ambz-2mb-468k",
"pcb/ic-rtl8710bn"
],
"build": {
"mcu": "rtl8710bn",
"variant": "generic-rtl8710bn-2mb-468k"
},
"name": "Generic - RTL8710BN (2M/468k)",
"symbol": "RTL8710BN (2M/468k)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bn-2mb-468k/",
"vendor": "Generic",
"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"
},
"18": {
"IC": 27,
"ARD": "A1"
}
}
}
}

View File

@@ -0,0 +1,83 @@
# Generic - RTL8710BN (2M/468k)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bn-2mb-468k/)
- [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-rtl8710bn-2mb-468k`
MCU | RTL8710BN
Manufacturer | Realtek
Series | AmebaZ
Frequency | 125 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 17x GPIO, 6x PWM, 2x UART, 2x ADC
Wi-Fi | 802.11 b/g/n
## Usage
**Board code:** `generic-rtl8710bn-2mb-468k`
In `platformio.ini`:
```ini
[env:generic-rtl8710bn-2mb-468k]
platform = libretuya
board = generic-rtl8710bn-2mb-468k
framework = arduino
```
## 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 | | | | |
A1 | ADC2 | | | | |
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
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 | 468 KiB / 0x75000 | 0x080000
OTA2 Image | 0x080000 | 468 KiB / 0x75000 | 0x0F5000
Key-Value Store | 0x0F5000 | 24 KiB / 0x6000 | 0x0FB000
User Data | 0x0FB000 | 1 MiB / 0x104000 | 0x1FF000
RDP | 0x1FF000 | 4 KiB / 0x1000 | 0x200000
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.

View File

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

View File

@@ -0,0 +1,48 @@
/* This file was auto-generated from generic-rtl8710bn-2mb-468k.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},
// A1: ADC2
{AD_2, PIN_ADC, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

View File

@@ -0,0 +1,53 @@
/* This file was auto-generated from generic-rtl8710bn-2mb-468k.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 18
#define NUM_DIGITAL_PINS 17
#define NUM_ANALOG_INPUTS 2
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 12u // PA_19
#define PIN_A1 17u // AD_2
#define A0 PIN_A0
#define A1 PIN_A1
// 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

View File

@@ -0,0 +1,95 @@
{
"_base": [
"generic",
"realtek-ambz",
"realtek-ambz-2mb-788k",
"pcb/ic-rtl8710bn"
],
"build": {
"mcu": "rtl8710bn",
"variant": "generic-rtl8710bn-2mb-788k"
},
"name": "Generic - RTL8710BN (2M/788k)",
"symbol": "RTL8710BN (2M/788k)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bn-2mb-788k/",
"vendor": "Generic",
"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"
},
"18": {
"IC": 27,
"ARD": "A1"
}
}
}
}

View File

@@ -0,0 +1,83 @@
# Generic - RTL8710BN (2M/788k)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-rtl8710bn-2mb-788k/)
- [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-rtl8710bn-2mb-788k`
MCU | RTL8710BN
Manufacturer | Realtek
Series | AmebaZ
Frequency | 125 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 17x GPIO, 6x PWM, 2x UART, 2x ADC
Wi-Fi | 802.11 b/g/n
## Usage
**Board code:** `generic-rtl8710bn-2mb-788k`
In `platformio.ini`:
```ini
[env:generic-rtl8710bn-2mb-788k]
platform = libretuya
board = generic-rtl8710bn-2mb-788k
framework = arduino
```
## 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 | | | | |
A1 | ADC2 | | | | |
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
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 | 788 KiB / 0xC5000 | 0x0D0000
OTA2 Image | 0x0D0000 | 788 KiB / 0xC5000 | 0x195000
Key-Value Store | 0x195000 | 24 KiB / 0x6000 | 0x19B000
User Data | 0x19B000 | 400 KiB / 0x64000 | 0x1FF000
RDP | 0x1FF000 | 4 KiB / 0x1000 | 0x200000
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.

View File

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

View File

@@ -0,0 +1,48 @@
/* This file was auto-generated from generic-rtl8710bn-2mb-788k.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},
// A1: ADC2
{AD_2, PIN_ADC, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

View File

@@ -0,0 +1,53 @@
/* This file was auto-generated from generic-rtl8710bn-2mb-788k.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 18
#define NUM_DIGITAL_PINS 17
#define NUM_ANALOG_INPUTS 2
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 12u // PA_19
#define PIN_A1 17u // AD_2
#define A0 PIN_A0
#define A1 PIN_A1
// 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

View File

@@ -0,0 +1,101 @@
{
"_base": [
"generic",
"realtek-ambz2",
"realtek-ambz2-8720",
"realtek-ambz2-2mb-992k",
"pcb/ic-rtl8720cf"
],
"build": {
"mcu": "rtl8720cf",
"variant": "generic-rtl8720cf-2mb-992k"
},
"name": "Generic - RTL8720CF (2M/992k)",
"symbol": "RTL8720CF (2M/992k)",
"url": "https://kuba2k2.github.io/libretuya/boards/generic-rtl8720cf-2mb-992k/",
"vendor": "Generic",
"pcb": {
"pinout": {
"1": {
"IC": 15,
"ARD": "D0"
},
"2": {
"IC": 16,
"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": 24,
"ARD": "D8"
},
"10": {
"IC": 25,
"ARD": "D9"
},
"11": {
"IC": 26,
"ARD": "D10"
},
"12": {
"IC": 33,
"ARD": "D11"
},
"13": {
"IC": 34,
"ARD": "D12"
},
"14": {
"IC": 36,
"ARD": "D13"
},
"15": {
"IC": 37,
"ARD": "D14"
},
"16": {
"IC": 38,
"ARD": "D15"
},
"17": {
"IC": 39,
"ARD": "D16"
},
"18": {
"IC": 40,
"ARD": "D17"
},
"19": {
"IC": 1,
"ARD": "D18"
},
"20": {
"IC": 3,
"ARD": "D19"
}
}
}
}

View File

@@ -0,0 +1,52 @@
# Generic - RTL8720CF (2M/992k)
*by Generic*
[Product page](https://kuba2k2.github.io/libretuya/boards/generic-rtl8720cf-2mb-992k/)
- [General info](../../docs/platform/realtek/README.md)
Parameter | Value
-------------|-----------------------------
Board code | `generic-rtl8720cf-2mb-992k`
MCU | RTL8720CF
Manufacturer | Realtek
Series | AmebaZ2
Frequency | 100 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 20x GPIO, 8x PWM, 3x UART
Wi-Fi | 802.11 b/g/n
BLE | v4.2
## Usage
**Board code:** `generic-rtl8720cf-2mb-992k`
In `platformio.ini`:
```ini
[env:generic-rtl8720cf-2mb-992k]
platform = libretuya
board = generic-rtl8720cf-2mb-992k
framework = arduino
```
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
Hex values are in bytes.
Name | Start | Length | End
----------------|----------|-------------------|---------
Partition Table | 0x000000 | 4 KiB / 0x1000 | 0x001000
System Data | 0x001000 | 4 KiB / 0x1000 | 0x002000
Calibration | 0x002000 | 4 KiB / 0x1000 | 0x003000
(reserved) | 0x003000 | 4 KiB / 0x1000 | 0x004000
Boot Image | 0x004000 | 32 KiB / 0x8000 | 0x00C000
OTA1 Image | 0x00C000 | 992 KiB / 0xF8000 | 0x104000
OTA2 Image | 0x104000 | 992 KiB / 0xF8000 | 0x1FC000
Key-Value Store | 0x1FC000 | 8 KiB / 0x2000 | 0x1FE000
User Data | 0x1FE000 | 8 KiB / 0x2000 | 0x200000

View File

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

View File

@@ -0,0 +1,7 @@
/* This file was auto-generated from generic-rtl8720cf-2mb-992k.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off

29
boards/lsc-lma35.json Normal file
View File

@@ -0,0 +1,29 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/lsc-lma35"
],
"build": {
"mcu": "bk7231n",
"variant": "lsc-lma35"
},
"name": "LSC LMA35",
"symbol": "LSC LMA35",
"url": "https://www.action.com/de-at/p/lsc-smart-connect-outdoor-led-streifen/",
"vendor": "Unknown",
"pcb": {
"symbol": "LMA35"
},
"doc": {
"extra": [
"## Information",
"This board has no marking on the front side, only something that looks like PCB manufacturing info on the back; thus it was named based on these symbols.",
"It can be found in 'LSC Smart Connect Outdoor LED Strip', and is likely custom-made for this product.",
"The pinout was established by writing to and probing consecutive GPIOs, using the generic board definition.",
"Pins marked with '?' are currently unknown, with a possibility of being CEN. Pin 22 (P1/D14) is also not confirmed."
]
}
}

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