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,315 @@
const sys = @import("sys");
const errors = @import("error");
// ---------------------------------------------------------------------------
// Re-exported types from sys
// ---------------------------------------------------------------------------
pub const WifiInterface = sys.wifi_interface_t;
pub const WifiPktRxCtrl = sys.wifi_pkt_rx_ctrl_t;
pub const WifiTxInfo = sys.wifi_tx_info_t;
pub const WifiTxRateConfig = sys.wifi_tx_rate_config_t;
pub const WifiActionTx = sys.wifi_action_tx_t;
pub const WifiSecondChan = sys.wifi_second_chan_t;
pub const WifiRoc = sys.wifi_roc_t;
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
pub const MAC_LEN = 6;
pub const LMK_LEN = 16;
pub const PMK_LEN = 16;
pub const OUI_LEN = 3;
// ---------------------------------------------------------------------------
// Send status
// ---------------------------------------------------------------------------
pub const SendStatus = enum(c_uint) {
success = 0,
fail = 1,
};
// ---------------------------------------------------------------------------
// Peer info
// ---------------------------------------------------------------------------
pub const PeerInfo = extern struct {
peer_addr: [MAC_LEN]u8 = .{0} ** MAC_LEN,
lmk: [LMK_LEN]u8 = .{0} ** LMK_LEN,
channel: u8 = 0,
ifidx: WifiInterface = undefined,
encrypt: bool = false,
priv: ?*anyopaque = null,
};
pub const PeerNum = extern struct {
total_num: c_int = 0,
encrypt_num: c_int = 0,
};
// ---------------------------------------------------------------------------
// Receive info (passed to the recv callback)
// ---------------------------------------------------------------------------
pub const RecvInfo = extern struct {
src_addr: [*c]u8 = null,
des_addr: [*c]u8 = null,
rx_ctrl: ?*WifiPktRxCtrl = null,
};
// ---------------------------------------------------------------------------
// Switch-channel / remain-on-channel action structs
// ---------------------------------------------------------------------------
pub const SwitchChannel = extern struct {
type: WifiActionTx = undefined,
channel: u8 = 0,
sec_channel: WifiSecondChan = undefined,
wait_time_ms: u32 = 0,
op_id: u8 = 0,
dest_mac: [MAC_LEN]u8 = .{0} ** MAC_LEN,
data_len: u16 = 0,
_data: [0]u8 = .{},
};
pub const RemainOnChannel = extern struct {
type: WifiRoc = undefined,
channel: u8 = 0,
sec_channel: WifiSecondChan = undefined,
wait_time_ms: u32 = 0,
op_id: u8 = 0,
};
// ---------------------------------------------------------------------------
// Callback types — use these in your application; cast to/from the C type
// at registration time via the EspNow.registerRecvCb / registerSendCb wrappers.
// ---------------------------------------------------------------------------
pub const RecvCb = *const fn (
info: *const RecvInfo,
data: [*]const u8,
data_len: usize,
) void;
pub const SendCb = *const fn (
tx_info: *const WifiTxInfo,
status: SendStatus,
) void;
// Internal C-ABI adapters stored when a Zig callback is registered.
var recv_cb_zig: ?RecvCb = null;
var send_cb_zig: ?SendCb = null;
fn recvCbAdapter(
info: [*c]const sys.esp_now_recv_info_t,
data: [*c]const u8,
data_len: c_int,
) callconv(.c) void {
if (recv_cb_zig) |cb|
cb(@ptrCast(info), data, @intCast(data_len));
}
fn sendCbAdapter(
tx_info: [*c]const sys.esp_now_send_info_t,
status: sys.esp_now_send_status_t,
) callconv(.c) void {
if (send_cb_zig) |cb|
cb(@ptrCast(tx_info), @enumFromInt(status));
}
// ---------------------------------------------------------------------------
// EspNow namespace
// ---------------------------------------------------------------------------
pub const EspNow = struct {
// -- Lifecycle -----------------------------------------------------------
pub fn init() !void {
try errors.espCheckError(sys.esp_now_init());
}
pub fn deinit() !void {
try errors.espCheckError(sys.esp_now_deinit());
}
pub fn getVersion() !u32 {
var ver: u32 = 0;
try errors.espCheckError(sys.esp_now_get_version(&ver));
return ver;
}
// -- Callbacks -----------------------------------------------------------
/// Register a Zig-typed receive callback.
pub fn registerRecvCb(cb: RecvCb) !void {
recv_cb_zig = cb;
try errors.espCheckError(sys.esp_now_register_recv_cb(recvCbAdapter));
}
pub fn unregisterRecvCb() !void {
recv_cb_zig = null;
try errors.espCheckError(sys.esp_now_unregister_recv_cb());
}
/// Register a Zig-typed send callback.
pub fn registerSendCb(cb: SendCb) !void {
send_cb_zig = cb;
try errors.espCheckError(sys.esp_now_register_send_cb(sendCbAdapter));
}
pub fn unregisterSendCb() !void {
send_cb_zig = null;
try errors.espCheckError(sys.esp_now_unregister_send_cb());
}
// -- Sending -------------------------------------------------------------
/// Send data to a peer.
/// `peer_addr` — 6-byte MAC or null for broadcast.
/// `data` — payload slice (max 250 bytes).
pub fn send(peer_addr: ?*const [MAC_LEN]u8, data: []const u8) !void {
const addr_ptr: [*c]const u8 = if (peer_addr) |a| a else null;
try errors.espCheckError(sys.esp_now_send(addr_ptr, data.ptr, data.len));
}
// -- Peer management -----------------------------------------------------
pub fn addPeer(peer: *const PeerInfo) !void {
try errors.espCheckError(sys.esp_now_add_peer(@ptrCast(peer)));
}
pub fn delPeer(peer_addr: *const [MAC_LEN]u8) !void {
try errors.espCheckError(sys.esp_now_del_peer(peer_addr));
}
pub fn modPeer(peer: *const PeerInfo) !void {
try errors.espCheckError(sys.esp_now_mod_peer(@ptrCast(peer)));
}
pub fn setPeerRateConfig(
peer_addr: *const [MAC_LEN]u8,
config: *WifiTxRateConfig,
) !void {
try errors.espCheckError(sys.esp_now_set_peer_rate_config(peer_addr, config));
}
pub fn getPeer(peer_addr: *const [MAC_LEN]u8) !PeerInfo {
var info: PeerInfo = undefined;
try errors.espCheckError(sys.esp_now_get_peer(peer_addr, @ptrCast(&info)));
return info;
}
/// Iterate over the peer list.
/// Pass `from_head = true` on the first call, then `false` to continue.
pub fn fetchPeer(from_head: bool) !PeerInfo {
var info: PeerInfo = undefined;
try errors.espCheckError(sys.esp_now_fetch_peer(from_head, @ptrCast(&info)));
return info;
}
pub fn isPeerExist(peer_addr: *const [MAC_LEN]u8) bool {
return sys.esp_now_is_peer_exist(peer_addr);
}
pub fn getPeerNum() !PeerNum {
var num: PeerNum = undefined;
try errors.espCheckError(sys.esp_now_get_peer_num(@ptrCast(&num)));
return num;
}
// -- Security ------------------------------------------------------------
/// Set the Primary Master Key (16 bytes).
pub fn setPmk(pmk: *const [PMK_LEN]u8) !void {
try errors.espCheckError(sys.esp_now_set_pmk(pmk));
}
// -- Power saving --------------------------------------------------------
pub fn setWakeWindow(window: u16) !void {
try errors.espCheckError(sys.esp_now_set_wake_window(window));
}
// -- OUI -----------------------------------------------------------------
/// Set user OUI (3 bytes).
pub fn setUserOui(oui: *[OUI_LEN]u8) !void {
try errors.espCheckError(sys.esp_now_set_user_oui(oui));
}
/// Get user OUI (3 bytes).
pub fn getUserOui(oui: *[OUI_LEN]u8) !void {
try errors.espCheckError(sys.esp_now_get_user_oui(oui));
}
// -- Channel actions -----------------------------------------------------
pub fn switchChannel(config: *SwitchChannel) !void {
try errors.espCheckError(sys.esp_now_switch_channel_tx(@ptrCast(config)));
}
pub fn remainOnChannel(config: *RemainOnChannel) !void {
try errors.espCheckError(sys.esp_now_remain_on_channel(@ptrCast(config)));
}
};
// ---------------------------------------------------------------------------
// SmartConfig — bundled here because the raw bindings file included it.
// ---------------------------------------------------------------------------
pub const SmartconfigType = enum(c_uint) {
esptouch = 0,
airkiss = 1,
esptouch_airkiss = 2,
esptouch_v2 = 3,
};
pub const SmartconfigEvent = enum(c_uint) {
scan_done = 0,
found_channel = 1,
got_ssid_pswd = 2,
send_ack_done = 3,
};
pub const SmartconfigGotSsidPswd = extern struct {
ssid: [32]u8 = .{0} ** 32,
password: [64]u8 = .{0} ** 64,
bssid_set: bool = false,
bssid: [MAC_LEN]u8 = .{0} ** MAC_LEN,
type: SmartconfigType = .esptouch,
token: u8 = 0,
cellphone_ip: [4]u8 = .{0} ** 4,
};
pub const SmartConfig = struct {
pub fn getVersion() [*:0]const u8 {
return sys.esp_smartconfig_get_version();
}
pub fn start(config: *const sys.smartconfig_start_config_t) !void {
try errors.espCheckError(sys.esp_smartconfig_start(config));
}
pub fn stop() !void {
try errors.espCheckError(sys.esp_smartconfig_stop());
}
pub fn setTimeout(time_s: u8) !void {
try errors.espCheckError(sys.esp_esptouch_set_timeout(time_s));
}
pub fn setType(kind: SmartconfigType) !void {
try errors.espCheckError(sys.esp_smartconfig_set_type(@intFromEnum(kind)));
}
pub fn setFastMode(enable: bool) !void {
try errors.espCheckError(sys.esp_smartconfig_fast_mode(enable));
}
pub fn getRvdData(buf: []u8) !void {
try errors.espCheckError(sys.esp_smartconfig_get_rvd_data(buf.ptr, @intCast(buf.len)));
}
};