diff --git a/build.zig b/build.zig index fdde523..cba05dd 100644 --- a/build.zig +++ b/build.zig @@ -27,11 +27,6 @@ pub fn build(b: *std.Build) !void { const external_compiler_support_dir = try std.process.getEnvVarOwned(b.allocator, "NIEXTCCOMPILERSUPP"); exe.addSystemIncludePath(.{ .cwd_relative = try std.fs.path.join(b.allocator, &.{ external_compiler_support_dir, "include" }) }); - const lib_folder_name = if (target.result.ptrBitWidth() == 64) "lib64" else "lib32"; - exe.addLibraryPath(.{ .cwd_relative = try std.fs.path.join(b.allocator, &.{ external_compiler_support_dir, lib_folder_name, "msvc" }) }); - - exe.linkSystemLibrary("nidaqmx"); - // TODO: Emebed all assets using build.zig // https://github.com/ziglang/zig/issues/14637#issuecomment-1428689051 diff --git a/src/app.zig b/src/app.zig index 245e527..8d12e40 100644 --- a/src/app.zig +++ b/src/app.zig @@ -5,7 +5,7 @@ const UI = @import("./ui.zig"); const Platform = @import("./platform.zig"); const Assets = @import("./assets.zig"); const Graph = @import("./graph.zig"); -const NIDaq = @import("ni-daq.zig"); +const NIDaq = @import("ni-daq/root.zig"); const rect_utils = @import("./rect-utils.zig"); const remap = @import("./utils.zig").remap; const TaskPool = @import("./task-pool.zig"); diff --git a/src/main.zig b/src/main.zig index f89dfe3..ad0d3e6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -153,7 +153,7 @@ pub fn main() !void { defer app.deinit(); if (builtin.mode == .Debug) { - try app.appendChannelFromDevice("Dev1/ai0"); + // try app.appendChannelFromDevice("Dev1/ai0"); // try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_I.bin"); // try app.appendChannelFromFile("samples/HeLa Cx37_ 40nM GFX + 35uM Propofol_18-Sep-2024_0003_IjStim.bin"); } @@ -191,5 +191,5 @@ pub fn main() !void { } test { - _ = @import("./ni-daq.zig"); + _ = @import("./ni-daq/root.zig"); } \ No newline at end of file diff --git a/src/ni-daq/api.zig b/src/ni-daq/api.zig new file mode 100644 index 0000000..e5ef5c5 --- /dev/null +++ b/src/ni-daq/api.zig @@ -0,0 +1,59 @@ +const std = @import("std"); +pub const c = @cImport({ + @cInclude("stdint.h"); + @cDefine("__int64", "long long"); + @cInclude("NIDAQmx.h"); +}); + +const Api = @This(); + +const log = std.log.scoped(.ni_daq_api); + +lib: std.DynLib, // This MUST be the first field of `Api` struct + +DAQmxGetSysNIDAQMajorVersion: *const @TypeOf(c.DAQmxGetSysNIDAQMajorVersion), +DAQmxGetSysNIDAQMinorVersion: *const @TypeOf(c.DAQmxGetSysNIDAQMinorVersion), +DAQmxGetSysNIDAQUpdateVersion: *const @TypeOf(c.DAQmxGetSysNIDAQUpdateVersion), +DAQmxGetErrorString: *const @TypeOf(c.DAQmxGetErrorString), +DAQmxStopTask: *const @TypeOf(c.DAQmxStopTask), +DAQmxStartTask: *const @TypeOf(c.DAQmxStartTask), +DAQmxClearTask: *const @TypeOf(c.DAQmxClearTask), +DAQmxGetTaskName: *const @TypeOf(c.DAQmxGetTaskName), +DAQmxCfgSampClkTiming: *const @TypeOf(c.DAQmxCfgSampClkTiming), +DAQmxCreateTask: *const @TypeOf(c.DAQmxCreateTask), +DAQmxCreateAIVoltageChan: *const @TypeOf(c.DAQmxCreateAIVoltageChan), +DAQmxGetSysDevNames: *const @TypeOf(c.DAQmxGetSysDevNames), +DAQmxGetDevAIVoltageRngs: *const @TypeOf(c.DAQmxGetDevAIVoltageRngs), +DAQmxGetDevAOVoltageRngs: *const @TypeOf(c.DAQmxGetDevAOVoltageRngs), +DAQmxGetDevAIMaxSingleChanRate: *const @TypeOf(c.DAQmxGetDevAIMaxSingleChanRate), +DAQmxGetDevAOMaxRate: *const @TypeOf(c.DAQmxGetDevAOMaxRate), +DAQmxGetDevAIMinRate: *const @TypeOf(c.DAQmxGetDevAIMinRate), +DAQmxGetDevAOMinRate: *const @TypeOf(c.DAQmxGetDevAOMinRate), +DAQmxGetDevAISupportedMeasTypes: *const @TypeOf(c.DAQmxGetDevAISupportedMeasTypes), +DAQmxGetDevAOSupportedOutputTypes: *const @TypeOf(c.DAQmxGetDevAOSupportedOutputTypes), +DAQmxGetDevProductCategory: *const @TypeOf(c.DAQmxGetDevProductCategory), +DAQmxGetDevAIPhysicalChans: *const @TypeOf(c.DAQmxGetDevAIPhysicalChans), +DAQmxGetDevAOPhysicalChans: *const @TypeOf(c.DAQmxGetDevAOPhysicalChans), +DAQmxReadAnalogF64: *const @TypeOf(c.DAQmxReadAnalogF64), + +pub fn init() !Api { + var api: Api = undefined; + + api.lib = try std.DynLib.open("nicaiu"); + errdefer api.lib.close(); + + inline for (@typeInfo(Api).Struct.fields[1..]) |field| { + const name = std.fmt.comptimePrint("{s}\x00", .{field.name}); + const name_z = name[0 .. (name.len - 1) :0]; + @field(api, field.name) = api.lib.lookup(field.type, name_z) orelse { + log.err("Symbol lookup failed for {s}", .{name}); + return error.SymbolLookup; + }; + } + + return api; +} + +pub fn deinit(self: *Api) void { + self.lib.close(); +} \ No newline at end of file diff --git a/src/ni-daq.zig b/src/ni-daq/root.zig similarity index 83% rename from src/ni-daq.zig rename to src/ni-daq/root.zig index 116cb0f..161299d 100644 --- a/src/ni-daq.zig +++ b/src/ni-daq/root.zig @@ -1,9 +1,6 @@ const std = @import("std"); -pub const c = @cImport({ - @cInclude("stdint.h"); - @cDefine("__int64", "long long"); - @cInclude("NIDAQmx.h"); -}); +const Api = @import("./api.zig"); +pub const c = Api.c; const assert = std.debug.assert; const log = std.log.scoped(.ni_daq); @@ -38,6 +35,7 @@ pub const Options = struct { }; pub const Task = struct { + ni_daq: *NIDaq, handle: TaskHandle, name_buffer: [max_task_name_size]u8 = undefined, @@ -45,19 +43,23 @@ pub const Task = struct { dropped_samples: u32 = 0, pub fn clear(self: Task) void { - logDAQmxError(c.DAQmxClearTask(self.handle)); + // Ignore error + const api = self.ni_daq.api; + self.ni_daq.logDAQmxError(api.DAQmxClearTask(self.handle)); } pub fn name(self: *Task) ![]const u8 { - const required_size = c.DAQmxGetTaskName(self.handle, null, 0); + const api = self.ni_daq.api; + + const required_size = api.DAQmxGetTaskName(self.handle, null, 0); assert(required_size >= 0); if (required_size > self.name_buffer.len) { return error.BufferTooSmall; } - try checkDAQmxError( - c.DAQmxGetTaskName( + try self.ni_daq.checkDAQmxError( + api.DAQmxGetTaskName( self.handle, &self.name_buffer, self.name_buffer.len @@ -69,29 +71,33 @@ pub const Task = struct { } pub fn start(self: Task) !void { - try checkDAQmxError( - c.DAQmxStartTask(self.handle), + const api = self.ni_daq.api; + try self.ni_daq.checkDAQmxError( + api.DAQmxStartTask(self.handle), error.DAQmxStartTask ); } pub fn stop(self: Task) !void { - try checkDAQmxError( - c.DAQmxStopTask(self.handle), + const api = self.ni_daq.api; + try self.ni_daq.checkDAQmxError( + api.DAQmxStopTask(self.handle), error.DAQmxStopTask ); } pub fn setContinousSampleRate(self: Task, sample_rate: f64) !void { - try checkDAQmxError( - c.DAQmxCfgSampClkTiming(self.handle, null, sample_rate, c.DAQmx_Val_Rising, c.DAQmx_Val_ContSamps, 0), + const api = self.ni_daq.api; + try self.ni_daq.checkDAQmxError( + api.DAQmxCfgSampClkTiming(self.handle, null, sample_rate, c.DAQmx_Val_Rising, c.DAQmx_Val_ContSamps, 0), error.DAQmxCfgSampClkTiming ); } pub fn setFiniteSampleRate(self: Task, sample_rate: f64, samples_per_channel: u64) !void { - try checkDAQmxError( - c.DAQmxCfgSampClkTiming(self.handle, null, sample_rate, c.DAQmx_Val_Rising, c.DAQmx_Val_FiniteSamps, samples_per_channel), + const api = self.ni_daq.api; + try self.ni_daq.checkDAQmxError( + api.DAQmxCfgSampClkTiming(self.handle, null, sample_rate, c.DAQmx_Val_Rising, c.DAQmx_Val_FiniteSamps, samples_per_channel), error.DAQmxCfgSampClkTiming ); } @@ -107,8 +113,9 @@ pub const Task = struct { }; pub fn createAIVoltageChannel(self: Task, options: AIVoltageChannelOptions) !void { - try checkDAQmxError( - c.DAQmxCreateAIVoltageChan( + const api = self.ni_daq.api; + try self.ni_daq.checkDAQmxError( + api.DAQmxCreateAIVoltageChan( self.handle, options.channel, options.assigned_name, @@ -132,7 +139,7 @@ pub const Task = struct { }; pub fn createAOVoltageChannel(self: Task, options: AOVoltageChannelOptions) !void { - try checkDAQmxError( + try self.ni_daq.checkDAQmxError( c.DAQmxCreateAOVoltageChan( self.handle, options.channel, @@ -155,8 +162,9 @@ pub const Task = struct { }; pub fn readAnalog(self: *Task, options: ReadAnalogOptions) !u32 { + const api = self.ni_daq.api; var samples_per_channel: i32 = 0; - const err = c.DAQmxReadAnalogF64( + const err = api.DAQmxReadAnalogF64( self.handle, options.samples_per_channel, options.timeout, @@ -171,7 +179,7 @@ pub const Task = struct { self.dropped_samples += 1; log.err("Dropped samples, not reading samples fast enough.", .{}); } else if (err < 0) { - try checkDAQmxError(err, error.DAQmxReadAnalogF64); + try self.ni_daq.checkDAQmxError(err, error.DAQmxReadAnalogF64); } return @intCast(samples_per_channel); @@ -179,7 +187,7 @@ pub const Task = struct { pub fn isDone(self: Task) !bool { var result: c.bool32 = 0; - try checkDAQmxError( + try self.ni_daq.checkDAQmxError( c.DAQmxIsTaskDone(self.handle, &result), error.DAQmxIsTaskDone ); @@ -365,12 +373,16 @@ const DeviceBuffers = struct { }; options: Options, +api: Api, device_names_buffer: []u8, device_names: StringArrayListUnmanaged, device_buffers: []DeviceBuffers, pub fn init(allocator: std.mem.Allocator, options: Options) !NIDaq { + var api = try Api.init(); + errdefer api.deinit(); + const device_names_buffer_size = options.max_devices * (max_device_name_size + 2); const device_names_buffer = try allocator.alloc(u8, device_names_buffer_size); errdefer allocator.free(device_names_buffer); @@ -388,6 +400,7 @@ pub fn init(allocator: std.mem.Allocator, options: Options) !NIDaq { return NIDaq{ .options = options, + .api = api, .device_names_buffer = device_names_buffer, .device_names = device_names, .device_buffers = device_buffers @@ -395,6 +408,8 @@ pub fn init(allocator: std.mem.Allocator, options: Options) !NIDaq { } pub fn deinit(self: *NIDaq, allocator: std.mem.Allocator) void { + self.api.deinit(); + self.device_names.deinit(allocator); allocator.free(self.device_names_buffer); @@ -423,33 +438,33 @@ test { try std.testing.expectEqual(3, maxIndexStringLength(101)); } -pub fn logDAQmxError(error_code: i32) void { +pub fn logDAQmxError(self: NIDaq, error_code: i32) void { if (error_code == 0) { return; } var msg: [512:0]u8 = .{ 0 } ** 512; - if (c.DAQmxGetErrorString(error_code, &msg, msg.len) == 0) { + if (self.api.DAQmxGetErrorString(error_code, &msg, msg.len) == 0) { log.err("DAQmx ({}): {s}", .{error_code, msg}); } else { log.err("DAQmx ({}): Unknown (Buffer too small for message)", .{error_code}); } } -pub fn checkDAQmxError(error_code: i32, err: anyerror) !void { - logDAQmxError(error_code); +pub fn checkDAQmxError(self: NIDaq, error_code: i32, err: anyerror) !void { + self.logDAQmxError(error_code); if (error_code < 0) { return err; } } -pub fn checkDAQmxErrorIgnoreWarnings(error_code: i32, err: anyerror) !void { +pub fn checkDAQmxErrorIgnoreWarnings(self: NIDaq, error_code: i32, err: anyerror) !void { if (error_code > 0) { return; } - try checkDAQmxError(error_code, err); + try self.checkDAQmxError(error_code, err); } fn splitCommaDelimitedList(array_list: *std.ArrayListUnmanaged([:0]const u8), buffer: []u8) !void { @@ -471,22 +486,22 @@ fn splitCommaDelimitedList(array_list: *std.ArrayListUnmanaged([:0]const u8), bu } } -pub fn version() !std.SemanticVersion { +pub fn version(self: NIDaq) !std.SemanticVersion { var major: u32 = 0; - try checkDAQmxError( - c.DAQmxGetSysNIDAQMajorVersion(&major), + try self.checkDAQmxError( + self.api.DAQmxGetSysNIDAQMajorVersion(&major), error.GetMajorVersion ); var minor: u32 = 0; - try checkDAQmxError( - c.DAQmxGetSysNIDAQMinorVersion(&minor), + try self.checkDAQmxError( + self.api.DAQmxGetSysNIDAQMinorVersion(&minor), error.GetMinorVersion ); var update: u32 = 0; - try checkDAQmxError( - c.DAQmxGetSysNIDAQUpdateVersion(&update), + try self.checkDAQmxError( + self.api.DAQmxGetSysNIDAQUpdateVersion(&update), error.GetUpdateVersion ); @@ -501,8 +516,8 @@ pub fn listDeviceNames(self: *NIDaq) ![]const [:0]const u8 { self.device_names.clearRetainingCapacity(); self.clearAllDeviceBuffers(); - const required_size = c.DAQmxGetSysDevNames(null, 0); - try checkDAQmxErrorIgnoreWarnings(required_size, error.DAQmxGetSysDevNames); + const required_size = self.api.DAQmxGetSysDevNames(null, 0); + try self.checkDAQmxErrorIgnoreWarnings(required_size, error.DAQmxGetSysDevNames); if (required_size == 0) { return self.device_names.items; } @@ -511,8 +526,8 @@ pub fn listDeviceNames(self: *NIDaq) ![]const [:0]const u8 { return error.BufferTooSmall; } - try checkDAQmxError( - c.DAQmxGetSysDevNames(self.device_names_buffer.ptr, @intCast(self.device_names_buffer.len)), + try self.checkDAQmxError( + self.api.DAQmxGetSysDevNames(self.device_names_buffer.ptr, @intCast(self.device_names_buffer.len)), error.GetDeviceNames ); @@ -549,6 +564,7 @@ fn clearAllDeviceBuffers(self: *NIDaq) void { } fn listDevicePhysicalChannels( + self: NIDaq, getPhysicalChannels: anytype, device: [:0]const u8, channel_names: *DeviceBuffers.ChannelNames, @@ -559,7 +575,7 @@ fn listDevicePhysicalChannels( array_list.clearRetainingCapacity(); const required_size = getPhysicalChannels(device, null, 0); - try checkDAQmxErrorIgnoreWarnings(required_size, error.GetPhysicalChannels); + try self.checkDAQmxErrorIgnoreWarnings(required_size, error.GetPhysicalChannels); if (required_size == 0) { return array_list.items; } @@ -568,7 +584,7 @@ fn listDevicePhysicalChannels( return error.BufferTooSmall; } - try checkDAQmxError( + try self.checkDAQmxError( getPhysicalChannels(device, buffer.ptr, @intCast(buffer.len)), error.GetPhysicalChannels ); @@ -584,8 +600,8 @@ fn listDevicePhysicalChannels( pub fn listDeviceAIPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const [:0]const u8 { var device_buffers = try self.getDeviceBuffers(device); - return listDevicePhysicalChannels( - c.DAQmxGetDevAIPhysicalChans, + return self.listDevicePhysicalChannels( + self.api.DAQmxGetDevAIPhysicalChans, device, &device_buffers.analog_input_names ); @@ -594,8 +610,8 @@ pub fn listDeviceAIPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const pub fn listDeviceAOPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const [:0]const u8 { var device_buffers = try self.getDeviceBuffers(device); - return listDevicePhysicalChannels( - c.DAQmxGetDevAOPhysicalChans, + return self.listDevicePhysicalChannels( + self.api.DAQmxGetDevAOPhysicalChans, device, &device_buffers.analog_output_names ); @@ -604,7 +620,7 @@ pub fn listDeviceAOPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const pub fn listDeviceCOPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const [:0]const u8 { var device_buffers = try self.getDeviceBuffers(device); - return listDevicePhysicalChannels( + return self.listDevicePhysicalChannels( c.DAQmxGetDevCOPhysicalChans, device, &device_buffers.counter_output_names @@ -614,7 +630,7 @@ pub fn listDeviceCOPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const pub fn listDeviceCIPhysicalChannels(self: *NIDaq, device: [:0]const u8) ![]const [:0]const u8 { var device_buffers = try self.getDeviceBuffers(device); - return listDevicePhysicalChannels( + return self.listDevicePhysicalChannels( c.DAQmxGetDevCIPhysicalChans, device, &device_buffers.counter_input_names @@ -646,21 +662,19 @@ fn getChannelType(device: [:0]const u8) ?ChannelType { } pub fn getMinSampleRate(self: NIDaq, channel: [:0]const u8) !f64 { - _ = self; - var result: f64 = 0; const channel_type = getChannelType(channel) orelse return error.UnknownChannelType; switch (channel_type) { .analog_input => { - try checkDAQmxError( - c.DAQmxGetDevAIMinRate(channel, &result), + try self.checkDAQmxError( + self.api.DAQmxGetDevAIMinRate(channel, &result), error.DAQmxGetDevAIMinRate ); }, .analog_output => { - try checkDAQmxError( - c.DAQmxGetDevAOMinRate(channel, &result), + try self.checkDAQmxError( + self.api.DAQmxGetDevAOMinRate(channel, &result), error.DAQmxGetDevAOMinRate ); }, @@ -674,21 +688,19 @@ pub fn getMinSampleRate(self: NIDaq, channel: [:0]const u8) !f64 { } pub fn getMaxSampleRate(self: NIDaq, channel: [:0]const u8) !f64 { - _ = self; - var result: f64 = 0; const channel_type = getChannelType(channel) orelse return error.UnknownChannelType; switch (channel_type) { .analog_input => { - try checkDAQmxError( - c.DAQmxGetDevAIMaxSingleChanRate(channel, &result), + try self.checkDAQmxError( + self.api.DAQmxGetDevAIMaxSingleChanRate(channel, &result), error.DAQmxGetDevAIMaxSingleChanRate ); }, .analog_output => { - try checkDAQmxError( - c.DAQmxGetDevAOMaxRate(channel, &result), + try self.checkDAQmxError( + self.api.DAQmxGetDevAOMaxRate(channel, &result), error.DAQmxGetDevAOMaxRate ); }, @@ -702,6 +714,7 @@ pub fn getMaxSampleRate(self: NIDaq, channel: [:0]const u8) !f64 { } fn listDeviceVoltageRanges( + self: NIDaq, getVoltageRanges: anytype, device: [:0]const u8, voltage_ranges: *std.ArrayListUnmanaged(Range) @@ -709,7 +722,7 @@ fn listDeviceVoltageRanges( voltage_ranges.clearRetainingCapacity(); const count = getVoltageRanges(device, null, 0); - try checkDAQmxErrorIgnoreWarnings(count, error.GetVoltageRanges); + try self.checkDAQmxErrorIgnoreWarnings(count, error.GetVoltageRanges); if (count == 0) { return voltage_ranges.items; } @@ -722,7 +735,7 @@ fn listDeviceVoltageRanges( return error.BufferTooSmall; } - try checkDAQmxError( + try self.checkDAQmxError( getVoltageRanges(device, buffer, @intCast(buffer_len)), error.GetVoltageRanges ); @@ -735,8 +748,8 @@ fn listDeviceVoltageRanges( pub fn listDeviceAIVoltageRanges(self: *NIDaq, device: [:0]const u8) ![]Range { var device_buffers = try self.getDeviceBuffers(device); - return listDeviceVoltageRanges( - c.DAQmxGetDevAIVoltageRngs, + return self.listDeviceVoltageRanges( + self.api.DAQmxGetDevAIVoltageRngs, device, &device_buffers.analog_input_voltage_ranges ); @@ -745,36 +758,33 @@ pub fn listDeviceAIVoltageRanges(self: *NIDaq, device: [:0]const u8) ![]Range { pub fn listDeviceAOVoltageRanges(self: *NIDaq, device: [:0]const u8) ![]Range { var device_buffers = try self.getDeviceBuffers(device); - return listDeviceVoltageRanges( - c.DAQmxGetDevAOVoltageRngs, + return self.listDeviceVoltageRanges( + self.api.DAQmxGetDevAOVoltageRngs, device, &device_buffers.analog_output_voltage_ranges ); } -pub fn createTask(self: NIDaq, name: ?[:0]const u8) !Task { - _ = self; - +pub fn createTask(self: *NIDaq, name: ?[:0]const u8) !Task { var handle: TaskHandle = undefined; - try checkDAQmxError( - c.DAQmxCreateTask(name orelse "", &handle), + try self.checkDAQmxError( + self.api.DAQmxCreateTask(name orelse "", &handle), error.DAQmxCreateTask ); - return Task{ .handle = handle }; + return Task{ .ni_daq = self, .handle = handle }; } pub fn listDeviceAIMeasurementTypes(self: NIDaq, device: [:0]const u8) !AIMeasurementTypeList { var result = AIMeasurementTypeList.init(0) catch unreachable; - _ = self; - const count = c.DAQmxGetDevAISupportedMeasTypes(device, null, 0); - try checkDAQmxErrorIgnoreWarnings(count, error.DAQmxGetDevAISupportedMeasTypes); + const count = self.api.DAQmxGetDevAISupportedMeasTypes(device, null, 0); + try self.checkDAQmxErrorIgnoreWarnings(count, error.DAQmxGetDevAISupportedMeasTypes); assert(count <= result.buffer.len); - try checkDAQmxError( - c.DAQmxGetDevAISupportedMeasTypes(device, @as([*c]c_int, @ptrCast(&result.buffer)), result.buffer.len), + try self.checkDAQmxError( + self.api.DAQmxGetDevAISupportedMeasTypes(device, @as([*c]c_int, @ptrCast(&result.buffer)), result.buffer.len), error.DAQmxGetDevAISupportedMeasTypes ); @@ -790,14 +800,13 @@ pub fn checkDeviceAIMeasurementType(self: NIDaq, device: [:0]const u8, measureme pub fn listDeviceAOOutputTypes(self: NIDaq, device: [:0]const u8) !AOOutputTypeList { var result = AOOutputTypeList.init(0) catch unreachable; - _ = self; - const count = c.DAQmxGetDevAOSupportedOutputTypes(device, null, 0); - try checkDAQmxErrorIgnoreWarnings(count, error.DAQmxGetDevAOSupportedOutputTypes); + const count = self.api.DAQmxGetDevAOSupportedOutputTypes(device, null, 0); + try self.checkDAQmxErrorIgnoreWarnings(count, error.DAQmxGetDevAOSupportedOutputTypes); assert(count <= result.buffer.len); - try checkDAQmxError( - c.DAQmxGetDevAOSupportedOutputTypes(device, @as([*c]c_int, @ptrCast(&result.buffer)), result.buffer.len), + try self.checkDAQmxError( + self.api.DAQmxGetDevAOSupportedOutputTypes(device, @as([*c]c_int, @ptrCast(&result.buffer)), result.buffer.len), error.DAQmxGetDevAOSupportedOutputTypes ); @@ -812,11 +821,9 @@ pub fn checkDeviceAOOutputType(self: NIDaq, device: [:0]const u8, output_type: A } pub fn getDeviceProductCategory(self: NIDaq, device: [:0]const u8) !ProductCategory { - _ = self; - var product_category = ProductCategory.Unknown; - try checkDAQmxError( - c.DAQmxGetDevProductCategory(device, @ptrCast(&product_category)), + try self.checkDAQmxError( + self.api.DAQmxGetDevProductCategory(device, @ptrCast(&product_category)), error.DAQmxGetDevProductCategory ); diff --git a/src/task-pool.zig b/src/task-pool.zig index e648c5a..d620960 100644 --- a/src/task-pool.zig +++ b/src/task-pool.zig @@ -1,5 +1,5 @@ const std = @import("std"); -const NIDaq = @import("./ni-daq.zig"); +const NIDaq = @import("./ni-daq/root.zig"); const assert = std.debug.assert; const log = std.log.scoped(.task_pool);