@mikrojs/firmware 0.21.0 → 0.21.1-next.20260926222438
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/README.md +5 -5
- package/bin/mikro-fw.js +7 -0
- package/components/mikrojs/CMakeLists.txt +87 -86
- package/components/mikrojs/mik_gpio.cpp +1 -1
- package/components/mikrojs/mik_i2c.cpp +4 -4
- package/components/mikrojs/mik_i2s.cpp +5 -5
- package/components/mikrojs/mik_main.cpp +2 -5
- package/components/mikrojs/mik_neopixel.cpp +1 -1
- package/components/mikrojs/mik_nvs_kv.cpp +5 -5
- package/components/mikrojs/mik_ota_env.cpp +2 -3
- package/components/mikrojs/mik_pwm.cpp +1 -1
- package/components/mikrojs/mik_rtc.cpp +16 -12
- package/components/mikrojs/mik_spi.cpp +5 -5
- package/components/mikrojs/mik_uart.cpp +8 -8
- package/components/mikrojs/mik_wifi.cpp +1 -3
- package/components/mikrojs/test/nvs_kv_test.cpp +21 -0
- package/components/mikrojs/test/rtc_test.cpp +74 -3
- package/dist/boards.d.ts +80 -0
- package/dist/boards.d.ts.map +1 -0
- package/dist/boards.js +263 -0
- package/dist/boards.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +75 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/inputs.d.ts +16 -0
- package/dist/inputs.d.ts.map +1 -0
- package/dist/inputs.js +97 -0
- package/dist/inputs.js.map +1 -0
- package/dist/manifest.d.ts +44 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +164 -0
- package/dist/manifest.js.map +1 -0
- package/{prebuilds → dist-fw}/esp32-generic/bootloader/bootloader.bin +0 -0
- package/dist-fw/esp32-generic/firmware.json +1 -0
- package/{prebuilds → dist-fw}/esp32-generic/mikrojs.bin +0 -0
- package/{prebuilds → dist-fw}/esp32c3-generic/bootloader/bootloader.bin +0 -0
- package/dist-fw/esp32c3-generic/firmware.json +1 -0
- package/{prebuilds → dist-fw}/esp32c3-generic/mikrojs.bin +0 -0
- package/{prebuilds → dist-fw}/esp32c5-generic/bootloader/bootloader.bin +0 -0
- package/dist-fw/esp32c5-generic/firmware.json +1 -0
- package/{prebuilds → dist-fw}/esp32c5-generic/mikrojs.bin +0 -0
- package/{prebuilds → dist-fw}/esp32c6-generic/bootloader/bootloader.bin +0 -0
- package/dist-fw/esp32c6-generic/firmware.json +1 -0
- package/{prebuilds → dist-fw}/esp32c6-generic/mikrojs.bin +0 -0
- package/{prebuilds → dist-fw}/esp32s3-generic/bootloader/bootloader.bin +0 -0
- package/dist-fw/esp32s3-generic/firmware.json +1 -0
- package/{prebuilds → dist-fw}/esp32s3-generic/mikrojs.bin +0 -0
- package/package.json +51 -15
- package/project.cmake +74 -46
- package/resolve.cmake +36 -0
- package/cmake.js +0 -9
- package/discover.js +0 -82
- package/index.d.ts +0 -9
- package/index.js +0 -41
- package/prebuilds/esp32-generic/firmware.json +0 -1
- package/prebuilds/esp32c3-generic/firmware.json +0 -1
- package/prebuilds/esp32c5-generic/firmware.json +0 -1
- package/prebuilds/esp32c6-generic/firmware.json +0 -1
- package/prebuilds/esp32s3-generic/firmware.json +0 -1
- package/resolve.js +0 -64
- /package/{prebuilds → dist-fw}/esp32-generic/flasher_args.json +0 -0
- /package/{prebuilds → dist-fw}/esp32-generic/partition_table/partition-table.bin +0 -0
- /package/{prebuilds → dist-fw}/esp32c3-generic/flasher_args.json +0 -0
- /package/{prebuilds → dist-fw}/esp32c3-generic/partition_table/partition-table.bin +0 -0
- /package/{prebuilds → dist-fw}/esp32c5-generic/flasher_args.json +0 -0
- /package/{prebuilds → dist-fw}/esp32c5-generic/partition_table/partition-table.bin +0 -0
- /package/{prebuilds → dist-fw}/esp32c6-generic/flasher_args.json +0 -0
- /package/{prebuilds → dist-fw}/esp32c6-generic/partition_table/partition-table.bin +0 -0
- /package/{prebuilds → dist-fw}/esp32s3-generic/flasher_args.json +0 -0
- /package/{prebuilds → dist-fw}/esp32s3-generic/partition_table/partition-table.bin +0 -0
package/README.md
CHANGED
|
@@ -4,18 +4,18 @@ ESP32 firmware package for Mikro.js. Provides the ESP-IDF integration, build sys
|
|
|
4
4
|
|
|
5
5
|
## What's included
|
|
6
6
|
|
|
7
|
-
- **`project.cmake`** - CMake module that integrates with ESP-IDF.
|
|
7
|
+
- **`project.cmake`** - CMake module that integrates with ESP-IDF. Turns the native modules that the project lists into ESP-IDF components, merges SDK config, and applies partition table defaults.
|
|
8
8
|
- **`components/mikrojs/`** - ESP-IDF component that compiles the Mikro.js runtime, QuickJS engine, and platform-specific C modules.
|
|
9
9
|
- **Default configs** - `sdkconfig.defaults` and `partitions.csv` for common setups.
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
|
-
A custom firmware project depends on this package and includes `project.cmake
|
|
13
|
+
A custom firmware project depends on this package and includes its `project.cmake`, whose path the package's `mikro-fw` bin prints (see the docs below for the CMakeLists boilerplate):
|
|
14
14
|
|
|
15
15
|
```
|
|
16
16
|
my-firmware/
|
|
17
|
-
├── package.json # depends on @mikrojs/firmware
|
|
18
|
-
├── CMakeLists.txt #
|
|
17
|
+
├── package.json # depends on @mikrojs/firmware and mikro
|
|
18
|
+
├── CMakeLists.txt # includes project.cmake from @mikrojs/firmware
|
|
19
19
|
└── main/ # optional: omit it and the package's default main
|
|
20
20
|
├── CMakeLists.txt # (which calls MIK_Main()) is used automatically
|
|
21
21
|
└── main.cpp
|
|
@@ -28,4 +28,4 @@ See the [Custom Firmware](https://mikrojs.dev/develop/custom-firmware) docs for
|
|
|
28
28
|
- Node.js >= 24
|
|
29
29
|
- ESP-IDF >= 6.1 (installed via [EIM](https://docs.espressif.com/projects/idf-im-ui/en/latest/))
|
|
30
30
|
|
|
31
|
-
To build,
|
|
31
|
+
To build, run `pn mikro idf build` in the project. `mikro idf` passes its arguments to `idf.py`, through EIM when ESP-IDF is not active in the shell. Plain `idf.py` works too, in a shell where ESP-IDF is active.
|
package/bin/mikro-fw.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// In the Mikro.js repository, run the TypeScript source, so a firmware build
|
|
3
|
+
// never runs a stale dist/. A published package has only dist/.
|
|
4
|
+
import {existsSync} from 'node:fs'
|
|
5
|
+
|
|
6
|
+
const src = new URL('../src/cli.ts', import.meta.url)
|
|
7
|
+
await import(existsSync(src) ? src.href : '../dist/cli.js')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ──
|
|
1
|
+
# ── Package paths ────────────────────────────────────────────────────
|
|
2
2
|
# MIKROJS_PROJECT_DIR is the directory containing package.json and node_modules.
|
|
3
3
|
# Defaults to CMAKE_SOURCE_DIR which works for both:
|
|
4
4
|
# - Monorepo: CMAKE_SOURCE_DIR is esp32/ (has package.json with workspace deps)
|
|
@@ -7,28 +7,18 @@ if(NOT DEFINED MIKROJS_PROJECT_DIR)
|
|
|
7
7
|
set(MIKROJS_PROJECT_DIR "${CMAKE_SOURCE_DIR}")
|
|
8
8
|
endif()
|
|
9
9
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
)
|
|
23
|
-
# Parse JSON output
|
|
24
|
-
string(JSON MIK_INCLUDE_DIR GET "${_NATIVE_JSON}" "include")
|
|
25
|
-
string(JSON MIK_SRC_DIR GET "${_NATIVE_JSON}" "src")
|
|
26
|
-
string(JSON MIK_RUNTIME_DIR GET "${_NATIVE_JSON}" "runtime")
|
|
27
|
-
string(JSON MIK_SCRIPTS_DIR GET "${_NATIVE_JSON}" "scripts")
|
|
28
|
-
string(JSON MIK_BYTECODE_CMAKE GET "${_NATIVE_JSON}" "bytecodeCmake")
|
|
29
|
-
|
|
30
|
-
# Include quickjs.cmake for QUICKJS_SOURCES, QUICKJS_INCLUDE_DIR, etc.
|
|
31
|
-
include("${QUICKJS_CMAKE_PATH}")
|
|
10
|
+
# The MIK_* paths come from resolve.cmake, which project.cmake includes.
|
|
11
|
+
# ESP-IDF first runs this file in a separate script-mode pass that only
|
|
12
|
+
# collects REQUIRES, where they are unset. That pass reads no SRCS, so only
|
|
13
|
+
# the include below needs a guard; REQUIRES must never depend on them.
|
|
14
|
+
if(MIK_SRC_DIR)
|
|
15
|
+
# Include quickjs.cmake for QUICKJS_SOURCES, QUICKJS_INCLUDE_DIR, etc.
|
|
16
|
+
include("${MIK_QUICKJS_CMAKE}")
|
|
17
|
+
elseif(NOT CMAKE_BUILD_EARLY_EXPANSION)
|
|
18
|
+
message(FATAL_ERROR
|
|
19
|
+
"mikrojs: the @mikrojs/native paths are not set. Include @mikrojs/firmware's "
|
|
20
|
+
"project.cmake in the project's CMakeLists.txt, before project().")
|
|
21
|
+
endif()
|
|
32
22
|
|
|
33
23
|
# nanocbor lives inside the native package
|
|
34
24
|
set(MIK_NANOCBOR_DIR "${MIK_SRC_DIR}/../deps/nanocbor")
|
|
@@ -155,15 +145,12 @@ set_source_files_properties(${QUICKJS_SOURCES} PROPERTIES
|
|
|
155
145
|
COMPILE_OPTIONS "-Wno-unused-but-set-variable")
|
|
156
146
|
|
|
157
147
|
# ── Board and version metadata ──────────────────────────────────────
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
OUTPUT_VARIABLE _MIK_VERSION
|
|
161
|
-
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
162
|
-
)
|
|
148
|
+
file(READ "${CMAKE_CURRENT_LIST_DIR}/../../package.json" _MIK_PACKAGE)
|
|
149
|
+
string(JSON _MIK_VERSION GET "${_MIK_PACKAGE}" version)
|
|
163
150
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_FW_VERSION=\"${_MIK_VERSION}\"")
|
|
164
151
|
# Core runtime owns the bare `native:mikro/*` namespace. MIK_PACKAGE_NAME makes
|
|
165
152
|
# MIK_REGISTER_MODULE enforce that every native module here is named
|
|
166
|
-
# "native:mikro/<module>";
|
|
153
|
+
# "native:mikro/<module>"; a package's native module sets its package name.
|
|
167
154
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_PACKAGE_NAME=\"mikro\"")
|
|
168
155
|
# The version is read at configure time, so configure must re-run when the
|
|
169
156
|
# firmware package version changes — otherwise an incremental idf.py build
|
|
@@ -171,24 +158,53 @@ target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_PACKAGE_NAME=\"mikro\""
|
|
|
171
158
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
|
|
172
159
|
"${CMAKE_CURRENT_LIST_DIR}/../../package.json")
|
|
173
160
|
|
|
174
|
-
#
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
#
|
|
178
|
-
#
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
161
|
+
# Board name and description: MIKROJS_BOARD_NAME and MIKROJS_BOARD_DESCRIPTION
|
|
162
|
+
# (resolved by project.cmake), else the name and description in the nearest
|
|
163
|
+
# package.json at or above the project (the app's, for a firmware folder inside
|
|
164
|
+
# an app). The name is compiled in and reported as sys.board.name, and as
|
|
165
|
+
# `board` and `fw` in MSG_READY. The CLI only auto-flashes its bundled image over
|
|
166
|
+
# a device whose `fw` matches that image's name, so other firmware is never
|
|
167
|
+
# replaced by accident. Without a name, `fw` is omitted and the board is
|
|
168
|
+
# <chip>-generic.
|
|
169
|
+
set(_MIK_NAME "${_MIK_BOARD_NAME}")
|
|
170
|
+
set(_MIK_DESCRIPTION "${_MIK_BOARD_DESCRIPTION}")
|
|
171
|
+
set(_MIK_FW_DIR "${CMAKE_SOURCE_DIR}")
|
|
172
|
+
while(NOT EXISTS "${_MIK_FW_DIR}/package.json")
|
|
173
|
+
get_filename_component(_MIK_FW_PARENT "${_MIK_FW_DIR}" DIRECTORY)
|
|
174
|
+
if(_MIK_FW_PARENT STREQUAL _MIK_FW_DIR)
|
|
175
|
+
break()
|
|
176
|
+
endif()
|
|
177
|
+
set(_MIK_FW_DIR "${_MIK_FW_PARENT}")
|
|
178
|
+
endwhile()
|
|
179
|
+
if(EXISTS "${_MIK_FW_DIR}/package.json")
|
|
180
|
+
file(READ "${_MIK_FW_DIR}/package.json" _MIK_PROJECT_PACKAGE)
|
|
181
|
+
foreach(_field IN ITEMS name description)
|
|
182
|
+
string(TOUPPER "${_field}" _FIELD)
|
|
183
|
+
if(_MIK_${_FIELD} STREQUAL "")
|
|
184
|
+
string(JSON _MIK_${_FIELD} ERROR_VARIABLE _MIK_FIELD_ERROR
|
|
185
|
+
GET "${_MIK_PROJECT_PACKAGE}" ${_field})
|
|
186
|
+
if(_MIK_FIELD_ERROR)
|
|
187
|
+
set(_MIK_${_FIELD} "")
|
|
188
|
+
endif()
|
|
189
|
+
endif()
|
|
190
|
+
endforeach()
|
|
190
191
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
|
|
191
|
-
"${
|
|
192
|
+
"${_MIK_FW_DIR}/package.json")
|
|
193
|
+
endif()
|
|
194
|
+
# STREQUAL, not if(_MIK_NAME): a project named "0", "off", or "false" would read
|
|
195
|
+
# as a false constant and silently lose its name.
|
|
196
|
+
if(NOT _MIK_NAME STREQUAL "")
|
|
197
|
+
# The device keeps the name in a 64-byte buffer, and a registry rejects a
|
|
198
|
+
# check-in whose board name has another form.
|
|
199
|
+
string(LENGTH "${_MIK_NAME}" _MIK_NAME_LENGTH)
|
|
200
|
+
if(_MIK_NAME_LENGTH GREATER 63 OR NOT _MIK_NAME MATCHES
|
|
201
|
+
"^(@[a-z0-9][a-z0-9._-]*/)?[a-z0-9][a-z0-9._-]*(/[a-z0-9]([a-z0-9.-]*[a-z0-9])?)?$")
|
|
202
|
+
message(FATAL_ERROR
|
|
203
|
+
"mikrojs: the board name is \"${_MIK_NAME}\". A board name has at most 63 "
|
|
204
|
+
"characters and the form of a package name, optionally followed by /<board> "
|
|
205
|
+
"(lowercase letters, digits, '.' and '-'). Set MIKROJS_BOARD_NAME.")
|
|
206
|
+
endif()
|
|
207
|
+
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_BOARD_NAME=\"${_MIK_NAME}\"")
|
|
192
208
|
endif()
|
|
193
209
|
|
|
194
210
|
# UTC build timestamp. `string(TIMESTAMP ... UTC)` honors SOURCE_DATE_EPOCH
|
|
@@ -198,19 +214,21 @@ endif()
|
|
|
198
214
|
string(TIMESTAMP _MIK_BUILD_DATE_UTC "%Y-%m-%dT%H:%M:%SZ" UTC)
|
|
199
215
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_BUILD_DATE_UTC=\"${_MIK_BUILD_DATE_UTC}\"")
|
|
200
216
|
|
|
201
|
-
#
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
string(
|
|
206
|
-
if(NOT "$ENV{MIKROJS_BOARD}" MATCHES "^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$" OR _MIK_BOARD_NAME_LEN GREATER 47)
|
|
207
|
-
message(FATAL_ERROR
|
|
208
|
-
"mikrojs: MIKROJS_BOARD is \"$ENV{MIKROJS_BOARD}\". A board name has at most 47 "
|
|
209
|
-
"characters: lowercase letters, digits, '.' and '-', and it starts and ends with a "
|
|
210
|
-
"letter or digit.")
|
|
211
|
-
endif()
|
|
212
|
-
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_BOARD_NAME=\"$ENV{MIKROJS_BOARD}\"")
|
|
217
|
+
# firmware.json next to flasher_args.json: what the image is, for the tools
|
|
218
|
+
# that read it without a device (mikro flash, mikro fw pack and prepack).
|
|
219
|
+
set(_MIK_FW_JSON "{")
|
|
220
|
+
if(NOT _MIK_NAME STREQUAL "")
|
|
221
|
+
string(APPEND _MIK_FW_JSON "\"name\": \"${_MIK_NAME}\", ")
|
|
213
222
|
endif()
|
|
223
|
+
if(NOT _MIK_DESCRIPTION STREQUAL "")
|
|
224
|
+
# Free text: escape it for JSON, on one line.
|
|
225
|
+
string(REPLACE "\\" "\\\\" _MIK_DESCRIPTION "${_MIK_DESCRIPTION}")
|
|
226
|
+
string(REPLACE "\"" "\\\"" _MIK_DESCRIPTION "${_MIK_DESCRIPTION}")
|
|
227
|
+
string(REGEX REPLACE "[\r\n\t]+" " " _MIK_DESCRIPTION "${_MIK_DESCRIPTION}")
|
|
228
|
+
string(APPEND _MIK_FW_JSON "\"description\": \"${_MIK_DESCRIPTION}\", ")
|
|
229
|
+
endif()
|
|
230
|
+
string(APPEND _MIK_FW_JSON "\"chip\": \"${IDF_TARGET}\", \"version\": \"${_MIK_VERSION}\"}\n")
|
|
231
|
+
file(WRITE "${CMAKE_BINARY_DIR}/firmware.json" "${_MIK_FW_JSON}")
|
|
214
232
|
|
|
215
233
|
# ── Module lists derived from runtime/modules.json ───────────────────
|
|
216
234
|
# Feature gating for the derived lists: ble-gated modules compile only when
|
|
@@ -227,38 +245,23 @@ else()
|
|
|
227
245
|
set(_MIK_WIFI_FLAG "--wifi=off")
|
|
228
246
|
endif()
|
|
229
247
|
|
|
230
|
-
# Firmware feature list (e.g. "wifi,i2s,ble"), reported in MSG_READY so the
|
|
231
|
-
# host knows which feature-gated builtins this firmware carries.
|
|
232
248
|
execute_process(
|
|
233
|
-
COMMAND node "${MIK_SCRIPTS_DIR}/modules-list.js"
|
|
234
|
-
OUTPUT_VARIABLE
|
|
249
|
+
COMMAND node "${MIK_SCRIPTS_DIR}/modules-list.js" ${_MIK_BLE_FLAG} ${_MIK_WIFI_FLAG}
|
|
250
|
+
OUTPUT_VARIABLE _MIK_LISTS
|
|
235
251
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
236
|
-
RESULT_VARIABLE
|
|
252
|
+
RESULT_VARIABLE _MIK_LISTS_RESULT
|
|
237
253
|
)
|
|
238
|
-
if(NOT
|
|
239
|
-
message(FATAL_ERROR "modules-list.js
|
|
254
|
+
if(NOT _MIK_LISTS_RESULT EQUAL 0)
|
|
255
|
+
message(FATAL_ERROR "modules-list.js failed")
|
|
240
256
|
endif()
|
|
257
|
+
string(JSON _MIK_FEATURES GET "${_MIK_LISTS}" features)
|
|
258
|
+
string(JSON _MIK_MODULES GET "${_MIK_LISTS}" native)
|
|
259
|
+
string(JSON _MIK_BYTECODE_MODULES GET "${_MIK_LISTS}" bytecode)
|
|
260
|
+
|
|
261
|
+
# Firmware feature list (e.g. "wifi,i2s,ble"), reported in MSG_READY so the
|
|
262
|
+
# host knows which feature-gated builtins this firmware carries.
|
|
241
263
|
string(REPLACE ";" "," _MIK_FEATURES "${_MIK_FEATURES}")
|
|
242
264
|
target_compile_definitions(${COMPONENT_LIB} PRIVATE "MIK_FW_FEATURES=\"${_MIK_FEATURES}\"")
|
|
243
|
-
|
|
244
|
-
execute_process(
|
|
245
|
-
COMMAND node "${MIK_SCRIPTS_DIR}/modules-list.js" native ${_MIK_BLE_FLAG} ${_MIK_WIFI_FLAG}
|
|
246
|
-
OUTPUT_VARIABLE _MIK_MODULES
|
|
247
|
-
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
248
|
-
RESULT_VARIABLE _MIK_MODULES_RESULT
|
|
249
|
-
)
|
|
250
|
-
if(NOT _MIK_MODULES_RESULT EQUAL 0)
|
|
251
|
-
message(FATAL_ERROR "modules-list.js native failed")
|
|
252
|
-
endif()
|
|
253
|
-
execute_process(
|
|
254
|
-
COMMAND node "${MIK_SCRIPTS_DIR}/modules-list.js" bytecode ${_MIK_BLE_FLAG} ${_MIK_WIFI_FLAG}
|
|
255
|
-
OUTPUT_VARIABLE _MIK_BYTECODE_MODULES
|
|
256
|
-
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
257
|
-
RESULT_VARIABLE _MIK_BYTECODE_RESULT
|
|
258
|
-
)
|
|
259
|
-
if(NOT _MIK_BYTECODE_RESULT EQUAL 0)
|
|
260
|
-
message(FATAL_ERROR "modules-list.js bytecode failed")
|
|
261
|
-
endif()
|
|
262
265
|
# The lists are read at configure time, so configure must re-run when the
|
|
263
266
|
# table or the script changes.
|
|
264
267
|
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
|
|
@@ -273,8 +276,6 @@ mikrojs_force_include_modules(${_MIK_MODULES})
|
|
|
273
276
|
mikrojs_generate_bytecode(
|
|
274
277
|
RUNTIME_DIR "${MIK_RUNTIME_DIR}"
|
|
275
278
|
MODULES ${_MIK_BYTECODE_MODULES}
|
|
276
|
-
MODULE_PREFIX "mikro"
|
|
277
|
-
SYMBOL_PREFIX "mikro"
|
|
278
279
|
TARGET gen_bytecode
|
|
279
280
|
WORKING_DIRECTORY "${MIKROJS_PROJECT_DIR}"
|
|
280
281
|
)
|
|
@@ -93,7 +93,7 @@ static MIKGpioState* mik__gpio_get(JSContext* ctx, JSValueConst this_val, JSClas
|
|
|
93
93
|
|
|
94
94
|
/* Claims `gpio` for the handle kind, or returns the GpioInUse Result. */
|
|
95
95
|
static JSValue mik__gpio_claim(JSContext* ctx, int gpio, MIKGpioKind kind) {
|
|
96
|
-
return
|
|
96
|
+
return MIK_ClaimGpios(ctx, &gpio, 1, s_owner_names[kind]);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/* Converts a JS value to a pin level. Returns false unless it is the number 0 or 1. */
|
|
@@ -60,7 +60,7 @@ static void mik__i2c_release(MIKI2CState* s) {
|
|
|
60
60
|
i2c_del_master_bus(s->bus);
|
|
61
61
|
s->bus = nullptr;
|
|
62
62
|
const int gpios[] = {s->sda, s->scl};
|
|
63
|
-
|
|
63
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2c");
|
|
64
64
|
s->active = false;
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -129,7 +129,7 @@ static JSValue js_i2c(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
129
129
|
JSValue invalid = mik__gpio_check(ctx, checks, countof(checks));
|
|
130
130
|
if (!JS_IsUndefined(invalid)) return invalid;
|
|
131
131
|
const int gpios[] = {sda, scl};
|
|
132
|
-
JSValue claim_failed =
|
|
132
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, countof(gpios), "I2c");
|
|
133
133
|
if (!JS_IsUndefined(claim_failed)) return claim_failed;
|
|
134
134
|
|
|
135
135
|
i2c_master_bus_config_t bus_cfg = {};
|
|
@@ -143,7 +143,7 @@ static JSValue js_i2c(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
143
143
|
i2c_master_bus_handle_t bus = nullptr;
|
|
144
144
|
esp_err_t err = i2c_new_master_bus(&bus_cfg, &bus);
|
|
145
145
|
if (err != ESP_OK) {
|
|
146
|
-
|
|
146
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2c");
|
|
147
147
|
return mik__result_err_named(ctx, "BusInitFailed", "failed to initialize I2C bus %d: %s",
|
|
148
148
|
(int)port, esp_err_to_name(err));
|
|
149
149
|
}
|
|
@@ -151,7 +151,7 @@ static JSValue js_i2c(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
151
151
|
auto* s = static_cast<MIKI2CState*>(calloc(1, sizeof(MIKI2CState)));
|
|
152
152
|
if (!s) {
|
|
153
153
|
i2c_del_master_bus(bus);
|
|
154
|
-
|
|
154
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2c");
|
|
155
155
|
return JS_ThrowOutOfMemory(ctx);
|
|
156
156
|
}
|
|
157
157
|
s->bus = bus;
|
|
@@ -193,7 +193,7 @@ static void mik__i2s_finalizer(JSRuntime* rt, JSValue val) {
|
|
|
193
193
|
i2s_del_channel(s->rx_chan);
|
|
194
194
|
}
|
|
195
195
|
const int gpios[] = MIK__I2S_GPIOS(s);
|
|
196
|
-
|
|
196
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2s");
|
|
197
197
|
}
|
|
198
198
|
for (int i = 0; i < s->tx_count; i++) {
|
|
199
199
|
MIKI2sTxChunk* c = &s->tx_queue[(s->tx_head + i) % MIK_I2S_TX_QUEUE_DEPTH];
|
|
@@ -362,7 +362,7 @@ static JSValue js_i2s(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
362
362
|
s->din = din;
|
|
363
363
|
|
|
364
364
|
const int gpios[] = MIK__I2S_GPIOS(s);
|
|
365
|
-
JSValue claim_failed =
|
|
365
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, countof(gpios), "I2s");
|
|
366
366
|
if (!JS_IsUndefined(claim_failed)) {
|
|
367
367
|
free(s);
|
|
368
368
|
return claim_failed;
|
|
@@ -374,7 +374,7 @@ static JSValue js_i2s(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
374
374
|
if (err == ESP_OK && !mik__i2s_track(ctx, s)) err = ESP_ERR_NO_MEM;
|
|
375
375
|
if (err != ESP_OK) {
|
|
376
376
|
mik__i2s_del_channels(s);
|
|
377
|
-
|
|
377
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2s");
|
|
378
378
|
free(s);
|
|
379
379
|
return mik__result_err_named(ctx, "ChannelInitFailed", "I2S init failed: %s",
|
|
380
380
|
esp_err_to_name(err));
|
|
@@ -385,7 +385,7 @@ static JSValue js_i2s(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
385
385
|
if (JS_IsException(obj)) {
|
|
386
386
|
mik__i2s_untrack(ctx, s);
|
|
387
387
|
mik__i2s_del_channels(s);
|
|
388
|
-
|
|
388
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2s");
|
|
389
389
|
free(s);
|
|
390
390
|
return obj;
|
|
391
391
|
}
|
|
@@ -421,7 +421,7 @@ static JSValue js_i2s_end(JSContext* ctx, JSValue this_val, int argc, JSValue* a
|
|
|
421
421
|
mik__i2s_untrack(ctx, s);
|
|
422
422
|
mik__i2s_del_channels(s);
|
|
423
423
|
const int gpios[] = MIK__I2S_GPIOS(s);
|
|
424
|
-
|
|
424
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "I2s");
|
|
425
425
|
s->active = false;
|
|
426
426
|
MIK_DropHandle(ctx, this_val);
|
|
427
427
|
return JS_UNDEFINED;
|
|
@@ -565,8 +565,7 @@ void MIK_Main(void) {
|
|
|
565
565
|
* (USB-Serial/JTAG). `printf` goes to newlib stdio, which
|
|
566
566
|
* ESP-IDF routes to UART0 and is invisible over USB. */
|
|
567
567
|
const char* core_word = chip_info.cores == 1 ? "core" : "cores";
|
|
568
|
-
const
|
|
569
|
-
const char* dev_id = plat->get_device_id ? plat->get_device_id() : nullptr;
|
|
568
|
+
const char* dev_id = MIK_GetPlatform()->get_device_id();
|
|
570
569
|
char banner[160];
|
|
571
570
|
int off = 0;
|
|
572
571
|
#ifdef MIK_FW_VERSION
|
|
@@ -577,9 +576,7 @@ void MIK_Main(void) {
|
|
|
577
576
|
JS_GetVersion(), CONFIG_IDF_TARGET);
|
|
578
577
|
#endif
|
|
579
578
|
/* Stable per-board device id (chip MAC as Crockford Base32). */
|
|
580
|
-
|
|
581
|
-
off += snprintf(banner + off, sizeof(banner) - off, " (%s)", dev_id);
|
|
582
|
-
}
|
|
579
|
+
off += snprintf(banner + off, sizeof(banner) - off, " (%s)", dev_id);
|
|
583
580
|
off += snprintf(banner + off, sizeof(banner) - off, ", %d %s", chip_info.cores, core_word);
|
|
584
581
|
if (has_wifi || has_bt || has_ble) {
|
|
585
582
|
off += snprintf(banner + off, sizeof(banner) - off, ", ");
|
|
@@ -213,7 +213,7 @@ static JSValue js_neopixel(JSContext* ctx, JSValue this_val, int argc, JSValue*
|
|
|
213
213
|
JSValue invalid = mik__gpio_check(ctx, &check, 1);
|
|
214
214
|
if (!JS_IsUndefined(invalid)) return invalid;
|
|
215
215
|
const int gpios[] = {gpio};
|
|
216
|
-
JSValue claim_failed =
|
|
216
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, 1, "NeoPixel");
|
|
217
217
|
if (!JS_IsUndefined(claim_failed)) return claim_failed;
|
|
218
218
|
|
|
219
219
|
int bytes_per_led = rgbw ? 4 : 3;
|
|
@@ -186,14 +186,14 @@ static JSValue mik__nvs_kv_remove(JSContext* ctx, JSValue this_val, int argc, JS
|
|
|
186
186
|
esp_err_t err = nvs_erase_key(handle, key);
|
|
187
187
|
JS_FreeCString(ctx, key);
|
|
188
188
|
|
|
189
|
-
|
|
189
|
+
/* A missing key is already removed, not a failure. */
|
|
190
|
+
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
|
190
191
|
nvs_close(handle);
|
|
191
|
-
return JS_NewBool(ctx,
|
|
192
|
+
return JS_NewBool(ctx, true);
|
|
192
193
|
}
|
|
193
|
-
|
|
194
|
-
nvs_commit(handle);
|
|
194
|
+
if (err == ESP_OK) err = nvs_commit(handle);
|
|
195
195
|
nvs_close(handle);
|
|
196
|
-
return JS_NewBool(ctx,
|
|
196
|
+
return JS_NewBool(ctx, err == ESP_OK);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
static JSValue mik__nvs_kv_clear(JSContext* ctx, JSValue this_val, int argc, JSValue* argv,
|
|
@@ -339,9 +339,8 @@ bool env_read_app_version(void* opaque, char* out, size_t out_len) {
|
|
|
339
339
|
const MIKOtaEnv* mik__ota_env_for(MIKRuntime* rt, int bytecode_version) {
|
|
340
340
|
g_state.rt = rt;
|
|
341
341
|
g_state.bytecode_version = bytecode_version;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
snprintf(g_state.device_id, sizeof(g_state.device_id), "%s", id ? id : "");
|
|
342
|
+
snprintf(g_state.device_id, sizeof(g_state.device_id), "%s",
|
|
343
|
+
MIK_GetPlatform()->get_device_id());
|
|
345
344
|
|
|
346
345
|
MIKOtaEnv& env = g_state.env;
|
|
347
346
|
env = {};
|
|
@@ -232,7 +232,7 @@ static JSValue js_pwm(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
232
232
|
invalid = mik__gpio_check(ctx, &check, 1);
|
|
233
233
|
if (!JS_IsUndefined(invalid)) return invalid;
|
|
234
234
|
const int gpios[] = {gpio};
|
|
235
|
-
JSValue claim_failed =
|
|
235
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, 1, "Pwm");
|
|
236
236
|
if (!JS_IsUndefined(claim_failed)) return claim_failed;
|
|
237
237
|
|
|
238
238
|
int ch = mik__pwm_alloc_channel();
|
|
@@ -157,26 +157,29 @@ static JSValue mik__rtc_set(JSContext* ctx, JSValue this_val, int argc, JSValue*
|
|
|
157
157
|
auto* hdr = reinterpret_cast<RtcHeader*>(s_rtc_store);
|
|
158
158
|
uint8_t* data = mik__rtc_data();
|
|
159
159
|
|
|
160
|
-
/*
|
|
160
|
+
/* Check space before changing anything, counting the bytes an existing entry would free, so
|
|
161
|
+
* a failed set keeps the old value and a valid CRC */
|
|
161
162
|
uint8_t* next = nullptr;
|
|
162
163
|
uint8_t* found = mik__rtc_find(key, static_cast<uint8_t>(key_len), &next);
|
|
164
|
+
size_t old_size = (found && next) ? static_cast<size_t>(next - found) : 0;
|
|
165
|
+
size_t used = hdr->data_len - old_size;
|
|
166
|
+
size_t needed = mik__rtc_entry_size(static_cast<uint8_t>(key_len), static_cast<uint16_t>(val_len));
|
|
167
|
+
if (used + needed > MIK_RTC_DATA_CAPACITY) {
|
|
168
|
+
JS_FreeCString(ctx, key);
|
|
169
|
+
return mik__result_err(ctx, MIK_ERR_KV_STORAGE_FULL, 0,
|
|
170
|
+
"RTC memory full (need %zu bytes, %zu available)", needed,
|
|
171
|
+
MIK_RTC_DATA_CAPACITY - used);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Remove existing entry if present */
|
|
163
175
|
if (found && next) {
|
|
164
176
|
uint8_t* end = data + hdr->data_len;
|
|
165
177
|
size_t tail = end - next;
|
|
166
178
|
memmove(found, next, tail);
|
|
167
|
-
hdr->data_len -= static_cast<uint16_t>(
|
|
179
|
+
hdr->data_len -= static_cast<uint16_t>(old_size);
|
|
168
180
|
hdr->entry_count--;
|
|
169
181
|
}
|
|
170
182
|
|
|
171
|
-
/* Check space */
|
|
172
|
-
size_t needed = mik__rtc_entry_size(static_cast<uint8_t>(key_len), static_cast<uint16_t>(val_len));
|
|
173
|
-
if (hdr->data_len + needed > MIK_RTC_DATA_CAPACITY) {
|
|
174
|
-
JS_FreeCString(ctx, key);
|
|
175
|
-
return mik__result_err(ctx, MIK_ERR_KV_STORAGE_FULL, 0,
|
|
176
|
-
"RTC memory full (need %zu bytes, %zu available)", needed,
|
|
177
|
-
MIK_RTC_DATA_CAPACITY - hdr->data_len);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
183
|
/* Append new entry: encode CBOR directly into the RTC store */
|
|
181
184
|
uint8_t* write_pos = data + hdr->data_len;
|
|
182
185
|
write_pos[0] = static_cast<uint8_t>(key_len);
|
|
@@ -250,7 +253,8 @@ static JSValue mik__rtc_remove(JSContext* ctx, JSValue this_val, int argc, JSVal
|
|
|
250
253
|
uint8_t* found = mik__rtc_find(key, static_cast<uint8_t>(key_len), &next);
|
|
251
254
|
JS_FreeCString(ctx, key);
|
|
252
255
|
|
|
253
|
-
|
|
256
|
+
/* A missing key is already removed, not a failure. */
|
|
257
|
+
if (!found || !next) return JS_NewBool(ctx, true);
|
|
254
258
|
|
|
255
259
|
uint8_t* end = data + hdr->data_len;
|
|
256
260
|
size_t tail = end - next;
|
|
@@ -34,7 +34,7 @@ static void mik__spi_release(MIKSPIState* s) {
|
|
|
34
34
|
s->device = nullptr;
|
|
35
35
|
spi_bus_free(s->host);
|
|
36
36
|
const int gpios[] = {s->clk, s->mosi, s->miso, s->cs};
|
|
37
|
-
|
|
37
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Spi");
|
|
38
38
|
s->active = false;
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -95,7 +95,7 @@ static JSValue js_spi(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
95
95
|
JSValue invalid = mik__gpio_check(ctx, checks, countof(checks));
|
|
96
96
|
if (!JS_IsUndefined(invalid)) return invalid;
|
|
97
97
|
const int gpios[] = {clk, mosi, miso, cs};
|
|
98
|
-
JSValue claim_failed =
|
|
98
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, countof(gpios), "Spi");
|
|
99
99
|
if (!JS_IsUndefined(claim_failed)) return claim_failed;
|
|
100
100
|
|
|
101
101
|
/* SPI2_HOST is 1, SPI3_HOST is 2, etc. — host maps directly */
|
|
@@ -110,7 +110,7 @@ static JSValue js_spi(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
110
110
|
|
|
111
111
|
esp_err_t err = spi_bus_initialize(host_id, &bus_cfg, SPI_DMA_CH_AUTO);
|
|
112
112
|
if (err != ESP_OK) {
|
|
113
|
-
|
|
113
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Spi");
|
|
114
114
|
return mik__result_err_named(ctx, "BusInitFailed", "SPI bus init failed: %s",
|
|
115
115
|
esp_err_to_name(err));
|
|
116
116
|
}
|
|
@@ -129,7 +129,7 @@ static JSValue js_spi(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
129
129
|
err = spi_bus_add_device(host_id, &dev_cfg, &device);
|
|
130
130
|
if (err != ESP_OK) {
|
|
131
131
|
spi_bus_free(host_id);
|
|
132
|
-
|
|
132
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Spi");
|
|
133
133
|
return mik__result_err_named(ctx, "AddDeviceFailed", "failed to add SPI device: %s",
|
|
134
134
|
esp_err_to_name(err));
|
|
135
135
|
}
|
|
@@ -138,7 +138,7 @@ static JSValue js_spi(JSContext* ctx, JSValue this_val, int argc, JSValue* argv)
|
|
|
138
138
|
if (!s) {
|
|
139
139
|
spi_bus_remove_device(device);
|
|
140
140
|
spi_bus_free(host_id);
|
|
141
|
-
|
|
141
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Spi");
|
|
142
142
|
return JS_ThrowOutOfMemory(ctx);
|
|
143
143
|
}
|
|
144
144
|
s->device = device;
|
|
@@ -74,7 +74,7 @@ static void mik__uart_release(MIKRuntime* mik_rt, MIKUartState* s) {
|
|
|
74
74
|
mik__uart_untrack(mik_rt, s);
|
|
75
75
|
uart_driver_delete(s->port);
|
|
76
76
|
const int gpios[] = {s->tx_pin, s->rx_pin};
|
|
77
|
-
|
|
77
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
78
78
|
s->active = false;
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -130,7 +130,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
130
130
|
JSValue invalid = mik__gpio_check(ctx, checks, countof(checks));
|
|
131
131
|
if (!JS_IsUndefined(invalid)) return invalid;
|
|
132
132
|
const int gpios[] = {tx, rx};
|
|
133
|
-
JSValue claim_failed =
|
|
133
|
+
JSValue claim_failed = MIK_ClaimGpios(ctx, gpios, countof(gpios), "Uart");
|
|
134
134
|
if (!JS_IsUndefined(claim_failed)) return claim_failed;
|
|
135
135
|
|
|
136
136
|
auto uart_port = static_cast<uart_port_t>(port);
|
|
@@ -138,7 +138,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
138
138
|
* refused before uart_param_config and uart_set_pin can change its baud
|
|
139
139
|
* rate and pins. */
|
|
140
140
|
if (uart_is_driver_installed(uart_port)) {
|
|
141
|
-
|
|
141
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
142
142
|
return mik__result_err_named(ctx, "DriverInstallFailed", "port %d is already in use",
|
|
143
143
|
(int)port);
|
|
144
144
|
}
|
|
@@ -153,7 +153,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
153
153
|
|
|
154
154
|
esp_err_t err = uart_param_config(uart_port, &uart_config);
|
|
155
155
|
if (err != ESP_OK) {
|
|
156
|
-
|
|
156
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
157
157
|
return mik__result_err_named(ctx, "InvalidParam",
|
|
158
158
|
"uart_param_config failed on port %d: %s", (int)port,
|
|
159
159
|
esp_err_to_name(err));
|
|
@@ -162,7 +162,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
162
162
|
err = uart_set_pin(uart_port, tx >= 0 ? tx : UART_PIN_NO_CHANGE,
|
|
163
163
|
rx >= 0 ? rx : UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
|
|
164
164
|
if (err != ESP_OK) {
|
|
165
|
-
|
|
165
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
166
166
|
return mik__result_err_named(ctx, "SetPinFailed",
|
|
167
167
|
"uart_set_pin failed on port %d (tx=%d, rx=%d): %s", (int)port,
|
|
168
168
|
tx, rx, esp_err_to_name(err));
|
|
@@ -173,7 +173,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
173
173
|
int rx_buf = rx >= 0 ? MIK_UART_RX_BUF_SIZE : UART_HW_FIFO_LEN(uart_port) + 1;
|
|
174
174
|
err = uart_driver_install(uart_port, rx_buf, 0, 0, nullptr, ESP_INTR_FLAG_IRAM);
|
|
175
175
|
if (err != ESP_OK) {
|
|
176
|
-
|
|
176
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
177
177
|
return mik__result_err_named(ctx, "DriverInstallFailed",
|
|
178
178
|
"uart_driver_install failed on port %d: %s", (int)port,
|
|
179
179
|
esp_err_to_name(err));
|
|
@@ -182,7 +182,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
182
182
|
auto* s = static_cast<MIKUartState*>(calloc(1, sizeof(MIKUartState)));
|
|
183
183
|
if (!s) {
|
|
184
184
|
uart_driver_delete(uart_port);
|
|
185
|
-
|
|
185
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
186
186
|
return JS_ThrowOutOfMemory(ctx);
|
|
187
187
|
}
|
|
188
188
|
s->port = uart_port;
|
|
@@ -194,7 +194,7 @@ static JSValue js_uart(JSContext* ctx, JSValue this_val, int argc, JSValue* argv
|
|
|
194
194
|
JSValue obj = JS_NewObjectClass(ctx, mik_uart_class_id);
|
|
195
195
|
if (JS_IsException(obj)) {
|
|
196
196
|
uart_driver_delete(uart_port);
|
|
197
|
-
|
|
197
|
+
MIK_ReleaseGpios(gpios, countof(gpios), "Uart");
|
|
198
198
|
free(s);
|
|
199
199
|
return obj;
|
|
200
200
|
}
|
|
@@ -300,9 +300,7 @@ static bool mik__wifi_apply_hostname(JSContext* ctx) {
|
|
|
300
300
|
hostname = buf;
|
|
301
301
|
}
|
|
302
302
|
if (!hostname) {
|
|
303
|
-
|
|
304
|
-
if (!dev_id || !dev_id[0]) return false;
|
|
305
|
-
snprintf(buf, sizeof(buf), "mikrojs-%s", dev_id);
|
|
303
|
+
snprintf(buf, sizeof(buf), "mikrojs-%s", MIK_GetPlatform()->get_device_id());
|
|
306
304
|
hostname = buf;
|
|
307
305
|
}
|
|
308
306
|
return esp_netif_set_hostname(s_sta_netif, hostname) == ESP_OK;
|