Added the zig_main project to software for zig based implementation of code for robot

This commit is contained in:
2026-05-05 20:14:04 +12:00
parent 7d752f2534
commit f21f909a71
83 changed files with 13631 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
set(DEPS nvs_flash)
if(CONFIG_ESP_WIFI_ENABLED)
list(APPEND DEPS esp_wifi esp_netif esp_event)
endif()
if(CONFIG_BT_ENABLED)
list(APPEND DEPS bt)
endif()
set(MAIN_SRCS "placeholder.c")
# Add C++ Matter wrapper shim only when esp_matter is an active build component.
# The component must be added via idf.py add-dependency espressif/esp_matter.
# Note: esp_matter 1.4.x is not yet compatible with IDF v6.0 (requires json/mqtt builtins).
if(TARGET __idf_espressif__esp_matter AND IDF_VERSION_MAJOR LESS 6)
list(APPEND MAIN_SRCS "matter_wrappers.cpp")
list(APPEND DEPS espressif__esp_matter)
message(STATUS "ESP Matter: C++ wrapper shim enabled")
endif()
idf_component_register(
SRCS ${MAIN_SRCS}
INCLUDE_DIRS "." "${CMAKE_SOURCE_DIR}/include"
REQUIRES ${DEPS}
)
# Build your project or examples
set(ZIG_EXAMPLE_ARG "") # default is main/app.zig
if(CONFIG_ZIG_EXAMPLE_SMARTLED_RGB)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/smartled-rgb.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_WIFI_STATION AND CONFIG_ESP_WIFI_ENABLED)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/wifi-station.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_DSP_MATH)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/dsp-math.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_GPIO_BLINK)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/gpio-blink.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_HTTP_SERVER)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/http-server.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_BLE_GATT_SERVER AND CONFIG_BT_ENABLED)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/ble-gatt-server.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_I2C_SCAN)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/i2c-scan.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_UART_ECHO)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/uart-echo.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
elseif(CONFIG_ZIG_EXAMPLE_MATTER_LIGHT)
set(ZIG_ROOT_EXAMPLE_SOURCE "main/examples/matter-light.zig")
set(ZIG_EXAMPLE_ARG "-Dexample=${ZIG_ROOT_EXAMPLE_SOURCE}")
endif()
if(ZIG_EXAMPLE_ARG)
message(STATUS "Zig Example: ${ZIG_ROOT_EXAMPLE_SOURCE}")
else()
message(STATUS "Zig Example: using default (main/app.zig)")
endif()
include(${CMAKE_SOURCE_DIR}/cmake/zig-config.cmake)
# FIXME: need add <cmath> for build kalman
if(TARGET __idf_espressif__esp-dsp AND IDF_VERSION_MAJOR EQUAL 6)
target_compile_options(__idf_espressif__esp-dsp PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-includecmath>
)
endif()
# CHIP SDK: suppress -Werror=format-nonliteral warnings-as-errors that GCC 14
# raises on format strings forwarded through function pointers (BLEManagerImpl etc.).
if(TARGET __idf_espressif__esp_matter AND IDF_VERSION_MAJOR LESS 6)
target_compile_options(__idf_espressif__esp_matter PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:-Wno-error=format-nonliteral>
)
endif()
# CHIP SDK closure-control cluster structs are missing operator==(const T&), which
# GCC 14 C++23 mode rejects when used in std::optional comparisons.
# Inject a patch header via -include on only the two failing translation units so
# that the types satisfy std::equality_comparable without touching managed_components.
if(TARGET __idf_espressif__esp_matter AND IDF_VERSION_MAJOR LESS 6)
set(_CHIP_CLOSURE_DIR
"${CMAKE_SOURCE_DIR}/managed_components/espressif__esp_matter/connectedhomeip/connectedhomeip/src/app/clusters/closure-control-server"
)
set_source_files_properties(
"${_CHIP_CLOSURE_DIR}/closure-control-cluster-logic.cpp"
"${_CHIP_CLOSURE_DIR}/closure-control-server.cpp"
DIRECTORY "${CMAKE_SOURCE_DIR}/managed_components/espressif__esp_matter"
PROPERTIES COMPILE_FLAGS
"-include${CMAKE_SOURCE_DIR}/include/matter_closure_patch.h"
)
unset(_CHIP_CLOSURE_DIR)
endif()

