Add gpioset command

This commit is contained in:
Elara 2023-12-25 12:50:17 -08:00
parent 5b2a7bacaa
commit 10cbc36b6b
3 changed files with 93 additions and 1 deletions

View File

@ -16,6 +16,7 @@ const commands = [_]Item{
.{ .name = "gpiodetect", .src = "src/cmd/detect.zig" }, .{ .name = "gpiodetect", .src = "src/cmd/detect.zig" },
.{ .name = "gpioinfo", .src = "src/cmd/info.zig" }, .{ .name = "gpioinfo", .src = "src/cmd/info.zig" },
.{ .name = "gpioget", .src = "src/cmd/get.zig" }, .{ .name = "gpioget", .src = "src/cmd/get.zig" },
.{ .name = "gpioset", .src = "src/cmd/set.zig" },
}; };
pub fn build(b: *std.Build) !void { pub fn build(b: *std.Build) !void {

53
src/cmd/set.zig Normal file
View File

@ -0,0 +1,53 @@
const std = @import("std");
const gpio = @import("gpio");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const alloc = gpa.allocator();
var args = try std.process.argsAlloc(alloc);
defer std.process.argsFree(alloc, args);
const stdout = std.io.getStdOut().writer();
if (args.len < 3) {
try stdout.print("Usage: {s} <gpiochip> <line=value...>\n\n", .{args[0]});
return error.InsufficientArguments;
}
var path: []const u8 = if (hasPrefix(args[1], "gpiochip"))
try std.mem.concat(alloc, u8, &.{ "/dev/", args[1] })
else
try std.mem.concat(alloc, u8, &.{ "/dev/gpiochip", args[1] });
defer alloc.free(path);
var chip = try gpio.getChip(path);
defer chip.close();
try chip.setConsumer("gpioset");
var values = std.AutoArrayHashMap(u32, bool).init(alloc);
defer values.deinit();
// Iterate over each argument starting from the second one
for (args[2..args.len]) |argument| {
// Get the index of the equals sign in the argument
const eqIndex = std.mem.indexOf(u8, argument, "=") orelse return error.InvalidArgument;
// Parse each argument's offset and value, and add it to the values map
var offset = try std.fmt.parseUnsigned(u32, argument[0..eqIndex], 10);
var value = try std.fmt.parseUnsigned(u1, argument[eqIndex + 1 .. argument.len], 10);
try values.put(offset, value != 0);
}
var lines = try chip.requestLines(values.keys(), .{ .output = true });
defer lines.close();
var vals = gpio.uapi.LineValueBitset{ .mask = 0 };
for (0.., values.values()) |i, val| vals.setValue(i, val);
try lines.setAllValues(vals);
}
fn hasPrefix(s: []const u8, prefix: []const u8) bool {
if (s.len < prefix.len) return false;
return (std.mem.eql(u8, s[0..prefix.len], prefix));
}

View File

@ -209,13 +209,44 @@ pub const Lines = struct {
try gpio.uapi.setLineConfig(self.handle, lc); try gpio.uapi.setLineConfig(self.handle, lc);
} }
/// Sets the values of the lines at the given indices.
///
/// Note that this function takes indices and not offsets.
/// The indices correspond to the index of the offset in your request.
/// For example, if you requested `&.{22, 20, 23}`,
/// `22` will correspond to `0`, `20` will correspond to `1`,
/// and `23` will correspond to `2`.
pub fn setValues(self: Lines, indices: []const u32, vals: gpio.uapi.LineValueBitset) !void {
if (self.closed) return error.LineClosed;
var lv = gpio.uapi.LineValues{ .bits = vals };
for (indices) |index| {
if (index >= self.num_lines) return error.IndexOutOfRange;
lv.mask.set(index);
}
return try gpio.uapi.setLineValues(self.handle, lv);
}
/// Sets the values of all the controlled lines
pub fn setAllValues(self: Lines, vals: gpio.uapi.LineValueBitset) !void {
if (self.closed) return error.LineClosed;
var lv = gpio.uapi.LineValues{ .bits = vals };
// Add all the indices to the bitset of values to set
var i: u32 = 0;
while (i < self.num_lines) : (i += 1) lv.mask.set(i);
return try gpio.uapi.setLineValues(self.handle, lv);
}
/// Gets the values of all the controlled lines as a bitset /// Gets the values of all the controlled lines as a bitset
pub fn getValues(self: Lines) !gpio.uapi.LineValueBitset { pub fn getValues(self: Lines) !gpio.uapi.LineValueBitset {
if (self.closed) return error.LineClosed; if (self.closed) return error.LineClosed;
var vals = gpio.uapi.LineValueBitset{ .mask = 0 }; var vals = gpio.uapi.LineValueBitset{ .mask = 0 };
// Add all the indices to the bitset of values to get
var i: u32 = 0; var i: u32 = 0;
// Add all the indices to the list of values to get
while (i < self.num_lines) : (i += 1) vals.set(i); while (i < self.num_lines) : (i += 1) vals.set(i);
return try gpio.uapi.getLineValues(self.handle, vals); return try gpio.uapi.getLineValues(self.handle, vals);
} }
@ -242,6 +273,13 @@ pub const Line = struct {
try self.lines.setLow(&.{0}); try self.lines.setLow(&.{0});
} }
// Sets the value of the line.
pub fn setValue(self: Line, value: bool) !void {
var vals = gpio.uapi.LineValueBitset{ .mask = 0 };
vals.setValue(0, value);
try self.lines.setValues(&.{0}, vals);
}
/// Sets the configuration flags of the line. /// Sets the configuration flags of the line.
pub fn reconfigure(self: Line, flags: gpio.uapi.LineFlags) !void { pub fn reconfigure(self: Line, flags: gpio.uapi.LineFlags) !void {
try self.lines.reconfigure(&.{0}, flags); try self.lines.reconfigure(&.{0}, flags);