40 Commits

Author SHA1 Message Date
d967be0245 x
Some checks failed
Push (dev), Pull Request / Run Clang lint (push) Has been cancelled
Push (dev), Pull Request / Run Python lint (push) Has been cancelled
2026-01-02 01:43:15 -07:00
b040f336d4 (XXX) use scratch lwip 2026-01-02 01:43:15 -07:00
1bf1ea7596 [common] Log at warning level mDNS services or TXT records cannot be added 2026-01-02 01:43:15 -07:00
Kuba Szczodrzyński
29303f7ec9 [boards] Add generic-rtl8720cf-2mb-896k board
Some checks failed
Push (dev), Pull Request / Run Clang lint (push) Has been cancelled
Push (dev), Pull Request / Run Python lint (push) Has been cancelled
Push (master) / Deploy docs (push) Has been cancelled
2025-11-17 20:32:54 +01:00
Kuba Szczodrzyński
c6b06d4be6 [release] v1.9.2
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2025-09-19 22:44:44 +02:00
Kuba Szczodrzyński
c9b2f9dd23 [boards] Fix syntax error in WB02A 2025-09-19 22:44:44 +02:00
Kuba Szczodrzyński
40590d174f [core] Update ltchiptool to v4.12.2 2025-09-19 22:39:47 +02:00
Rishab Mehta
780fb72bba [docs] Update README.md (#323) 2025-09-19 22:37:02 +02:00
Henri Chain
e9977a26e4 [boards] Add WB02A board (#332) 2025-09-19 22:36:51 +02:00
Piotr Szulc
1d97f0ce84 [core] Avoid re-defining C++ round() method (#321) 2025-09-19 22:36:35 +02:00
Luca Olivetti
895b6e89c5 [lightning-ln882h] Fix GPIO interrupt support (#326)
* fix interrupt handling for the ln882h

- all GPIOS can generate interrupts
- added calls to NVIC_SetPriority/NVIC_EnableIRQ/NVIC_DisableIRQ

* fix clang formatting error

* only call NVIC_DisableIRQ if no other gpio is using an interrupt

* fix (again) clang-format errors

* add IRQ capability on all pins

* don't bother with NVIC_DisableIRQ

* use pin->gpio instead of interruptNumber, use macro GPIO_GET_PORT for clarity

* Mark interrupts as supported for the LN882H

---------

Co-authored-by: lamauny <pub.elc@free.fr>
2025-09-19 22:25:03 +02:00
Kuba Szczodrzyński
9114bc4c49 [release] v1.9.1
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2025-06-01 19:38:36 +02:00
Kuba Szczodrzyński
9eae0cd253 [common] Add Arduino emptyString declaration 2025-06-01 19:38:11 +02:00
Kuba Szczodrzyński
37f096d3b5 [release] v1.9.0
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2025-05-28 15:51:09 +02:00
Kuba Szczodrzyński
6bf549b104 [misc] Update .clang-format style 2025-05-28 15:50:18 +02:00
lamauny
3054db9d9b [lightning-ln882h] Fix analog read, add Wi-Fi calibration, add generic board (#319)
* [ln882x] fix analog read

* [ln882h] add wifi temp calibration task

* [ln882h] add generic-ln882hki board

* [ln882h] fix wifi null pointer crash
2025-05-28 15:45:10 +02:00
lamauny
69e7e2debe [lightning-ln882h] Add support for Lightning LN882H family (#312)
* fix mbedtls bad pointer in function call (prototype mismatch)

* fix issue with weak families functions implemented in static library, it will never be linked. fixed by redefining prototypes inside families

* [ln882x] add support for lightning ln882x & ln882h families

* add i2c (wire) support

* add analog (adc) support

* add watchdog support

* [ln882x] changed default uart 0/1 pins; added board wl2s

* [ln882x] fix IRQ & ADC pins

* [ln882x] boards cosmetic

* [ln882x] wifi sta use otp mac addr by default; re-enabled wifi powersave mode

* [ln882x] clang-format clean code

* [ln882x] clang-format clean code

* Update families.json

* Apply suggestions from code review

* [ln882x] reformat json board files

* [ln882x] os_queue cleanup

* [ln882x] removed Beken auto-download command

* [ln882x] removed personal script file

* [ln882x] removed unusefull pi section in debugging.md

* [ln882x] removed Arduino.h and changed private I2C definition

* [ln882x] updated README.md

* [ln882x] changed pin naming scheme to PA/PB

* [ln882x] clean code

* [ln882x] clean code

* [ln882x] add ota image verification

* Update push-dev.yml

* [ln882x] fix boards ADC missing inputs]

* [ln882x] removed reg_xxx fixup files and use include guards instead

* [ln882x] cleanup code

* [ln882x] cleanup code

* [ln882x] fix lt_init weak functions linking

* [ln882x] revert lt_api.h modification, fixed with previous commit

* [ln882x] setup UF2 firmware for flasher with partitions

* [ln882x] update README.md

* [ln882x] include ln_wifi.h and ln_serial.h to avoid including bad headers on case insensitive systems

* [ln882x] Replace RingBuffer by SerialRingBuffer

* [ln882x] clang-format

* [ln882x] update README.md

* Apply suggestions from code review

* Reformat board JSON files

* Add mkdocs link redirect

* Update ltchiptool to v4.12.0

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2025-03-25 17:26:53 +01:00
Kuba Szczodrzyński
6083cca72e [misc] Update style to clang-format 19, black 25 and isort 6 2025-01-30 18:50:55 +01:00
Kuba Szczodrzyński
d17ea4da0f [release] v1.8.0
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2025-01-14 22:13:16 +01:00
Hajo Noerenberg
2ea0066536 [common] Make Serial RX buffer size configurable, increase default to 256 bytes (#313)
* Make Serial RX buffer configurable and set default to 256 bytes

* Replace RingBuffer by SerialRingBuffer
2025-01-13 12:14:41 +01:00
Martin Prokopič
3d23211c1e [realtek-ambz2] Fix partition table & bootloader flashing via UART (#307) 2024-12-17 17:13:04 +01:00
shilga
1769680d9e [realtek-ambz2] Fix C linkage for sys_now() in lwipopts (#286) 2024-12-17 11:50:44 +01:00
kuwoyuki
92351c0b92 [boards] Add RTL8710BX AFW121T board (#305)
* feat: afw121t board

* Update layout, regenerate with boardgen

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-12-16 15:46:36 +01:00
Kuba Szczodrzyński
0f6c31386b [release] v1.7.0
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2024-09-05 16:41:10 +02:00
Kuba Szczodrzyński
a9009a8cee [misc] Update .clang-format style 2024-09-05 16:36:55 +02:00
Piotr Szulc
31e1d51dbd [common] Cleanup mDNS code, cache service records (#263)
* Handle possible failure of mdns_resp_add_service

* One more place where mdns_resp_add_service may fail

* addServiceImpl should always store services

* Register in services when new netif is added

* Refactored handling of cached services.

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-09-05 15:54:04 +02:00
Luca Olivetti
41819f2fd6 [beken-72xx] Fix CHANGE interrupt logic (#290)
* fix CHANGE interrupt for beken-72xx

* Update cores/beken-72xx/arduino/src/wiring_irq.c

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-09-05 14:46:42 +02:00
David Woodhouse
17043f634f [beken-72xx] Add IPv6 and lwIP 2.2.0 support (#292)
* mDNS: Fix build against LwIP 2.2.0

* Stop defining ip_addr_t when !CONFIG_IPV6

The only reason we had to do this is because we forgot to define LWIP_IPV4,
which is fixed in our LwIP port now, but keep it around for !CONFIG_IPV6
for now for builds against older LwIP.

* Allow returning IPv6 results from WiFiClass::hostByName()

* Add ipv6 and extra mDNS files for LwIP 2.2.0

* Add IPv6 support to BK72xx WifiSTA

Add an allLocalIPv6() method to return a *vector* of addresses, rather
than just one. It's not clear where the enableIpV6() and localIPv6()
methods came from; they don't seem to be part of the standard Arduino
class.

Eventually at least for ESPHome, I'd like to stop using these classes
and just let the ESPHome wifi component talk directly to LwIP. Or maybe
LibreTiny should offer an API compatible with the esp-idf one which is
a light wrapper around LwIP.

But short of a major refactor, this seems like a reasonable option.

* Update LwIP default to 2.2.0

* Apply suggestions from code review

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-09-05 14:46:13 +02:00
devgs
e1c5761df9 [beken-72xx] Allow setting deep sleep wake-up pins as floating (#275)
According to guide `gpio_stay_*_map` are specifically there to prevent
pulling pins to a specific level and let them float during deep sleep.

https://docs.bekencorp.com/sdk_3.0.x/bk7238/build/en/latest/developer-guide/power_save/sleep_test.html

This allows any external low-power circuitry to change a pin level, as
required, to trigger the wake up

This requires changes in BDK and was implemented via fixup. Also, exposed
`gpio_stay_lo_map` parameter via `lt_deep_sleep_keep_floating_gpio` to
manage this configuration for pins in range P0-P31.
2024-09-05 14:45:48 +02:00
Kuba Szczodrzyński
fbaae21011 [release] v1.6.0
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2024-05-31 15:01:17 +02:00
Jaco Malan
fa2064b957 [realtek-ambz] Temporarily workaround CHANGE interrupts not supported (#282)
* fix change interruptsnot supported on rtl8710b

* Update cores/realtek-amb/arduino/src/wiring_irq.c

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-05-31 14:59:46 +02:00
Kuba Szczodrzyński
21a194f43d [core] Fix lwIP debugging support 2024-05-31 14:58:38 +02:00
devgs
b255402659 [beken-72xx] Fix race condition when checking Wi-Fi SSID (#274)
* Fix for a race condition in WiFi connection loop

There seems to be the race between the event RW_EVT_STA_CONNECTED
and an actual valid SSID value returned by BDK. If even a small delay
is injected immediately after the event reception the valid value
becomes available. Without this fix, due to a polling nature of ESPHome
WiFiComponent::check_connecting_finished function may observe the
WiFiSTAConnectStatus::CONNECTED status but with an empty SSID value,
leading to `Incomplete connection.` warning and immediate attempt to
start another connection, while the current one was actually established.

* Fixed clang format conformance

* Apply suggestions from code review

* Update cores/beken-72xx/arduino/libraries/WiFi/WiFiEvents.cpp

Co-authored-by: Cossid <83468485+Cossid@users.noreply.github.com>

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
Co-authored-by: Cossid <83468485+Cossid@users.noreply.github.com>
2024-05-31 14:54:41 +02:00
Kuba Szczodrzyński
dfabfbb921 [beken-72xx] Increase MBEDTLS_ENTROPY_MAX_SOURCES 2024-05-18 13:50:25 +02:00
Kuba Szczodrzyński
3b36a70c9a [core] Fix ESP_LOG#() macro syntax 2024-05-18 13:50:10 +02:00
Piotr Szulc
d1386a8e9d [libs] Fix mDNS string memory corruption, print error on record add failure (#260)
* Fixed unsafe conversion to underscore string

* Fixed formatting

* Save one byte if underscore not needed

* Don't allocate new string if already underscored

* Fix missing first character while copying

* Renamed function and made it inline

* Don't use signed index variable when searching for service

* Add proper cleanup of LwIPmDNS

- Free allocated memory both on end() and in the destructor
- Unregister callback from netif

* Don't free const pointer

* Removed unneeded casting

* Don't break the loop if failed to add txt record

* Fixed code formatting
2024-03-08 12:21:14 +01:00
Kuba Szczodrzyński
67b92b7f56 [release] v1.5.1
Some checks failed
Release / Run Clang lint (push) Has been cancelled
Release / Publish PlatformIO platform (push) Has been cancelled
Release / Publish GitHub release (push) Has been cancelled
2024-02-29 14:14:01 +01:00
Hajo Noerenberg
a1f8516e60 [realtek-ambz] Fix crash after WiFi scan (#258) 2024-02-26 21:35:35 +01:00
cap9qd
cf52021d38 [core] Split reboot reasons due to wakeup (#254)
* Updates to break out wakeup reasons.

Per https://github.com/libretiny-eu/libretiny/issues/234

* Update cores/common/base/api/lt_device.h

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

* fix clang-format

* Fix formatting of python files.

* Update lt_device.h

---------

Co-authored-by: Kuba Szczodrzyński <kuba@szczodrzynski.pl>
2024-02-25 18:45:22 +01:00
cap9qd
b78c9387a6 [beken-72xx] Fix duration rollover in deep sleep (#253) 2024-02-22 20:24:40 +01:00
150 changed files with 7458 additions and 494 deletions

View File

@@ -1,11 +1,14 @@
# 2025-02-12
Language: Cpp
BasedOnStyle: LLVM
AlignAfterOpenBracket: BlockIndent
AlignArrayOfStructures: Left
AlignConsecutiveAssignments: true
AlignConsecutiveMacros: AcrossComments
AlignEscapedNewlinesLeft: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortFunctionsOnASingleLine: Empty
AlwaysBreakTemplateDeclarations: Yes
@@ -21,7 +24,7 @@ IndentCaseLabels: true
IndentWidth: 4
LambdaBodyIndentation: Signature
MaxEmptyLinesToKeep: 1
# PointerAlignment: Left # TODO enable this and reformat project
PenaltyReturnTypeOnItsOwnLine: 1000
QualifierAlignment: Left
ReflowComments: true
SeparateDefinitionBlocks: Always

View File

@@ -3,6 +3,7 @@ on:
push:
branches: ["**"]
pull_request:
workflow_dispatch:
jobs:
lint-clang:
name: Run Clang lint

View File

@@ -15,10 +15,11 @@
![RTL8710BN](https://img.shields.io/badge/-rtl8710bn-blue)
![BK7231](https://img.shields.io/badge/-bk7231-blue)
![LN882H](https://img.shields.io/badge/-ln882h-blue)
</div>
PlatformIO development platform for BK7231 and RTL8710 IoT chips.
PlatformIO development platform for BK7231, RTL8710 and LN882H IoT chips.
The main goal of this project is to provide a usable build environment for IoT developers. While also providing vendor SDKs as PlatformIO cores,
the project focuses on developing working Arduino-compatible cores for supported families. The cores are inspired by Espressif's official core for ESP32,

View File

@@ -19,6 +19,7 @@
* [Realtek AmebaZ](docs/platform/realtek-ambz/README.md)
* [Debugging](docs/platform/realtek-ambz/debugging.md)
* [Exception decoder](docs/platform/realtek-ambz/exception-decoder.md)
* [Lightning LN882x](docs/platform/lightning-ln882x/README.md)
* [🔧 LT Configuration](docs/dev/config.md)
* 🧑 Programmer's manual
* [⚠️ Migration guide](docs/dev/migration_v1.0.0.md)

View File

@@ -0,0 +1,221 @@
{
"pcb": {
"ic": {
"7": {
"IO": "I",
"CTRL": "CEN"
},
"8": {
"C_NAME": "PA_0",
"GPIO": "PA00",
"IRQ": null,
"ADC": 2,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"9": {
"C_NAME": "PA_1",
"GPIO": "PA01",
"IRQ": null,
"ADC": 3,
"SWD": "DIO",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"10": {
"C_NAME": "PA_2",
"GPIO": "PA02",
"IRQ": null,
"UART": "0_TX",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"11": {
"C_NAME": "PA_3",
"GPIO": "PA03",
"IRQ": null,
"UART": "0_RX",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"12": {
"C_NAME": "PA_4",
"GPIO": "PA04",
"IRQ": null,
"ADC": 4,
"SWD": "CLK",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"13": {
"C_NAME": "PA_5",
"GPIO": "PA05",
"IRQ": null,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"14": {
"C_NAME": "PA_6",
"GPIO": "PA06",
"IRQ": null,
"SD": "D2",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"15": {
"C_NAME": "PA_7",
"GPIO": "PA07",
"IRQ": null,
"SD": "D3",
"I2S": "0_RX",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"16": {
"C_NAME": "PA_8",
"GPIO": "PA08",
"IRQ": null,
"CTRL": "BOOT0",
"SD": "CMD",
"I2S": "0_WS",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"17": {
"C_NAME": "PA_9",
"GPIO": "PA09",
"IRQ": null,
"CTRL": "BOOT1",
"SD": "CLK",
"I2S": "0_SCLK",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"21": {
"C_NAME": "PA_10",
"GPIO": "PA10",
"IRQ": null,
"SD": "D0",
"I2S": "0_TX",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"22": {
"C_NAME": "PA_11",
"GPIO": "PA11",
"IRQ": null,
"SD": "D1",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"23": {
"C_NAME": "PA_12",
"GPIO": "PA12",
"IRQ": null,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"24": {
"C_NAME": "PB_3",
"GPIO": "PB03",
"GPIONUM": 19,
"IRQ": null,
"ADC": 5,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"25": {
"C_NAME": "PB_4",
"GPIO": "PB04",
"GPIONUM": 20,
"IRQ": null,
"ADC": 6,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"26": {
"C_NAME": "PB_5",
"GPIO": "PB05",
"GPIONUM": 21,
"IRQ": null,
"ADC": 7,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"27": {
"C_NAME": "PB_6",
"GPIO": "PB06",
"GPIONUM": 22,
"IRQ": null,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"28": {
"C_NAME": "PB_7",
"GPIO": "PB07",
"GPIONUM": 23,
"IRQ": null,
"I2C": [
"0_SCL",
"0_SDA"
]
},
"29": {
"C_NAME": "PB_8",
"GPIO": "PB08",
"GPIONUM": 24,
"IRQ": null,
"UART": "1_RX",
"I2C": [
"0_SCL",
"0_SDA"
]
},
"30": {
"C_NAME": "PB_9",
"GPIO": "PB09",
"GPIONUM": 25,
"IRQ": null,
"UART": "1_TX",
"I2C": [
"0_SCL",
"0_SDA"
]
}
}
}
}

View File

@@ -0,0 +1,31 @@
{
"build": {
"family": "LN882H",
"ldscript": "ln882hki_bsp.ld",
"bootfile": "boot_ln882h.bin"
},
"flash": {
"boot": "0x000000+0x06000",
"part_tab": "0x006000+0x01000",
"app": "0x007000+0x12C000",
"ota": "0x133000+0xAA000",
"nvds": "0x1DD000+0x03000",
"kv": "0x1E0000+0x04000",
"kvs": "0x1E4000+0x08000",
"user": "0x1EC000+0x14000"
},
"upload": {
"flash_size": 2097152,
"maximum_size": 1228800
},
"connectivity": [
"ble"
],
"doc": {
"params": {
"extra": {
"Bluetooth": "BLE v5.1"
}
}
}
}

View File

@@ -0,0 +1,43 @@
{
"build": {
"f_cpu": "160000000L",
"prefix": "arm-none-eabi-"
},
"flash": {},
"connectivity": [
"wifi"
],
"debug": {
"protocol": "openocd",
"protocols": [
"openocd"
],
"openocd_config": "ln882x.cfg",
"gdb_init": [
"mem 0x00000000 0x10000000 ro"
]
},
"upload": {
"maximum_ram_size": 302080,
"require_upload_port": true,
"speed": 115200,
"protocol": "uart",
"protocols": [
"uart"
]
},
"doc": {
"params": {
"manufacturer": "Lightning",
"series": "LN882X",
"voltage": "3.0V - 3.6V",
"extra": {
"Wi-Fi": "802.11 b/g/n"
}
},
"links": {
"Info & flashing guide": "../../docs/platform/lightning-ln882x/README.md",
"Debugging": "../../docs/platform/lightning-ln882x/debugging.md"
}
}
}

View File

@@ -0,0 +1,90 @@
{
"pcb": {
"templates": [
"99iot-21p",
"pcb-blue-light",
"rf-type1"
],
"scale": 16,
"vars": {
"TRACE_COLOR": "#FAFD9D"
},
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD",
"pinout": {
"1": {
"GND": null
},
"2": {
"CTRL": "RF_O"
},
"3": {
"GND": null
},
"4": {
"NC": null
},
"5": {
"CTRL": "CEN"
},
"6": {
"IC": 13,
"ARD": "D0"
},
"7": {
"IC": 14,
"ARD": "D1"
},
"8": {
"IC": 16,
"ARD": "D2"
},
"9": {
"IC": 17,
"ARD": "D3"
},
"10": {
"GND": null
},
"11": {
"PWR": 3.3
},
"12": {
"GND": null
},
"13": {
"NC": null
},
"14": {
"IC": 28,
"ARD": "D5"
},
"15": {
"IC": 29,
"ARD": "D6"
},
"16": {
"IC": 30,
"ARD": "D7"
},
"17": {
"IC": 31,
"ARD": "D8"
},
"18": {
"IC": 32,
"ARD": "D9"
},
"19": {
"IC": 1,
"ARD": "D10"
},
"20": {
"IC": 2,
"ARD": "D4"
},
"21": {
"GND": null
}
}
}
}

View File

@@ -0,0 +1,23 @@
{
"pcb": {
"test_pads": {
"TBOOT": "ln-02.back.boot.anchor"
},
"back": [
{
"id": "boot",
"name": "label_line_up",
"pos": "12,12.1",
"vars": {
"DIR": "right",
"W": 2.5,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "11,12"
}
]
}
}

View File

@@ -0,0 +1,67 @@
{
"pcb": {
"templates": [
"tuya2",
"pcb-black",
"rf-type1"
],
"scale": 10.5,
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,I2C",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 22,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 24,
"ARD": [
"D1",
"A0"
]
},
"5": {
"IC": 11,
"ARD": "D2"
},
"6": {
"IC": 29,
"ARD": "D3"
},
"7": {
"IC": 10,
"ARD": "D4"
},
"8": {
"IC": 30,
"ARD": "D5"
},
"9": {
"IC": 9,
"ARD": [
"D6",
"A1"
]
},
"10": {
"IC": 7
},
"11": {
"IC": 8,
"ARD": [
"D7",
"A2"
]
},
"TBOOT": {
"IC": 17,
"ARD": "D8"
}
}
}
}

View File

@@ -0,0 +1,93 @@
{
"pcb": {
"test_pads": {
"TA9": "wb02a.back.a9.anchor",
"TGND": "wb02a.back.gnd.anchor",
"TRX1": "wb02a.back.rx1.anchor",
"TTX1": "wb02a.back.tx1.anchor"
},
"back": [
{
"type": "text",
"pos": "0.5,2.3",
"text": "WB02A-0882H-1518D1",
"font_size": 1.4,
"fill": {
"color": "${SILK_COLOR}"
}
},
{
"type": "circle",
"pos": "11.6,6.4",
"d": 4.5,
"preset": "copper1"
},
{
"type": "rect",
"pos": "3.5,8.5",
"size": "4.2,3.7",
"preset": "copper1"
},
{
"id": "a9",
"name": "label_line_up",
"pos": "1.9,12.3",
"vars": {
"DIR": "left",
"W": 1.3,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "2.5,12.3"
},
{
"id": "gnd",
"name": "label_line_up",
"pos": ".6,6.6",
"vars": {
"DIR": "left",
"W": 0,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "1.2,6.6"
},
{
"id": "rx1",
"name": "label_line_up",
"pos": "3.2,6",
"vars": {
"DIR": "left",
"W": 2.6,
"H": 1.4
}
},
{
"name": "test_pad_1mm",
"pos": "3.2,6.6"
},
{
"id": "tx1",
"name": "label_line_up",
"pos": "5.2,6",
"vars": {
"DIR": "left",
"W": 4.6,
"H": 3.4
}
},
{
"name": "test_pad_1mm",
"pos": "5.2,6.6"
},
{
"name": "test_pad_1mm",
"pos": "8.5,12.3"
}
]
}
}

View File

@@ -0,0 +1,75 @@
{
"pcb": {
"templates": [
"tuya2",
"pcb-blue-light",
"rf-type1"
],
"scale": 10.5,
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,I2C",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 15,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 13,
"ARD": "D1"
},
"5": {
"IC": 11,
"ARD": "D2"
},
"6": {
"IC": 21,
"ARD": "D3"
},
"7": {
"IC": 10,
"ARD": "D4"
},
"8": {
"IC": 9,
"ARD": [
"D5",
"A0"
]
},
"9": {
"IC": 12,
"ARD": [
"D6",
"A1"
]
},
"10": {
"IC": 7
},
"11": {
"IC": 13,
"ARD": "D1"
},
"TA9": {
"IC": 17,
"ARD": "D7"
},
"TGND": {
"GND": null
},
"TRX1": {
"IC": 29,
"ARD": "D8"
},
"TTX1": {
"IC": 30,
"ARD": "D9"
}
}
}
}

View File

@@ -0,0 +1,98 @@
{
"pcb": {
"test_pads": {
"TA9": "wl2s.back.a9.anchor",
"TGND": "wl2s.back.gnd.anchor",
"TRX1": "wl2s.back.rx1.anchor",
"TTX1": "wl2s.back.tx1.anchor",
"TSCLK": "wl2s.back.sclk.anchor",
"TSWD": "wl2s.back.swd.anchor"
},
"back": [
{
"id": "a9",
"name": "label_line_up",
"pos": "2.8,11.8",
"vars": {
"DIR": "left",
"W": 2.5,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "3,12"
},
{
"id": "gnd",
"name": "label_line_up",
"pos": "0.8,8.3",
"vars": {
"DIR": "left",
"W": 0.5,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "1,8.5"
},
{
"id": "rx1",
"name": "label_line_up",
"pos": "3,5.8",
"vars": {
"DIR": "left",
"W": 2.6,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "3.2,6"
},
{
"id": "tx1",
"name": "label_line_up",
"pos": "5,5.8",
"vars": {
"DIR": "left",
"W": 4.5,
"H": 2
}
},
{
"name": "test_pad_1mm",
"pos": "5.2,6"
},
{
"id": "swd",
"name": "label_line_up",
"pos": "10.2,11.1",
"vars": {
"DIR": "right",
"W": 3.0,
"H": 1
}
},
{
"name": "test_pad_1mm",
"pos": "10,11"
},
{
"id": "sclk",
"name": "label_line_up",
"pos": "5.2,12.2",
"vars": {
"DIR": "right",
"W": 8.0,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "5,12"
}
]
}
}

View File

@@ -0,0 +1,86 @@
{
"pcb": {
"templates": [
"tuya2",
"pcb-blue-light",
"rf-type1"
],
"scale": 10.5,
"pinout_hidden": "I2S,TRIG,WAKE,CTS,RTS,SD,SPI,I2C",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 15,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 23,
"ARD": "D1"
},
"5": {
"IC": 11,
"ARD": "D2"
},
"6": {
"IC": 21,
"ARD": "D3"
},
"7": {
"IC": 10,
"ARD": "D4"
},
"8": {
"IC": 8,
"ARD": [
"D5",
"A0"
]
},
"9": {
"IC": 24,
"ARD": [
"D6",
"A1"
]
},
"10": {
"IC": 7
},
"11": {
"IC": 22,
"ARD": "D7"
},
"TA9": {
"IC": 17,
"ARD": "D8"
},
"TGND": {
"GND": null
},
"TRX1": {
"IC": 29,
"ARD": "D9"
},
"TTX1": {
"IC": 30,
"ARD": "D10"
},
"TSCLK": {
"IC": 13,
"ARD": "D11"
},
"TSWD": {
"IC": 9,
"ARD": [
"D12",
"A2"
]
}
}
}
}

View File

@@ -0,0 +1,16 @@
{
"build": {
"amb_boot_all": "boot_all_77F7.bin"
},
"flash": {
"ota1": "0x00B000+0x75000",
"ota2": "0x080000+0x75000",
"kvs": "0x0F5000+0x4000",
"userdata": "0x0F9000+0x7000"
},
"upload": {
"flash_size": 1048576,
"maximum_size": 479232
}
}

View File

@@ -2,8 +2,7 @@
"flash": {
"ota1": "0x010000+0xE0000",
"ota2": "0x0F0000+0xE0000",
"kvs": "0x1D0000+0x8000",
"userdata": "0x1D8000+0x28000"
"kvs": "0x1F8000+0x8000"
},
"upload": {
"flash_size": 2097152,

24
boards/afw121t.json Normal file
View File

@@ -0,0 +1,24 @@
{
"_base": [
"realtek-ambz",
"realtek-ambz-1mb-468k",
"realtek-ambz-bx",
"ic/rtl8710bn",
"pcb/afw121t"
],
"build": {
"mcu": "rtl8710bx",
"variant": "afw121t"
},
"name": "AFW121T",
"url": "https://item.szlcsc.com/357903.html?fromZone=l_b__%2522brand%2522",
"vendor": "99iot(Shenzhen)co.,ltd",
"pcb": {
"symbol": "AFW121T"
},
"doc": {
"links": {
"Vendor datasheet": "https://item.szlcsc.com/datasheet/AFW121TI-AY1LED1/357903.html"
}
}
}

View File

@@ -0,0 +1,118 @@
{
"_base": [
"generic",
"lightning-ln882x",
"lightning-ln882hki",
"ic/ln882hk"
],
"build": {
"mcu": "ln882hk",
"variant": "generic-ln882hki"
},
"name": "Generic - LN882HKI",
"symbol": "LN882HKI",
"url": "https://docs.libretiny.eu/boards/generic-ln882hki/",
"vendor": "Generic",
"pcb": {
"pinout": {
"1": {
"IC": 8,
"ARD": [
"D0",
"A2"
]
},
"2": {
"IC": 9,
"ARD": [
"D1",
"A3"
]
},
"3": {
"IC": 10,
"ARD": "D2"
},
"4": {
"IC": 11,
"ARD": "D3"
},
"5": {
"IC": 12,
"ARD": [
"D4",
"A4"
]
},
"6": {
"IC": 13,
"ARD": "D5"
},
"7": {
"IC": 14,
"ARD": "D6"
},
"8": {
"IC": 15,
"ARD": "D7"
},
"9": {
"IC": 16,
"ARD": "D8"
},
"10": {
"IC": 17,
"ARD": "D9"
},
"11": {
"IC": 21,
"ARD": "D10"
},
"12": {
"IC": 22,
"ARD": "D11"
},
"13": {
"IC": 23,
"ARD": "D12"
},
"14": {
"IC": 24,
"ARD": [
"D13",
"A5"
]
},
"15": {
"IC": 25,
"ARD": [
"D14",
"A6"
]
},
"16": {
"IC": 26,
"ARD": [
"D15",
"A7"
]
},
"17": {
"IC": 27,
"ARD": "D16"
},
"18": {
"IC": 28,
"ARD": "D17"
},
"19": {
"IC": 29,
"ARD": "D18"
},
"20": {
"IC": 30,
"ARD": "D19"
}
}
}
}

View File

@@ -0,0 +1,102 @@
{
"_base": [
"generic",
"realtek-ambz2",
"realtek-ambz2-8720",
"realtek-ambz2-image",
"realtek-ambz2-2mb-896k",
"ic/rtl8720cf"
],
"build": {
"mcu": "rtl8720cf",
"variant": "generic-rtl8720cf-2mb-896k"
},
"name": "Generic - RTL8720CF (2M/896k)",
"symbol": "RTL8720CF (2M/896k)",
"url": "https://docs.libretiny.eu/boards/generic-rtl8720cf-2mb-896k/",
"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"
}
}
}
}

22
boards/ln-02.json Normal file
View File

@@ -0,0 +1,22 @@
{
"_base": [
"lightning-ln882x",
"lightning-ln882hki",
"ic/ln882hk",
"pcb/ln-02",
"pcb/ln-02-test"
],
"build": {
"mcu": "ln882hk",
"variant": "ln-02"
},
"name": "LN-02 Wi-Fi/BLE Module",
"url": "https://docs.libretiny.eu/boards/ln-02/",
"vendor": "Unknown",
"doc": {
"fccid": ""
},
"pcb": {
"symbol": "LN-02"
}
}

View File

@@ -0,0 +1,142 @@
{
"name": "99iot-21p",
"title": "99iot 21-pin modules",
"width": 18,
"height": 22,
"vars": {
"PINTYPE_VERT": "pin_vert_cast_nohole",
"PINTYPE_HORZ": "pin_horz_cast_nohole",
"RASTER": 1.2,
"RF_W": 18,
"RF_H": 3.9
},
"front": [
{
"comment": "PCB soldermask",
"type": "rect",
"pos": "0,0",
"size": "18,22",
"preset": "${MASK_PRESET}"
},
{
"comment": "Metal shielding",
"type": "rect",
"pos": "1.105,7",
"size": "15.79,14.58",
"preset": "shield"
},
{
"comment": "Pins (1-3)",
"id": "left_t",
"name": "r_pins_vert",
"repeat": 3,
"pos": "0,3.9",
"vars": {
"PINDIR": "left"
}
},
{
"comment": "Pins (3-10)",
"id": "left_b",
"name": "r_pins_vert",
"repeat": 7,
"pos": "0,12.8",
"vars": {
"PINDIR": "left"
}
},
{
"comment": "Pins (10-20)",
"id": "right_b",
"name": "r_pins_vert",
"repeat": 10,
"pos": "18,9.2",
"vars": {
"PINDIR": "right"
}
},
{
"comment": "Pin 21",
"id": "right_t",
"name": "r_pins_vert",
"repeat": 1,
"pos": "18,7",
"vars": {
"PINDIR": "right"
}
}
],
"back": [
{
"comment": "PCB soldermask",
"type": "rect",
"pos": "0,0",
"size": "18,22",
"preset": "${MASK_PRESET}"
},
{
"comment": "Pins (1-3)",
"id": "left_t",
"name": "r_pins_vert",
"repeat": 3,
"pos": "0,3.9",
"vars": {
"PINDIR": "left"
}
},
{
"comment": "Pins (3-10)",
"id": "left_b",
"name": "r_pins_vert",
"repeat": 7,
"pos": "0,12.8",
"vars": {
"PINDIR": "left"
}
},
{
"comment": "Pins (10-20)",
"id": "right_b",
"name": "r_pins_vert",
"repeat": 10,
"pos": "18,9.2",
"vars": {
"PINDIR": "right"
}
},
{
"comment": "Pin 21",
"id": "right_t",
"name": "r_pins_vert",
"repeat": 1,
"pos": "18,7",
"vars": {
"PINDIR": "right"
}
}
],
"pads": {
"1": "99iot-21p.front.left_t.pin1",
"2": "99iot-21p.front.left_t.pin2",
"3": "99iot-21p.front.left_t.pin3",
"4": "99iot-21p.front.left_b.pin1",
"5": "99iot-21p.front.left_b.pin2",
"6": "99iot-21p.front.left_b.pin3",
"7": "99iot-21p.front.left_b.pin4",
"8": "99iot-21p.front.left_b.pin5",
"9": "99iot-21p.front.left_b.pin6",
"10": "99iot-21p.front.left_b.pin7",
"11": "99iot-21p.front.right_b.pin10",
"12": "99iot-21p.front.right_b.pin9",
"13": "99iot-21p.front.right_b.pin8",
"14": "99iot-21p.front.right_b.pin7",
"15": "99iot-21p.front.right_b.pin6",
"16": "99iot-21p.front.right_b.pin5",
"17": "99iot-21p.front.right_b.pin4",
"18": "99iot-21p.front.right_b.pin3",
"19": "99iot-21p.front.right_b.pin2",
"20": "99iot-21p.front.right_b.pin1",
"21": "99iot-21p.front.right_t.pin1"
},
"test_pads": {}
}

48
boards/variants/afw121t.c Normal file
View File

@@ -0,0 +1,48 @@
/* This file was auto-generated from afw121t.json using boardgen */
#include <Arduino.h>
#ifdef LT_VARIANT_INCLUDE
#include LT_VARIANT_INCLUDE
#endif
// clang-format off
PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
// D0: PA14, PWM0, SWCLK
{PA_14, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
// D1: PA15, PWM1, SWDIO
{PA_15, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_SWD, PIN_NONE, 0},
// D2: PA00, PWM2
{PA_0, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D3: PA12, PWM3
{PA_12, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D4: PA29, UART2_RX, I2C0_SCL, PWM4
{PA_29, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D5: PA05, PWM4, WAKE1
{PA_5, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D6: PA18, UART0_RX, SPI0_SCK, SPI1_SCK, I2C1_SCL, SD_D2, TMR4_TRIG, I2S0_MCK, WAKE0
{PA_18, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0},
// D7: PA19, ADC1, UART0_CTS, SPI0_CS, SPI1_CS, I2C0_SDA, SD_D3, TMR5_TRIG, I2S0_TX
{PA_19, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0},
// D8: PA22, UART0_RTS, SPI0_MISO, SPI1_MISO, I2C0_SCL, SD_D0, PWM5, I2S0_WS, WAKE2
{PA_22, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_I2S | PIN_SPI | PIN_UART, PIN_NONE, 0},
// D9: PA23, UART0_TX, SPI0_MOSI, SPI1_MOSI, I2C1_SDA, SD_D1, PWM0, WAKE3
{PA_23, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_SPI | PIN_UART, PIN_NONE, 0},
// D10: PA30, UART2_TX, I2C0_SDA, PWM4
{PA_30, PIN_GPIO | PIN_IRQ | PIN_PWM | PIN_I2C | PIN_UART, PIN_NONE, 0},
};
PinInfo *lt_arduino_pin_gpio_map[] = {
[0] = &(lt_arduino_pin_info_list[2]), // PA_0 (D2)
[5] = &(lt_arduino_pin_info_list[5]), // PA_5 (D5)
[12] = &(lt_arduino_pin_info_list[3]), // PA_12 (D3)
[14] = &(lt_arduino_pin_info_list[0]), // PA_14 (D0)
[15] = &(lt_arduino_pin_info_list[1]), // PA_15 (D1)
[18] = &(lt_arduino_pin_info_list[6]), // PA_18 (D6)
[19] = &(lt_arduino_pin_info_list[7]), // PA_19 (D7)
[22] = &(lt_arduino_pin_info_list[8]), // PA_22 (D8)
[23] = &(lt_arduino_pin_info_list[9]), // PA_23 (D9)
[29] = &(lt_arduino_pin_info_list[4]), // PA_29 (D4)
[30] = &(lt_arduino_pin_info_list[10]), // PA_30 (D10)
};
// clang-format on

136
boards/variants/afw121t.h Normal file
View File

@@ -0,0 +1,136 @@
/* This file was auto-generated from afw121t.json using boardgen */
#pragma once
// clang-format off
// Pins
// ----
#define PINS_COUNT 11 // Total GPIO count
#define NUM_DIGITAL_PINS 11 // Digital inputs/outputs
#define NUM_ANALOG_INPUTS 0 // ADC inputs
#define NUM_ANALOG_OUTPUTS 9 // PWM & DAC outputs
#define PINS_GPIO_MAX 30 // Last usable GPIO number
// SPI Interfaces
// --------------
#define PIN_SPI0_CS 19u // PA_19
#define PIN_SPI0_MISO 22u // PA_22
#define PIN_SPI0_MOSI 23u // PA_23
#define PIN_SPI0_SCK 18u // PA_18
#define PIN_SPI1_CS 19u // PA_19
#define PIN_SPI1_MISO 22u // PA_22
#define PIN_SPI1_MOSI 23u // PA_23
#define PIN_SPI1_SCK 18u // PA_18
#define PINS_SPI0_CS (pin_size_t[]){19u}
#define PINS_SPI0_MISO (pin_size_t[]){22u}
#define PINS_SPI0_MOSI (pin_size_t[]){23u}
#define PINS_SPI0_SCK (pin_size_t[]){18u}
#define PINS_SPI1_CS (pin_size_t[]){19u}
#define PINS_SPI1_MISO (pin_size_t[]){22u}
#define PINS_SPI1_MOSI (pin_size_t[]){23u}
#define PINS_SPI1_SCK (pin_size_t[]){18u}
// Wire Interfaces
// ---------------
#define PIN_WIRE0_SCL_0 22u // PA_22
#define PIN_WIRE0_SCL_1 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
#define PINS_WIRE0_SCL (pin_size_t[]){22u, 29u}
#define PINS_WIRE0_SDA (pin_size_t[]){19u, 30u}
#define PINS_WIRE1_SCL (pin_size_t[]){18u}
#define PINS_WIRE1_SDA (pin_size_t[]){23u}
// Serial ports
// ------------
#define PIN_SERIAL0_CTS 19u // PA_19
#define PIN_SERIAL0_RTS 22u // PA_22
#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
#define PINS_SERIAL0_CTS (pin_size_t[]){19u}
#define PINS_SERIAL0_RTS (pin_size_t[]){22u}
#define PINS_SERIAL0_RX (pin_size_t[]){18u}
#define PINS_SERIAL0_TX (pin_size_t[]){23u}
#define PINS_SERIAL2_RX (pin_size_t[]){29u}
#define PINS_SERIAL2_TX (pin_size_t[]){30u}
// Pin function macros
// -------------------
#define PIN_ADC1 19u // PA_19
#define PIN_CS0 19u // PA_19
#define PIN_CS1 19u // PA_19
#define PIN_CTS0 19u // PA_19
#define PIN_MISO0 22u // PA_22
#define PIN_MISO1 22u // PA_22
#define PIN_MOSI0 23u // PA_23
#define PIN_MOSI1 23u // PA_23
#define PIN_PA00 0u // PA_0
#define PIN_PA05 5u // PA_5
#define PIN_PA12 12u // PA_12
#define PIN_PA14 14u // PA_14
#define PIN_PA15 15u // PA_15
#define PIN_PA18 18u // PA_18
#define PIN_PA19 19u // PA_19
#define PIN_PA22 22u // PA_22
#define PIN_PA23 23u // PA_23
#define PIN_PA29 29u // PA_29
#define PIN_PA30 30u // PA_30
#define PIN_PWM1 15u // PA_15
#define PIN_PWM2 0u // PA_0
#define PIN_PWM3 12u // PA_12
#define PIN_PWM4 29u // PA_29
#define PIN_PWM5 22u // PA_22
#define PIN_RTS0 22u // PA_22
#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_SCL1 18u // PA_18
#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_SPI0 1
#define HAS_SPI1 1
#define HAS_WIRE0 1
#define HAS_WIRE1 1
#define SERIAL_INTERFACES_COUNT 2
#define SPI_INTERFACES_COUNT 2
#define WIRE_INTERFACES_COUNT 2
// Arduino pin names
// -----------------
#define PIN_D0 14u // PA_14
#define PIN_D1 15u // PA_15
#define PIN_D2 0u // PA_0
#define PIN_D3 12u // PA_12
#define PIN_D4 29u // PA_29
#define PIN_D5 5u // PA_5
#define PIN_D6 18u // PA_18
#define PIN_D7 19u // PA_19
#define PIN_D8 22u // PA_22
#define PIN_D9 23u // PA_23
#define PIN_D10 30u // PA_30
// Static pin names
// ----------------
static const unsigned char D0 = PIN_D0;
static const unsigned char D1 = PIN_D1;
static const unsigned char D2 = PIN_D2;
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;
static const unsigned char D9 = PIN_D9;
static const unsigned char D10 = PIN_D10;

View File

@@ -0,0 +1,75 @@
/* This file was auto-generated from generic-ln882hki.json using boardgen */
#include <Arduino.h>
#ifdef LT_VARIANT_INCLUDE
#include LT_VARIANT_INCLUDE
#endif
// clang-format off
PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
// D0: PA00, ADC2, I2C0_SCL, I2C0_SDA
{PA_0, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D1: PA01, ADC3, SWDIO, I2C0_SCL, I2C0_SDA
{PA_1, PIN_SWD | PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D2: PA02, UART0_TX, I2C0_SCL, I2C0_SDA
{PA_2, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D3: PA03, UART0_RX, I2C0_SCL, I2C0_SDA
{PA_3, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D4: PA04, ADC4, SWCLK, I2C0_SCL, I2C0_SDA
{PA_4, PIN_SWD | PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D5: PA05, I2C0_SCL, I2C0_SDA
{PA_5, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D6: PA06, SD_D2, I2C0_SCL, I2C0_SDA
{PA_6, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D7: PA07, SD_D3, I2S0_RX, I2C0_SCL, I2C0_SDA
{PA_7, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D8: PA08, BOOT0, SD_CMD, I2S0_WS, I2C0_SCL, I2C0_SDA
{PA_8, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D9: PA09, BOOT1, SD_CLK, I2S0_SCLK, I2C0_SCL, I2C0_SDA
{PA_9, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D10: PA10, SD_D0, I2S0_TX, I2C0_SCL, I2C0_SDA
{PA_10, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D11: PA11, SD_D1, I2C0_SCL, I2C0_SDA
{PA_11, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D12: PA12, I2C0_SCL, I2C0_SDA
{PA_12, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D13: PB03, ADC5, I2C0_SCL, I2C0_SDA
{PB_3, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D14: PB04, ADC6, I2C0_SCL, I2C0_SDA
{PB_4, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D15: PB05, ADC7, I2C0_SCL, I2C0_SDA
{PB_5, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D16: PB06, I2C0_SCL, I2C0_SDA
{PB_6, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D17: PB07, I2C0_SCL, I2C0_SDA
{PB_7, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D18: PB08, UART1_RX, I2C0_SCL, I2C0_SDA
{PB_8, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D19: PB09, UART1_TX, I2C0_SCL, I2C0_SDA
{PB_9, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
};
PinInfo *lt_arduino_pin_gpio_map[] = {
[0] = &(lt_arduino_pin_info_list[0]), // PA_0 (D0)
[1] = &(lt_arduino_pin_info_list[1]), // PA_1 (D1)
[2] = &(lt_arduino_pin_info_list[2]), // PA_2 (D2)
[3] = &(lt_arduino_pin_info_list[3]), // PA_3 (D3)
[4] = &(lt_arduino_pin_info_list[4]), // PA_4 (D4)
[5] = &(lt_arduino_pin_info_list[5]), // PA_5 (D5)
[6] = &(lt_arduino_pin_info_list[6]), // PA_6 (D6)
[7] = &(lt_arduino_pin_info_list[7]), // PA_7 (D7)
[8] = &(lt_arduino_pin_info_list[8]), // PA_8 (D8)
[9] = &(lt_arduino_pin_info_list[9]), // PA_9 (D9)
[10] = &(lt_arduino_pin_info_list[10]), // PA_10 (D10)
[11] = &(lt_arduino_pin_info_list[11]), // PA_11 (D11)
[12] = &(lt_arduino_pin_info_list[12]), // PA_12 (D12)
[19] = &(lt_arduino_pin_info_list[13]), // PB_3 (D13)
[20] = &(lt_arduino_pin_info_list[14]), // PB_4 (D14)
[21] = &(lt_arduino_pin_info_list[15]), // PB_5 (D15)
[22] = &(lt_arduino_pin_info_list[16]), // PB_6 (D16)
[23] = &(lt_arduino_pin_info_list[17]), // PB_7 (D17)
[24] = &(lt_arduino_pin_info_list[18]), // PB_8 (D18)
[25] = &(lt_arduino_pin_info_list[19]), // PB_9 (D19)
};
// clang-format on

View File

@@ -0,0 +1,168 @@
/* This file was auto-generated from generic-ln882hki.json using boardgen */
#pragma once
// clang-format off
// Pins
// ----
#define PINS_COUNT 20 // Total GPIO count
#define NUM_DIGITAL_PINS 20 // Digital inputs/outputs
#define NUM_ANALOG_INPUTS 6 // ADC inputs
#define NUM_ANALOG_OUTPUTS 0 // PWM & DAC outputs
#define PINS_GPIO_MAX 25 // Last usable GPIO number
// Wire Interfaces
// ---------------
#define PIN_WIRE0_SCL_0 0u // PA_0
#define PIN_WIRE0_SCL_1 1u // PA_1
#define PIN_WIRE0_SCL_2 2u // PA_2
#define PIN_WIRE0_SCL_3 3u // PA_3
#define PIN_WIRE0_SCL_4 4u // PA_4
#define PIN_WIRE0_SCL_5 5u // PA_5
#define PIN_WIRE0_SCL_6 6u // PA_6
#define PIN_WIRE0_SCL_7 7u // PA_7
#define PIN_WIRE0_SCL_8 8u // PA_8
#define PIN_WIRE0_SCL_9 9u // PA_9
#define PIN_WIRE0_SCL_10 10u // PA_10
#define PIN_WIRE0_SCL_11 11u // PA_11
#define PIN_WIRE0_SCL_12 12u // PA_12
#define PIN_WIRE0_SCL_13 19u // PB_3
#define PIN_WIRE0_SCL_14 20u // PB_4
#define PIN_WIRE0_SCL_15 21u // PB_5
#define PIN_WIRE0_SCL_16 22u // PB_6
#define PIN_WIRE0_SCL_17 23u // PB_7
#define PIN_WIRE0_SCL_18 24u // PB_8
#define PIN_WIRE0_SCL_19 25u // PB_9
#define PIN_WIRE0_SDA_0 0u // PA_0
#define PIN_WIRE0_SDA_1 1u // PA_1
#define PIN_WIRE0_SDA_2 2u // PA_2
#define PIN_WIRE0_SDA_3 3u // PA_3
#define PIN_WIRE0_SDA_4 4u // PA_4
#define PIN_WIRE0_SDA_5 5u // PA_5
#define PIN_WIRE0_SDA_6 6u // PA_6
#define PIN_WIRE0_SDA_7 7u // PA_7
#define PIN_WIRE0_SDA_8 8u // PA_8
#define PIN_WIRE0_SDA_9 9u // PA_9
#define PIN_WIRE0_SDA_10 10u // PA_10
#define PIN_WIRE0_SDA_11 11u // PA_11
#define PIN_WIRE0_SDA_12 12u // PA_12
#define PIN_WIRE0_SDA_13 19u // PB_3
#define PIN_WIRE0_SDA_14 20u // PB_4
#define PIN_WIRE0_SDA_15 21u // PB_5
#define PIN_WIRE0_SDA_16 22u // PB_6
#define PIN_WIRE0_SDA_17 23u // PB_7
#define PIN_WIRE0_SDA_18 24u // PB_8
#define PIN_WIRE0_SDA_19 25u // PB_9
#define PINS_WIRE0_SCL (pin_size_t[]){0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 19u, 20u, 21u, 22u, 23u, 24u, 25u}
#define PINS_WIRE0_SDA (pin_size_t[]){0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u, 11u, 12u, 19u, 20u, 21u, 22u, 23u, 24u, 25u}
// Serial ports
// ------------
#define PIN_SERIAL0_RX 3u // PA_3
#define PIN_SERIAL0_TX 2u // PA_2
#define PIN_SERIAL1_RX 24u // PB_8
#define PIN_SERIAL1_TX 25u // PB_9
#define PINS_SERIAL0_RX (pin_size_t[]){3u}
#define PINS_SERIAL0_TX (pin_size_t[]){2u}
#define PINS_SERIAL1_RX (pin_size_t[]){24u}
#define PINS_SERIAL1_TX (pin_size_t[]){25u}
// Pin function macros
// -------------------
#define PIN_ADC2 0u // PA_0
#define PIN_ADC3 1u // PA_1
#define PIN_ADC4 4u // PA_4
#define PIN_ADC5 19u // PB_3
#define PIN_ADC6 20u // PB_4
#define PIN_ADC7 21u // PB_5
#define PIN_PA00 0u // PA_0
#define PIN_PA01 1u // PA_1
#define PIN_PA02 2u // PA_2
#define PIN_PA03 3u // PA_3
#define PIN_PA04 4u // PA_4
#define PIN_PA05 5u // PA_5
#define PIN_PA06 6u // PA_6
#define PIN_PA07 7u // PA_7
#define PIN_PA08 8u // PA_8
#define PIN_PA09 9u // PA_9
#define PIN_PA10 10u // PA_10
#define PIN_PA11 11u // PA_11
#define PIN_PA12 12u // PA_12
#define PIN_PB03 19u // PB_3
#define PIN_PB04 20u // PB_4
#define PIN_PB05 21u // PB_5
#define PIN_PB06 22u // PB_6
#define PIN_PB07 23u // PB_7
#define PIN_PB08 24u // PB_8
#define PIN_PB09 25u // PB_9
#define PIN_RX0 3u // PA_3
#define PIN_RX1 24u // PB_8
#define PIN_TX0 2u // PA_2
#define PIN_TX1 25u // PB_9
// Port availability
// -----------------
#define HAS_SERIAL0 1
#define HAS_SERIAL1 1
#define HAS_WIRE0 1
#define SERIAL_INTERFACES_COUNT 2
#define WIRE_INTERFACES_COUNT 1
// Arduino pin names
// -----------------
#define PIN_D0 0u // PA_0
#define PIN_D1 1u // PA_1
#define PIN_D2 2u // PA_2
#define PIN_D3 3u // PA_3
#define PIN_D4 4u // PA_4
#define PIN_D5 5u // PA_5
#define PIN_D6 6u // PA_6
#define PIN_D7 7u // PA_7
#define PIN_D8 8u // PA_8
#define PIN_D9 9u // PA_9
#define PIN_D10 10u // PA_10
#define PIN_D11 11u // PA_11
#define PIN_D12 12u // PA_12
#define PIN_D13 19u // PB_3
#define PIN_D14 20u // PB_4
#define PIN_D15 21u // PB_5
#define PIN_D16 22u // PB_6
#define PIN_D17 23u // PB_7
#define PIN_D18 24u // PB_8
#define PIN_D19 25u // PB_9
#define PIN_A2 0u // PA_0
#define PIN_A3 1u // PA_1
#define PIN_A4 4u // PA_4
#define PIN_A5 19u // PB_3
#define PIN_A6 20u // PB_4
#define PIN_A7 21u // PB_5
// Static pin names
// ----------------
static const unsigned char A2 = PIN_A2;
static const unsigned char A3 = PIN_A3;
static const unsigned char A4 = PIN_A4;
static const unsigned char A5 = PIN_A5;
static const unsigned char A6 = PIN_A6;
static const unsigned char A7 = PIN_A7;
static const unsigned char D0 = PIN_D0;
static const unsigned char D1 = PIN_D1;
static const unsigned char D2 = PIN_D2;
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;
static const unsigned char D9 = PIN_D9;
static const unsigned char D10 = PIN_D10;
static const unsigned char D11 = PIN_D11;
static const unsigned char D12 = PIN_D12;
static const unsigned char D13 = PIN_D13;
static const unsigned char D14 = PIN_D14;
static const unsigned char D15 = PIN_D15;
static const unsigned char D16 = PIN_D16;
static const unsigned char D17 = PIN_D17;
static const unsigned char D18 = PIN_D18;
static const unsigned char D19 = PIN_D19;

42
boards/variants/ln-02.c Normal file
View File

@@ -0,0 +1,42 @@
/* This file was auto-generated from ln-02.json using boardgen */
#include <Arduino.h>
#ifdef LT_VARIANT_INCLUDE
#include LT_VARIANT_INCLUDE
#endif
// clang-format off
PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
// D0: PA11, SD_D1, I2C0_SCL, I2C0_SDA
{PA_11, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D1: PB03, ADC5, I2C0_SCL, I2C0_SDA
{PB_3, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D2: PA03, UART0_RX, I2C0_SCL, I2C0_SDA
{PA_3, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D3: PB08, UART1_RX, I2C0_SCL, I2C0_SDA
{PB_8, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D4: PA02, UART0_TX, I2C0_SCL, I2C0_SDA
{PA_2, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D5: PB09, UART1_TX, I2C0_SCL, I2C0_SDA
{PB_9, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D6: PA01, ADC3, SWDIO, I2C0_SCL, I2C0_SDA
{PA_1, PIN_SWD | PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D7: PA00, ADC2, I2C0_SCL, I2C0_SDA
{PA_0, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D8: PA09, BOOT1, SD_CLK, I2S0_SCLK, I2C0_SCL, I2C0_SDA
{PA_9, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
};
PinInfo *lt_arduino_pin_gpio_map[] = {
[0] = &(lt_arduino_pin_info_list[7]), // PA_0 (D7)
[1] = &(lt_arduino_pin_info_list[6]), // PA_1 (D6)
[2] = &(lt_arduino_pin_info_list[4]), // PA_2 (D4)
[3] = &(lt_arduino_pin_info_list[2]), // PA_3 (D2)
[9] = &(lt_arduino_pin_info_list[8]), // PA_9 (D8)
[11] = &(lt_arduino_pin_info_list[0]), // PA_11 (D0)
[19] = &(lt_arduino_pin_info_list[1]), // PB_3 (D1)
[24] = &(lt_arduino_pin_info_list[3]), // PB_8 (D3)
[25] = &(lt_arduino_pin_info_list[5]), // PB_9 (D5)
};
// clang-format on

106
boards/variants/ln-02.h Normal file
View File

@@ -0,0 +1,106 @@
/* This file was auto-generated from ln-02.json using boardgen */
#pragma once
// clang-format off
// Pins
// ----
#define PINS_COUNT 9 // Total GPIO count
#define NUM_DIGITAL_PINS 9 // Digital inputs/outputs
#define NUM_ANALOG_INPUTS 3 // ADC inputs
#define NUM_ANALOG_OUTPUTS 0 // PWM & DAC outputs
#define PINS_GPIO_MAX 25 // Last usable GPIO number
// Wire Interfaces
// ---------------
#define PIN_WIRE0_SCL_0 11u // PA_11
#define PIN_WIRE0_SCL_1 19u // PB_3
#define PIN_WIRE0_SCL_2 3u // PA_3
#define PIN_WIRE0_SCL_3 24u // PB_8
#define PIN_WIRE0_SCL_4 2u // PA_2
#define PIN_WIRE0_SCL_5 25u // PB_9
#define PIN_WIRE0_SCL_6 1u // PA_1
#define PIN_WIRE0_SCL_7 0u // PA_0
#define PIN_WIRE0_SCL_8 9u // PA_9
#define PIN_WIRE0_SDA_0 11u // PA_11
#define PIN_WIRE0_SDA_1 19u // PB_3
#define PIN_WIRE0_SDA_2 3u // PA_3
#define PIN_WIRE0_SDA_3 24u // PB_8
#define PIN_WIRE0_SDA_4 2u // PA_2
#define PIN_WIRE0_SDA_5 25u // PB_9
#define PIN_WIRE0_SDA_6 1u // PA_1
#define PIN_WIRE0_SDA_7 0u // PA_0
#define PIN_WIRE0_SDA_8 9u // PA_9
#define PINS_WIRE0_SCL (pin_size_t[]){11u, 19u, 3u, 24u, 2u, 25u, 1u, 0u, 9u}
#define PINS_WIRE0_SDA (pin_size_t[]){11u, 19u, 3u, 24u, 2u, 25u, 1u, 0u, 9u}
// Serial ports
// ------------
#define PIN_SERIAL0_RX 3u // PA_3
#define PIN_SERIAL0_TX 2u // PA_2
#define PIN_SERIAL1_RX 24u // PB_8
#define PIN_SERIAL1_TX 25u // PB_9
#define PINS_SERIAL0_RX (pin_size_t[]){3u}
#define PINS_SERIAL0_TX (pin_size_t[]){2u}
#define PINS_SERIAL1_RX (pin_size_t[]){24u}
#define PINS_SERIAL1_TX (pin_size_t[]){25u}
// Pin function macros
// -------------------
#define PIN_ADC2 0u // PA_0
#define PIN_ADC3 1u // PA_1
#define PIN_ADC5 19u // PB_3
#define PIN_PA00 0u // PA_0
#define PIN_PA01 1u // PA_1
#define PIN_PA02 2u // PA_2
#define PIN_PA03 3u // PA_3
#define PIN_PA09 9u // PA_9
#define PIN_PA11 11u // PA_11
#define PIN_PB03 19u // PB_3
#define PIN_PB08 24u // PB_8
#define PIN_PB09 25u // PB_9
#define PIN_RX0 3u // PA_3
#define PIN_RX1 24u // PB_8
#define PIN_SCL0 9u // PA_9
#define PIN_SDA0 9u // PA_9
#define PIN_TX0 2u // PA_2
#define PIN_TX1 25u // PB_9
// Port availability
// -----------------
#define HAS_SERIAL0 1
#define HAS_SERIAL1 1
#define HAS_WIRE0 1
#define SERIAL_INTERFACES_COUNT 2
#define WIRE_INTERFACES_COUNT 1
// Arduino pin names
// -----------------
#define PIN_D0 11u // PA_11
#define PIN_D1 19u // PB_3
#define PIN_D2 3u // PA_3
#define PIN_D3 24u // PB_8
#define PIN_D4 2u // PA_2
#define PIN_D5 25u // PB_9
#define PIN_D6 1u // PA_1
#define PIN_D7 0u // PA_0
#define PIN_D8 9u // PA_9
#define PIN_A0 19u // PB_3
#define PIN_A1 1u // PA_1
#define PIN_A2 0u // PA_0
// Static pin names
// ----------------
static const unsigned char A0 = PIN_A0;
static const unsigned char A1 = PIN_A1;
static const unsigned char A2 = PIN_A2;
static const unsigned char D0 = PIN_D0;
static const unsigned char D1 = PIN_D1;
static const unsigned char D2 = PIN_D2;
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;

45
boards/variants/wb02a.c Normal file
View File

@@ -0,0 +1,45 @@
/* This file was auto-generated from wb02a.json using boardgen */
#include <Arduino.h>
#ifdef LT_VARIANT_INCLUDE
#include LT_VARIANT_INCLUDE
#endif
// clang-format off
PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
// D0: PA07, SD_D3, I2S0_RX, I2C0_SCL, I2C0_SDA
{PA_7, , PIN_NONE, 0},
// D1: PA05, I2C0_SCL, I2C0_SDA
{PA_5, , PIN_NONE, 0},
// D2: PA03, UART0_RX, I2C0_SCL, I2C0_SDA
{PA_3, , PIN_NONE, 0},
// D3: PA10, SD_D0, I2S0_TX, I2C0_SCL, I2C0_SDA
{PA_10, , PIN_NONE, 0},
// D4: PA02, UART0_TX, I2C0_SCL, I2C0_SDA
{PA_2, , PIN_NONE, 0},
// D5: PA01, ADC3, SWDIO, I2C0_SCL, I2C0_SDA
{PA_1, , PIN_NONE, 0},
// D6: PA04, ADC4, SWCLK, I2C0_SCL, I2C0_SDA
{PA_4, , PIN_NONE, 0},
// D7: PA09, BOOT1, SD_CLK, I2S0_SCLK, I2C0_SCL, I2C0_SDA
{PA_9, , PIN_NONE, 0},
// D8: PB08, UART1_RX, I2C0_SCL, I2C0_SDA
{PB_8, , PIN_NONE, 0},
// D9: PB09, UART1_TX, I2C0_SCL, I2C0_SDA
{PB_9, , PIN_NONE, 0},
};
PinInfo *lt_arduino_pin_gpio_map[] = {
[1] = &(lt_arduino_pin_info_list[5]), // PA_1 (D5)
[2] = &(lt_arduino_pin_info_list[4]), // PA_2 (D4)
[3] = &(lt_arduino_pin_info_list[2]), // PA_3 (D2)
[4] = &(lt_arduino_pin_info_list[6]), // PA_4 (D6)
[5] = &(lt_arduino_pin_info_list[1]), // PA_5 (D1)
[7] = &(lt_arduino_pin_info_list[0]), // PA_7 (D0)
[9] = &(lt_arduino_pin_info_list[7]), // PA_9 (D7)
[10] = &(lt_arduino_pin_info_list[3]), // PA_10 (D3)
[24] = &(lt_arduino_pin_info_list[8]), // PB_8 (D8)
[25] = &(lt_arduino_pin_info_list[9]), // PB_9 (D9)
};
// clang-format on

110
boards/variants/wb02a.h Normal file
View File

@@ -0,0 +1,110 @@
/* This file was auto-generated from wb02a.json using boardgen */
#pragma once
// clang-format off
// Pins
// ----
#define PINS_COUNT 10 // Total GPIO count
#define NUM_DIGITAL_PINS 10 // Digital inputs/outputs
#define NUM_ANALOG_INPUTS 2 // ADC inputs
#define NUM_ANALOG_OUTPUTS 0 // PWM & DAC outputs
#define PINS_GPIO_MAX 25 // Last usable GPIO number
// Wire Interfaces
// ---------------
#define PIN_WIRE0_SCL_0 7u // PA_7
#define PIN_WIRE0_SCL_1 5u // PA_5
#define PIN_WIRE0_SCL_2 3u // PA_3
#define PIN_WIRE0_SCL_3 10u // PA_10
#define PIN_WIRE0_SCL_4 2u // PA_2
#define PIN_WIRE0_SCL_5 1u // PA_1
#define PIN_WIRE0_SCL_6 4u // PA_4
#define PIN_WIRE0_SCL_7 5u // PA_5
#define PIN_WIRE0_SCL_8 9u // PA_9
#define PIN_WIRE0_SCL_9 24u // PB_8
#define PIN_WIRE0_SCL_10 25u // PB_9
#define PIN_WIRE0_SDA_0 7u // PA_7
#define PIN_WIRE0_SDA_1 5u // PA_5
#define PIN_WIRE0_SDA_2 3u // PA_3
#define PIN_WIRE0_SDA_3 10u // PA_10
#define PIN_WIRE0_SDA_4 2u // PA_2
#define PIN_WIRE0_SDA_5 1u // PA_1
#define PIN_WIRE0_SDA_6 4u // PA_4
#define PIN_WIRE0_SDA_7 5u // PA_5
#define PIN_WIRE0_SDA_8 9u // PA_9
#define PIN_WIRE0_SDA_9 24u // PB_8
#define PIN_WIRE0_SDA_10 25u // PB_9
#define PINS_WIRE0_SCL (pin_size_t[]){7u, 5u, 3u, 10u, 2u, 1u, 4u, 5u, 9u, 24u, 25u}
#define PINS_WIRE0_SDA (pin_size_t[]){7u, 5u, 3u, 10u, 2u, 1u, 4u, 5u, 9u, 24u, 25u}
// Serial ports
// ------------
#define PIN_SERIAL0_RX 3u // PA_3
#define PIN_SERIAL0_TX 2u // PA_2
#define PIN_SERIAL1_RX 24u // PB_8
#define PIN_SERIAL1_TX 25u // PB_9
#define PINS_SERIAL0_RX (pin_size_t[]){3u}
#define PINS_SERIAL0_TX (pin_size_t[]){2u}
#define PINS_SERIAL1_RX (pin_size_t[]){24u}
#define PINS_SERIAL1_TX (pin_size_t[]){25u}
// Pin function macros
// -------------------
#define PIN_ADC3 1u // PA_1
#define PIN_ADC4 4u // PA_4
#define PIN_PA01 1u // PA_1
#define PIN_PA02 2u // PA_2
#define PIN_PA03 3u // PA_3
#define PIN_PA04 4u // PA_4
#define PIN_PA05 5u // PA_5
#define PIN_PA07 7u // PA_7
#define PIN_PA09 9u // PA_9
#define PIN_PA10 10u // PA_10
#define PIN_PB08 24u // PB_8
#define PIN_PB09 25u // PB_9
#define PIN_RX0 3u // PA_3
#define PIN_RX1 24u // PB_8
#define PIN_SCL0 25u // PB_9
#define PIN_SDA0 25u // PB_9
#define PIN_TX0 2u // PA_2
#define PIN_TX1 25u // PB_9
// Port availability
// -----------------
#define HAS_SERIAL0 1
#define HAS_SERIAL1 1
#define HAS_WIRE0 1
#define SERIAL_INTERFACES_COUNT 2
#define WIRE_INTERFACES_COUNT 1
// Arduino pin names
// -----------------
#define PIN_D0 7u // PA_7
#define PIN_D1 5u // PA_5
#define PIN_D2 3u // PA_3
#define PIN_D3 10u // PA_10
#define PIN_D4 2u // PA_2
#define PIN_D5 1u // PA_1
#define PIN_D6 4u // PA_4
#define PIN_D7 9u // PA_9
#define PIN_D8 24u // PB_8
#define PIN_D9 25u // PB_9
#define PIN_A0 1u // PA_1
#define PIN_A1 4u // PA_4
// Static pin names
// ----------------
static const unsigned char A0 = PIN_A0;
static const unsigned char A1 = PIN_A1;
static const unsigned char D0 = PIN_D0;
static const unsigned char D1 = PIN_D1;
static const unsigned char D2 = PIN_D2;
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;
static const unsigned char D9 = PIN_D9;

54
boards/variants/wl2s.c Normal file
View File

@@ -0,0 +1,54 @@
/* This file was auto-generated from wl2s.json using boardgen */
#include <Arduino.h>
#ifdef LT_VARIANT_INCLUDE
#include LT_VARIANT_INCLUDE
#endif
// clang-format off
PinInfo lt_arduino_pin_info_list[PINS_COUNT] = {
// D0: PA07, SD_D3, I2S0_RX, I2C0_SCL, I2C0_SDA
{PA_7, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D1: PA12, I2C0_SCL, I2C0_SDA
{PA_12, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D2: PA03, UART0_RX, I2C0_SCL, I2C0_SDA
{PA_3, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D3: PA10, SD_D0, I2S0_TX, I2C0_SCL, I2C0_SDA
{PA_10, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D4: PA02, UART0_TX, I2C0_SCL, I2C0_SDA
{PA_2, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D5: PA00, ADC2, I2C0_SCL, I2C0_SDA
{PA_0, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D6: PB03, ADC5, I2C0_SCL, I2C0_SDA
{PB_3, PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D7: PA11, SD_D1, I2C0_SCL, I2C0_SDA
{PA_11, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D8: PA09, BOOT1, SD_CLK, I2S0_SCLK, I2C0_SCL, I2C0_SDA
{PA_9, PIN_I2S | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D9: PB08, UART1_RX, I2C0_SCL, I2C0_SDA
{PB_8, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D10: PB09, UART1_TX, I2C0_SCL, I2C0_SDA
{PB_9, PIN_UART | PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D11: PA05, I2C0_SCL, I2C0_SDA
{PA_5, PIN_I2C | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
// D12: PA01, ADC3, SWDIO, I2C0_SCL, I2C0_SDA
{PA_1, PIN_SWD | PIN_I2C | PIN_ADC | PIN_IRQ | PIN_GPIO, PIN_NONE, 0},
};
PinInfo *lt_arduino_pin_gpio_map[] = {
[0] = &(lt_arduino_pin_info_list[5]), // PA_0 (D5)
[1] = &(lt_arduino_pin_info_list[12]), // PA_1 (D12)
[2] = &(lt_arduino_pin_info_list[4]), // PA_2 (D4)
[3] = &(lt_arduino_pin_info_list[2]), // PA_3 (D2)
[5] = &(lt_arduino_pin_info_list[11]), // PA_5 (D11)
[7] = &(lt_arduino_pin_info_list[0]), // PA_7 (D0)
[9] = &(lt_arduino_pin_info_list[8]), // PA_9 (D8)
[10] = &(lt_arduino_pin_info_list[3]), // PA_10 (D3)
[11] = &(lt_arduino_pin_info_list[7]), // PA_11 (D7)
[12] = &(lt_arduino_pin_info_list[1]), // PA_12 (D1)
[19] = &(lt_arduino_pin_info_list[6]), // PB_3 (D6)
[24] = &(lt_arduino_pin_info_list[9]), // PB_8 (D9)
[25] = &(lt_arduino_pin_info_list[10]), // PB_9 (D10)
};
// clang-format on

126
boards/variants/wl2s.h Normal file
View File

@@ -0,0 +1,126 @@
/* This file was auto-generated from wl2s.json using boardgen */
#pragma once
// clang-format off
// Pins
// ----
#define PINS_COUNT 13 // Total GPIO count
#define NUM_DIGITAL_PINS 13 // Digital inputs/outputs
#define NUM_ANALOG_INPUTS 3 // ADC inputs
#define NUM_ANALOG_OUTPUTS 0 // PWM & DAC outputs
#define PINS_GPIO_MAX 25 // Last usable GPIO number
// Wire Interfaces
// ---------------
#define PIN_WIRE0_SCL_0 7u // PA_7
#define PIN_WIRE0_SCL_1 12u // PA_12
#define PIN_WIRE0_SCL_2 3u // PA_3
#define PIN_WIRE0_SCL_3 10u // PA_10
#define PIN_WIRE0_SCL_4 2u // PA_2
#define PIN_WIRE0_SCL_5 0u // PA_0
#define PIN_WIRE0_SCL_6 19u // PB_3
#define PIN_WIRE0_SCL_7 11u // PA_11
#define PIN_WIRE0_SCL_8 9u // PA_9
#define PIN_WIRE0_SCL_9 24u // PB_8
#define PIN_WIRE0_SCL_10 25u // PB_9
#define PIN_WIRE0_SCL_11 5u // PA_5
#define PIN_WIRE0_SCL_12 1u // PA_1
#define PIN_WIRE0_SDA_0 7u // PA_7
#define PIN_WIRE0_SDA_1 12u // PA_12
#define PIN_WIRE0_SDA_2 3u // PA_3
#define PIN_WIRE0_SDA_3 10u // PA_10
#define PIN_WIRE0_SDA_4 2u // PA_2
#define PIN_WIRE0_SDA_5 0u // PA_0
#define PIN_WIRE0_SDA_6 19u // PB_3
#define PIN_WIRE0_SDA_7 11u // PA_11
#define PIN_WIRE0_SDA_8 9u // PA_9
#define PIN_WIRE0_SDA_9 24u // PB_8
#define PIN_WIRE0_SDA_10 25u // PB_9
#define PIN_WIRE0_SDA_11 5u // PA_5
#define PIN_WIRE0_SDA_12 1u // PA_1
#define PINS_WIRE0_SCL (pin_size_t[]){7u, 12u, 3u, 10u, 2u, 0u, 19u, 11u, 9u, 24u, 25u, 5u, 1u}
#define PINS_WIRE0_SDA (pin_size_t[]){7u, 12u, 3u, 10u, 2u, 0u, 19u, 11u, 9u, 24u, 25u, 5u, 1u}
// Serial ports
// ------------
#define PIN_SERIAL0_RX 3u // PA_3
#define PIN_SERIAL0_TX 2u // PA_2
#define PIN_SERIAL1_RX 24u // PB_8
#define PIN_SERIAL1_TX 25u // PB_9
#define PINS_SERIAL0_RX (pin_size_t[]){3u}
#define PINS_SERIAL0_TX (pin_size_t[]){2u}
#define PINS_SERIAL1_RX (pin_size_t[]){24u}
#define PINS_SERIAL1_TX (pin_size_t[]){25u}
// Pin function macros
// -------------------
#define PIN_ADC2 0u // PA_0
#define PIN_ADC3 1u // PA_1
#define PIN_ADC5 19u // PB_3
#define PIN_PA00 0u // PA_0
#define PIN_PA01 1u // PA_1
#define PIN_PA02 2u // PA_2
#define PIN_PA03 3u // PA_3
#define PIN_PA05 5u // PA_5
#define PIN_PA07 7u // PA_7
#define PIN_PA09 9u // PA_9
#define PIN_PA10 10u // PA_10
#define PIN_PA11 11u // PA_11
#define PIN_PA12 12u // PA_12
#define PIN_PB03 19u // PB_3
#define PIN_PB08 24u // PB_8
#define PIN_PB09 25u // PB_9
#define PIN_RX0 3u // PA_3
#define PIN_RX1 24u // PB_8
#define PIN_SCL0 1u // PA_1
#define PIN_SDA0 1u // PA_1
#define PIN_TX0 2u // PA_2
#define PIN_TX1 25u // PB_9
// Port availability
// -----------------
#define HAS_SERIAL0 1
#define HAS_SERIAL1 1
#define HAS_WIRE0 1
#define SERIAL_INTERFACES_COUNT 2
#define WIRE_INTERFACES_COUNT 1
// Arduino pin names
// -----------------
#define PIN_D0 7u // PA_7
#define PIN_D1 12u // PA_12
#define PIN_D2 3u // PA_3
#define PIN_D3 10u // PA_10
#define PIN_D4 2u // PA_2
#define PIN_D5 0u // PA_0
#define PIN_D6 19u // PB_3
#define PIN_D7 11u // PA_11
#define PIN_D8 9u // PA_9
#define PIN_D9 24u // PB_8
#define PIN_D10 25u // PB_9
#define PIN_D11 5u // PA_5
#define PIN_D12 1u // PA_1
#define PIN_A0 0u // PA_0
#define PIN_A1 19u // PB_3
#define PIN_A2 1u // PA_1
// Static pin names
// ----------------
static const unsigned char A0 = PIN_A0;
static const unsigned char A1 = PIN_A1;
static const unsigned char A2 = PIN_A2;
static const unsigned char D0 = PIN_D0;
static const unsigned char D1 = PIN_D1;
static const unsigned char D2 = PIN_D2;
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;
static const unsigned char D9 = PIN_D9;
static const unsigned char D10 = PIN_D10;
static const unsigned char D11 = PIN_D11;
static const unsigned char D12 = PIN_D12;

19
boards/wb02a.json Normal file
View File

@@ -0,0 +1,19 @@
{
"_base": [
"lightning-ln882x",
"lightning-ln882hki",
"ic/ln882hk",
"pcb/wb02a",
"pcb/wb02a-test"
],
"build": {
"mcu": "ln882hk",
"variant": "wb02a"
},
"name": "WB02A Wi-Fi/BLE Module",
"url": "https://docs.libretiny.eu/boards/wb02a/",
"vendor": "Unknown",
"pcb": {
"symbol": ""
}
}

22
boards/wl2s.json Normal file
View File

@@ -0,0 +1,22 @@
{
"_base": [
"lightning-ln882x",
"lightning-ln882hki",
"ic/ln882hk",
"pcb/wl2s",
"pcb/wl2s-test"
],
"build": {
"mcu": "ln882hk",
"variant": "wl2s"
},
"name": "WL2S Wi-Fi/BLE Module",
"url": "https://docs.libretiny.eu/boards/wl2s/",
"vendor": "Unknown",
"doc": {
"fccid": ""
},
"pcb": {
"symbol": "WL2S"
}
}

View File

@@ -0,0 +1,263 @@
# Copyright (c) Etienne Le Cousin 2024-02-08.
from os.path import join
from shutil import copyfile
from platformio.platform.board import PlatformBoardConfig
from SCons.Script import DefaultEnvironment, Environment
env: Environment = DefaultEnvironment()
board: PlatformBoardConfig = env.BoardConfig()
queue = env.AddLibraryQueue("lightning-ln882h")
env.ConfigureFamily()
# Flags
queue.AppendPublic(
CCFLAGS=[
"-mcpu=cortex-m4",
"-mthumb",
"-mabi=aapcs",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-fno-short-enums",
"-Wfatal-errors",
"-ffunction-sections",
"-fdata-sections",
"-fno-strict-aliasing",
"-MD",
"-MP",
],
CFLAGS=[
"-Wpointer-arith",
"-Wno-write-strings",
"-Wno-maybe-uninitialized",
],
CXXFLAGS=[],
CPPDEFINES=[
# other options
"ARM_MATH_CM4",
"LN882H",
("PLATFORM_LN882H", "1"),
("MBEDTLS_CONFIG_FILE", r"\"mbedtls_config.h\""),
],
ASFLAGS=[
"-mcpu=cortex-m4",
"-mthumb",
"-mabi=aapcs",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-g",
"-c",
],
LINKFLAGS=[
"-mcpu=cortex-m4",
"-mthumb",
"-mabi=aapcs",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"--specs=nano.specs",
"-Wl,--gc-sections",
"-Wl,--whole-archive",
"-lcore_ln882h",
"-Wl,--no-whole-archive",
# stdio wrappers (base/port/printf.c)
"-Wl,-wrap,ln_printf",
],
)
queue.AppendPrivate(
CFLAGS=[
"-Wno-implicit-function-declaration",
"-Wno-incompatible-pointer-types",
"-Wno-int-conversion",
"-Wno-pointer-sign",
"-Wfatal-errors",
"-ffunction-sections",
"-fdata-sections",
"-fno-strict-aliasing",
"-std=gnu99",
"-MD",
"-MP",
],
)
# Boot files - from SDK project/wifi_mcu_basic_example
"""
queue.AddLibrary(
name="ln882h_boot",
base_dir="$SDK_DIR/project/wifi_mcu_basic_example",
srcs=[
"+<startup/startup_ln882h_gcc.c>",
],
)
"""
# Sources
queue.AddLibrary(
name="ln882h_sdk",
base_dir="$SDK_DIR",
srcs=[
# MCU
"+<mcu/ln882h/system_ln882h.c>"
# Hal
"+<mcu/driver_ln882h/hal/*.c>",
# FreeRTOS
"+<components/kernel/FreeRTOS_Adapter/*.c>",
# Serial
"+<components/serial/serial.c>",
# Misc
"+<components/fs/nvds/ln_nvds.c>",
"+<components/fs/kv/kv/ln_kv.c>",
"+<components/fs/kv/kv_port/ln_kv_port.c>",
"+<components/fota/ota_agent/ota_image.c>",
"+<components/utils/fifo/fifobuf.c>",
"+<components/utils/debug/log.c>",
"+<components/utils/debug/CmBacktrace/cm_backtrace.c>",
"+<components/utils/system_parameter.c>",
"+<components/utils/power_mgmt/ln_pm.c>",
"+<components/utils/runtime/runtime.c>",
"+<components/utils/reboot_trace/reboot_trace.c>",
"+<components/tencent/qcloud_iot_c_sdk/external_libs/cJSON/cJSON.c>",
],
includes=[
# MCU
"+<mcu/CMSIS_5.3.0>",
"+<mcu/ln882h>",
# Hal
"+<mcu/driver_ln882h>",
"+<mcu/driver_ln882h/reg>",
"+<mcu/driver_ln882h/hal>",
# Components
"+<components>",
# FreeRTOS
"+<components/kernel>",
"+<components/kernel/FreeRTOS/Source/portable/GCC/ARM_CM4F>",
"+<components/kernel/FreeRTOS_Adapter>",
"+<components/kernel/osal>",
# Misc
"+<components/fs/nvds>",
"+<components/fs/kv/kv>",
"+<components/fs/kv/kv_port>",
"+<components/fs/partition_mgr>",
"+<components/fota/ota_agent>",
"+<components/serial>",
"+<components/utils/debug/CmBacktrace>",
"+<components/utils/power_mgmt>",
# "+<components/utils/runtime>",
"+<components/utils/reboot_trace>",
"+<components/tencent/qcloud_iot_c_sdk/external_libs/cJSON>",
],
options=dict(
CPPDEFINES=["LN882H_SDK"],
CFLAGS=["-w"],
),
)
queue.AddLibrary(
name="ln882h_net",
base_dir="$SDK_DIR",
srcs=[
# WiFi
"+<components/wifi/wifi_manager/wifi_manager.c>",
"+<components/wifi/wifi_lib_import/wifi_port.c>",
# DHCPD
"+<components/net/dhcpd/*.c>",
# Utils
"+<components/utils/ln_misc.c>",
"+<components/utils/ln_sha1.c>",
"+<components/utils/ln_aes.c>",
"+<components/utils/ln_psk_calc.c>",
],
includes=[
"+<components/wifi/wifi_manager>",
"+<components/wifi/wifi_lib_import>",
"+<components/wifi/wifi_lib_export>",
"+<components/net/dhcpd>",
],
options=dict(
CPPDEFINES=["LN882H_SDK"],
CFLAGS=["-w"],
),
)
# Sources - FreeRTOS
env.Replace(FREERTOS_PORT=env["FAMILY_NAME"], FREERTOS_PORT_DEFINE="LIGHTNING_LN882H")
queue.AddExternalLibrary("freertos")
queue.AddExternalLibrary("freertos-port")
# Sources - lwIP
queue.AddExternalLibrary("lwip", port="ln882h")
# Sources - mbedTLS
queue.AddLibrary(
name="ln882h_mbedtls",
base_dir="$SDK_DIR",
srcs=[
# mbedTLS from SDK
"+<components/net/mbedtls/library/*.c>",
# replace this with a port specific
"-<components/net/mbedtls/library/net_sockets.c>",
"-<components/net/mbedtls/library/platform.c>",
"-<components/net/mbedtls/library/threading_alt.c>",
"-<components/net/mbedtls/library/timing.c>",
# ln port
"+<components/net/mbedtls/port_ln/library/*.c>",
],
includes=[
"+<components/net/mbedtls/include>",
"+<components/net/mbedtls/port_ln/include>",
],
options=dict(
CPPDEFINES=["LN882H_SDK"],
CFLAGS=["-w"],
),
)
# Libs & linker config
queue.AppendPublic(
LIBPATH=[
# fmt: off
join("$SDK_DIR", "lib", "gcclib"),
# fmt: on
],
LIBS=[
"arm_cortexM4lf_math",
"ln882h_wifi",
"m",
"c",
"nosys",
"gcc",
],
)
# Copy Bootloader
bootfile = board.get("build.bootfile")
copyfile(
join(env.subst("$MISC_DIR"), bootfile), join(env.subst("$BUILD_DIR"), "boot.bin")
)
# Generate linker scripts with correct flash offsets
env.GenerateLinkerScript(board, board.get("build.ldscript"))
# Build all libraries
queue.BuildLibraries()
# Main firmware outputs and actions
# fmt: off
image_ota = "${BUILD_DIR}/image_ota.${FLASH_OTA_OFFSET}.bin"
image_part_tab = "${BUILD_DIR}/image_part_tab.${FLASH_PART_TAB_OFFSET}.bin"
image_boot = "${BUILD_DIR}/image_boot.${FLASH_BOOT_OFFSET}.bin"
image_app = "${BUILD_DIR}/image_app.${FLASH_APP_OFFSET}.bin"
# fmt: on
env.Replace(
# linker command
LINK='${LTCHIPTOOL} link2bin ${BOARD_JSON} "" ""',
# UF2OTA input list
UF2OTA=[
# ota binary image for device
f"{image_ota}=device:ota",
# binary image for flasher
f"{image_boot}=flasher:boot",
f"{image_part_tab}=flasher:part_tab",
f"{image_app}=flasher:app",
],
)

View File

@@ -410,7 +410,7 @@ if not isfile(bootloader_dst):
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)
f.write(b"\xff" * 4096)
# Build all libraries
queue.BuildLibraries()
@@ -427,8 +427,8 @@ env.Replace(
# 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",
f"{image_bootloader},{image_bootloader}=flasher:boot,boot",
f"{image_part_table},{image_part_table}=flasher:part_table,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",
],

View File

@@ -20,8 +20,6 @@ env.ParseCustomOptions(platform)
env.ParseCustomFlashLayout(platform, board)
# Add flash layout C defines
env.AddFlashLayout(board)
# Write custom header options
env.ApplyCustomOptions(platform)
# Export board manifest for ltchiptool
env.ExportBoardData(board)
# Print information about versions and custom options

View File

@@ -18,7 +18,7 @@ platform: PlatformBase = env.PioPlatform()
board: PlatformBoardConfig = env.BoardConfig()
python_deps = {
"ltchiptool": ">=4.5.1,<5.0",
"ltchiptool": ">=4.12.2,<5.0",
}
env.SConscript("python-venv.py", exports="env")
env.ConfigurePythonVenv()

View File

@@ -51,7 +51,7 @@ def env_add_core_sources(env: Environment, queue, name: str, path: str) -> bool:
"+<compat/*.c*>",
"+<port/*.c*>",
"+<posix/*.c>",
"+<wiring/*.c>",
"+<wiring/*.c*>",
"+<wraps/*.c>",
],
includes=[
@@ -89,15 +89,17 @@ def env_add_arduino_libraries(env: Environment, queue, name: str, path: str) ->
srcs=[
"+<**/*.c*>",
],
includes=[
"!<*/.>",
"!<*/*>",
]
if name.startswith("common")
else [
"!<.>",
"!<*>",
],
includes=(
[
"!<*/.>",
"!<*/*>",
]
if name.startswith("common")
else [
"!<.>",
"!<*>",
]
),
)
return True

View File

@@ -184,6 +184,9 @@ class LibraryQueue:
else:
self.env.Append(CPPPATH=self.includes)
# prepend headers with custom options
self.env.ApplyCustomOptions(self.env.PioPlatform())
# clone the environment for the whole library queue
queue_env = self.env.Clone()
# add private options to the cloned environment

View File

@@ -6,9 +6,9 @@
#include <sdk_private.h>
typedef struct {
RingBuffer buf;
SerialRingBuffer buf;
} SerialData;
#define DATA ((SerialData *)data)
#define BUF (DATA->buf)
#define pBUF ((RingBuffer *)param)
#define pBUF ((SerialRingBuffer *)param)

View File

@@ -27,6 +27,40 @@ static void wifiEventTask(void *arg) {
}
}
// There is a race condition, when we have an event about a successful
// connection but no SSID yet returned by BDK. Even a single millisecond
// delay should prevent this from happening. It's better to waste a bit
// of time here than to lose a valid connection down the line.
static String waitForValidSSID(WiFiClass *pWiFi) {
String result;
// Read the initial value that might just be available already.
result = pWiFi->SSID();
if (!result.length()) {
std::size_t i = 0;
for (; i < 10; i++) {
// Delay and query again.
delay(1);
result = pWiFi->SSID();
if (result.length()) {
LT_DM(WIFI, "Got valid SSID after %u delays", i + 1);
break;
}
// It's a good idea to yield.
yield();
}
if (!result.length()) {
LT_WM(WIFI, "Could not obtain a valid SSID after %u delays", i);
}
}
return result;
}
void wifiEventSendArduino(EventId event) {
event = (EventId)(RW_EVT_ARDUINO | event);
wifiStatusCallback((rw_evt_type *)&event);
@@ -52,11 +86,6 @@ void wifiEventHandler(rw_evt_type event) {
LT_DM(WIFI, "BK event %u", event);
if (event <= RW_EVT_STA_GOT_IP)
pDATA->lastStaEvent = event;
else
pDATA->lastApEvent = event;
EventId eventId;
EventInfo eventInfo;
String ssid;
@@ -103,7 +132,7 @@ void wifiEventHandler(rw_evt_type event) {
case RW_EVT_STA_CONNECTED:
eventId = ARDUINO_EVENT_WIFI_STA_CONNECTED;
ssid = pWiFi->SSID();
ssid = waitForValidSSID(pWiFi);
eventInfo.wifi_sta_connected.ssid_len = ssid.length();
eventInfo.wifi_sta_connected.channel = pWiFi->channel();
eventInfo.wifi_sta_connected.authmode = pWiFi->getEncryption();
@@ -145,5 +174,13 @@ void wifiEventHandler(rw_evt_type event) {
break;
}
// Publish state update only after the event data is retrieved.
// This relates to the race condition with RW_EVT_STA_CONNECTED.
if (event <= RW_EVT_STA_GOT_IP) {
pDATA->lastStaEvent = event;
} else {
pDATA->lastApEvent = event;
}
pWiFi->postEvent(eventId, eventInfo);
}

View File

@@ -80,7 +80,30 @@ IPAddress WiFiClass::hostByName(const char *hostname) {
ip_addr_t ip;
int ret = netconn_gethostbyname(hostname, &ip);
if (ret == ERR_OK) {
return ip.addr;
#ifdef CONFIG_IPV6
if (IP_IS_V6(&ip)) {
ip6_addr_t *ip6 = ip_2_ip6(&ip);
return IPAddress(
IP6_ADDR_BLOCK1(ip6) >> 8,
IP6_ADDR_BLOCK1(ip6) & 0xff,
IP6_ADDR_BLOCK2(ip6) >> 8,
IP6_ADDR_BLOCK2(ip6) & 0xff,
IP6_ADDR_BLOCK3(ip6) >> 8,
IP6_ADDR_BLOCK3(ip6) & 0xff,
IP6_ADDR_BLOCK4(ip6) >> 8,
IP6_ADDR_BLOCK4(ip6) & 0xff,
IP6_ADDR_BLOCK5(ip6) >> 8,
IP6_ADDR_BLOCK5(ip6) & 0xff,
IP6_ADDR_BLOCK6(ip6) >> 8,
IP6_ADDR_BLOCK6(ip6) & 0xff,
IP6_ADDR_BLOCK7(ip6) >> 8,
IP6_ADDR_BLOCK7(ip6) & 0xff,
IP6_ADDR_BLOCK8(ip6) >> 8,
IP6_ADDR_BLOCK8(ip6) & 0xff
);
}
#endif
return IPAddress(ip_addr_get_ip4_u32(&ip));
}
return IPAddress();
}

View File

@@ -79,34 +79,34 @@ typedef struct {
#define IP_STATUS (DATA->statusIp)
#define LINK_STATUS (DATA->statusLink)
#define STA_GET_LINK_STATUS_RETURN(ret) \
{ \
if (!sta_ip_is_start()) \
return ret; \
memset(&LINK_STATUS, 0x00, sizeof(LinkStatusTypeDef)); \
bk_wlan_get_link_status(&LINK_STATUS); \
#define STA_GET_LINK_STATUS_RETURN(ret) \
{ \
if (!sta_ip_is_start()) \
return ret; \
memset(&LINK_STATUS, 0x00, sizeof(LinkStatusTypeDef)); \
bk_wlan_get_link_status(&LINK_STATUS); \
}
#define STA_GET_IP_STATUS_RETURN(ret) \
{ \
if (!sta_ip_is_start()) \
return ret; \
memset(&IP_STATUS, 0x00, sizeof(IPStatusTypedef)); \
bk_wlan_get_ip_status(&IP_STATUS, BK_STATION); \
#define STA_GET_IP_STATUS_RETURN(ret) \
{ \
if (!sta_ip_is_start()) \
return ret; \
memset(&IP_STATUS, 0x00, sizeof(IPStatusTypedef)); \
bk_wlan_get_ip_status(&IP_STATUS, BK_STATION); \
}
#define AP_GET_LINK_STATUS_RETURN(ret) \
{ \
if (!uap_ip_is_start()) \
return ret; \
#define AP_GET_LINK_STATUS_RETURN(ret) \
{ \
if (!uap_ip_is_start()) \
return ret; \
}
#define AP_GET_IP_STATUS_RETURN(ret) \
{ \
if (!uap_ip_is_start()) \
return ret; \
memset(&IP_STATUS, 0x00, sizeof(IPStatusTypedef)); \
bk_wlan_get_ip_status(&IP_STATUS, BK_SOFT_AP); \
#define AP_GET_IP_STATUS_RETURN(ret) \
{ \
if (!uap_ip_is_start()) \
return ret; \
memset(&IP_STATUS, 0x00, sizeof(IPStatusTypedef)); \
bk_wlan_get_ip_status(&IP_STATUS, BK_SOFT_AP); \
}
} // extern "C"

View File

@@ -2,8 +2,13 @@
#include "WiFiPrivate.h"
WiFiStatus
WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, const uint8_t *bssid, bool connect) {
WiFiStatus WiFiClass::begin(
const char *ssid,
const char *passphrase,
int32_t channel,
const uint8_t *bssid,
bool connect
) {
if (!enableSTA(true))
return WL_CONNECT_FAILED;
if (!validate(ssid, passphrase))
@@ -246,3 +251,41 @@ WiFiAuthMode WiFiClass::getEncryption() {
STA_GET_LINK_STATUS_RETURN(WIFI_AUTH_INVALID);
return securityTypeToAuthMode(LINK_STATUS.security);
}
#ifdef CONFIG_IPV6
bool WiFiClass::enableIpV6() {
return true;
}
IPv6Address WiFiClass::localIPv6() {
struct netif *ifs = (struct netif *)net_get_sta_handle();
std::vector<IPv6Address> result;
struct wlan_ip_config addr;
int nr_addresses = 0;
if (sta_ip_is_start())
nr_addresses = net_get_if_ipv6_pref_addr(&addr, ifs);
for (int i = 0; i < nr_addresses; i++) {
if (ip6_addr_islinklocal(&addr.ipv6[i]))
return IPv6Address(addr.ipv6[i].addr);
}
return IPv6Address();
}
std::vector<IPv6Address> WiFiClass::allLocalIPv6() {
struct netif *ifs = (struct netif *)net_get_sta_handle();
std::vector<IPv6Address> result;
struct wlan_ip_config addr;
int nr_addresses = 0;
if (sta_ip_is_start())
nr_addresses = net_get_if_ipv6_pref_addr(&addr, ifs);
for (int i = 0; i < nr_addresses; i++) {
result.push_back(IPv6Address(addr.ipv6[i].addr));
}
return result;
}
#endif

View File

@@ -9,19 +9,19 @@ static void irqHandler(unsigned char gpio) {
PinData *data = pinData(pin);
if (!data->irqHandler)
return;
if (data->irqChange) {
if (data->gpioMode == INPUT_PULLDOWN) {
data->gpioMode = INPUT_PULLUP;
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
} else if (data->gpioMode == INPUT_PULLUP) {
data->gpioMode = INPUT_PULLDOWN;
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_RISING, irqHandler);
}
}
if (!data->irqParam)
((voidFuncPtr)data->irqHandler)();
else
((voidFuncPtrParam)data->irqHandler)(data->irqParam);
if (data->irqChange) {
if (data->irqMode == RISING) {
data->irqMode = FALLING;
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_FALLING, irqHandler);
} else {
data->irqMode = RISING;
gpio_int_enable(pin->gpio, GPIO_INT_LEVEL_RISING, irqHandler);
}
}
}
void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback, PinStatus mode, void *param) {
@@ -52,7 +52,13 @@ void attachInterruptParam(pin_size_t interruptNumber, voidFuncPtrParam callback,
event = GPIO_INT_LEVEL_RISING;
break;
case CHANGE:
event = GPIO_INT_LEVEL_FALLING;
if (gpio_input(pin->gpio)) {
event = GPIO_INT_LEVEL_FALLING;
mode = FALLING;
} else {
event = GPIO_INT_LEVEL_RISING;
mode = RISING;
}
change = true;
break;
default:

View File

@@ -31,10 +31,12 @@ lt_reboot_reason_t lt_get_reboot_reason() {
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;
return REBOOT_REASON_SLEEP_USB;
case RESET_SOURCE_DEEPPS_GPIO:
return REBOOT_REASON_SLEEP_GPIO;
case RESET_SOURCE_DEEPPS_RTC:
return REBOOT_REASON_SLEEP_RTC;
default:
return REBOOT_REASON_UNKNOWN;
}

View File

@@ -19,14 +19,21 @@ 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;
void lt_deep_sleep_keep_floating_gpio(uint32_t gpio_index_map, bool enabled) {
if (enabled) {
deep_sleep_param.gpio_stay_lo_map |= gpio_index_map;
} else {
deep_sleep_param.sleep_time = (duration_math / 1000) & 0xFFFFFFFF;
deep_sleep_param.gpio_stay_lo_map &= (~gpio_index_map);
}
}
void lt_deep_sleep_config_timer(uint32_t sleep_duration_ms) {
deep_sleep_param.wake_up_way |= PS_DEEP_WAKEUP_RTC;
uint64_t sleep_ticks = 32.768 * sleep_duration_ms;
if (sleep_ticks >= 0xFFFFFFFF) {
deep_sleep_param.sleep_time = 0xFFFFFFFE;
} else {
deep_sleep_param.sleep_time = sleep_ticks & 0xFFFFFFFF;
}
}
@@ -34,7 +41,7 @@ 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);
sctrl_enter_rtos_deep_sleep_fix((PS_DEEP_CTRL_PARAM *)&deep_sleep_param);
ps_delay(500);
GLOBAL_INT_RESTORE();
}

View File

@@ -10,8 +10,10 @@
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
#define MEMP_NUM_UDP_PCB (MAX_SOCKETS_UDP + 2 + 1)
#ifndef CONFIG_IPV6
#define ip_addr ip4_addr
#define ip_addr_t ip4_addr_t
#endif
// increase TCP/IP thread stack size (was 512)
#undef TCPIP_THREAD_STACKSIZE

View File

@@ -0,0 +1,9 @@
/* Copyright (c) Kuba Szczodrzyński 2024-05-18. */
#pragma once
#include_next "tls_config.h"
// allow more entropy sources
#undef MBEDTLS_ENTROPY_MAX_SOURCES
#define MBEDTLS_ENTROPY_MAX_SOURCES 10

View File

@@ -0,0 +1,431 @@
#include "include.h"
#include "sys_ctrl.h"
#include "flash_pub.h"
#include "power_save_pub.h"
#include "gpio_pub.h"
#include "reg_rc.h"
#include "manual_ps_pub.h"
// usage:
// extern void sctrl_enter_rtos_deep_sleep_fix(PS_DEEP_CTRL_PARAM *deep_param);
static void sctrl_mac_ahb_slave_clock_disable(void)
{
UINT32 reg;
#if (CFG_SOC_NAME == SOC_BK7271)
reg = REG_READ(SCTRL_CONTROL);
reg &= ~MAC_HCLK_EN_BIT;
REG_WRITE(SCTRL_CONTROL, reg);
#else
reg = REG_READ(SCTRL_MODEM_CORE_RESET_PHY_HCLK);
reg &= ~MAC_HCLK_EN_BIT;
REG_WRITE(SCTRL_MODEM_CORE_RESET_PHY_HCLK, reg);
#endif
}
// This is a patched version, where `gpio_stay_*_map` arguments are actually
// taken into account as intended. The offical doc says that they control
// whether the original voltage should 'stay' (float) instead of configuring
// pins to pullup/pulldown.
//
// https://docs.bekencorp.com/sdk_3.0.x/bk7238/build/en/latest/developer-guide/power_save/sleep_test.html
void sctrl_enter_rtos_deep_sleep_fix(PS_DEEP_CTRL_PARAM *deep_param)
{
DD_HANDLE flash_hdl;
UINT32 status;
UINT32 param;
UINT32 reg;
UINT32 i;
uart_wait_tx_over();
/* close all peri clock*/
REG_WRITE(ICU_PERI_CLK_PWD, 0xfffff); // icu: 0x2;
#if CFG_USE_UART2
uart2_exit();
#endif
#if CFG_USE_UART1
uart1_exit();
#endif
#if (CFG_SOC_NAME == SOC_BK7231U) || (SOC_BK7231N == CFG_SOC_NAME)
reg = REG_READ(SCTRL_LOW_PWR_CLK);
reg &=~(LPO_CLK_MUX_MASK);
reg |=(LPO_SRC_ROSC << LPO_CLK_MUX_POSI);
REG_WRITE(SCTRL_LOW_PWR_CLK, reg);
REG_WRITE(SCTRL_ROSC_CAL, 0x75);
REG_WRITE(SCTRL_ROSC_CAL, 0x77);
#else
/*ana_reg set*/
REG_WRITE(SCTRL_ANALOG_CTRL0, 0x7819a59b);
REG_WRITE(SCTRL_ANALOG_CTRL1, 0x7819a59b);
REG_WRITE(SCTRL_ANALOG_CTRL2, 0x84036080);
REG_WRITE(SCTRL_ANALOG_CTRL3, 0x180004a0);
REG_WRITE(SCTRL_ANALOG_CTRL4, 0x84200e52);
REG_WRITE(SCTRL_ANALOG_CTRL5, 0x3b13b13b);
#if (CFG_SOC_NAME != SOC_BK7231)
REG_WRITE(SCTRL_ANALOG_CTRL6, 0xb09350);
#endif
#if (CFG_SOC_NAME == SOC_BK7221U)
REG_WRITE(SCTRL_ANALOG_CTRL7, 0x441a7f0);
REG_WRITE(SCTRL_ANALOG_CTRL8, 0x3b187c);
REG_WRITE(SCTRL_ANALOG_CTRL9, 0x82204007);
REG_WRITE(SCTRL_ANALOG_CTRL10, 0x80801432);
#endif
#endif
ps_delay(10);
/*clear int*/
REG_WRITE(ICU_INTERRUPT_ENABLE, 0);
extern void gpio_ops_disable_filter(void);
gpio_ops_disable_filter();
/* disable gpio0~31*/
REG_WRITE(SCTRL_GPIO_WAKEUP_EN,0x0); //sys_ctrl : 0x48;
REG_WRITE(SCTRL_GPIO_WAKEUP_INT_STATUS,0xFFFFFFFF); //sys_ctrl : 0x4a;
#if (CFG_SOC_NAME != SOC_BK7231N)
/* disable gpio32~39*/
REG_WRITE(SCTRL_GPIO_WAKEUP_EN1,0x0); //sys_ctrl : 0x51;
REG_WRITE(SCTRL_GPIO_WAKEUP_INT_STATUS1,0xFF); //sys_ctrl : 0x53;
#endif
REG_WRITE(SCTRL_BLOCK_EN_MUX, 0x0); //sys_ctrl : 0x4F;
/* ROSC_TIMER_int_clear*/
reg = REG_READ(SCTRL_ROSC_TIMER);
reg = reg| ROSC_TIMER_INT_STATUS_BIT ;
REG_WRITE(SCTRL_ROSC_TIMER,reg); //sys_ctrl : 0x47;
/*ROSC_TIMER close */
reg = REG_READ(SCTRL_ROSC_TIMER);
reg = reg & (~ROSC_TIMER_ENABLE_BIT); //'C'
REG_WRITE(SCTRL_ROSC_TIMER,reg);
reg = REG_READ(SCTRL_LOW_PWR_CLK);
reg &=~(LPO_CLK_MUX_MASK);
if(deep_param->lpo_32k_src == LPO_SELECT_32K_XTAL)
{
reg |=(LPO_SRC_32K_XTAL << LPO_CLK_MUX_POSI);
}
else
{
reg |=(LPO_SRC_ROSC << LPO_CLK_MUX_POSI);
}
REG_WRITE(SCTRL_LOW_PWR_CLK, reg); //sys_ctrl : 0x40;
/* close all peri int*/
// REG_WRITE(ICU_INTERRUPT_ENABLE, 0);
/* MAC pwd*/
REG_WRITE(SCTRL_PWR_MAC_MODEM, MAC_PWD << MAC_PWD_POSI); //sys_ctrl : 0x43;
sctrl_mac_ahb_slave_clock_disable();
/* Mac Subsystem clock 480m disable*/
reg = REG_READ(SCTRL_CONTROL);
REG_WRITE(SCTRL_CONTROL, reg | MAC_CLK480M_PWD_BIT);
/* Modem pwd*/
REG_WRITE(SCTRL_PWR_MAC_MODEM, MODEM_PWD << MODEM_PWD_POSI);
/* Modem AHB clock disable*/
reg = REG_READ(SCTRL_MODEM_CORE_RESET_PHY_HCLK);
reg &= ~PHY_HCLK_EN_BIT;
REG_WRITE(SCTRL_MODEM_CORE_RESET_PHY_HCLK, reg);
/* Modem Subsystem clock 480m disable*/
reg = REG_READ(SCTRL_CONTROL);
REG_WRITE(SCTRL_CONTROL, reg | MODEM_CLK480M_PWD_BIT);
/* Flash 26MHz clock select dco clock*/
flash_hdl = ddev_open(FLASH_DEV_NAME, &status, 0);
ASSERT(DD_HANDLE_UNVALID != flash_hdl);
ddev_control(flash_hdl, CMD_FLASH_SET_DCO, 0);
/* MCLK(main clock) select:dco*/ /* MCLK division*/
reg = REG_READ(SCTRL_CONTROL);
reg &= ~(MCLK_MUX_MASK << MCLK_MUX_POSI);
reg &= ~(MCLK_DIV_MASK << MCLK_DIV_POSI);
REG_WRITE(SCTRL_CONTROL, reg); //0x02
if(deep_param->lpo_32k_src == LPO_SELECT_32K_XTAL)
{
reg = REG_READ(SCTRL_CONTROL);
reg =((reg & (~0xF0)) | (0<<4));
reg =((reg & (~0x03)) | (0<<MCLK_MUX_POSI));
reg =((reg & (~0x100)) | FLASH_26M_MUX_BIT);
REG_WRITE(SCTRL_CONTROL,reg); //sys_ctrl : 0x02;
}
ps_delay(10);
reg = 0x0;
reg = (reg &(~(BLOCK_EN_WORD_MASK << 20))&(~(0x7FFFUL<<5)) &(~(0x01UL<<1)));
reg = (reg |(BLOCK_EN_WORD_PWD<< 20 )|BLK_EN_FLASH|BLK_EN_ROSC32K|BLK_EN_DIGITAL_CORE|BLK_EN_ANALOG_SYS_LDO);
if(deep_param->lpo_32k_src == LPO_SELECT_32K_XTAL)
{
reg = (reg |BLK_EN_32K_XTAL|BLK_EN_26M_XTAL);
}
REG_WRITE(SCTRL_BLOCK_EN_CFG, reg); //sys_ctrl : 0x4B; //'E'
#if (CFG_SOC_NAME != SOC_BK7231U) && (SOC_BK7231N != CFG_SOC_NAME)
reg = REG_READ(SCTRL_ROSC_CAL); //ROSC Calibration disable
reg =(reg & (~0x01));
REG_WRITE(SCTRL_ROSC_CAL, reg);
#endif
for(i=0; i<GPIONUM; i++)
{
#if (CFG_SOC_NAME == SOC_BK7231N)
if(((i > GPIO1) && (i < GPIO6))
|| ((i > GPIO11) && (i < GPIO14))
|| ((i > GPIO17) && (i < GPIO20))
|| ((i > GPIO24) && (i < GPIO26))
|| ((i > GPIO26) && (i < GPIO28)))
{
continue;
}
#endif
if(((i < BITS_INT)&&(deep_param->gpio_stay_lo_map & (0x01UL << i)))
||((deep_param->gpio_index_map & (0x01UL << i)))
||((deep_param->gpio_last_index_map & (0x01UL << i)))
||((i >= BITS_INT)&&(deep_param->gpio_stay_hi_map & (0x01UL << (i - BITS_INT)))) )
{
continue;
}
param = GPIO_CFG_PARAM(i, GMODE_DEEP_PS); /*set gpio 0~39 as high impendance*/
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
}
if (((deep_param->wake_up_way & PS_DEEP_WAKEUP_RTC))
&& (deep_param->sleep_time!= 0xffffffff))
{
/*ROSC_TIMER init*/
#if (CFG_SOC_NAME != SOC_BK7231)
reg = (deep_param->sleep_time >> 16)& 0xffff; //'A'
REG_WRITE(SCTRL_ROSC_TIMER_H,reg);
#endif
reg = REG_READ(SCTRL_ROSC_TIMER);
reg |= ROSC_TIMER_INT_STATUS_BIT; //'C'
REG_WRITE(SCTRL_ROSC_TIMER,reg); //sys_ctrl : 0x47;
reg = REG_READ(SCTRL_ROSC_TIMER);
reg &= ~(ROSC_TIMER_PERIOD_MASK << ROSC_TIMER_PERIOD_POSI);
reg |= ((deep_param->sleep_time & ROSC_TIMER_PERIOD_MASK) << ROSC_TIMER_PERIOD_POSI);
REG_WRITE(SCTRL_ROSC_TIMER,reg); //sys_ctrl : 0x47; //'D'
reg = REG_READ(SCTRL_ROSC_TIMER);
reg |= ROSC_TIMER_ENABLE_BIT;
REG_WRITE(SCTRL_ROSC_TIMER,reg); //sys_ctrl : 0x47; //'B'
if(deep_param->lpo_32k_src == LPO_SELECT_32K_XTAL)
{
REG_WRITE(SCTRL_CONTROL, 0x330100);
REG_WRITE(SCTRL_BLOCK_EN_CFG, (0x15D|(0xA5C<<20)));
REG_WRITE(SCTRL_ROSC_CAL, 0x30);
REG_WRITE(SCTRL_LOW_PWR_CLK, 0x01);
REG_WRITE(SCTRL_MODEM_CORE_RESET_PHY_HCLK, 0x03);
REG_WRITE(SCTRL_CLK_GATING, 0x1ff);
}
}
#if ((CFG_SOC_NAME != SOC_BK7231N) && (CFG_SOC_NAME != SOC_BK7236))
if ((deep_param->wake_up_way & PS_DEEP_WAKEUP_GPIO))
{
for (i = 0; i < BITS_INT; i++)
{
#if(BITS_INT > GPIONUM)
if(i >= GPIONUM)
{
break;
}
#endif
if (deep_param->gpio_index_map & (0x01UL << i)) /*set gpio 0~31 mode*/
{
if( deep_param->gpio_edge_map & (0x01UL << i)) //0:high,1:low.
{
if (deep_param->gpio_stay_lo_map & (0x01UL << i)) {
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i, GMODE_INPUT_PULLUP);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
if(0x1 != (UINT32)gpio_ctrl( CMD_GPIO_INPUT, &i))
{ /*check gpio really input value,to correct wrong edge setting*/
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
deep_param->gpio_edge_map &= ~(0x01UL << i);
}
}
else
{
if (deep_param->gpio_stay_lo_map & (0x01UL << i)) {
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i, GMODE_INPUT_PULLDOWN);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
if(0x0 != (UINT32)gpio_ctrl( CMD_GPIO_INPUT, &i))
{ /*check gpio really input value,to correct wrong edge setting*/
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
deep_param->gpio_edge_map |= (0x01UL << i);
}
}
}
}
for (i = 0; i < (GPIONUM - BITS_INT); i++)
{
if (deep_param->gpio_last_index_map & (0x01UL << i)) /*set gpio 32~39 mode*/
{
if( deep_param->gpio_last_edge_map & (0x01UL << i))
{
if (deep_param->gpio_stay_hi_map & (0x01UL << (i - BITS_INT))) {
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT_PULLUP);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
reg = i + BITS_INT;
if(0x1 != (UINT32)gpio_ctrl( CMD_GPIO_INPUT, &reg))
{ /*check gpio really input value,to correct wrong edge setting*/
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT);
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
deep_param->gpio_last_edge_map &= ~(0x01UL << i);
}
}
else
{
if (deep_param->gpio_stay_hi_map & (0x01UL << (i - BITS_INT))) {
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT_PULLDOWN);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
reg = i + BITS_INT;
if(0x0 != (UINT32)gpio_ctrl( CMD_GPIO_INPUT, &reg))
{ /*check gpio really input value,to correct wrong edge setting*/
param = GPIO_CFG_PARAM(i + BITS_INT, GMODE_INPUT);
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
deep_param->gpio_last_edge_map |= (0x01UL << i);
}
}
}
}
/* set gpio 0~31 mode*/
reg = 0xFFFFFFFF;
REG_WRITE(SCTRL_GPIO_WAKEUP_INT_STATUS,reg);
reg = deep_param->gpio_edge_map;
REG_WRITE(SCTRL_GPIO_WAKEUP_TYPE,reg);
reg = deep_param->gpio_index_map;
REG_WRITE(SCTRL_GPIO_WAKEUP_EN,reg);
/* set gpio 31~32 mode*/
reg = 0xFF;
REG_WRITE(SCTRL_GPIO_WAKEUP_INT_STATUS1,reg);
reg = deep_param->gpio_last_edge_map;
REG_WRITE(SCTRL_GPIO_WAKEUP_TYPE1,reg);
reg = deep_param->gpio_last_index_map;
REG_WRITE(SCTRL_GPIO_WAKEUP_EN1,reg);
}
#elif ((CFG_SOC_NAME == SOC_BK7231N) || (CFG_SOC_NAME == SOC_BK7236))
if(( deep_param->wake_up_way & PS_DEEP_WAKEUP_GPIO ))
{
for ( i = 0; i < BITS_INT; i++ )
{
#if(BITS_INT > GPIONUM)
if( i >= GPIONUM )
{
break;
}
#endif
if((( i > GPIO1 ) && ( i < GPIO6 ))
|| (( i > GPIO11 ) && ( i < GPIO14 ))
|| (( i > GPIO17 ) && ( i < GPIO20 ))
|| (( i > GPIO24 ) && ( i < GPIO26 ))
|| (( i > GPIO26 ) && ( i < GPIO28 )))
{
continue;
}
if ( deep_param->gpio_index_map & ( 0x01UL << i ))
{
int type_h,type_l;
type_l = deep_param->gpio_edge_map;
type_h = 0x0;
/* low level or negedge wakeup */
if(( type_h & ( 0x01UL << i )) == ( type_l & ( 0x01UL << i )))
{
if (deep_param->gpio_stay_lo_map & (0x01UL << i)) {
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i, GMODE_INPUT_PULLUP);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
}
else /* high level or posedge wakeup */
{
if (deep_param->gpio_stay_lo_map & (0x01UL << i)) {
param = GPIO_CFG_PARAM(i, GMODE_INPUT);
} else {
param = GPIO_CFG_PARAM(i, GMODE_INPUT_PULLDOWN);
}
sddev_control(GPIO_DEV_NAME, CMD_GPIO_CFG, &param);
}
REG_WRITE(SCTRL_GPIO_WAKEUP_TYPE, type_l);
REG_WRITE(SCTRL_GPIO_WAKEUP_TYPE_SELECT, type_h);
}
}
reg = deep_param->gpio_index_map;
REG_WRITE(SCTRL_GPIO_WAKEUP_EN,reg);
}
#endif
#if (CFG_SOC_NAME != SOC_BK7231N)
REG_WRITE(SCTRL_USB_PLUG_WAKEUP,USB_PLUG_IN_INT_BIT|USB_PLUG_OUT_INT_BIT);
if(deep_param->wake_up_way & PS_DEEP_WAKEUP_USB)
{
REG_WRITE(SCTRL_USB_PLUG_WAKEUP,USB_PLUG_IN_EN_BIT|USB_PLUG_OUT_EN_BIT);
}
#endif
#ifdef BK_DEEP_SLEEP_DEBUG
BK_DEEP_SLEEP_PRT("SCTRL_CONTROL=0x%08X\r\n", REG_READ(SCTRL_CONTROL));
BK_DEEP_SLEEP_PRT("SCTRL_SLEEP=0x%08X\r\n", REG_READ(SCTRL_SLEEP));
BK_DEEP_SLEEP_PRT("SCTRL_ROSC_TIMER=0x%08X\r\n", REG_READ(SCTRL_ROSC_TIMER));
BK_DEEP_SLEEP_PRT("SCTRL_BLOCK_EN_CFG=0x%08X\r\n", REG_READ(SCTRL_BLOCK_EN_CFG));
BK_DEEP_SLEEP_PRT("SCTRL_ROSC_CAL=0x%08X\r\n", REG_READ(SCTRL_ROSC_CAL));
BK_DEEP_SLEEP_PRT("SCTRL_BLOCK_EN_MUX=0x%08X\r\n", REG_READ(SCTRL_BLOCK_EN_MUX));
BK_DEEP_SLEEP_PRT("SCTRL_LOW_PWR_CLK=0x%08X\r\n", REG_READ(SCTRL_LOW_PWR_CLK));
BK_DEEP_SLEEP_PRT("SCTRL_PWR_MAC_MODEM=0x%08X\r\n", REG_READ(SCTRL_PWR_MAC_MODEM));
BK_DEEP_SLEEP_PRT("SCTRL_MODEM_CORE_RESET_PHY_HCLK=0x%08X\r\n", REG_READ(SCTRL_MODEM_CORE_RESET_PHY_HCLK));
BK_DEEP_SLEEP_PRT("SCTRL_CLK_GATING=0x%08X\r\n", REG_READ(SCTRL_CLK_GATING));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_INT_STATUS=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_INT_STATUS));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_TYPE=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_TYPE));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_EN=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_EN));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_INT_STATUS1=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_INT_STATUS1));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_TYPE1=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_TYPE1));
BK_DEEP_SLEEP_PRT("SCTRL_GPIO_WAKEUP_EN1=0x%08X\r\n", REG_READ(SCTRL_GPIO_WAKEUP_EN1));
#endif
/* enter deep_sleep mode */
reg = REG_READ(SCTRL_SLEEP);
reg &= ~(SLEEP_MODE_MASK << SLEEP_MODE_POSI);
reg = reg | SLEEP_MODE_CFG_DEEP_WORD;
REG_WRITE(SCTRL_SLEEP, reg);
delay(5);
}

View File

@@ -18,7 +18,7 @@ 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 sctrl_enter_rtos_deep_sleep_fix(PS_DEEP_CTRL_PARAM *deep_param);
void ps_delay(volatile UINT16 times);
#ifdef __cplusplus

View File

@@ -70,8 +70,12 @@ OSStatus __wrap_bk_flash_erase(bk_partition_t partition, uint32_t off_set, uint3
return kNoErr;
}
OSStatus
__wrap_bk_flash_write(bk_partition_t partition, volatile uint32_t off_set, uint8_t *inBuffer, uint32_t inBufferLength) {
OSStatus __wrap_bk_flash_write(
bk_partition_t partition,
volatile uint32_t off_set,
uint8_t *inBuffer,
uint32_t inBufferLength
) {
UINT32 status;
DD_HANDLE flash_hdl;
uint32_t start_addr;
@@ -98,8 +102,12 @@ __wrap_bk_flash_write(bk_partition_t partition, volatile uint32_t off_set, uint8
return kNoErr;
}
OSStatus
__wrap_bk_flash_read(bk_partition_t partition, volatile uint32_t off_set, uint8_t *outBuffer, uint32_t inBufferLength) {
OSStatus __wrap_bk_flash_read(
bk_partition_t partition,
volatile uint32_t off_set,
uint8_t *outBuffer,
uint32_t inBufferLength
) {
UINT32 status;
uint32_t start_addr;
DD_HANDLE flash_hdl;

View File

@@ -8,6 +8,8 @@
using namespace arduino;
typedef RingBufferN<LT_SERIAL_BUFFER_SIZE> SerialRingBuffer;
class SerialClass : public HardwareSerial {
private:
uint32_t port;
@@ -18,7 +20,7 @@ class SerialClass : public HardwareSerial {
void *data;
private:
RingBuffer *buf;
SerialRingBuffer *buf;
uint32_t baudrate;
uint16_t config;

View File

@@ -27,7 +27,7 @@ typedef enum {
typedef struct {
SoftState state;
RingBuffer *buf;
SerialRingBuffer *buf;
uint8_t byte;
pin_size_t pin;
void *param;

View File

@@ -97,8 +97,13 @@ class WiFiClass {
const uint8_t *bssid = NULL,
bool connect = true
);
WiFiStatus
begin(char *ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t *bssid = NULL, bool connect = true);
WiFiStatus begin(
char *ssid,
char *passphrase = NULL,
int32_t channel = 0,
const uint8_t *bssid = NULL,
bool connect = true
);
bool config(
IPAddress localIP,
@@ -129,6 +134,8 @@ class WiFiClass {
uint8_t subnetCIDR();
bool enableIpV6();
IPv6Address localIPv6();
std::vector<IPv6Address> allLocalIPv6();
const char *getHostname();
bool setHostname(const char *hostname);
bool setMacAddress(const uint8_t *mac);
@@ -176,7 +183,11 @@ class WiFiClass {
public: /* WiFiAP.cpp */
bool softAP(
const char *ssid, const char *passphrase = NULL, int channel = 1, bool ssidHidden = false, int maxClients = 4
const char *ssid,
const char *passphrase = NULL,
int channel = 1,
bool ssidHidden = false,
int maxClients = 4
);
bool softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet);
bool softAPdisconnect(bool wifiOff = false);

View File

@@ -44,5 +44,9 @@ __attribute__((weak)) bool WiFiClass::enableIpV6() {
}
__attribute__((weak)) IPv6Address WiFiClass::localIPv6() {
return IPv6Address();
return {};
}
__attribute__((weak)) std::vector<IPv6Address> WiFiClass::allLocalIPv6() {
return {};
}

View File

@@ -3,7 +3,12 @@
#include "WiFi.h"
bool WiFiClass::getNetworkInfo(
uint8_t networkItem, String &ssid, WiFiAuthMode &encType, int32_t &rssi, uint8_t *&bssid, int32_t &channel
uint8_t networkItem,
String &ssid,
WiFiAuthMode &encType,
int32_t &rssi,
uint8_t *&bssid,
int32_t &channel
) {
ssid = SSID(networkItem);
encType = encryptionType(networkItem);

View File

@@ -86,13 +86,21 @@ int MbedTLSClient::connect(const char *host, uint16_t port, int32_t timeout) {
}
int MbedTLSClient::connect(
IPAddress ip, uint16_t port, const char *rootCABuf, const char *clientCert, const char *clientKey
IPAddress ip,
uint16_t port,
const char *rootCABuf,
const char *clientCert,
const char *clientKey
) {
return connect(ipToString(ip).c_str(), port, 0, rootCABuf, clientCert, clientKey, NULL, NULL) == 0;
}
int MbedTLSClient::connect(
const char *host, uint16_t port, const char *rootCABuf, const char *clientCert, const char *clientKey
const char *host,
uint16_t port,
const char *rootCABuf,
const char *clientCert,
const char *clientKey
) {
return connect(host, port, 0, rootCABuf, clientCert, clientKey, NULL, NULL) == 0;
}
@@ -165,7 +173,7 @@ int MbedTLSClient::connect(
#ifdef MBEDTLS_SSL_ALPN
if (_alpnProtocols) {
ret = mbedtls_ssl_conf_alpn_protocols(&_sslCfg, _alpnProtocols);
ret = mbedtls_ssl_conf_alpn_protocols(_sslCfg, _alpnProtocols);
LT_RET_NZ(ret);
}
#endif

View File

@@ -26,12 +26,22 @@
class IWiFiClientSecure {
public:
virtual int
connect(IPAddress ip, uint16_t port, const char *rootCABuf, const char *clientCert, const char *clientKey) = 0;
virtual int
connect(const char *host, uint16_t port, const char *rootCABuf, const char *clientCert, const char *clientKey) = 0;
virtual int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psk) = 0;
virtual int connect(const char *host, uint16_t port, const char *pskIdent, const char *psk) = 0;
virtual int connect(
IPAddress ip,
uint16_t port,
const char *rootCABuf,
const char *clientCert,
const char *clientKey
) = 0;
virtual int connect(
const char *host,
uint16_t port,
const char *rootCABuf,
const char *clientCert,
const char *clientKey
) = 0;
virtual int connect(IPAddress ip, uint16_t port, const char *pskIdent, const char *psk) = 0;
virtual int connect(const char *host, uint16_t port, const char *pskIdent, const char *psk) = 0;
virtual int lastError(char *buf, const size_t size) = 0;
virtual void setInsecure() = 0; // Don't validate the chain, just accept whatever is given. VERY INSECURE!

View File

@@ -20,11 +20,45 @@ extern "C" {
#if LWIP_MDNS_RESPONDER
static std::vector<char *> services_name;
static std::vector<char *> services;
static std::vector<uint8_t> protos;
static std::vector<uint16_t> ports;
static std::vector<std::vector<char *>> records;
struct CachedService {
CachedService(const char *_name, const char *_service, mdns_sd_proto _proto, uint16_t _port)
: name(strdup(_name)), service(strdup(_service)), proto(_proto), port(_port) {}
CachedService(const CachedService &) = delete;
CachedService &operator=(const CachedService &) = delete;
CachedService(CachedService &&other)
: name(other.name), service(other.service), proto(other.proto), port(other.port),
records(std::move(other.records)) {
other.name = nullptr;
other.service = nullptr;
other.records.clear();
}
~CachedService() {
if (name) {
free(name);
}
if (service) {
free(service);
}
for (auto &str : records) {
if (str) {
free(str);
}
}
}
char *name;
char *service;
mdns_sd_proto proto;
uint16_t port;
std::vector<char *> records;
};
static std::vector<CachedService> sCachedServices;
static const char *hostName;
#ifdef LWIP_NETIF_EXT_STATUS_CALLBACK
@@ -33,46 +67,72 @@ NETIF_DECLARE_EXT_CALLBACK(netif_callback)
mDNS::mDNS() {}
mDNS::~mDNS() {}
mDNS::~mDNS() {
cleanup();
}
void mDNS::cleanup() {
sCachedServices.clear();
free((void *)hostName);
hostName = NULL;
free((void *)instanceName);
instanceName = NULL;
}
static void mdnsTxtCallback(struct mdns_service *service, void *userdata) {
size_t index = (size_t)userdata;
if (index >= records.size())
if (index >= sCachedServices.size())
return;
for (const auto record : records[index]) {
for (const auto &record : sCachedServices[index].records) {
err_t err = mdns_resp_add_service_txtitem(service, record, strlen(record));
if (err != ERR_OK)
return;
if (err != ERR_OK) {
LT_WM(MDNS, "Error %d while adding txt record: %s", err, record);
}
}
}
#if LWIP_VERSION_SIMPLE < 20200 // TTL removed in LwIP commit 62fb2fd749b (2.2.0 release)
static void mdnsStatusCallback(struct netif *netif, uint8_t result) {
LT_DM(MDNS, "Status: netif %u, status %u", netif->num, result);
}
#else
static void mdnsStatusCallback(struct netif *netif, uint8_t result, int8_t slot) {
LT_DM(MDNS, "Status: netif %u, status %u slot %d", netif->num, result, slot);
}
#endif
#ifdef LWIP_NETIF_EXT_STATUS_CALLBACK
static void addServices(struct netif *netif) {
for (uint8_t i = 0; i < services.size(); i++) {
for (uint8_t i = 0; i < sCachedServices.size(); i++) {
const auto &cachedService = sCachedServices[i];
LT_DM(
MDNS,
"Add service: netif %u / %s / %s / %u / %u",
netif->num,
services_name[i],
services[i],
protos[i],
ports[i]
cachedService.name,
cachedService.service,
cachedService.proto,
cachedService.port
);
mdns_resp_add_service(
s8_t slot = mdns_resp_add_service(
netif,
services_name[i],
services[i],
(mdns_sd_proto)protos[i],
ports[i],
cachedService.name,
cachedService.service,
cachedService.proto,
cachedService.port,
#if LWIP_VERSION_SIMPLE < 20200 // TTL removed in LwIP commit 62fb2fd749b (2.2.0 release)
255,
#endif
mdnsTxtCallback,
reinterpret_cast<void *>(i) // index of newly added service
);
if (slot < 0) {
LT_WM(MDNS, "mdns_resp_add_service returned error %d", slot);
}
}
}
#endif
@@ -85,7 +145,11 @@ static bool enableMDNS(struct netif *netif) {
igmp_start(netif);
LT_DM(MDNS, "Added IGMP to netif %u", netif->num);
}
#if LWIP_VERSION_SIMPLE < 20200 // TTL removed in LwIP commit 62fb2fd749b (2.2.0 release)
err_t ret = mdns_resp_add_netif(netif, hostName, 255);
#else
err_t ret = mdns_resp_add_netif(netif, hostName);
#endif
if (ret == ERR_OK) {
LT_DM(MDNS, "mDNS started on netif %u, announcing it to network", netif->num);
#if LWIP_VERSION_SIMPLE >= 20100
@@ -102,14 +166,17 @@ static bool enableMDNS(struct netif *netif) {
}
#ifdef LWIP_NETIF_EXT_STATUS_CALLBACK
static void
mdns_netif_ext_status_callback(struct netif *netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args) {
static void mdns_netif_ext_status_callback(
struct netif *netif,
netif_nsc_reason_t reason,
const netif_ext_callback_args_t *args
) {
if (reason & LWIP_NSC_NETIF_REMOVED) {
LT_DM(MDNS, "Netif removed, stopping mDNS on netif %u", netif->num);
mdns_resp_remove_netif(netif);
} else if (reason & LWIP_NSC_STATUS_CHANGED) {
LT_DM(MDNS, "Netif changed, starting mDNS on netif %u", netif->num);
if (enableMDNS(netif) && services.size() > 0) {
} else if ((reason & LWIP_NSC_STATUS_CHANGED) || (reason & LWIP_NSC_NETIF_ADDED)) {
LT_DM(MDNS, "Netif changed/added, starting mDNS on netif %u", netif->num);
if (enableMDNS(netif) && sCachedServices.size() > 0) {
LT_DM(MDNS, "Adding services to netif %u", netif->num);
addServices(netif);
}
@@ -136,63 +203,71 @@ bool mDNS::begin(const char *hostname) {
}
void mDNS::end() {
#ifdef LWIP_NETIF_EXT_STATUS_CALLBACK
netif_remove_ext_callback(&netif_callback);
#endif
struct netif *netif = netif_list;
while (netif != NULL) {
if (netif_is_up(netif))
mdns_resp_remove_netif(netif);
netif = netif->next;
}
cleanup();
}
bool mDNS::addServiceImpl(const char *name, const char *service, uint8_t proto, uint16_t port) {
bool added = false;
struct netif *netif = netif_list;
std::size_t serviceIndex = sCachedServices.size();
// add the service to TXT record arrays
sCachedServices.emplace_back(name, service, (mdns_sd_proto)proto, port);
while (netif != NULL) {
if (netif_is_up(netif)) {
// register TXT callback;
// pass service index as userdata parameter
LT_DM(MDNS, "Add service: netif %u / %s / %s / %u / %u", netif->num, name, service, proto, port);
mdns_resp_add_service(
s8_t slot = mdns_resp_add_service(
netif,
name,
service,
(mdns_sd_proto)proto,
port,
#if LWIP_VERSION_SIMPLE < 20200 // TTL removed in LwIP commit 62fb2fd749b (2.2.0 release)
255,
#endif
mdnsTxtCallback,
(void *)services.size() // index of newly added service
(void *)serviceIndex // index of newly added service
);
if (slot < 0) {
LT_WM(MDNS, "mdns_resp_add_service returned error %d", slot);
}
added = true;
}
netif = netif->next;
}
if (!added)
return false;
// add the service to TXT record arrays
services_name.push_back(strdup(name));
services.push_back(strdup(service));
protos.push_back(proto);
ports.push_back(port);
records.emplace_back();
return true;
return added;
}
bool mDNS::addServiceTxtImpl(const char *service, uint8_t proto, const char *item) {
int8_t index = -1;
for (uint8_t i = 0; i < services.size(); i++) {
uint8_t i;
for (i = 0; i < sCachedServices.size(); i++) {
const auto &cachedService = sCachedServices[i];
// find a matching service
if (strcmp(services[i], service) == 0 && protos[i] == proto) {
index = i;
if (strcmp(cachedService.service, service) == 0 && cachedService.proto == proto) {
break;
}
}
if (index == -1)
if (i == sCachedServices.size())
return false;
records[index].push_back(strdup(item));
sCachedServices[i].records.push_back(strdup(item));
return true;
}

View File

@@ -2,14 +2,23 @@
#include "mDNS.h"
static char *ensureUnderscore(const char *value) {
uint8_t len = strlen(value) + 1;
static char *ensureUnderscore(char *value) {
if (value[0] == '_') {
return value;
}
size_t len = strlen(value) + 1 + 1; // 1 for underscore, 1 for null-terminator
char *result = (char *)malloc(len);
result[0] = '_';
strcpy(result + 1, value + (value[0] == '_'));
strcpy(result + 1, value);
return result;
}
static inline void freeIfCopied(const char *original, char *duplicate) {
if ((duplicate) && (original != duplicate)) {
free(duplicate);
}
}
void mDNS::setInstanceName(const char *name) {
if (instanceName)
free(instanceName);
@@ -21,7 +30,7 @@ bool mDNS::addService(char *service, char *proto, uint16_t port) {
uint8_t _proto = strncmp(proto + (proto[0] == '_'), "tcp", 3) == 0 ? MDNS_TCP : MDNS_UDP;
bool result = addServiceImpl(instanceName ? instanceName : "LT mDNS", _service, _proto, port);
free(_service);
freeIfCopied(service, _service);
return result;
}
@@ -34,7 +43,7 @@ bool mDNS::addServiceTxt(char *service, char *proto, char *key, char *value) {
sprintf(txt, "%s=%s", key, value);
bool result = addServiceTxtImpl(_service, _proto, txt);
free(_service);
freeIfCopied(service, _service);
free(txt);
return result;
}

View File

@@ -51,6 +51,7 @@ class mDNS {
private:
bool addServiceImpl(const char *name, const char *service, uint8_t proto, uint16_t port);
bool addServiceTxtImpl(const char *service, uint8_t proto, const char *item);
void cleanup();
char *instanceName = NULL;

View File

@@ -321,7 +321,12 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const char *CAcer
}
bool HTTPClient::begin(
String host, uint16_t port, String uri, const char *CAcert, const char *cli_cert, const char *cli_key
String host,
uint16_t port,
String uri,
const char *CAcert,
const char *cli_cert,
const char *cli_key
) {
if (_client && !_tcpDeprecated) {
log_d("mix up of new and deprecated api");

View File

@@ -1,48 +1,48 @@
#pragma once
/* Request Methods */
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M - SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
#define HTTP_METHOD_MAP(XX) \
XX(0, DELETE, DELETE) \
XX(1, GET, GET) \
XX(2, HEAD, HEAD) \
XX(3, POST, POST) \
XX(4, PUT, PUT) \
/* pathological */ \
XX(5, CONNECT, CONNECT) \
XX(6, OPTIONS, OPTIONS) \
XX(7, TRACE, TRACE) \
/* WebDAV */ \
XX(8, COPY, COPY) \
XX(9, LOCK, LOCK) \
XX(10, MKCOL, MKCOL) \
XX(11, MOVE, MOVE) \
XX(12, PROPFIND, PROPFIND) \
XX(13, PROPPATCH, PROPPATCH) \
XX(14, SEARCH, SEARCH) \
XX(15, UNLOCK, UNLOCK) \
XX(16, BIND, BIND) \
XX(17, REBIND, REBIND) \
XX(18, UNBIND, UNBIND) \
XX(19, ACL, ACL) \
/* subversion */ \
XX(20, REPORT, REPORT) \
XX(21, MKACTIVITY, MKACTIVITY) \
XX(22, CHECKOUT, CHECKOUT) \
XX(23, MERGE, MERGE) \
/* upnp */ \
XX(24, MSEARCH, M - SEARCH) \
XX(25, NOTIFY, NOTIFY) \
XX(26, SUBSCRIBE, SUBSCRIBE) \
XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \
/* RFC-5789 */ \
XX(28, PATCH, PATCH) \
XX(29, PURGE, PURGE) \
/* CalDAV */ \
XX(30, MKCALENDAR, MKCALENDAR) \
/* RFC-2068, section 19.6.1.2 */ \
XX(31, LINK, LINK) \
XX(32, UNLINK, UNLINK) \
/* icecast */ \
XX(33, SOURCE, SOURCE)
enum http_method {

View File

@@ -81,7 +81,9 @@ class WebServer {
bool authenticate(const char *username, const char *password);
void requestAuthentication(
HTTPAuthMethod mode = BASIC_AUTH, const char *realm = NULL, const String &authFailMsg = String("")
HTTPAuthMethod mode = BASIC_AUTH,
const char *realm = NULL,
const String &authFailMsg = String("")
);
typedef std::function<void(void)> THandlerFunction;

View File

@@ -10,7 +10,10 @@ using namespace mime;
class FunctionRequestHandler : public RequestHandler {
public:
FunctionRequestHandler(
WebServer::THandlerFunction fn, WebServer::THandlerFunction ufn, const Uri &uri, HTTPMethod method
WebServer::THandlerFunction fn,
WebServer::THandlerFunction ufn,
const Uri &uri,
HTTPMethod method
)
: _fn(fn), _ufn(ufn), _uri(uri.clone()), _method(method) {
_uri->initPathArgs(pathArgs);

View File

@@ -5,8 +5,8 @@
class UriBraces : public Uri {
public:
explicit UriBraces(const char *uri) : Uri(uri){};
explicit UriBraces(const String &uri) : Uri(uri){};
explicit UriBraces(const char *uri) : Uri(uri) {};
explicit UriBraces(const String &uri) : Uri(uri) {};
Uri *clone() const override final {
return new UriBraces(_uri);

View File

@@ -6,8 +6,8 @@
class UriGlob : public Uri {
public:
explicit UriGlob(const char *uri) : Uri(uri){};
explicit UriGlob(const String &uri) : Uri(uri){};
explicit UriGlob(const char *uri) : Uri(uri) {};
explicit UriGlob(const String &uri) : Uri(uri) {};
Uri *clone() const override final {
return new UriGlob(_uri);

View File

@@ -6,8 +6,8 @@
class UriRegex : public Uri {
public:
explicit UriRegex(const char *uri) : Uri(uri){};
explicit UriRegex(const String &uri) : Uri(uri){};
explicit UriRegex(const char *uri) : Uri(uri) {};
explicit UriRegex(const String &uri) : Uri(uri) {};
Uri *clone() const override final {
return new UriRegex(_uri);

View File

@@ -7,3 +7,6 @@ String ipToString(const IPAddress &ip) {
sprintf(szRet, "%hhu.%hhu.%hhu.%hhu", ip[0], ip[1], ip[2], ip[3]);
return String(szRet);
}
// global empty string to allow returning const String& with nothing
const String emptyString;

View File

@@ -22,11 +22,13 @@ extern "C" {
#define voidFuncPtrArg voidFuncPtrParam
// Additional Arduino compatibility macros
#define round(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x)-0.5))
#ifndef __cplusplus
#define round(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x) - 0.5))
#endif
#define digitalPinToInterrupt(pin) (pin)
// FreeRTOS utilities
#define xTaskCreateUniversal(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID) \
#define xTaskCreateUniversal(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, xCoreID) \
xTaskCreate(pxTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask)
#define xTaskCreatePinnedToCore xTaskCreateUniversal
@@ -35,6 +37,7 @@ extern "C" {
#ifdef __cplusplus
String ipToString(const IPAddress &ip);
extern const String emptyString;
#endif
#ifdef __cplusplus

View File

@@ -27,36 +27,36 @@ inline void pinDisable(PinInfo *pin, uint32_t mask) {
pin->enabled &= ~mask;
}
#define pinCheckGetInfo(pinNumber, mask, ret) \
PinInfo *pin = pinInfo(pinNumber); \
if (!pin) \
return ret; \
if (!pinSupported(pin, mask)) \
#define pinCheckGetInfo(pinNumber, mask, ret) \
PinInfo *pin = pinInfo(pinNumber); \
if (!pin) \
return ret; \
if (!pinSupported(pin, mask)) \
return ret;
#define pinCheckGetData(pinNumber, mask, ret) \
PinInfo *pin = pinInfo(pinNumber); \
if (!pin) \
return ret; \
if (!pinSupported(pin, mask)) \
return ret; \
#define pinCheckGetData(pinNumber, mask, ret) \
PinInfo *pin = pinInfo(pinNumber); \
if (!pin) \
return ret; \
if (!pinSupported(pin, mask)) \
return ret; \
PinData *data = pinData(pin);
#define pinIsOutput(pin, data) (pinEnabled(pin, PIN_GPIO) && (data->gpioMode ^ 0b101) < 5)
#define pinIsInput(pin, data) (pinEnabled(pin, PIN_GPIO) && (data->gpioMode ^ 0b101) > 4)
#define pinSetOutputPull(pin, data, pinNumber, status) \
do { \
if (!pinIsOutput(pin, data)) { \
pinMode(pinNumber, INPUT_PULLDOWN ^ !!status); \
return; \
} \
#define pinSetOutputPull(pin, data, pinNumber, status) \
do { \
if (!pinIsOutput(pin, data)) { \
pinMode(pinNumber, INPUT_PULLDOWN ^ !!status); \
return; \
} \
} while (0);
#define pinSetInputMode(pin, data, pinNumber) \
do { \
if (!pinIsInput(pin, data)) \
pinMode(pinNumber, INPUT); \
#define pinSetInputMode(pin, data, pinNumber) \
do { \
if (!pinIsInput(pin, data)) \
pinMode(pinNumber, INPUT); \
} while (0);
#ifdef __cplusplus

View File

@@ -62,8 +62,12 @@ const char *lt_get_reboot_reason_name(lt_reboot_reason_t reason) {
return "WDT Reset";
case REBOOT_REASON_CRASH:
return "Crash";
case REBOOT_REASON_SLEEP:
return "Sleep Wakeup";
case REBOOT_REASON_SLEEP_GPIO:
return "Sleep Wakeup (GPIO)";
case REBOOT_REASON_SLEEP_RTC:
return "Sleep Wakeup (RTC)";
case REBOOT_REASON_SLEEP_USB:
return "Sleep Wakeup (USB)";
case REBOOT_REASON_DEBUGGER:
return "Debugger";
default:

View File

@@ -4,32 +4,40 @@
#include <libretiny.h>
#define RESET_REASON_UNKNOWN REBOOT_REASON_UNKNOWN
#define RESET_REASON_POWER REBOOT_REASON_POWER
#define RESET_REASON_BROWNOUT REBOOT_REASON_BROWNOUT
#define RESET_REASON_HARDWARE REBOOT_REASON_HARDWARE
#define RESET_REASON_SOFTWARE REBOOT_REASON_SOFTWARE
#define RESET_REASON_WATCHDOG REBOOT_REASON_WATCHDOG
#define RESET_REASON_CRASH REBOOT_REASON_CRASH
#define RESET_REASON_SLEEP REBOOT_REASON_SLEEP
#define RESET_REASON_MAX REBOOT_REASON_MAX
#define RESET_REASON_UNKNOWN REBOOT_REASON_UNKNOWN
#define RESET_REASON_POWER REBOOT_REASON_POWER
#define RESET_REASON_BROWNOUT REBOOT_REASON_BROWNOUT
#define RESET_REASON_HARDWARE REBOOT_REASON_HARDWARE
#define RESET_REASON_SOFTWARE REBOOT_REASON_SOFTWARE
#define RESET_REASON_WATCHDOG REBOOT_REASON_WATCHDOG
#define RESET_REASON_CRASH REBOOT_REASON_CRASH
#define RESET_REASON_SLEEP_GPIO REBOOT_REASON_SLEEP_GPIO
#define RESET_REASON_SLEEP_RTC REBOOT_REASON_SLEEP_RTC
#define RESET_REASON_SLEEP_USB REBOOT_REASON_SLEEP_USB
#define RESET_REASON_MAX REBOOT_REASON_MAX
/**
* @brief Reset reason enumeration.
*/
typedef enum {
REBOOT_REASON_UNKNOWN = 1,
REBOOT_REASON_POWER = 2,
REBOOT_REASON_BROWNOUT = 3,
REBOOT_REASON_HARDWARE = 4,
REBOOT_REASON_SOFTWARE = 5,
REBOOT_REASON_WATCHDOG = 6,
REBOOT_REASON_CRASH = 7,
REBOOT_REASON_SLEEP = 8,
REBOOT_REASON_DEBUGGER = 9,
REBOOT_REASON_MAX = 10,
REBOOT_REASON_UNKNOWN = 1,
REBOOT_REASON_POWER = 2,
REBOOT_REASON_BROWNOUT = 3,
REBOOT_REASON_HARDWARE = 4,
REBOOT_REASON_SOFTWARE = 5,
REBOOT_REASON_WATCHDOG = 6,
REBOOT_REASON_CRASH = 7,
REBOOT_REASON_SLEEP_GPIO = 8,
REBOOT_REASON_SLEEP_RTC = 9,
REBOOT_REASON_SLEEP_USB = 10,
REBOOT_REASON_DEBUGGER = 11,
REBOOT_REASON_MAX = 12,
} lt_reboot_reason_t;
// RESET_REASON_SLEEP deprecated, kept for compatibility
#define RESET_REASON_SLEEP REBOOT_REASON_SLEEP_GPIO
#define REBOOT_REASON_SLEEP REBOOT_REASON_SLEEP_GPIO
/**
* @brief Debugging mode enumeration.
*/

View File

@@ -6,6 +6,8 @@ __attribute__((weak)) void lt_deep_sleep_config_gpio(uint32_t gpio_index_map, bo
__attribute__((weak)) void lt_deep_sleep_unset_gpio(uint32_t gpio_index_map);
__attribute__((weak)) void lt_deep_sleep_keep_floating_gpio(uint32_t gpio_index_map, bool on_high);
__attribute__((weak)) void lt_deep_sleep_config_timer(uint32_t sleep_duration);
__attribute__((weak)) void lt_deep_sleep_enter();

View File

@@ -19,6 +19,21 @@ void lt_deep_sleep_config_gpio(uint32_t gpio_index_map, bool on_high);
*/
void lt_deep_sleep_unset_gpio(uint32_t gpio_index_map);
/**
* @brief Configure GPIO pins to be kept floating
*
* This prevents pins from being configured as pullup/pulldown, based on
* the configured wake-up mode (low/high), upon entering deep sleep.
* This is important, as some-low power devices may be unable to ever
* overcome the internal pull strength and change the level. One example
* of such device is a magnetic door sensor that must be able to wake on
* level change in both directions.
*
* @param gpio_index_map bitMap of the pins to set/unset as floating
* @param enabled whether to set pins to floating or roll back to default mode
*/
void lt_deep_sleep_keep_floating_gpio(uint32_t gpio_index_map, bool enabled);
/**
* @brief Set a sleep timer to wake up the device
* @param sleep_duration the time in milliseconds to sleep

View File

@@ -5,17 +5,17 @@
#include <libretiny.h>
// https://stackoverflow.com/a/3437484
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
#define MAX(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a > _b ? _a : _b; \
})
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
#define MIN(a, b) \
({ \
__typeof__(a) _a = (a); \
__typeof__(b) _b = (b); \
_a < _b ? _a : _b; \
})
/**

View File

@@ -20,21 +20,23 @@ extern const struct fal_flash_dev flash0;
#define FAL_FLASH_DEV_NAME "flash0"
#define FAL_FLASH_DEV_TABLE \
{ &flash0, }
#define FAL_FLASH_DEV_TABLE \
{ \
&flash0, \
}
#define FAL_DEV_NAME_MAX 16 // no need for 24 chars (default)
// Partition table
#define FAL_PART_HAS_TABLE_CFG
#define FAL_PART_TABLE_ITEM(part_lower, part_upper) \
{ \
.magic_word = FAL_PART_MAGIC_WORD, /* magic word */ \
.name = #part_lower, /* lowercase name as string */ \
.flash_name = FAL_FLASH_DEV_NAME, /* flash device name */ \
.offset = FLASH_##part_upper##_OFFSET, /* partition offset macro as uppercase string */ \
.len = FLASH_##part_upper##_LENGTH, /* partition length macro as uppercase string */ \
#define FAL_PART_TABLE_ITEM(part_lower, part_upper) \
{ \
.magic_word = FAL_PART_MAGIC_WORD, /* magic word */ \
.name = #part_lower, /* lowercase name as string */ \
.flash_name = FAL_FLASH_DEV_NAME, /* flash device name */ \
.offset = FLASH_##part_upper##_OFFSET, /* partition offset macro as uppercase string */ \
.len = FLASH_##part_upper##_LENGTH, /* partition length macro as uppercase string */ \
},
// for fal_partition_t

View File

@@ -15,8 +15,15 @@
// set lwIP debugging options according to LT config
#if LT_DEBUG_LWIP
// enable main debugging switch
#undef LWIP_DEBUG
#define LWIP_DEBUG 1
// enable all messages
#undef LWIP_DBG_MIN_LEVEL
#define LWIP_DBG_MIN_LEVEL 0
// enable all debugging types
#undef LWIP_DBG_TYPES_ON
#define LWIP_DBG_TYPES_ON 0xF8
// make lwIP use printf() library
#include <stdio.h>
#undef LWIP_PLATFORM_DIAG
@@ -80,16 +87,16 @@
*/
#define SNTP_SERVER_DNS 1
#define SNTP_SET_SYSTEM_TIME_US(sec, us) \
do { \
struct timeval tv = {.tv_sec = sec, .tv_usec = us}; \
settimeofday(&tv, NULL); \
#define SNTP_SET_SYSTEM_TIME_US(sec, us) \
do { \
struct timeval tv = {.tv_sec = sec, .tv_usec = us}; \
settimeofday(&tv, NULL); \
} while (0);
#define SNTP_GET_SYSTEM_TIME(sec, us) \
do { \
struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; \
gettimeofday(&tv, NULL); \
(sec) = tv.tv_sec; \
(us) = tv.tv_usec; \
#define SNTP_GET_SYSTEM_TIME(sec, us) \
do { \
struct timeval tv = {.tv_sec = 0, .tv_usec = 0}; \
gettimeofday(&tv, NULL); \
(sec) = tv.tv_sec; \
(us) = tv.tv_usec; \
} while (0);

View File

@@ -21,133 +21,133 @@ extern "C" {
// declare putchar() method with custom output port
void putchar_p(char c, unsigned long port);
#define WRAP_DISABLE_DEF(name) \
extern void __wrap_##name##_disable(); \
extern void __wrap_##name##_enable(); \
extern void __wrap_##name##_set(unsigned char disabled); \
#define WRAP_DISABLE_DEF(name) \
extern void __wrap_##name##_disable(); \
extern void __wrap_##name##_enable(); \
extern void __wrap_##name##_set(unsigned char disabled); \
extern unsigned char __wrap_##name##_get();
#if !LT_UART_SILENT_ENABLED || LT_UART_SILENT_ALL
#define WRAP_DISABLE_DECL(name) \
void __wrap_##name##_disable() {} \
void __wrap_##name##_enable() {} \
void __wrap_##name##_set(unsigned char disabled) {} \
unsigned char __wrap_##name##_get() { \
return LT_UART_SILENT_ALL; \
#define WRAP_DISABLE_DECL(name) \
void __wrap_##name##_disable() {} \
void __wrap_##name##_enable() {} \
void __wrap_##name##_set(unsigned char disabled) {} \
unsigned char __wrap_##name##_get() { \
return LT_UART_SILENT_ALL; \
}
#define WRAP_DISABLE_CHECK(name) \
{ \
if (LT_UART_SILENT_ALL) \
return 0; \
#define WRAP_DISABLE_CHECK(name) \
{ \
if (LT_UART_SILENT_ALL) \
return 0; \
}
#else // LT_UART_SILENT_ENABLED && !LT_UART_SILENT_ALL
#define WRAP_DISABLE_DECL(name) \
static unsigned char __wrap_##name##_disabled = 0; \
void __wrap_##name##_disable() { \
__wrap_##name##_disabled = 1; \
} \
void __wrap_##name##_enable() { \
__wrap_##name##_disabled = 0; \
} \
void __wrap_##name##_set(unsigned char disabled) { \
__wrap_##name##_disabled = disabled; \
} \
unsigned char __wrap_##name##_get() { \
return __wrap_##name##_disabled; \
#define WRAP_DISABLE_DECL(name) \
static unsigned char __wrap_##name##_disabled = 0; \
void __wrap_##name##_disable() { \
__wrap_##name##_disabled = 1; \
} \
void __wrap_##name##_enable() { \
__wrap_##name##_disabled = 0; \
} \
void __wrap_##name##_set(unsigned char disabled) { \
__wrap_##name##_disabled = disabled; \
} \
unsigned char __wrap_##name##_get() { \
return __wrap_##name##_disabled; \
}
#define WRAP_DISABLE_CHECK(name) \
{ \
if (__wrap_##name##_disabled) \
return 0; \
#define WRAP_DISABLE_CHECK(name) \
{ \
if (__wrap_##name##_disabled) \
return 0; \
}
#endif // LT_UART_SILENT_ENABLED && !LT_UART_SILENT_ALL
#if !LT_UART_SILENT_ENABLED
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vprintf(format, va); \
va_end(va); \
return ret; \
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vprintf(format, va); \
va_end(va); \
return ret; \
}
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
return vprintf(format, arg); \
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
return vprintf(format, arg); \
}
#elif LT_UART_SILENT_ALL
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
return 0; \
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
return 0; \
}
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
return 0; \
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
return 0; \
}
#else // !LT_UART_SILENT_ENABLED || !LT_UART_SILENT_ALL
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
WRAP_DISABLE_CHECK(name); \
va_list va; \
va_start(va, format); \
const int ret = vprintf(format, va); \
va_end(va); \
return ret; \
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
WRAP_DISABLE_CHECK(name); \
va_list va; \
va_start(va, format); \
const int ret = vprintf(format, va); \
va_end(va); \
return ret; \
}
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
WRAP_DISABLE_CHECK(name); \
return vprintf(format, arg); \
#define WRAP_VPRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, va_list arg) { \
WRAP_DISABLE_CHECK(name); \
return vprintf(format, arg); \
}
#endif // !LT_UART_SILENT_ENABLED || !LT_UART_SILENT_ALL
#define WRAP_SPRINTF(name) \
int __wrap_##name(char *s, const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vsprintf(s, format, va); \
va_end(va); \
return ret; \
#define WRAP_SPRINTF(name) \
int __wrap_##name(char *s, const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vsprintf(s, format, va); \
va_end(va); \
return ret; \
}
#define WRAP_SNPRINTF(name) \
int __wrap_##name(char *s, size_t count, const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vsnprintf(s, count, format, va); \
va_end(va); \
return ret; \
#define WRAP_SNPRINTF(name) \
int __wrap_##name(char *s, size_t count, const char *format, ...) { \
va_list va; \
va_start(va, format); \
const int ret = vsnprintf(s, count, format, va); \
va_end(va); \
return ret; \
}
#define WRAP_VSPRINTF(name) \
int __wrap_##name(char *s, const char *format, va_list arg) { \
return vsprintf(s, format, arg); \
#define WRAP_VSPRINTF(name) \
int __wrap_##name(char *s, const char *format, va_list arg) { \
return vsprintf(s, format, arg); \
}
#define WRAP_VSNPRINTF(name) \
int __wrap_##name(char *s, size_t count, const char *format, va_list arg) { \
return vsnprintf(s, count, format, arg); \
#define WRAP_VSNPRINTF(name) \
int __wrap_##name(char *s, size_t count, const char *format, va_list arg) { \
return vsnprintf(s, count, format, arg); \
}
#ifdef __cplusplus

View File

@@ -25,10 +25,10 @@
#define STRINGIFY_MACRO(x) STRINGIFY(x)
#define LT_VERSION_STR STRINGIFY_MACRO(LT_VERSION)
#define LT_BOARD_STR STRINGIFY_MACRO(LT_BOARD)
#define GCC_VERSION_STR \
#define GCC_VERSION_STR \
STRINGIFY_MACRO(__GNUC__) "." STRINGIFY_MACRO(__GNUC_MINOR__) "." STRINGIFY_MACRO(__GNUC_PATCHLEVEL__)
#define LT_BANNER_STR \
"LibreTiny v" LT_VERSION_STR " on " LT_BOARD_STR ", compiled at " __DATE__ " " __TIME__ ", GCC " GCC_VERSION_STR \
#define LT_BANNER_STR \
"LibreTiny v" LT_VERSION_STR " on " LT_BOARD_STR ", compiled at " __DATE__ " " __TIME__ ", GCC " GCC_VERSION_STR \
" (-O" STRINGIFY_MACRO(__OPTIMIZE_LEVEL__) ")"
// Functional macros

View File

@@ -77,6 +77,10 @@
#define LT_UART_DEFAULT_SERIAL LT_UART_DEFAULT_PORT
#endif
#ifndef LT_SERIAL_BUFFER_SIZE
#define LT_SERIAL_BUFFER_SIZE 256
#endif
// Misc options
#ifndef LT_USE_TIME
#define LT_USE_TIME 0

View File

@@ -10,21 +10,21 @@ extern "C" {
#if LT_LOGGER_CALLER
#define LT_LOG(level, caller, line, ...) lt_log(level, caller, line, __VA_ARGS__)
#define LT_LOGM(level, module, caller, line, ...) \
do { \
if (LT_DEBUG_##module) { \
lt_log(level, caller, line, #module ": " __VA_ARGS__); \
} \
#define LT_LOGM(level, module, caller, line, ...) \
do { \
if (LT_DEBUG_##module) { \
lt_log(level, caller, line, #module ": " __VA_ARGS__); \
} \
} while (0)
void lt_log(const uint8_t level, const char *caller, const unsigned short line, const char *format, ...)
__attribute__((format(printf, 4, 5)));
#else
#define LT_LOG(level, caller, line, ...) lt_log(level, __VA_ARGS__)
#define LT_LOGM(level, module, caller, line, ...) \
do { \
if (LT_DEBUG_##module) { \
lt_log(level, #module ": " __VA_ARGS__); \
} \
#define LT_LOGM(level, module, caller, line, ...) \
do { \
if (LT_DEBUG_##module) { \
lt_log(level, #module ": " __VA_ARGS__); \
} \
} while (0)
void lt_log(const uint8_t level, const char *format, ...) __attribute__((format(printf, 2, 3)));
#endif
@@ -100,73 +100,73 @@ void lt_log_disable();
#endif
// ESP32 compat
#define log_printf(...) LT_I(__VA_ARGS__)
#define log_v(...) LT_V(__VA_ARGS__)
#define log_d(...) LT_D(__VA_ARGS__)
#define log_i(...) LT_I(__VA_ARGS__)
#define log_w(...) LT_W(__VA_ARGS__)
#define log_e(...) LT_E(__VA_ARGS__)
#define log_n(...) LT_E(__VA_ARGS__)
#define isr_log_v(...) LT_V(__VA_ARGS__)
#define isr_log_d(...) LT_D(__VA_ARGS__)
#define isr_log_i(...) LT_I(__VA_ARGS__)
#define isr_log_w(...) LT_W(__VA_ARGS__)
#define isr_log_e(...) LT_E(__VA_ARGS__)
#define isr_log_n(...) LT_E(__VA_ARGS__)
#define ESP_LOGV(...) LT_V(__VA_ARGS__)
#define ESP_LOGD(...) LT_D(__VA_ARGS__)
#define ESP_LOGI(...) LT_I(__VA_ARGS__)
#define ESP_LOGW(...) LT_W(__VA_ARGS__)
#define ESP_LOGE(...) LT_E(__VA_ARGS__)
#define ESP_EARLY_LOGV(...) LT_V(__VA_ARGS__)
#define ESP_EARLY_LOGD(...) LT_D(__VA_ARGS__)
#define ESP_EARLY_LOGI(...) LT_I(__VA_ARGS__)
#define ESP_EARLY_LOGW(...) LT_W(__VA_ARGS__)
#define ESP_EARLY_LOGE(...) LT_E(__VA_ARGS__)
#define ets_printf(...) LT_I(__VA_ARGS__)
#define ETS_PRINTF(...) LT_I(__VA_ARGS__)
#define log_printf(...) LT_I(__VA_ARGS__)
#define log_v(...) LT_V(__VA_ARGS__)
#define log_d(...) LT_D(__VA_ARGS__)
#define log_i(...) LT_I(__VA_ARGS__)
#define log_w(...) LT_W(__VA_ARGS__)
#define log_e(...) LT_E(__VA_ARGS__)
#define log_n(...) LT_E(__VA_ARGS__)
#define isr_log_v(...) LT_V(__VA_ARGS__)
#define isr_log_d(...) LT_D(__VA_ARGS__)
#define isr_log_i(...) LT_I(__VA_ARGS__)
#define isr_log_w(...) LT_W(__VA_ARGS__)
#define isr_log_e(...) LT_E(__VA_ARGS__)
#define isr_log_n(...) LT_E(__VA_ARGS__)
#define ESP_LOGV(tag, ...) LT_V(__VA_ARGS__)
#define ESP_LOGD(tag, ...) LT_D(__VA_ARGS__)
#define ESP_LOGI(tag, ...) LT_I(__VA_ARGS__)
#define ESP_LOGW(tag, ...) LT_W(__VA_ARGS__)
#define ESP_LOGE(tag, ...) LT_E(__VA_ARGS__)
#define ESP_EARLY_LOGV(tag, ...) LT_V(__VA_ARGS__)
#define ESP_EARLY_LOGD(tag, ...) LT_D(__VA_ARGS__)
#define ESP_EARLY_LOGI(tag, ...) LT_I(__VA_ARGS__)
#define ESP_EARLY_LOGW(tag, ...) LT_W(__VA_ARGS__)
#define ESP_EARLY_LOGE(tag, ...) LT_E(__VA_ARGS__)
#define ets_printf(...) LT_I(__VA_ARGS__)
#define ETS_PRINTF(...) LT_I(__VA_ARGS__)
#define LT_RET(ret) \
LT_E("ret=%d", ret); \
#define LT_RET(ret) \
LT_E("ret=%d", ret); \
return ret;
#define LT_RET_NZ(ret) \
if (ret) { \
LT_E("ret=%d", ret); \
return ret; \
#define LT_RET_NZ(ret) \
if (ret) { \
LT_E("ret=%d", ret); \
return ret; \
}
#define LT_RET_LZ(ret) \
if (ret < 0) { \
LT_E("ret=%d", ret); \
return ret; \
#define LT_RET_LZ(ret) \
if (ret < 0) { \
LT_E("ret=%d", ret); \
return ret; \
}
#define LT_RET_LEZ(ret) \
if (ret <= 0) { \
LT_E("ret=%d", ret); \
return ret; \
#define LT_RET_LEZ(ret) \
if (ret <= 0) { \
LT_E("ret=%d", ret); \
return ret; \
}
#define LT_ERRNO_NZ(ret) \
if (ret) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
#define LT_ERRNO_NZ(ret) \
if (ret) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
}
#define LT_ERRNO_LZ(ret) \
if (ret < 0) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
#define LT_ERRNO_LZ(ret) \
if (ret < 0) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
}
#define LT_ERRNO_LEZ(ret) \
if (ret <= 0) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
#define LT_ERRNO_LEZ(ret) \
if (ret <= 0) { \
LT_E("errno=%d, ret=%d", errno, ret); \
return ret; \
}
#if LT_LOG_ERRNO
#define LT_ERRNO() \
if (errno) { \
LT_E("errno=%d", errno); \
errno = 0; \
#define LT_ERRNO() \
if (errno) { \
LT_E("errno=%d", errno); \
errno = 0; \
}
#else
#define LT_ERRNO()

View File

@@ -17,6 +17,7 @@ typedef enum {
F_BK7231N = 0x7B3EF230, // Beken 7231N
F_BK7251 = 0x6A82CC42, // Beken 7251/7252
F_BL60X = 0xDE1270B7, // Boufallo 602
F_LN882H = 0xA38090A8, // Lightning LN882H
} lt_cpu_family_t;
typedef enum {
@@ -44,4 +45,8 @@ typedef enum {
BL2028N = BK7231N,
BK7231S = BK7231T,
BK7231U = BK7231T,
// Lightning LN882x
LN882HF = CPU_MODEL(F_LN882H, 0x00), // TODO / QFN24
LN882HK = CPU_MODEL(F_LN882H, 0x00), // TODO / QFN32
LN882HC = CPU_MODEL(F_LN882H, 0x00), // TODO / QFN40
} lt_cpu_model_t;

View File

@@ -0,0 +1,99 @@
/* Copyright (c) Etienne Le Cousin 2024-02-10. */
#include "SerialPrivate.h"
extern Serial_t *serial_handles[SER_PORT_NUM];
#if LT_HW_UART0
SerialClass Serial0(0, PIN_SERIAL0_RX, PIN_SERIAL0_TX);
static void callback_uart0(void) {
SerialData *data = (SerialData *)Serial0.data;
char ch;
while (serial_read(serial_handles[0], &ch, 1)) {
data->buf.store_char(ch);
}
}
#else
#define callback_uart0 NULL
#endif
#if LT_HW_UART1
SerialClass Serial1(1, PIN_SERIAL1_RX, PIN_SERIAL1_TX);
static void callback_uart1(void) {
SerialData *data = (SerialData *)Serial1.data;
char ch;
while (serial_read(serial_handles[1], &ch, 1)) {
data->buf.store_char(ch);
}
}
#else
#define callback_uart1 NULL
#endif
#if LT_HW_UART2
SerialClass Serial2(2, PIN_SERIAL2_RX, PIN_SERIAL2_TX);
static void callback_uart2(void) {
SerialData *data = (SerialData *)Serial2.data;
char ch;
while (serial_read(serial_handles[2], &ch, 1)) {
data->buf.store_char(ch);
}
}
#else
#define callback_uart2 NULL
#endif
// clang-format off
static const serial_rx_callbcak serial_rx_callbacks[SER_PORT_NUM] = {
callback_uart0,
callback_uart1,
callback_uart2
};
// clang-format on
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;
serial_init(serial_handles[port], (serial_port_id_t)port, baudrate, serial_rx_callbacks[port]);
this->baudrate = baudrate;
this->config = config;
}
void SerialClass::end() {
if (!this->data)
return;
serial_deinit(serial_handles[port]);
delete (SerialData *)this->data;
delete this->buf;
this->data = NULL;
this->buf = NULL;
this->baudrate = 0;
}
void SerialClass::flush() {
if (!this->data)
return;
serial_flush(serial_handles[port]);
}
size_t SerialClass::write(uint8_t c) {
if (!this->data)
return 0;
serial_putchar(serial_handles[port], c);
return 1;
}

View File

@@ -0,0 +1,14 @@
/* Copyright (c) Etienne Le Cousin 2024-02-10. */
#pragma once
#include <Arduino.h>
#include <sdk_private.h>
typedef struct {
SerialRingBuffer buf;
void (*callback)(void);
} SerialData;
#define DATA ((SerialData *)this->data)
#define BUF (DATA->buf)

View File

@@ -0,0 +1,59 @@
/* Copyright (c) Etienne Le Cousin 2024-02-18. */
#include "WiFiPrivate.h"
WiFiClass::WiFiClass() {
data = (WiFiData *)calloc(1, sizeof(WiFiData));
DATA->scanSem = xSemaphoreCreateBinary();
}
WiFiClass::~WiFiClass() {
vSemaphoreDelete(DATA->scanSem);
free(data);
data = NULL;
}
WiFiAuthMode securityTypeToAuthMode(uint8_t type) {
switch (type) {
case LN_WIFI_AUTH_OPEN:
return WIFI_AUTH_OPEN;
case LN_WIFI_AUTH_WEP:
return WIFI_AUTH_WEP;
case LN_WIFI_AUTH_WPA_PSK:
return WIFI_AUTH_WPA_PSK;
case LN_WIFI_AUTH_WPA2_PSK:
return WIFI_AUTH_WPA2_PSK;
case LN_WIFI_AUTH_WPA_WPA2_PSK:
return WIFI_AUTH_WPA_WPA2_PSK;
case LN_WIFI_AUTH_WPA2_ENTERPRISE:
return WIFI_AUTH_WPA2_ENTERPRISE;
case LN_WIFI_AUTH_WPA3_SAE:
return WIFI_AUTH_WPA3_PSK;
case LN_WIFI_AUTH_WPA2_PSK_WPA3_SAE:
return WIFI_AUTH_WPA2_WPA3_PSK;
}
return WIFI_AUTH_INVALID;
}
uint8_t authModeToSecurityType(WiFiAuthMode auth) {
switch (auth) {
case WIFI_AUTH_OPEN:
return LN_WIFI_AUTH_OPEN;
case WIFI_AUTH_WEP:
return LN_WIFI_AUTH_WEP;
case WIFI_AUTH_WPA_PSK:
return LN_WIFI_AUTH_WPA_PSK;
case WIFI_AUTH_WPA2_PSK:
return LN_WIFI_AUTH_WPA2_PSK;
case WIFI_AUTH_WPA_WPA2_PSK:
return LN_WIFI_AUTH_WPA_WPA2_PSK;
case WIFI_AUTH_WPA2_ENTERPRISE:
return LN_WIFI_AUTH_WPA2_ENTERPRISE;
case WIFI_AUTH_WPA3_PSK:
return LN_WIFI_AUTH_WPA3_SAE;
case WIFI_AUTH_WPA2_WPA3_PSK:
return LN_WIFI_AUTH_WPA2_PSK_WPA3_SAE;
}
return WIFI_AUTH_INVALID;
}

View File

@@ -0,0 +1,134 @@
/* Copyright (c) Etienne Le Cousin 2024-02-18. */
#include "WiFiPrivate.h"
static uint8_t psk_value[40] = {0x0};
static uint8_t mac_addr[6] = {0x00, 0x50, 0xC2, 0x7F, 0xBC, 0x01};
bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bool ssidHidden, int maxClients) {
if (!enableAP(true))
return false;
if (!validate(ssid, passphrase))
return false;
LT_HEAP_I();
WiFiNetworkInfo &info = DATA->ap;
if (info.ssid != ssid)
// free network info, if not called from restoreAPConfig()
resetNetworkInfo(info);
if (info.ssid != ssid)
info.ssid = strdup(ssid);
if (info.password != passphrase)
info.password = strdup(passphrase);
info.ssidHidden = ssidHidden;
info.bssid = softAPmacAddress(mac_addr);
info.channel = channel;
info.auth = passphrase ? LN_WIFI_AUTH_WPA2_PSK : LN_WIFI_AUTH_OPEN;
LT_IM(WIFI, "Creating SoftAP %s", ssid);
// clang-format off
wifi_softap_cfg_t ap_cfg = {
.ssid = info.ssid,
.pwd = info.password,
.bssid = info.bssid,
.ext_cfg = {
.channel = (uint8_t)info.channel,
.authmode = (ln_wifi_auth_mode_t)info.auth,
.ssid_hidden = info.ssidHidden,
.beacon_interval = 100,
.psk_value = NULL,
}
};
// clang-format on
if ((strlen(ap_cfg.pwd) != 0) && (ap_cfg.ext_cfg.authmode != LN_WIFI_AUTH_OPEN) &&
(ap_cfg.ext_cfg.authmode != LN_WIFI_AUTH_WEP)) {
memset(psk_value, 0, sizeof(psk_value));
if (0 == ln_psk_calc(ap_cfg.ssid, ap_cfg.pwd, psk_value, sizeof(psk_value))) {
ap_cfg.ext_cfg.psk_value = psk_value;
hexdump(psk_value, sizeof(psk_value));
}
}
// wifi start
__wrap_ln_printf_disable();
int ret = wifi_softap_start(&ap_cfg);
__wrap_ln_printf_enable();
if (ret != 0) {
LT_EM(WIFI, "SoftAP failed; ret=%d", ret);
return false;
}
return true;
}
bool WiFiClass::softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet) {
if (!enableAP(true))
return false;
WiFiNetworkInfo &info = DATA->ap;
// dhcp server config
server_config_t server_config;
server_config.server.addr = localIP;
server_config.port = 67;
server_config.lease = 2880;
server_config.renew = 2880;
server_config.ip_start.addr = IPAddress(localIP[0], localIP[1], localIP[2], 100);
server_config.ip_end.addr = IPAddress(localIP[0], localIP[1], localIP[2], 150);
server_config.client_max = 3;
dhcpd_curr_config_set(&server_config);
// net device config
tcpip_ip_info_t ip_info;
ip_info.ip.addr = info.localIP = localIP;
ip_info.netmask.addr = info.subnet = subnet;
ip_info.gw.addr = info.gateway = gateway;
netdev_set_ip_info(NETIF_IDX_AP, &ip_info);
netdev_set_active(NETIF_IDX_AP);
return true;
}
bool WiFiClass::softAPdisconnect(bool wifiOff) {
return enableAP(false);
}
uint8_t WiFiClass::softAPgetStationNum() {
return 0;
}
IPAddress WiFiClass::softAPIP() {
return netif_ip_addr4(netdev_get_netif(NETIF_IDX_AP))->addr;
}
IPAddress WiFiClass::softAPSubnetMask() {
return netif_ip_netmask4(netdev_get_netif(NETIF_IDX_AP))->addr;
}
const char *WiFiClass::softAPgetHostname() {
return netif_get_hostname(netdev_get_netif(NETIF_IDX_AP));
}
bool WiFiClass::softAPsetHostname(const char *hostname) {
netif_set_hostname(netdev_get_netif(NETIF_IDX_AP), (char *)hostname);
return true;
}
uint8_t *WiFiClass::softAPmacAddress(uint8_t *mac) {
memcpy(mac, netdev_get_netif(NETIF_IDX_AP)->hwaddr, MAC_ADDRESS_LEN);
return mac;
}
String WiFiClass::softAPmacAddress(void) {
uint8_t mac[MAC_ADDRESS_LEN];
softAPmacAddress(mac);
return macToString(mac);
}
const String WiFiClass::softAPSSID(void) {
WiFiNetworkInfo &info = DATA->ap;
return (char *)info.ssid;
}

View File

@@ -0,0 +1,122 @@
/* Copyright (c) Etienne Le Cousin 2024-03-10. */
#include "WiFiPrivate.h"
void wifiEventSendArduino(EventId event) {
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
pWiFi->postEvent(event, eventInfo);
}
static void wifiEventStaStartup(void *arg) {
wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_START);
}
static void wifiEventStaConnected(void *arg) {
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
String ssid = pWiFi->SSID();
eventInfo.wifi_sta_connected.ssid_len = ssid.length();
eventInfo.wifi_sta_connected.channel = pWiFi->channel();
eventInfo.wifi_sta_connected.authmode = pWiFi->getEncryption();
memcpy(eventInfo.wifi_sta_connected.ssid, ssid.c_str(), eventInfo.wifi_sta_connected.ssid_len + 1);
memcpy(eventInfo.wifi_sta_connected.bssid, pWiFi->BSSID(), 6);
pWiFi->postEvent(ARDUINO_EVENT_WIFI_STA_CONNECTED, eventInfo);
}
static void wifiEventStaDisconnected(void *arg) {
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
eventInfo.wifi_sta_disconnected.ssid_len = 0;
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_ASSOC_LEAVE;
pWiFi->postEvent(ARDUINO_EVENT_WIFI_STA_DISCONNECTED, eventInfo);
}
static void wifiEventStaConnectFailed(void *arg) {
wifi_sta_connect_failed_reason_t reason = *(wifi_sta_connect_failed_reason_t *)arg;
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
eventInfo.wifi_sta_disconnected.ssid_len = 0;
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_UNSPECIFIED;
switch (reason) {
case WIFI_STA_CONN_WRONG_PWD:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_AUTH_FAIL;
break;
case WIFI_STA_CONN_TARGET_AP_NOT_FOUND:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_NO_AP_FOUND;
break;
case WIFI_STA_CONN_TIMEOUT:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_BEACON_TIMEOUT;
break;
case WIFI_STA_CONN_REFUSED:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_CONNECTION_FAIL;
break;
}
pWiFi->postEvent(ARDUINO_EVENT_WIFI_STA_DISCONNECTED, eventInfo);
}
static void wifiEventSoftAPStartup(void *arg) {
netdev_set_state(NETIF_IDX_AP, NETDEV_UP);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_START);
}
static void wifiEventSoftAPAssociated(void *arg) {
const uint8_t *mac_addr = (const uint8_t *)arg;
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
memcpy(eventInfo.wifi_ap_staconnected.mac, mac_addr, 6);
pWiFi->postEvent(ARDUINO_EVENT_WIFI_AP_STACONNECTED, eventInfo);
}
static void wifiEventSoftAPDisassociated(void *arg) {
const uint8_t *mac_addr = (const uint8_t *)arg;
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi)
return; // failsafe
memcpy(eventInfo.wifi_ap_staconnected.mac, mac_addr, 6);
pWiFi->postEvent(ARDUINO_EVENT_WIFI_AP_STADISCONNECTED, eventInfo);
}
static void wifiEventIpReceived(struct netif *nif) {
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
if (!pWiFi || !nif)
return; // failsafe
eventInfo.got_ip.if_index = 0;
eventInfo.got_ip.ip_changed = true;
eventInfo.got_ip.ip_info.ip.addr = nif->ip_addr.addr;
eventInfo.got_ip.ip_info.gw.addr = nif->gw.addr;
eventInfo.got_ip.ip_info.netmask.addr = nif->netmask.addr;
pWiFi->postEvent(ARDUINO_EVENT_WIFI_STA_GOT_IP, eventInfo);
}
void registerWifiHandlers() {
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_STARTUP, &wifiEventStaStartup);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_CONNECTED, &wifiEventStaConnected);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_DISCONNECTED, &wifiEventStaDisconnected);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_CONNECT_FAILED, &wifiEventStaConnectFailed);
netdev_get_ip_cb_set(&wifiEventIpReceived);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_SOFTAP_STARTUP, &wifiEventSoftAPStartup);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_SOFTAP_ASSOCIATED, &wifiEventSoftAPAssociated);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_SOFTAP_DISASSOCIATED, &wifiEventSoftAPDisassociated);
}

View File

@@ -0,0 +1,144 @@
/* Copyright (c) Etienne Le Cousin 2024-03-10. */
#include "WiFiPrivate.h"
static uint8_t psk_value[40] = {0x0};
bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
__wrap_ln_printf_disable();
if (!DATA->initialized) {
// rf preprocess,img cal
wifi_rf_calibration();
// Init wifi stack.
wifi_init();
// Init lwip stack.
LT_IM(WIFI, "Initializing LwIP");
lwip_tcpip_init();
// Init wifi manager
wifi_manager_init();
// Register event handlers
registerWifiHandlers();
DATA->mode = WIFI_MODE_NULL;
DATA->initialized = true;
}
LT_HEAP_I();
WiFiMode currentMode = DATA->mode;
WiFiNetworkInfo &staInfo = DATA->sta;
WiFiNetworkInfo &apInfo = DATA->ap;
if (mode == WIFI_MODE_APSTA) {
LT_EM(WIFI, "AP+STA mode not supported!");
goto error;
}
if (sta == WLMODE_ENABLE) {
LT_DM(WIFI, "Enabling STA");
// 1. sta mac get
uint8_t mac_addr[6];
setMacAddress(macAddress(mac_addr));
// 2. net device(lwip)
netdev_set_active(NETIF_IDX_STA);
// 3. wifi start
wifi_sta_start(mac_addr, WIFI_NO_POWERSAVE);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_START);
} else if (sta == WLMODE_DISABLE) {
LT_DM(WIFI, "Disabling STA");
wifi_sta_disconnect();
netdev_set_state(NETIF_IDX_STA, NETDEV_DOWN);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_STOP);
}
LT_HEAP_I();
if (ap == WLMODE_ENABLE) {
LT_DM(WIFI, "Enabling AP");
// 1. ap mac get
uint8_t mac_addr[6];
sysparam_softap_mac_get(mac_addr);
netdev_set_mac_addr(NETIF_IDX_AP, mac_addr);
// 2. net device(lwip)
netdev_set_active(NETIF_IDX_AP);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_START);
} else if (ap == WLMODE_DISABLE) {
LT_DM(WIFI, "Disabling AP");
wifi_softap_deauth_all();
netdev_set_state(NETIF_IDX_AP, NETDEV_DOWN);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_STOP);
}
DATA->mode = mode;
LT_HEAP_I();
__wrap_ln_printf_enable();
return true;
error:
__wrap_ln_printf_enable();
return false;
}
WiFiMode WiFiClass::getMode() {
if (!DATA->initialized)
return WIFI_MODE_NULL;
// return fake value because the chip doesn't report the mode before it is started
return DATA->mode;
/*switch (wifi_current_mode_get()) {
case LN_WIFI_MODE_STATION:
return WIFI_MODE_STA;
case LN_WIFI_MODE_AP:
return WIFI_MODE_AP;
case LN_WIFI_MODE_AP_STATION:
return WIFI_MODE_APSTA;
}
return WIFI_MODE_NULL;*/
}
WiFiStatus WiFiClass::status() {
wifi_sta_status_t status = WIFI_STA_STATUS_STARTUP;
wifi_get_sta_status(&status);
if (status == WIFI_STA_STATUS_CONNECTED) {
return WL_CONNECTED;
} else {
return WL_DISCONNECTED;
}
}
bool WiFiClass::setSleep(bool enable) {
LT_DM(WIFI, "WiFi sleep mode %u", enable);
if (enable) {
if (wifi_sta_set_powersave(WIFI_MAX_POWERSAVE))
return false;
} else {
if (wifi_sta_set_powersave(WIFI_NO_POWERSAVE))
return false;
}
DATA->sleep = enable;
return true;
}
bool WiFiClass::getSleep() {
return DATA->sleep;
}
IPAddress WiFiClass::hostByName(const char *hostname) {
ip_addr_t ip;
int ret = netconn_gethostbyname(hostname, &ip);
if (ret == ERR_OK) {
return ip.addr;
}
return IPAddress();
}

View File

@@ -0,0 +1,47 @@
/* Copyright (c) Etienne Le Cousin 2024-02-10. */
#pragma once
#include <WiFi.h>
#include <sdk_private.h>
extern "C" {
// copy defines from PIO builder (for IDE to understand)
#define LWIP_TIMEVAL_PRIVATE 0
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_SO_RCVBUF 1
#include <lwip/api.h>
#include <lwip/dns.h>
#include <lwip/ip_addr.h>
#include <lwip/netif.h>
#include <lwip/netifapi.h>
#include <netif/ethernetif.h>
#include <FreeRTOS.h>
#include <semphr.h>
} // extern "C"
// WiFi.cpp
extern WiFiAuthMode securityTypeToAuthMode(uint8_t type);
uint8_t authModeToSecurityType(WiFiAuthMode auth);
// WiFiEvents.cpp
extern void wifiEventSendArduino(EventId event);
extern void registerWifiHandlers();
typedef struct {
bool initialized;
bool sleep;
WiFiMode mode;
SemaphoreHandle_t scanSem;
WiFiNetworkInfo sta;
WiFiNetworkInfo ap;
} WiFiData;
#define DATA ((WiFiData *)data)
#define pDATA ((WiFiData *)pWiFi->data)
#define cDATA ((WiFiData *)cls->data)
#define IP_FMT "%u.%u.%u.%u"

View File

@@ -0,0 +1,213 @@
/* Copyright (c) Etienne Le Cousin 2024-03-10. */
#include "WiFiPrivate.h"
WiFiStatus WiFiClass::begin(
const char *ssid,
const char *passphrase,
int32_t channel,
const uint8_t *bssid,
bool connect
) {
if (!enableSTA(true))
return WL_CONNECT_FAILED;
if (!validate(ssid, passphrase))
return WL_CONNECT_FAILED;
LT_HEAP_I();
WiFiNetworkInfo &info = DATA->sta;
if (info.ssid != ssid)
// free network info, if not called from restoreSTAConfig()
resetNetworkInfo(info);
if (info.ssid != ssid)
info.ssid = strdup(ssid);
info.channel = channel;
info.auth = LN_WIFI_AUTH_OPEN;
if (passphrase) {
if (info.password != passphrase)
info.password = strdup(passphrase);
info.auth = LN_WIFI_AUTH_WPA_WPA2_PSK;
}
if (reconnect(bssid))
return WL_CONNECTED;
else
return WL_CONNECT_FAILED;
}
bool WiFiClass::config(IPAddress localIP, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) {
if (!enableSTA(true))
return false;
WiFiNetworkInfo &info = DATA->sta;
struct netif *ifs = netdev_get_netif(NETIF_IDX_STA);
ip4_addr_t d1, d2;
d1.addr = info.dns1 = dns1;
d2.addr = info.dns2 = dns2;
if (d1.addr)
dns_setserver(0, &d1);
if (d2.addr)
dns_setserver(0, &d2);
if (!localIP[0]) {
info.localIP = 0;
netifapi_dhcp_start(ifs);
return true;
}
ip4_addr_t ipaddr, netmask, gw;
ipaddr.addr = info.localIP = localIP;
netmask.addr = info.subnet = subnet;
gw.addr = info.gateway = gateway;
netif_set_addr(ifs, &ipaddr, &netmask, &gw);
netifapi_dhcp_release_and_stop(ifs);
return true;
}
bool WiFiClass::reconnect(const uint8_t *bssid) {
WiFiNetworkInfo &info = DATA->sta;
LT_IM(WIFI, "Connecting to %s (bssid=%p)", info.ssid, bssid);
if (bssid != info.bssid) {
if (!info.bssid)
info.bssid = (uint8_t *)malloc(BSSID_LEN);
memcpy(info.bssid, bssid, BSSID_LEN);
}
uint8_t psk_value[40] = {0x0};
wifi_sta_connect_t connect = {
.ssid = info.ssid,
.pwd = info.password,
.bssid = NULL, // info.bssid,
.psk_value = NULL,
};
wifi_scan_cfg_t scan_cfg = {
.channel = (uint8_t)info.channel,
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
.scan_time = 5,
};
if (0 == ln_psk_calc(connect.ssid, connect.pwd, psk_value, sizeof(psk_value)))
connect.psk_value = psk_value;
LT_DM(WIFI, "Starting WiFi...");
__wrap_ln_printf_disable();
int ret = wifi_sta_connect(&connect, &scan_cfg);
// int ret = wifi_sta_connect_v2(&connect, &scan_cfg, 10);
__wrap_ln_printf_enable();
LT_DM(WIFI, "Start OK (%d)", ret);
return true;
}
bool WiFiClass::disconnect(bool wifiOff) {
free(DATA->sta.ssid);
DATA->sta.ssid = NULL;
int ret = wifi_sta_disconnect();
if (wifiOff)
enableSTA(false);
return ret == 0;
}
bool WiFiClass::setAutoReconnect(bool autoReconnect) {
return false;
}
bool WiFiClass::getAutoReconnect() {
return false;
}
IPAddress WiFiClass::localIP() {
tcpip_ip_info_t ip_info;
netdev_get_ip_info(NETIF_IDX_STA, &ip_info);
return IPAddress(ip_info.ip.addr);
}
IPAddress WiFiClass::subnetMask() {
tcpip_ip_info_t ip_info;
netdev_get_ip_info(NETIF_IDX_STA, &ip_info);
return IPAddress(ip_info.netmask.addr);
}
IPAddress WiFiClass::gatewayIP() {
tcpip_ip_info_t ip_info;
netdev_get_ip_info(NETIF_IDX_STA, &ip_info);
return IPAddress(ip_info.gw.addr);
}
IPAddress WiFiClass::dnsIP(uint8_t dns_no) {
return dns_getserver(dns_no)->addr;
}
IPAddress WiFiClass::broadcastIP() {
return calculateBroadcast(localIP(), subnetMask());
}
const char *WiFiClass::getHostname() {
struct netif *ifs = netdev_get_netif(NETIF_IDX_STA);
return netif_get_hostname(ifs);
}
bool WiFiClass::setHostname(const char *hostname) {
struct netif *ifs = netdev_get_netif(NETIF_IDX_STA);
netif_set_hostname(ifs, (char *)hostname);
return true;
}
uint8_t *WiFiClass::macAddress(uint8_t *mac) {
if (SYSPARAM_ERR_NONE == sysparam_sta_mac_get(mac))
return mac;
else
LT_WM(WIFI, "sysparam sta mac get failed!");
lt_get_device_mac(mac);
return mac;
}
bool WiFiClass::setMacAddress(const uint8_t *mac) {
sysparam_sta_mac_update(mac);
return netdev_set_mac_addr(NETIF_IDX_STA, (uint8_t *)mac) == 0;
}
const String WiFiClass::SSID() {
const char *ssid = "";
const uint8_t *bssid = NULL;
wifi_get_sta_conn_info(&ssid, &bssid);
return ssid;
}
const String WiFiClass::psk() {
if (!isConnected() || !DATA->sta.password)
return "";
return DATA->sta.password;
}
uint8_t *WiFiClass::BSSID() {
const char *ssid = NULL;
const uint8_t *bssid = NULL;
wifi_get_sta_conn_info(&ssid, &bssid);
return (uint8_t *)bssid;
}
int32_t WiFiClass::channel() {
uint8_t channel = 0;
wifi_get_channel(&channel);
return (int32_t)channel;
}
int8_t WiFiClass::RSSI() {
int8_t rssi = 0;
wifi_sta_get_rssi(&rssi);
return rssi;
}
WiFiAuthMode WiFiClass::getEncryption() {
ln_wifi_auth_mode_t mode;
wifi_sta_get_connected_ap_security(&mode);
return securityTypeToAuthMode(mode);
}

View File

@@ -0,0 +1,114 @@
/* Copyright (c) Etienne Le Cousin 2024-03-13. */
#include "WiFiPrivate.h"
static void scanHandler(void *arg) {
WiFiClass *cls = (WiFiClass *)pWiFi;
WiFiScanData *scan = cls->scan;
LT_HEAP_I();
ln_list_t *list;
uint8_t n = 0, node_count = 0;
ap_info_node_t *pnode;
wifi_manager_ap_list_update_enable(LN_FALSE);
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_SCAN_COMPLETE, NULL);
// 1.get ap info list.
if (wifi_manager_get_ap_list(&list, &node_count)) {
LT_EM(WIFI, "Failed to get scan result");
goto end;
}
LT_IM(WIFI, "Found %d APs", node_count);
cls->scanAlloc(node_count);
if (!scan->ap) {
LT_WM(WIFI, "scan->ap alloc failed");
goto end;
}
// 2.get all ap info in the list.
LN_LIST_FOR_EACH_ENTRY(pnode, ap_info_node_t, list, list) {
uint8_t *mac = (uint8_t *)pnode->info.bssid;
ap_info_t *ap_info = &pnode->info;
scan->ap[n].ssid = strdup(ap_info->ssid);
scan->ap[n].auth = securityTypeToAuthMode(ap_info->authmode);
scan->ap[n].rssi = ap_info->rssi;
scan->ap[n].channel = ap_info->channel;
memcpy(scan->ap[n].bssid.addr, mac, 6);
n++;
}
end:
scan->timeout = 0;
if (scan->running) {
// running == false means it was discarded (timeout)
scan->running = false;
xSemaphoreGive(cDATA->scanSem);
// Send event scan finished
EventInfo eventInfo;
memset(&eventInfo, 0, sizeof(EventInfo));
eventInfo.wifi_scan_done.status = 0;
eventInfo.wifi_scan_done.number = scan->count;
pWiFi->postEvent(ARDUINO_EVENT_WIFI_SCAN_DONE, eventInfo);
}
// wifi_manager_ap_list_update_enable(LN_TRUE);
// wifi_sta_disconnect();
LT_HEAP_I();
return;
}
int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint32_t maxMsPerChannel, uint8_t channel) {
if (scan && scan->running) {
if (scan->timeout && millis() > scan->timeout) {
LT_WM(WIFI, "Scan timeout, discarding");
scan->running = false;
} else {
return WIFI_SCAN_RUNNING;
}
}
enableSTA(true);
scanDelete();
scanInit();
LT_IM(WIFI, "Starting WiFi scan");
__wrap_ln_printf_disable();
wifi_manager_reg_event_callback(WIFI_MGR_EVENT_STA_SCAN_COMPLETE, &scanHandler);
wifi_manager_ap_list_update_enable(LN_TRUE);
wifi_manager_cleanup_scan_results();
wifi_scan_cfg_t scan_cfg = {
.channel = 0,
.scan_type = WIFI_SCAN_TYPE_ACTIVE,
.scan_time = 5,
};
wifi_sta_scan(&scan_cfg);
LT_HEAP_I();
scan->running = true;
scan->timeout = millis() + maxMsPerChannel * 20 + 1000;
int16_t ret = WIFI_SCAN_RUNNING;
if (!async) {
LT_IM(WIFI, "Waiting for results");
xSemaphoreTake(DATA->scanSem, 1); // reset the semaphore quickly
xSemaphoreTake(DATA->scanSem, pdMS_TO_TICKS(maxMsPerChannel * 20));
if (scan->running) {
scanDelete();
ret = WIFI_SCAN_FAILED;
goto exit;
}
ret = scan->count;
goto exit;
}
exit:
__wrap_ln_printf_enable();
return ret;
}

View File

@@ -0,0 +1,295 @@
/* Copyright (c) Etienne Le Cousin 2025-01-19. */
#include "wiring_private.h"
#include <sdk_private.h>
#define I2C_PRIV i2c_init_t_def
#include "Wire.h"
// Functions from I2C demo of SDK
static uint8_t hal_i2c_master_7bit_write(uint32_t i2c_x_base, uint8_t dev_addr, const uint8_t *buf, uint16_t buf_len);
static uint8_t hal_i2c_master_7bit_read(uint32_t i2c_x_base, uint8_t dev_addr, uint8_t *buf, uint16_t buf_len);
#ifdef PIN_WIRE0_SDA
// Wire object associated to I2C0 interface.
TwoWire Wire(PIN_WIRE0_SDA, PIN_WIRE0_SCL);
#endif
TwoWire::TwoWire(int8_t sda, int8_t scl) {
_sda = sda;
_scl = scl;
}
TwoWire::~TwoWire() {}
bool TwoWire::setPins(int8_t sda, int8_t scl) {
// return true when changing pins on initialized I2C
if (_inSetPins)
return true;
// check if pins are provided
if (sda == -1 || scl == -1)
return false;
// set private pins
_sda = sda;
_scl = scl;
uint32_t pin_sda = pinInfo(sda)->gpio;
uint32_t pin_scl = pinInfo(scl)->gpio;
hal_gpio_pin_afio_select(GPIO_GET_BASE(pin_sda), GPIO_GET_PIN(pin_sda), I2C0_SDA); // TODO: check pin value
hal_gpio_pin_afio_select(GPIO_GET_BASE(pin_scl), GPIO_GET_PIN(pin_scl), I2C0_SCL);
hal_gpio_pin_afio_en(GPIO_GET_BASE(pin_sda), GPIO_GET_PIN(pin_sda), HAL_ENABLE);
hal_gpio_pin_afio_en(GPIO_GET_BASE(pin_scl), GPIO_GET_PIN(pin_scl), HAL_ENABLE);
// restart I2C if changing pins
// this will never be called from begin()
if (_i2c) {
_inSetPins = true;
end();
begin();
_inSetPins = false;
}
return true;
}
bool TwoWire::begin(int8_t sda, int8_t scl, uint32_t frequency) {
if (_i2c)
return true;
// set private i2c pins
if (!setPins(sda, scl))
return false;
// use default frequency
if (!frequency)
frequency = WIRE_DEFAULT_FREQ;
/* disable the i2c */
hal_i2c_en(I2C_BASE, HAL_DISABLE);
_freq = frequency;
_i2c = new i2c_init_t_def;
memset(&_i2c, 0, sizeof(_i2c));
_i2c->i2c_peripheral_clock_freq = 4;
_i2c->i2c_master_mode_sel = I2C_FM_MODE;
_i2c->i2c_fm_mode_duty_cycle = I2C_FM_MODE_DUTY_CYCLE_2;
/*
* TPCLK1 = 1/80MHz = 0.0125us
* Thigh = 9 x CCR x TPCLK1
* Tlow = 16 x CCR x TPCLK1
* Thigh + Tlow = 1/frequency
* ccr = 3.200.000/frequency
*/
_i2c->i2c_ccr = 3200000 / frequency;
_i2c->i2c_trise = 0xF;
hal_i2c_init(I2C_BASE, _i2c);
hal_i2c_en(I2C_BASE, HAL_ENABLE);
return true;
}
bool TwoWire::begin(uint8_t address, int8_t sda, int8_t scl, uint32_t frequency) {
if (_i2c)
return true;
// init master bus first, return if failed
if (!begin(sda, scl, frequency))
return false;
hal_i2c_slave_set_add_mode(I2C_BASE, I2C_ADD_7BIT_MODE);
hal_i2c_slave_set_add1(I2C_BASE, address);
return true;
}
bool TwoWire::end() {
hal_i2c_deinit();
delete _i2c;
_i2c = NULL;
return true;
}
bool TwoWire::setClock(uint32_t freq) {
if (_i2c) {
_i2c->i2c_ccr = 3200000 / freq;
hal_i2c_init(I2C_BASE, _i2c);
}
_freq = freq;
return true;
}
void TwoWire::beginTransmission(uint8_t address) {
_txAddr = address;
_txBuf.clear();
}
// Errors:
// 0 : Success
// 1 : Data too long
// 2 : NACK on transmit of address
// 3 : NACK on transmit of data
// 4 : Other error
uint8_t TwoWire::endTransmission(bool stopBit) {
if (!_i2c || !_txAddr)
return 4;
uint8_t *buf = (uint8_t *)malloc(_txBuf.available());
uint8_t i = 0;
while (_txBuf.available()) {
buf[i++] = _txBuf.read_char();
}
if (hal_i2c_master_7bit_write(I2C_BASE, _txAddr, buf, i) == HAL_RESET)
return 4;
free(buf);
_txAddr = 0;
return 0;
}
size_t TwoWire::requestFrom(uint8_t address, size_t len, bool stopBit) {
if (!len)
return 0;
if (len > SERIAL_BUFFER_SIZE)
len = SERIAL_BUFFER_SIZE;
_rxBuf.clear();
uint8_t *buf = (uint8_t *)malloc(_txBuf.available());
if (hal_i2c_master_7bit_read(I2C_BASE, address, buf, len) == HAL_RESET)
return 0;
uint8_t i = 0;
while (len) {
_rxBuf.store_char(buf[i++]);
len--;
}
free(buf);
return len;
}
size_t TwoWire::write(uint8_t data) {
if (!_txAddr || _txBuf.isFull())
return 0;
_txBuf.store_char(data);
return 1;
}
size_t TwoWire::write(const uint8_t *data, size_t len) {
for (size_t i = 0; i < len; i++) {
if (!write(data[i]))
return i;
}
return len;
}
int TwoWire::available() {
return _rxBuf.available();
}
int TwoWire::read() {
return _rxBuf.read_char();
}
int TwoWire::peek() {
return _rxBuf.peek();
}
void TwoWire::flush() {}
//--------------------------------------------------------------------------------------------------------------------
#define TIMEOUT_CYCLE 4000
static uint8_t hal_i2c_master_7bit_write(uint32_t i2c_x_base, uint8_t dev_addr, const uint8_t *buf, uint16_t buf_len) {
// 1. check busy
if (hal_i2c_wait_bus_idle(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET) {
hal_i2c_master_reset(i2c_x_base);
return HAL_RESET;
}
// 2. send start
if (hal_i2c_master_start(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET)
return HAL_RESET;
// 3. send addr
hal_i2c_master_send_data(i2c_x_base, dev_addr);
// 4. wait send complete
if (hal_i2c_master_wait_addr(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET)
return HAL_RESET;
// 5. clear addr flag
hal_i2c_clear_sr(i2c_x_base);
// 6. send data
for (uint32_t i = 0; i < buf_len; i++) {
// wait tx empty flag
if (hal_i2c_wait_txe(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET) {
return HAL_RESET;
} else {
hal_i2c_master_send_data(i2c_x_base, buf[i]);
}
}
// 7. wait send complete.
if (hal_i2c_wait_btf(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET)
return HAL_RESET;
// 8. stop the i2c.
hal_i2c_master_stop(i2c_x_base);
return HAL_SET;
}
static uint8_t hal_i2c_master_7bit_read(uint32_t i2c_x_base, uint8_t dev_addr, uint8_t *buf, uint16_t buf_len) {
// 1. check busy
if (hal_i2c_wait_bus_idle(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET) {
hal_i2c_master_reset(i2c_x_base);
return HAL_RESET;
}
// 2. send start
if (hal_i2c_master_start(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET)
return HAL_RESET;
// 3. send addr (+1 is read operation)
hal_i2c_master_send_data(i2c_x_base, dev_addr + 1);
// 4. Wait for an ack after sending the address
if (hal_i2c_master_wait_addr(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET)
return HAL_RESET;
// 5. clear addr flag
hal_i2c_clear_sr(i2c_x_base);
// 6. clear the DR
hal_i2c_master_recv_data(i2c_x_base);
// 7. receive data
for (int i = buf_len; i > 0; i--) {
// when reading the last byte,do not send the ack
if (buf_len == 1) {
// do not send the ack
hal_i2c_ack_en(i2c_x_base, HAL_DISABLE);
/// wait rx not empty
if (hal_i2c_wait_rxne(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET) {
return HAL_RESET;
} else {
*buf = hal_i2c_master_recv_data(i2c_x_base);
}
// read data
} else {
// send ack
hal_i2c_ack_en(i2c_x_base, HAL_ENABLE);
// wait rx not empty
if (hal_i2c_wait_rxne(i2c_x_base, TIMEOUT_CYCLE) == HAL_RESET) {
return HAL_RESET;
} else {
*buf = hal_i2c_master_recv_data(i2c_x_base);
}
}
buf_len--;
buf++;
}
// 8. stop the i2c.
hal_i2c_master_stop(i2c_x_base);
return HAL_SET;
}

View File

@@ -0,0 +1,66 @@
/* Copyright (c) Etienne Le Cousin 2025-01-19. */
#pragma once
#include <Arduino.h>
#include <HardwareI2C.h>
#include <api/RingBuffer.h>
#define Wire1 Wire
#define WIRE_HAS_END 1
#define WIRE_DEFAULT_FREQ 100000
#ifndef I2C_PRIV
#define I2C_PRIV void
#endif
using arduino::RingBuffer;
class TwoWire : public HardwareI2C {
private:
I2C_PRIV *_i2c = NULL;
RingBuffer _rxBuf;
RingBuffer _txBuf;
uint8_t _txAddr = 0;
bool _inSetPins = false;
public:
TwoWire();
TwoWire(int8_t sda, int8_t scl);
~TwoWire();
bool setPins(int8_t sda, int8_t scl);
bool begin(int8_t sda, int8_t scl, uint32_t frequency = 0);
bool begin(uint8_t address, int8_t sda, int8_t scl, uint32_t frequency = 0);
bool end();
bool setClock(uint32_t freq);
void beginTransmission(uint8_t address);
uint8_t endTransmission(bool stopBit);
size_t requestFrom(uint8_t address, size_t len, bool stopBit);
size_t write(uint8_t data);
size_t write(const uint8_t *data, size_t len);
int available();
int read();
int peek();
void flush();
using HardwareI2C::begin;
using HardwareI2C::endTransmission;
using HardwareI2C::requestFrom;
using HardwareI2C::write;
using Print::write;
};
#ifdef PIN_WIRE0_SDA
extern TwoWire Wire;
#endif
#ifdef PIN_WIRE1_SDA
extern TwoWire Wire1;
#endif

View File

@@ -0,0 +1,27 @@
/* Copyright (c) Etienne Le Cousin 2024-02-10. */
#pragma once
// Provide GPIO names to variant.cpp files
#define LT_VARIANT_INCLUDE "sdk_private.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
extern void vPortClearInterruptMask(uint32_t ulNewMaskValue);
extern uint32_t ulPortSetInterruptMask(void);
// TODO
// #define clockCyclesPerMicrosecond() (SystemCoreClock / 1000000L)
// #define clockCyclesToMicroseconds(a) (a * 1000L / (SystemCoreClock / 1000L))
// #define microsecondsToClockCycles(a) (a * (SystemCoreClock / 1000000L))
#define interrupts() vPortClearInterruptMask(0)
#define noInterrupts() ulPortSetInterruptMask()
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -0,0 +1,8 @@
#pragma once
#error "Don't include this file directly"
#define LT_ARD_HAS_WIFI 1
#define LT_ARD_HAS_SERIAL 1
#define LT_ARD_HAS_WIRE 1
#define LT_ARD_MD5_MBEDTLS 1

View File

@@ -0,0 +1,53 @@
/* Copyright (c) Etienne Le Cousin 2024-02-17. */
#include <Arduino.h>
#include <sdk_private.h>
extern "C" {
extern void cal_temp_app_task_entry();
#define MAIN_TASK_STACK_SIZE 8192
#define TEMP_APP_TASK_STACK_SIZE 1024
static OS_Thread_t g_mainTask_thread;
static OS_Thread_t g_temp_cal_thread;
bool startMainTask() {
OS_Status ret = OS_ThreadCreate(
&g_mainTask_thread,
"main",
(OS_ThreadEntry_t)mainTask,
NULL,
OS_PRIORITY_BELOW_NORMAL,
MAIN_TASK_STACK_SIZE
);
if (ret != OS_OK)
return false;
ret = OS_ThreadCreate(
&g_temp_cal_thread,
"TempCal",
(OS_ThreadEntry_t)cal_temp_app_task_entry,
NULL,
OS_PRIORITY_BELOW_NORMAL,
TEMP_APP_TASK_STACK_SIZE
);
if (ret != OS_OK) {
return false;
}
OS_ThreadStartScheduler();
return true;
}
void wait_for_debug() {
while (((CoreDebug->DHCSR) & CoreDebug_DHCSR_C_DEBUGEN_Msk) == 0) {
asm("nop");
}
delay(1000);
}
} // extern "C"

View File

@@ -0,0 +1,66 @@
/* Copyright (c) Etienne Le Cousin 2024-02-17. */
#include "wiring_private.h"
#ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG
#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *)0xe000e018))
#endif
void delayMicroseconds(unsigned int us) {
int i;
uint32_t t0, tn;
int dfactor = 20 * us - 10 + (81 * us / 100);
if (us > 100) {
t0 = micros();
do {
tn = micros();
} while (tn >= t0 && tn < (t0 + us - 1));
} else {
for (i = 0; i < dfactor; i++) {
asm("nop");
}
}
}
unsigned long millis(void) {
return (__get_IPSR() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR();
}
unsigned long micros(void) {
uint32_t tick1, tick2;
uint32_t us;
uint32_t tick_per_us = F_CPU / 1000;
if (__get_IPSR() == 0) {
tick1 = xTaskGetTickCount();
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
tick2 = xTaskGetTickCount();
} else {
tick1 = xTaskGetTickCountFromISR();
us = portNVIC_SYSTICK_CURRENT_VALUE_REG;
tick2 = xTaskGetTickCountFromISR();
}
if (tick1 == tick2) {
return tick1 * 1000 - us * 1000 / tick_per_us;
} else if ((us * 1000 / tick_per_us) < 500) {
return tick1 * 1000 - us * 1000 / tick_per_us;
} else {
return tick1 * 1000;
}
}
void pinRemoveMode(PinInfo *pin, uint32_t mask) {
PinData *data = pinData(pin);
if ((mask & PIN_GPIO) && (pin->enabled & PIN_GPIO)) {
hal_gpio_pin_direction_set(data->gpio_base, data->gpio->pin, GPIO_INPUT);
free(data->gpio);
pinDisable(pin, PIN_GPIO);
}
if ((mask & PIN_IRQ) && (pin->enabled & PIN_IRQ)) {
data->irqHandler = NULL;
hal_gpio_pin_it_en(data->gpio_base, data->gpio->pin, HAL_DISABLE);
pinDisable(pin, PIN_IRQ);
}
}

View File

@@ -0,0 +1,79 @@
/* Copyright (c) Etienne Le Cousin 2025-01-19. */
#include "wiring_private.h"
#ifndef PIN_ADC1
#define PIN_ADC1 -1
#endif
#ifndef PIN_ADC2
#define PIN_ADC2 -1
#endif
#ifndef PIN_ADC3
#define PIN_ADC3 -1
#endif
#ifndef PIN_ADC4
#define PIN_ADC4 -1
#endif
#ifndef PIN_ADC5
#define PIN_ADC5 -1
#endif
#ifndef PIN_ADC6
#define PIN_ADC6 -1
#endif
#ifndef PIN_ADC7
#define PIN_ADC7 -1
#endif
const uint32_t adc_channels[] = {
-1,
PIN_ADC1,
PIN_ADC2,
PIN_ADC3,
PIN_ADC4,
PIN_ADC5,
PIN_ADC6,
PIN_ADC7,
};
static adc_ch_t pinToAdcCh(uint32_t gpio) {
for (uint8_t i = 0; i < ADC_CH_NUM; i++) {
if (adc_channels[i] == gpio)
return (adc_ch_t)(1 << i);
}
return ADC_CH0;
}
uint16_t analogReadVoltage(pin_size_t pinNumber) {
uint16_t ret = 0;
pinCheckGetInfo(pinNumber, PIN_ADC, 0);
hal_gpio_pin_mode_set(GPIO_GET_BASE(pin->gpio), GPIO_GET_PIN(pin->gpio), GPIO_MODE_ANALOG);
adc_ch_t ch = pinToAdcCh(pin->gpio);
adc_init_t_def adc_init;
memset(&adc_init, 0, sizeof(adc_init_t_def));
adc_init.adc_ch = ch;
adc_init.adc_conv_mode = ADC_CONV_MODE_CONTINUE;
adc_init.adc_presc = 80;
adc_init.adc_ov_smp_ratio = ADC_OVER_SAMPLING_RATIO_X8;
adc_init.adc_ov_smp_ratio_en = ADC_OVER_SAMPLING_EN_STATUS_BIT0;
hal_adc_init(ADC_BASE, &adc_init);
hal_adc_en(ADC_BASE, HAL_ENABLE);
hal_adc_start_conv(ADC_BASE);
while (hal_adc_get_conv_status(ADC_BASE, ch) == 0)
;
ret = hal_adc_get_data(ADC_BASE, ch);
hal_adc_clr_conv_status(ADC_BASE, ch);
return (uint16_t)(3700UL * ret / 4095);
}
uint16_t analogReadMaxVoltage(pin_size_t pinNumber) {
return 3300;
}

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