24 Commits

Author SHA1 Message Date
Kuba Szczodrzyński
ead577a116 [release] v0.7.0
Some checks failed
Lint check / Lint with clang-format (push) Has been cancelled
Lint check / Lint with black (push) Has been cancelled
PlatformIO Publish / publish (push) Has been cancelled
2022-07-10 19:50:07 +02:00
Kuba Szczodrzyński
ccf7d972ce [beken-72xx] Implement WiFi events 2022-07-10 19:49:14 +02:00
Kuba Szczodrzyński
b2df9e6a8b [beken-72xx] Use chip ID based on MAC address 2022-07-07 18:01:35 +02:00
Kuba Szczodrzyński
e37014ebd6 [beken-72xx] Wrap BkDriverFlash for correct partition offsets 2022-07-07 17:45:58 +02:00
Kuba Szczodrzyński
c96ef2ff7a [beken-72xx] Add draft BK7231N support 2022-07-07 17:18:25 +02:00
Kuba Szczodrzyński
c19dd0d87e [beken-72xx] Fix WiFi using DHCP 2022-07-07 17:15:52 +02:00
Kuba Szczodrzyński
02f972bd5f [boards] Add CB2S board definition 2022-07-07 14:57:35 +02:00
Kuba Szczodrzyński
15facd8866 [realtek-ambz] Fix reading MAC address without WiFi enabled 2022-07-05 13:16:51 +02:00
Kuba Szczodrzyński
cf584c3bd6 [tools] Fix link2bin with long command line 2022-07-04 22:37:25 +02:00
Kuba Szczodrzyński
4744351964 [core] Allow changing SDK, logger & Serial output ports 2022-07-04 13:56:03 +02:00
Kuba Szczodrzyński
31b753ab5a [core] Allow configuring silencing of SDK output 2022-07-04 13:55:58 +02:00
Kuba Szczodrzyński
3cb944dde2 [realtek-ambz] Implement SoftwareSerial class 2022-07-03 22:54:18 +02:00
Kuba Szczodrzyński
1b4265f522 [docs] Add TODO list 2022-07-03 19:50:27 +02:00
Kuba Szczodrzyński
5d16338faa [realtek-ambz] Add missing #define 2022-07-03 19:48:24 +02:00
Kuba Szczodrzyński
673b8233e5 [realtek-ambz] Refactor Serial class 2022-07-03 19:15:33 +02:00
Kuba Szczodrzyński
0dd2e2583b [core] Rename init() to initArduino() 2022-07-03 16:49:46 +02:00
Kuba Szczodrzyński
c19f24cbfd [beken-72xx] Implement WiFi Access Point mode 2022-07-01 19:16:48 +02:00
Kuba Szczodrzyński
cfb6830d95 [beken-72xx] Revert scanning before connecting 2022-07-01 19:15:14 +02:00
Kuba Szczodrzyński
27dea356cf [beken-72xx] Fix station with static IP 2022-07-01 19:14:41 +02:00
Kuba Szczodrzyński
352a425c4f [beken-72xx] Wait for init_thread to start TCP/IP 2022-07-01 18:49:14 +02:00
Kuba Szczodrzyński
4beaa79d02 [beken-72xx] Revert to standard station config struct 2022-07-01 18:48:11 +02:00
Kuba Szczodrzyński
e54eab83f2 [beken-72xx] Use station data structs in WiFiData 2022-07-01 16:17:48 +02:00
Kuba Szczodrzyński
e74a491b4a [core] Move SSID & passphrase validation to common 2022-07-01 15:36:49 +02:00
Kuba Szczodrzyński
a9415c1db7 [core] Fix compilation and linking on Linux 2022-07-01 12:47:32 +02:00
75 changed files with 2490 additions and 404 deletions

View File

@@ -47,15 +47,15 @@ Core functions | ✔️ | ✔️
GPIO/PWM/IRQ | ✔️/✔️/✔️ | ❓/✔️/❌
Analog input (ADC) | ✔️ | ✔️
Serial | ✔️ | ✔️
Serial (extra) | | 1, 2
Serial (extra) | 0, 1, 2 | 1, 2
Flash I/O | ✔️ | ✔️
**CORE LIBRARIES** | |
SoftwareSerial | | ❌
SoftwareSerial | ✔️ | ❌
SPI | ❌ | ❌
Wire | ❗ | ❌
**OTHER LIBRARIES** | |
Wi-Fi STA/AP/Mixed | ✔️ | ✔️/❌/❌
Wi-Fi Events | ✔️ |
Wi-Fi STA/AP/Mixed | ✔️ | ✔️
Wi-Fi Events | ✔️ | ✔️
TCP Client (SSL) | ✔️ (✔️) | ✔️ (❗)
TCP Server | ✔️ | ✔️
IPv6 | ❌ | ❌

View File

@@ -14,6 +14,7 @@
* Common API
* [FS](ltapi/classfs_1_1_f_s.md)
* [Preferences](ltapi/class_i_preferences.md)
* [SoftwareSerial](ltapi/class_software_serial.md)
* [WiFi API](ltapi/class_wi_fi_class.md)
* [TCP Client](ltapi/class_i_wi_fi_client.md)
* [SSL Client](ltapi/class_i_wi_fi_client_secure.md)
@@ -50,4 +51,5 @@
* [Debugging](docs/platform/realtek/debugging.md)
* [Exception decoder](docs/platform/realtek/exception-decoder.md)
* [All supported boards](boards/)
* [📓 TODO](TODO.md)
* [🔗 Resources](docs/resources.md)

46
TODO.md Normal file
View File

@@ -0,0 +1,46 @@
# TODO list
## General
### New families
- BL602
- RTL8710A
- RTL8720C
- RTL8720D
- W600 and/or W800
- LN8825
- host-native family
### Tools
- move all UF2 assembling/uploading/processing tools (as well as `uf2ota` C library) to a separate repository, possibly rewriting parts of it again. Make these tools CLI-usable
- write OpenOCD flashers, using uf2ota library + FAL for partitions (same repo as above)
### Serial
- configuration of RX/TX pins
- SoftwareSerial library - receiving + Beken family
### Other
- watchdog API
- `Preferences` library
- test/fix IPv6 on different families
- what is `PowerManagement` at all? probably useless -> remove
## BK7231
- WiFi events
- implement OTA
- fix WiFi on BK7231N, test other functionality
- add generic board definition
- fix SSL (mbedTLS)
- I2C (Wire)
- SPI
- BLE
## RTL8710B
- add generic board definition
- rewrite most of Wiring (it was copied from `ambd_arduino`, and is ugly)

View File

@@ -14,19 +14,17 @@
// Include board variant
#include "variant.h"
// Choose the main UART output port
#ifndef LT_UART_DEFAULT_PORT
#if defined(PIN_SERIAL2_TX)
#define LT_UART_DEFAULT_PORT 2
#else
#define LT_UART_DEFAULT_PORT 1
#endif
#endif
// Define available serial ports
#ifdef __cplusplus
#include "SerialClass.h"
#ifdef HAS_SERIAL_CLASS
// declare instances of available Serial* components
// map Serial to Serial2 if available, else to Serial1
#ifdef PIN_SERIAL1_RX
extern SerialClass Serial1;
#endif
#ifdef PIN_SERIAL2_RX
extern SerialClass Serial2;
#define Serial Serial2
#else
#define Serial Serial1
#endif
#endif
#include <core/SerialExtern.h>
#endif

View File

@@ -13,11 +13,16 @@
#define FLASH_OP_RDID 20
extern "C" {
#include <flash_pub.h>
#include <param_config.h>
#include <sys_ctrl.h>
#include <sys_rtos.h>
#include <wlan_ui_pub.h>
}
extern uint8_t system_mac[];
} // extern "C"
void LibreTuya::restart() {
bk_reboot();
@@ -35,10 +40,9 @@ const char *LibreTuya::getChipModel() {
}
uint32_t LibreTuya::getChipId() {
// TODO determine if this really is unique
uint32_t chipId = REG_READ(SCTRL_DEVICE_ID);
chipId &= 0xFFFFFF;
return chipId;
uint8_t mac[6];
cfg_load_mac(mac); // force loading MAC from TLV (ignore user-set WiFi MAC)
return (mac[3]) | (mac[4] << 8) | (mac[5] << 16);
}
uint8_t LibreTuya::getChipCores() {

View File

@@ -3,17 +3,19 @@
#include "SerialClass.h"
extern "C" {
#include <uart_pub.h>
extern void bk_send_byte(uint8_t uport, uint8_t data);
extern void uart_hw_set_change(uint8_t uport, bk_uart_config_t *uart_config);
extern int uart_rx_callback_set(int uport, uart_callback callback, void *param);
}
#ifdef PIN_SERIAL1_RX
} // extern "C"
#ifdef PIN_SERIAL1_TX
SerialClass Serial1(UART1_PORT);
#endif
#ifdef PIN_SERIAL2_RX
#ifdef PIN_SERIAL2_TX
SerialClass Serial2(UART2_PORT);
#endif
@@ -39,11 +41,13 @@ void SerialClass::begin(unsigned long baudrate, uint16_t config) {
.stop_bits = (uart_stop_bits_t)stopBits,
.flow_control = FLOW_CTRL_DISABLED,
};
if (this->buf) {
this->buf->clear();
} else {
this->buf = new RingBuffer();
}
uart_hw_set_change(port, &cfg);
uart_rx_callback_set(port, callback, this->buf);
}

View File

