gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+can/+ni/+xnet/Channel.m
classdef Channel < can.Channel % Channel Connection to an NI-XNET device channel. % % This class provides connectivity to CAN channels for NI-XNET % devices. It contains properties and methods to configure and use the % channel on a network. % % See also VNT. % Authors: JDP % Copyright 2013-2015 The MathWorks, Inc. % Note that all uncommented properties are Abstract and inherit their % help from the super class. properties (SetAccess = 'private', GetAccess = 'protected') AsyncioChannel AsyncioReplayChannel end properties (Dependent, SetAccess = 'private') BusSpeed NumOfSamples SJW TSEG1 TSEG2 end properties (Dependent, SetAccess = 'private') BusStatus end properties (SetAccess = 'private') Device DeviceChannelIndex DeviceSerialNumber DeviceVendor end properties (SetAccess = 'private') % DeviceType - The series and form factor of the device to which the % channel is connected. DeviceType end properties (SetAccess = 'protected') InitializationAccess InitialTimestamp end properties (Dependent, SetAccess = 'private') ReceiveErrorCount TransmitErrorCount end properties (SetAccess = 'private', GetAccess = 'protected') ReceiveQueueSize TransmitQueueSize end properties (SetAccess = 'private', GetAccess = 'private') % SessionReferenceInput - The reference value used within the vendor % driver to access the device represented by the channel for input. SessionReferenceInput % SessionReferenceOutput - The reference value used within the vendor % driver to access the device represented by the channel for output. SessionReferenceOutput end properties (Dependent) SilentMode % OnboardTermination - Configures the onboard termination of the % NI-XNET device which controls bus termination on device. OnboardTermination end properties (SetAccess = 'private') TransceiverName end properties (Dependent) TransceiverState end properties (SetAccess = 'private', GetAccess = 'protected') MultipleAccessAllowed = true; Usable = false; PrivateInitialTimestamp = datetime.empty(); end properties UserData % StartTriggerTerminal - Configures a sync/trigger connection % to start the NI-XNET channel on the connected source terminal. StartTriggerTerminal end methods function obj = Channel(varargin) % Channel Construct a connection to a CAN device. % Check the argument count. narginchk(2,2); % Put the input arguments into local variables. inVendor = varargin{1}; inDevice = varargin{2}; % Validate the vendor string. inVendor = validatestring(inVendor, {'NI'}, 'Channel', 'VENDOR', 1); % Validate the device string. validateattributes(inDevice, {'char'}, {'nonempty', 'row'}, 'Channel', 'DEVICE', 2); % Check for the presence of the vendor driver. if ~can.ni.xnet.Utility.isDriverAvailable(); error(message('vnt:Channel:DriverNotFound', 'National Instruments X-NET')); end % Get the channel information for the requested device. channelInfo = can.ni.xnet.Utility.getChannelInfoByInterface(inDevice); % If channel info is empty, the requested interface is not available. if isempty(channelInfo) error(message('vnt:Channel:DeviceNotFound')); end % Set the device identification properties. obj.DeviceVendor = inVendor; obj.Device = inDevice; obj.DeviceChannelIndex = channelInfo.Interface.PortNumber; obj.DeviceSerialNumber = dec2hex(channelInfo.Device.SerialNumber); obj.DeviceType = channelInfo.Device.ProductName; % Construct connections to the device. obj.SessionReferenceInput = can.ni.xnet.NIXNET.nxCreateSession( ... can.ni.xnet.Utility.USE_DEFAULT_DATABASE, ... can.ni.xnet.Utility.USE_NO_CLUSTER, ... can.ni.xnet.Utility.USE_NO_LIST, ... obj.Device, ... can.ni.xnet.Utility.nxMode_FrameInStream); obj.SessionReferenceOutput = can.ni.xnet.NIXNET.nxCreateSession( ... can.ni.xnet.Utility.USE_DEFAULT_DATABASE, ... can.ni.xnet.Utility.USE_NO_CLUSTER, ... can.ni.xnet.Utility.USE_NO_LIST, ... obj.Device, ... can.ni.xnet.Utility.nxMode_FrameOutStream); % Configure the read and write message queue sizes. obj.ReceiveQueueSize = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_QueueSize, ... 'u32'); obj.TransmitQueueSize = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceOutput, ... can.ni.xnet.Utility.nxPropSession_QueueSize, ... 'u32'); % Configure the device so that it does not automatically go online % when the connection is established. We want it to go online on % demand only. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceOutput, ... can.ni.xnet.Utility.nxPropSession_AutoStart, ... false); % Enable self reception so that messages transmitted are received % on this channel. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfEchoTx, ... true); % NI-XNET sessions are created without any baud rate set, so % default it to a known good value. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfBaudRate, ... can.ni.xnet.Utility.DefaultBusSpeed); % Determine the path for all asyncio plugins. arch = computer('arch'); devicePath = fullfile(toolboxdir('vnt'), 'vnt', 'private', arch, 'nixnetplugin'); converterPath = fullfile(toolboxdir('vnt'), 'vnt', 'private', arch, 'canmlconverter'); % Create the asyncio object for normal receive and transmit. asyncioOptions.SessionReferenceInput = obj.SessionReferenceInput; asyncioOptions.SessionReferenceOutput = obj.SessionReferenceOutput; asyncioOptions.ReceiveCapable = true; asyncioOptions.TransmitCapable = true; asyncioOptions.ReplayCapable = false; obj.AsyncioChannel = asyncio.Channel( ... devicePath, converterPath, asyncioOptions, [Inf, 0]); % Create the asyncio replay object. asyncioOptions.ReceiveCapable = false; asyncioOptions.TransmitCapable = true; asyncioOptions.ReplayCapable = true; obj.AsyncioReplayChannel = asyncio.Channel( ... devicePath, converterPath, asyncioOptions, [Inf, Inf]); % Normally this is used to indicate if the channel has % initialization rights for the device to which it is connected. % For NI-XNET devices though, InitializationAccess has no concrete % meaning because only one connection may be used at a time. It is % provided for general compatibility with code written for other % vendor devices. For NI-XNET devices then, InitializationAccess is % always true. obj.InitializationAccess = true; % Set the object usable. obj.Usable = true; end function configBusSpeed(obj, varargin) % configBusSpeed Set the bit timing of a CAN channel. % % configBusSpeed(CHANNEL, BUSSPEED) sets the speed of the CHANNEL % to BUSSPEED in a direct form that uses default bit timing % calculation factors. % % Examples: % channel = canChannel('NI', 'CAN0') % configBusSpeed(channel, 250000) % % See also VNT. % The full version of the bus speed configuration function is not % available for this hardware vendor. In order to avoid confusion, % we throw a special error message to indicate this. if nargin == 6 error(message('vnt:Channel:ConfigBusSpeedAdvancedFormNotAvailable')); end % Check the argument count. narginchk(2,2); % Validate the channel before using its functionality. assertValidity(obj); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Validate the busSpeed. validateattributes(varargin{1}, {'numeric'}, ... {'integer', 'nonempty', 'nonnan', 'nonsparse', 'real', ... 'scalar', '>=', 5000, '<=', 1000000}, ... 'configBusSpeed', 'BUSSPEED'); % Call the vendor driver to set the bit timing in direct form. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfBaudRate, ... varargin{1}); end function disp(obj) % disp Display array. % Validate the channel before using its functionality. assertValidity(obj); % Display a top level summary. fprintf(1, 'Summary of CAN Channel using ''%s'' ''%s''.\n\n',... obj.DeviceVendor,... obj.Device); % Display basic configuration parameters. fprintf(1, ' Channel Parameters: Bus Speed is %d.\n', obj.BusSpeed); fprintf(1, '%23sDevice type is ''%s''.\n', '', obj.DeviceType); fprintf(1, '%23sSerial Number of this device is ''%s''.\n', '', obj.DeviceSerialNumber); fprintf(1, '%23sTransceiver name is ''%s''.\n', '', obj.TransceiverName); % Display the currently attached database. if isempty(obj.Database) fprintf(1, '%23sNo database is attached.\n\n', ''); else fprintf(1, '%23s''%s.dbc'' database is attached.\n\n', '', obj.Database.Name); end % Display the current channel status. if obj.Running fprintf(1, '%14sStatus: Online.\n', ''); else fprintf(1, '%14sStatus: Offline - Waiting for start.\n', ''); end % Display message transmit and receive information. fprintf(1, '%23s%d messages available to receive.\n', '', obj.MessagesAvailable); fprintf(1, '%23s%d messages transmitted since last start.\n', '', obj.MessagesTransmitted); fprintf(1, '%23s%d messages received since last start.\n\n', '', obj.MessagesReceived); % Display a filter history section with the first entry in the log. fprintf(1, ' Filter History: %s\n', obj.FilterHistory); % Add a final line for spacing. fprintf(1, '\n'); end function getdisp(obj) % getdisp Overrides the standard getdisp to provide a formatting listing. % Validate the channel before using its functionality. assertValidity(obj); % Display general information. fprintf(1, '\n General Settings:\n'); fprintf(1, '\tBusStatus = ''%s''\n', obj.BusStatus); if isempty(obj.Database) fprintf(1, '\tDatabase = []\n'); else fprintf(1, '\tDatabase = ''%s.dbc''\n', obj.Database.Name); end fprintf(1, '\tFilterHistory = ''%s''\n', obj.FilterHistory); fprintf(1, '\tInitializationAccess = %d\n', obj.InitializationAccess); fprintf(1, '\tMessageReceivedFcn = %s\n', can.Utility.callbackFcnToString(obj.MessageReceivedFcn)); fprintf(1, '\tMessageReceivedFcnCount = %d\n', obj.MessageReceivedFcnCount); fprintf(1, '\tMessagesAvailable = %d\n', obj.MessagesAvailable); fprintf(1, '\tMessagesReceived = %d\n', obj.MessagesReceived); fprintf(1, '\tMessagesTransmitted = %d\n', obj.MessagesTransmitted); fprintf(1, '\tReceiveErrorCount = %d\n', obj.ReceiveErrorCount); fprintf(1, '\tRunning = %d\n', obj.Running); fprintf(1, '\tSilentMode = %d\n', obj.SilentMode); fprintf(1, '\tTransmitErrorCount = %d\n', obj.TransmitErrorCount); % Display device specific information. fprintf(1, '\n Device Settings:\n'); fprintf(1, '\tDevice = ''%s''\n', obj.Device); fprintf(1, '\tDeviceChannelIndex = %d\n', obj.DeviceChannelIndex); fprintf(1, '\tDeviceSerialNumber = ''%s''\n', obj.DeviceSerialNumber); fprintf(1, '\tDeviceVendor = ''%s''\n', obj.DeviceVendor); fprintf(1, '\tDeviceType = ''%s''\n', obj.DeviceType); % Display transceiver information. fprintf(1, '\n Transceiver Settings:\n'); fprintf(1, '\tTransceiverName = ''%s''\n', obj.TransceiverName); fprintf(1, '\tTransceiverState = %d\n', obj.TransceiverState); % Display bit timing information. fprintf(1, '\n Bit Timing Settings:\n'); fprintf(1, '\tBusSpeed = %d\n', obj.BusSpeed); fprintf(1, '\tSJW = %d\n', obj.SJW); fprintf(1, '\tTSEG1 = %d\n', obj.TSEG1); fprintf(1, '\tTSEG2 = %d\n', obj.TSEG2); fprintf(1, '\tNumOfSamples = %d\n\n', obj.NumOfSamples); end function setdisp(obj) % setdisp Overrides the standard setdisp to provide a formatting listing. % Validate the channel before using its functionality. assertValidity(obj); fprintf(1, '\n Database = can.Database handle -or- empty\n'); fprintf(1, ' MessageReceivedFcn = string -or- function handle -or- cell array\n'); fprintf(1, ' MessageReceivedFcnCount\n'); fprintf(1, ' SilentMode = [ {false} | true ]\n'); fprintf(1, ' TransceiverState\n\n'); end function out = get.BusStatus(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Get the value from the vendor driver. [state, ~] = can.ni.xnet.NIXNET.nxReadState( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxState_CANComm); out = state.CommunicationState; end function out = get.ReceiveErrorCount(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Get the value from the vendor driver. [state, ~] = can.ni.xnet.NIXNET.nxReadState( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxState_CANComm); out = state.ReceiveErrorCounter; end function out = get.TransmitErrorCount(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Get the value from the vendor driver. [state, ~] = can.ni.xnet.NIXNET.nxReadState( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxState_CANComm); out = state.TransmitErrorCounter; end function out = get.SilentMode(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Query the driver for the property value. out = logical(can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANLstnOnly, ... 'boolean')); end function set.SilentMode(obj, newValue) % Validate the channel before using its functionality. assertValidity(obj); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Validate the new value. validateattributes(newValue, {'logical'}, {'nonempty', 'scalar'}, 'set.SilentMode', 'VALUE'); % Set the property value according to the input. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANLstnOnly, ... newValue); end function out = get.OnboardTermination(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Query the driver for the property value. out = logical(can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANTerm, ... 'u32')); end function set.OnboardTermination(obj, newValue) % Validate the channel before using its functionality. assertValidity(obj); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Validate the new value. validateattributes(newValue, {'logical'}, {'nonempty', 'scalar'}, 'set.OnboardTermination', 'VALUE'); % Set the property value according to the input. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANTerm, ... newValue); end function set.StartTriggerTerminal(obj, newValue) % Validate the channel before using its functionality. assertValidity(obj); % Validate inputs. validateattributes(newValue, {'char'}, ... {'nonempty'}, 'set.StartTriggerTerminal', 'TERMINAL'); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Verify that the property is not being set more than once. if ~isempty(obj.StartTriggerTerminal) error(message('vnt:Channel:StartTriggerTerminalWriteOnce')); end % Insert a forward slash into the trigger terminal string if one is % not present. This is done to mask a bug in the XNET API that will % crash MATLAB if a slash is not included. Should NI fix this bug, % this protection can be removed. if newValue(1) ~= '/' newValue = ['/' newValue]; end % Get the channel information to determine the form factor. channelInfo = can.ni.xnet.Utility.getChannelInfoByInterface(obj.Device); %#ok<MCSUP> try % Set the start trigger in the driver depending on the form factor. switch channelInfo.Device.FormFactor % C series devices use the nxPropSession_IntfSrcTermStartTrigger % property. case can.ni.xnet.Utility.nxPropDev_FormFac_Values(2) % Set the XNET property. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfSrcTermStartTrigger, ... newValue); %#ok<MCSUP> % Other devices use the connectTerminals function. otherwise % Call the XNET function. can.ni.xnet.NIXNET.nxConnectTerminals( ... obj.SessionReferenceInput, ... newValue, ... can.ni.xnet.Utility.nxTerm_StartTrigger); %#ok<MCSUP> end catch err % Invalidate the property value. obj.StartTriggerTerminal = 'N/A'; % Rethrow the original error, likely a direct NI-XNET error. rethrow(err); end % Set the object property. obj.StartTriggerTerminal = newValue; end function out = get.TransceiverName(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Get the value of the property. out = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANTcvrType, ... 'u32'); out = can.ni.xnet.Utility.nxPropSession_IntfCANTcvrType_Values(out); end function out = get.TransceiverState(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Query the driver for the property value. out = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANTcvrState, ... 'u32'); end function set.TransceiverState(obj, newValue) % Validate the channel before using its functionality. assertValidity(obj); % Validate the input argument newValue. validateattributes(newValue, {'numeric'}, ... {'finite', 'integer', 'nonempty', 'nonnan', ... 'nonnegative', 'nonsparse', 'real', 'scalar'}, ... 'set.TransceiverState', 'VALUE'); % Query the driver for the property value. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfCANTcvrState, ... newValue); end function out = get.BusSpeed(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Query the driver for the property value. out = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfBaudRate, ... 'u32'); end function out = get.SJW(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Return this value as invalid as access to reading it for NI % hardware it not provided in their interface. out = NaN; end function out = get.TSEG1(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Return this value as invalid as access to reading it for NI % hardware it not provided in their interface. out = NaN; end function out = get.TSEG2(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Return this value as invalid as access to reading it for NI % hardware it not provided in their interface. out = NaN; end function out = get.InitialTimestamp(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Check the value of the internal private storage. if isempty(obj.PrivateInitialTimestamp) % Reread the value from the driver to see if the value has % changed or the channel has been triggered after start. [out, ~] = can.ni.xnet.NIXNET.nxReadState( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxState_TimeCommunicating); % Set the value into the internal private storage. obj.PrivateInitialTimestamp = out; else % Otherwise return the existing stored value. out = obj.PrivateInitialTimestamp; end end function out = get.NumOfSamples(obj) % Validate the channel before using its functionality. if ~assertValidity(obj) % Return empty for any invalid object state. out = []; return; end % Return this value as invalid as access to reading it for NI % hardware it not provided in their interface. out = NaN; end function obj = saveobj(obj) % saveobj Saves the channel information to file. % % OBJ = saveobj(OBJ) saves the channel for future loading. The % channel information is saved as a structure to due to the % nature of the channel's underlying connection to third party % drivers and devices. % Set object properties into a structure for saving. Turn the % warning off to so that it does not show to the user. warnState = warning('OFF', 'MATLAB:structOnObject'); saveInfo = struct(obj); warning(warnState); % Remove fields that should not be saved. saveInfo = rmfield(saveInfo, 'AsyncioChannel'); saveInfo = rmfield(saveInfo, 'AsyncioReplayChannel'); saveInfo = rmfield(saveInfo, 'CustomEventListener'); saveInfo = rmfield(saveInfo, 'ReceiveCallbackListener'); % Set the output to save. obj = saveInfo; end end methods (Access = 'protected') function onAsyncioCustomEvent(obj, source, data) %#ok<INUSD> % onAsyncioCustomEvent Callback function for event occurrence. % % onAsyncioCustomEvent(CHANNEL, SOURCE, DATA) is registered % with the Asyncio layer and is called upon custom event. end function filterSetInternal(obj, code, mask, idType) %#ok<INUSD> % filterSetInternal Sets hardware filters. % % This method is used internally by the hardware agnostic filtering % code to employ use of the hardware filters. There is a performance % benefit to block as many messages as possible via hardware filters % before applying software filtering on the channel. % NI-XNET has no implementation for hardware filtering use. end function setInitialTimestamp(obj) % setInitialTimestamp Set the initial timestamp property value. % Get the value direct from the driver. Set the value into the % internal private storage. [obj.PrivateInitialTimestamp, ~] = can.ni.xnet.NIXNET.nxReadState( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxState_TimeCommunicating); end end methods (Hidden) function delete(obj) % Stop the channel to ensure it is offline when removed. The % channel is stopped in the asyncio layer directly. if ~isempty(obj.AsyncioReplayChannel) obj.AsyncioReplayChannel.close(); end if ~isempty(obj.AsyncioChannel) obj.AsyncioChannel.close(); end % Clean up any vendor driver connections only if they were % initialized. This protects delete from generating errors on % partially failed construction. if ~isempty(obj.SessionReferenceInput) can.ni.xnet.NIXNET.nxClear(obj.SessionReferenceInput); end if ~isempty(obj.SessionReferenceOutput) can.ni.xnet.NIXNET.nxClear(obj.SessionReferenceOutput); end end function connectTerminals(obj, sourceTerminal, destinationTerminal) % connectTerminals Connects triggering terminals. % % connectTerminals(ch, sourceTerminal, destinationTerminal) connects % a source terminal to a destination terminal on the device. This % represents an external or internal hardware connection point. % Terminal inputs use NI Terminal I/O names. % % Examples: % channel = canChannel('NI', 'CAN0') % connectTerminals(channel, 'StartTrigger', 'FrontPanel0') % % See also VNT. % Check the argument count. narginchk(3, 3); % Validate the channel before using its functionality. assertValidity(obj); % Validate inputs. validateattributes(sourceTerminal, {'char'}, ... {'nonempty'}, 'connectTerminals', 'SourceTerminal'); validateattributes(destinationTerminal, {'char','cell'}, ... {'nonempty'}, 'connectTerminals', 'DestinationTerminal'); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Call direct to the NI-XNET API. can.ni.xnet.NIXNET.nxConnectTerminals( ... obj.SessionReferenceInput, ... sourceTerminal, ... destinationTerminal); end function disconnectTerminals(obj, sourceTerminal, destinationTerminal) % disconnectTerminals Disconnects triggering terminals. % % disconnectTerminals(ch, sourceTerminal, destinationTerminal) disconnects % a source terminal from a destination terminal on the device. This % represents an external or internal hardware connection point. % Terminal inputs use NI Terminal I/O names. % % Examples: % channel = canChannel('NI', 'CAN0') % connectTerminals(channel, 'StartTrigger', 'FrontPanel0') % disconnectTerminals(channel, 'StartTrigger', 'FrontPanel0') % % See also VNT. % Check the argument count. narginchk(3, 3); % Validate the channel before using its functionality. assertValidity(obj); % Validate inputs. validateattributes(sourceTerminal, {'char'}, ... {'nonempty'}, 'disconnectTerminals', 'SourceTerminal'); validateattributes(destinationTerminal, {'char','cell'}, ... {'nonempty'}, 'disconnectTerminals', 'DestinationTerminal'); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Call direct to the NI-XNET API. can.ni.xnet.NIXNET.nxDisconnectTerminals( ... obj.SessionReferenceInput, ... sourceTerminal, ... destinationTerminal); end function setStartTrigger(obj, sourceTerminal) % setStartTrigger Specifies a start trigger terminal. % % setStartTrigger(ch, sourceTerminal) connects a source terminal % to the start trigger on the device. This represents an internal % hardware connection point. Terminal inputs use NI Terminal I/O names. % % Examples: % channel = canChannel('NI', 'CAN0') % setStartTrigger(channel, '/cDAQ1/do/StartTrigger') % % See also VNT. % Check the argument count. narginchk(2, 2); % Validate the channel before using its functionality. assertValidity(obj); % Validate inputs. validateattributes(sourceTerminal, {'char'}, ... {'nonempty'}, 'setStartTrigger', 'SourceTerminal'); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Call direct to the NI-XNET API. can.ni.xnet.NIXNET.nxSetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfSrcTermStartTrigger, ... sourceTerminal); end function value = getStartTrigger(obj) % getStartTrigger Retrieves the interface start trigger terminal. % % getStartTrigger(ch, sourceTerminal) retrieves the interface start % trigger for use as a source terminal. This represents an internal % hardware connection point. % % Examples: % channel = canChannel('NI', 'CAN0') % triggerValue = getStartTrigger(channel) % % See also VNT. % Check the argument count. narginchk(1, 1); % Validate the channel before using its functionality. assertValidity(obj); % Verify that the channel is offline. if obj.Running error(message('vnt:Channel:ChannelNotOffline')); end % Call direct to the NI-XNET API. value = can.ni.xnet.NIXNET.nxGetProperty( ... obj.SessionReferenceInput, ... can.ni.xnet.Utility.nxPropSession_IntfSrcTermStartTrigger, ... 'cstr'); end end methods (Static) function obj = loadobj(obj) % loadobj Load a channel from memory. % % OBJ = loadobj(OBJ) loads the channel from memory. The % information loaded comes as a structure from which a new % channel is built and configured to look like the previously % saved channel. % % Note that if an error happens while attempting to reconnect or % reconfigure the channel, an empty version of the channel is % returned. The empty object will not reach the user though. The % MATLAB object system will reconstruct an invalid version of the % channel with empty properties. Returning empty is done simply % to avoid a class type warning in the event of a load error. % Check if the driver is available for devices from this vendor. if ~can.ni.xnet.Utility.isDriverAvailable() % Warn the user of the load issue. warning(message('vnt:Channel:CannotReconnectToDriver')); % Return an empty version of the channel. obj = can.ni.xnet.Channel.empty(); return; end % Collect information on all NI devices. channelInfo = can.ni.xnet.Utility.getChannelInfoByInterface(obj.Device); % Check for no match on the device. if isempty(channelInfo) % Warn the user of the load issue. warning(message('vnt:Channel:CannotReconnectToDevice')); % Return an empty version of the channel. obj = can.ni.xnet.Channel.empty(); return; end try % Recreate the loaded channel to rebuild a connection % to the device. newObj = can.ni.xnet.Channel('NI', channelInfo.Interface.Name); catch err % Check the error condition. if strfind(err.message, can.ni.xnet.Utility.ActiveConnectionErrorCode) % If the error condition matches the case checked, it means % this call failed because a connection to the device is % already established and running. In this case, we cannot % allow another connection to be made because NI hardware % only allows a single active connection. error(message('vnt:Channel:ActiveConnectionExists')); % Return an empty version of the channel. obj = can.ni.xnet.Channel.empty(); return; else % Warn the user of the load issue. warning(message('vnt:Channel:CannotReconfigureChannel')); % Return an empty version of the channel. obj = can.ni.xnet.Channel.empty(); return; end end try % Set the database in the channel only if the database file % was loaded properly for use. if ~isempty(obj.Database) && obj.Database.Usable newObj.Database = obj.Database; else newObj.Database = []; end % Reset the channel to the previous bus speed. configBusSpeed(newObj, obj.BusSpeed); % Reset silent mode only if the mode was previously set to % true. Since some devices from this vendor do not support % setting silent mode, we don't want to error and break the % load. if obj.SilentMode newObj.SilentMode = obj.SilentMode; end % Restore the filters to their previous state by performing % each filter operation again. Note that due to changes made in % version 1.3 of this object, we no longer maintain forward or % backward compatibility to restore filter settings. Only % 1.3 and great versions will have state restored on load. if obj.Version >= 1.3 % Check the configured state and set the filters on the new % object accordingly for standard and extended filters. switch obj.FilterStateStandard.State case 'Allow All' newObj.filterAllowAll('Standard'); case 'Block All' newObj.filterBlockAll('Standard'); case 'Allow Only' newObj.filterAllowOnly(obj.FilterStateStandard.PassList, 'Standard'); end switch obj.FilterStateExtended.State case 'Allow All' newObj.filterAllowAll('Extended'); case 'Block All' newObj.filterBlockAll('Extended'); case 'Allow Only' newObj.filterAllowOnly(obj.FilterStateExtended.PassList, 'Extended'); end end % Reset other properties to match the saved state. newObj.MessageReceivedFcn = obj.MessageReceivedFcn; newObj.MessageReceivedFcnCount = obj.MessageReceivedFcnCount; % Set the transceiver mode, but protect it also by only setting % it if the value is other than normal mode. Some devices do % not support setting of this property. if obj.TransceiverState ~= can.ni.xnet.Utility.nxCANTcvrState_Normal newObj.TransceiverState = obj.TransceiverState; end % Load the UserData. if obj.Version >= 1.4 newObj.UserData = obj.UserData; end % Load the InitialTimestamp and NI-specific properties. if obj.Version >= 1.5 newObj.PrivateInitialTimestamp = obj.PrivateInitialTimestamp; newObj.OnboardTermination = obj.OnboardTermination; if ~isempty(obj.StartTriggerTerminal) newObj.StartTriggerTerminal = obj.StartTriggerTerminal; end end % Set the new channel to return from loading. obj = newObj; catch err %#ok<NASGU> % Warn the user of the load issue. warning(message('vnt:Channel:CannotReconfigureChannel')); % Return an empty version of the channel. obj = can.ni.xnet.Channel.empty(); return; end end end end