This file is indexed.

/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;