diff --git a/README.md b/README.md index 8a8b29e..15a2516 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ [![PlatformIO Registry](https://badges.registry.platformio.org/packages/kuba2k2/platform/libretuya.svg)](https://registry.platformio.org/platforms/kuba2k2/libretuya) ![RTL8710BN](https://img.shields.io/badge/-rtl8710bn-blue) +![BK7231](https://img.shields.io/badge/-bk7231-blue) @@ -40,33 +41,33 @@ See [Boards & CPU list](https://kuba2k2.github.io/libretuya/docs/supported/). Note: this list will probably change with each functionality update. -  | `realtek-ambz` ---------------------|--------------- -Core functions | ✔️ -GPIO/PWM/IRQ | ✔️/✔️/✔️ -Analog input | ✔️ -UART I/O | ✔️ -Flash I/O | ✔️ -**CORE LIBRARIES** | -SoftwareSerial | ❌ -SPI | ❌ -Wire | ❗ -**OTHER LIBRARIES** | -Wi-Fi STA/AP/Mixed | ✔️ -Wi-Fi Events | ✔️ -TCP Client (SSL) | ✔️ (✔️) -TCP Server | ✔️ -IPv6 | ❌ -HTTP Client (SSL) | ✔️ (✔️) -HTTP Server | ✔️ -NVS / Preferences | ❌ -SPIFFS | ❌ -BLE | - -NTP | ❌ -OTA | ✔️ -MDNS | ✔️ -MQTT | ✅ -SD | ❌ +  | `realtek-ambz` | `beken-72xx` +--------------------|----------------|------------- +Core functions | ✔️ | ✔️ +GPIO/PWM/IRQ | ✔️/✔️/✔️ | ❌/❌/❌ +Analog input | ✔️ | ❌ +UART I/O | ✔️ | ❌ +Flash I/O | ✔️ | ✔️ +**CORE LIBRARIES** | | +SoftwareSerial | ❌ | ❌ +SPI | ❌ | ❌ +Wire | ❗ | ❌ +**OTHER LIBRARIES** | | +Wi-Fi STA/AP/Mixed | ✔️ | ❌ +Wi-Fi Events | ✔️ | ❌ +TCP Client (SSL) | ✔️ (✔️) | ❌ +TCP Server | ✔️ | ❌ +IPv6 | ❌ | ❌ +HTTP Client (SSL) | ✔️ (✔️) | ❌ +HTTP Server | ✔️ | ❌ +NVS / Preferences | ❌ | ❌ +SPIFFS | ❌ | ❌ +BLE | - | ❌ +NTP | ❌ | ❌ +OTA | ✔️ | ❌ +MDNS | ✔️ | ❌ +MQTT | ✅ | ❌ +SD | ❌ | ❌ Symbols: diff --git a/arduino/beken-72xx/cores/arduino/Arduino.h b/arduino/beken-72xx/cores/arduino/Arduino.h new file mode 100644 index 0000000..cbea0ee --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/Arduino.h @@ -0,0 +1,15 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-14. */ + +#pragma once + +#ifdef __cplusplus +#include "WCharacterFixup.h" +#endif + +#include +#include + +// Include family-specific code +#include "WVariant.h" +// Include board variant +#include "variant.h" diff --git a/arduino/beken-72xx/cores/arduino/LibreTuyaAPI.cpp b/arduino/beken-72xx/cores/arduino/LibreTuyaAPI.cpp new file mode 100644 index 0000000..c500f27 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/LibreTuyaAPI.cpp @@ -0,0 +1,121 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */ + +#include + +// can't include as it collides with on Windows -_- +#define REG_FLASH_BASE 0x00803000 +#define REG_FLASH_OPERATE_SW (REG_FLASH_BASE + 0 * 4) +#define REG_FLASH_RDID (REG_FLASH_BASE + 4 * 4) +#define FLASH_BUSY_SW (0x01UL << 31) +#define FLASH_WP_VALUE (0x01UL << 30) +#define FLASH_OP_SW (0x01UL << 29) +#define FLASH_OP_TYPE_POS 24 +#define FLASH_OP_RDID 20 + +extern "C" { +#include +#include +#include +} + +void LibreTuya::restart() { + // TODO +} + +/* CPU-related */ + +ChipType LibreTuya::getChipType() { + uint8_t chipId = *(uint8_t *)(SCTRL_CHIP_ID); + return CHIP_TYPE_ENUM(FAMILY, chipId); +} + +const char *LibreTuya::getChipModel() { + return STRINGIFY_MACRO(MCU); +} + +uint32_t LibreTuya::getChipId() { + // TODO determine if this really is unique + uint32_t chipId = REG_READ(SCTRL_DEVICE_ID); + chipId &= 0xFFFFFF; + return chipId; +} + +uint8_t LibreTuya::getChipCores() { + return 1; +} + +const char *LibreTuya::getChipCoreType() { + return "ARM968E-S"; +} + +uint32_t LibreTuya::getCpuFreq() { + // TODO + return 0; +} + +uint32_t LibreTuya::getCycleCount() { + // TODO + return 0; +} + +/* Flash memory utilities */ + +FlashId LibreTuya::getFlashChipId() { + uint32_t data = (FLASH_OP_RDID << FLASH_OP_TYPE_POS) | FLASH_OP_SW | FLASH_WP_VALUE; + REG_WRITE(REG_FLASH_OPERATE_SW, data); + while (REG_READ(REG_FLASH_OPERATE_SW) & FLASH_BUSY_SW) {} + FlashId id = { + .manufacturerId = REG_RD8(REG_FLASH_RDID, 2), + .chipId = REG_RD8(REG_FLASH_RDID, 1), + .chipSizeId = REG_RD8(REG_FLASH_RDID, 0), + }; + return id; +} + +/* Memory management */ + +uint32_t LibreTuya::getRamSize() { + return 256 * 1024; +} + +uint32_t LibreTuya::getHeapSize() { + return configTOTAL_HEAP_SIZE; +} + +uint32_t LibreTuya::getFreeHeap() { + return xPortGetFreeHeapSize(); +} + +uint32_t LibreTuya::getMinFreeHeap() { + return xPortGetMinimumEverFreeHeapSize(); +} + +uint32_t LibreTuya::getMaxAllocHeap() { + return 0; +} + +/* OTA-related */ + +uint8_t LibreTuya::otaGetStoredIndex() { + return 1; +} + +bool LibreTuya::otaSupportsDual() { + return false; +} + +bool LibreTuya::otaHasImage1() { + return true; +} + +bool LibreTuya::otaHasImage2() { + return false; +} + +bool LibreTuya::otaSwitch(bool force) { + return true; +} + +/* Global instance */ + +LibreTuya LT; diff --git a/arduino/beken-72xx/cores/arduino/WVariant.h b/arduino/beken-72xx/cores/arduino/WVariant.h new file mode 100644 index 0000000..eede287 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/WVariant.h @@ -0,0 +1,14 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-18. */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_extern.h" +#include "sdk_mem.h" + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/arduino/beken-72xx/cores/arduino/main.cpp b/arduino/beken-72xx/cores/arduino/main.cpp new file mode 100644 index 0000000..4636345 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/main.cpp @@ -0,0 +1,25 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */ + +#include + +extern "C" { +#include +#include +} + +beken_thread_t mainThread; + +bool startMainTask() { + OSStatus ret = rtos_create_thread( + &mainThread, + THD_APPLICATION_PRIORITY, + "main", + (beken_thread_function_t)main_task, + 4096, + NULL + ); + if (ret != kNoErr) + return false; + vTaskStartScheduler(); + return true; +} diff --git a/arduino/beken-72xx/cores/arduino/sdk_extern.h b/arduino/beken-72xx/cores/arduino/sdk_extern.h new file mode 100644 index 0000000..dfec335 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/sdk_extern.h @@ -0,0 +1,19 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-18. */ + +#pragma once + +// for printf() etc (they are wrapped anyway) +#include + +// most stuff is here +#include +// for os_printf +#include +// for GPIO names +#include + +// conflict with stl_algobase.h +#undef min +#undef max + +extern unsigned char __disable_bk_printf; diff --git a/arduino/beken-72xx/cores/arduino/sdk_mem.h b/arduino/beken-72xx/cores/arduino/sdk_mem.h new file mode 100644 index 0000000..e61ab14 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/sdk_mem.h @@ -0,0 +1,20 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-18. */ + +#pragma once + +#include + +// Beken SDK is actually pretty good, in terms of declaring +// stdlib functions properly! So no need for any #define hell. +#include + +// All the MemMang functions are in stdlib, just wrapped +// during linking. +#include +// for memcpy etc. +#include + +// ...except zalloc, which is apparently not in the stdlib +#define zalloc os_zalloc + +#define LT_HEAP_FUNC xPortGetFreeHeapSize diff --git a/arduino/beken-72xx/cores/arduino/wiring.c b/arduino/beken-72xx/cores/arduino/wiring.c new file mode 100644 index 0000000..06345b2 --- /dev/null +++ b/arduino/beken-72xx/cores/arduino/wiring.c @@ -0,0 +1,21 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */ + +#include +#include +#include + +// TODO work out this conflicting with func/misc/target_util.c +/* void delay(unsigned long ms) { + rtos_delay_milliseconds(ms); +} */ + +void delayMicroseconds(unsigned int us) {} + +uint32_t millis() { + return xTaskGetTickCount() * portTICK_PERIOD_MS; +} + +void yield() { + vTaskDelay(1); + taskYIELD(); +} diff --git a/arduino/beken-72xx/port/flashdb/fal_flash_bk72xx_port.c b/arduino/beken-72xx/port/flashdb/fal_flash_bk72xx_port.c new file mode 100644 index 0000000..d0c0c68 --- /dev/null +++ b/arduino/beken-72xx/port/flashdb/fal_flash_bk72xx_port.c @@ -0,0 +1,45 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */ + +#include + +#include +#include + +#define FLASH_ERASE_MIN_SIZE (4 * 1024) + +extern uint32_t flash_ctrl(uint32_t cmd, void *param); + +static int init() { + __disable_bk_printf = 1; + flash_init(); + __disable_bk_printf = 0; + return 0; +} + +static int read(long offset, uint8_t *buf, size_t size) { + flash_read((char *)buf, size, offset); + return size; +} + +static int write(long offset, const uint8_t *buf, size_t size) { + flash_write((char *)buf, size, offset); + return size; +} + +static int erase(long offset, size_t size) { + size = ((size - 1) / FLASH_ERASE_MIN_SIZE) + 1; + for (uint16_t i = 0; i < size; i++) { + uint32_t addr = offset + i * FLASH_ERASE_MIN_SIZE; + flash_ctrl(CMD_FLASH_ERASE_SECTOR, &addr); + } + return size * FLASH_ERASE_MIN_SIZE; +} + +const struct fal_flash_dev flash0 = { + .name = FAL_FLASH_DEV_NAME, + .addr = 0x0, + .len = FLASH_LENGTH, + .blk_size = FLASH_ERASE_MIN_SIZE, + .ops = {init, read, write, erase}, + .write_gran = 1, +}; diff --git a/arduino/beken-72xx/port/printf/printf.c b/arduino/beken-72xx/port/printf/printf.c new file mode 100644 index 0000000..44d6d38 --- /dev/null +++ b/arduino/beken-72xx/port/printf/printf.c @@ -0,0 +1,11 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */ + +#include +#include + +// include bk_send_byte() +#include + +void putchar_(char c) { + uart_write_byte(uart_print_port, c); +} diff --git a/boards/_base/beken-72xx.json b/boards/_base/beken-72xx.json index 54d447b..81c093e 100644 --- a/boards/_base/beken-72xx.json +++ b/boards/_base/beken-72xx.json @@ -17,7 +17,8 @@ ] }, "frameworks": [ - "beken-72xx-sdk" + "beken-72xx-sdk", + "beken-72xx-arduino" ], "upload": { "maximum_ram_size": 262144, diff --git a/builder/frameworks/beken-72xx-arduino.py b/builder/frameworks/beken-72xx-arduino.py new file mode 100644 index 0000000..1880952 --- /dev/null +++ b/builder/frameworks/beken-72xx-arduino.py @@ -0,0 +1,28 @@ +# Copyright (c) Kuba Szczodrzyński 2022-06-14. + +from SCons.Script import DefaultEnvironment + +env = DefaultEnvironment() + +# SDK options +env.Replace( + LIB_BDK_DRIVER_SKIP=[ + # using printf library wrappers instead + "uart/printf.c", + ] +) + +env.SConscript("beken-72xx-sdk.py", exports="env") +env.SConscript("../arduino-common.py", exports="env") + +# Flags +env.Append( + CCFLAGS=[ + "-Wno-write-strings", + "-Wno-char-subscripts", + "-Wno-missing-braces", + ], +) + +# Build all libraries +env.BuildLibraries() diff --git a/builder/frameworks/beken-72xx-sdk.py b/builder/frameworks/beken-72xx-sdk.py index e0ed1cd..595b0b3 100644 --- a/builder/frameworks/beken-72xx-sdk.py +++ b/builder/frameworks/beken-72xx-sdk.py @@ -87,7 +87,6 @@ env.Append( "-marm", "-mthumb-interwork", "-g", - "-nostdlib", "-nostartfiles", "--specs=nano.specs", "-Wl,--gc-sections", @@ -104,6 +103,7 @@ env.Append( "-Wl,-wrap,snprintf", "-Wl,-wrap,sprintf", "-Wl,-wrap,vsnprintf", + # for disabling os_printf() output "-Wl,-wrap,bk_printf", ], ) diff --git a/docs/supported_families.md b/docs/supported_families.md index dae1bf1..fec0459 100644 --- a/docs/supported_families.md +++ b/docs/supported_families.md @@ -6,7 +6,7 @@ Realtek Ameba1 | `-` [Realtek AmebaZ](https://www.amebaiot.com/en/amebaz/) | `realtek-ambz` | `ambz` | `RTL8710B` (0x22E0D6FC) | ✔️ | `framework-realtek-amb1` ([amb1_sdk](https://github.com/ambiot/amb1_sdk)) Realtek AmebaZ2 | `-` | `-` | `RTL8720C` (0xE08F7564) | ❌ | - Realtek AmebaD | `-` | `-` | `RTL8720D` (0x3379CFE2) | ❌ | - -[Beken 7231T](http://www.bekencorp.com/en/goods/detail/cid/7.html) | `beken-7231t` (`beken-72xx`) | `bk7231t` (`bk72xx`) | `BK7231T` (0x675A40B0) | ❌ | `framework-beken-bdk` ([bdk_freertos](https://github.com/bekencorp/bdk_freertos)) +[Beken 7231T](http://www.bekencorp.com/en/goods/detail/cid/7.html) | `beken-7231t` (`beken-72xx`) | `bk7231t` (`bk72xx`) | `BK7231T` (0x675A40B0) | ✔️ | `framework-beken-bdk` ([bdk_freertos](https://github.com/bekencorp/bdk_freertos)) Beken 7231N | `-` | `-` | `BK7231N` (0x7B3EF230) | ❌ | - Boufallo 602 | `-` | `-` | `BL602` (0xDE1270B7) | ❌ | - Xradiotech 809 | `-` | `-` | `XR809` (0x51E903A8) | ❌ | - diff --git a/platform.json b/platform.json index 7f6113f..1d8cc10 100644 --- a/platform.json +++ b/platform.json @@ -26,6 +26,11 @@ "title": "Beken 72XX - SDK", "package": "framework-beken-bdk", "script": "builder/frameworks/beken-72xx-sdk.py" + }, + "beken-72xx-arduino": { + "title": "Beken 72XX - Arduino", + "package": "framework-beken-bdk", + "script": "builder/frameworks/beken-72xx-arduino.py" } }, "packages": { diff --git a/tools/util/models.py b/tools/util/models.py index ffa3df9..0365a52 100644 --- a/tools/util/models.py +++ b/tools/util/models.py @@ -32,7 +32,13 @@ class Family: def has_arduino_core(self) -> bool: if not self.name: return False - return isdir(join(dirname(__file__), "..", "..", "arduino", self.name)) + if isdir(join(dirname(__file__), "..", "..", "arduino", self.name)): + return True + if not self.parent: + return False + if isdir(join(dirname(__file__), "..", "..", "arduino", self.parent)): + return True + return False def dict(self) -> dict: return dict(