/usr/share/psychtoolbox-3/PsychHardware/Daq/DaqAIn.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | function v=DaqAIn(daq,channel,range,UnCal)
% v=DaqAIn(DeviceIndex,channel,range,[DoNotCalibrate])
% Analog input.
% USB-1208FS:
% "v" is the measured voltage, in Volts, or NaN if no data were received.
% "DeviceIndex" is a small integer, the array index specifying which HID
% device in the array returned by PsychHID('Devices') is interface 0
% of the desired Daq device.
% "channel" (0 to 15) selects any of various single-ended or differential
% measurements.
% "channel" Measurement
% 0 0-1 (differential)
% 1 2-3 (differential)
% 2 4-5 (differential)
% 3 6-7 (differential)
% 4 1-0 (differential)
% 5 3-2 (differential)
% 6 5-4 (differential)
% 7 7-6 (differential)
% 8 0 (single-ended)
% 9 1 (single-ended)
% 10 2 (single-ended)
% 11 3 (single-ended)
% 12 4 (single-ended)
% 13 5 (single-ended)
% 14 6 (single-ended)
% 15 7 (single-ended)
% "range" (0 to 7) sets the gain (hence voltage range):
% for single-ended measurements (channels 8-15), range is always +/- 10 V,
% and attempts to set ranges other than 0 usually result in saturation, so
% setting range in this function does not do anything. For differential
% measurements (channels 0-7), the map between range as input to this
% function and the output generated is:
% 0 for Gain 1x (+/-20 V), 1 for Gain 2x (+/-10 V),
% 2 for Gain 4x (+/-5 V), 3 for Gain 5x (+/-4 V),
% 4 for Gain 8x (+/-2.5 V), 5 for Gain 10x (+/-2 V),
% 6 for Gain 16x (+/-1.25 V), 7 for Gain 20x (+/-1 V).
% "DoNotCalibrate" for 1208FS has no effect
%
% USB-1608FS:
% only single-ended inputs are defined, so "channel" is restricted to integers
% from 0 to 7. Ignore the manual which claims that gains are restricted to only
% four possible values. Thank the linux people for discovering:
% 0 for Gain 1x (+/- 10 V), 1 for Gain 2x (+/-5 V),
% 2 for Gain 4x (+/- 2.5 V), 3 for Gain 5x (+/- 2 V),
% 4 for Gain 8x (+/- 1.25 V), 5 for Gain 10x (+/- 1V),
% 6 for Gain 16x (+/- 0.625 V), 7 for Gain 32x (+/- 0.3125 V)
%
% "DoNotCalibrate" (0 or 1) if non-zero, function does not use information
% acquired from calibration measurements (see DaqCalibrateAIn). This should
% probably always be 0 when function is called by a user (hence it defaults to
% 0). Flag was created for the purpose of acquiring calibration data.
% Otherwise subsequent calibration measurements would be fits of fits.
%
% See also Daq, DaqFunctions, DaqPins, DaqTest, PsychHIDTest,
% DaqDeviceIndex, DaqDIn, DaqDOut, DaqAIn, DaqAOut, DaqAInScan,DaqAOutScan.
%
% 4/15/05 dgp Wrote it.
% 1/21/07 asg changed normalization value from 2^16 to 2^15 to account for 16th bit as a sign bit (not data bit)
% and modified the "range" value help.
% 6/17/07 mk Add proper sign handling for negative voltages.
% 12/2x/07-1/x/08 mpr modified to work with USB-1608FS and changed some
% terminology; particularly did away with "sign" name
% conflict ("sign" is a Matlab function)
% 6/07/13 mk Try to make it more robust: Retry on no-date received, proper
% error handling with error abort on error instead of silent
% failure returning NaN. Cleanup.
% Perform internal caching of list of HID devices to speedup call:
persistent devices;
if isempty(devices)
devices = PsychHIDDAQS;
end
if nargin < 4 || isempty(UnCal)
UnCal=0;
end
if strcmp(devices(daq).product(5:6),'16')
Is1608=1;
MaxChannelID = 7;
else
Is1608=0;
MaxChannelID = 15;
% ignore range input for single-ended measurements
if channel > 7
range=0;
end
end
% Receive and flush all stale reports from device or in receive queue:
err = PsychHID('ReceiveReports',daq);
if err.n
error('DaqAIn ReceiveReports error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
err = PsychHID('ReceiveReportsStop',daq);
if err.n
error('DaqAIn ReceiveReportsStop error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
[reports,err] = PsychHID('GiveMeReports',daq);
if err.n
error('DaqAIn GiveMeReports error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
if ~ismember(channel,0:MaxChannelID)
error('DaqAIn: "channel" must be an integer 0 to %d.',MaxChannelID);
end
if ~ismember(range,0:7)
error('DaqAIn: "range" must be an integer 0 to 7.');
end
% Send analog measurement request to device:
err = PsychHID('SetReport',daq,2,16,uint8([16 channel range]));
if err.n
error('DaqAIn SetReport error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
% Enable reception of data from device and retry reception until a valid
% non-empty report of 3 Bytes size arrives:
report = [];
while isempty(report) || length(report)~=3
err = PsychHID('ReceiveReports',daq);
if err.n
error('DaqAIn ReceiveReports-II error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
[report,err] = PsychHID('GetReport',daq,1,16,3); % Get report
if err.n
error('DaqAIn GetReport error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
end
% Ok, got a non-empty report of length 3 as expected. Stop reception:
err = PsychHID('ReceiveReportsStop',daq);
if err.n
error('DaqAIn ReceiveReportsStop-II error 0x%s. %s: %s\n',hexstr(err.n),err.name,err.description);
end
if Is1608
vmax = [10 5 2.5 2 1.25 1 0.625 0.3125];
RawValue = double(report(3))*256 + double(report(2));
v = vmax(range+1)*(RawValue/32768-1);
if UnCal
return;
else
DaqPrefsDir = DaqtoolboxConfigDir;
if exist([DaqPrefsDir filesep 'DaqPrefs.mat'],'file')
DaqVars = load([DaqPrefsDir filesep 'DaqPrefs']);
if isfield(DaqVars,'CalData')
CalData = DaqVars.CalData;
GoodIndices = find(CalData(:,1) == channel & CalData(:,2) == range);
if ~isempty(GoodIndices)
TheDays = CalData(GoodIndices,end);
ThisDay = datenum(date);
[DaysSinceLast,BestIndex] = min(ThisDay-TheDays);
AllThatDay = find(TheDays == TheDays(BestIndex));
MostRecentPolyFit = CalData(GoodIndices(AllThatDay(end)),3:5);
if DaysSinceLast > 30
warning('Psychtoolbox:Daq:outdatedCalibration', 'Calibration of this channel has not been performed since %s!!', ...
datestr(TheDays(BestIndex)));
end
v = polyval(MostRecentPolyFit,v);
return;
end
end % if isfield(DaqVars,'CalData')
end % if exist([DaqPrefsDir filesep 'DaqPrefs.mat'],'file')
end % if UnCal
warning('Psychtoolbox:Daq:missingCalibration', ['It looks like this channel has not yet been calibrated. In my\n' ...
'tests, uncalibrated values could be off by as much as 15%%!']);
else
% Mapping table value -> voltage for differential gains:
vmax=[20 10 5 4 2.5 2 1.25 1];
RawReturn = double(report(2:3))*[1; 256];
if channel < 8
% combined two-bytes of report make a 2's complement 12-bit value
DigitalValue = bitshift(RawReturn,-4);
if bitget(DigitalValue,12)
DigitalValue = -bitcmp(DigitalValue,12)-1;
end
else
% range needs to be zero above during call to PsychHID('SetReport',... but
% must be 1 to get scale below.
range=1;
% combined two-bytes of report make a 2's complement 11-bit value
if RawReturn > 32752
DigitalValue = -2048;
elseif RawReturn > 32736
DigitalValue = 2047;
else
DigitalValue = bitand(4095,bitshift(RawReturn,-3))-2048;
end
end
v=vmax(range+1)*DigitalValue/2047;
end
return;
|