View File

@@ -0,0 +1,67 @@
menu "Example Configuration"
config ESP_WIFI_SSID
string "WiFi SSID"
default "myssid"
help
SSID (network name) for the example to connect to.
config ESP_WIFI_PASSWORD
string "WiFi Password"
default "mypassword"
help
WiFi password (WPA or WPA2) for the example to use.
choice ESP_WIFI_SAE_MODE
prompt "WPA3 SAE mode selection"
default ESP_WPA3_SAE_PWE_BOTH
help
Select mode for SAE as Hunt and Peck, H2E or both.
config ESP_WPA3_SAE_PWE_HUNT_AND_PECK
bool "HUNT AND PECK"
config ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT
bool "H2E"
config ESP_WPA3_SAE_PWE_BOTH
bool "BOTH"
endchoice
config ESP_WIFI_PW_ID
string "PASSWORD IDENTIFIER"
depends on ESP_WPA3_SAE_PWE_HASH_TO_ELEMENT|| ESP_WPA3_SAE_PWE_BOTH
default ""
help
password identifier for SAE H2E
config ESP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
prompt "WiFi Scan auth mode threshold"
default ESP_WIFI_AUTH_WPA2_PSK
help
The weakest authmode to accept in the scan mode.
This value defaults to ESP_WIFI_AUTH_WPA2_PSK incase password is present and ESP_WIFI_AUTH_OPEN is used.
Please select ESP_WIFI_AUTH_WEP/ESP_WIFI_AUTH_WPA_PSK incase AP is operating in WEP/WPA mode.
config ESP_WIFI_AUTH_OPEN
bool "OPEN"
config ESP_WIFI_AUTH_WEP
bool "WEP"
config ESP_WIFI_AUTH_WPA_PSK
bool "WPA PSK"
config ESP_WIFI_AUTH_WPA2_PSK
bool "WPA2 PSK"
config ESP_WIFI_AUTH_WPA_WPA2_PSK
bool "WPA/WPA2 PSK"
config ESP_WIFI_AUTH_WPA3_PSK
bool "WPA3 PSK"
config ESP_WIFI_AUTH_WPA2_WPA3_PSK
bool "WPA2/WPA3 PSK"
config ESP_WIFI_AUTH_WAPI_PSK
bool "WAPI PSK"
endchoice
endmenu

View File

@@ -0,0 +1,121 @@
const std = @import("std");
const builtin = @import("builtin");
const idf = @import("esp_idf");
const ver = idf.ver.Version;
const mem = std.mem;
comptime {
@export(&main, .{ .name = "app_main" });
}
fn main() callconv(.c) void {
// This allocator is safe to use as the backing allocator w/ arena allocator
// custom allocators (based on old raw_c_allocator)
// idf.heap.HeapCapsAllocator
// idf.heap.MultiHeapAllocator
// idf.heap.VPortAllocator
var heap = idf.heap.HeapCapsAllocator.init(.{ .@"8bit" = true });
var arena = std.heap.ArenaAllocator.init(heap.allocator());
defer arena.deinit();
const allocator = arena.allocator();
log.info("Hello, world from Zig!", .{});
log.info(
\\[Zig Info]
\\* Version: {s}
\\* Compiler Backend: {s}
, .{
@as([]const u8, builtin.zig_version_string),
@tagName(builtin.zig_backend),
});
log.info(
\\[ESP-IDF Info]
\\* Version: {s}
, .{ver.get().toString(allocator)});
log.info(
\\[Memory Info]
\\* Total: {d}
\\* Free: {d}
\\* Minimum: {d}
, .{
heap.totalSize(),
heap.freeSize(),
heap.minimumFreeSize(),
});
log.info("Let's have a look at your shiny {s} - {s} system! :)", .{
@tagName(builtin.cpu.arch),
builtin.cpu.model.name,
});
arraylist(allocator) catch |err| {
log.err("Error: {s}", .{@errorName(err)});
};
if (builtin.mode == .Debug)
heap.dump();
// FreeRTOS Tasks — Task.create returns !Handle; on failure panic with a clear message.
_ = idf.rtos.Task.create(fooTask, "foo", 1024 * 3, null, 1) catch @panic("Task foo not created");
_ = idf.rtos.Task.create(barTask, "bar", 1024 * 3, null, 2) catch @panic("Task bar not created");
_ = idf.rtos.Task.create(blinkTask, "blink", 1024 * 2, null, 5) catch @panic("Task blink not created");
}
fn blinkLED(delay_ms: u32) !void {
try idf.gpio.Direction.set(.@"18", .output);
while (true) {
log.info("LED: ON", .{});
try idf.gpio.Level.set(.@"18", 1);
idf.rtos.Task.delayMs(delay_ms);
log.info("LED: OFF", .{});
try idf.gpio.Level.set(.@"18", 0);
idf.rtos.Task.delayMs(delay_ms);
}
}
fn arraylist(allocator: mem.Allocator) !void {
var arr: std.ArrayList(u32) = .empty;
defer arr.deinit(allocator);
try arr.append(allocator, 10);
try arr.append(allocator, 20);
try arr.append(allocator, 30);
for (arr.items) |value| {
idf.log.ESP_LOG(allocator, idf.log.default_level, "EXAMPLE", "Arr value: {}\n", .{value});
}
}
export fn blinkTask(_: ?*anyopaque) callconv(.c) void {
blinkLED(1000) catch |err| @panic(@errorName(err));
}
export fn fooTask(_: ?*anyopaque) callconv(.c) void {
while (true) {
log.info("Demo_Task foo printing..", .{});
idf.rtos.Task.delayMs(2000);
}
}
export fn barTask(_: ?*anyopaque) callconv(.c) void {
while (true) {
log.info("Demo_Task bar printing..", .{});
idf.rtos.Task.delayMs(1000);
}
}
pub const panic = idf.esp_panic.panic;
const log = std.log.scoped(idf.log.default_log_scope);
pub const std_options: std.Options = .{
.log_level = switch (builtin.mode) {
.Debug => .debug,
else => .info,
},
.logFn = idf.log.espLogFn,
};

