Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
159ffa76fd | ||
|
|
1ac3d30d84 | ||
|
|
631ef6ba59 | ||
|
|
27393e47c3 | ||
|
|
bd47772c04 | ||
|
|
f3871388ce | ||
|
|
62874bebf4 |
35
.github/workflows/lint.yml
vendored
35
.github/workflows/lint.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Lint check
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
lint-clang-format:
|
||||
name: Lint with clang-format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Check code with clang-format
|
||||
uses: jidicula/clang-format-action@v4.5.0
|
||||
with:
|
||||
clang-format-version: "14"
|
||||
lint-black:
|
||||
name: Lint with black
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: "3.9"
|
||||
- name: Install test dependencies
|
||||
uses: BSFishy/pip-action@v1
|
||||
with:
|
||||
packages: |
|
||||
black
|
||||
isort
|
||||
- name: Check code with black
|
||||
run: black --check .
|
||||
- name: Check code with isort
|
||||
run: isort --profile black . --check-only
|
||||
46
.github/workflows/platformio-publish.yml
vendored
46
.github/workflows/platformio-publish.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: PlatformIO Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v2
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install --upgrade platformio
|
||||
- name: Publish PlatformIO package
|
||||
run: pio package publish --non-interactive
|
||||
env:
|
||||
CI: true
|
||||
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
|
||||
- name: Get latest version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
name: ${{ steps.get_version.outputs.VERSION }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
12
.github/workflows/push-dev.yml
vendored
Normal file
12
.github/workflows/push-dev.yml
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
name: Push (dev), Pull Request
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
pull_request:
|
||||
jobs:
|
||||
lint-clang:
|
||||
name: Run Clang lint
|
||||
uses: kuba2k2/kuba2k2/.github/workflows/lint-clang.yml@master
|
||||
lint-python:
|
||||
name: Run Python lint
|
||||
uses: kuba2k2/kuba2k2/.github/workflows/lint-python.yml@master
|
||||
@@ -1,10 +1,8 @@
|
||||
name: Deploy docs on GitHub Pages
|
||||
|
||||
name: Push (master)
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
branches: ["master"]
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
docs:
|
||||
name: Deploy docs
|
||||
22
.github/workflows/release.yml
vendored
Normal file
22
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags: ["v*.*.*"]
|
||||
jobs:
|
||||
lint-clang:
|
||||
name: Run Clang lint
|
||||
uses: kuba2k2/kuba2k2/.github/workflows/lint-clang.yml@master
|
||||
publish-pio-platform:
|
||||
name: Publish PlatformIO platform
|
||||
needs:
|
||||
- lint-clang
|
||||
uses: kuba2k2/kuba2k2/.github/workflows/publish-pio-platform.yml@master
|
||||
secrets:
|
||||
PLATFORMIO_AUTH_TOKEN: ${{ secrets.PLATFORMIO_AUTH_TOKEN }}
|
||||
gh-release:
|
||||
name: Publish GitHub release
|
||||
needs:
|
||||
- publish-pio-platform
|
||||
uses: kuba2k2/kuba2k2/.github/workflows/gh-release.yml@master
|
||||
permissions:
|
||||
contents: write
|
||||
67
README.md
67
README.md
@@ -1,8 +1,10 @@
|
||||
# LibreTiny
|
||||
|
||||
<small>(formerly LibreTuya)</small>
|
||||
|
||||
<div align="center" markdown>
|
||||
|
||||
[](https://kuba2k2.github.io/libretiny/)
|
||||
[](https://docs.libretiny.eu/)
|
||||

|
||||
|
||||
[](.clang-format)
|
||||
@@ -16,12 +18,6 @@
|
||||
|
||||
</div>
|
||||
|
||||
## LibreTuya is now LibreTiny! 🎉
|
||||
|
||||
We have [renamed the project](https://github.com/kuba2k2/libretiny/issues/92) to LibreTiny, also marking the very first v1.0.0 release, along with a huge structure refactor. While some care has been taken to ensure that things don't break, you may still need to update some references in your code to use the new name.
|
||||
|
||||
---
|
||||
|
||||
PlatformIO development platform for IoT modules manufactured by Tuya Inc.
|
||||
|
||||
The main goal of this project is to provide a usable build environment for IoT developers. While also providing vendor SDKs as PlatformIO cores,
|
||||
@@ -32,62 +28,11 @@ which should make it easier to port/run existing ESP apps on less-common, unsupp
|
||||
|
||||
**Note:** this project is work-in-progress.
|
||||
|
||||
## Usage
|
||||
<div align="center" markdown>
|
||||
|
||||
1. [Install PlatformIO](https://platformio.org/platformio-ide)
|
||||
2. `platformio platform install -f https://github.com/kuba2k2/libretiny`
|
||||
3. Create a project, build it and upload!
|
||||
4. See the [docs](https://docs.libretiny.eu/) for any questions/problems.
|
||||
## [⭐ Getting started ⭐](https://docs.libretiny.eu/docs/getting-started/)
|
||||
|
||||
<!--
|
||||
## Arduino Core support status
|
||||
|
||||
Note: this list will probably change with each functionality update.
|
||||
|
||||
| `realtek-ambz` | `beken-72xx`
|
||||
--------------------|----------------|-------------
|
||||
Core functions | ✔️ | ✔️
|
||||
GPIO/PWM/IRQ | ✔️/✔️/✔️ | ✔️/✔️/✔️
|
||||
Analog input (ADC) | ✔️ | ✔️
|
||||
Serial | ✔️ | ✔️
|
||||
Serial (extra) | 0, 1, 2 | 1, 2
|
||||
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:
|
||||
|
||||
- ✔️ working
|
||||
- ✅ tested, external library
|
||||
- ❓ untested
|
||||
- ❗ broken
|
||||
- ❌ not implemented (yet?)
|
||||
- \- not applicable
|
||||
|
||||
Names:
|
||||
|
||||
- Core functions - stuff like delay(), millis(), yield(), etc.
|
||||
- **CORE LIBRARIES** - included normally in all Arduino cores
|
||||
- **OTHER LIBRARIES** - included in ESP32 core or downloadable
|
||||
-->
|
||||
</div>
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
* [Home](README.md)
|
||||
* [](SUMMARY.md)
|
||||
* [😊 Getting started](docs/getting-started/README.md)
|
||||
* [➡️ Info on accessing GPIOs](docs/getting-started/gpio.md)
|
||||
* [](SUMMARY.md)
|
||||
* [📺 Cloudcutter & ESPHome video guide](https://www.youtube.com/watch?v=sSj8f-HCHQ0)
|
||||
* [💡 ESPHome setup guide](docs/projects/esphome.md)
|
||||
* [🛖 ESPHome Hassio Add-On](https://github.com/libretiny-eu/esphome-hass-addon/pkgs/container/libretiny-esphome-hassio)
|
||||
* [](SUMMARY.md)
|
||||
* [📲 Flashing/dumping guide](docs/flashing/)
|
||||
* [🔌 How to flash/enter download mode?](docs/platform/)
|
||||
* [💻 Supported chips](docs/status/supported.md)
|
||||
* [](SUMMARY.md)
|
||||
* [💻 Chips, boards, features](docs/status/supported.md)
|
||||
* [All boards](boards/)
|
||||
* [](SUMMARY.md)
|
||||
* 🍪 Chip family docs & info
|
||||
|
||||
@@ -47,6 +47,10 @@ void SerialClass::configure(unsigned long baudrate, uint16_t config) {
|
||||
.flow_control = FLOW_CTRL_DISABLED,
|
||||
};
|
||||
|
||||
if (port == 1)
|
||||
uart1_init();
|
||||
else if (port == 2)
|
||||
uart2_init();
|
||||
uart_hw_set_change(port, &cfg);
|
||||
uart_rx_callback_set(port, callback, &BUF);
|
||||
|
||||
|
||||
@@ -6,4 +6,9 @@
|
||||
void lt_init_family() {
|
||||
// set default UART output port
|
||||
uart_print_port = LT_UART_DEFAULT_PORT - 1;
|
||||
// initialize the UART (needed e.g. after deep sleep)
|
||||
if (uart_print_port == 1)
|
||||
uart1_init();
|
||||
else if (uart_print_port == 2)
|
||||
uart2_init();
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ void lt_deep_sleep_config_gpio(uint32_t gpio_index_map, bool on_high) {
|
||||
deep_sleep_param.wake_up_way |= PS_DEEP_WAKEUP_GPIO;
|
||||
deep_sleep_param.gpio_index_map |= gpio_index_map;
|
||||
if (on_high) {
|
||||
deep_sleep_param.gpio_edge_map &= (~gpio_index_map);
|
||||
} else {
|
||||
deep_sleep_param.gpio_edge_map |= gpio_index_map;
|
||||
} else {
|
||||
deep_sleep_param.gpio_edge_map &= (~gpio_index_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-03. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned long total[2]; /*!< number of bytes processed */
|
||||
unsigned long state[4]; /*!< intermediate digest state */
|
||||
unsigned char buffer[64]; /*!< data block being processed */
|
||||
} md5_context;
|
||||
|
||||
#define LT_MD5_CTX_T md5_context
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -61,6 +61,10 @@ bool UpdateClass::begin(
|
||||
lt_ota_begin(this->ctx, size);
|
||||
this->ctx->callback = reinterpret_cast<void (*)(void *)>(progressHandler);
|
||||
this->ctx->callback_param = this;
|
||||
|
||||
this->md5Ctx = static_cast<LT_MD5_CTX_T *>(malloc(sizeof(LT_MD5_CTX_T)));
|
||||
MD5Init(this->md5Ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,6 +83,9 @@ bool UpdateClass::end(bool evenIfRemaining) {
|
||||
// abort if not finished
|
||||
this->errArd = UPDATE_ERROR_ABORT;
|
||||
|
||||
this->md5Digest = static_cast<uint8_t *>(malloc(16));
|
||||
MD5Final(this->md5Digest, this->md5Ctx);
|
||||
|
||||
this->cleanup(/* clearError= */ evenIfRemaining);
|
||||
return !this->hasError();
|
||||
}
|
||||
@@ -97,6 +104,10 @@ void UpdateClass::cleanup(bool clearError) {
|
||||
// activating firmware failed
|
||||
this->errArd = UPDATE_ERROR_ACTIVATE;
|
||||
this->errUf2 = UF2_ERR_OK;
|
||||
} else if (this->md5Digest && this->md5Expected && memcmp(this->md5Digest, this->md5Expected, 16) != 0) {
|
||||
// MD5 doesn't match
|
||||
this->errArd = UPDATE_ERROR_MD5;
|
||||
this->errUf2 = UF2_ERR_OK;
|
||||
} else if (clearError) {
|
||||
// successful finish and activation, clear error codes
|
||||
this->clearError();
|
||||
@@ -116,6 +127,12 @@ void UpdateClass::cleanup(bool clearError) {
|
||||
|
||||
free(this->ctx);
|
||||
this->ctx = nullptr;
|
||||
free(this->md5Ctx);
|
||||
this->md5Ctx = nullptr;
|
||||
free(this->md5Digest);
|
||||
this->md5Digest = nullptr;
|
||||
free(this->md5Expected);
|
||||
this->md5Expected = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +149,7 @@ size_t UpdateClass::write(const uint8_t *data, size_t len) {
|
||||
return 0;
|
||||
|
||||
size_t written = lt_ota_write(ctx, data, len);
|
||||
MD5Update(this->md5Ctx, data, len);
|
||||
if (written != len)
|
||||
this->cleanup(/* clearError= */ false);
|
||||
return written;
|
||||
@@ -171,6 +189,8 @@ size_t UpdateClass::writeStream(Stream &data) {
|
||||
// read data to fit in the remaining buffer space
|
||||
auto bufSize = this->ctx->buf_pos - this->ctx->buf;
|
||||
auto read = data.readBytes(this->ctx->buf_pos, UF2_BLOCK_SIZE - bufSize);
|
||||
// update MD5
|
||||
MD5Update(this->md5Ctx, this->ctx->buf_pos, read);
|
||||
// increment buffer writing head
|
||||
this->ctx->buf_pos += read;
|
||||
// process the block if complete
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MD5.h>
|
||||
#include <functional>
|
||||
#include <uf2ota/uf2ota.h>
|
||||
|
||||
@@ -56,6 +57,9 @@ class UpdateClass {
|
||||
UpdateClass &onProgress(THandlerFunction_Progress handler);
|
||||
static bool canRollBack();
|
||||
static bool rollBack();
|
||||
bool setMD5(const char *md5);
|
||||
String md5String();
|
||||
void md5(uint8_t *result);
|
||||
uint16_t getErrorCode() const;
|
||||
bool hasError() const;
|
||||
void clearError();
|
||||
@@ -71,6 +75,9 @@ class UpdateClass {
|
||||
uf2_err_t errUf2{UF2_ERR_OK};
|
||||
UpdateError errArd{UPDATE_ERROR_OK};
|
||||
THandlerFunction_Progress callback{nullptr};
|
||||
LT_MD5_CTX_T *md5Ctx{nullptr};
|
||||
uint8_t *md5Digest{nullptr};
|
||||
uint8_t *md5Expected{nullptr};
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -71,6 +71,41 @@ bool UpdateClass::rollBack() {
|
||||
return lt_ota_switch(/* revert= */ false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the expected MD5 of the firmware (hexadecimal string).
|
||||
*/
|
||||
bool UpdateClass::setMD5(const char *md5) {
|
||||
if (strlen(md5) != 32)
|
||||
return false;
|
||||
this->md5Expected = static_cast<uint8_t *>(malloc(16));
|
||||
if (!this->md5Expected)
|
||||
return false;
|
||||
lt_xtob(md5, 32, this->md5Expected);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a hexadecimal string of calculated firmware MD5 sum.
|
||||
*/
|
||||
String UpdateClass::md5String() {
|
||||
if (!this->md5Digest)
|
||||
return "";
|
||||
char out[32 + 1];
|
||||
lt_btox(this->md5Digest, 16, out);
|
||||
return String(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get calculated MD5 digest of the firmware.
|
||||
*/
|
||||
void UpdateClass::md5(uint8_t *result) {
|
||||
if (!this->md5Digest) {
|
||||
memset(result, '\0', 16);
|
||||
return;
|
||||
}
|
||||
memcpy(result, this->md5Digest, 16);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get combined error code of the update.
|
||||
*/
|
||||
|
||||
@@ -21,7 +21,7 @@ void lt_deep_sleep_unset_gpio(uint32_t gpio_index_map);
|
||||
|
||||
/**
|
||||
* @brief Set a sleep timer to wake up the device
|
||||
* @param sleep_duration the time in seconds to sleep
|
||||
* @param sleep_duration the time in milliseconds to sleep
|
||||
*/
|
||||
void lt_deep_sleep_config_timer(uint32_t sleep_duration);
|
||||
|
||||
|
||||
@@ -39,3 +39,36 @@ void hexdump(const uint8_t *buf, size_t len, uint32_t offset, uint8_t width) {
|
||||
pos += lineWidth;
|
||||
}
|
||||
}
|
||||
|
||||
char *lt_btox(const uint8_t *src, int len, char *dest) {
|
||||
// https://stackoverflow.com/a/53966346
|
||||
const char hex[] = "0123456789abcdef";
|
||||
len *= 2;
|
||||
dest[len] = '\0';
|
||||
while (--len >= 0)
|
||||
dest[len] = hex[(src[len >> 1] >> ((1 - (len & 1)) << 2)) & 0xF];
|
||||
return dest;
|
||||
}
|
||||
|
||||
uint8_t *lt_xtob(const char *src, int len, uint8_t *dest) {
|
||||
// https://gist.github.com/vi/dd3b5569af8a26b97c8e20ae06e804cb
|
||||
|
||||
// mapping of ASCII characters to hex values
|
||||
// (16-byte swapped to reduce XOR 0x10 operation)
|
||||
const uint8_t mapping[] = {
|
||||
0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // @ABCDEFG
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // HIJKLMNO
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 01234567
|
||||
0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 89:;<=>?
|
||||
};
|
||||
|
||||
int j = 0;
|
||||
uint8_t idx0;
|
||||
uint8_t idx1;
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
idx0 = ((uint8_t)src[i + 0] & 0x1F);
|
||||
idx1 = ((uint8_t)src[i + 1] & 0x1F);
|
||||
dest[j++] = (mapping[idx0] << 4) | (mapping[idx1] << 0);
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
@@ -45,3 +45,23 @@ void hexdump(
|
||||
uint8_t width
|
||||
#endif
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Convert a byte array to hexadecimal string.
|
||||
*
|
||||
* @param src source byte array
|
||||
* @param len source length (bytes)
|
||||
* @param dest destination string
|
||||
* @return destination string
|
||||
*/
|
||||
char *lt_btox(const uint8_t *src, int len, char *dest);
|
||||
|
||||
/**
|
||||
* @brief Convert a hexadecimal string to byte array.
|
||||
*
|
||||
* @param src source string
|
||||
* @param len source length (chars)
|
||||
* @param dest destination byte array
|
||||
* @return destination byte array
|
||||
*/
|
||||
uint8_t *lt_xtob(const char *src, int len, uint8_t *dest);
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Implementation status
|
||||
|
||||
{%
|
||||
include-markdown "../../README.md"
|
||||
start="\n## Arduino Core support status\n"
|
||||
end="\n## License\n"
|
||||
%}
|
||||
@@ -26,12 +26,49 @@ A list of chip families currently supported by this project.
|
||||
!!! note
|
||||
The term *family* was chosen over *platform*, in order to reduce possible confusion between LibreTiny supported "platforms" and PlatformIO's "platform", as an entire package. *Family* is also more compatible with the UF2 term.
|
||||
|
||||
The following list corresponds to UF2 OTA format family names, and is also [available as JSON](../../families.json). The IDs are also present in [lt_types.h](../../ltapi/lt__types_8h.md).
|
||||
The following list corresponds to UF2 OTA format family names, and is also [available as JSON](../../families.json). The IDs are also present in [lt_types.h](../../ltapi/lt__types_8h.md). You can view the family list by using `ltchiptool list families`.
|
||||
|
||||
{%
|
||||
include-markdown "./supported_families.md"
|
||||
%}
|
||||
|
||||
## Feature support
|
||||
|
||||
If you notice a feature that you've tested, which works (or not) and doesn't match this table, feel free to submit an issue on GitHub.
|
||||
|
||||
| `BK7231T` | `BK7231N` | `RTL8710B` | `RTL8720C` | `BK7231Q`
|
||||
-------------------------|-----------|-----------|------------|------------|----------
|
||||
Stability | 5/5 | 5/5 | 4/5 | 2/5 | 1/5
|
||||
LibreTiny Core | ✔️ | ✔️ | ✔️ | ✔️ | ✔️
|
||||
Wiring Core | ✔️ | ✔️ | ✔️ | ✔️ | ✔️
|
||||
**PERIPHERALS** (Core) | | | | |
|
||||
UART I/O | ✔️ | ✔️ | ✔️ | ✔️ | ✔️
|
||||
Flash I/O | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
Deep sleep | ❓ | ✔️ | ❌ | ❌ | ❓
|
||||
Watchdog timer | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
**PERIPHERALS** (Wiring) | | | | |
|
||||
Digital I/O | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
PWM | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
Interrupts | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
Analog input (ADC) | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
`Wire` (I²C) | ❌ | ❌ | ❗ | ❌ | ❌
|
||||
`SPI` | ❌ | ❌ | ❌ | ❌ | ❌
|
||||
`Serial` | ✔️ | ✔️ | ✔️ | ✔️ | ❓
|
||||
`SoftwareSerial` | ❌ | ❌ | ✔️ | ❌ | ❌
|
||||
**NETWORKING** | | | | |
|
||||
Wi-Fi STA/AP/Mixed | ✔️ | ✔️ | ✔️ | ❓ | ❌
|
||||
Wi-Fi Events | ✔️ | ✔️ | ✔️ | ❓ | ❌
|
||||
OTA updates | ✔️ | ✔️ | ✔️ | ❌ | ❌
|
||||
MDNS | ✔️ | ✔️ | ✔️ | ❓ | ❓
|
||||
|
||||
Symbols:
|
||||
|
||||
- ✔️ working
|
||||
- ❓ untested
|
||||
- ❗ broken
|
||||
- ❌ not implemented (yet?)
|
||||
- \- not applicable
|
||||
|
||||
## Unsupported boards
|
||||
|
||||
### Tuya Inc.
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
"description": "PlatformIO development platform for IoT modules",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kuba2k2/platformio-libretiny"
|
||||
"url": "https://github.com/kuba2k2/libretiny.git"
|
||||
},
|
||||
"version": "1.2.1",
|
||||
"version": "1.3.0",
|
||||
"frameworks": {
|
||||
"base": {
|
||||
"title": "Base Framework (SDK only)",
|
||||
|
||||
Reference in New Issue
Block a user