@mikrojs/firmware 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +30 -0
- package/bin/idf.py +7 -0
- package/chips.json +3 -0
- package/cmake.js +9 -0
- package/components/mikrojs/CMakeLists.txt +187 -0
- package/components/mikrojs/Kconfig +55 -0
- package/components/mikrojs/idf_component.yml +6 -0
- package/components/mikrojs/include/mem.h +3 -0
- package/components/mikrojs/include/mik_color.h +3 -0
- package/components/mikrojs/include/mik_http_internal.h +77 -0
- package/components/mikrojs/include/mikrojs.h +5 -0
- package/components/mikrojs/include/mikrojs_esp32.h +65 -0
- package/components/mikrojs/include/private.h +10 -0
- package/components/mikrojs/include/utils.h +3 -0
- package/components/mikrojs/mik_ble.cpp +1588 -0
- package/components/mikrojs/mik_ble_c_shim.c +61 -0
- package/components/mikrojs/mik_ble_c_shim.h +37 -0
- package/components/mikrojs/mik_config.cpp +167 -0
- package/components/mikrojs/mik_deploy.cpp +584 -0
- package/components/mikrojs/mik_http.cpp +916 -0
- package/components/mikrojs/mik_i2c.cpp +364 -0
- package/components/mikrojs/mik_main.cpp +542 -0
- package/components/mikrojs/mik_neopixel.cpp +437 -0
- package/components/mikrojs/mik_nvs_kv.cpp +219 -0
- package/components/mikrojs/mik_pin.cpp +195 -0
- package/components/mikrojs/mik_pwm.cpp +525 -0
- package/components/mikrojs/mik_recovery.cpp +86 -0
- package/components/mikrojs/mik_rtc.cpp +305 -0
- package/components/mikrojs/mik_serial_io.cpp +362 -0
- package/components/mikrojs/mik_sleep.cpp +226 -0
- package/components/mikrojs/mik_sntp.cpp +275 -0
- package/components/mikrojs/mik_spi.cpp +330 -0
- package/components/mikrojs/mik_uart.cpp +497 -0
- package/components/mikrojs/mik_wifi.cpp +1434 -0
- package/components/mikrojs/platform_esp32.cpp +192 -0
- package/components/mikrojs/test/CMakeLists.txt +32 -0
- package/components/mikrojs/test/abort_test.cpp +254 -0
- package/components/mikrojs/test/ble_test.cpp +714 -0
- package/components/mikrojs/test/fs_js_test.cpp +458 -0
- package/components/mikrojs/test/fs_pub_test.cpp +312 -0
- package/components/mikrojs/test/http_test.cpp +475 -0
- package/components/mikrojs/test/i2c_test.cpp +138 -0
- package/components/mikrojs/test/modules_extended_test.cpp +137 -0
- package/components/mikrojs/test/modules_test.cpp +131 -0
- package/components/mikrojs/test/pins_test.cpp +47 -0
- package/components/mikrojs/test/pwm_test.cpp +166 -0
- package/components/mikrojs/test/repl_protocol_test.cpp +405 -0
- package/components/mikrojs/test/rtc_test.cpp +331 -0
- package/components/mikrojs/test/runtime_test.cpp +89 -0
- package/components/mikrojs/test/sleep_test.cpp +222 -0
- package/components/mikrojs/test/sntp_test.cpp +249 -0
- package/components/mikrojs/test/stdio_test.cpp +449 -0
- package/components/mikrojs/test/sys_test.cpp +165 -0
- package/components/mikrojs/test/text_encoding_test.cpp +224 -0
- package/components/mikrojs/test/timers_js_test.cpp +244 -0
- package/components/mikrojs/test/timers_test.cpp +79 -0
- package/components/mikrojs/test/wifi_test.cpp +599 -0
- package/default-app/main/CMakeLists.txt +3 -0
- package/default-app/main/main.cpp +5 -0
- package/discover.js +77 -0
- package/index.d.ts +7 -0
- package/index.js +20 -0
- package/package.json +61 -0
- package/partitions.csv +5 -0
- package/prebuilds/esp32/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32/flasher_args.json +24 -0
- package/prebuilds/esp32/mikrojs.bin +0 -0
- package/prebuilds/esp32/partition_table/partition-table.bin +0 -0
- package/prebuilds/esp32c3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c3/flasher_args.json +24 -0
- package/prebuilds/esp32c3/mikrojs.bin +0 -0
- package/prebuilds/esp32c3/partition_table/partition-table.bin +0 -0
- package/prebuilds/esp32c6/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32c6/flasher_args.json +24 -0
- package/prebuilds/esp32c6/mikrojs.bin +0 -0
- package/prebuilds/esp32c6/partition_table/partition-table.bin +0 -0
- package/prebuilds/esp32s3/bootloader/bootloader.bin +0 -0
- package/prebuilds/esp32s3/flasher_args.json +24 -0
- package/prebuilds/esp32s3/mikrojs.bin +0 -0
- package/prebuilds/esp32s3/partition_table/partition-table.bin +0 -0
- package/project.cmake +101 -0
- package/resolve.js +54 -0
- package/sdkconfig.defaults +127 -0
- package/sdkconfig.defaults.esp32 +8 -0
- package/sdkconfig.defaults.esp32c3 +15 -0
- package/sdkconfig.defaults.esp32c6 +26 -0
- package/sdkconfig.defaults.esp32s3 +22 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* BLE C shim.
|
|
3
|
+
*
|
|
4
|
+
* esp_bt.h transitively pulls in hal/assert.h which defines
|
|
5
|
+
* #define __noreturn [[noreturn]]
|
|
6
|
+
* The HAL chain then applies __noreturn to a type, which fails C++
|
|
7
|
+
* -Wattributes (treated as -Werror in ESP-IDF's default build). Compiling
|
|
8
|
+
* this in C sidesteps the attribute restriction entirely, so every
|
|
9
|
+
* esp_bt.h-touching call mik_ble.cpp needs is wrapped here.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
#include "esp_bt.h"
|
|
13
|
+
|
|
14
|
+
#include "mik_ble_c_shim.h"
|
|
15
|
+
|
|
16
|
+
/* ── TX power ──────────────────────────────────────────────────────── */
|
|
17
|
+
|
|
18
|
+
/* Convert dBm <-> esp_power_level_t enum.
|
|
19
|
+
* The enum spans -24 dBm (0) to +9 dBm (15) in 3 dBm steps on most ESP chips. */
|
|
20
|
+
static esp_power_level_t dbm_to_level(int dbm) {
|
|
21
|
+
int level = (dbm + 24) / 3;
|
|
22
|
+
if (level < 0) level = 0;
|
|
23
|
+
if (level > 15) level = 15;
|
|
24
|
+
return (esp_power_level_t)level;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static int level_to_dbm(esp_power_level_t level) {
|
|
28
|
+
return (int)level * 3 - 24;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
int mik_ble_get_tx_power_dbm(void) {
|
|
32
|
+
esp_power_level_t level = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_ADV);
|
|
33
|
+
return level_to_dbm(level);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
int mik_ble_set_tx_power_dbm(int dbm) {
|
|
37
|
+
esp_power_level_t level = dbm_to_level(dbm);
|
|
38
|
+
esp_err_t err = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, level);
|
|
39
|
+
if (err != ESP_OK) return (int)err;
|
|
40
|
+
/* Also set the default power so any implicit advertising uses the new level. */
|
|
41
|
+
esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, level);
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* ── Controller teardown ───────────────────────────────────────────── */
|
|
46
|
+
|
|
47
|
+
/* Disable the BT controller. Returns the esp_err_t code (0 on success).
|
|
48
|
+
* Safe to call even if the controller is already disabled. */
|
|
49
|
+
int mik_ble_controller_disable(void) {
|
|
50
|
+
esp_bt_controller_status_t status = esp_bt_controller_get_status();
|
|
51
|
+
if (status != ESP_BT_CONTROLLER_STATUS_ENABLED) return 0;
|
|
52
|
+
return (int)esp_bt_controller_disable();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Deinitialize the BT controller, freeing its RAM. Returns the esp_err_t
|
|
56
|
+
* code (0 on success). Safe to call even if already deinitialized. */
|
|
57
|
+
int mik_ble_controller_deinit(void) {
|
|
58
|
+
esp_bt_controller_status_t status = esp_bt_controller_get_status();
|
|
59
|
+
if (status == ESP_BT_CONTROLLER_STATUS_IDLE) return 0;
|
|
60
|
+
return (int)esp_bt_controller_deinit();
|
|
61
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#ifndef MIK_BLE_C_SHIM_H
|
|
2
|
+
#define MIK_BLE_C_SHIM_H
|
|
3
|
+
|
|
4
|
+
#ifdef __cplusplus
|
|
5
|
+
extern "C" {
|
|
6
|
+
#endif
|
|
7
|
+
|
|
8
|
+
/* ── TX power ──────────────────────────────────────────────────────── */
|
|
9
|
+
|
|
10
|
+
/** Returns the current BLE advertising TX power in dBm. */
|
|
11
|
+
int mik_ble_get_tx_power_dbm(void);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Sets the BLE advertising (and default) TX power in dBm.
|
|
15
|
+
* Returns 0 on success, or a non-zero esp_err_t code on failure.
|
|
16
|
+
*/
|
|
17
|
+
int mik_ble_set_tx_power_dbm(int dbm);
|
|
18
|
+
|
|
19
|
+
/* ── Controller teardown ───────────────────────────────────────────── */
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Disable the BT controller. Returns 0 on success or if already disabled,
|
|
23
|
+
* or a non-zero esp_err_t code on failure.
|
|
24
|
+
*/
|
|
25
|
+
int mik_ble_controller_disable(void);
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Deinitialize the BT controller, freeing its RAM. Returns 0 on success
|
|
29
|
+
* or if already deinitialized, or a non-zero esp_err_t code on failure.
|
|
30
|
+
*/
|
|
31
|
+
int mik_ble_controller_deinit(void);
|
|
32
|
+
|
|
33
|
+
#ifdef __cplusplus
|
|
34
|
+
}
|
|
35
|
+
#endif
|
|
36
|
+
|
|
37
|
+
#endif // MIK_BLE_C_SHIM_H
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#include <stdio.h>
|
|
2
|
+
#include <string.h>
|
|
3
|
+
#include <unistd.h>
|
|
4
|
+
|
|
5
|
+
#include <string>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
#include <nanocbor/nanocbor.h>
|
|
9
|
+
|
|
10
|
+
#include "nvs.h"
|
|
11
|
+
#include "nvs_flash.h"
|
|
12
|
+
#include "mikrojs/mikrojs.h"
|
|
13
|
+
#include "mikrojs/private.h"
|
|
14
|
+
#include "mikrojs_esp32.h"
|
|
15
|
+
|
|
16
|
+
/* ── Unified protocol config handler ────────────────────────────── */
|
|
17
|
+
|
|
18
|
+
/** Collected config entry for CBOR encoding */
|
|
19
|
+
struct config_entry_t {
|
|
20
|
+
std::string key;
|
|
21
|
+
std::string value;
|
|
22
|
+
bool secret;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/** Encode a single config entry into a CBOR encoder */
|
|
26
|
+
static void encode_config_entry(nanocbor_encoder_t* enc, const config_entry_t& entry) {
|
|
27
|
+
nanocbor_fmt_map(enc, 3);
|
|
28
|
+
nanocbor_put_tstr(enc, "key");
|
|
29
|
+
nanocbor_put_tstrn(enc, entry.key.c_str(), entry.key.size());
|
|
30
|
+
nanocbor_put_tstr(enc, "value");
|
|
31
|
+
nanocbor_put_tstrn(enc, entry.value.c_str(), entry.value.size());
|
|
32
|
+
nanocbor_put_tstr(enc, "secret");
|
|
33
|
+
nanocbor_fmt_bool(enc, entry.secret);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Build CBOR array of env entries for MSG_CONFIG_ENTRIES */
|
|
37
|
+
static std::vector<uint8_t> build_config_entries_cbor() {
|
|
38
|
+
std::vector<config_entry_t> entries;
|
|
39
|
+
|
|
40
|
+
nvs_handle_t handle;
|
|
41
|
+
if (nvs_open(MIK__NVS_NS_ENV, NVS_READONLY, &handle) == ESP_OK) {
|
|
42
|
+
nvs_iterator_t it = NULL;
|
|
43
|
+
esp_err_t err = nvs_entry_find_in_handle(handle, NVS_TYPE_STR, &it);
|
|
44
|
+
while (err == ESP_OK && it != NULL) {
|
|
45
|
+
nvs_entry_info_t info;
|
|
46
|
+
nvs_entry_info(it, &info);
|
|
47
|
+
|
|
48
|
+
config_entry_t entry;
|
|
49
|
+
entry.key = info.key;
|
|
50
|
+
entry.secret = mik__nvs_is_secret(info.key);
|
|
51
|
+
|
|
52
|
+
if (!entry.secret) {
|
|
53
|
+
size_t val_len = 0;
|
|
54
|
+
nvs_get_str(handle, info.key, NULL, &val_len);
|
|
55
|
+
char buf[512];
|
|
56
|
+
if (val_len > 0 && val_len <= sizeof(buf)) {
|
|
57
|
+
nvs_get_str(handle, info.key, buf, &val_len);
|
|
58
|
+
entry.value.assign(buf, val_len > 0 ? val_len - 1 : 0);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
entries.push_back(std::move(entry));
|
|
63
|
+
err = nvs_entry_next(&it);
|
|
64
|
+
}
|
|
65
|
+
nvs_release_iterator(it);
|
|
66
|
+
nvs_close(handle);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/* Two-pass CBOR encode */
|
|
70
|
+
nanocbor_encoder_t enc;
|
|
71
|
+
nanocbor_encoder_init(&enc, nullptr, 0);
|
|
72
|
+
nanocbor_fmt_array(&enc, entries.size());
|
|
73
|
+
for (const auto& e : entries) {
|
|
74
|
+
encode_config_entry(&enc, e);
|
|
75
|
+
}
|
|
76
|
+
size_t needed = nanocbor_encoded_len(&enc);
|
|
77
|
+
|
|
78
|
+
std::vector<uint8_t> buf(needed);
|
|
79
|
+
nanocbor_encoder_init(&enc, buf.data(), needed);
|
|
80
|
+
nanocbor_fmt_array(&enc, entries.size());
|
|
81
|
+
for (const auto& e : entries) {
|
|
82
|
+
encode_config_entry(&enc, e);
|
|
83
|
+
}
|
|
84
|
+
return buf;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
bool mik__handle_config_command(MIKReplTransport* transport, uint8_t cmd_type,
|
|
88
|
+
uint32_t payload_len) {
|
|
89
|
+
switch (cmd_type) {
|
|
90
|
+
case MIK_CMD_CONFIG_LIST: {
|
|
91
|
+
mik__proto_drain(transport, payload_len);
|
|
92
|
+
auto cbor = build_config_entries_cbor();
|
|
93
|
+
mik__proto_send(transport, MIK_MSG_CONFIG_ENTRIES, cbor.data(), cbor.size());
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
case MIK_CMD_CONFIG_SET: {
|
|
98
|
+
/* Payload: u8 flags | u16le key_len | key | u16le val_len | value */
|
|
99
|
+
uint8_t flags;
|
|
100
|
+
if (!mik__proto_read_exact(transport, &flags, 1)) return false;
|
|
101
|
+
|
|
102
|
+
uint8_t kl[2];
|
|
103
|
+
if (!mik__proto_read_exact(transport, kl, 2)) return false;
|
|
104
|
+
uint16_t key_len = kl[0] | (kl[1] << 8);
|
|
105
|
+
|
|
106
|
+
char key[64];
|
|
107
|
+
if (key_len >= sizeof(key)) {
|
|
108
|
+
mik__proto_drain(transport, payload_len - 3);
|
|
109
|
+
mik__proto_send_err(transport, "key too long");
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (!mik__proto_read_exact(transport, key, key_len)) return false;
|
|
113
|
+
key[key_len] = '\0';
|
|
114
|
+
|
|
115
|
+
uint8_t vl[2];
|
|
116
|
+
if (!mik__proto_read_exact(transport, vl, 2)) return false;
|
|
117
|
+
uint16_t val_len = vl[0] | (vl[1] << 8);
|
|
118
|
+
|
|
119
|
+
char value[512];
|
|
120
|
+
if (val_len >= sizeof(value)) {
|
|
121
|
+
mik__proto_drain(transport, val_len);
|
|
122
|
+
mik__proto_send_err(transport, "value too long");
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
if (!mik__proto_read_exact(transport, value, val_len)) return false;
|
|
126
|
+
value[val_len] = '\0';
|
|
127
|
+
|
|
128
|
+
if (key_len > 15) {
|
|
129
|
+
mik__proto_send_err(transport, "key exceeds NVS 15-char limit");
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
bool changed = false;
|
|
134
|
+
if (mik__nvs_env_set(key, value, flags & MIK_ENV_FLAG_SECRET, &changed)) {
|
|
135
|
+
uint8_t byte = changed ? 1 : 0;
|
|
136
|
+
mik__proto_send(transport, MIK_MSG_OK, &byte, 1);
|
|
137
|
+
} else {
|
|
138
|
+
mik__proto_send_err(transport, "nvs write failed");
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case MIK_CMD_CONFIG_DELETE: {
|
|
144
|
+
/* Payload: u16le key_len | key */
|
|
145
|
+
uint8_t kl[2];
|
|
146
|
+
if (!mik__proto_read_exact(transport, kl, 2)) return false;
|
|
147
|
+
uint16_t key_len = kl[0] | (kl[1] << 8);
|
|
148
|
+
|
|
149
|
+
char key[64];
|
|
150
|
+
if (key_len >= sizeof(key)) {
|
|
151
|
+
mik__proto_drain(transport, key_len);
|
|
152
|
+
mik__proto_send_err(transport, "key too long");
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
if (!mik__proto_read_exact(transport, key, key_len)) return false;
|
|
156
|
+
key[key_len] = '\0';
|
|
157
|
+
|
|
158
|
+
uint8_t byte = mik__nvs_env_delete(key) ? 1 : 0;
|
|
159
|
+
mik__proto_send(transport, MIK_MSG_OK, &byte, 1);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
default:
|
|
164
|
+
mik__proto_drain(transport, payload_len);
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
}
|