Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
159ffa76fd | ||
|
|
1ac3d30d84 | ||
|
|
631ef6ba59 | ||
|
|
27393e47c3 | ||
|
|
bd47772c04 | ||
|
|
f3871388ce | ||
|
|
62874bebf4 | ||
|
|
2ca368305c | ||
|
|
f697ae6f11 | ||
|
|
ef6dd35977 | ||
|
|
ccf21b4eab | ||
|
|
e99c6124e7 | ||
|
|
5721bd74d7 | ||
|
|
ff443ca488 | ||
|
|
93e0a5d066 | ||
|
|
150c2ef26d | ||
|
|
4d81fcac26 | ||
|
|
a3bbdf1c16 | ||
|
|
39df2e7b54 | ||
|
|
6169f68119 | ||
|
|
e38e53bac0 | ||
|
|
b38a4d5d46 | ||
|
|
96412624d9 | ||
|
|
74659901c0 | ||
|
|
73ede2838c | ||
|
|
e2794d5f84 | ||
|
|
e7f35c584b | ||
|
|
1e49c3ff6f | ||
|
|
e256ac8e46 | ||
|
|
9c6e9d1525 | ||
|
|
41985e5743 | ||
|
|
f1e41f7cc1 | ||
|
|
6135e4f7b0 | ||
|
|
af8c7417b3 | ||
|
|
babdb1287f | ||
|
|
4532c88873 | ||
|
|
bc1b83d931 | ||
|
|
87ad0798e4 | ||
|
|
a80032d46c | ||
|
|
4dae304f51 | ||
|
|
9b7d34fa65 | ||
|
|
c0cc602c9a | ||
|
|
e5f98ff41f | ||
|
|
bc74c21599 | ||
|
|
3836ad20b7 | ||
|
|
b073290989 | ||
|
|
43c9d0db10 | ||
|
|
c40bdd68af | ||
|
|
620e457eb6 | ||
|
|
8c636e44f7 | ||
|
|
07e9aa1ded |
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
|
||||
@@ -25,7 +23,8 @@ jobs:
|
||||
run: |
|
||||
mkdir -p site/
|
||||
boardgen ltci
|
||||
python docs/scripts/update_docs.py
|
||||
python docs/scripts/write_boards.py
|
||||
python docs/scripts/write_apis.py
|
||||
python docs/scripts/prepare_doxygen.py
|
||||
python docs/scripts/build_json.py
|
||||
cp *.json site/
|
||||
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
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -264,3 +264,5 @@ docs/status/supported_*.md
|
||||
docs/status/unsupported_boards_*.md
|
||||
boards/**/*.svg
|
||||
boards/**/*.md
|
||||
# other generated files
|
||||
docs/contrib/lt-api-functions.md
|
||||
|
||||
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
|
||||
|
||||
|
||||
21
SUMMARY.md
21
SUMMARY.md
@@ -1,11 +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 connect the chip in download mode?](docs/flashing/chip-connection/)
|
||||
* [💻 Supported chips](docs/status/supported.md)
|
||||
* [🔌 How to flash/enter download mode?](docs/platform/)
|
||||
* [](SUMMARY.md)
|
||||
* [💻 Chips, boards, features](docs/status/supported.md)
|
||||
* [All boards](boards/)
|
||||
* [](SUMMARY.md)
|
||||
* 🍪 Chip family docs & info
|
||||
@@ -47,10 +51,13 @@
|
||||
* [Macros](ltapi/macros.md)
|
||||
* [File list](ltapi/files.md)
|
||||
* 👷 Contributor's manual (WIP)
|
||||
* [📁 Project structure](docs/dev/project-structure.md)
|
||||
* [✈️ OTA format](docs/dev/ota/README.md)
|
||||
* [uf2ota.py tool](docs/dev/ota/uf2ota.md)
|
||||
* [uf2ota.h library](docs/dev/ota/library.md)
|
||||
* [Porting new families](docs/contrib/porting.md)
|
||||
* [API functions guide](docs/contrib/lt-api.md)
|
||||
* [C standard library](docs/contrib/stdlib.md)
|
||||
* [📁 Project structure](docs/contrib/project-structure.md)
|
||||
* [✈️ OTA format](docs/contrib/ota/README.md)
|
||||
* [uf2ota.py tool](docs/contrib/ota/uf2ota.md)
|
||||
* [uf2ota.h library](docs/contrib/ota/library.md)
|
||||
* [📓 TODO](docs/TODO.md)
|
||||
* [](SUMMARY.md)
|
||||
* [🔗 Resources](docs/resources/)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"build": {
|
||||
"bkcrypt_coeffs": "510fb093a3cbeadc5993a17ec7adeb03"
|
||||
},
|
||||
"flash": {
|
||||
"tuya": "0x1ED000+0x13000"
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,7 @@
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"General info": "../../docs/platform/beken-72xx/README.md",
|
||||
"Flashing guide": "../../docs/platform/beken-72xx/flashing.md"
|
||||
"Info & flashing guide": "../../docs/platform/beken-72xx/README.md"
|
||||
},
|
||||
"extra": [
|
||||
"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."
|
||||
|
||||
@@ -2,14 +2,9 @@
|
||||
"pcb": {
|
||||
"templates": [
|
||||
"esp12s",
|
||||
"esp12s-shield",
|
||||
"pcb-black",
|
||||
"rf-type1"
|
||||
],
|
||||
"vars": {
|
||||
"MASK_PRESET": "mask_black",
|
||||
"TRACE_COLOR": "#FAFD9D",
|
||||
"SILK_COLOR": "white"
|
||||
},
|
||||
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD",
|
||||
"pinout": {
|
||||
"1": {
|
||||
|
||||
44
boards/_base/pcb/wr2-test.json
Normal file
44
boards/_base/pcb/wr2-test.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"pcb": {
|
||||
"back": [
|
||||
{
|
||||
"comment": "RXD Pad",
|
||||
"name": "test_pad_1mm",
|
||||
"pos": "5.4,14.5"
|
||||
},
|
||||
{
|
||||
"comment": "TXD Pad",
|
||||
"name": "test_pad_1mm",
|
||||
"pos": "5.4,13.2"
|
||||
},
|
||||
{
|
||||
"comment": "RXD Pad label",
|
||||
"id": "rxd",
|
||||
"name": "label_line_up",
|
||||
"pos": "4.6,14.6",
|
||||
"vars": {
|
||||
"DIR": "left",
|
||||
"RASTER": 2,
|
||||
"W": 2.1,
|
||||
"H": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "TXD Pad label",
|
||||
"id": "txd",
|
||||
"name": "label_line_up",
|
||||
"pos": "5.4,12.4",
|
||||
"vars": {
|
||||
"DIR": "left",
|
||||
"RASTER": 2,
|
||||
"W": 2.7,
|
||||
"H": 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"test_pads": {
|
||||
"TRX2": "wr2.back.rxd.anchor",
|
||||
"TTX2": "wr2.back.txd.anchor"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,14 @@
|
||||
"11": {
|
||||
"IC": 14,
|
||||
"ARD": "D7"
|
||||
},
|
||||
"TTX2": {
|
||||
"IC": 1,
|
||||
"ARD": "D8"
|
||||
},
|
||||
"TRX2": {
|
||||
"IC": 2,
|
||||
"ARD": "D9"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
44
boards/_base/pcb/wr2e-test.json
Normal file
44
boards/_base/pcb/wr2e-test.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"pcb": {
|
||||
"back": [
|
||||
{
|
||||
"comment": "RXD Pad",
|
||||
"name": "test_pad_1mm",
|
||||
"pos": "5.4,14.5"
|
||||
},
|
||||
{
|
||||
"comment": "TXD Pad",
|
||||
"name": "test_pad_1mm",
|
||||
"pos": "5.4,13.2"
|
||||
},
|
||||
{
|
||||
"comment": "RXD Pad label",
|
||||
"id": "rxd",
|
||||
"name": "label_line_up",
|
||||
"pos": "4.6,14.6",
|
||||
"vars": {
|
||||
"DIR": "left",
|
||||
"RASTER": 2,
|
||||
"W": 2.1,
|
||||
"H": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"comment": "TXD Pad label",
|
||||
"id": "txd",
|
||||
"name": "label_line_up",
|
||||
"pos": "5.4,12.4",
|
||||
"vars": {
|
||||
"DIR": "left",
|
||||
"RASTER": 2,
|
||||
"W": 2.7,
|
||||
"H": 0.5
|
||||
}
|
||||
}
|
||||
],
|
||||
"test_pads": {
|
||||
"TRX2": "wr2e.back.rxd.anchor",
|
||||
"TTX2": "wr2e.back.txd.anchor"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,14 @@
|
||||
"11": {
|
||||
"IC": 14,
|
||||
"ARD": "D6"
|
||||
},
|
||||
"TTX2": {
|
||||
"IC": 1,
|
||||
"ARD": "D7"
|
||||
},
|
||||
"TRX2": {
|
||||
"IC": 2,
|
||||
"ARD": "D8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
"flash": {
|
||||
"ota1": "0x00B000+0x75000",
|
||||
"ota2": "0x080000+0x75000",
|
||||
"kvs": "0xF5000+0x6000",
|
||||
"userdata": "0xFB000+0x104000",
|
||||
"rdp": "0x1FF000+0x1000"
|
||||
"kvs": "0x0F5000+0x8000",
|
||||
"userdata": "0x0FD000+0x102000"
|
||||
},
|
||||
"upload": {
|
||||
"flash_size": 2097152,
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
"flash": {
|
||||
"ota1": "0x00B000+0xC5000",
|
||||
"ota2": "0x0D0000+0xC5000",
|
||||
"kvs": "0x195000+0x6000",
|
||||
"userdata": "0x19B000+0x64000",
|
||||
"rdp": "0x1FF000+0x1000"
|
||||
"kvs": "0x195000+0x8000",
|
||||
"userdata": "0x19D000+0x62000"
|
||||
},
|
||||
"upload": {
|
||||
"flash_size": 2097152,
|
||||
|
||||
@@ -6,8 +6,7 @@
|
||||
"ota1": "0x00B000+0xF5000",
|
||||
"ota2": "0x100000+0xF5000",
|
||||
"kvs": "0x1F5000+0x8000",
|
||||
"userdata": "0x1FD000+0x202000",
|
||||
"rdp": "0x3FF000+0x1000"
|
||||
"userdata": "0x1FD000+0x202000"
|
||||
},
|
||||
"upload": {
|
||||
"flash_size": 4194304,
|
||||
|
||||
5
boards/_base/realtek-ambz-tuya.json
Normal file
5
boards/_base/realtek-ambz-tuya.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"flash": {
|
||||
"tuya": "0x1EB000+0x15000"
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,8 @@
|
||||
"boot_xip": "0x000000+0x4000",
|
||||
"boot_ram": "0x004000+0x4000",
|
||||
"system": "0x009000+0x1000",
|
||||
"calibration": "0x00A000+0x1000"
|
||||
"calibration": "0x00A000+0x1000",
|
||||
"rdp": "0x1FF000+0x1000"
|
||||
},
|
||||
"connectivity": [
|
||||
"wifi"
|
||||
@@ -44,13 +45,8 @@
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"General info": "../../docs/platform/realtek-amb/README.md",
|
||||
"Flashing guide": "../../docs/platform/realtek-ambz/flashing.md",
|
||||
"Info & flashing guide": "../../docs/platform/realtek-ambz/README.md",
|
||||
"Debugging": "../../docs/platform/realtek-ambz/debugging.md"
|
||||
},
|
||||
"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.",
|
||||
"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."
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
boards/_base/realtek-ambz2-2mb-900k.json
Normal file
12
boards/_base/realtek-ambz2-2mb-900k.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"flash": {
|
||||
"ota1": "0x010000+0xE0000",
|
||||
"ota2": "0x0F0000+0xE0000",
|
||||
"kvs": "0x1D0000+0x8000",
|
||||
"userdata": "0x1D8000+0x28000"
|
||||
},
|
||||
"upload": {
|
||||
"flash_size": 2097152,
|
||||
"maximum_size": 917504
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,7 @@
|
||||
"flash": {
|
||||
"ota1": "0x00C000+0xF8000",
|
||||
"ota2": "0x104000+0xF8000",
|
||||
"kvs": "0x1FC000+0x2000",
|
||||
"userdata": "0x1FE000+0x2000"
|
||||
"kvs": "0x1FC000+0x4000"
|
||||
},
|
||||
"upload": {
|
||||
"flash_size": 2097152,
|
||||
|
||||
96
boards/_base/realtek-ambz2-image.json
Normal file
96
boards/_base/realtek-ambz2-image.json
Normal file
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"image": {
|
||||
"keys": {
|
||||
"decryption": "a0d6dae7e062ca94cbb294bf896b9f68cf8438774256ac7403ca4fd9a1c9564f",
|
||||
"keyblock": {
|
||||
"part_table": "882aa16c8c44a7760aa8c9ab22e3568c6fa16c2afa4f0cea29a10abcdf60e44f",
|
||||
"boot": "882aa16c8c44a7760aa8c9ab22e3568c6fa16c2afa4f0cea29a10abcdf60e44f"
|
||||
},
|
||||
"hash_keys": {
|
||||
"part_table": "47e5661335a4c5e0a94d69f3c737d54f2383791332939753ef24279608f6d72b",
|
||||
"boot": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"ota1": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e5f",
|
||||
"ota2": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e5f"
|
||||
},
|
||||
"user_keys": {
|
||||
"boot": "aa0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"ota1": "bb0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
|
||||
"ota2": "bb0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
|
||||
},
|
||||
"xip_sce_key": "a0d6dae7e062ca94cbb294bf896b9f68",
|
||||
"xip_sce_iv": "94879487948794879487948794879487"
|
||||
},
|
||||
"ptable": {
|
||||
"boot": "BOOT",
|
||||
"ota1": "FW1",
|
||||
"ota2": "FW2"
|
||||
},
|
||||
"boot": {
|
||||
"name": "boot.sram",
|
||||
"type": "SRAM",
|
||||
"entry": "__ram_start_table_start__",
|
||||
"elf": [
|
||||
".ram.func.table",
|
||||
".data",
|
||||
".ram.code_text",
|
||||
".ram.code_rodata"
|
||||
],
|
||||
"is_boot": true
|
||||
},
|
||||
"fw": [
|
||||
{
|
||||
"type": "FWHS_S",
|
||||
"sections": [
|
||||
{
|
||||
"name": "fwhs.sram",
|
||||
"type": "SRAM",
|
||||
"entry": "__ram_start_table_start__",
|
||||
"elf": [
|
||||
".ram.img.signature",
|
||||
".ram.func.table",
|
||||
".data",
|
||||
".ram.code_text",
|
||||
".ram.code_rodata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "fwhs.psram",
|
||||
"type": "PSRAM",
|
||||
"entry": "__psram_start__",
|
||||
"elf": [
|
||||
".psram.data",
|
||||
".psram.code_text",
|
||||
".psram.code_rodata"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "XIP",
|
||||
"sections": [
|
||||
{
|
||||
"name": "fwhs.xip_c",
|
||||
"entry": "XIP_RamImgSignature_s",
|
||||
"type": "XIP",
|
||||
"elf": [
|
||||
".xip.code_c"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "XIP",
|
||||
"sections": [
|
||||
{
|
||||
"name": "fwhs.xip_p",
|
||||
"entry": "__xip_code_rodata_start__",
|
||||
"type": "XIP",
|
||||
"elf": [
|
||||
".xip.code_p"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
5
boards/_base/realtek-ambz2-tuya.json
Normal file
5
boards/_base/realtek-ambz2-tuya.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"flash": {
|
||||
"tuya": "0x1D5000+0x10000"
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,20 @@
|
||||
},
|
||||
"debug": {
|
||||
"protocol": "openocd",
|
||||
"protocols": []
|
||||
"protocols": [
|
||||
"openocd"
|
||||
],
|
||||
"openocd_config": "amebaz2.cfg",
|
||||
"gdb_init": [
|
||||
"mem 0x9b000000 0x9c000000 ro"
|
||||
]
|
||||
},
|
||||
"upload": {
|
||||
"maximum_ram_size": 262144
|
||||
"maximum_ram_size": 262144,
|
||||
"protocol": "uart",
|
||||
"protocols": [
|
||||
"uart"
|
||||
]
|
||||
},
|
||||
"doc": {
|
||||
"params": {
|
||||
|
||||
26
boards/bw15.json
Normal file
26
boards/bw15.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz2",
|
||||
"realtek-ambz2-8720",
|
||||
"realtek-ambz2-image",
|
||||
"realtek-ambz2-2mb-992k",
|
||||
"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": {
|
||||
"fccid": "2AXVG-BW15",
|
||||
"links": {
|
||||
"Vendor datasheet": "https://docs.ai-thinker.com/_media/rtl8710/docs/bw15_datasheet_en.pdf"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb1s",
|
||||
"pcb/cb1s-test"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb2l",
|
||||
"pcb/cb2l-test"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb2s",
|
||||
"pcb/cb2s-test"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb3l"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb3s"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cb3se"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cblc5",
|
||||
"pcb/cblc5-test"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/cbu",
|
||||
"pcb/cbu-test"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"generic",
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32"
|
||||
],
|
||||
"build": {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32"
|
||||
],
|
||||
"build": {
|
||||
|
||||
102
boards/generic-rtl8720cf-2mb-992k.json
Normal file
102
boards/generic-rtl8720cf-2mb-992k.json
Normal file
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"_base": [
|
||||
"generic",
|
||||
"realtek-ambz2",
|
||||
"realtek-ambz2-8720",
|
||||
"realtek-ambz2-image",
|
||||
"realtek-ambz2-2mb-992k",
|
||||
"ic/rtl8720cf"
|
||||
],
|
||||
"build": {
|
||||
"mcu": "rtl8720cf",
|
||||
"variant": "generic-rtl8720cf-2mb-992k"
|
||||
},
|
||||
"name": "Generic - RTL8720CF (2M/992k)",
|
||||
"symbol": "RTL8720CF (2M/992k)",
|
||||
"url": "https://docs.libretiny.eu/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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/lsc-lma35"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/lsc-lma35"
|
||||
],
|
||||
|
||||
@@ -22,6 +22,10 @@ PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
|
||||
{PA_14, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
|
||||
// D7: PA15, PWM1, SWDIO
|
||||
{PA_15, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
|
||||
// D8: PA30, UART2_TX, I2C0_SDA, PWM4
|
||||
{PA_30, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
|
||||
// D9: PA29, UART2_RX, I2C0_SCL, PWM4
|
||||
{PA_29, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
|
||||
// A1: ADC2
|
||||
{AD_2, PIN_ADC, PIN_NONE, 0},
|
||||
};
|
||||
@@ -34,6 +38,8 @@ PinInfo *lt_arduino_pin_gpio_map[] = {
|
||||
[15] = &(lt_arduino_pin_info_list[6]), // PA_15 (D7)
|
||||
[18] = &(lt_arduino_pin_info_list[3]), // PA_18 (D4)
|
||||
[23] = &(lt_arduino_pin_info_list[4]), // PA_23 (D5)
|
||||
[41] = &(lt_arduino_pin_info_list[7]), // AD_2 (A1)
|
||||
[29] = &(lt_arduino_pin_info_list[8]), // PA_29 (D9)
|
||||
[30] = &(lt_arduino_pin_info_list[7]), // PA_30 (D8)
|
||||
[41] = &(lt_arduino_pin_info_list[9]), // AD_2 (A1)
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -6,14 +6,16 @@
|
||||
|
||||
// Pins
|
||||
// ----
|
||||
#define PINS_COUNT 8 // Total GPIO count
|
||||
#define NUM_DIGITAL_PINS 7 // Digital inputs/outputs
|
||||
#define PINS_COUNT 10 // Total GPIO count
|
||||
#define NUM_DIGITAL_PINS 9 // Digital inputs/outputs
|
||||
#define NUM_ANALOG_INPUTS 1 // ADC inputs
|
||||
#define NUM_ANALOG_OUTPUTS 6 // PWM & DAC outputs
|
||||
#define NUM_ANALOG_OUTPUTS 8 // PWM & DAC outputs
|
||||
#define PINS_GPIO_MAX 41 // Last usable GPIO number
|
||||
|
||||
// Wire Interfaces
|
||||
// ---------------
|
||||
#define PIN_WIRE0_SCL 29u // PA_29
|
||||
#define PIN_WIRE0_SDA 30u // PA_30
|
||||
#define PIN_WIRE1_SCL 18u // PA_18
|
||||
#define PIN_WIRE1_SDA 23u // PA_23
|
||||
|
||||
@@ -21,6 +23,8 @@
|
||||
// ------------
|
||||
#define PIN_SERIAL0_RX 18u // PA_18
|
||||
#define PIN_SERIAL0_TX 23u // PA_23
|
||||
#define PIN_SERIAL2_RX 29u // PA_29
|
||||
#define PIN_SERIAL2_TX 30u // PA_30
|
||||
|
||||
// Pin function macros
|
||||
// -------------------
|
||||
@@ -34,24 +38,32 @@
|
||||
#define PIN_PA15 15u // PA_15
|
||||
#define PIN_PA18 18u // PA_18
|
||||
#define PIN_PA23 23u // PA_23
|
||||
#define PIN_PA29 29u // PA_29
|
||||
#define PIN_PA30 30u // PA_30
|
||||
#define PIN_PWM0 14u // PA_14
|
||||
#define PIN_PWM1 15u // PA_15
|
||||
#define PIN_PWM2 0u // PA_0
|
||||
#define PIN_PWM3 12u // PA_12
|
||||
#define PIN_PWM4 5u // PA_5
|
||||
#define PIN_PWM4 29u // PA_29
|
||||
#define PIN_RX0 18u // PA_18
|
||||
#define PIN_RX2 29u // PA_29
|
||||
#define PIN_SCK0 18u // PA_18
|
||||
#define PIN_SCK1 18u // PA_18
|
||||
#define PIN_SCL0 29u // PA_29
|
||||
#define PIN_SCL1 18u // PA_18
|
||||
#define PIN_SDA0 30u // PA_30
|
||||
#define PIN_SDA1 23u // PA_23
|
||||
#define PIN_TX0 23u // PA_23
|
||||
#define PIN_TX2 30u // PA_30
|
||||
|
||||
// Port availability
|
||||
// -----------------
|
||||
#define HAS_SERIAL0 1
|
||||
#define HAS_SERIAL2 1
|
||||
#define HAS_WIRE0 1
|
||||
#define HAS_WIRE1 1
|
||||
#define SERIAL_INTERFACES_COUNT 1
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
#define SERIAL_INTERFACES_COUNT 2
|
||||
#define WIRE_INTERFACES_COUNT 2
|
||||
|
||||
// Arduino pin names
|
||||
// -----------------
|
||||
@@ -62,6 +74,8 @@
|
||||
#define PIN_D5 23u // PA_23
|
||||
#define PIN_D6 14u // PA_14
|
||||
#define PIN_D7 15u // PA_15
|
||||
#define PIN_D8 30u // PA_30
|
||||
#define PIN_D9 29u // PA_29
|
||||
#define PIN_A1 41u // AD_2
|
||||
|
||||
// Static pin names
|
||||
@@ -74,3 +88,5 @@ static const unsigned char D4 = PIN_D4;
|
||||
static const unsigned char D5 = PIN_D5;
|
||||
static const unsigned char D6 = PIN_D6;
|
||||
static const unsigned char D7 = PIN_D7;
|
||||
static const unsigned char D8 = PIN_D8;
|
||||
static const unsigned char D9 = PIN_D9;
|
||||
|
||||
@@ -22,6 +22,10 @@ PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
|
||||
{PA_14, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
|
||||
// D6: PA15, PWM1, SWDIO
|
||||
{PA_15, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
|
||||
// D7: PA30, UART2_TX, I2C0_SDA, PWM4
|
||||
{PA_30, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
|
||||
// D8: PA29, UART2_RX, I2C0_SCL, PWM4
|
||||
{PA_29, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
|
||||
// A1: ADC2
|
||||
{AD_2, PIN_ADC, PIN_NONE, 0},
|
||||
};
|
||||
@@ -34,6 +38,8 @@ PinInfo *lt_arduino_pin_gpio_map[] = {
|
||||
[18] = &(lt_arduino_pin_info_list[3]), // PA_18 (D3)
|
||||
[19] = &(lt_arduino_pin_info_list[1]), // PA_19 (D1)
|
||||
[23] = &(lt_arduino_pin_info_list[4]), // PA_23 (D4)
|
||||
[41] = &(lt_arduino_pin_info_list[7]), // AD_2 (A1)
|
||||
[29] = &(lt_arduino_pin_info_list[8]), // PA_29 (D8)
|
||||
[30] = &(lt_arduino_pin_info_list[7]), // PA_30 (D7)
|
||||
[41] = &(lt_arduino_pin_info_list[9]), // AD_2 (A1)
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -6,22 +6,27 @@
|
||||
|
||||
// Pins
|
||||
// ----
|
||||
#define PINS_COUNT 8 // Total GPIO count
|
||||
#define NUM_DIGITAL_PINS 7 // Digital inputs/outputs
|
||||
#define PINS_COUNT 10 // Total GPIO count
|
||||
#define NUM_DIGITAL_PINS 9 // Digital inputs/outputs
|
||||
#define NUM_ANALOG_INPUTS 2 // ADC inputs
|
||||
#define NUM_ANALOG_OUTPUTS 5 // PWM & DAC outputs
|
||||
#define NUM_ANALOG_OUTPUTS 7 // PWM & DAC outputs
|
||||
#define PINS_GPIO_MAX 41 // Last usable GPIO number
|
||||
|
||||
// Wire Interfaces
|
||||
// ---------------
|
||||
#define PIN_WIRE1_SCL 18u // PA_18
|
||||
#define PIN_WIRE1_SDA 23u // PA_23
|
||||
#define PIN_WIRE0_SCL 29u // PA_29
|
||||
#define PIN_WIRE0_SDA_0 19u // PA_19
|
||||
#define PIN_WIRE0_SDA_1 30u // PA_30
|
||||
#define PIN_WIRE1_SCL 18u // PA_18
|
||||
#define PIN_WIRE1_SDA 23u // PA_23
|
||||
|
||||
// Serial ports
|
||||
// ------------
|
||||
#define PIN_SERIAL0_CTS 19u // PA_19
|
||||
#define PIN_SERIAL0_RX 18u // PA_18
|
||||
#define PIN_SERIAL0_TX 23u // PA_23
|
||||
#define PIN_SERIAL2_RX 29u // PA_29
|
||||
#define PIN_SERIAL2_TX 30u // PA_30
|
||||
|
||||
// Pin function macros
|
||||
// -------------------
|
||||
@@ -39,24 +44,31 @@
|
||||
#define PIN_PA18 18u // PA_18
|
||||
#define PIN_PA19 19u // PA_19
|
||||
#define PIN_PA23 23u // PA_23
|
||||
#define PIN_PA29 29u // PA_29
|
||||
#define PIN_PA30 30u // PA_30
|
||||
#define PIN_PWM0 14u // PA_14
|
||||
#define PIN_PWM1 15u // PA_15
|
||||
#define PIN_PWM3 12u // PA_12
|
||||
#define PIN_PWM4 5u // PA_5
|
||||
#define PIN_PWM4 29u // PA_29
|
||||
#define PIN_RX0 18u // PA_18
|
||||
#define PIN_RX2 29u // PA_29
|
||||
#define PIN_SCK0 18u // PA_18
|
||||
#define PIN_SCK1 18u // PA_18
|
||||
#define PIN_SCL0 29u // PA_29
|
||||
#define PIN_SCL1 18u // PA_18
|
||||
#define PIN_SDA0 19u // PA_19
|
||||
#define PIN_SDA0 30u // PA_30
|
||||
#define PIN_SDA1 23u // PA_23
|
||||
#define PIN_TX0 23u // PA_23
|
||||
#define PIN_TX2 30u // PA_30
|
||||
|
||||
// Port availability
|
||||
// -----------------
|
||||
#define HAS_SERIAL0 1
|
||||
#define HAS_SERIAL2 1
|
||||
#define HAS_WIRE0 1
|
||||
#define HAS_WIRE1 1
|
||||
#define SERIAL_INTERFACES_COUNT 1
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
#define SERIAL_INTERFACES_COUNT 2
|
||||
#define WIRE_INTERFACES_COUNT 2
|
||||
|
||||
// Arduino pin names
|
||||
// -----------------
|
||||
@@ -67,6 +79,8 @@
|
||||
#define PIN_D4 23u // PA_23
|
||||
#define PIN_D5 14u // PA_14
|
||||
#define PIN_D6 15u // PA_15
|
||||
#define PIN_D7 30u // PA_30
|
||||
#define PIN_D8 29u // PA_29
|
||||
#define PIN_A0 19u // PA_19
|
||||
#define PIN_A1 41u // AD_2
|
||||
|
||||
@@ -81,3 +95,5 @@ static const unsigned char D3 = PIN_D3;
|
||||
static const unsigned char D4 = PIN_D4;
|
||||
static const unsigned char D5 = PIN_D5;
|
||||
static const unsigned char D6 = PIN_D6;
|
||||
static const unsigned char D7 = PIN_D7;
|
||||
static const unsigned char D8 = PIN_D8;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb1s"
|
||||
],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"_base": [
|
||||
"beken-72xx",
|
||||
"beken-7231n",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb2l",
|
||||
"pcb/wb2l-test",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb2l",
|
||||
"pcb/wb2l-test"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb2s",
|
||||
"pcb/wb2s-test"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb3l"
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wb3s"
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"beken-72xx",
|
||||
"beken-7231",
|
||||
"beken-7231t",
|
||||
"beken-7231-crypt-tuya",
|
||||
"beken-7231-tuya",
|
||||
"ic/bk7231-qfn32",
|
||||
"pcb/wblc5",
|
||||
"pcb/wblc5-test"
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"ic/rtl8710bn",
|
||||
"pcb/wr2-base",
|
||||
"pcb/wr2"
|
||||
"pcb/wr2",
|
||||
"pcb/wr2-test"
|
||||
],
|
||||
"build": {
|
||||
"mcu": "rtl8710bn",
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"ic/rtl8710bn",
|
||||
"pcb/wr2-base",
|
||||
"pcb/wr2e"
|
||||
"pcb/wr2e",
|
||||
"pcb/wr2e-test"
|
||||
],
|
||||
"build": {
|
||||
"mcu": "rtl8710bn",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"realtek-ambz-bx",
|
||||
"ic/rtl8710bn",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"realtek-ambz-bx",
|
||||
"ic/rtl8710bn",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"ic/rtl8710bn",
|
||||
"pcb/wr3-base",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"ic/rtl8710bn",
|
||||
"pcb/wr3-base",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"realtek-ambz-bx",
|
||||
"ic/rtl8710bn",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"realtek-ambz-bx",
|
||||
"ic/rtl8710bn",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"_base": [
|
||||
"realtek-ambz",
|
||||
"realtek-ambz-tuya",
|
||||
"realtek-ambz-2mb-788k",
|
||||
"ic/rtl8710bn",
|
||||
"pcb/wr3-base",
|
||||
|
||||
@@ -538,7 +538,7 @@ image_app_rblh = "${BUILD_DIR}/image_${MCULC}_app.${FLASH_RBL_OFFSET}.rblh"
|
||||
image_ota_rbl = "${BUILD_DIR}/image_${MCULC}_app.ota.rbl"
|
||||
env.Replace(
|
||||
# linker command (encryption + packaging)
|
||||
LINK="${LTCHIPTOOL} link2bin ${BOARD_JSON} '' ''",
|
||||
LINK='${LTCHIPTOOL} link2bin ${BOARD_JSON} "" ""',
|
||||
# UF2OTA input list
|
||||
UF2OTA=[
|
||||
# app binary image (enc+crc) for flasher
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Copyright (c) Kuba Szczodrzyński 2022-07-20.
|
||||
|
||||
from os.path import join
|
||||
from os.path import isfile, join
|
||||
from shutil import copyfile
|
||||
|
||||
from platformio.platform.base import PlatformBase
|
||||
from platformio.platform.board import PlatformBoardConfig
|
||||
@@ -52,9 +53,10 @@ queue.AppendPublic(
|
||||
"-mthumb",
|
||||
"-mcmse",
|
||||
"-mfloat-abi=soft",
|
||||
"--specs=nosys.specs",
|
||||
"--specs=nano.specs",
|
||||
"-Wl,--use-blx",
|
||||
"-Wl,--undefined=gRamStartFun",
|
||||
"-Wl,--warn-section-align",
|
||||
"-Wl,-wrap,aesccmp_construct_mic_iv",
|
||||
"-Wl,-wrap,aesccmp_construct_mic_header1",
|
||||
"-Wl,-wrap,aesccmp_construct_ctr_preload",
|
||||
@@ -91,6 +93,7 @@ queue.AppendPublic(
|
||||
"-Wl,-wrap,memset",
|
||||
# TODO remove this if possible
|
||||
"-Wl,-wrap,putc",
|
||||
# rt_printf wrappers are not here, as they're just changing code using #defines
|
||||
],
|
||||
)
|
||||
|
||||
@@ -103,17 +106,7 @@ queue.AddLibrary(
|
||||
# cmsis
|
||||
"+<soc/realtek/8710c/cmsis/rtl8710c/source/ram/*.c>",
|
||||
"+<soc/realtek/8710c/cmsis/rtl8710c/source/ram_s/app_start.c>",
|
||||
# console
|
||||
"+<common/api/at_cmd/atcmd_bt.c>",
|
||||
"+<common/api/at_cmd/atcmd_lwip.c>",
|
||||
"+<common/api/at_cmd/atcmd_mp_ext2.c>",
|
||||
"+<common/api/at_cmd/atcmd_mp.c>",
|
||||
"+<common/api/at_cmd/atcmd_sys.c>",
|
||||
"+<common/api/at_cmd/atcmd_wifi.c>",
|
||||
"+<common/api/at_cmd/log_service.c>",
|
||||
"+<soc/realtek/8710c/app/shell/cmd_shell.c>",
|
||||
"+<soc/realtek/8710c/app/shell/ram_s/consol_cmds.c>",
|
||||
"+<soc/realtek/8710c/misc/driver/rtl_console.c>",
|
||||
"+<soc/realtek/8710c/misc/driver/flash_api_ext.c>",
|
||||
# utilities
|
||||
"+<common/utilities/cJSON.c>",
|
||||
"+<common/utilities/http_client.c>",
|
||||
@@ -125,11 +118,6 @@ queue.AddLibrary(
|
||||
"+<os/freertos/freertos_service.c>",
|
||||
"+<os/os_dep/device_lock.c>",
|
||||
"+<os/os_dep/osdep_service.c>",
|
||||
# os - freertos
|
||||
"+<os/freertos/freertos_v10.0.1/Source/*.c>",
|
||||
# os - freertos - portable
|
||||
"+<os/freertos/freertos_v10.0.1/Source/portable/MemMang/heap_5.c>",
|
||||
"+<os/freertos/freertos_v10.0.1/Source/portable/GCC/ARM_RTL8710C/port.c>",
|
||||
# peripheral - api
|
||||
"+<common/mbed/targets/hal/rtl8710c/*.c>",
|
||||
# peripheral - hal
|
||||
@@ -146,13 +134,9 @@ queue.AddLibrary(
|
||||
"+<common/file_system/fatfs/r0.10c/src/ff.c>",
|
||||
"+<common/file_system/fatfs/r0.10c/src/option/ccsbcs.c>",
|
||||
"+<common/file_system/ftl/ftl.c>",
|
||||
# TODO remove this
|
||||
"+<common/example/example_entry.c>",
|
||||
"+<common/example/wlan_fast_connect/example_wlan_fast_connect.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<$SDK_DIR/project/realtek_amebaz2_v0_example/inc>",
|
||||
"+<common/api/at_cmd>",
|
||||
"+<common/api/platform>",
|
||||
"+<common/api>",
|
||||
"+<common/application>",
|
||||
@@ -170,11 +154,8 @@ queue.AddLibrary(
|
||||
"+<common/test>",
|
||||
"+<common/utilities>",
|
||||
"+<os/freertos>",
|
||||
"+<os/freertos/freertos_v10.0.1/Source/include>",
|
||||
"+<os/freertos/freertos_v10.0.1/Source/portable/GCC/ARM_RTL8710C>",
|
||||
"+<os/os_dep/include>",
|
||||
"+<soc/realtek/8710c/app/rtl_printf/include>",
|
||||
"+<soc/realtek/8710c/app/shell>",
|
||||
"+<soc/realtek/8710c/app/stdio_port>",
|
||||
"+<soc/realtek/8710c/cmsis/cmsis-core/include>",
|
||||
"+<soc/realtek/8710c/cmsis/rtl8710c/include>",
|
||||
@@ -205,6 +186,14 @@ queue.AddLibrary(
|
||||
),
|
||||
)
|
||||
|
||||
# Sources - FreeRTOS
|
||||
env.Replace(FREERTOS_PORT=env["FAMILY_NAME"], FREERTOS_PORT_DEFINE="REALTEK_AMBZ2")
|
||||
queue.AddExternalLibrary("freertos")
|
||||
queue.AddExternalLibrary("freertos-port")
|
||||
|
||||
# Sources - lwIP
|
||||
queue.AddExternalLibrary("lwip", port="ambz2")
|
||||
|
||||
# Sources - network utilities
|
||||
queue.AddLibrary(
|
||||
name="ambz2_net",
|
||||
@@ -214,6 +203,7 @@ queue.AddLibrary(
|
||||
"+<common/api/lwip_netconf.c>",
|
||||
# network - api - wifi
|
||||
"+<common/api/wifi/*.c>",
|
||||
"ARDUINO" in "ENV" and "-<common/api/wifi/wifi_ind.c>",
|
||||
# network - api - wifi - rtw_wpa_supplicant
|
||||
"+<common/api/wifi/rtw_wpa_supplicant/src/crypto/tls_polarssl.c>",
|
||||
"+<common/api/wifi/rtw_wpa_supplicant/wpa_supplicant/*.c>",
|
||||
@@ -231,7 +221,6 @@ queue.AddLibrary(
|
||||
"+<common/network/httpd/httpd_tls.c>",
|
||||
# network
|
||||
"+<common/network/dhcp/dhcps.c>",
|
||||
"+<common/network/sntp/sntp.c>",
|
||||
# network - websocket
|
||||
"+<common/network/websocket/*.c>",
|
||||
# network - mdns
|
||||
@@ -285,6 +274,7 @@ queue.AddLibrary(
|
||||
# "+<src/ble/profile/server/hids_rmc.c>",
|
||||
"+<src/ble/profile/server/simple_ble_service.c>",
|
||||
"+<src/mcu/module/data_uart_cmd/user_cmd_parse.c>",
|
||||
"-<board/common/src/bt_uart_bridge.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<.>",
|
||||
@@ -315,34 +305,6 @@ queue.AddLibrary(
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# Sources - lwIP 2.0.2
|
||||
queue.AddLibrary(
|
||||
name="ambz2_lwip",
|
||||
base_dir=join(COMPONENT_DIR, "common", "network", "lwip", "lwip_v2.0.2"),
|
||||
srcs=[
|
||||
"+<port/realtek/freertos/*.c>",
|
||||
"+<src/api/*.c>",
|
||||
"+<src/apps/ping/*.c>",
|
||||
"+<src/apps/mdns/*.c>",
|
||||
"+<src/core/*.c>",
|
||||
"+<src/core/ipv4/*.c>",
|
||||
"+<src/core/ipv6/*.c>",
|
||||
"+<src/netif/ethernet.c>",
|
||||
],
|
||||
includes=[
|
||||
"+<port/realtek>",
|
||||
"+<port/realtek/freertos>",
|
||||
"+<src/include>",
|
||||
"+<src/include/netif>",
|
||||
],
|
||||
options=dict(
|
||||
CFLAGS=[
|
||||
"-Wno-implicit-function-declaration",
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
# Sources - mbedTLS
|
||||
queue.AddLibrary(
|
||||
name="ambz2_mbedtls",
|
||||
@@ -436,10 +398,38 @@ env.Replace(
|
||||
SIZEPRINTCMD="$SIZETOOL -B -d $SOURCES",
|
||||
)
|
||||
|
||||
# Bootloader - copy for linking
|
||||
# fmt: off
|
||||
bootloader_src = env.subst("${SDK_DIR}/component/soc/realtek/8710c/misc/bsp/image/bootloader.axf")
|
||||
bootloader_dst = env.subst("${BUILD_DIR}/bootloader.axf")
|
||||
# fmt: on
|
||||
if not isfile(bootloader_dst):
|
||||
copyfile(bootloader_src, bootloader_dst)
|
||||
|
||||
# OTA2 clearing - 4096 bytes of 0xFF
|
||||
image_ota_clear = env.subst("${BUILD_DIR}/raw_ota_clear.bin")
|
||||
if not isfile(image_ota_clear):
|
||||
with open(image_ota_clear, "wb") as f:
|
||||
f.write(b"\xFF" * 4096)
|
||||
|
||||
# Build all libraries
|
||||
queue.BuildLibraries()
|
||||
|
||||
# Main firmware outputs and actions
|
||||
image_part_table = "${BUILD_DIR}/image_part_table.${FLASH_PART_TABLE_OFFSET}.bin"
|
||||
image_bootloader = "${BUILD_DIR}/image_bootloader.${FLASH_BOOT_OFFSET}.bin"
|
||||
image_firmware_is = "${BUILD_DIR}/image_firmware_is.${FLASH_OTA1_OFFSET}.bin"
|
||||
env.Replace(
|
||||
# TODO
|
||||
# linker command (dual .bin outputs)
|
||||
LINK='${LTCHIPTOOL} link2bin ${BOARD_JSON} "" ""',
|
||||
# UF2OTA input list
|
||||
UF2OTA=[
|
||||
# same OTA images for flasher and device
|
||||
f"{image_firmware_is},{image_firmware_is}=device:ota1,ota2;flasher:ota1,ota2",
|
||||
# having flashed an application image, update the bootloader and partition table (incl. keys)
|
||||
f"{image_bootloader}=device:boot;flasher:boot",
|
||||
f"{image_part_table}=device:part_table;flasher:part_table",
|
||||
# clearing headers of the "other" OTA image (hence the indexes are swapped)
|
||||
f"{image_ota_clear},{image_ota_clear}=device:ota2,ota1;flasher:ota2,ota1",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ for f in family.inheritance:
|
||||
code = f"{f.code}_arduino"
|
||||
path = join("$CORES_DIR", f.name, "arduino")
|
||||
|
||||
found = found or env.AddCoreSources(queue, name=code, path=join(path, "src"))
|
||||
found = env.AddCoreSources(queue, name=code, path=join(path, "src")) or found
|
||||
env.AddArduinoLibraries(queue, name=code, path=join(path, "libraries"))
|
||||
|
||||
if f.short_name:
|
||||
@@ -73,13 +73,6 @@ queue.AppendPublic(
|
||||
("ARDUINO_SDK", 1),
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"--specs=nosys.specs",
|
||||
"-Wl,--as-needed",
|
||||
"-Wl,--build-id=none",
|
||||
"-Wl,--cref",
|
||||
"-Wl,--no-enum-size-warning",
|
||||
"-Wl,--no-undefined",
|
||||
"-Wl,--warn-common",
|
||||
# wrappers from posix/time.c
|
||||
"-Wl,-wrap,gettimeofday",
|
||||
"-Wl,-wrap,settimeofday",
|
||||
|
||||
@@ -95,7 +95,7 @@ for f in family.inheritance:
|
||||
env.Prepend(CPPDEFINES=[(f"LT_{f.code.upper()}", "1")])
|
||||
|
||||
# Sources - external libraries
|
||||
queue.AddExternalLibrary("ltchiptool") # uf2ota source code
|
||||
queue.AddExternalLibrary("uf2ota")
|
||||
queue.AddExternalLibrary("flashdb")
|
||||
queue.AddExternalLibrary("printf")
|
||||
|
||||
@@ -138,11 +138,14 @@ queue.AppendPublic(
|
||||
LINKFLAGS=[
|
||||
"-g2",
|
||||
"-Os",
|
||||
"-Wl,--as-needed",
|
||||
"-Wl,--build-id=none",
|
||||
"-Wl,--cref",
|
||||
"-Wl,--gc-sections",
|
||||
"-Wl,--no-enum-size-warning",
|
||||
"-Wl,--no-wchar-size-warning",
|
||||
"-Wl,--no-undefined",
|
||||
"-Wl,--warn-common",
|
||||
# malloc.c wrappers
|
||||
"-Wl,-wrap,malloc",
|
||||
"-Wl,-wrap,calloc",
|
||||
|
||||
@@ -20,13 +20,21 @@ def env_load_defines(env: Environment, path: str):
|
||||
line = line[7:].strip()
|
||||
line = line.split(None, 2)
|
||||
if len(line) == 1:
|
||||
env.Append(CPPDEFINES=[(line[0], 1)])
|
||||
config[line[0]] = 1
|
||||
key, value = line[0], 1
|
||||
elif len(line) == 2:
|
||||
env.Append(CPPDEFINES=[(line[0], line[1])])
|
||||
config[line[0]] = line[1]
|
||||
key, value = line[0], line[1]
|
||||
else:
|
||||
raise ValueError(f"Unknown directive: {line}")
|
||||
for tpl in env["CPPDEFINES"]:
|
||||
if isinstance(tpl, tuple):
|
||||
k = tpl[0]
|
||||
else:
|
||||
k = tpl
|
||||
if k == key:
|
||||
env["CPPDEFINES"].remove(tpl)
|
||||
break
|
||||
env.Append(CPPDEFINES=[(key, value)])
|
||||
config[key] = value
|
||||
env.Append(
|
||||
CONFIG=config,
|
||||
)
|
||||
|
||||
@@ -46,10 +46,12 @@ def env_add_core_sources(env: Environment, queue, name: str, path: str) -> bool:
|
||||
base_dir=path,
|
||||
srcs=[
|
||||
"+<*.c*>",
|
||||
"+<api/*.c>",
|
||||
"+<common/*.c*>",
|
||||
"+<compat/*.c*>",
|
||||
"+<port/*.c*>",
|
||||
"+<posix/*.c>",
|
||||
"+<wiring/*.c>",
|
||||
"+<wraps/*.c>",
|
||||
],
|
||||
includes=[
|
||||
@@ -58,6 +60,7 @@ def env_add_core_sources(env: Environment, queue, name: str, path: str) -> bool:
|
||||
"!<compat>",
|
||||
"!<config>",
|
||||
"!<port>",
|
||||
"!<wiring>",
|
||||
],
|
||||
)
|
||||
queue.AddLibrary(
|
||||
|
||||
@@ -59,14 +59,23 @@ def env_uf2ota(env: Environment, *args, **kwargs):
|
||||
|
||||
|
||||
def env_flash_write(env: Environment):
|
||||
# UPLOAD_PROTOCOL = upload_protocol or board->upload.protocol
|
||||
# UPLOAD_PORT = upload_port (PIO can choose this automatically I guess)
|
||||
# UPLOAD_SPEED = upload_speed or board->upload.speed (**can be empty**)
|
||||
protocol = env.subst("${UPLOAD_PROTOCOL}")
|
||||
speed = env.subst("${UPLOAD_SPEED}")
|
||||
if protocol == "uart":
|
||||
# upload via UART
|
||||
if speed:
|
||||
return [
|
||||
"-d",
|
||||
"${UPLOAD_PORT}",
|
||||
"-b",
|
||||
"${UPLOAD_SPEED}",
|
||||
]
|
||||
return [
|
||||
"-d",
|
||||
"${UPLOAD_PORT}",
|
||||
"-b",
|
||||
"${UPLOAD_SPEED}",
|
||||
]
|
||||
else:
|
||||
# can't upload via ltchiptool
|
||||
|
||||
5
cores/beken-7231n/base/lt_defs.h
Normal file
5
cores/beken-7231n/base/lt_defs.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#error "Don't include this file directly"
|
||||
|
||||
#define LT_HW_BLE 1
|
||||
5
cores/beken-7231t/base/lt_defs.h
Normal file
5
cores/beken-7231t/base/lt_defs.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#error "Don't include this file directly"
|
||||
|
||||
#define LT_HW_BLE 1
|
||||
5
cores/beken-7251/base/lt_defs.h
Normal file
5
cores/beken-7251/base/lt_defs.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#error "Don't include this file directly"
|
||||
|
||||
#define LT_HW_BLE 1
|
||||
@@ -1,59 +1,40 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-23. */
|
||||
|
||||
#include "Serial.h"
|
||||
#include "SerialPrivate.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <uart_pub.h>
|
||||
|
||||
extern void bk_send_byte(uint8_t uport, uint8_t data);
|
||||
extern void uart_hw_set_change(uint8_t uport, bk_uart_config_t *uart_config);
|
||||
extern int uart_rx_callback_set(int uport, uart_callback callback, void *param);
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#if HAS_SERIAL1
|
||||
#if LT_HW_UART1
|
||||
SerialClass Serial1(UART1_PORT);
|
||||
#endif
|
||||
#if HAS_SERIAL2
|
||||
#if LT_HW_UART2
|
||||
SerialClass Serial2(UART2_PORT);
|
||||
#endif
|
||||
|
||||
SerialClass::SerialClass(uint8_t port) {
|
||||
this->port = port;
|
||||
this->buf = NULL;
|
||||
}
|
||||
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT
|
||||
static uint8_t adrState = 0;
|
||||
static const uint8_t adrCmd[] = {0x01, 0xE0, 0xFC, 0x01, 0x00};
|
||||
|
||||
static void adrParse(uint8_t c) {
|
||||
// parse and respond to link check command (CMD_LinkCheck=0)
|
||||
adrState = (adrState + 1) * (c == adrCmd[adrState]);
|
||||
if (adrState == 5) {
|
||||
LT_I("Auto download mode: rebooting");
|
||||
LT.restart();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void callback(int port, void *param) {
|
||||
RingBuffer *buf = (RingBuffer *)param;
|
||||
int ch;
|
||||
while ((ch = uart_read_byte(port)) != -1) {
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(PIN_SERIAL1_RX)
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(LT_UART_ADR_PATTERN) && PIN_SERIAL1_RX != PIN_INVALID
|
||||
// parse UART protocol commands on UART1
|
||||
if (port == UART1_PORT)
|
||||
adrParse(ch);
|
||||
SerialClass::adrParse(ch);
|
||||
#endif
|
||||
buf->store_char(ch);
|
||||
pBUF->store_char(ch);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
|
||||
if (!this->data) {
|
||||
this->data = new SerialData();
|
||||
this->buf = &BUF;
|
||||
}
|
||||
|
||||
if (this->baudrate != baudrate || this->config != config)
|
||||
this->configure(baudrate, config);
|
||||
}
|
||||
|
||||
void SerialClass::configure(unsigned long baudrate, uint16_t config) {
|
||||
if (!this->data)
|
||||
return;
|
||||
|
||||
uint8_t dataWidth = ((config & SERIAL_DATA_MASK) >> 8) - 1; // 0x100..0x400 -> 0..3
|
||||
uint8_t parity = 3 - (config & SERIAL_PARITY_MASK); // 0x3..0x1 -> 0..2
|
||||
uint8_t stopBits = (config & SERIAL_STOP_BIT_MASK) == SERIAL_STOP_BIT_2; // 0x10..0x30 -> 0..1
|
||||
@@ -66,17 +47,21 @@ void SerialClass::begin(unsigned long baudrate, uint16_t config) {
|
||||
.flow_control = FLOW_CTRL_DISABLED,
|
||||
};
|
||||
|
||||
if (this->buf) {
|
||||
this->buf->clear();
|
||||
} else {
|
||||
this->buf = new RingBuffer();
|
||||
}
|
||||
|
||||
if (port == 1)
|
||||
uart1_init();
|
||||
else if (port == 2)
|
||||
uart2_init();
|
||||
uart_hw_set_change(port, &cfg);
|
||||
uart_rx_callback_set(port, callback, this->buf);
|
||||
uart_rx_callback_set(port, callback, &BUF);
|
||||
|
||||
this->baudrate = baudrate;
|
||||
this->config = config;
|
||||
}
|
||||
|
||||
void SerialClass::end() {
|
||||
if (!this->data)
|
||||
return;
|
||||
|
||||
uart_rx_callback_set(port, NULL, NULL);
|
||||
switch (port) {
|
||||
case 1:
|
||||
@@ -86,26 +71,22 @@ void SerialClass::end() {
|
||||
uart2_exit();
|
||||
break;
|
||||
}
|
||||
delete this->buf;
|
||||
}
|
||||
|
||||
int SerialClass::available() {
|
||||
return buf->available();
|
||||
}
|
||||
|
||||
int SerialClass::peek() {
|
||||
return buf->peek();
|
||||
}
|
||||
|
||||
int SerialClass::read() {
|
||||
return buf->read_char();
|
||||
delete DATA;
|
||||
this->data = NULL;
|
||||
this->buf = NULL;
|
||||
this->baudrate = 0;
|
||||
}
|
||||
|
||||
void SerialClass::flush() {
|
||||
if (!this->data)
|
||||
return;
|
||||
uart_wait_tx_over();
|
||||
}
|
||||
|
||||
size_t SerialClass::write(uint8_t c) {
|
||||
if (!this->data)
|
||||
return 0;
|
||||
bk_send_byte(port, c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
14
cores/beken-72xx/arduino/libraries/Serial/SerialPrivate.h
Normal file
14
cores/beken-72xx/arduino/libraries/Serial/SerialPrivate.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
typedef struct {
|
||||
RingBuffer buf;
|
||||
} SerialData;
|
||||
|
||||
#define DATA ((SerialData *)data)
|
||||
#define BUF (DATA->buf)
|
||||
#define pBUF ((RingBuffer *)param)
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#error "Don't include this file directly"
|
||||
|
||||
#define LT_ARD_HAS_WIFI 1
|
||||
#define LT_ARD_HAS_SERIAL 1
|
||||
|
||||
#define LT_ARD_HAS_WIFI 1
|
||||
#define LT_ARD_HAS_SERIAL 1
|
||||
#define LT_ARD_MD5_HOSTAPD 1
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <include.h>
|
||||
|
||||
#include <arm_arch.h>
|
||||
#include <bk_timer.h>
|
||||
#include <bk_timer_pub.h>
|
||||
#include <rtos_pub.h>
|
||||
#include <sys_rtos.h>
|
||||
#include "wiring_private.h"
|
||||
|
||||
#if LT_BK7231Q
|
||||
#undef LT_MICROS_HIGH_RES
|
||||
@@ -18,10 +11,6 @@
|
||||
#define US_PER_OVERFLOW (portTICK_PERIOD_MS * 1000)
|
||||
#define TICKS_PER_OVERFLOW (TICKS_PER_US * US_PER_OVERFLOW)
|
||||
|
||||
void delayMilliseconds(unsigned long ms) {
|
||||
rtos_delay_milliseconds(ms);
|
||||
}
|
||||
|
||||
#if LT_MICROS_HIGH_RES
|
||||
static uint32_t getTicksCount() {
|
||||
// copied from bk_timer_ctrl(), for speeds
|
||||
@@ -107,8 +96,22 @@ unsigned long micros() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void yield() {
|
||||
runPeriodicTasks();
|
||||
vTaskDelay(1);
|
||||
taskYIELD();
|
||||
void pinRemoveMode(PinInfo *pin, uint32_t mask) {
|
||||
PinData *data = pinData(pin);
|
||||
if ((mask & PIN_GPIO) && (pin->enabled & PIN_GPIO)) {
|
||||
gpio_config(pin->gpio, GMODE_INPUT_PULLDOWN);
|
||||
pinDisable(pin, PIN_GPIO);
|
||||
}
|
||||
if ((mask & PIN_IRQ) && (pin->enabled & PIN_IRQ)) {
|
||||
data->irqHandler = NULL;
|
||||
gpio_int_disable(pin->gpio);
|
||||
pinDisable(pin, PIN_IRQ);
|
||||
}
|
||||
if ((mask & PIN_PWM) && (pin->enabled & PIN_PWM)) {
|
||||
data->pwm->cfg.bits.en = PWM_DISABLE;
|
||||
__wrap_bk_printf_disable();
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, data->pwm);
|
||||
__wrap_bk_printf_enable();
|
||||
pinDisable(pin, PIN_PWM);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <gpio_pub.h>
|
||||
#include <pwm_pub.h>
|
||||
#include <saradc_pub.h>
|
||||
#include "wiring_private.h"
|
||||
|
||||
static GPIO_INDEX pwmToGpio[] = {
|
||||
GPIO6, // PWM0
|
||||
@@ -59,11 +55,7 @@ static pwm_param_t pwm;
|
||||
static uint16_t adcData[1];
|
||||
|
||||
uint16_t analogReadVoltage(pin_size_t pinNumber) {
|
||||
PinInfo *pin = pinInfo(pinNumber);
|
||||
if (!pin)
|
||||
return 0;
|
||||
if (!pinSupported(pin, PIN_ADC))
|
||||
return 0;
|
||||
pinCheckGetInfo(pinNumber, PIN_ADC, 0);
|
||||
|
||||
UINT32 status;
|
||||
saradc_desc_t adc;
|
||||
@@ -90,11 +82,10 @@ uint16_t analogReadMaxVoltage(pin_size_t pinNumber) {
|
||||
}
|
||||
|
||||
void analogWrite(pin_size_t pinNumber, int value) {
|
||||
PinInfo *pin = pinInfo(pinNumber);
|
||||
if (!pin)
|
||||
return;
|
||||
if (!pinSupported(pin, PIN_PWM))
|
||||
return;
|
||||
pinCheckGetData(pinNumber, PIN_PWM, );
|
||||
|
||||
// GPIO can't be used together with PWM
|
||||
pinRemoveMode(pin, PIN_GPIO | PIN_IRQ);
|
||||
|
||||
float percent = value * 1.0 / ((1 << _analogWriteResolution) - 1);
|
||||
uint32_t frequency = 26 * _analogWritePeriod - 1;
|
||||
@@ -122,8 +113,9 @@ void analogWrite(pin_size_t pinNumber, int value) {
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_INIT_LEVL_SET_HIGH, &pwm.channel);
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_UNIT_ENABLE, &pwm.channel);
|
||||
__wrap_bk_printf_enable();
|
||||
pin->enabled &= ~PIN_GPIO;
|
||||
pin->enabled |= PIN_PWM;
|
||||
// pass global PWM object pointer
|
||||
data->pwm = &pwm;
|
||||
pinEnable(pin, PIN_PWM);
|
||||
} else {
|
||||
// update duty cycle
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_SET_DUTY_CYCLE, &pwm);
|
||||
@@ -131,11 +123,7 @@ void analogWrite(pin_size_t pinNumber, int value) {
|
||||
} else {
|
||||
if (pinEnabled(pin, PIN_PWM)) {
|
||||
// disable PWM
|
||||
pwm.cfg.bits.en = PWM_DISABLE;
|
||||
__wrap_bk_printf_disable();
|
||||
sddev_control(PWM_DEV_NAME, CMD_PWM_DEINIT_PARAM, &pwm);
|
||||
__wrap_bk_printf_enable();
|
||||
pin->enabled &= ~PIN_PWM;
|
||||
pinRemoveMode(pin, PIN_PWM);
|
||||
}
|
||||
// force level as LOW
|
||||
pinMode(pinNumber, OUTPUT);
|
||||
|
||||
23
cores/beken-72xx/arduino/src/wiring_data.h
Normal file
23
cores/beken-72xx/arduino/src/wiring_data.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct PinData_s {
|
||||
pwm_param_t *pwm;
|
||||
PinMode gpioMode;
|
||||
PinStatus irqMode;
|
||||
void *irqHandler;
|
||||
void *irqParam;
|
||||
bool irqChange;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -1,20 +1,16 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-20. */
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <gpio_pub.h>
|
||||
#include "wiring_private.h"
|
||||
|
||||
void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
||||
PinInfo *pin = pinInfo(pinNumber);
|
||||
if (!pin)
|
||||
return;
|
||||
if (!pinSupported(pin, PIN_GPIO))
|
||||
return;
|
||||
if (pinEnabled(pin, PIN_PWM))
|
||||
// disable PWM before using the pin
|
||||
analogWrite(pinNumber, 0);
|
||||
if (pinEnabled(pin, PIN_GPIO) && pin->mode == pinMode)
|
||||
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||
|
||||
if (pinEnabled(pin, PIN_GPIO) && data->gpioMode == pinMode)
|
||||
return;
|
||||
|
||||
// GPIO can't be used together with PWM
|
||||
pinRemoveMode(pin, PIN_PWM);
|
||||
|
||||
switch (pinMode) {
|
||||
case INPUT:
|
||||
gpio_config(pin->gpio, GMODE_INPUT);
|
||||
@@ -31,34 +27,21 @@ void pinMode(pin_size_t pinNumber, PinMode pinMode) {
|
||||
case OUTPUT_OPENDRAIN:
|
||||
gpio_config(pin->gpio, GMODE_SET_HIGH_IMPENDANCE);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
pin->enabled |= PIN_GPIO;
|
||||
pin->mode = pinMode;
|
||||
pinEnable(pin, PIN_GPIO);
|
||||
data->gpioMode = pinMode;
|
||||
}
|
||||
|
||||
void digitalWrite(pin_size_t pinNumber, PinStatus status) {
|
||||
// verify level is 0 or 1
|
||||
if (status > HIGH)
|
||||
return;
|
||||
PinInfo *pin = pinInfo(pinNumber);
|
||||
if (!pin)
|
||||
return;
|
||||
// pin is not GPIO yet or not OUTPUT; enable or disable input pullup
|
||||
if (!pinEnabled(pin, PIN_GPIO) || !pinIsOutput(pin)) {
|
||||
pinMode(pinNumber, status * INPUT_PULLUP);
|
||||
return;
|
||||
}
|
||||
// write the new state
|
||||
gpio_output(pin->gpio, status);
|
||||
pinCheckGetData(pinNumber, PIN_GPIO, );
|
||||
pinSetOutputPull(pin, data, pinNumber, status);
|
||||
gpio_output(pin->gpio, !!status);
|
||||
}
|
||||
|
||||
PinStatus digitalRead(pin_size_t pinNumber) {
|
||||
PinInfo *pin = pinInfo(pinNumber);
|
||||
if (!pin)
|
||||
return 0;
|
||||
// pin is not GPIO yet or not INPUT; change the mode
|
||||
if (!pinEnabled(pin, PIN_GPIO) || !pinIsInput(pin))
|
||||
pinMode(pinNumber, INPUT);
|
||||
// read the value
|
||||
pinCheckGetData(pinNumber, PIN_GPIO, LOW);
|
||||
pinSetInputMode(pin, data, pinNumber);
|
||||
return gpio_input(pin->gpio);
|
||||
}
|
||||
|
||||
@@ -1,98 +1,70 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-07-31. */
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <gpio_pub.h>
|
||||
|
||||
static void *irqHandlerList[PINS_COUNT] = {NULL};
|
||||
static void *irqHandlerArgs[PINS_COUNT] = {NULL};
|
||||
static bool irqChangeList[PINS_COUNT];
|
||||
#include "wiring_private.h"
|
||||
|
||||
static void irqHandler(unsigned char gpio) {
|
||||
PinInfo *pin = pinByGpio(gpio);
|
||||
if (pin == NULL)
|
||||
return;
|
||||
uint32_t index = pinIndex(pin);
|
||||
if (!irqHandlerList[index])
|
||||
PinData *data = pinData(pin);
|
||||
if (!data->irqHandler)
|
||||
return;
|
||||
if (irqChangeList[index]) {
|
||||
if (pin->mode == INPUT_PULLDOWN) {
|
||||
pin->mode = INPUT_PULLUP;
|
||||
if (data->irqChange) {
|
||||
if (data->gpioMode == INPUT_PULLDOWN) {
|
||||
data->gpioMode = INPUT_PULLUP;
|
||||
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
|
||||
} else if (pin->mode == INPUT_PULLUP) {
|
||||
pin->mode = INPUT_PULLDOWN;
|
||||
} else if (data->gpioMode == INPUT_PULLUP) {
|
||||
data->gpioMode = INPUT_PULLDOWN;
|
||||
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_RISING, irqHandler);
|
||||
}
|
||||
}
|
||||
if (irqHandlerArgs[index] == NULL) {
|
||||
((voidFuncPtr)irqHandlerList[index])();
|
||||
} else {
|
||||
((voidFuncPtrParam)irqHandlerList[index])(irqHandlerArgs[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus mode) {
|
||||
attachInterruptParam(interruptNumber, (voidFuncPtrParam)callback, mode, NULL);
|
||||
if (!data->irqParam)
|
||||
((voidFuncPtr)data->irqHandler)();
|
||||
else
|
||||
((voidFuncPtrParam)data->irqHandler)(data->irqParam);
|
||||
}
|
||||
|
||||
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 index = pinIndex(pin);
|
||||
uint32_t event = 0;
|
||||
PinMode modeNew = 0;
|
||||
bool change = 0;
|
||||
pinCheckGetData(interruptNumber, PIN_IRQ, );
|
||||
|
||||
data->irqHandler = callback;
|
||||
data->irqParam = param;
|
||||
|
||||
if (pinEnabled(pin, PIN_IRQ) && data->irqMode == mode)
|
||||
return;
|
||||
|
||||
// GPIO can't be used together with PWM
|
||||
pinRemoveMode(pin, PIN_PWM);
|
||||
|
||||
uint32_t event = 0;
|
||||
bool change = false;
|
||||
switch (mode) {
|
||||
case LOW:
|
||||
event = GPIO_INT_LEVEL_LOW;
|
||||
modeNew = INPUT_PULLUP;
|
||||
change = false;
|
||||
event = GPIO_INT_LEVEL_LOW;
|
||||
break;
|
||||
case HIGH:
|
||||
event = GPIO_INT_LEVEL_HIGH;
|
||||
modeNew = INPUT_PULLDOWN;
|
||||
change = false;
|
||||
event = GPIO_INT_LEVEL_HIGH;
|
||||
break;
|
||||
case FALLING:
|
||||
event = GPIO_INT_LEVEL_FALLING;
|
||||
modeNew = INPUT_PULLUP;
|
||||
change = false;
|
||||
event = GPIO_INT_LEVEL_FALLING;
|
||||
break;
|
||||
case RISING:
|
||||
event = GPIO_INT_LEVEL_RISING;
|
||||
modeNew = INPUT_PULLDOWN;
|
||||
change = false;
|
||||
event = GPIO_INT_LEVEL_RISING;
|
||||
break;
|
||||
case CHANGE:
|
||||
event = GPIO_INT_LEVEL_FALLING;
|
||||
modeNew = INPUT_PULLUP;
|
||||
change = true;
|
||||
event = GPIO_INT_LEVEL_FALLING;
|
||||
change = true;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
irqHandlerList[index] = callback;
|
||||
irqHandlerArgs[index] = param;
|
||||
irqChangeList[index] = change;
|
||||
pinEnable(pin, PIN_IRQ);
|
||||
data->irqMode = mode;
|
||||
data->irqChange = change;
|
||||
|
||||
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;
|
||||
uint32_t index = pinIndex(pin);
|
||||
irqHandlerList[index] = NULL;
|
||||
irqHandlerArgs[index] = NULL;
|
||||
irqChangeList[index] = false;
|
||||
gpio_int_disable(pin->gpio);
|
||||
pin->enabled &= ~PIN_IRQ;
|
||||
pinModeRemove(interruptNumber, PIN_IRQ);
|
||||
}
|
||||
|
||||
13
cores/beken-72xx/base/api/lt_cpu.c
Normal file
13
cores/beken-72xx/base/api/lt_cpu.c
Normal file
@@ -0,0 +1,13 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
lt_cpu_model_t lt_cpu_get_model() {
|
||||
uint8_t chipId = *(uint8_t *)(SCTRL_CHIP_ID);
|
||||
return CPU_MODEL_ENUM(FAMILY, chipId);
|
||||
}
|
||||
|
||||
const char *lt_cpu_get_core_type() {
|
||||
return "ARM968E-S (ARMv5TE)";
|
||||
}
|
||||
41
cores/beken-72xx/base/api/lt_device.c
Normal file
41
cores/beken-72xx/base/api/lt_device.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
void lt_get_device_mac(uint8_t *mac) {
|
||||
cfg_load_mac(mac);
|
||||
}
|
||||
|
||||
void lt_reboot() {
|
||||
bk_reboot();
|
||||
}
|
||||
|
||||
bool lt_reboot_download_mode() {
|
||||
bk_reboot();
|
||||
return true;
|
||||
}
|
||||
|
||||
lt_reboot_reason_t lt_get_reboot_reason() {
|
||||
switch (bk_misc_get_start_type()) {
|
||||
case RESET_SOURCE_POWERON:
|
||||
return REBOOT_REASON_POWER;
|
||||
case RESET_SOURCE_REBOOT:
|
||||
return REBOOT_REASON_SOFTWARE;
|
||||
case RESET_SOURCE_WATCHDOG:
|
||||
return REBOOT_REASON_WATCHDOG;
|
||||
case RESET_SOURCE_CRASH_XAT0:
|
||||
case RESET_SOURCE_CRASH_UNDEFINED:
|
||||
case RESET_SOURCE_CRASH_PREFETCH_ABORT:
|
||||
case RESET_SOURCE_CRASH_DATA_ABORT:
|
||||
case RESET_SOURCE_CRASH_UNUSED:
|
||||
case RESET_SOURCE_CRASH_PER_XAT0:
|
||||
return REBOOT_REASON_CRASH;
|
||||
case RESET_SOURCE_DEEPPS_GPIO:
|
||||
case RESET_SOURCE_DEEPPS_RTC:
|
||||
case RESET_SOURCE_DEEPPS_USB:
|
||||
return REBOOT_REASON_SLEEP;
|
||||
default:
|
||||
return REBOOT_REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
26
cores/beken-72xx/base/api/lt_flash.c
Normal file
26
cores/beken-72xx/base/api/lt_flash.c
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
// can't include <flash.h> as it collides with <Flash.h> 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
|
||||
|
||||
lt_flash_id_t lt_flash_get_id() {
|
||||
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) {}
|
||||
lt_flash_id_t id = {
|
||||
.manufacturer_id = REG_RD8(REG_FLASH_RDID, 2),
|
||||
.chip_id = REG_RD8(REG_FLASH_RDID, 1),
|
||||
.chip_size_id = REG_RD8(REG_FLASH_RDID, 0),
|
||||
};
|
||||
return id;
|
||||
}
|
||||
14
cores/beken-72xx/base/api/lt_init.c
Normal file
14
cores/beken-72xx/base/api/lt_init.c
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
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();
|
||||
}
|
||||
21
cores/beken-72xx/base/api/lt_mem.c
Normal file
21
cores/beken-72xx/base/api/lt_mem.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
uint32_t lt_ram_get_size() {
|
||||
return 256 * 1024;
|
||||
}
|
||||
|
||||
uint32_t lt_heap_get_size() {
|
||||
#if configDYNAMIC_HEAP_SIZE
|
||||
extern unsigned char _empty_ram;
|
||||
#if CFG_SOC_NAME == SOC_BK7231N
|
||||
return (0x00400000 + 192 * 1024) - (uint32_t)(&_empty_ram);
|
||||
#else
|
||||
return (0x00400000 + 256 * 1024) - (uint32_t)(&_empty_ram);
|
||||
#endif
|
||||
#else
|
||||
return configTOTAL_HEAP_SIZE;
|
||||
#endif
|
||||
}
|
||||
39
cores/beken-72xx/base/api/lt_ota.c
Normal file
39
cores/beken-72xx/base/api/lt_ota.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
lt_ota_type_t lt_ota_get_type() {
|
||||
return OTA_TYPE_SINGLE;
|
||||
}
|
||||
|
||||
bool lt_ota_is_valid(uint8_t index) {
|
||||
if (index != 0)
|
||||
return false;
|
||||
// check download RBL
|
||||
// TODO: maybe check header CRC or even binary hashes
|
||||
uint32_t magic;
|
||||
lt_flash_read(FLASH_DOWNLOAD_OFFSET, (uint8_t *)&magic, 4);
|
||||
return magic == 0x004C4252; // "RBL\0", little-endian
|
||||
}
|
||||
|
||||
uint8_t lt_ota_dual_get_current() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t lt_ota_dual_get_stored() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool lt_ota_switch(bool revert) {
|
||||
if (!lt_ota_is_valid(0))
|
||||
// no valid "download" image
|
||||
// - return false when trying to activate
|
||||
// - return true when trying to revert
|
||||
return revert;
|
||||
if (revert) {
|
||||
// there's a valid "download" image, which has to be removed
|
||||
return lt_flash_erase_block(FLASH_DOWNLOAD_OFFSET);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
40
cores/beken-72xx/base/api/lt_sleep.c
Normal file
40
cores/beken-72xx/base/api/lt_sleep.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/* Copyright (c) Peter Sarkozi 2023-06-17. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
static PS_DEEP_CTRL_PARAM deep_sleep_param;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void lt_deep_sleep_unset_gpio(uint32_t gpio_index_map) {
|
||||
deep_sleep_param.gpio_index_map &= (~gpio_index_map);
|
||||
}
|
||||
|
||||
void lt_deep_sleep_config_timer(uint32_t sleep_duration) {
|
||||
deep_sleep_param.wake_up_way |= PS_DEEP_WAKEUP_RTC;
|
||||
uint64_t duration_math = 32768 * sleep_duration;
|
||||
if (duration_math / 1000 > 0xFFFFFFFF) {
|
||||
// Sleep forever
|
||||
deep_sleep_param.sleep_time = 0xFFFFFFFF;
|
||||
} else {
|
||||
deep_sleep_param.sleep_time = (duration_math / 1000) & 0xFFFFFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
void lt_deep_sleep_enter() {
|
||||
bk_misc_update_set_type(RESET_SOURCE_DEEPPS_GPIO);
|
||||
GLOBAL_INT_DECLARATION();
|
||||
GLOBAL_INT_DISABLE();
|
||||
sctrl_enter_rtos_deep_sleep((PS_DEEP_CTRL_PARAM *)&deep_sleep_param);
|
||||
ps_delay(500);
|
||||
GLOBAL_INT_RESTORE();
|
||||
}
|
||||
18
cores/beken-72xx/base/api/lt_wdt.c
Normal file
18
cores/beken-72xx/base/api/lt_wdt.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
bool lt_wdt_enable(uint32_t timeout) {
|
||||
wdt_ctrl(WCMD_SET_PERIOD, &timeout);
|
||||
wdt_ctrl(WCMD_POWER_UP, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lt_wdt_disable() {
|
||||
wdt_ctrl(WCMD_POWER_DOWN, NULL);
|
||||
}
|
||||
|
||||
void lt_wdt_feed() {
|
||||
wdt_ctrl(WCMD_RELOAD_PERIOD, NULL);
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-02-27. */
|
||||
|
||||
#include <libretiny.h>
|
||||
#include <sdk_private.h>
|
||||
|
||||
// can't include <flash.h> as it collides with <Flash.h> 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
|
||||
|
||||
void lt_init_family() {
|
||||
// set default UART output port
|
||||
uart_print_port = LT_UART_DEFAULT_PORT - 1;
|
||||
}
|
||||
|
||||
/* _____ _____ _ _
|
||||
/ ____| __ \| | | |
|
||||
| | | |__) | | | |
|
||||
| | | ___/| | | |
|
||||
| |____| | | |__| |
|
||||
\_____|_| \____*/
|
||||
lt_cpu_model_t lt_cpu_get_model() {
|
||||
uint8_t chipId = *(uint8_t *)(SCTRL_CHIP_ID);
|
||||
return CPU_MODEL_ENUM(FAMILY, chipId);
|
||||
}
|
||||
|
||||
uint32_t lt_cpu_get_unique_id() {
|
||||
return lt_cpu_get_mac_id();
|
||||
}
|
||||
|
||||
uint32_t lt_cpu_get_mac_id() {
|
||||
uint8_t mac[6];
|
||||
cfg_load_mac(mac); // force loading MAC from TLV (ignore user-set WiFi MAC)
|
||||
return (mac[3]) | (mac[4] << 8) | (mac[5] << 16);
|
||||
}
|
||||
|
||||
const char *lt_cpu_get_core_type() {
|
||||
return "ARM968E-S";
|
||||
}
|
||||
|
||||
/*_____ _
|
||||
| __ \ (_)
|
||||
| | | | _____ ___ ___ ___
|
||||
| | | |/ _ \ \ / / |/ __/ _ \
|
||||
| |__| | __/\ V /| | (_| __/
|
||||
|_____/ \___| \_/ |_|\___\__*/
|
||||
void lt_reboot() {
|
||||
bk_reboot();
|
||||
}
|
||||
|
||||
bool lt_reboot_download_mode() {
|
||||
bk_reboot();
|
||||
return true;
|
||||
}
|
||||
|
||||
lt_reboot_reason_t lt_get_reboot_reason() {
|
||||
switch (bk_misc_get_start_type()) {
|
||||
case RESET_SOURCE_POWERON:
|
||||
return REBOOT_REASON_POWER;
|
||||
case RESET_SOURCE_REBOOT:
|
||||
return REBOOT_REASON_SOFTWARE;
|
||||
case RESET_SOURCE_WATCHDOG:
|
||||
return REBOOT_REASON_WATCHDOG;
|
||||
case RESET_SOURCE_CRASH_XAT0:
|
||||
case RESET_SOURCE_CRASH_UNDEFINED:
|
||||
case RESET_SOURCE_CRASH_PREFETCH_ABORT:
|
||||
case RESET_SOURCE_CRASH_DATA_ABORT:
|
||||
case RESET_SOURCE_CRASH_UNUSED:
|
||||
case RESET_SOURCE_CRASH_PER_XAT0:
|
||||
return REBOOT_REASON_CRASH;
|
||||
case RESET_SOURCE_DEEPPS_GPIO:
|
||||
case RESET_SOURCE_DEEPPS_RTC:
|
||||
case RESET_SOURCE_DEEPPS_USB:
|
||||
return REBOOT_REASON_SLEEP;
|
||||
default:
|
||||
return REBOOT_REASON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
/*______ _ _
|
||||
| ____| | | |
|
||||
| |__ | | __ _ ___| |__
|
||||
| __| | |/ _` / __| '_ \
|
||||
| | | | (_| \__ \ | | |
|
||||
|_| |_|\__,_|___/_| |*/
|
||||
lt_flash_id_t lt_flash_get_id() {
|
||||
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) {}
|
||||
lt_flash_id_t id = {
|
||||
.manufacturer_id = REG_RD8(REG_FLASH_RDID, 2),
|
||||
.chip_id = REG_RD8(REG_FLASH_RDID, 1),
|
||||
.chip_size_id = REG_RD8(REG_FLASH_RDID, 0),
|
||||
};
|
||||
return id;
|
||||
}
|
||||
|
||||
/*__ __
|
||||
| \/ |
|
||||
| \ / | ___ _ __ ___ ___ _ __ _ _
|
||||
| |\/| |/ _ \ '_ ` _ \ / _ \| '__| | | |
|
||||
| | | | __/ | | | | | (_) | | | |_| |
|
||||
|_| |_|\___|_| |_| |_|\___/|_| \__, |
|
||||
__/ |
|
||||
|__*/
|
||||
uint32_t lt_ram_get_size() {
|
||||
return 256 * 1024;
|
||||
}
|
||||
|
||||
uint32_t lt_heap_get_size() {
|
||||
#if configDYNAMIC_HEAP_SIZE
|
||||
extern unsigned char _empty_ram;
|
||||
#if CFG_SOC_NAME == SOC_BK7231N
|
||||
return (0x00400000 + 192 * 1024) - (uint32_t)(&_empty_ram);
|
||||
#else
|
||||
return (0x00400000 + 256 * 1024) - (uint32_t)(&_empty_ram);
|
||||
#endif
|
||||
#else
|
||||
return configTOTAL_HEAP_SIZE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ____ _______
|
||||
/ __ \__ __|/\
|
||||
| | | | | | / \
|
||||
| | | | | | / /\ \
|
||||
| |__| | | |/ ____ \
|
||||
\____/ |_/_/ \*/
|
||||
|
||||
lt_ota_type_t lt_ota_get_type() {
|
||||
return OTA_TYPE_SINGLE;
|
||||
}
|
||||
|
||||
bool lt_ota_is_valid(uint8_t index) {
|
||||
if (index != 0)
|
||||
return false;
|
||||
// check download RBL
|
||||
// TODO: maybe check header CRC or even binary hashes
|
||||
uint32_t magic;
|
||||
lt_flash_read(FLASH_DOWNLOAD_OFFSET, (uint8_t *)&magic, 4);
|
||||
return magic == 0x004C4252; // "RBL\0", little-endian
|
||||
}
|
||||
|
||||
uint8_t lt_ota_dual_get_current() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t lt_ota_dual_get_stored() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool lt_ota_switch(bool revert) {
|
||||
if (!lt_ota_is_valid(0))
|
||||
// no valid "download" image
|
||||
// - return false when trying to activate
|
||||
// - return true when trying to revert
|
||||
return revert;
|
||||
if (revert) {
|
||||
// there's a valid "download" image, which has to be removed
|
||||
return lt_flash_erase_block(FLASH_DOWNLOAD_OFFSET);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*_ __ _ _ _
|
||||
\ \ / / | | | | | |
|
||||
\ \ /\ / /_ _| |_ ___| |__ __| | ___ __ _
|
||||
\ \/ \/ / _` | __/ __| '_ \ / _` |/ _ \ / _` |
|
||||
\ /\ / (_| | || (__| | | | (_| | (_) | (_| |
|
||||
\/ \/ \__,_|\__\___|_| |_|\__,_|\___/ \__, |
|
||||
__/ |
|
||||
|___*/
|
||||
bool lt_wdt_enable(uint32_t timeout) {
|
||||
wdt_ctrl(WCMD_SET_PERIOD, &timeout);
|
||||
wdt_ctrl(WCMD_POWER_UP, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void lt_wdt_disable() {
|
||||
wdt_ctrl(WCMD_POWER_DOWN, NULL);
|
||||
}
|
||||
|
||||
void lt_wdt_feed() {
|
||||
wdt_ctrl(WCMD_RELOAD_PERIOD, NULL);
|
||||
}
|
||||
@@ -2,11 +2,16 @@
|
||||
|
||||
#error "Don't include this file directly"
|
||||
|
||||
#define LT_HAS_PRINTF 1
|
||||
#define LT_HAS_LWIP 1
|
||||
#define LT_HAS_LWIP2 1
|
||||
#define LT_HAS_FREERTOS 1
|
||||
#define LT_HAS_MBEDTLS 1
|
||||
#define LT_HAS_FLASH 1
|
||||
#define LT_HAS_FREERTOS 1
|
||||
#define LT_HAS_LWIP 1
|
||||
#define LT_HAS_LWIP2 1
|
||||
#define LT_HAS_MBEDTLS 1
|
||||
#define LT_HAS_OTA 1
|
||||
#define LT_HAS_PRINTF 1
|
||||
#define LT_HW_DEEP_SLEEP 1
|
||||
#define LT_HW_WATCHDOG 1
|
||||
#define LT_HW_WIFI 1
|
||||
|
||||
#define LT_HEAP_FUNC xPortGetFreeHeapSize
|
||||
#define LT_REALLOC_FUNC pvPortRealloc
|
||||
|
||||
@@ -2,15 +2,19 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include LT_VARIANT_H
|
||||
#include <lt_pins.h>
|
||||
|
||||
// Choose the main UART output port
|
||||
#ifndef LT_UART_DEFAULT_PORT
|
||||
#if HAS_SERIAL2
|
||||
#if LT_HW_UART2
|
||||
#define LT_UART_DEFAULT_PORT 2
|
||||
#elif HAS_SERIAL1
|
||||
#elif LT_HW_UART1
|
||||
#define LT_UART_DEFAULT_PORT 1
|
||||
#else
|
||||
#error "No serial port is available"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto-download-reboot detection pattern
|
||||
// Link check command (CMD_LinkCheck=0)
|
||||
#define LT_UART_ADR_PATTERN 0x01, 0xE0, 0xFC, 0x01, 0x00
|
||||
|
||||
26
cores/beken-72xx/base/sdk_extern.h
Normal file
26
cores/beken-72xx/base/sdk_extern.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-24. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#include <uart_pub.h>
|
||||
|
||||
// SDK
|
||||
extern uint8_t system_mac[];
|
||||
extern int uart_print_port;
|
||||
uint32_t wdt_ctrl(uint32_t cmd, void *param);
|
||||
void bk_send_byte(uint8_t uport, uint8_t data);
|
||||
void uart_hw_set_change(uint8_t uport, bk_uart_config_t *uart_config);
|
||||
int uart_rx_callback_set(int uport, uart_callback callback, void *param);
|
||||
void sctrl_enter_rtos_deep_sleep(PS_DEEP_CTRL_PARAM *deep_param);
|
||||
void ps_delay(volatile UINT16 times);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
@@ -6,12 +6,19 @@
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// most stuff is here
|
||||
// most stuff is here - this has to be before other includes!
|
||||
#include <include.h>
|
||||
// other includes
|
||||
#include <arm_arch.h>
|
||||
#include <bk_timer.h>
|
||||
#include <bk_timer_pub.h>
|
||||
#include <flash_pub.h>
|
||||
#include <gpio_pub.h>
|
||||
#include <manual_ps_pub.h>
|
||||
#include <param_config.h>
|
||||
#include <pwm_pub.h>
|
||||
#include <rtos_pub.h>
|
||||
#include <saradc_pub.h>
|
||||
#include <start_type_pub.h>
|
||||
#include <sys_ctrl.h>
|
||||
#include <sys_rtos.h>
|
||||
@@ -19,9 +26,7 @@ extern "C" {
|
||||
#include <wdt_pub.h>
|
||||
#include <wlan_ui_pub.h>
|
||||
|
||||
extern uint8_t system_mac[];
|
||||
extern uint32_t wdt_ctrl(uint32_t cmd, void *param);
|
||||
extern int uart_print_port;
|
||||
#include <sdk_extern.h>
|
||||
|
||||
// conflict with stl_algobase.h
|
||||
#undef min
|
||||
|
||||
36
cores/common/arduino/libraries/api/Serial/Serial.cpp
Normal file
36
cores/common/arduino/libraries/api/Serial/Serial.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2023-05-23. */
|
||||
|
||||
#include "Serial.h"
|
||||
|
||||
SerialClass::SerialClass(uint32_t port, pin_size_t rx, pin_size_t tx) {
|
||||
this->port = port;
|
||||
this->rx = rx;
|
||||
this->tx = tx;
|
||||
this->buf = NULL;
|
||||
this->data = NULL;
|
||||
}
|
||||
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT && defined(LT_UART_ADR_PATTERN)
|
||||
static uint8_t adrState = 0;
|
||||
static uint8_t adrCmd[] = {LT_UART_ADR_PATTERN};
|
||||
|
||||
void SerialClass::adrParse(uint8_t c) {
|
||||
adrState = (adrState + 1) * (c == adrCmd[adrState]);
|
||||
if (adrState == sizeof(adrCmd) / sizeof(uint8_t)) {
|
||||
LT_I("Auto download mode: rebooting");
|
||||
LT.restartDownloadMode();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int SerialClass::available() {
|
||||
return this->buf && this->buf->available();
|
||||
}
|
||||
|
||||
int SerialClass::peek() {
|
||||
return this->buf ? this->buf->peek() : -1;
|
||||
}
|
||||
|
||||
int SerialClass::read() {
|
||||
return this->buf ? this->buf->read_char() : -1;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <api/ArduinoAPI.h>
|
||||
#include <Arduino.h>
|
||||
#include <api/HardwareSerial.h>
|
||||
#include <api/RingBuffer.h>
|
||||
|
||||
@@ -10,17 +10,31 @@ using namespace arduino;
|
||||
|
||||
class SerialClass : public HardwareSerial {
|
||||
private:
|
||||
uint8_t port;
|
||||
RingBuffer *buf;
|
||||
uint32_t port;
|
||||
pin_size_t rx;
|
||||
pin_size_t tx;
|
||||
|
||||
public:
|
||||
SerialClass(uint8_t port);
|
||||
void *data;
|
||||
|
||||
private:
|
||||
RingBuffer *buf;
|
||||
uint32_t baudrate;
|
||||
uint16_t config;
|
||||
|
||||
public:
|
||||
SerialClass(uint32_t port, pin_size_t rx = PIN_INVALID, pin_size_t tx = PIN_INVALID);
|
||||
|
||||
inline void begin(unsigned long baudrate) {
|
||||
begin(baudrate, SERIAL_8N1);
|
||||
}
|
||||
|
||||
inline void configure(unsigned long baudrate) {
|
||||
configure(baudrate, SERIAL_8N1);
|
||||
}
|
||||
|
||||
void begin(unsigned long baudrate, uint16_t config);
|
||||
void configure(unsigned long baudrate, uint16_t config);
|
||||
void end();
|
||||
int available();
|
||||
int peek();
|
||||
@@ -32,5 +46,12 @@ class SerialClass : public HardwareSerial {
|
||||
return !!buf;
|
||||
}
|
||||
|
||||
public:
|
||||
#if LT_AUTO_DOWNLOAD_REBOOT
|
||||
static void adrParse(uint8_t c);
|
||||
#endif
|
||||
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
#define HAS_SERIAL_CLASS 1
|
||||
@@ -3,11 +3,11 @@
|
||||
#include "WiFi.h"
|
||||
|
||||
void WiFiClass::printDiag(Print &dest) {
|
||||
const char *modes[] = {"NULL", "STA", "AP", "STA+AP"};
|
||||
const char *enc[] = {"Open", "WEP", "WPA PSK", "WPA2 PSK", "WPA/WPA2", "WPA", "WPA2"};
|
||||
|
||||
dest.print("Mode: ");
|
||||
dest.println(modes[getMode()]);
|
||||
dest.println(WiFiModeText[getMode()]);
|
||||
|
||||
dest.print("Status: ");
|
||||
dest.println(WiFiStatusText[status()]);
|
||||
|
||||
if (getMode() & WIFI_MODE_STA) {
|
||||
dest.println("-- Station --");
|
||||
@@ -21,7 +21,7 @@ void WiFiClass::printDiag(Print &dest) {
|
||||
dest.print("RSSI: ");
|
||||
dest.println(RSSI());
|
||||
dest.print("Encryption: ");
|
||||
dest.println(enc[getEncryption()]);
|
||||
dest.println(WiFiAuthModeText[getEncryption()]);
|
||||
dest.print("IP: ");
|
||||
dest.println(localIP());
|
||||
dest.print("MAC: ");
|
||||
|
||||
@@ -11,7 +11,7 @@ bool WiFiClass::mode(WiFiMode mode) {
|
||||
pWiFi = this;
|
||||
|
||||
WiFiMode currentMode = getMode();
|
||||
LT_DM(WIFI, "Mode changing %u -> %u", currentMode, mode);
|
||||
LT_DM(WIFI, "Mode changing %s -> %s", WiFiModeText[currentMode], WiFiModeText[mode]);
|
||||
if (mode == currentMode)
|
||||
return true;
|
||||
|
||||
|
||||
@@ -162,3 +162,28 @@ typedef enum {
|
||||
WLMODE_DISABLE = 1,
|
||||
WLMODE_ENABLE = 2,
|
||||
} WiFiModeAction;
|
||||
|
||||
static const char *WiFiModeText[] = {"NULL", "STA", "AP", "AP+STA"};
|
||||
static const char *WiFiStatusText[] = {
|
||||
"Idle",
|
||||
"No SSID",
|
||||
"Scan Completed",
|
||||
"Connected",
|
||||
"Connect failed",
|
||||
"Connection lost",
|
||||
"Disconnected",
|
||||
};
|
||||
static const char *WiFiAuthModeText[] = {
|
||||
"Open",
|
||||
"WEP",
|
||||
"WPA PSK",
|
||||
"WPA2 PSK",
|
||||
"WPA/WPA2 PSK",
|
||||
"WPA2 EAP",
|
||||
"WPA3 PSK",
|
||||
"WPA2/WPA3 PSK",
|
||||
"WAPI PSK",
|
||||
"WPA",
|
||||
"WPA2",
|
||||
"Auto",
|
||||
};
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
#include <Arduino.h>
|
||||
|
||||
// available built-in implementations
|
||||
#if LT_ARD_MD5_POLARSSL
|
||||
#include "MD5PolarSSLImpl.h"
|
||||
#endif
|
||||
#if LT_ARD_MD5_MBEDTLS
|
||||
#include "MD5MbedTLSImpl.h"
|
||||
#endif
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/* Copyright (c) Kuba Szczodrzyński 2022-06-03. */
|
||||
|
||||
#if LT_ARD_MD5_POLARSSL
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <polarssl/md5.h>
|
||||
|
||||
void MD5Init(md5_context *context) {
|
||||
md5_init(context);
|
||||
md5_starts(context);
|
||||
}
|
||||
|
||||
void MD5Update(md5_context *context, const unsigned char *buf, unsigned len) {
|
||||
md5_update(context, buf, len);
|
||||
}
|
||||
|
||||
void MD5Final(unsigned char digest[16], md5_context *context) {
|
||||
md5_finish(context, digest);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // LT_ARD_MD5_POLARSSL
|
||||
@@ -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
|
||||
@@ -2,9 +2,25 @@
|
||||
|
||||
#include "Update.h"
|
||||
|
||||
UpdateClass::UpdateClass() : ctx(NULL), info(NULL), buf(NULL) {
|
||||
cleanup();
|
||||
}
|
||||
static const UpdateError errorMap[] = {
|
||||
UPDATE_ERROR_OK, /* UF2_ERR_OK - no error */
|
||||
UPDATE_ERROR_OK, /* UF2_ERR_IGNORE - block should be ignored */
|
||||
UPDATE_ERROR_MAGIC_BYTE, /* UF2_ERR_MAGIC - wrong magic numbers */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_FAMILY - family ID mismatched */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_NOT_HEADER - block is not a header */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_OTA_VER - unknown/invalid OTA format version */
|
||||
UPDATE_ERROR_MAGIC_BYTE, /* UF2_ERR_OTA_WRONG - no data for current OTA scheme */
|
||||
UPDATE_ERROR_NO_PARTITION, /* UF2_ERR_PART_404 - no partition with that name */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_PART_INVALID - invalid partition info tag */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_PART_UNSET - attempted to write without target partition */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_DATA_TOO_LONG - data too long - tags won't fit */
|
||||
UPDATE_ERROR_BAD_ARGUMENT, /* UF2_ERR_SEQ_MISMATCH - sequence number mismatched */
|
||||
UPDATE_ERROR_ERASE, /* UF2_ERR_ERASE_FAILED - erasing flash failed */
|
||||
UPDATE_ERROR_WRITE, /* UF2_ERR_WRITE_FAILED - writing to flash failed */
|
||||
UPDATE_ERROR_WRITE, /* UF2_ERR_WRITE_LENGTH - wrote fewer data than requested */
|
||||
UPDATE_ERROR_WRITE, /* UF2_ERR_WRITE_PROTECT - target area is write-protected */
|
||||
UPDATE_ERROR_WRITE, /* UF2_ERR_ALLOC_FAILED - dynamic memory allocation failed */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Initialize the update process.
|
||||
@@ -13,55 +29,110 @@ UpdateClass::UpdateClass() : ctx(NULL), info(NULL), buf(NULL) {
|
||||
* @param command must be U_FLASH
|
||||
* @return false if parameters are invalid or update is running, true otherwise
|
||||
*/
|
||||
bool UpdateClass::begin(size_t size, int command, int unused2, uint8_t unused3, const char *unused4) {
|
||||
if (ctx)
|
||||
return false;
|
||||
cleanup();
|
||||
|
||||
LT_DM(OTA, "begin(%u, ...) / OTA curr: %u, scheme: %u", size, lt_ota_dual_get_current(), lt_ota_get_uf2_scheme());
|
||||
|
||||
ctx = uf2_ctx_init(lt_ota_get_uf2_scheme(), FAMILY);
|
||||
info = uf2_info_init();
|
||||
|
||||
if (!size) {
|
||||
cleanup(UPDATE_ERROR_SIZE);
|
||||
bool UpdateClass::begin(
|
||||
size_t size,
|
||||
int command,
|
||||
__attribute__((unused)) int ledPin,
|
||||
__attribute__((unused)) uint8_t ledOn,
|
||||
__attribute__((unused)) const char *label
|
||||
) {
|
||||
#if !LT_HAS_OTA
|
||||
LT_E("OTA is not yet supported on this chip!");
|
||||
this->errArd = UPDATE_ERROR_BAD_ARGUMENT;
|
||||
return false;
|
||||
#endif
|
||||
if (this->ctx) {
|
||||
return false;
|
||||
}
|
||||
this->clearError();
|
||||
if (size == 0) {
|
||||
this->errArd = UPDATE_ERROR_SIZE;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (command != U_FLASH) {
|
||||
cleanup(UPDATE_ERROR_BAD_ARGUMENT);
|
||||
this->errArd = UPDATE_ERROR_BAD_ARGUMENT;
|
||||
return false;
|
||||
}
|
||||
if (size == UPDATE_SIZE_UNKNOWN) {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
this->ctx = static_cast<lt_ota_ctx_t *>(malloc(sizeof(lt_ota_ctx_t)));
|
||||
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);
|
||||
|
||||
bytesTotal = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finalize the update process. Check for errors and update completion, then activate the new firmware image.
|
||||
*
|
||||
* @param evenIfRemaining no idea
|
||||
* @return false in case of errors or no update running, true otherwise
|
||||
* @param evenIfRemaining don't raise errors if still in progress
|
||||
* @return false in case of errors or no update running; true otherwise
|
||||
*/
|
||||
bool UpdateClass::end(bool evenIfRemaining) {
|
||||
if (hasError() || !ctx)
|
||||
// false if not running
|
||||
if (!this->ctx)
|
||||
return false;
|
||||
|
||||
if (!isFinished() && !evenIfRemaining) {
|
||||
// update is running or finished; cleanup and end it
|
||||
if (!isFinished() && !evenIfRemaining)
|
||||
// abort if not finished
|
||||
cleanup(UPDATE_ERROR_ABORT);
|
||||
return false;
|
||||
}
|
||||
// TODO what is evenIfRemaining for?
|
||||
// try to activate the second OTA
|
||||
if (!lt_ota_switch(/* revert= */ false)) {
|
||||
cleanup(UPDATE_ERROR_ACTIVATE);
|
||||
return false;
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cleanup (free) the update context.
|
||||
* Try activating the firmware if possible, set local error codes.
|
||||
*
|
||||
* @param clearError assume successful finish after correct activation
|
||||
*/
|
||||
void UpdateClass::cleanup(bool clearError) {
|
||||
if (!this->ctx)
|
||||
return;
|
||||
|
||||
if (!lt_ota_end(this->ctx)) {
|
||||
// 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();
|
||||
} else if (this->ctx->error > UF2_ERR_IGNORE) {
|
||||
// make error code based on UF2OTA code
|
||||
this->errArd = errorMap[this->ctx->error];
|
||||
this->errUf2 = this->ctx->error;
|
||||
} else {
|
||||
// only keep Arduino error code (set by the caller)
|
||||
this->errUf2 = UF2_ERR_OK;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
return true;
|
||||
#if LT_DEBUG_OTA
|
||||
if (this->hasError())
|
||||
this->printErrorContext();
|
||||
#endif
|
||||
|
||||
free(this->ctx);
|
||||
this->ctx = nullptr;
|
||||
free(this->md5Ctx);
|
||||
this->md5Ctx = nullptr;
|
||||
free(this->md5Digest);
|
||||
this->md5Digest = nullptr;
|
||||
free(this->md5Expected);
|
||||
this->md5Expected = nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,60 +140,45 @@ bool UpdateClass::end(bool evenIfRemaining) {
|
||||
*
|
||||
* It's advised to write in 512-byte chunks (or its multiples).
|
||||
*
|
||||
* @param data
|
||||
* @param len
|
||||
* @return size_t
|
||||
* @param data chunk of data
|
||||
* @param len length of the chunk
|
||||
* @return size_t amount of bytes written
|
||||
*/
|
||||
size_t UpdateClass::write(uint8_t *data, size_t len) {
|
||||
size_t written = 0;
|
||||
if (hasError() || !ctx)
|
||||
// 0 if not running
|
||||
size_t UpdateClass::write(const uint8_t *data, size_t len) {
|
||||
if (!this->ctx)
|
||||
return 0;
|
||||
|
||||
LT_VM(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)) {
|
||||
// returns 0 if data contains an invalid block
|
||||
return written;
|
||||
}
|
||||
data += UF2_BLOCK_SIZE;
|
||||
len -= UF2_BLOCK_SIZE;
|
||||
written += UF2_BLOCK_SIZE;
|
||||
} */
|
||||
|
||||
// write until buffer space is available
|
||||
uint16_t toWrite; // 1..512
|
||||
while (len && (toWrite = min(len, bufLeft()))) {
|
||||
tryWriteData(data, toWrite);
|
||||
if (hasError()) {
|
||||
// return on errors
|
||||
printErrorContext2(data, toWrite);
|
||||
return written;
|
||||
}
|
||||
data += toWrite;
|
||||
len -= toWrite;
|
||||
written += toWrite;
|
||||
}
|
||||
size_t written = lt_ota_write(ctx, data, len);
|
||||
MD5Update(this->md5Ctx, data, len);
|
||||
if (written != len)
|
||||
this->cleanup(/* clearError= */ false);
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write all data remaining in the given stream.
|
||||
*
|
||||
* If the stream doesn't produce any data within UPDATE_TIMEOUT_MS,
|
||||
* the update process will be aborted.
|
||||
*
|
||||
* @param data stream to read from
|
||||
* @return size_t amount of bytes written
|
||||
*/
|
||||
size_t UpdateClass::writeStream(Stream &data) {
|
||||
size_t written = 0;
|
||||
if (hasError() || !ctx)
|
||||
// 0 if not running
|
||||
if (!this->ctx)
|
||||
return 0;
|
||||
|
||||
size_t written = 0;
|
||||
uint32_t lastData = millis();
|
||||
// loop until the update is complete
|
||||
while (remaining()) {
|
||||
// check stream availability
|
||||
int available = data.available();
|
||||
auto available = data.available();
|
||||
if (available <= 0) {
|
||||
if (millis() - lastData > UPDATE_TIMEOUT_MS) {
|
||||
// waited for data too long; abort with error
|
||||
cleanup(UPDATE_ERROR_STREAM);
|
||||
this->errArd = UPDATE_ERROR_STREAM;
|
||||
this->cleanup(/* clearError= */ false);
|
||||
return written;
|
||||
}
|
||||
continue;
|
||||
@@ -131,94 +187,23 @@ size_t UpdateClass::writeStream(Stream &data) {
|
||||
lastData = millis();
|
||||
|
||||
// read data to fit in the remaining buffer space
|
||||
bufAlloc();
|
||||
uint16_t read = data.readBytes(bufPos, bufLeft());
|
||||
bufPos += read;
|
||||
written += read;
|
||||
tryWriteData();
|
||||
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
|
||||
if (bufSize + read == UF2_BLOCK_SIZE)
|
||||
lt_ota_write_block(this->ctx, reinterpret_cast<uf2_block_t *>(this->ctx->buf));
|
||||
// abort on errors
|
||||
if (hasError()) {
|
||||
// return on errors
|
||||
printErrorContext2(NULL, read); // buf is not valid anymore
|
||||
this->cleanup(/* clearError= */ false);
|
||||
return written;
|
||||
}
|
||||
written += read;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to use the buffer as a block to write. In case of UF2 errors,
|
||||
* error codes are set, the update is aborted and 0 is returned
|
||||
*
|
||||
* @param data received data to copy to buffer or NULL if already in buffer
|
||||
* @param len received data length - must be at most bufLeft()
|
||||
* @return size_t "used" data size - 0 or 512
|
||||
*/
|
||||
size_t UpdateClass::tryWriteData(uint8_t *data, size_t len) {
|
||||
uf2_block_t *block = NULL;
|
||||
|
||||
LT_VM(OTA, "Writing %u to buffer (%u/512)", len, bufSize());
|
||||
|
||||
if (len == UF2_BLOCK_SIZE) {
|
||||
// data has a complete block
|
||||
block = (uf2_block_t *)data;
|
||||
} else if (data && len) {
|
||||
// data has a part of a block, copy it to buffer
|
||||
bufAlloc();
|
||||
memcpy(bufPos, data, len);
|
||||
bufPos += len;
|
||||
}
|
||||
|
||||
if (!block && bufSize() == UF2_BLOCK_SIZE) {
|
||||
// use buffer as block (only if not found above)
|
||||
block = (uf2_block_t *)buf;
|
||||
}
|
||||
|
||||
// a complete block has been found
|
||||
if (block) {
|
||||
if (checkUf2Error(uf2_check_block(ctx, block)))
|
||||
// block is invalid
|
||||
return 0;
|
||||
|
||||
if (errUf2 == UF2_ERR_IGNORE)
|
||||
// treat ignored blocks as valid
|
||||
return UF2_BLOCK_SIZE;
|
||||
|
||||
if (!bytesWritten) {
|
||||
// parse header block to allow retrieving firmware info
|
||||
if (checkUf2Error(uf2_parse_header(ctx, block, info)))
|
||||
// header is invalid
|
||||
return 0;
|
||||
|
||||
LT_IM(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_EM(OTA, "Image size wrong; got %u, calculated %u", bytesTotal, block->block_count * UF2_BLOCK_SIZE);
|
||||
cleanup(UPDATE_ERROR_SIZE);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// write data blocks normally
|
||||
if (checkUf2Error(uf2_write(ctx, block)))
|
||||
// block writing failed
|
||||
return 0;
|
||||
}
|
||||
|
||||
// increment total writing progress
|
||||
bytesWritten += UF2_BLOCK_SIZE;
|
||||
// call progress callback
|
||||
if (callback)
|
||||
callback(bytesWritten, bytesTotal);
|
||||
// reset the buffer as it's used already
|
||||
if (bufSize() == UF2_BLOCK_SIZE)
|
||||
bufPos = buf;
|
||||
return UF2_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UpdateClass Update;
|
||||
|
||||
@@ -1,42 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <MD5.h>
|
||||
#include <functional>
|
||||
#include <uf2ota/uf2ota.h>
|
||||
|
||||
// No Error
|
||||
#define UPDATE_ERROR_OK (0)
|
||||
// Flash Write Failed
|
||||
#define UPDATE_ERROR_WRITE (1)
|
||||
// Flash Erase Failed
|
||||
#define UPDATE_ERROR_ERASE (2)
|
||||
// Flash Read Failed
|
||||
#define UPDATE_ERROR_READ (3)
|
||||
// Not Enough Space
|
||||
#define UPDATE_ERROR_SPACE (4)
|
||||
// Bad Size Given
|
||||
#define UPDATE_ERROR_SIZE (5)
|
||||
// Stream Read Timeout
|
||||
#define UPDATE_ERROR_STREAM (6)
|
||||
// MD5 Check Failed
|
||||
#define UPDATE_ERROR_MD5 (7)
|
||||
// Wrong Magic Byte
|
||||
#define UPDATE_ERROR_MAGIC_BYTE (8)
|
||||
// Could Not Activate The Firmware
|
||||
#define UPDATE_ERROR_ACTIVATE (9)
|
||||
// Partition Could Not be Found
|
||||
#define UPDATE_ERROR_NO_PARTITION (10)
|
||||
// Bad Argument
|
||||
#define UPDATE_ERROR_BAD_ARGUMENT (11)
|
||||
// Aborted
|
||||
#define UPDATE_ERROR_ABORT (12)
|
||||
typedef enum {
|
||||
UPDATE_ERROR_OK = 0, //!< No Error
|
||||
UPDATE_ERROR_WRITE = 1, //!< Flash Write Failed
|
||||
UPDATE_ERROR_ERASE = 2, //!< Flash Erase Failed
|
||||
UPDATE_ERROR_READ = 3, //!< Flash Read Failed
|
||||
UPDATE_ERROR_SPACE = 4, //!< Not Enough Space
|
||||
UPDATE_ERROR_SIZE = 5, //!< Bad Size Given
|
||||
UPDATE_ERROR_STREAM = 6, //!< Stream Read Timeout
|
||||
UPDATE_ERROR_MD5 = 7, //!< MD5 Check Failed
|
||||
UPDATE_ERROR_MAGIC_BYTE = 8, //!< Wrong Magic Byte
|
||||
UPDATE_ERROR_ACTIVATE = 9, //!< Could Not Activate The Firmware
|
||||
UPDATE_ERROR_NO_PARTITION = 10, //!< Partition Could Not be Found
|
||||
UPDATE_ERROR_BAD_ARGUMENT = 11, //!< Bad Argument
|
||||
UPDATE_ERROR_ABORT = 12, //!< Aborted
|
||||
} UpdateError;
|
||||
|
||||
typedef enum {
|
||||
U_FLASH = 0,
|
||||
U_SPIFFS = 100,
|
||||
U_AUTH = 200,
|
||||
} UpdateCommand;
|
||||
|
||||
#define UPDATE_SIZE_UNKNOWN 0xFFFFFFFF
|
||||
|
||||
#define U_FLASH 0
|
||||
#define U_SPIFFS 100
|
||||
#define U_AUTH 200
|
||||
|
||||
#define ENCRYPTED_BLOCK_SIZE 16
|
||||
|
||||
#define UPDATE_TIMEOUT_MS 30 * 1000
|
||||
@@ -46,109 +38,138 @@ class UpdateClass {
|
||||
typedef std::function<void(size_t, size_t)> THandlerFunction_Progress;
|
||||
|
||||
public: /* Update.cpp */
|
||||
UpdateClass();
|
||||
bool begin(
|
||||
size_t size = UPDATE_SIZE_UNKNOWN,
|
||||
int command = U_FLASH,
|
||||
int unused2 = -1,
|
||||
uint8_t unused3 = LOW,
|
||||
const char *unused4 = NULL // this is for SPIFFS
|
||||
size_t size = UPDATE_SIZE_UNKNOWN,
|
||||
int command = U_FLASH,
|
||||
int ledPin = -1,
|
||||
uint8_t ledOn = LOW,
|
||||
const char *label = nullptr
|
||||
);
|
||||
bool end(bool evenIfRemaining = false);
|
||||
size_t write(uint8_t *data, size_t len);
|
||||
|
||||
size_t write(const uint8_t *data, size_t len);
|
||||
size_t writeStream(Stream &data);
|
||||
bool canRollBack();
|
||||
bool rollBack();
|
||||
// bool setMD5(const char *expected_md5);
|
||||
|
||||
private: /* Update.cpp */
|
||||
size_t tryWriteData(uint8_t *data = NULL, size_t len = 0);
|
||||
void cleanup(bool clearError = false);
|
||||
|
||||
public: /* UpdateUtil.cpp */
|
||||
UpdateClass &onProgress(THandlerFunction_Progress callback);
|
||||
void abort();
|
||||
void printError(Print &out);
|
||||
const char *errorString();
|
||||
const char *getFirmwareName();
|
||||
const char *getFirmwareVersion();
|
||||
const char *getLibreTinyVersion();
|
||||
const char *getBoardName();
|
||||
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();
|
||||
const char *errorString() const;
|
||||
void printError(Print &out) const;
|
||||
|
||||
private: /* UpdateUtil.cpp */
|
||||
void cleanup(uint8_t ardErr = UPDATE_ERROR_OK, uf2_err_t uf2Err = UF2_ERR_OK);
|
||||
bool checkUf2Error(uf2_err_t err);
|
||||
void bufAlloc();
|
||||
void printErrorContext1();
|
||||
void printErrorContext2(const uint8_t *data, size_t len);
|
||||
uint16_t bufLeft();
|
||||
uint16_t bufSize();
|
||||
static void progressHandler(UpdateClass *self);
|
||||
void printErrorContext();
|
||||
|
||||
private:
|
||||
// uf2ota context
|
||||
uf2_ota_t *ctx;
|
||||
uf2_info_t *info;
|
||||
// block buffer
|
||||
uint8_t *buf;
|
||||
uint8_t *bufPos;
|
||||
// update progress - multiplies of 512 bytes
|
||||
uint32_t bytesWritten;
|
||||
uint32_t bytesTotal;
|
||||
// errors
|
||||
uf2_err_t errUf2;
|
||||
uint8_t errArd;
|
||||
// progress callback
|
||||
THandlerFunction_Progress callback;
|
||||
// String _target_md5;
|
||||
// MD5Builder _md5;
|
||||
lt_ota_ctx_t *ctx{nullptr};
|
||||
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:
|
||||
String md5String(void) {
|
||||
// return _md5.toString();
|
||||
return "";
|
||||
/**
|
||||
* @brief Get Arduino error code of the update.
|
||||
*/
|
||||
inline UpdateError getError() const {
|
||||
return this->errArd;
|
||||
}
|
||||
|
||||
void md5(uint8_t *result) {
|
||||
// return _md5.getBytes(result);
|
||||
/**
|
||||
* @brief Get UF2OTA error code of the update.
|
||||
*/
|
||||
inline uf2_err_t getUF2Error() const {
|
||||
return this->ctx ? this->ctx->error : this->errUf2;
|
||||
}
|
||||
|
||||
uint8_t getError() {
|
||||
return errArd;
|
||||
/**
|
||||
* @brief Same as end().
|
||||
*/
|
||||
inline void abort() {
|
||||
this->end();
|
||||
}
|
||||
|
||||
uf2_err_t getUF2Error() {
|
||||
return errUf2;
|
||||
/**
|
||||
* @brief Check if the update process has been started.
|
||||
*/
|
||||
inline bool isRunning() {
|
||||
return this->ctx;
|
||||
}
|
||||
|
||||
uint16_t getErrorCode() {
|
||||
return (errArd << 8) | errUf2;
|
||||
/**
|
||||
* @brief Check if the update process hasn't been started or has been completed.
|
||||
*/
|
||||
inline bool isFinished() {
|
||||
return !(this->ctx && this->ctx->bytes_written != this->ctx->bytes_total);
|
||||
}
|
||||
|
||||
void clearError() {
|
||||
cleanup(UPDATE_ERROR_OK);
|
||||
/**
|
||||
* @brief Return complete update image size.
|
||||
*/
|
||||
inline size_t size() {
|
||||
return this->ctx ? this->ctx->bytes_total : 0;
|
||||
}
|
||||
|
||||
bool hasError() {
|
||||
return errArd != UPDATE_ERROR_OK;
|
||||
/**
|
||||
* @brief Return amount of bytes already written.
|
||||
*/
|
||||
inline size_t progress() {
|
||||
return this->ctx ? this->ctx->bytes_written : 0;
|
||||
}
|
||||
|
||||
bool isRunning() {
|
||||
return ctx != NULL;
|
||||
/**
|
||||
* @brief Return amount of bytes remaining to write.
|
||||
*/
|
||||
inline size_t remaining() {
|
||||
return this->size() - this->progress();
|
||||
}
|
||||
|
||||
bool isFinished() {
|
||||
return bytesWritten == bytesTotal;
|
||||
/**
|
||||
* @brief Get firmware name from UF2 info.
|
||||
*/
|
||||
inline const char *getFirmwareName() {
|
||||
if (this->ctx)
|
||||
return this->ctx->info.fw_name;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
return bytesTotal;
|
||||
/**
|
||||
* @brief Get firmware version from UF2 info.
|
||||
*/
|
||||
inline const char *getFirmwareVersion() {
|
||||
if (this->ctx)
|
||||
return this->ctx->info.fw_version;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t progress() {
|
||||
return bytesWritten;
|
||||
/**
|
||||
* @brief Get LibreTiny version from UF2 info.
|
||||
*/
|
||||
inline const char *getLibreTinyVersion() {
|
||||
if (this->ctx)
|
||||
return this->ctx->info.lt_version;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t remaining() {
|
||||
return bytesTotal - bytesWritten;
|
||||
/**
|
||||
* @brief Get target board name from UF2 info.
|
||||
*/
|
||||
inline const char *getBoardName() {
|
||||
if (this->ctx)
|
||||
return this->ctx->info.board;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user