From 21108f86d833bad9a1b22681f000c1570200d1ab Mon Sep 17 00:00:00 2001 From: SGudla Date: Tue, 19 Dec 2023 17:08:02 +0530 Subject: [PATCH] Add support and doc for AD579x DAC Add precision toolbox support for AD5760, AD5780, AD5781, AD5790, AD5791 DACs Signed-off-by: SGudla --- +adi/+AD5760/Tx.m | 133 ++++++++++++++++++++++++++++++ +adi/+AD5780/Tx.m | 134 +++++++++++++++++++++++++++++++ +adi/+AD5781/Tx.m | 134 +++++++++++++++++++++++++++++++ +adi/+AD5790/Tx.m | 133 ++++++++++++++++++++++++++++++ +adi/+AD5791/Tx.m | 134 +++++++++++++++++++++++++++++++ +adi/+AD579x/Base.m | 55 +++++++++++++ +adi/Contents.m | 5 ++ CI/gen_doc/docs/gen_sysobj_doc.m | 5 ++ examples/ad5791_DataStreaming.m | 32 ++++++++ 9 files changed, 765 insertions(+) create mode 100644 +adi/+AD5760/Tx.m create mode 100644 +adi/+AD5780/Tx.m create mode 100644 +adi/+AD5781/Tx.m create mode 100644 +adi/+AD5790/Tx.m create mode 100644 +adi/+AD5791/Tx.m create mode 100644 +adi/+AD579x/Base.m create mode 100644 examples/ad5791_DataStreaming.m diff --git a/+adi/+AD5760/Tx.m b/+adi/+AD5760/Tx.m new file mode 100644 index 0000000..07cd172 --- /dev/null +++ b/+adi/+AD5760/Tx.m @@ -0,0 +1,133 @@ +classdef Tx < adi.AD579x.Base & matlabshared.libiio.base & adi.common.Attribute + % AD5760 Voltage output DAC Class + % adi.AD5760.Tx Transmits data to the AD5760 DAC + % The adi.AD5760.Tx System object is a signal sink that can transmit + % data to the AD5760. + % + % tx = adi.AD5760.Tx; + % tx = adi.AD5760.Tx('uri','ip:192.168.2.1'); + % + % AD5760 Datasheet + + properties + SampleRate + CodeSelect + PowerDown + Raw + end + + % Channel names + properties (Nontunable, Hidden) + channel_names = {'voltage0'} + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx' + end + + properties (Nontunable, Hidden) + Timeout = Inf + kernelBuffersCount = 1 + dataTypeStr = 'int16' + phyDevName = 'ad5760' + devName = 'ad5760' + end + + properties (Constant, Hidden) + CodeSelectSet = matlab.system.StringSet([ ... + "2s_complement", "binary_offset"]); + end + + methods + + %% Constructor + function obj = Tx(varargin) + obj = obj@matlabshared.libiio.base(varargin{:}); + obj.enableExplicitPolling = false; + obj.EnabledChannels = 1; + obj.uri = 'ip:analog.local'; + obj.DataSource = 'DMA'; + end + + function set.SampleRate(obj, value) + % Set device sampling rate + obj.SampleRate = value; + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('sampling_frequency', num2str(value)); end + end + + function set.CodeSelect(obj, value) + % Set code select option + obj.CodeSelect = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setDeviceAttributeRAW(id, 'code_select', num2str(value), true) + end + end + + function set.PowerDown(obj, value) + options = [0,1]; + if ~any(value==options) + error(['PowerDown must be one of ',num2str(options)]); + end + % Set channel power down value + obj.PowerDown = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'powerdown', num2str(value), true) + end + end + + function set.Raw(obj, value) + % Set channel raw value + obj.Raw = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'raw', num2str(value), true) + 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 doesn't support + % modification to nontunable variables at SetupImpl + + id = 'voltage0'; + + obj.setDeviceAttributeRAW('sampling_frequency', num2str(obj.SampleRate)); + obj.setDeviceAttributeRAW('code_select', num2str(obj.CodeSelect)); + obj.setAttributeRAW(id, 'powerdown', num2str(obj.PowerDown), true); + obj.setAttributeRAW(id, 'raw', num2str(obj.Raw), true); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD5760 DAC'; + end + + end +end \ No newline at end of file diff --git a/+adi/+AD5780/Tx.m b/+adi/+AD5780/Tx.m new file mode 100644 index 0000000..4b4774e --- /dev/null +++ b/+adi/+AD5780/Tx.m @@ -0,0 +1,134 @@ +classdef Tx < adi.AD579x.Base & matlabshared.libiio.base & adi.common.Attribute + % AD5780 Voltage output DAC Class + % adi.AD5780.Tx Transmits data to the AD5780 DAC + % The adi.AD5780.Tx System object is a signal sink that can transmit + % data to the AD5780. + % + % tx = adi.AD5780.Tx; + % tx = adi.AD5780.Tx('uri','ip:192.168.2.1'); + % + % AD5780 Datasheet + + properties + SampleRate + CodeSelect + PowerDown + Raw + end + + % Channel names + properties (Nontunable, Hidden) + channel_names = {'voltage0'} + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx' + end + + properties (Nontunable, Hidden) + Timeout = Inf + kernelBuffersCount = 1 + dataTypeStr = 'int32' + phyDevName = 'ad5780' + devName = 'ad5780' + end + + properties (Constant, Hidden) + CodeSelectSet = matlab.system.StringSet([ ... + "2s_complement", "binary_offset"]); + end + + methods + + %% Constructor + function obj = Tx(varargin) + obj = obj@matlabshared.libiio.base(varargin{:}); + obj.enableExplicitPolling = false; + obj.EnabledChannels = 1; + obj.uri = 'ip:analog.local'; + obj.DataSource = 'DMA'; + end + + function set.SampleRate(obj, value) + % Set device sampling rate + obj.SampleRate = value; + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('sampling_frequency', num2str(value)); + end + end + + function set.CodeSelect(obj, value) + % Set code select option + obj.CodeSelect = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setDeviceAttributeRAW(id, 'code_select', num2str(value), true) + end + end + + function set.PowerDown(obj, value) + options = [0,1]; + if ~any(value==options) + error(['PowerDown must be one of ',num2str(options)]); + end + % Set channel power down value + obj.PowerDown = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'powerdown', num2str(value), true) + end + end + + function set.Raw(obj, value) + % Set channel raw value + obj.Raw = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'raw', num2str(value), true) + 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 doesn't support + % modification to nontunable variables at SetupImpl + + id = 'voltage0'; + + obj.setDeviceAttributeRAW('sampling_frequency', num2str(obj.SampleRate)); + obj.setDeviceAttributeRAW('code_select', num2str(obj.CodeSelect)); + obj.setAttributeRAW(id, 'powerdown', num2str(obj.PowerDown), true); + obj.setAttributeRAW(id, 'raw', num2str(obj.Raw), true); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD5780 DAC'; + end + + end +end \ No newline at end of file diff --git a/+adi/+AD5781/Tx.m b/+adi/+AD5781/Tx.m new file mode 100644 index 0000000..561576c --- /dev/null +++ b/+adi/+AD5781/Tx.m @@ -0,0 +1,134 @@ +classdef Tx < adi.AD579x.Base & matlabshared.libiio.base & adi.common.Attribute + % AD5781 Voltage output DAC Class + % adi.AD5781.Tx Transmits data to the AD5781 DAC + % The adi.AD5781.Tx System object is a signal sink that can transmit + % data to the AD5781. + % + % tx = adi.AD5781.Tx; + % tx = adi.AD5781.Tx('uri','ip:192.168.2.1'); + % + % AD5781 Datasheet + + properties + SampleRate + CodeSelect + PowerDown + Raw + end + + % Channel names + properties (Nontunable, Hidden) + channel_names = {'voltage0'} + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx' + end + + properties (Nontunable, Hidden) + Timeout = Inf + kernelBuffersCount = 1 + dataTypeStr = 'int32' + phyDevName = 'ad5781' + devName = 'ad5781' + end + + properties (Constant, Hidden) + CodeSelectSet = matlab.system.StringSet([ ... + "2s_complement", "binary_offset"]); + end + + methods + + %% Constructor + function obj = Tx(varargin) + obj = obj@matlabshared.libiio.base(varargin{:}); + obj.enableExplicitPolling = false; + obj.EnabledChannels = 1; + obj.uri = 'ip:analog.local'; + obj.DataSource = 'DMA'; + end + + function set.SampleRate(obj, value) + % Set device sampling rate + obj.SampleRate = value; + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('sampling_frequency', num2str(value)); + end + end + + function set.CodeSelect(obj, value) + % Set code select option + obj.CodeSelect = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setDeviceAttributeRAW(id, 'code_select', num2str(value), true) + end + end + + function set.PowerDown(obj, value) + options = [0,1]; + if ~any(value==options) + error(['PowerDown must be one of ',num2str(options)]); + end + % Set channel power down value + obj.PowerDown = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'powerdown', num2str(value), true) + end + end + + function set.Raw(obj, value) + % Set channel raw value + obj.Raw = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'raw', num2str(value), true) + 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 doesn't support + % modification to nontunable variables at SetupImpl + + id = 'voltage0'; + + obj.setDeviceAttributeRAW('sampling_frequency', num2str(obj.SampleRate)); + obj.setDeviceAttributeRAW('code_select', num2str(obj.CodeSelect)); + obj.setAttributeRAW(id, 'powerdown', num2str(obj.PowerDown), true); + obj.setAttributeRAW(id, 'raw', num2str(obj.Raw), true); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD5781 DAC'; + end + + end +end \ No newline at end of file diff --git a/+adi/+AD5790/Tx.m b/+adi/+AD5790/Tx.m new file mode 100644 index 0000000..1d85ea0 --- /dev/null +++ b/+adi/+AD5790/Tx.m @@ -0,0 +1,133 @@ +classdef Tx < adi.AD579x.Base & matlabshared.libiio.base & adi.common.Attribute + % AD5790 Voltage output DAC Class + % adi.AD5790.Tx Transmits data to the AD5790 DAC + % The adi.AD5790.Tx System object is a signal sink that can transmit + % data to the AD5790. + % + % tx = adi.AD5790.Tx; + % tx = adi.AD5790.Tx('uri','ip:192.168.2.1'); + % + % AD5790 Datasheet + + properties + SampleRate + CodeSelect + PowerDown + Raw + end + + % Channel names + properties (Nontunable, Hidden) + channel_names = {'voltage0'} + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx' + end + + properties (Nontunable, Hidden) + Timeout = Inf + kernelBuffersCount = 1 + dataTypeStr = 'int32' + phyDevName = 'ad5790' + devName = 'ad5790' + end + + properties (Constant, Hidden) + CodeSelectSet = matlab.system.StringSet([ ... + "2s_complement", "binary_offset"]); + end + + methods + + %% Constructor + function obj = Tx(varargin) + obj = obj@matlabshared.libiio.base(varargin{:}); + obj.enableExplicitPolling = false; + obj.EnabledChannels = 1; + obj.uri = 'ip:analog.local'; + obj.DataSource = 'DMA'; + end + + function set.SampleRate(obj, value) + % Set device sampling rate + obj.SampleRate = value; + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('sampling_frequency', num2str(value)); end + end + + function set.CodeSelect(obj, value) + % Set code select option + obj.CodeSelect = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setDeviceAttributeRAW(id, 'code_select', num2str(value), true) + end + end + + function set.PowerDown(obj, value) + options = [0,1]; + if ~any(value==options) + error(['PowerDown must be one of ',num2str(options)]); + end + % Set channel power down value + obj.PowerDown = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'powerdown', num2str(value), true) + end + end + + function set.Raw(obj, value) + % Set channel raw value + obj.Raw = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'raw', num2str(value), true) + 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 doesn't support + % modification to nontunable variables at SetupImpl + + id = 'voltage0'; + + obj.setDeviceAttributeRAW('sampling_frequency', num2str(obj.SampleRate)); + obj.setDeviceAttributeRAW('code_select', num2str(obj.CodeSelect)); + obj.setAttributeRAW(id, 'powerdown', num2str(obj.PowerDown), true); + obj.setAttributeRAW(id, 'raw', num2str(obj.Raw), true); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD5790 DAC'; + end + + end +end \ No newline at end of file diff --git a/+adi/+AD5791/Tx.m b/+adi/+AD5791/Tx.m new file mode 100644 index 0000000..a675662 --- /dev/null +++ b/+adi/+AD5791/Tx.m @@ -0,0 +1,134 @@ +classdef Tx < adi.AD579x.Base & matlabshared.libiio.base & adi.common.Attribute + % AD5791 Voltage output DAC Class + % adi.AD5791.Tx Transmits data to the AD5791 DAC + % The adi.AD5791.Tx System object is a signal sink that can transmit + % data to the AD5791. + % + % tx = adi.AD5791.Tx; + % tx = adi.AD5791.Tx('uri','ip:192.168.2.1'); + % + % AD5791 Datasheet + + properties + SampleRate + CodeSelect + PowerDown + Raw + end + + % Channel names + properties (Nontunable, Hidden) + channel_names = {'voltage0'} + end + + properties (Hidden, Nontunable, Access = protected) + isOutput = true + end + + properties (Nontunable, Hidden, Constant) + Type = 'Tx' + end + + properties (Nontunable, Hidden) + Timeout = Inf + kernelBuffersCount = 1 + dataTypeStr = 'int32' + phyDevName = 'ad5791' + devName = 'ad5791' + end + + properties (Constant, Hidden) + CodeSelectSet = matlab.system.StringSet([ ... + "2s_complement", "binary_offset"]); + end + + methods + + %% Constructor + function obj = Tx(varargin) + obj = obj@matlabshared.libiio.base(varargin{:}); + obj.enableExplicitPolling = false; + obj.EnabledChannels = 1; + obj.uri = 'ip:analog.local'; + obj.DataSource = 'DMA'; + end + + function set.SampleRate(obj, value) + % Set device sampling rate + obj.SampleRate = value; + if obj.ConnectedToDevice + obj.setDeviceAttributeRAW('sampling_frequency', num2str(value)); + end + end + + function set.CodeSelect(obj, value) + % Set code select option + obj.CodeSelect = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setDeviceAttributeRAW(id, 'code_select', num2str(value), true) + end + end + + function set.PowerDown(obj, value) + options = [0,1]; + if ~any(value==options) + error(['PowerDown must be one of ',num2str(options)]); + end + % Set channel power down value + obj.PowerDown = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'powerdown', num2str(value), true) + end + end + + function set.Raw(obj, value) + % Set channel raw value + obj.Raw = value; + if obj.ConnectedToDevice + id = 'voltage0'; + obj.setAttributeRAW(id, 'raw', num2str(value), true) + 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 doesn't support + % modification to nontunable variables at SetupImpl + + id = 'voltage0'; + + obj.setDeviceAttributeRAW('sampling_frequency', num2str(obj.SampleRate)); + obj.setDeviceAttributeRAW('code_select', num2str(obj.CodeSelect)); + obj.setAttributeRAW(id, 'powerdown', num2str(obj.PowerDown), true); + obj.setAttributeRAW(id, 'raw', num2str(obj.Raw), true); + end + + end + + %% External Dependency Methods + methods (Hidden, Static) + + function tf = isSupportedContext(bldCfg) + tf = matlabshared.libiio.ExternalDependency.isSupportedContext(bldCfg); + end + + function updateBuildInfo(buildInfo, bldCfg) + % Call the matlabshared.libiio.method first + matlabshared.libiio.ExternalDependency.updateBuildInfo(buildInfo, bldCfg); + end + + function bName = getDescriptiveName(~) + bName = 'AD5791 DAC'; + end + + end +end \ No newline at end of file diff --git a/+adi/+AD579x/Base.m b/+adi/+AD579x/Base.m new file mode 100644 index 0000000..79516d0 --- /dev/null +++ b/+adi/+AD579x/Base.m @@ -0,0 +1,55 @@ +classdef Base < adi.common.Tx & adi.common.RxTx & ... + matlabshared.libiio.base & adi.common.Attribute & ... + adi.common.RegisterReadWrite & adi.common.Channel + % AD579x is a family of Voltage output DAC + % AD5790 is single channel 20bit DAC + % AD5791 is single channel 20bit DAC + % AD5780 is single channel 18bit DAC + % AD5781 is single channel 18bit DAC + % AD5760 is single channel 16bit DAC + + properties(Nontunable) + % SamplesPerFrame Samples Per Frame + % Number of samples per frame, specified as an even positive + % integer. + SamplesPerFrame + end + + properties (Abstract) + % SampleRate Sample Rate + % Baseband sampling rate in Hz, specified as a scalar + % in samples per second. + SampleRate + % PowerDown Power Down + PowerDown + % Raw Channel Raw Value + Raw + % CodeSelect Code Select + CodeSelect + end + + properties (Abstract, Nontunable, Hidden) + Timeout + kernelBuffersCount + dataTypeStr + phyDevName + devName + end + + properties (Hidden, Constant) + ComplexData = false + end + + methods + %% Constructor + function obj = Base(varargin) + coder.allowpcode('plain'); + obj = obj@matlabshared.libiio.base(varargin{:}); + end + + % Destructor + function delete(obj) + delete@adi.common.RxTx(obj); + end + end +end \ No newline at end of file diff --git a/+adi/Contents.m b/+adi/Contents.m index 735aea5..044e80c 100644 --- a/+adi/Contents.m +++ b/+adi/Contents.m @@ -14,3 +14,8 @@ % AD4858 - ADC % AD2S1210 - Resolver-to-Digital Converter % AD4020 - ADC +% AD5760 - DAC +% AD5780 - DAC +% AD5781 - DAC +% AD5790 - DAC +% AD5791 - DAC \ No newline at end of file diff --git a/CI/gen_doc/docs/gen_sysobj_doc.m b/CI/gen_doc/docs/gen_sysobj_doc.m index f4e0c29..3031e69 100644 --- a/CI/gen_doc/docs/gen_sysobj_doc.m +++ b/CI/gen_doc/docs/gen_sysobj_doc.m @@ -16,6 +16,11 @@ , {'AD4858', {'Rx'}}... , {'AD2S1210', {'Rx'}}... , {'AD4020', {'Rx'}}... + , {'AD5760', {'Tx'}}... + , {'AD5780', {'Tx'}}... + , {'AD5781', {'Tx'}}... + , {'AD5790', {'Tx'}}... + , {'AD5791', {'Tx'}}... %{'QuadMxFE',{'Rx','Tx'}}... }; diff --git a/examples/ad5791_DataStreaming.m b/examples/ad5791_DataStreaming.m new file mode 100644 index 0000000..5866a47 --- /dev/null +++ b/examples/ad5791_DataStreaming.m @@ -0,0 +1,32 @@ +%% Script for generating and transmitting a set of samples to a +%% connected AD579x board + +%% Generate data +samplerate = 50000; +amplitude = 2^17-1; +frequency = 250; +sine_wave = dsp.SineWave(amplitude, frequency); +sine_wave.ComplexOutput = false; +sine_wave.SamplesPerFrame = 200; +sine_wave.SampleRate = samplerate; +data = sine_wave(); + +%% Tx set up +% Instantiate the system object +tx = adi.AD5780.Tx; +% Specify uri +tx.uri = 'serial:COM39,230400'; +tx.EnableCyclicBuffers = true; +tx.SampleRate = samplerate; +% Power up the channel +tx.PowerDown = 0; +tx.CodeSelect = "2s_complement"; + +% Stream data +tx(data) + +%Pause the execution to see the ouput for 5 seconds +pause(5); + +% Delete the system object +tx.release(); \ No newline at end of file