-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. Add a generic driver and example script Signed-off-by: RibhuDP <[email protected]>
- Loading branch information
Showing
2 changed files
with
272 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
classdef Rx < adi.common.Rx & matlabshared.libiio.base & ... | ||
adi.common.Attribute & adi.common.DeviceAttribute & adi.common.Channel | ||
% Generic Precision ADC Class | ||
% adi.Generic.Rx Receives data from the connected ADC | ||
% The adi.Generic.Rx System object is a signal source that can receive | ||
% data from any generic ADI precision ADC. | ||
% | ||
% rx = adi.Generic.Rx('adxxxx', 'ip:analog.local'); | ||
% | ||
|
||
properties | ||
% DeviceAttributeNames Device Attribute Names | ||
% Array of device IIO attribute names as defined in the | ||
% driver/firmware, and queried from the hardware | ||
% at initialization time | ||
DeviceAttributeNames | ||
|
||
% ChannelAttributeNames Device Attribute Names | ||
% Array of channel IIO attribute names as defined in the | ||
% driver/firmware, and queried from the hardware | ||
% at initialization time | ||
ChannelAttributeNames | ||
end | ||
|
||
properties (Nontunable) | ||
% SamplesPerFrame Samples Per Frame | ||
% Number of samples per frame, specified as an even positive | ||
% integer. | ||
SamplesPerFrame = 1024 | ||
end | ||
|
||
properties (Nontunable, Hidden) | ||
channel_names = {'voltage0'} | ||
Timeout = Inf | ||
kernelBuffersCount = 1 | ||
dataTypeStr = 'int32' | ||
phyDevName = 'adxxxx' | ||
devName = 'adxxxx' | ||
end | ||
|
||
properties (Nontunable, Hidden, Constant) | ||
Type = 'Rx' | ||
ComplexData = false | ||
end | ||
|
||
properties (Hidden, Nontunable, Access = protected) | ||
isOutput = false | ||
end | ||
|
||
properties(Hidden, Access = protected) | ||
cachedAttrWrites = {} | ||
end | ||
|
||
methods | ||
|
||
%% Constructor | ||
function obj = Rx(varargin) | ||
obj = [email protected](varargin{4:end}); | ||
obj.enableExplicitPolling = false; | ||
obj.EnabledChannels = 1; | ||
obj.BufferTypeConversionEnable = true; | ||
|
||
% Set device name and uri from input arguments | ||
obj.devName = varargin{1}; | ||
obj.phyDevName = varargin{1}; | ||
obj.uri = varargin{2}; | ||
|
||
% Determine datatype using trial and error | ||
possibleDataTypeStr = {'int8', 'int16', 'int32', 'int64'}; | ||
for k = 1:length(possibleDataTypeStr) | ||
try | ||
obj.dataTypeStr = possibleDataTypeStr{k}; | ||
obj.setup(); | ||
break; | ||
catch | ||
end | ||
end | ||
assert(obj.ConnectedToDevice == 1, "Connection could not be established with the specified device") | ||
|
||
% Check is the platform is running ADI Kuiper Linux. | ||
% Presence of 'local,kernel' context attribute would | ||
% indicate usage of Linux platform | ||
isLinuxPLatform = false; | ||
try | ||
obj.iio_context_get_attr_value(obj.iioCtx, 'local,kernel'); | ||
isLinuxPLatform = true; | ||
catch | ||
end | ||
|
||
release(obj); | ||
|
||
% If platform is running ADI Kuiper Linux, kernelBuffersCount | ||
% can be increased | ||
if isLinuxPLatform | ||
obj.kernelBuffersCount = 4; | ||
disp("Detected ADI Kuiper Linux platform. Changing buffer count to 4..") | ||
end | ||
|
||
end | ||
|
||
function flush(obj) | ||
% Flush the buffer contents | ||
flushBuffers(obj); | ||
end | ||
|
||
function SetDeviceAttrValue(obj, attr, val) | ||
% Apply the device attribute value when device is | ||
% connected | ||
% rx.SetDeviceAttrValue('sampling_frequency', '1000000') | ||
obj.cachedAttrWrites{end+1} = {attr, val}; | ||
end | ||
|
||
|
||
function val = GetDeviceAttrValue(obj, attr) | ||
% Fetch the device attribute value if device is | ||
% connected. | ||
% rx.GetDeviceAttrValue('sampling_frequency') | ||
if obj.ConnectedToDevice | ||
val = obj.getDeviceAttributeRAW(attr, 128); | ||
end | ||
end | ||
|
||
function SetChannelAttrValue(obj, chnID, attr, val) | ||
% Apply the channel attribute value when device is | ||
% connected. To write to the first channel attribute use | ||
% rx.SetChannelAttrValue('voltage0', 'scale', '2') or | ||
% rx.SetChannelAttrValue(1, 'scale', '2') | ||
if isnumeric(chnID) | ||
chnID = obj.channel_names(chanID); | ||
end | ||
obj.cachedAttrWrites{end+1} = {chnID, attr, val}; | ||
end | ||
|
||
function val = GetChannelAttrValue(obj, chnID, attr) | ||
% Fetch the channel attribute value if device is | ||
% connected. To get the first channel attribute value, use | ||
% rx.GetChannelAttrValue('voltage0', 'scale') or | ||
% rx.GetChannelAttrValue(1, 'scale') | ||
if obj.ConnectedToDevice | ||
if isnumeric(chnID) | ||
chnID = obj.channel_names(chanID); | ||
end | ||
val = obj.getAttributeRAW(attr, chnID, obj.isOutput); | ||
end | ||
end | ||
|
||
end | ||
|
||
%% API Functions | ||
methods (Hidden, Access = protected) | ||
|
||
function setupInit(obj) | ||
|
||
% Write all attributes to device once connected through set | ||
% methods | ||
% Do writes directly to hardware without using set methods. | ||
% This is required since Simulink support doesn't support | ||
% modification to nontunable variables at SetupImpl | ||
|
||
%Fetch all the attributes and channel names | ||
if ~isempty(obj.channel_names) | ||
obj.fetch_channel_names(); | ||
end | ||
|
||
if isempty(obj.DeviceAttributeNames) | ||
obj.fetch_device_attributes(); | ||
end | ||
|
||
if isempty(obj.ChannelAttributeNames) | ||
obj.fetch_channel_attributes(); | ||
end | ||
|
||
% Apply attribute settings in hardware | ||
if ~isempty(obj.cachedAttrWrites) | ||
for i = 1:length(obj.cachedAttrWrites) | ||
if length(obj.cachedAttrWrites{i}) == 2 | ||
% Apply device attribute | ||
attr = obj.cachedAttrWrites{i}{1}; | ||
val = obj.cachedAttrWrites{i}{2}; | ||
obj.setDeviceAttributeRAW(attr, val); | ||
elseif length(obj.cachedAttrWrites{i}) == 3 | ||
% Apply channel attribute | ||
chan = obj.cachedAttrWrites{i}{1}; | ||
attr = obj.cachedAttrWrites{i}{2}; | ||
val = obj.cachedAttrWrites{i}{3}; | ||
obj.setAttributeRAW(chan, attr, val, obj.isOutput); | ||
end | ||
end | ||
end | ||
|
||
obj.cachedAttrWrites = {}; | ||
|
||
end | ||
|
||
function fetch_channel_names(obj) | ||
% Update the channel names | ||
obj.channel_names = {}; | ||
phydev = getDev(obj, obj.devName); | ||
chanCount = obj.iio_device_get_channels_count(phydev); | ||
for c = 1:chanCount | ||
chanPtr = obj.iio_device_get_channel(phydev, c - 1); | ||
obj.channel_names{end + 1} = obj.iio_channel_get_name(chanPtr); | ||
end | ||
end | ||
|
||
function fetch_device_attributes(obj) | ||
% Store the attribute names | ||
devPtr = obj.getDev(obj.phyDevName); | ||
devAttrCnt = obj.iio_device_get_attrs_count(devPtr); | ||
for i=1:devAttrCnt | ||
obj.DeviceAttributeNames{end+1} = obj.iio_device_get_attr(devPtr, i-1); | ||
end | ||
end | ||
|
||
function fetch_channel_attributes(obj) | ||
% Store channel attribute names, if there's channels present | ||
devPtr = obj.getDev(obj.phyDevName); | ||
|
||
if ~isempty(obj.channel_names) | ||
% Fetch first channel | ||
chanPtr = calllib(obj.libName, 'iio_device_get_channel', devPtr, 0); | ||
|
||
% Fetch count of channel attributes | ||
chanAttrCnt = obj.iio_channel_get_attrs_count(chanPtr); | ||
|
||
% Fetch each attribute for the channel | ||
for j=1:chanAttrCnt | ||
obj.ChannelAttributeNames{j} = obj.iio_channel_get_attr(chanPtr, j-1); | ||
end | ||
end | ||
|
||
end | ||
|
||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
%% Script for capturing buffers of data from a connected IIO device | ||
|
||
% Instantiate the Generic Rx system object, and specify the device name and uri | ||
% in the manner shown below | ||
rx = adi.Generic.Rx('ad4630-24', 'ip:analog.local'); | ||
|
||
rx.SamplesPerFrame = 4096; % Using values less than 3660 can yield poor | ||
% performance, generally | ||
|
||
% Enable channels for data capture | ||
rx.EnabledChannels = [1]; | ||
|
||
% Display device and channel attribute names | ||
rx.DeviceAttributeNames | ||
rx.ChannelAttributeNames | ||
|
||
% Read and write attribute values | ||
% For example, with ad4630-24 | ||
% rx.GetDeviceAttrValue('sampling_frequency') | ||
% rx.SetDeviceAttrValue('sampling_frequency', '2000000'); | ||
% rx.SetChannelAttrValue('differential0', 'hardwaregain', '2'); | ||
|
||
% Capture data | ||
data = rx(); | ||
|
||
% Plot samples | ||
enabledChannels = size(data, 2); | ||
figure(1); | ||
for i = 1:enabledChannels | ||
subplot(enabledChannels, 1, i); | ||
plot(data(1:rx.SamplesPerFrame, i)); | ||
title("Channel " + num2str(rx.EnabledChannels(i))); | ||
end | ||
|
||
% Delete the system object | ||
release(rx); |