View File

@@ -0,0 +1,16 @@
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf:
version: '>=5.3.0'
# # Put list of dependencies here
# # For components maintained by Espressif:
# component: "~1.0.0"
# # For 3rd party components:
# username/component: ">=1.0.0,<2.0.0"
# username2/component2:
# version: "~1.0.0"
# # For transient dependencies `public` flag can be set.
# # `public` flag doesn't have an effect dependencies of the `main` component.
# # All dependencies of `main` are public by default.
# public: true

View File

@@ -0,0 +1,190 @@
/*
* matter_wrappers.cpp — extern "C" shims that bridge the C wrapper interface
* (matter_stubs.h) to the C++ esp_matter API.
*
* This file is compiled as C++ by the ESP-IDF CMake build, giving it full
* access to CHIP SDK headers and the esp_matter C++ namespace.
*/
#include <esp_err.h>
#include <esp_matter.h>
#include <esp_matter_core.h>
#include <esp_matter_identify.h>
#include <esp_matter_attribute_utils.h>
#include <esp_matter_endpoint.h>
#include <esp_matter_cluster.h>
#include <esp_matter_attribute.h>
#include <esp_matter_data_model.h>
#include <esp_log.h>
#include "matter_stubs.h"
static const char *TAG = "matter_wrap";
/* ── Type alias shorthands ────────────────────────────────────────────────── */
using namespace esp_matter;
/* ── Callback adapter types ───────────────────────────────────────────────── */
/*
* The C callback types in matter_stubs.h are binary-compatible with the C++
* types declared in esp_matter_attribute_utils.h and esp_matter_identify.h.
* We use reinterpret_cast to pass them across the ABI boundary.
*/
static attribute::callback_t s_attr_cb = nullptr;
static identification::callback_t s_ident_cb = nullptr;
/* ── Core ─────────────────────────────────────────────────────────────────── */
extern "C" esp_err_t esp_matter_wrapper_start(
esp_matter_attr_callback_t attr_cb,
esp_matter_identify_callback_t identify_cb)
{
s_attr_cb = reinterpret_cast<attribute::callback_t>(attr_cb);
s_ident_cb = reinterpret_cast<identification::callback_t>(identify_cb);
return esp_matter::start(nullptr);
}
extern "C" esp_err_t esp_matter_wrapper_factory_reset(void)
{
return esp_matter::factory_reset();
}
extern "C" bool esp_matter_wrapper_is_started(void)
{
return esp_matter::is_started();
}
/* ── Node ─────────────────────────────────────────────────────────────────── */
extern "C" esp_matter_node_t *esp_matter_wrapper_node_create(
esp_matter_attr_callback_t attr_cb,
esp_matter_identify_callback_t identify_cb,
void *priv_data)
{
node::config_t node_cfg;
auto *attr_cpp = reinterpret_cast<attribute::callback_t>(attr_cb);
auto *ident_cpp = reinterpret_cast<identification::callback_t>(identify_cb);
return node::create(&node_cfg, attr_cpp, ident_cpp, priv_data);
}
/* ── Endpoint ─────────────────────────────────────────────────────────────── */
extern "C" esp_matter_endpoint_t *esp_matter_wrapper_endpoint_create(
esp_matter_node_t *node,
uint8_t flags,
void *priv_data)
{
return endpoint::create(node, flags, priv_data);
}
extern "C" esp_err_t esp_matter_wrapper_endpoint_destroy(
esp_matter_node_t *node,
esp_matter_endpoint_t *ep)
{
return endpoint::destroy(node, ep);
}
extern "C" uint16_t esp_matter_wrapper_endpoint_get_id(
esp_matter_endpoint_t *ep)
{
return endpoint::get_id(ep);
}
extern "C" esp_err_t esp_matter_wrapper_endpoint_add_device_type(
esp_matter_endpoint_t *ep,
uint32_t device_type_id,
uint8_t version)
{
return endpoint::add_device_type(ep, device_type_id, version);
}
extern "C" esp_err_t esp_matter_wrapper_endpoint_enable(
esp_matter_endpoint_t *ep)
{
return endpoint::enable(ep);
}
/* ── Pre-built device-type endpoints ─────────────────────────────────────── */
extern "C" esp_matter_endpoint_t *esp_matter_wrapper_add_on_off_light(
esp_matter_node_t *node,
uint8_t flags,
void *priv_data)
{
endpoint::on_off_light::config_t cfg;
return endpoint::on_off_light::create(node, &cfg, flags, priv_data);
}
extern "C" esp_matter_endpoint_t *esp_matter_wrapper_add_on_off_switch(
esp_matter_node_t *node,
uint8_t flags,
void *priv_data)
{
endpoint::on_off_switch::config_t cfg;
return endpoint::on_off_switch::create(node, &cfg, flags, priv_data);
}
extern "C" esp_matter_endpoint_t *esp_matter_wrapper_add_dimmable_light(
esp_matter_node_t *node,
uint8_t flags,
void *priv_data)
{
endpoint::dimmable_light::config_t cfg;
return endpoint::dimmable_light::create(node, &cfg, flags, priv_data);
}
extern "C" esp_matter_endpoint_t *esp_matter_wrapper_add_color_temperature_light(
esp_matter_node_t *node,
uint8_t flags,
void *priv_data)
{
endpoint::color_temperature_light::config_t cfg;
return endpoint::color_temperature_light::create(node, &cfg, flags, priv_data);
}
/* ── Cluster ──────────────────────────────────────────────────────────────── */
extern "C" esp_matter_cluster_t *esp_matter_wrapper_cluster_create(
esp_matter_endpoint_t *ep,
uint32_t cluster_id,
uint8_t flags)
{
return cluster::create(ep, cluster_id, flags);
}
/* ── Attribute ────────────────────────────────────────────────────────────── */
extern "C" esp_matter_attribute_t *esp_matter_wrapper_attribute_create(
esp_matter_cluster_t *cl,
uint32_t attribute_id,
uint16_t flags,
esp_matter_attr_val_t val)
{
return attribute::create(cl, attribute_id, flags, val);
}
extern "C" esp_err_t esp_matter_wrapper_attribute_update(
uint16_t endpoint_id,
uint32_t cluster_id,
uint32_t attribute_id,
esp_matter_attr_val_t *val)
{
return attribute::update(endpoint_id, cluster_id, attribute_id, val);
}
extern "C" esp_err_t esp_matter_wrapper_attribute_get_val(
esp_matter_attribute_t *attr,
esp_matter_attr_val_t *val)
{
return attribute::get_val(attr, val);
}
extern "C" esp_err_t esp_matter_wrapper_attribute_set_val(
esp_matter_attribute_t *attr,
esp_matter_attr_val_t *val)
{
return attribute::set_val(attr, val);
}

View File

@@ -0,0 +1 @@
// empty file