@@ -3,12 +3,21 @@
#include <Arduino.h>
extern "C" {
#include <rtos_pub.h>
#include <sys_rtos.h>
}
extern int uart_print_port;
} // extern "C"
beken_thread_t mainThread;
void initArduino() {
// set default UART output port
uart_print_port = LT_UART_DEFAULT_PORT - 1;
}
bool startMainTask() {
OSStatus ret = rtos_create_thread(
&mainThread,

View File

@@ -13,6 +13,18 @@ static GPIO_INDEX pwmToGpio[] = {
GPIO26, // PWM5
};
#if CFG_SOC_NAME == SOC_BK7231N
static GPIO_INDEX adcToGpio[] = {
-1, // ADC0 - VBAT
GPIONUM, // ADC1
GPIONUM, // ADC2
GPIO23, // ADC3
GPIONUM, // ADC4
GPIONUM, // ADC5
GPIONUM, // ADC6
GPIONUM, // ADC7
};
#else
static GPIO_INDEX adcToGpio[] = {
-1, // ADC0 - VBAT
GPIO4, // ADC1
@@ -23,6 +35,7 @@ static GPIO_INDEX adcToGpio[] = {
GPIO12, // ADC6
GPIO13, // ADC7
};
#endif
static uint8_t gpioToPwm(GPIO_INDEX gpio) {
for (uint8_t i = 0; i < sizeof(pwmToGpio); i++) {
@@ -84,7 +97,13 @@ void analogWrite(pin_size_t pinNumber, int value) {
float percent = value * 1.0 / (1 << _analogWriteResolution);
uint32_t dutyCycle = percent * _analogWritePeriod * 26 - 1;
pwm.channel = gpioToPwm(pin->gpio);
pwm.duty_cycle = dutyCycle;
#if CFG_SOC_NAME != SOC_BK7231N
pwm.duty_cycle = dutyCycle;
#else
pwm.duty_cycle1 = dutyCycle;
pwm.duty_cycle2 = dutyCycle;
pwm.duty_cycle3 = dutyCycle;
#endif
if (!pinEnabled(pin, PIN_PWM)) {
// enable PWM and set its value

View File

@@ -15,6 +15,7 @@ WiFiStatus eventTypeToStatus(uint8_t type) {
switch (type) {
case RW_EVT_STA_IDLE:
return WL_IDLE_STATUS;
case RW_EVT_STA_NO_AP_FOUND:
return WL_NO_SSID_AVAIL;
case RW_EVT_STA_CONNECTING:
case RW_EVT_STA_CONNECTED:
@@ -22,7 +23,6 @@ WiFiStatus eventTypeToStatus(uint8_t type) {
case RW_EVT_STA_GOT_IP:
return WL_CONNECTED;
case RW_EVT_STA_PASSWORD_WRONG:
case RW_EVT_STA_NO_AP_FOUND:
case RW_EVT_STA_ASSOC_FULL:
case RW_EVT_STA_CONNECT_FAILED:
return WL_CONNECT_FAILED;

View File

@@ -0,0 +1,112 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-01. */
#include "WiFiPriv.h"
bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bool ssidHidden, int maxClients) {
if (!enableAP(true))
return WL_CONNECT_FAILED;
if (!validate(ssid, passphrase))
return WL_CONNECT_FAILED;
LT_HEAP_I();
strcpy(AP_CFG->wifi_ssid, ssid);
if (passphrase) {
strcpy(AP_CFG->wifi_key, passphrase);
AP_CFG->security = BK_SECURITY_TYPE_WPA2_MIXED;
} else {
AP_CFG->wifi_key[0] = '\0';
AP_CFG->security = BK_SECURITY_TYPE_NONE;
}
AP_CFG->channel = channel;
AP_CFG->ssid_hidden = ssidHidden;
AP_CFG->max_con = maxClients;
AP_CFG->dhcp_mode = DHCP_SERVER;
AP_CFG->wifi_retry_interval = 100;
LT_I("Creating SoftAP %s", ssid);
__wrap_bk_printf_disable();
OSStatus ret = bk_wlan_start_ap_adv(AP_CFG);
__wrap_bk_printf_enable();
if (ret != 0) {
LT_E("SoftAP failed; ret=%d", ret);
return false;
}
LT_D_WG("Start OK");
return true;
}
bool WiFiClass::softAPConfig(IPAddress localIP, IPAddress gateway, IPAddress subnet) {
if (!localIP) {
localIP = gateway = IPAddress(192, 168, 43, 1);
subnet = IPAddress(255, 255, 255, 0);
}
sprintf(AP_CFG->local_ip_addr, IP_FMT, localIP[0], localIP[1], localIP[2], localIP[3]);
sprintf(AP_CFG->net_mask, IP_FMT, subnet[0], subnet[1], subnet[2], subnet[3]);
sprintf(AP_CFG->gateway_ip_addr, IP_FMT, gateway[0], gateway[1], gateway[2], gateway[3]);
// from wlan_ui.c:1370
if (uap_ip_is_start()) {
uap_ip_down();
ip_address_set(
BK_STATION,
AP_CFG->dhcp_mode,
AP_CFG->local_ip_addr,
AP_CFG->net_mask,
AP_CFG->gateway_ip_addr,
AP_CFG->dns_server_ip_addr
);
uap_ip_start();
}
return true;
}
bool WiFiClass::softAPdisconnect(bool wifiOff) {
return bk_wlan_stop(BK_SOFT_AP) == kNoErr;
}
uint8_t WiFiClass::softAPgetStationNum() {
return 0;
}
IPAddress WiFiClass::softAPIP() {
bk_wlan_get_ip_status(IP_STATUS, BK_SOFT_AP);
IPAddress ip;
ip.fromString(IP_STATUS->ip);
return ip;
}
IPAddress WiFiClass::softAPSubnetMask() {
bk_wlan_get_ip_status(IP_STATUS, BK_SOFT_AP);
IPAddress ip;
ip.fromString(IP_STATUS->mask);
return ip;
}
const char *WiFiClass::softAPgetHostname() {
struct netif *ifs = (struct netif *)net_get_uap_handle();
return netif_get_hostname(ifs);
}
bool WiFiClass::softAPsetHostname(const char *hostname) {
struct netif *ifs = (struct netif *)net_get_uap_handle();
netif_set_hostname(ifs, (char *)hostname);
return true;
}
uint8_t *WiFiClass::softAPmacAddress(uint8_t *mac) {
setMacAddress(mac);
return mac;
}
String WiFiClass::softAPmacAddress(void) {
uint8_t mac[ETH_ALEN];
wifi_get_mac_address((char *)mac, CONFIG_ROLE_AP);
return macToString(mac);
}
const String WiFiClass::softAPSSID(void) {
return AP_CFG->wifi_ssid;
}

View File

@@ -12,11 +12,9 @@ extern "C" {
} // extern "C"
typedef struct {
char ssid[32 + 1];
char pass[64 + 1];
void *configSta;
void *configAp;
unsigned long scannedAt;
uint32_t ipSta[4];
uint32_t ipAp[4];
SemaphoreHandle_t scanSem;
void *statusIp;
void *statusLink;

View File

@@ -0,0 +1,144 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-10. */
#include "WiFiPriv.h"
#include <vector>
static xQueueHandle wifiEventQueueHandle = NULL;
static xTaskHandle wifiEventTaskHandle = NULL;
static const rw_evt_type eventConnected = RW_EVT_STA_CONNECTED;
// callback for bk_wlan_status_register_cb()
static void wifiStatusCallback(rw_evt_type *pEvent) {
if (wifiEventQueueHandle && wifiEventTaskHandle) {
xQueueSend(wifiEventQueueHandle, pEvent, portMAX_DELAY);
} else {
wifiEventHandler(*pEvent);
}
}
static void wifiEventTask(void *arg) {
rw_evt_type event = RW_EVT_MAX;
for (;;) {
if (xQueueReceive(wifiEventQueueHandle, &event, portMAX_DELAY) == pdTRUE) {
wifiEventHandler(event);
}
}
}
void wifiEventSendArduino(EventId event) {
event = (EventId)(RW_EVT_ARDUINO | event);
wifiStatusCallback((rw_evt_type *)&event);
}
void startWifiTask() {
if (!wifiEventQueueHandle) {
LT_HEAP_I();
wifiEventQueueHandle = xQueueCreate(32, sizeof(rw_evt_type));
LT_HEAP_I();
}
if (!wifiEventTaskHandle) {
LT_HEAP_I();
xTaskCreate(wifiEventTask, "wifievent", 512, NULL, 4, &wifiEventTaskHandle);
LT_HEAP_I();
}
bk_wlan_status_register_cb((FUNC_1PARAM_PTR)wifiStatusCallback);
}
void wifiEventHandler(rw_evt_type event) {
if (!pWiFi)
return; // failsafe
LT_D_WG("WiFi event %u", event);
EventId eventId;
EventInfo eventInfo;
String ssid;
memset(&eventInfo, 0, sizeof(EventInfo));
switch (event) {
case RW_EVT_STA_IDLE:
eventId = ARDUINO_EVENT_WIFI_READY;
break;
case RW_EVT_STA_BEACON_LOSE:
case RW_EVT_STA_PASSWORD_WRONG:
case RW_EVT_STA_NO_AP_FOUND:
case RW_EVT_STA_ASSOC_FULL:
case RW_EVT_STA_DISCONNECTED:
case RW_EVT_STA_CONNECT_FAILED:
eventId = ARDUINO_EVENT_WIFI_STA_DISCONNECTED;
eventInfo.wifi_sta_disconnected.ssid_len = 0;
switch (event) {
case RW_EVT_STA_BEACON_LOSE:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_BEACON_TIMEOUT;
break;
case RW_EVT_STA_PASSWORD_WRONG:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_AUTH_FAIL;
break;
case RW_EVT_STA_NO_AP_FOUND:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_NO_AP_FOUND;
break;
case RW_EVT_STA_ASSOC_FULL:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_ASSOC_TOOMANY;
break;
case RW_EVT_STA_DISCONNECTED:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_ASSOC_LEAVE;
break;
case RW_EVT_STA_CONNECT_FAILED:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_CONNECTION_FAIL;
break;
default:
eventInfo.wifi_sta_disconnected.reason = WIFI_REASON_UNSPECIFIED;
break;
}
break;
case RW_EVT_STA_CONNECTED:
eventId = ARDUINO_EVENT_WIFI_STA_CONNECTED;
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);
break;
case RW_EVT_STA_GOT_IP:
eventId = ARDUINO_EVENT_WIFI_STA_GOT_IP;
eventInfo.got_ip.if_index = 0;
eventInfo.got_ip.ip_changed = true;
eventInfo.got_ip.ip_info.ip.addr = WiFi.localIP();
eventInfo.got_ip.ip_info.netmask.addr = WiFi.subnetMask();
eventInfo.got_ip.ip_info.gw.addr = WiFi.gatewayIP();
break;
case RW_EVT_AP_CONNECTED:
eventId = ARDUINO_EVENT_WIFI_AP_STACONNECTED;
// TODO station MAC
break;
case RW_EVT_AP_DISCONNECTED:
eventId = ARDUINO_EVENT_WIFI_AP_STADISCONNECTED;
// TODO station MAC
break;
case RW_EVT_ARDUINO | ARDUINO_EVENT_WIFI_SCAN_DONE:
eventId = ARDUINO_EVENT_WIFI_SCAN_DONE;
eventInfo.wifi_scan_done.status = 0;
if (pWiFi->scan)
eventInfo.wifi_scan_done.number = pWiFi->scan->count;
eventInfo.wifi_scan_done.scan_id = 0;
break;
default:
if (event < RW_EVT_ARDUINO)
return;
eventId = (EventId)(event - RW_EVT_ARDUINO);
break;
}
pWiFi->postEvent(eventId, eventInfo);
}

View File

@@ -4,16 +4,26 @@
bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
__wrap_bk_printf_disable();
startWifiTask();
if (mode && !data.statusIp) {
data.statusIp = (IPStatusTypedef *)malloc(sizeof(IPStatusTypedef));
data.statusLink = (LinkStatusTypeDef *)malloc(sizeof(LinkStatusTypeDef));
data.configSta = zalloc(sizeof(network_InitTypeDef_st));
data.configAp = zalloc(sizeof(network_InitTypeDef_ap_st));
data.statusIp = malloc(sizeof(IPStatusTypedef));
data.statusLink = malloc(sizeof(LinkStatusTypeDef));
STA_CFG->dhcp_mode = DHCP_CLIENT;
}
if (!__bk_rf_is_init) {
LT_D_WG("Initializing func&app");
func_init_extended();
app_pre_start();
// wait for the init_thread to finish its job
while (xTaskGetHandle("init_thread")) {
LT_V_WG("Waiting for init_thread");
delay(10);
}
LT_D_WG("Success");
__bk_rf_is_init = true;
}
@@ -22,9 +32,11 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
if (sta == WLMODE_ENABLE) {
LT_D_WG("Enabling STA");
bk_wlan_sta_init(NULL);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_START);
} else if (sta == WLMODE_DISABLE) {
LT_D_WG("Disabling STA");
bk_wlan_stop(BK_STATION);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_STA_STOP);
}
LT_HEAP_I();
@@ -32,14 +44,20 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
if (ap == WLMODE_ENABLE) {
LT_D_WG("Enabling AP");
bk_wlan_ap_init(NULL);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_START);
} else if (ap == WLMODE_DISABLE) {
LT_D_WG("Disabling AP");
bk_wlan_stop(BK_SOFT_AP);
wifiEventSendArduino(ARDUINO_EVENT_WIFI_AP_STOP);
}
if (!mode) {
free(data.configSta);
free(data.configAp);
free(data.statusIp);
free(data.statusLink);
data.configSta = NULL;
data.configAp = NULL;
data.statusIp = NULL;
data.statusLink = NULL;
}
@@ -47,6 +65,7 @@ bool WiFiClass::modePriv(WiFiMode mode, WiFiModeAction sta, WiFiModeAction ap) {
LT_HEAP_I();
__wrap_bk_printf_enable();
return true;
}
WiFiMode WiFiClass::getMode() {
@@ -58,7 +77,10 @@ WiFiMode WiFiClass::getMode() {
}
WiFiStatus WiFiClass::status() {
return eventTypeToStatus(mhdr_get_station_status());
rw_evt_type status = mhdr_get_station_status();
if (status == RW_EVT_STA_CONNECTED && STA_CFG->dhcp_mode == DHCP_DISABLE)
status = RW_EVT_STA_GOT_IP;
return eventTypeToStatus(status);
}
IPAddress WiFiClass::hostByName(const char *hostname) {

View File

@@ -9,6 +9,8 @@ extern "C" {
#include <lwip/api.h>
#include <lwip/ip_addr.h>
#include <lwip/netif.h>
// port/net.h
#include <net.h>
#include <FreeRTOS.h>
#include <semphr.h>
@@ -28,10 +30,6 @@ extern void bk_wlan_ap_init(network_InitTypeDef_st *inNetworkInitPara);
// func/hostapd-2.5/wpa_supplicant/main_supplicant.c
extern struct wpa_ssid_value *wpas_connect_ssid;
// func/lwip_intf/lwip-2.0.2/port/net.c
extern struct netif *net_get_sta_handle(void);
extern struct netif *net_get_uap_handle(void);
// app/param_config.c
extern general_param_t *g_wlan_general_param;
extern ap_param_t *g_ap_param_ptr;
@@ -42,15 +40,17 @@ extern uint8_t system_mac[6];
WiFiStatus eventTypeToStatus(uint8_t type);
WiFiAuthMode securityTypeToAuthMode(uint8_t type);
#define ADDR_STA_IP data.ipSta[0]
#define ADDR_STA_MASK data.ipSta[1]
#define ADDR_STA_GW data.ipSta[2]
#define ADDR_STA_DNS data.ipSta[3]
#define ADDR_AP_IP data.ipAp[0]
#define ADDR_AP_MASK data.ipAp[1]
#define ADDR_AP_GW data.ipAp[2]
#define ADDR_AP_DNS data.ipAp[3]
// WiFiEvents.cpp
extern void wifiEventSendArduino(EventId event);
extern void startWifiTask();
extern void wifiEventHandler(rw_evt_type event);
#define RW_EVT_ARDUINO (1 << 7)
#define IP_FMT "%u.%u.%u.%u"
#define STA_CFG ((network_InitTypeDef_st *)data.configSta)
#define AP_CFG ((network_InitTypeDef_ap_st *)data.configAp)
#define IP_STATUS ((IPStatusTypedef *)data.statusIp)
#define LINK_STATUS ((LinkStatusTypeDef *)data.statusLink)

View File

@@ -4,24 +4,19 @@
WiFiStatus
WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, const uint8_t *bssid, bool connect) {
enableSTA(true);
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
LT_W("SSID not specified or too long");
if (!enableSTA(true))
return WL_CONNECT_FAILED;
}
if (passphrase && strlen(passphrase) > 64) {
LT_W("Passphrase too long");
if (!validate(ssid, passphrase))
return WL_CONNECT_FAILED;
}
// store the network data for later
strcpy(data.ssid, ssid);
if (passphrase)
strcpy(data.pass, passphrase);
else
data.pass[0] = 0;
LT_HEAP_I();
strcpy(STA_CFG->wifi_ssid, ssid);
if (passphrase) {
strcpy(STA_CFG->wifi_key, passphrase);
} else {
STA_CFG->wifi_bssid[0] = '\0';
}
if (reconnect(bssid))
return WL_CONNECTED;
@@ -30,28 +25,36 @@ WiFiClass::begin(const char *ssid, const char *passphrase, int32_t channel, cons
}
bool WiFiClass::config(IPAddress localIP, IPAddress gateway, IPAddress subnet, IPAddress dns1, IPAddress dns2) {
ADDR_STA_IP = (uint32_t)localIP;
ADDR_STA_GW = (uint32_t)gateway;
ADDR_STA_MASK = (uint32_t)subnet;
ADDR_STA_DNS = (uint32_t)dns1;
// need to initialize data struct first
enableSTA(true);
if (status() == WL_CONNECTED) {
IPStatusTypedef config;
config.dhcp = !localIP[0];
if (localIP) {
sprintf(config.ip, "%u.%u.%u.%u", ADDR_STA_IP);
sprintf(config.mask, "%u.%u.%u.%u", ADDR_STA_MASK);
sprintf(config.gate, "%u.%u.%u.%u", ADDR_STA_GW);
STA_CFG->dhcp_mode = localIP ? DHCP_DISABLE : DHCP_CLIENT;
if (localIP) {
sprintf(STA_CFG->local_ip_addr, IP_FMT, localIP[0], localIP[1], localIP[2], localIP[3]);
sprintf(STA_CFG->net_mask, IP_FMT, subnet[0], subnet[1], subnet[2], subnet[3]);
sprintf(STA_CFG->gateway_ip_addr, IP_FMT, gateway[0], gateway[1], gateway[2], gateway[3]);
if (dns1) {
sprintf(STA_CFG->dns_server_ip_addr, IP_FMT, dns1[0], dns1[1], dns1[2], dns1[3]);
}
if (dns1)
sprintf(config.dns, "%u.%u.%u.%u", ADDR_STA_DNS);
bk_wlan_set_ip_status(&config, BK_STATION);
}
// from wlan_ui.c:1370
if (sta_ip_is_start()) {
sta_ip_down();
ip_address_set(
BK_STATION,
STA_CFG->dhcp_mode,
STA_CFG->local_ip_addr,
STA_CFG->net_mask,
STA_CFG->gateway_ip_addr,
STA_CFG->dns_server_ip_addr
);
sta_ip_start();
}
return true;
}
bool WiFiClass::reconnect(const uint8_t *bssid) {
if (!bssid && !data.ssid[0]) {
if (!bssid && !STA_CFG->wifi_ssid[0]) {
LT_E("(B)SSID not specified");
goto error;
}
@@ -59,55 +62,30 @@ bool WiFiClass::reconnect(const uint8_t *bssid) {
if (bssid) {
LT_D_WG("Connecting to " MACSTR, MAC2STR(bssid));
} else {
LT_D_WG("Connecting to %s", data.ssid);
LT_D_WG("Connecting to %s", STA_CFG->wifi_ssid);
}
network_InitTypeDef_st config;
memset(&config, 0, sizeof(network_InitTypeDef_st));
// network_InitTypeDef_adv_st config;
// memset(&config, 0, sizeof(network_InitTypeDef_adv_st));
config.wifi_mode = BK_STATION;
config.wifi_retry_interval = 100;
// config.ap_info.security = BK_SECURITY_TYPE_WPA2_MIXED;
// config.ap_info.channel = 6;
strcpy(config.wifi_ssid, data.ssid);
// strcpy(config.ap_info.ssid, data.ssid);
strcpy(config.wifi_key, data.pass);
// strcpy(config.key, data.pass);
// config.key_len = strlen(data.pass);
STA_CFG->wifi_mode = BK_STATION;
STA_CFG->wifi_retry_interval = 100;
if (bssid)
memcpy(config.wifi_bssid, bssid, 6);
// memcpy(config.ap_info.bssid, bssid, 6);
memcpy(STA_CFG->wifi_bssid, bssid, 6);
else
memset(STA_CFG->wifi_bssid, 0x00, 6);
if (ADDR_STA_IP && ADDR_STA_MASK && ADDR_STA_GW) {
config.dhcp_mode = DHCP_DISABLE;
sprintf(config.local_ip_addr, "%u.%u.%u.%u", ADDR_STA_IP);
sprintf(config.net_mask, "%u.%u.%u.%u", ADDR_STA_MASK);
sprintf(config.gateway_ip_addr, "%u.%u.%u.%u", ADDR_STA_GW);
LT_D_WG("Static IP: %s / %s / %s", config.local_ip_addr, config.net_mask, config.gateway_ip_addr);
if (STA_CFG->dhcp_mode == DHCP_DISABLE) {
LT_D_WG("Static IP: %s / %s / %s", STA_CFG->local_ip_addr, STA_CFG->net_mask, STA_CFG->gateway_ip_addr);
LT_D_WG("Static DNS: %s", STA_CFG->dns_server_ip_addr);
} else {
config.dhcp_mode = DHCP_CLIENT;
LT_D_WG("Using DHCP");
}
if (ADDR_STA_DNS) {
sprintf(config.dns_server_ip_addr, "%u.%u.%u.%u", ADDR_STA_DNS);
LT_D_WG("Static DNS: %s", config.dns_server_ip_addr);
}
if (!data.scannedAt || millis() - data.scannedAt > 10000) {
LT_D_WG("Scan needed");
// apparently a scan must be performed first,
// else it hangs at "[sa_sta]MM_START_REQ"
scanNetworks(false);
}
LT_D_WG("Starting WiFi...");
__wrap_bk_printf_disable();
bk_wlan_start_sta(&config);
bk_wlan_start_sta(STA_CFG);
__wrap_bk_printf_enable();
LT_D_WG("bk_wlan_start() OK");
LT_D_WG("Start OK");
return true;
error:
@@ -116,6 +94,8 @@ error:
bool WiFiClass::disconnect(bool wifiOff) {
bk_wlan_connection_loss();
if (wifiOff)
enableSTA(false);
return true;
}
@@ -128,34 +108,30 @@ bool WiFiClass::getAutoReconnect() {
}
IPAddress WiFiClass::localIP() {
IPStatusTypedef config;
bk_wlan_get_ip_status(&config, BK_STATION);
bk_wlan_get_ip_status(IP_STATUS, BK_STATION);
IPAddress ip;
ip.fromString(config.ip);
ip.fromString(IP_STATUS->ip);
return ip;
}
IPAddress WiFiClass::subnetMask() {
IPStatusTypedef config;
bk_wlan_get_ip_status(&config, BK_STATION);
bk_wlan_get_ip_status(IP_STATUS, BK_STATION);
IPAddress ip;
ip.fromString(config.mask);
ip.fromString(IP_STATUS->mask);
return ip;
}
IPAddress WiFiClass::gatewayIP() {
IPStatusTypedef config;
bk_wlan_get_ip_status(&config, BK_STATION);
bk_wlan_get_ip_status(IP_STATUS, BK_STATION);
IPAddress ip;
ip.fromString(config.gate);
ip.fromString(IP_STATUS->gate);
return ip;
}
IPAddress WiFiClass::dnsIP(uint8_t dns_no) {
IPStatusTypedef config;
bk_wlan_get_ip_status(&config, BK_STATION);
bk_wlan_get_ip_status(IP_STATUS, BK_STATION);
IPAddress ip;
ip.fromString(config.dns);
ip.fromString(IP_STATUS->dns);
return ip;
}
@@ -164,12 +140,12 @@ IPAddress WiFiClass::broadcastIP() {
}
const char *WiFiClass::getHostname() {
struct netif *ifs = net_get_sta_handle();
struct netif *ifs = (struct netif *)net_get_sta_handle();
return netif_get_hostname(ifs);
}
bool WiFiClass::setHostname(const char *hostname) {
struct netif *ifs = net_get_sta_handle();
struct netif *ifs = (struct netif *)net_get_sta_handle();
netif_set_hostname(ifs, (char *)hostname);
return true;
}
@@ -180,7 +156,19 @@ uint8_t *WiFiClass::macAddress(uint8_t *mac) {
}
bool WiFiClass::setMacAddress(const uint8_t *mac) {
wifi_set_mac_address((char *)mac);
if (mac[0] & 0x01) {
LT_E("Invalid MAC address");
return false;
}
// ensure "mac_inited" is true
wifi_get_mac_address((char *)system_mac, BK_STATION);
// store the MAC globally
memcpy(system_mac, mac, 6);
WiFiMode previousMode = getMode();
if (previousMode) {
mode(WIFI_MODE_NULL);
mode(previousMode);
}
return true;
}

View File

@@ -38,6 +38,8 @@ static void scanHandler(void *ctx, uint8_t param) {
cls->data.scannedAt = millis();
wifiEventSendArduino(ARDUINO_EVENT_WIFI_SCAN_DONE);
end:
scan->running = false;
xSemaphoreGive(cls->data.scanSem);
@@ -57,17 +59,26 @@ int16_t WiFiClass::scanNetworks(bool async, bool showHidden, bool passive, uint3
__wrap_bk_printf_disable();
mhdr_scanu_reg_cb(scanHandler, this);
bk_wlan_start_scan();
__wrap_bk_printf_enable();
LT_HEAP_I();
scan->running = true;
int16_t ret = WIFI_SCAN_RUNNING;
if (!async) {
LT_I("Waiting for results");
xSemaphoreTake(data.scanSem, 1); // reset the semaphore quickly
xSemaphoreTake(data.scanSem, pdMS_TO_TICKS(maxMsPerChannel * 20));
return scan->count;
if (scan->running) {
scanDelete();
ret = WIFI_SCAN_FAILED;
goto exit;
}
ret = scan->count;
goto exit;
}
return WIFI_SCAN_RUNNING;
exit:
__wrap_bk_printf_enable();
return ret;
}

View File

@@ -14,4 +14,8 @@ void putchar_(char c) {
bk_send_byte(uart_print_port, c);
}
void putchar_p(char c, unsigned long port) {
bk_send_byte(port & 0xFF, c);
}
WRAP_PRINTF(bk_printf);

View File

@@ -0,0 +1,41 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#include "SoftwareSerial.h"
SoftwareSerial::SoftwareSerial(pin_size_t receivePin, pin_size_t transmitPin, bool inverted) {
data.rx.buf = NULL;
data.tx.buf = NULL;
data.rx.pin = receivePin;
data.tx.pin = transmitPin;
data.invert = inverted == true;
}
int SoftwareSerial::available() {
return data.rx.buf->available();
}
int SoftwareSerial::peek() {
return data.rx.buf->peek();
}
int SoftwareSerial::read() {
return data.rx.buf->read_char();
}
void SoftwareSerial::flush() {
while (data.rx.buf->available()) {
yield();
}
}
size_t SoftwareSerial::write(uint8_t c) {
while (data.tx.buf->isFull()) {
yield();
}
data.tx.buf->store_char(c);
if (data.tx.state == SS_IDLE) {
data.tx.state = SS_START;
this->startTx();
}
return 1;
}

View File

@@ -0,0 +1,74 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#pragma once
#include <Arduino.h>
#include <api/HardwareSerial.h>
#include <api/RingBuffer.h>
using namespace arduino;
typedef enum {
SS_IDLE = 0,
SS_START,
SS_DATA0,
SS_DATA1,
SS_DATA2,
SS_DATA3,
SS_DATA4,
SS_DATA5,
SS_DATA6,
SS_DATA7,
SS_STOP,
SS_END,
} SoftState;
typedef struct {
SoftState state;
RingBuffer *buf;
uint8_t byte;
pin_size_t pin;
void *param;
} SoftData;
typedef struct {
SoftData rx;
SoftData tx;
uint8_t invert;
void *param;
} SoftSerial;
class SoftwareSerial : public HardwareSerial {
private:
SoftSerial data;
void *param;
public:
SoftwareSerial(pin_size_t receivePin, pin_size_t transmitPin, bool inverted = false);
inline void begin(unsigned long baudrate) {
begin(baudrate, SERIAL_8N1);
}
int available();
int peek();
int read();
void flush();
size_t write(uint8_t c);
operator bool() {
return data.rx.buf || data.tx.buf;
}
public: // Family needs to implement these methods only
void begin(unsigned long baudrate, uint16_t config);
void end();
private:
void startTx();
void endTx();
using Print::write;
};
#define HAS_SERIAL_CLASS 1

View File

@@ -14,6 +14,8 @@ void WiFiClass::printDiag(Print &dest) {
dest.print("SSID: ");
dest.println(SSID());
if (isConnected()) {
dest.print("Channel: ");
dest.println(channel());
dest.print("BSSID: ");
dest.println(BSSIDstr());
dest.print("RSSI: ");
@@ -42,5 +44,24 @@ void WiFiClass::printDiag(Print &dest) {
}
}
bool WiFiClass::validate(const char *ssid, const char *passphrase) {
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
LT_W("SSID not specified or too long");
return false;
}
if (passphrase) {
uint16_t length = strlen(passphrase);
if (length < 8) {
LT_W("Passphrase too short (%u)", length);
return false;
}
if (length > 63) {
LT_W("Passphrase too long (%u)", length);
return false;
}
}
return true;
}
WiFiClass WiFi;
WiFiClass *pWiFi = NULL;

View File

@@ -46,6 +46,7 @@ class WiFiClass {
WiFiClass();
~WiFiClass();
void printDiag(Print &dest);
bool validate(const char *ssid, const char *passphrase);
public: /* WiFiGeneric.cpp */
bool mode(WiFiMode mode);

View File

@@ -12,7 +12,7 @@ fal_partition_t fal_root_part = NULL;
// Arduino framework initialization.
// May be redefined by family files.
void init() __attribute__((weak));
void initArduino() __attribute__((weak));
// Weak empty variant initialization function.
// May be redefined by variant files.
@@ -36,7 +36,7 @@ int main(void) {
// print a startup banner
LT_BANNER();
// initialize Arduino framework
init();
initArduino();
// initialize C library
__libc_init_array();
// optionally initialize per-variant code

View File

@@ -26,4 +26,7 @@ enum ChipType {
RTL8710L0 = CHIP_TYPE(F_RTL8710B, 0xFB), // CHIPID_8710BN_L0 / QFN32
RTL8711BN = CHIP_TYPE(F_RTL8710B, 0xFD), // CHIPID_8711BN / QFN48
RTL8711BU = CHIP_TYPE(F_RTL8710B, 0xFC), // CHIPID_8711BG / QFN68
// Beken 72XX
BK7231T = CHIP_TYPE(F_BK7231T, 0x1A), // *SCTRL_CHIP_ID = 0x7231a
BK7231N = CHIP_TYPE(F_BK7231N, 0x1C), // *SCTRL_CHIP_ID = 0x7231c
};

View File

@@ -54,6 +54,23 @@
#define LT_LOG_ERRNO 0
#endif
// Serial output options
#ifndef LT_UART_SILENT_ENABLED
#define LT_UART_SILENT_ENABLED 1
#endif
#ifndef LT_UART_SILENT_ALL
#define LT_UART_SILENT_ALL 0
#endif
#ifndef LT_UART_DEFAULT_LOGGER
#define LT_UART_DEFAULT_LOGGER LT_UART_DEFAULT_PORT
#endif
#ifndef LT_UART_DEFAULT_SERIAL
#define LT_UART_DEFAULT_SERIAL LT_UART_DEFAULT_PORT
#endif
// Per-module debugging
#ifndef LT_DEBUG_WIFI
#define LT_DEBUG_WIFI 0

View File

@@ -0,0 +1,25 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-04. */
#pragma once
#include <Arduino.h>
#ifdef HAS_SERIAL_CLASS // failsafe for circular inclusion
#ifdef PIN_SERIAL0_TX
extern SerialClass Serial0;
#endif
#ifdef PIN_SERIAL1_TX
extern SerialClass Serial1;
#endif
#ifdef PIN_SERIAL2_TX
extern SerialClass Serial2;
#endif
#define SerialN(x) Serial##x
#define SerialM(x) SerialN(x)
#define Serial SerialM(LT_UART_DEFAULT_SERIAL)
#endif

View File

@@ -3,6 +3,7 @@
#include "lt_logger.h"
#include <Arduino.h>
#include <printf/printf.h>
#if LT_LOGGER_TASK && LT_HAS_FREERTOS
#include <FreeRTOS.h>
@@ -27,10 +28,11 @@
#define COLOR_BRIGHT_CYAN 0x16
#define COLOR_BRIGHT_WHITE 0x17
const char levels[] = {'V', 'D', 'I', 'W', 'E', 'F'};
static uint32_t uart_port = LT_UART_DEFAULT_LOGGER;
static const char levels[] = {'V', 'D', 'I', 'W', 'E', 'F'};
#if LT_LOGGER_COLOR
const uint8_t colors[] = {
static const uint8_t colors[] = {
COLOR_BRIGHT_CYAN,
COLOR_BRIGHT_BLUE,
COLOR_BRIGHT_GREEN,
@@ -72,7 +74,10 @@ void lt_log(const uint8_t level, const char *format, ...) {
char c_value = '0' + (colors[level] & 0x7);
#endif
printf(
fctprintf(
(void (*)(char, void *))putchar_p,
(void *)uart_port,
// format:
#if LT_LOGGER_COLOR
"\e[%c;3%cm"
#endif
@@ -94,6 +99,7 @@ void lt_log(const uint8_t level, const char *format, ...) {
"%s%c "
#endif
,
// arguments:
#if LT_LOGGER_COLOR
c_bright, // whether text is bright
c_value, // text color
@@ -121,7 +127,12 @@ void lt_log(const uint8_t level, const char *format, ...) {
va_list va_args;
va_start(va_args, format);
vprintf(format, va_args);
vfctprintf((void (*)(char, void *))putchar_p, (void *)uart_port, format, va_args);
va_end(va_args);
printf("\r\n");
putchar_p('\r', uart_port);
putchar_p('\n', uart_port);
}
void lt_log_set_port(uint8_t port) {
uart_port = port;
}

View File

@@ -13,6 +13,13 @@ void lt_log(const uint8_t level, const char *caller, const unsigned short line,
void lt_log(const uint8_t level, const char *format, ...);
#endif
/**
* @brief Change log output port.
*
* @param port UART port index - can be 0, 1 or 2
*/
void lt_log_set_port(uint8_t port);
#if LT_LEVEL_TRACE >= LT_LOGLEVEL
#define LT_T(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)
#define LT_V(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__)

View File

@@ -2,6 +2,8 @@
#pragma once
#include <LibreTuyaConfig.h>
#define PRINTF_HAS_DISABLE 1
// make printf.c define wrapper functions
@@ -12,12 +14,33 @@
#define vsnprintf_ __wrap_vsnprintf
#define vprintf_ __wrap_vprintf
// 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); \
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_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() { \
@@ -39,6 +62,24 @@
return 0; \
}
#endif // LT_UART_SILENT_ENABLED && !LT_UART_SILENT_ALL
#if LT_UART_SILENT_ALL
#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; \
}
#else // !LT_UART_SILENT_ALL
#define WRAP_PRINTF(name) \
WRAP_DISABLE_DECL(name) \
int __wrap_##name(const char *format, ...) { \
@@ -50,6 +91,15 @@
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); \
}
#endif // !LT_UART_SILENT_ALL
#define WRAP_SPRINTF(name) \
int __wrap_##name(char *s, const char *format, ...) { \
va_list va; \
@@ -68,13 +118,6 @@
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_VSPRINTF(name) \
int __wrap_##name(char *s, const char *format, va_list arg) { \
return vsprintf(s, format, arg); \

View File

@@ -16,7 +16,19 @@
// Include board variant
#include "variant.h"
#ifdef __cplusplus
#include "LOGUARTClass.h"
extern LOGUARTClass Serial;
// Choose the main UART output port
#ifndef LT_UART_DEFAULT_PORT
#if defined(PIN_SERIAL2_TX)
#define LT_UART_DEFAULT_PORT 2
#elif defined(PIN_SERIAL0_TX)
#define LT_UART_DEFAULT_PORT 0
#else
#define LT_UART_DEFAULT_PORT 1
#endif
#endif
// Define available serial ports
#ifdef __cplusplus
#include "SerialClass.h"
#include <core/SerialExtern.h>
#endif

View File

@@ -1,98 +0,0 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "LOGUARTClass.h"
#include <Arduino.h>
#define LOG_UART_MODIFIABLE_BAUD_RATE 1
RingBuffer rx_buffer0;
LOGUARTClass::LOGUARTClass(int dwIrq, RingBuffer *pRx_buffer) {
_rx_buffer = pRx_buffer;
_dwIrq = dwIrq;
}
void IrqHandler(void) {
uint8_t data = 0;
BOOL PullMode = _FALSE;
uint32_t IrqEn = DiagGetIsrEnReg();
DiagSetIsrEnReg(0);
data = DiagGetChar(PullMode);
if (data > 0)
rx_buffer0.store_char(data);
DiagSetIsrEnReg(IrqEn);
}
void LOGUARTClass::begin(const uint32_t dwBaudRate) {
DIAG_UartReInit((IRQ_FUN)IrqHandler);
NVIC_SetPriority(UART_LOG_IRQ, 10);
LOGUART_SetBaud(dwBaudRate);
}
void LOGUARTClass::end(void) {
// clear any received data
_rx_buffer->_iHead = _rx_buffer->_iTail;
}
int LOGUARTClass::available(void) {
return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE;
}
int LOGUARTClass::peek(void) {
if (_rx_buffer->_iHead == _rx_buffer->_iTail)
return -1;
return _rx_buffer->_aucBuffer[_rx_buffer->_iTail];
}
int LOGUARTClass::read(void) {
// if the head isn't ahead of the tail, we don't have any characters
if (_rx_buffer->_iHead == _rx_buffer->_iTail)
return -1;
uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail];
_rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE;
return uc;
}
void LOGUARTClass::flush(void) {
// TODO:
// while ( serial_writable(&(this->sobj)) != 1 );
/*
// Wait for transmission to complete
while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY)
;
*/
}
size_t LOGUARTClass::write(const uint8_t uc_data) {
DiagPutChar(uc_data);
return 1;
}
LOGUARTClass Serial(UART_LOG_IRQ, &rx_buffer0);
bool Serial_available() {
return Serial.available() > 0;
}

View File

@@ -1,58 +0,0 @@
/*
Copyright (c) 2011 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <api/HardwareSerial.h>
#include <api/RingBuffer.h>
using namespace arduino;
// TODO this class begs to be rewritten :(
class LOGUARTClass : public HardwareSerial {
public:
LOGUARTClass(int dwIrq, RingBuffer *pRx_buffer);
void begin(const uint32_t dwBaudRate);
inline void begin(const uint32_t dwBaudRate, uint16_t config) {
begin(dwBaudRate); // TODO implement this properly
}
void end(void);
int available(void);
int peek(void);
int read(void);
void flush(void);
size_t write(const uint8_t c);
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool() {
return true; // UART always active
}
protected:
RingBuffer *_rx_buffer;
int _dwIrq;
private:
friend bool Serial_available();
};

View File

@@ -43,6 +43,7 @@ uint32_t LibreTuya::getChipId() {
// TODO do what EFUSE_LogicalMapRead() does, and read only the used data
EFUSE_LogicalMap_Read(efuse);
memcpy(id, efuse + 0x11A + 3, 3);
free(efuse);
return chipId;
}

View File

@@ -0,0 +1,98 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#include "SerialClass.h"
#ifdef PIN_SERIAL0_TX
SerialClass Serial0(UART0_DEV, UART0_IRQ, PIN_SERIAL0_RX, PIN_SERIAL0_TX);
#endif
#ifdef PIN_SERIAL1_TX
SerialClass Serial1(UART1_DEV, UART1_IRQ, PIN_SERIAL1_RX, PIN_SERIAL1_TX);
#endif
#ifdef PIN_SERIAL2_TX
SerialClass Serial2(UART2_DEV, UART_LOG_IRQ, PIN_SERIAL2_RX, PIN_SERIAL2_TX);
#endif
SerialClass::SerialClass(UART_TypeDef *uart, IRQn irq, pin_size_t rx, pin_size_t tx) {
data.uart = uart;
data.buf = NULL;
this->irq = irq;
this->rx = rx;
this->tx = tx;
}
static uint32_t callback(void *param) {
SerialData *data = (SerialData *)param;
uint32_t intcr = data->uart->DLH_INTCR;
data->uart->DLH_INTCR = 0;
uint8_t c;
UART_CharGet(data->uart, &c);
if (c)
data->buf->store_char(c);
data->uart->DLH_INTCR = intcr;
return 0;
}
void SerialClass::begin(unsigned long baudrate, uint16_t config) {
// RUART_WLS_7BITS / RUART_WLS_8BITS
uint8_t dataWidth = (config & SERIAL_DATA_MASK) == SERIAL_DATA_8;
// RUART_PARITY_DISABLE / RUART_PARITY_ENABLE
uint8_t parity = (config & SERIAL_PARITY_MASK) != SERIAL_PARITY_NONE;
// RUART_ODD_PARITY / RUART_EVEN_PARITY
uint8_t parityType = (config & SERIAL_PARITY_MASK) == SERIAL_PARITY_EVEN;
// RUART_STOP_BIT_1 / RUART_STOP_BIT_2
uint8_t stopBits = (config & SERIAL_STOP_BIT_MASK) == SERIAL_STOP_BIT_2;
UART_InitTypeDef cfg;
UART_StructInit(&cfg);
cfg.WordLen = dataWidth;
cfg.Parity = parity;
cfg.ParityType = parityType;
cfg.StopBit = stopBits;
UART_Init(data.uart, &cfg);
UART_SetBaud(data.uart, baudrate);
if (data.buf) {
data.buf->clear();
} else {
data.buf = new RingBuffer();
}
Pinmux_Config(pinInfo(this->rx)->gpio, PINMUX_FUNCTION_UART);
Pinmux_Config(pinInfo(this->tx)->gpio, PINMUX_FUNCTION_UART);
VECTOR_IrqUnRegister(this->irq);
VECTOR_IrqRegister(callback, this->irq, (uint32_t)&data, 10);
}
void SerialClass::end() {
if (data.uart == UART2_DEV) {
// restore command line mode
DIAG_UartReInit((IRQ_FUN)UartLogIrqHandle);
}
delete data.buf;
}
int SerialClass::available() {
return data.buf->available();
}
int SerialClass::peek() {
return data.buf->peek();
}
int SerialClass::read() {
return data.buf->read_char();
}
void SerialClass::flush() {
UART_WaitBusy(data.uart, 10);
}
size_t SerialClass::write(uint8_t c) {
while (UART_Writable(data.uart) == 0) {}
UART_CharPut(data.uart, c);
return 1;
}

View File

@@ -0,0 +1,46 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#pragma once
#include <Arduino.h>
#include <api/HardwareSerial.h>
#include <api/RingBuffer.h>
using namespace arduino;
typedef struct {
UART_TypeDef *uart;
RingBuffer *buf;
} SerialData;
class SerialClass : public HardwareSerial {
private:
// data accessible to IRQ handler
SerialData data;
IRQn irq;
pin_size_t rx;
pin_size_t tx;
public:
SerialClass(UART_TypeDef *uart, IRQn irq, pin_size_t rx, pin_size_t tx);
inline void begin(unsigned long baudrate) {
begin(baudrate, SERIAL_8N1);
}
void begin(unsigned long baudrate, uint16_t config);
void end();
int available();
int peek();
int read();
void flush();
size_t write(uint8_t c);
operator bool() {
return !!data.buf;
}
using Print::write;
};
#define HAS_SERIAL_CLASS 1

View File

@@ -1,37 +1,25 @@
/*
main.cpp - Main loop for Arduino sketches
Copyright (c) 2005-2013 Arduino Team. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#define ARDUINO_MAIN
/* Copyright (c) Kuba Szczodrzyński 2022-06-19. */
#include <Arduino.h>
#include <cmsis_os.h>
osThreadId main_tid = 0;
extern "C" {
#include <cmsis_os.h>
extern uint32_t GlobalDebugEnable;
extern uint16_t GlobalDebugLevel;
extern uint8_t GlobalPrivateLog;
extern uint8_t lt_uart_port;
void init() {
} // extern "C"
osThreadId main_tid = 0;
void initArduino() {
// make the SDK less verbose by default
GlobalDebugEnable = 0;
GlobalPrivateLog = 0;
lt_uart_port = LT_UART_DEFAULT_PORT;
}
bool startMainTask() {

View File

@@ -0,0 +1,99 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#include "SoftwareSerial.h"
extern "C" {
#include <timer_api.h>
} // extern "C"
#define TIMER_MAX 3
#define OBJ ((gtimer_t *)this->param)
static uint32_t timNum[TIMER_MAX] = {TIMER1, TIMER2, TIMER3};
static gtimer_t *timObj[TIMER_MAX] = {NULL, NULL, NULL};
static void callback(SoftSerial *data) {
SoftData *tx = &data->tx;
switch (tx->state) {
case SS_IDLE:
goto finish;
case SS_END:
case SS_START:
if (!tx->buf->available())
goto finish;
tx->byte = tx->buf->read_char();
digitalWrite(tx->pin, LOW);
tx->state = SS_DATA0;
return;
case SS_STOP:
digitalWrite(tx->pin, HIGH);
break;
default:
digitalWrite(tx->pin, (tx->byte & 0x1) ^ data->invert);
tx->byte /= 2;
break;
}
tx->state = (SoftState)(tx->state + 1);
return;
finish:
gtimer_stop((gtimer_t *)data->param);
data->tx.state = SS_IDLE;
return;
}
void SoftwareSerial::begin(unsigned long baudrate, uint16_t config) {
if (data.rx.buf || data.tx.buf)
return;
uint8_t i;
for (i = 0; i < TIMER_MAX; i++) {
if (timObj[i] == NULL)
break;
}
if (i == TIMER_MAX) {
LT_E("No more timers for SoftwareSerial");
return;
}
pinMode(data.tx.pin, OUTPUT);
digitalWrite(data.tx.pin, HIGH);
data.rx.buf = new RingBuffer();
data.tx.buf = new RingBuffer();
data.rx.state = SS_IDLE;
data.tx.state = SS_IDLE;
uint32_t us = 1E6 / baudrate;
timObj[i] = (gtimer_t *)malloc(sizeof(gtimer_t));
param = data.param = data.tx.param = timObj[i];
gtimer_init(OBJ, timNum[i]);
OBJ->is_periodcal = true;
OBJ->handler = (void *)callback;
OBJ->hid = (uint32_t)&data;
gtimer_reload(OBJ, us);
}
void SoftwareSerial::end() {
gtimer_stop(OBJ);
gtimer_deinit(OBJ);
free(OBJ);
delete data.rx.buf;
delete data.tx.buf;
}
void SoftwareSerial::startTx() {
gtimer_start(OBJ);
}
void SoftwareSerial::endTx() {
gtimer_stop(OBJ);
}

View File

@@ -0,0 +1,5 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-03. */
#pragma once
#include <api/SoftwareSerial.h>

View File

@@ -9,22 +9,14 @@ typedef struct {
bool WiFiClass::softAP(const char *ssid, const char *passphrase, int channel, bool ssidHidden, int maxClients) {
if (!enableAP(true))
return false;
return WL_CONNECT_FAILED;
if (!validate(ssid, passphrase))
return WL_CONNECT_FAILED;
LT_HEAP_I();
vTaskDelay(20);
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
LT_W("SSID not specified or too long");
return false;
}
if (passphrase && strlen(passphrase) < 8) {
LT_W("Passphrase too short");
return false;
}
strcpy((char *)ap.ssid.val, ssid);
ap.ssid.len = strlen(ssid);
ap.channel = channel;

View File

@@ -63,6 +63,9 @@ void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handl
}
} // extern "C"
// TODO queue handling is apparently done all wrong here
// (passing pointers to pointers in xQueueSend/xQueueReceive)
// function called by wext_wlan_indicate
void wifi_indication(rtw_event_indicate_t event, char *buf, int buf_len, int flags) {
LT_HEAP_I();
@@ -104,7 +107,7 @@ static void wifiEventTask(void *arg) {
void startWifiTask() {
if (!wifiEventQueueHandle) {
LT_HEAP_I();
wifiEventQueueHandle = xQueueCreate(32, sizeof(Event_t *));
wifiEventQueueHandle = xQueueCreate(32, sizeof(rtw_event_t *));
LT_HEAP_I();
}
if (!wifiEventTaskHandle) {

View File

@@ -6,19 +6,11 @@ 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();
if (!ssid || *ssid == 0x00 || strlen(ssid) > 32) {
LT_W("SSID not specified or too long");
return WL_CONNECT_FAILED;
}
if (passphrase && strlen(passphrase) > 64) {
LT_W("Passphrase too long");
return WL_CONNECT_FAILED;
}
memset(wifi.bssid.octet, 0, ETH_ALEN);
strcpy((char *)wifi.ssid.val, ssid);
wifi.ssid.len = strlen(ssid);
@@ -153,9 +145,14 @@ IPAddress WiFiClass::localIP() {
}
uint8_t *WiFiClass::macAddress(uint8_t *mac) {
uint8_t *macLocal = LwIP_GetMAC(NETIF_RTW_STA);
memcpy(mac, macLocal, ETH_ALEN);
free(macLocal);
if (getMode() == WIFI_MODE_NULL) {
uint8_t *efuse = (uint8_t *)malloc(512);
EFUSE_LogicalMap_Read(efuse);
memcpy(mac, efuse + 0x11A, ETH_ALEN);
free(efuse);
return mac;
}
memcpy(mac, LwIP_GetMAC(NETIF_RTW_STA), ETH_ALEN);
return mac;
}

View File

@@ -7,10 +7,29 @@
#include <stdint.h>
#include <stdio.h>
extern void LOGUART_PutChar(char c);
#define LOG_UART_REG_BASE 0x40003000
#define UART0_REG_BASE 0x40040000
#define UART1_REG_BASE 0x40040400
#define UART2_REG_BASE LOG_UART_REG_BASE
extern uint32_t UART_Writable(void *UARTx);
extern void UART_CharPut(void *UARTx, uint8_t TxData);
static const void *uart_dev[3] = {
UART0_REG_BASE,
UART1_REG_BASE,
LOG_UART_REG_BASE,
};
uint8_t lt_uart_port = 2;
void putchar_(char c) {
LOGUART_PutChar(c);
putchar_p(c, lt_uart_port);
}
void putchar_p(char c, unsigned long port) {
while (UART_Writable(uart_dev[port]) == 0) {}
UART_CharPut(uart_dev[port], c);
}
WRAP_PRINTF(rtl_printf);

View File

@@ -1,6 +1,7 @@
<!-- This file is auto-generated -->
- [BW12](../boards/bw12/README.md)
- [CB2S Wi-Fi Module](../boards/cb2s/README.md)
- [WB2L Wi-Fi Module](../boards/wb2l/README.md)
- [WR3 Wi-Fi Module](../boards/wr3/README.md)
- [Generic - Host-native](../boards/generic-native/README.md)

View File

@@ -0,0 +1,24 @@
{
"build": {
"bkcrypt_coeffs": "510fb093a3cbeadc5993a17ec7adeb03",
"bkboot_version": "1.0.1-bk7231n",
"bkrbl_size_app": "0x107800"
},
"flash": {
"bootloader": "0x000000+0x11000",
"app": "0x011000+0x119000",
"download": "0x12A000+0xA6000",
"tlv": "0x1D0000+0x1000",
"net": "0x1D1000+0x2000",
"kvs": "0x1D3000+0x8000",
"userdata": "0x1DB000+0x25000"
},
"upload": {
"maximum_size": 1083136
},
"doc": {
"extra": [
"Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes."
]
}
}

View File

@@ -0,0 +1,17 @@
{
"build": {
"family": "BK7231N",
"ldscript_sdk": "bk7231n_bsp.ld",
"ldscript_arduino": "bk7231n_bsp.ld"
},
"upload": {
"speed": 460800
},
"doc": {
"params": {
"extra": {
"Bluetooth": "BLE v5.1"
}
}
}
}

View File

@@ -4,6 +4,9 @@
"ldscript_sdk": "bk7231_bsp.ld",
"ldscript_arduino": "bk7231_bsp.ld"
},
"upload": {
"speed": 921600
},
"doc": {
"params": {
"extra": {

View File

@@ -25,7 +25,6 @@
"maximum_ram_size": 262144,
"flash_size": 2097152,
"require_upload_port": true,
"speed": 921600,
"protocol": "uart",
"protocols": [
"uart"

View File

@@ -0,0 +1,60 @@
{
"pcb": {
"scale": 11,
"test_pads": {
"TTX2": "cb2s.back.u2_txd.anchor",
"TRX2": "cb2s.back.u2_rxd.anchor",
"TCSN": "cb2s.back.csn.anchor"
},
"back": [
{
"type": "rect",
"pos": "6.0,8.9",
"size": "2.9,2.9",
"preset": "copper1"
},
{
"id": "u2_txd",
"name": "label_line_2mm_up",
"pos": "6.7,6.1",
"vars": {
"DIR": "left",
"W": 2.5,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "7.5,6.0"
},
{
"id": "u2_rxd",
"name": "label_line_2mm_up",
"pos": "6.2,8.1",
"vars": {
"DIR": "left",
"W": 2.0,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "7.0,8.0"
},
{
"id": "csn",
"name": "label_line_2mm_up",
"pos": "4.2,11.1",
"vars": {
"DIR": "left",
"W": 0,
"H": 0
}
},
{
"name": "test_pad_1mm",
"pos": "5.0,11.0"
}
]
}
}

View File

@@ -0,0 +1,74 @@
{
"pcb": {
"templates": [
"tuya2",
"rf-15mm-type1",
"tuya2-shield"
],
"vars": {
"MASK_PRESET": "mask_blue_light",
"TRACE_COLOR": "#58839B",
"SILK_COLOR": "white",
"PINTYPE_HORZ": "pin_horz_2mm_cast_hole"
},
"pinout_hidden": "I2S,JTAG,FLASH",
"pinout": {
"1": {
"PWR": 3.3
},
"2": {
"IC": 22,
"ARD": "D0"
},
"3": {
"GND": null
},
"4": {
"IC": 23,
"ARD": "D1"
},
"5": {
"IC": 26,
"ARD": "D4"
},
"6": {
"IC": 24,
"ARD": "D2"
},
"7": {
"IC": 27,
"ARD": "D5"
},
"8": {
"IC": 17,
"ARD": [
"D3",
"A0"
]
},
"9": {
"IC": 16,
"ARD": "D6"
},
"10": {
"IC": 21
},
"11": {
"IC": 15,
"ARD": "D7"
},
"TRX2": {
"IC": 28,
"ARD": "D9"
},
"TTX2": {
"IC": 29,
"ARD": "D8"
},
"TCSN": {
"IC": 19,
"ARD": "D10"
}
}
}
}

20
boards/cb2s.json Normal file
View File

@@ -0,0 +1,20 @@
{
"_base": [
"beken-72xx",
"beken-7231n",
"beken-7231n-tuya",
"pcb/ic-bk7231-qfn32",
"pcb/cb2s",
"pcb/cb2s-test"
],
"build": {
"mcu": "bk7231n",
"variant": "cb2s"
},
"name": "CB2S Wi-Fi Module",
"url": "https://developer.tuya.com/en/docs/iot/cb2s-module-datasheet?id=Kafgfsa2aaypq",
"vendor": "Tuya Inc.",
"pcb": {
"symbol": "CB2S"
}
}

61
boards/cb2s/README.md Normal file
View File

@@ -0,0 +1,61 @@
# CB2S Wi-Fi Module
*by Tuya Inc.*
[Product page](https://developer.tuya.com/en/docs/iot/cb2s-module-datasheet?id=Kafgfsa2aaypq)
- [General info](../../docs/platform/beken-72xx/README.md)
- [Flashing (Tuya manual)](https://developer.tuya.com/en/docs/iot/burn-and-authorize-wb-series-modules?id=Ka78f4pttsytd)
- [BkWriter v1.6.0](https://images.tuyacn.com/smart/bk_writer1.60/bk_writer1.60.exe)
Parameter | Value
-------------|----------------------------------
MCU | BK7231N
Manufacturer | Beken
Series | BK72XX
Frequency | 120 MHz
Flash size | 2 MiB
RAM size | 256 KiB
Voltage | 3.0V - 3.6V
I/O | 11x GPIO, 5x PWM, 2x UART, 1x ADC
Wi-Fi | 802.11 b/g/n
Bluetooth | BLE v5.1
## Pinout
![Pinout](pinout_cb2s.svg)
## Arduino Core pin mapping
No. | Pin | UART | I²C | SPI | PWM | Other
----|-----------|----------|----------|-----|------|------
D0 | P6 | | | | PWM0 |
D1 | P7 | | | | PWM1 |
D2 | P8 | | | | PWM2 |
D3 | P23 | | | | | TDO
D4 | P10 | UART1_RX | | | |
D5 | P11 | UART1_TX | | | |
D6 | P24 | | | | PWM4 |
D7 | P26 | | | | PWM5 |
D8 | P0 | UART2_TX | I2C2_SCL | | |
D9 | P1 | UART2_RX | I2C2_SDA | | |
D10 | P21 | | I2C1_SDA | | | TMS
A0 | P23, ADC3 | | | | |
## Flash memory map
Flash size: 2 MiB / 2,097,152 B / 0x200000
Hex values are in bytes.
Name | Start | Length | End
----------------|----------|--------------------|---------
Bootloader | 0x000000 | 68 KiB / 0x11000 | 0x011000
App Image | 0x011000 | 1.1 MiB / 0x119000 | 0x12A000
OTA Image | 0x12A000 | 664 KiB / 0xA6000 | 0x1D0000
TLV Store | 0x1D0000 | 4 KiB / 0x1000 | 0x1D1000
Network Data | 0x1D1000 | 8 KiB / 0x2000 | 0x1D3000
Key-Value Store | 0x1D3000 | 32 KiB / 0x8000 | 0x1DB000
User Data | 0x1DB000 | 148 KiB / 0x25000 | 0x200000
Bootloader and app partitions contain CRC16 sums every 32 bytes. That results in the actual flash offsets/sizes not aligned to sector boundaries. To simplify calculations, the values shown in the table (extracted from bootloader's partition table) were aligned to 4096 bytes.

276
boards/cb2s/pinout_cb2s.svg Normal file
View File

@@ -0,0 +1,276 @@
<?xml version="1.0" encoding="utf-8" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" baseProfile="full" height="500" version="1.1" viewBox="0,0,93.0909090909091,45.45454545454545" width="1024">
<defs/>
<rect fill="white" height="45.45454545454545" stroke="black" stroke-width="0.1" width="93.0909090909091" x="0" y="0"/>
<linearGradient gradientUnits="objectBoundingBox" id="id1" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#47a8cd"/>
<stop offset="100%" stop-color="#008fb5"/>
</linearGradient>
<rect fill="url(#id1) none" height="17.799999999999997" stroke="#b5a739" stroke-width="0.1" width="14.9" x="16.32272727272727" y="10.377272727272727"/>
<rect fill="#b5a739" height="0.1" width="1.6" x="16.27272727272727" y="24.677272727272726"/>
<rect fill="#b5a739" height="3.45" width="0.1" x="17.87272727272727" y="24.677272727272726"/>
<rect fill="#fff" height="3.55" width="1.7" x="16.17272727272727" y="24.777272727272724"/>
<rect fill="#b5a739" height="0.1" width="1.6" x="29.57272727272727" y="24.677272727272726"/>
<rect fill="#b5a739" height="3.45" width="0.1" x="29.57272727272727" y="24.677272727272726"/>
<rect fill="#fff" height="3.55" width="1.7" x="29.672727272727272" y="24.777272727272724"/>
<rect fill="#e5b472" height="2.5" id="pads_horz5_2mm.pin1.pad" rx="0.2" ry="0.2" width="1.0" x="19.27272727272727" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz5_2mm.pin2.pad" rx="0.2" ry="0.2" width="1.0" x="21.27272727272727" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz5_2mm.pin3.pad" rx="0.2" ry="0.2" width="1.0" x="23.27272727272727" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz5_2mm.pin4.pad" rx="0.2" ry="0.2" width="1.0" x="25.27272727272727" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz5_2mm.pin5.pad" rx="0.2" ry="0.2" width="1.0" x="27.27272727272727" y="25.377272727272725"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="19.67272727272727" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="19.47272727272727" y="30.227272727272727"/>
<rect height="0.0" id="tuya2.front.pins.label1.anchor" width="0.0" x="19.97272727272727" y="30.327272727272728"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="21.672727272727272" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="19.47272727272727" y="32.22727272727273"/>
<rect height="0.0" id="tuya2.front.pins.label2.anchor" width="0.0" x="19.97272727272727" y="32.32727272727273"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="23.672727272727272" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="19.47272727272727" y="34.22727272727273"/>
<rect height="0.0" id="tuya2.front.pins.label3.anchor" width="0.0" x="19.97272727272727" y="34.32727272727273"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="25.672727272727272" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="25.77272727272727" y="34.22727272727273"/>
<rect height="0.0" id="tuya2.front.pins.label4.anchor" width="0.0" x="29.47272727272727" y="34.32727272727273"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="27.672727272727272" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="27.77272727272727" y="32.22727272727273"/>
<rect height="0.0" id="tuya2.front.pins.label5.anchor" width="0.0" x="29.47272727272727" y="32.32727272727273"/>
<text fill="#fff" font-family="Consolas" font-size="1.0" x="23.27272727272727" y="15.327272727272726">CB2S</text>
<rect fill="#58839b" height="5.2" width="0.5" x="17.07272727272727" y="10.827272727272726"/>
<rect fill="#58839b" height="0.5" width="4.6" x="17.07272727272727" y="10.827272727272726"/>
<rect fill="#58839b" height="5.2" width="0.5" x="19.27272727272727" y="10.827272727272726"/>
<rect fill="#58839b" height="3.0" width="0.5" x="21.172727272727272" y="10.827272727272726"/>
<rect fill="#58839b" height="0.5" width="3.0" x="21.172727272727272" y="13.327272727272726"/>
<rect fill="#58839b" height="3.0" width="0.5" x="23.672727272727272" y="10.827272727272726"/>
<rect fill="#58839b" height="0.5" width="2.7" x="23.672727272727272" y="10.827272727272726"/>
<rect fill="#58839b" height="3.0" width="0.5" x="25.872727272727268" y="10.827272727272726"/>
<rect fill="#58839b" height="0.5" width="3.0" x="25.872727272727268" y="13.327272727272726"/>
<rect fill="#58839b" height="3.0" width="0.5" x="28.372727272727268" y="10.827272727272726"/>
<rect fill="#58839b" height="0.5" width="2.5" x="28.372727272727268" y="10.827272727272726"/>
<rect fill="#58839b" height="4.4" width="0.5" x="30.372727272727268" y="10.827272727272726"/>
<linearGradient gradientUnits="objectBoundingBox" id="id2" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="whitesmoke"/>
<stop offset="100%" stop-color="#999"/>
</linearGradient>
<rect fill="url(#id2) none" height="8.0" rx="0.5" ry="0.5" width="14.4" x="16.57272727272727" y="16.327272727272728"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="29.97272727272727" y="32.22727272727273"/>
<g transform="translate(33.38708662667217,31.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="34.872727272727275" y="32.32727272727273">P6</text>
<g transform="translate(36.98708662667217,31.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="38.17272727272727" y="32.32727272727273">D0</text>
<g transform="translate(39.98708662667217,31.527272727272727)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="41.472727272727276" y="32.32727272727273">PWM0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="29.97272727272727" y="34.22727272727273"/>
<g transform="translate(33.38708662667217,33.52727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="34.872727272727275" y="34.32727272727273">P7</text>
<g transform="translate(36.98708662667217,33.52727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="38.17272727272727" y="34.32727272727273">D1</text>
<g transform="translate(39.98708662667217,33.52727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="41.472727272727276" y="34.32727272727273">PWM1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.872727272727268" y="34.22727272727273"/>
<g transform="translate(13.087086626672166,33.52727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="14.572727272727267" y="34.32727272727273">P8</text>
<g transform="translate(10.087086626672168,33.52727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="11.27272727272727" y="34.32727272727273">D2</text>
<g transform="translate(6.487086626672168,33.52727272727273)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.97272727272727" y="34.32727272727273">PWM2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.872727272727268" y="32.22727272727273"/>
<g transform="translate(13.08708662667217,31.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="14.57272727272727" y="32.32727272727273">P23</text>
<g transform="translate(9.487086626672168,31.527272727272727)">
<rect fill="#8ad039" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="10.972727272727269" y="32.32727272727273">ADC3</text>
<g transform="translate(6.487086626672168,31.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="7.67272727272727" y="32.32727272727273">D3</text>
<g transform="translate(3.4870866266721685,31.527272727272727)">
<rect fill="#16a352" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="4.67272727272727" y="32.32727272727273">A0</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="16.872727272727268" y="30.227272727272727"/>
<g transform="translate(13.08708662667217,29.527272727272727)">
<rect fill="#ed602e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="14.57272727272727" y="30.327272727272728">CEN</text>
<linearGradient gradientUnits="objectBoundingBox" id="id3" x1="1.0" x2="0.0" y1="0.0" y2="1.0">
<stop offset="0%" stop-color="#47a8cd"/>
<stop offset="100%" stop-color="#008fb5"/>
</linearGradient>
<rect fill="url(#id3) none" height="17.799999999999997" stroke="#b5a739" stroke-width="0.1" width="14.9" x="61.543181818181814" y="10.377272727272727"/>
<rect fill="#b5a739" height="0.1" width="1.6" x="61.49318181818182" y="24.677272727272726"/>
<rect fill="#b5a739" height="3.45" width="0.1" x="63.09318181818182" y="24.677272727272726"/>
<rect fill="#fff" height="3.55" width="1.7" x="61.393181818181816" y="24.777272727272724"/>
<rect fill="#b5a739" height="0.1" width="1.6" x="74.79318181818182" y="24.677272727272726"/>
<rect fill="#b5a739" height="3.45" width="0.1" x="74.79318181818182" y="24.677272727272726"/>
<rect fill="#fff" height="3.55" width="1.7" x="74.89318181818182" y="24.777272727272724"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin1.pad" rx="0.2" ry="0.2" width="1.0" x="63.44318181818182" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin2.pad" rx="0.2" ry="0.2" width="1.0" x="65.44318181818181" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin3.pad" rx="0.2" ry="0.2" width="1.0" x="67.44318181818181" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin4.pad" rx="0.2" ry="0.2" width="1.0" x="69.44318181818181" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin5.pad" rx="0.2" ry="0.2" width="1.0" x="71.44318181818181" y="25.377272727272725"/>
<rect fill="#e5b472" height="2.5" id="pads_horz6_2mm.pin6.pad" rx="0.2" ry="0.2" width="1.0" x="73.44318181818181" y="25.377272727272725"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="63.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="63.643181818181816" y="30.227272727272727"/>
<rect height="0.0" id="tuya2.back.pins.label1.anchor" width="0.0" x="64.14318181818182" y="30.327272727272728"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="65.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="63.643181818181816" y="32.22727272727273"/>
<rect height="0.0" id="tuya2.back.pins.label2.anchor" width="0.0" x="64.14318181818182" y="32.32727272727273"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="67.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="63.643181818181816" y="34.22727272727273"/>
<rect height="0.0" id="tuya2.back.pins.label3.anchor" width="0.0" x="64.14318181818182" y="34.32727272727273"/>
<rect fill="#4e4c4c" height="6.0" width="0.2" x="69.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="4.2" x="69.94318181818181" y="34.22727272727273"/>
<rect height="0.0" id="tuya2.back.pins.label4.anchor" width="0.0" x="73.64318181818182" y="34.32727272727273"/>
<rect fill="#4e4c4c" height="4.0" width="0.2" x="71.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="71.94318181818181" y="32.22727272727273"/>
<rect height="0.0" id="tuya2.back.pins.label5.anchor" width="0.0" x="73.64318181818182" y="32.32727272727273"/>
<rect fill="#4e4c4c" height="2.0" width="0.2" x="73.84318181818182" y="28.427272727272722"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="73.94318181818181" y="30.227272727272727"/>
<rect height="0.0" id="tuya2.back.pins.label6.anchor" width="0.0" x="73.64318181818182" y="30.327272727272728"/>
<rect fill="#e5b472" height="2.9" width="2.9" x="67.49318181818182" y="19.227272727272727"/>
<rect fill="#4e4c4c" height="0.0" width="0.2" x="68.09318181818182" y="16.227272727272727"/>
<rect fill="#4e4c4c" height="0.2" width="2.7" x="65.39318181818182" y="16.227272727272727"/>
<rect height="0.0" id="cb2s.back.u2_txd.anchor" width="0.0" x="65.89318181818182" y="16.327272727272728"/>
<circle cx="68.99318181818182" cy="16.327272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="0.0" width="0.2" x="67.59318181818182" y="18.227272727272727"/>
<rect fill="#4e4c4c" height="0.2" width="2.2" x="65.39318181818182" y="18.227272727272727"/>
<rect height="0.0" id="cb2s.back.u2_rxd.anchor" width="0.0" x="65.89318181818182" y="18.327272727272728"/>
<circle cx="68.49318181818182" cy="18.327272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="0.0" width="0.2" x="65.59318181818182" y="21.227272727272727"/>
<rect fill="#4e4c4c" height="0.2" width="0.2" x="65.39318181818182" y="21.227272727272727"/>
<rect height="0.0" id="cb2s.back.csn.anchor" width="0.0" x="65.89318181818182" y="21.327272727272728"/>
<circle cx="66.49318181818182" cy="21.327272727272728" fill="#e5b472" r="0.5"/>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="61.043181818181814" y="30.227272727272727"/>
<g transform="translate(57.257541172126714,29.527272727272727)">
<rect fill="#cd3c24" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="58.74318181818182" y="30.327272727272728">3V3</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="61.043181818181814" y="32.22727272727273"/>
<g transform="translate(57.257541172126714,31.527272727272727)">
<rect fill="#000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="58.74318181818182" y="32.32727272727273">GND</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="61.043181818181814" y="34.22727272727273"/>
<g transform="translate(57.257541172126714,33.52727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="58.74318181818182" y="34.32727272727273">P10</text>
<g transform="translate(54.257541172126714,33.52727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="55.44318181818181" y="34.32727272727273">D4</text>
<g transform="translate(50.65754117212671,33.52727272727273)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="52.143181818181816" y="34.32727272727273">RX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="74.14318181818182" y="34.22727272727273"/>
<g transform="translate(77.55754117212672,33.52727272727273)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="79.04318181818182" y="34.32727272727273">P11</text>
<g transform="translate(81.15754117212671,33.52727272727273)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="82.34318181818182" y="34.32727272727273">D5</text>
<g transform="translate(84.15754117212671,33.52727272727273)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="85.64318181818182" y="34.32727272727273">TX1</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="74.14318181818182" y="32.22727272727273"/>
<g transform="translate(77.5575411721267,31.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="79.04318181818181" y="32.32727272727273">P24</text>
<g transform="translate(81.15754117212671,31.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="82.34318181818182" y="32.32727272727273">D6</text>
<g transform="translate(84.15754117212671,31.527272727272727)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="85.64318181818182" y="32.32727272727273">PWM4</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="74.14318181818182" y="30.227272727272727"/>
<g transform="translate(77.5575411721267,29.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="79.04318181818181" y="30.327272727272728">P26</text>
<g transform="translate(81.15754117212671,29.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="82.34318181818182" y="30.327272727272728">D7</text>
<g transform="translate(84.15754117212671,29.527272727272727)">
<rect fill="#aeafc1" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="85.64318181818182" y="30.327272727272728">IRDA</text>
<g transform="translate(87.75754117212671,29.527272727272727)">
<rect fill="#afa35e" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="89.24318181818181" y="30.327272727272728">PWM5</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="62.793181818181814" y="18.227272727272727"/>
<g transform="translate(59.007541172126714,17.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.49318181818182" y="18.327272727272728">P1</text>
<g transform="translate(56.00754117212672,17.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.19318181818182" y="18.327272727272728">D9</text>
<g transform="translate(52.40754117212672,17.527272727272727)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="53.89318181818182" y="18.327272727272728">RX2</text>
<g transform="translate(48.80754117212672,17.527272727272727)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="50.29318181818182" y="18.327272727272728">SDA2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="62.793181818181814" y="16.227272727272727"/>
<g transform="translate(59.007541172126714,15.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.49318181818182" y="16.327272727272728">P0</text>
<g transform="translate(56.00754117212672,15.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.19318181818182" y="16.327272727272728">D8</text>
<g transform="translate(52.40754117212672,15.527272727272727)">
<rect fill="#dcd4ee" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="53.89318181818182" y="16.327272727272728">TX2</text>
<g transform="translate(48.80754117212672,15.527272727272727)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="50.29318181818182" y="16.327272727272728">SCL2</text>
<rect fill="#4e4c4c" height="0.2" width="2.6" x="62.793181818181814" y="21.227272727272727"/>
<g transform="translate(59.007541172126714,20.527272727272727)">
<rect fill="#800000" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="60.49318181818182" y="21.327272727272728">P21</text>
<g transform="translate(56.00754117212672,20.527272727272727)">
<rect fill="#99188d" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="2.8" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="white" font-family="Consolas" font-size="1.2" text-anchor="middle" x="57.19318181818182" y="21.327272727272728">D10</text>
<g transform="translate(52.40754117212672,20.527272727272727)">
<rect fill="#f95" height="1.6" rx="0.3" ry="0.3" transform="skewX(-15)" width="3.4" x="0" y="0"/>
</g>
<text dominant-baseline="central" fill="#423F42" font-family="Consolas" font-size="1.2" text-anchor="middle" x="53.89318181818182" y="21.327272727272728">SDA1</text>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

View File

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

34
boards/cb2s/variant.cpp Normal file
View File

@@ -0,0 +1,34 @@
/* This file was auto-generated from cb2s.json using boardgen */
#include <Arduino.h>
extern "C" {
// clang-format off
PinInfo pinTable[PINS_COUNT] = {
// D0: P6, PWM0
{GPIO6, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D1: P7, PWM1
{GPIO7, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D2: P8, PWM2
{GPIO8, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D3: P23, ADC3, TDO, FSO
{GPIO23, PIN_GPIO | PIN_IRQ | PIN_ADC | PIN_JTAG, PIN_NONE, 0},
// D4: P10, UART1_RX
{GPIO10, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D5: P11, UART1_TX
{GPIO11, PIN_GPIO | PIN_IRQ | PIN_UART, PIN_NONE, 0},
// D6: P24, PWM4
{GPIO24, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D7: P26, PWM5, IRDA
{GPIO26, PIN_GPIO | PIN_IRQ | PIN_PWM, PIN_NONE, 0},
// D8: P0, UART2_TX, I2C2_SCL
{GPIO0, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D9: P1, UART2_RX, I2C2_SDA
{GPIO1, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_UART, PIN_NONE, 0},
// D10: P21, I2C1_SDA, TMS, MCLK, ^FCS
{GPIO21, PIN_GPIO | PIN_IRQ | PIN_I2C | PIN_I2S | PIN_JTAG, PIN_NONE, 0},
};
// clang-format on
} // extern "C"

37
boards/cb2s/variant.h Normal file
View File

@@ -0,0 +1,37 @@
/* This file was auto-generated from cb2s.json using boardgen */
#pragma once
#include <WVariant.h>
// clang-format off
// Pins
// ----
#define PINS_COUNT 11
#define NUM_DIGITAL_PINS 11
#define NUM_ANALOG_INPUTS 1
#define NUM_ANALOG_OUTPUTS 0
// Analog pins
// -----------
#define PIN_A0 3u // GPIO23
#define A0 PIN_A0
// SPI Interfaces
// --------------
#define SPI_INTERFACES_COUNT 0
// Wire Interfaces
// ---------------
#define WIRE_INTERFACES_COUNT 1
#define PIN_WIRE2_SCL 8u // GPIO0
#define PIN_WIRE2_SDA 9u // GPIO1
// Serial ports
// ------------
#define SERIAL_INTERFACES_COUNT 2
#define PIN_SERIAL1_RX 4u // GPIO10
#define PIN_SERIAL1_TX 5u // GPIO11
#define PIN_SERIAL2_RX 9u // GPIO1
#define PIN_SERIAL2_TX 8u // GPIO0

View File

@@ -2,6 +2,8 @@
*by N/A*
[Product page](https://kuba2k2.github.io/libretuya/)
Parameter | Value
-------------|-------
MCU | NATIVE

View File

@@ -3,7 +3,7 @@
"beken-72xx",
"beken-7231t",
"beken-7231t-tuya",
"pcb/ic-bk7231t",
"pcb/ic-bk7231-qfn32",
"pcb/wb2l",
"pcb/wb2l-test"
],

View File

@@ -72,12 +72,14 @@ env.Append(
("LT_HAS_MBEDTLS", "1"),
# SDK options
("CFG_OS_FREERTOS", "1"),
("MBEDTLS_CONFIG_FILE", "<tls_config.h>"),
("MBEDTLS_CONFIG_FILE", r"\"tls_config.h\""),
("WIFI_BLE_COEXIST", "1"),
("WOLFSSL_BEKEN", env.Cfg("CFG_WPA3")),
# LwIP options
("LWIP_SO_RCVBUF", "1"), # for ioctl(FIONREAD)
"MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED",
# FreeRTOS options
("INCLUDE_xTaskGetHandle", "1"),
],
ASFLAGS=[
"-mcpu=arm968e-s",
@@ -109,6 +111,10 @@ env.Append(
"-Wl,-wrap,snprintf",
"-Wl,-wrap,sprintf",
"-Wl,-wrap,vsnprintf",
"-Wl,-wrap,bk_flash_get_info",
"-Wl,-wrap,bk_flash_erase",
"-Wl,-wrap,bk_flash_write",
"-Wl,-wrap,bk_flash_read",
],
)
@@ -152,10 +158,20 @@ env.AddLibrary(
"+<arch_main.c>",
"+<ate_app.c>",
"+<intc.c>",
"+<wrap_BkDriverFlash.c>",
*srcs_fixups,
],
)
# Sources - family fixups
env.AddLibrary(
name="${FAMILY_CODE}_fixups",
base_dir="$FAMILY_DIR/fixups",
srcs=[
"+<temp_detect.c>",
],
)
# Sources - app module
env.AddLibrary(
name="bdk_app",

View File

@@ -40,6 +40,9 @@ def env_add_defaults(env, platform, board):
LINK2BIN='"${PYTHONEXE}" "${LT_DIR}/tools/link2bin.py"',
UF2OTA_PY='"${PYTHONEXE}" "${LT_DIR}/tools/uf2ota/uf2ota.py"',
UF2UPLOAD_PY='"${PYTHONEXE}" "${LT_DIR}/tools/upload/uf2upload.py"',
# Fix for link2bin to get tmpfile name in argv
LINKCOM="${LINK} ${LINKARGS}",
LINKARGS="${TEMPFILE('-o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS', '$LINKCOMSTR')}",
)
env.Replace(**vars)
# Store family parameters as environment variables

View File

@@ -12,7 +12,7 @@ custom_fw_name = my_firmware
custom_fw_version = 1.2.0
```
## LibreTuya API
## LibreTuya options
!!! note
See [LibreTuyaConfig.h](../ltapi/_libre_tuya_config_8h_source.md) for most options and their defaults.
@@ -24,9 +24,12 @@ build_flags =
-D LT_LOGLEVEL=LT_LEVEL_DEBUG
```
### Logging
!!! hint
Values in parentheses represent the defaults for the config options.
- `LT_LOGGER` - enable/disable LibreTuya logger globally. Enabled by default.
### Logger
- `LT_LOGGER` (1) - enable/disable LibreTuya logger globally. Enabled by default.
- `LT_LOGLEVEL` - global LT loglevel:
- `LT_LEVEL_TRACE` (same as LT_LEVEL_VERBOSE)
- `LT_LEVEL_DEBUG`
@@ -34,28 +37,45 @@ build_flags =
- `LT_LEVEL_WARN`
- `LT_LEVEL_ERROR`
- `LT_LEVEL_FATAL`
- `LT_LOGGER_TIMESTAMP` - print program runtime in printk-like format
- `LT_LOGGER_CALLER` - print calling method name
- `LT_LOGGER_TASK` - print calling FreeRTOS task (if available)
- `LT_LOGGER_COLOR` - output ANSI terminal colors
- `LT_PRINTF_BROKEN` - whether printf outputs "0." for floats with value 0
- `LT_LOG_HEAP` - print free heap size using `LT_HEAP_I()`
- `LT_LOG_ERRNO` - print and clear errno value (if set) using `LT_ERRNO()`
- `LT_LOGGER_TIMESTAMP` (1) - print program runtime in printk-like format
- `LT_LOGGER_CALLER` (1) - print calling method name
- `LT_LOGGER_TASK` (1) - print calling FreeRTOS task (if available)
- `LT_LOGGER_COLOR` (0) - output ANSI terminal colors
- `LT_PRINTF_BROKEN` (0) - whether printf outputs "0." for floats with value 0
- `LT_LOG_HEAP` (0) - print free heap size using `LT_HEAP_I()`
- `LT_LOG_ERRNO` (0) - print and clear errno value (if set) using `LT_ERRNO()`
### Debug logging
#### Debug logging
The following options enable library-specific debugging messages. They are only effective if `LT_LOGLEVEL` is set below INFO. All of them are disabled by default.
Families should generally call i.e. WiFiClient debugging for client-related code, even if the `WiFiClient.cpp` file is physically absent.
- `LT_DEBUG_WIFI` - `WiFi.cpp`
- `LT_DEBUG_WIFI_CLIENT` - `WiFiClient.cpp`
- `LT_DEBUG_WIFI_SERVER` - `WiFiServer.cpp`
- `LT_DEBUG_WIFI_STA` - `WiFiSTA.cpp`
- `LT_DEBUG_WIFI_AP` - `WiFiAP.cpp`
- `LT_DEBUG_SSL` - `WiFiClientSecure`
- `LT_DEBUG_WIFI` - WiFi
- `LT_DEBUG_WIFI_CLIENT` - WiFiClient
- `LT_DEBUG_WIFI_SERVER` - WiFiServer
- `LT_DEBUG_WIFI_STA` - WiFiSTA
- `LT_DEBUG_WIFI_AP` - WiFiAP
- `LT_DEBUG_SSL` - WiFiClientSecure
### Family options
### Serial output
Options for controlling default UART log output.
- `LT_UART_DEFAULT_PORT` (unset) - default output port for all messages (SDK, LT logger, Serial class); can be 0, 1 or 2
- `LT_UART_DEFAULT_LOGGER` (unset) - override default output port for LT logger only
- `LT_UART_DEFAULT_SERIAL` (unset) - override default output port for `Serial` class (without a number)
- `LT_UART_SILENT_ENABLED` (1) - enable auto-silencing of SDK "loggers"; this makes the serial output much more readable, but can hide some error messages
- `LT_UART_SILENT_ALL` (0) - disable all SDK output (LT output and logger still work)
!!! info
Values 0, 1 and 2 correspond to physical UART port numbers (refer to board pinout for the available ports).
Serial class instances (`Serial0`, `Serial1`, `Serial2`) use the respective port numbers for printing.
If `LT_UART_DEFAULT_LOGGER` is not set, it is chosen by the family code - whichever port is most appropriate (i.e. LOG_UART (2) on Realtek, RX2/TX2 on Beken).
### Family feature config
These options are selectively set by all families, as part of the build process. They are used for enabling LT core API parts, if the family has support for it.

View File

@@ -5,6 +5,7 @@ Name | MCU | Flash | RAM | Pin
**Ai-Thinker Co., Ltd.** | | | | | | | |
[BW12](../boards/bw12/README.md) | RTL8710BX | 2 MiB | 256 KiB | 16 (12 I/O) | ✔️ | ❌ | ❌ | `realtek-ambz`
**Tuya Inc.** | | | | | | | |
[CB2S](../boards/cb2s/README.md) | BK7231N | 2 MiB | 256 KiB | 11 (8 I/O) | ✔️ | ✔️ | ❌ | `beken-7231n`
[WB2L](../boards/wb2l/README.md) | BK7231T | 2 MiB | 256 KiB | 7 (5 I/O) | ✔️ | ✔️ | ❌ | `beken-7231t`
[WR3](../boards/wr3/README.md) | RTL8710BN | 2 MiB | 256 KiB | 16 (12 I/O) | ✔️ | ❌ | ❌ | `realtek-ambz`
**N/A** | | | | | | | |

View File

@@ -1,5 +1,6 @@
<!-- This file is auto-generated -->
- BK7231N
- BK7231S
- BK7231T
- BK7231U

View File

@@ -1,13 +1,13 @@
<!-- This file is auto-generated -->
Title | Name (parent) | Code | Short name & ID | Arduino Core | Source SDK
-------------------------------------------------------------------|------------------------------|----------------------|-------------------------|--------------|----------------------------------------------------------------------------------
Realtek Ameba1 | `-` | `-` | `RTL8710A` (0x9FFFD543) | ❌ | -
[Realtek AmebaZ](https://www.amebaiot.com/en/amebaz/) | `realtek-ambz` | `ambz` | `RTL8710B` (0x22E0D6FC) | ✔️ | `framework-realtek-amb1` ([amb1_sdk](https://github.com/ambiot/amb1_sdk))
Realtek AmebaZ2 | `-` | `-` | `RTL8720C` (0xE08F7564) | ❌ | -
Realtek AmebaD | `-` | `-` | `RTL8720D` (0x3379CFE2) | ❌ | -
[Beken 7231T](http://www.bekencorp.com/en/goods/detail/cid/7.html) | `beken-7231t` (`beken-72xx`) | `bk7231t` (`bk72xx`) | `BK7231T` (0x675A40B0) | ✔️ | `framework-beken-bdk` ([bdk_freertos](https://github.com/bekencorp/bdk_freertos))
Beken 7231N | `-` | `-` | `BK7231N` (0x7B3EF230) | | -
Boufallo 602 | `-` | `-` | `BL602` (0xDE1270B7) | ❌ | -
Xradiotech 809 | `-` | `-` | `XR809` (0x51E903A8) | ❌ | -
Native host architecture | `host-native` | `native` | `NATIVE` (0xDEADBEEF) | ❌ | -
Title | Name (parent) | Code | Short name & ID | Arduino Core | Source SDK
--------------------------------------------------------------------|------------------------------|----------------------|-------------------------|--------------|----------------------------------------------------------------------------------
Realtek Ameba1 | `-` | `-` | `RTL8710A` (0x9FFFD543) | ❌ | -
[Realtek AmebaZ](https://www.amebaiot.com/en/amebaz/) | `realtek-ambz` | `ambz` | `RTL8710B` (0x22E0D6FC) | ✔️ | `framework-realtek-amb1` ([amb1_sdk](https://github.com/ambiot/amb1_sdk))
Realtek AmebaZ2 | `-` | `-` | `RTL8720C` (0xE08F7564) | ❌ | -
Realtek AmebaD | `-` | `-` | `RTL8720D` (0x3379CFE2) | ❌ | -
[Beken 7231T](http://www.bekencorp.com/en/goods/detail/cid/7.html) | `beken-7231t` (`beken-72xx`) | `bk7231t` (`bk72xx`) | `BK7231T` (0x675A40B0) | ✔️ | `framework-beken-bdk` ([bdk_freertos](https://github.com/bekencorp/bdk_freertos))
[Beken 7231N](http://www.bekencorp.com/en/goods/detail/cid/39.html) | `beken-7231n` (`beken-72xx`) | `bk7231n` (`bk72xx`) | `BK7231N` (0x7B3EF230) | ✔️ | `framework-beken-bdk` ([bdk_freertos](https://github.com/bekencorp/bdk_freertos))
Boufallo 602 | `-` | `-` | `BL602` (0xDE1270B7) | ❌ | -
Xradiotech 809 | `-` | `-` | `XR809` (0x51E903A8) | ❌ | -
Native host architecture | `host-native` | `native` | `NATIVE` (0xDEADBEEF) | ❌ | -

View File

@@ -5,7 +5,6 @@ Name | MCU | Flash | RAM | Pins | Wi-Fi | BLE | ZigBee
**CB Series** | | | | | | |
CB1S | BK7231N | 2 MiB | 256 KiB | 18 | ✔️ | ✔️ | ❌
CB2L | BK7231N | 2 MiB | 256 KiB | 7 | ✔️ | ✔️ | ❌
CB2S | BK7231N | 2 MiB | 256 KiB | 11 | ✔️ | ✔️ | ❌
CB3L | BK7231N | 2 MiB | 256 KiB | 18 | ✔️ | ✔️ | ❌
CB3S | BK7231N | 2 MiB | 256 KiB | 22 | ✔️ | ✔️ | ❌
CB3S-NL | BK7231N | 2 MiB | 256 KiB | 22 | ✔️ | ✔️ | ❌

View File

@@ -48,7 +48,17 @@
{
"id": "0x7B3EF230",
"short_name": "BK7231N",
"description": "Beken 7231N"
"description": "Beken 7231N",
"name": "beken-7231n",
"parent": "beken-72xx",
"code": "bk7231n",
"parent_code": "bk72xx",
"url": "http://www.bekencorp.com/en/goods/detail/cid/39.html",
"sdk": "https://github.com/bekencorp/bdk_freertos",
"framework": "framework-beken-bdk",
"mcus": [
"BK7231N"
]
},
{
"id": "0xDE1270B7",

View File

@@ -6,7 +6,7 @@
"type": "git",
"url": "https://github.com/kuba2k2/platformio-libretuya"
},
"version": "0.6.1",
"version": "0.7.0",
"frameworks": {
"arduino": {
"title": "Generic Arduino framework",

View File

@@ -0,0 +1,132 @@
#pragma once
#define ASSERT_HALT 1
#define ASSERT_IGNORE 2
#define ASSERT_REBOOT 3
#define AT_SERVICE_CFG 0
#define BLE_DEFAULT_WIFI_REQUEST 2
#define BLE_VERSION_4_2 1
#define BLE_VERSION_5_x 2
#define BLE_WIFI_CO_REQUEST 3
#define CFG_AIRKISS_TEST 0
#define CFG_AP_MONITOR_COEXIST 0
#define CFG_AP_SUPPORT_HT_IE 0
#define CFG_ASSERT_OPTION ASSERT_IGNORE
#define CFG_BACKGROUND_PRINT 0
#define CFG_BK_AWARE 0
#define CFG_BK_AWARE_OUI "\xC8\x47\x8C"
#define CFG_BLE_ADV_NUM 1
#define CFG_BLE_CONN_NUM 1
#define CFG_BLE_INIT_NUM 0
#define CFG_BLE_SCAN_NUM 1
#define CFG_BLE_VERSION BLE_VERSION_5_x
#define CFG_EASY_FLASH 0
#define CFG_ENABLE_BUTTON 0
#define CFG_ENABLE_DEMO_TEST 0
#define CFG_ENABLE_WPA_LOG 0
#define CFG_GENERAL_DMA 1
#define CFG_IEEE80211N 1
#define CFG_IEEE80211W 0
#define CFG_INT_WDG_ENABLED 1
#define CFG_INT_WDG_PERIOD_MS 10000
#define CFG_IPERF_TEST 0
#define CFG_JTAG_ENABLE 0
#define CFG_LESS_MEMERY_IN_RWNX 0
#define CFG_LWIP_MEM_POLICY LWIP_REDUCE_THE_PLAN
#define CFG_MAC_PHY_BAPASS 1
#define CFG_MSDU_RESV_HEAD_LEN 96
#define CFG_MSDU_RESV_TAIL_LEN 16
#define CFG_PERIPHERAL_TEST 0
#define CFG_REAL_SDIO 0
#define CFG_RELEASE_FIRMWARE 0
#define CFG_ROLE_LAUNCH 0
#define CFG_RUNNING_PLATFORM SOC_PLATFORM
#define CFG_RWNX_QOS_MSDU 1
#define CFG_RX_SENSITIVITY_TEST 1
#define CFG_SARADC_CALIBRATE 0
#define CFG_SDIO 0
#define CFG_SDIO_TRANS 0
#define CFG_SOC_NAME SOC_BK7231N
#define CFG_SUPPOET_BSSID_CONNECT 0
#define CFG_SUPPORT_BKREG 1
#define CFG_SUPPORT_BLE 1
#define CFG_SUPPORT_BLE_MESH 0
#define CFG_SUPPORT_BSSID_CONNECT 0
#define CFG_SUPPORT_CALIBRATION 1
#define CFG_SUPPORT_MANUAL_CALI 1
#define CFG_SUPPORT_OTA_HTTP 1
#define CFG_SUPPORT_OTA_TFTP 0
#define CFG_SUPPORT_SPI_TEST 0
#define CFG_SUPPORT_TIANZHIHENG_DRONE 0
#define CFG_SUPPORT_TPC_PA_MAP 1
#define CFG_SYS_REDUCE_NORMAL_POWER 0
#define CFG_TASK_WDG_ENABLED 1
#define CFG_TASK_WDG_PERIOD_MS 60000
#define CFG_TCP_SERVER_TEST 0
#define CFG_TX_EVM_TEST 1
#define CFG_UART_DEBUG 0
#define CFG_UART_DEBUG_COMMAND_LINE 1
#define CFG_UDISK_MP3 0
#define CFG_USB 0
#define CFG_USE_AP_IDLE 0
#define CFG_USE_AP_PS 0
#define CFG_USE_AUD_ADC 0
#define CFG_USE_AUD_DAC 0
#define CFG_USE_AUDIO 0
#define CFG_USE_BLE_PS 1
#define CFG_USE_CAMERA_INTF 0
#define CFG_USE_DEEP_PS 1
#define CFG_USE_DHCP 1
#define CFG_USE_FAKERTC_PS 0
#define CFG_USE_FTPD_UPGRADE 0
#define CFG_USE_I2C1 0
#define CFG_USE_I2C2 1
#define CFG_USE_LWIP_NETSTACK 1
#define CFG_USE_MCU_PS 1
#define CFG_USE_PTA 0
#define CFG_USE_SDCARD_HOST 0
#define CFG_USE_SPI_DMA 1
#define CFG_USE_SPI_MASTER 1
#define CFG_USE_SPI_SLAVE 1
#define CFG_USE_SPIDMA 0
#define CFG_USE_STA_PS 1
#define CFG_USE_TEMPERATURE_DETECT 0
#define CFG_USE_TICK_CAL 1
#define CFG_USE_UART1 1
#define CFG_USE_USB_CHARGE 0
#define CFG_USE_USB_HOST 0
#define CFG_USE_WPA_29 1
#define CFG_WFA_CERT 0
#define CFG_WIFI_RAW_TX_CMD 0
#define CFG_WIFI_SENSOR 0
#define CFG_WLAN_FAST_CONNECT 0
#define CFG_WPA_CTRL_IFACE 1
#define CFG_WPA3 0
#define CFG_XTAL_FREQUENCE CFG_XTAL_FREQUENCE_26M
#define CFG_XTAL_FREQUENCE_26M 26000000
#define CFG_XTAL_FREQUENCE_40M 40000000
#define CONFIG_APP_MP3PLAYER 0
#define FPGA_PLATFORM 0
#define LWIP_DEFAULT_MEM_POLICY 1
#define LWIP_REDUCE_THE_PLAN 2
#define OSMALLOC_STATISTICAL 0
#define RF_USE_POLICY WIFI_DEFAULT_BLE_REQUEST
#define SOC_BK7221U 3
#define SOC_BK7231 1
#define SOC_BK7231N 5
#define SOC_BK7231U 2
#define SOC_BK7271 4
#define SOC_PLATFORM 1
#define THD_APPLICATION_PRIORITY 3
#define THD_CORE_PRIORITY 2
#define THD_EXTENDED_APP_PRIORITY 5
#define THD_HOSTAPD_PRIORITY 5
#define THD_INIT_PRIORITY 4
#define THD_LWIP_PRIORITY 4
#define THD_MEDIA_PRIORITY 4
#define THD_RECONNECT_PRIORITY 4
#define THD_UBG_PRIORITY 5
#define THD_UMP3_PRIORITY 4
#define THD_WPAS_PRIORITY 5
#define THDD_KEY_SCAN_PRIORITY 7
#define WIFI_DEFAULT_BLE_REQUEST 1

View File

@@ -0,0 +1,6 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-07. */
// Fix for compiling on BK7231N with CFG_USE_TEMPERATURE_DETECT=0
// Method is used by libuart_debug_bk7231n.a / bkreg_run_command_implement()
void temp_detect_change_configuration(unsigned long intval, unsigned long thre, unsigned long dist) {}

View File

@@ -40,7 +40,6 @@
#define CFG_SUPPORT_BKREG 1
#define CFG_SUPPORT_BLE 1
#define CFG_SUPPORT_BLE_MESH 0
#define CFG_SUPPORT_BOOTLOADER 1
#define CFG_SUPPORT_BSSID_CONNECT 0
#define CFG_SUPPORT_CALIBRATION 1
#define CFG_SUPPORT_MANUAL_CALI 1
@@ -100,6 +99,7 @@
#define SOC_BK7231 1
#define SOC_BK7231N 5
#define SOC_BK7231U 2
#define SOC_BK7271 4
#define SOC_PLATFORM 1
#define THD_APPLICATION_PRIORITY 3
#define THD_CORE_PRIORITY 2

View File

@@ -0,0 +1,127 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-07. */
#include "BkDriverFlash.h"
#include "drv_model_pub.h"
#include "uart_pub.h"
static const bk_logic_partition_t bk7231_partitions[BK_PARTITION_MAX] = {
{
.partition_owner = BK_FLASH_EMBEDDED,
.partition_description = "Bootloader",
.partition_start_addr = FLASH_BOOTLOADER_OFFSET,
.partition_length = FLASH_BOOTLOADER_LENGTH,
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
{
.partition_owner = BK_FLASH_EMBEDDED,
.partition_description = "Application",
.partition_start_addr = FLASH_APP_OFFSET,
.partition_length = FLASH_APP_LENGTH,
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
{
.partition_owner = BK_FLASH_EMBEDDED,
.partition_description = "ota",
.partition_start_addr = FLASH_DOWNLOAD_OFFSET,
.partition_length = FLASH_DOWNLOAD_LENGTH,
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
{
.partition_owner = BK_FLASH_EMBEDDED,
.partition_description = "RF Firmware",
.partition_start_addr = FLASH_TLV_OFFSET,
.partition_length = FLASH_TLV_LENGTH,
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
{
.partition_owner = BK_FLASH_EMBEDDED,
.partition_description = "NET info",
.partition_start_addr = FLASH_NET_OFFSET,
.partition_length = FLASH_NET_LENGTH,
.partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS,
},
};
bk_logic_partition_t *__wrap_bk_flash_get_info(bk_partition_t partition) {
if ((partition >= BK_PARTITION_BOOTLOADER) && (partition < BK_PARTITION_MAX))
return (bk_logic_partition_t *)&bk7231_partitions[partition];
return NULL;
}
OSStatus __wrap_bk_flash_erase(bk_partition_t partition, uint32_t off_set, uint32_t size) {
uint32_t i;
uint32_t param;
UINT32 status;
DD_HANDLE flash_hdl;
uint32_t start_sector, end_sector;
bk_logic_partition_t *partition_info;
GLOBAL_INT_DECLARATION();
partition_info = bk_flash_get_info(partition);
start_sector = off_set >> 12;
end_sector = (off_set + size - 1) >> 12;
flash_hdl = ddev_open(FLASH_DEV_NAME, &status, 0);
ASSERT(DD_HANDLE_UNVALID != flash_hdl);
for (i = start_sector; i <= end_sector; i++) {
param = partition_info->partition_start_addr + (i << 12);
GLOBAL_INT_DISABLE();
ddev_control(flash_hdl, CMD_FLASH_ERASE_SECTOR, (void *)&param);
GLOBAL_INT_RESTORE();
}
return kNoErr;
}
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;
bk_logic_partition_t *partition_info;
GLOBAL_INT_DECLARATION();
if (NULL == inBuffer) {
os_printf("%s inBuffer=NULL\r\n", __FUNCTION__);
return kParamErr;
}
partition_info = bk_flash_get_info(partition);
if (NULL == partition_info) {
os_printf("%s partiion not found\r\n", __FUNCTION__);
return kNotFoundErr;
}
start_addr = partition_info->partition_start_addr + off_set;
flash_hdl = ddev_open(FLASH_DEV_NAME, &status, 0);
if (DD_HANDLE_UNVALID == flash_hdl) {
os_printf("%s open failed\r\n", __FUNCTION__);
return kOpenErr;
}
GLOBAL_INT_DISABLE();
ddev_write(flash_hdl, (char *)inBuffer, inBufferLength, start_addr);
GLOBAL_INT_RESTORE();
return kNoErr;
}
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;
bk_logic_partition_t *partition_info;
GLOBAL_INT_DECLARATION();
if (NULL == outBuffer) {
os_printf("%s outBuffer=NULL\r\n", __FUNCTION__);
return kParamErr;
}
partition_info = bk_flash_get_info(partition);
if (NULL == partition_info) {
os_printf("%s partiion not found\r\n", __FUNCTION__);
return kNotFoundErr;
}
start_addr = partition_info->partition_start_addr + off_set;
flash_hdl = ddev_open(FLASH_DEV_NAME, &status, 0);
if (DD_HANDLE_UNVALID == flash_hdl) {
os_printf("%s open failed\r\n", __FUNCTION__);
return kOpenErr;
}
GLOBAL_INT_DISABLE();
ddev_read(flash_hdl, (char *)outBuffer, inBufferLength, start_addr);
GLOBAL_INT_RESTORE();
return kNoErr;
}

View File

@@ -0,0 +1,28 @@
/* Copyright (c) Kuba Szczodrzyński 2022-07-01. */
#include <param_config.h>
#include <wlan_ui_pub.h>
// NOTE: this wrap is currently not used, as the related methods
// are in the same translation unit (wlan_ui.c), so wrapping doesn't work
extern void __real_bk_wlan_sta_init_adv(network_InitTypeDef_adv_st *inNetworkInitParaAdv);
extern sta_param_t *g_sta_param_ptr;
// enable/disable fast connect according to the config parameters
void __wrap_bk_wlan_sta_init_adv(network_InitTypeDef_adv_st *inNetworkInitParaAdv) {
// let it do the job first
__real_bk_wlan_sta_init_adv(inNetworkInitParaAdv);
// correct the parameter
bool fast_connect = false;
if (inNetworkInitParaAdv->ap_info.channel) {
// enable fast connect after finding first non-zero octet of BSSID
for (uint8_t i = 0; i < 6; i++) {
if (inNetworkInitParaAdv->ap_info.bssid[i] != 0x00) {
fast_connect = true;
break;
}
}
}
g_sta_param_ptr->fast_connect_set = fast_connect;
}

View File

@@ -0,0 +1,406 @@
/*
* Script for GNU linker.
* Describes layout of sections, location of stack.
*
* In this case vectors are at location 0 (reset @ 0x08)
*
* +------------+ 0x00400020
* data |
* end
* |(heap) |
* . .
* . .
* |(heap limit)|
*
* |- - - - - - |
* stack bottom 256k
* +------------+
*
* +------------+ 0x0000000
* |vectors |
* | |
* |------------+
* |text |
* |data |
* | | 1024k
* +------------+
*/
/* Split memory into area for vectors and ram */
MEMORY
{
flash (rx) : ORIGIN = 0x00010000, LENGTH = 1912K
tcm (rw!x): ORIGIN = 0x003F0000, LENGTH = 60k - 512
itcm (rwx): ORIGIN = 0x003FEE00, LENGTH = 4k + 512
ram (rw!x): ORIGIN = 0x00400100, LENGTH = 192k - 0x100
}
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_vector_start);
_vector_start = ORIGIN(flash);
SECTIONS
{
/* vectors go to vectors region */
. = ORIGIN(flash);
.vectors :
{
KEEP(*(*.vectors))
KEEP( *(*.boot))
} > flash
/* instructions go to the text region*/
. = ORIGIN(itcm);
.itcm.code ALIGN(8) :
{
/* itcm 4KB code */
*(.text.intc_hdl_entry)
*(.text.intc_irq)
*(.text.intc_fiq)
*(.text.bk_timer_isr)
*(.text.power_save_wakeup_isr)
*(.text.bmsg_rx_sender)
*(.text.bmsg_null_sender)
*(.text.fclk_get_tick)
*(.text.flash_read_sr)
*(.text.flash_write_sr)
*(.text.flash_clr_qwfr)
*(.text.set_flash_protect)
*(.text.flash_read)
*(.text.flash_read_data)
*(.text.flash_set_qe)
*(.text.flash_set_qwfr)
*(.text.flash_set_line_mode*)
*(.text.flash_get_line_mode)
*(.text.flash_write)
*(.text.flash_ctrl)
*(.text.power_save_dtim_wake)
*(.text.sctrl_fix_dpll_div)
*(.text.vTaskSuspendAll)
*(.text.xTaskGetTickCount)
*(.text.xTaskGetTickCountFromISR)
*(.text.vTaskStepTick)
*(.text.xTaskIncrementTick)
*(.text.xTaskResumeAll)
*(.text.vTaskSwitchContext)
*(.text.vApplicationIdleHook)
*(.text.platform_is_in_irq_context)
*(.text.platform_is_in_fiq_context)
*(.text.platform_is_in_interrupt_context)
*(.text.portENABLE_IRQ)
*(.text.portENABLE_FIQ)
*(.text.portDISABLE_FIQ)
*(.text.portDISABLE_IRQ)
*(.text.vPortEnterCritical)
*(.text.vPortExitCritical)
} > itcm AT>flash
_itcmcode_flash_begin = LOADADDR(.itcm.code);
_itcmcode_ram_begin = ADDR(.itcm.code);
_itcmcode_ram_end = _itcmcode_ram_begin + SIZEOF(.itcm.code);
. = ALIGN(0x8);
/* code, instructions.for example: i=i+1; */
.text :
{
*(.text)
*(.text.*)
*(.stub)
/* https://www.embedded.com/building-bare-metal-arm-systems-with-gnu-part-3/ */
KEEP(*crtbegin.o(.ctors))
KEEP(*(EXCLUDE_FILE (*ctrend.o) .ctors))
KEEP(*(SORT(.ctors.*)))
KEEP(*crtend.o(.ctors))
KEEP(*crtbegin.o(.dtors))
KEEP(*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP(*(SORT(.dtors.*)))
KEEP(*crtend.o(.dtors))
. = ALIGN(4);
__preinit_array_start = .;
KEEP(*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
__init_array_end = .;
. = ALIGN(4);
__fini_array_start = .;
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
__fini_array_end = .;
. = ALIGN (4);
__cmd_table_start__ = .;
KEEP(*(.cmd.table.data*))
__cmd_table_end__ = .;
/* https://community.silabs.com/s/article/understand-the-gnu-linker-script-of-cortex-m4?language=en_US */
KEEP(*(.init))
KEEP(*(.fini))
*(.init)
*(.fini)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7t) *(.glue_7)
} > flash
/* read only data.for example: const int rom_data[3]={1,2,3}; */
.rodata ALIGN(8) :
{
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r*)
} > flash
.ARM.exidx :
{
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidx.*)
__exidx_end = .;
} > flash
. = ORIGIN(tcm);
.tcm ALIGN(8) :
{
*apm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*apm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_ble_init.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_ble_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_ble_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_ble.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_comm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_sdp.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_sec.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*app.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*arbitrate.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*arch_main*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ate_app*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*bam_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*bam.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*bk_timer.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*bk7011_cal*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*bk7231N_cal.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*BkDriverFlash.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_aes.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_main.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_rf_port.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_rf_xvr.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_ui.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble_util_buf.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ble.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*chan.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*cmd_evm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*cmd_rx_sensitivity.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*comm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*comm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*common_list.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*common_utils.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*common.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ctrl_iface.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dbg_mwsgen.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dbg_swdiag.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dbg_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dbg.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dd.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dhcp-server-main.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dhcp-server.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dhcp.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dma.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*dns.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*drv_model.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ecc_p256.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*eloop.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*etharp.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*fake_clock.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*flash.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gapc_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gapc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gapm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gapm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gattc_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gattc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gattm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gattm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*gpio.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*h4tl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hal_dma.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hal_machw.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hci_fc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hci_tl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hci.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*heap_4.marm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*hostapd*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ieee802_11_demo.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*igmp.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*intc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ip4_addr.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ip4.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*irda*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ke_env.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*kernel_event.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*kernel_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*kernel.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*l2cc_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*l2cc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*l2cm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*llc_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*llc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld_adv.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld_con.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld_init.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld_per_adv.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld_test.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*lld.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*llm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*llm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mac_phy_bypass.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*main_none.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*main_supplicant.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*manual_cal_bk7231U.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*me_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*me.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mem_arch.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mm_bcn.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mm_timer.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*mm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*net.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*netif.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*param_config.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*phy_trident*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ping.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*power_save*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*prf_utils.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*prf.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*ps.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*pwm_bk7231n.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*raw.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rf_xvr.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*role_launch.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*RomCallFlash.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rtos_pub*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rw_ieee80211.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rw_msg_rx.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwble.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwip_driver.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwip.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwip.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwnx_intf*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rwnx.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rx_sensitivity.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rx_swdesc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rxl_cntrl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rxl_hwdesc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*rxu_cntrl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sa_ap.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sa_station.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*saradc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*scan_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*scan.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*scanu_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*scanu.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sch_alarm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sch_arb.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sch_plan.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sch_prog.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sch_slice.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sdp_common.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sdp_service_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sdp_service.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sm_task.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sockets.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*spi*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sta_mgmt.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*start_type.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sys_arch.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*sys_ctrl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tasks.marm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tcp_in.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tcp.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tcpip.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*td.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*temp_detect.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*timeouts.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*timers.marm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tx_evm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*tx_swdesc.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*txl_buffer.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*txl_cfm.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*txl_cntrl.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*uart_ble.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*uart.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*vif_mgmt.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wdt.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wlan_cli*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wlan_ui*.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wpa_debug.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wpa_psk_cache.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wpa_psk_cache.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
*wpa_supplicant.o(.bss .bss.* .scommon .sbss .dynbss COMMON)
/* *memp.o(.bss .bss.* .scommon .sbss .dynbss COMMON) */
/* *mem.o(.bss .bss.* .scommon .sbss .dynbss COMMON) */
} >tcm AT>flash
_tcmbss_start = ADDR(.tcm);
_tcmbss_end = _tcmbss_start + SIZEOF(.tcm);
. = ORIGIN(ram);
/* globals.for example: int ram_data[3]={4,5,6}; */
/* VMA in RAM, but keep LMA in flash */
_begin_data = .;
.data :
{
*(.data .data.*)
*(.sdata)
*(.gnu.linkonce.d*)
SORT(CONSTRUCTORS)
} >ram AT>flash
_end_data = .;
/* Loader will copy data from _flash_begin to _ram_begin..ram_end */
_data_flash_begin = LOADADDR(.data);
_data_ram_begin = ADDR(.data);
_data_ram_end = .;
/* uninitialized data section - global int i; */
.bss ALIGN(8):
{
_bss_start = .;
*boot_handlers.O(.bss .bss.* .scommon .sbss .dynbss COMMON)
*(.bss .bss.*)
*(.scommon)
*(.sbss)
*(.dynbss)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
_bss_end = .;
} > ram /* in RAM */
. = ALIGN (8);
_empty_ram = .;
/* This symbol defines end of code/data sections. Heap starts here. */
PROVIDE(end = .);
}
GROUP(
libgcc.a
libg.a
libc.a
libm.a
libnosys.a
)

Submodule tools/boardgen updated: 7ab5a50be7...c41912a643

View File

@@ -5,15 +5,16 @@ from os.path import dirname, join
sys.path.append(join(dirname(__file__), ".."))
import shlex
from argparse import ArgumentParser
from enum import Enum
from os import stat, unlink
from os.path import basename, dirname, isfile, join
from shutil import copyfile
from subprocess import PIPE, Popen, list2cmdline
from subprocess import PIPE, Popen
from typing import IO, Dict, List, Tuple
from tools.util.fileio import chext, isnewer
from tools.util.fileio import chext, isnewer, readtext
from tools.util.models import Family
from tools.util.obj import get
from tools.util.platform import get_board_manifest, get_family
@@ -25,13 +26,15 @@ class SocType(Enum):
AMBZ = (1, "arm-none-eabi-", True, 0)
BK72XX = (2, "arm-none-eabi-", False, 0)
def cmd(self, cmd: str, args: str = []) -> IO[bytes]:
def cmd(self, program: str, args: List[str] = []) -> IO[bytes]:
program = self.prefix + program
cmd = [program] + args
try:
if args:
cmd += " " + list2cmdline(args)
process = Popen(self.prefix + cmd, stdout=PIPE)
process = Popen(cmd, stdout=PIPE)
except FileNotFoundError:
print(f"Toolchain not found while running: '{self.prefix + cmd}'")
if isinstance(cmd, list):
cmd = " ".join(cmd)
print(f"Toolchain not found while running: '{cmd}'")
exit(1)
return process.stdout
@@ -49,7 +52,7 @@ class SocType(Enum):
def nm(self, input: str) -> Dict[str, int]:
out = {}
stdout = self.cmd(f"gcc-nm", args=[input])
stdout = self.cmd("gcc-nm", [input])
for line in stdout.readlines():
line = line.decode().strip().split(" ")
if len(line) != 3:
@@ -67,8 +70,12 @@ class SocType(Enum):
# print graph element
print(f"| | |-- {basename(output)}")
if isnewer(input, output):
sections = " ".join(f"-j {section}" for section in sections)
self.cmd(f"objcopy {sections} -O {fmt}", args=[input, output]).read()
args = []
for section in sections:
args += ["-j", section]
args += ["-O", fmt]
args += [input, output]
self.cmd("objcopy", args).read()
return output
@@ -188,7 +195,7 @@ if __name__ == "__main__":
parser = ArgumentParser(
prog="link2bin",
description="Link to BIN format",
prefix_chars="@",
prefix_chars="#",
)
parser.add_argument("board", type=str, help="Target board name")
parser.add_argument("ota1", type=str, help=".LD file OTA1 pattern")
@@ -212,6 +219,17 @@ if __name__ == "__main__":
if not args.args:
print(f"Linker arguments must not be empty")
exit(1)
try:
while True:
i = next(i for i, a in enumerate(args.args) if a.startswith("@"))
arg = args.args.pop(i)
argv = readtext(arg[1:])
argv = shlex.split(argv)
args.args = args.args[0:i] + argv + args.args[i:]
except StopIteration:
pass
link2bin(
soc,
family,

View File

@@ -47,6 +47,8 @@ def upload_uart(
except ValueError as e:
print(prefix, f"Writing failed: {e.args[0]}")
return False
# reboot the chip
bk.reboot_chip()
return True