% 	NiPS stands for National Instruments Port Sensor
% 	Script configures the first 24 bits of the National Instruments PCI DIO 96 card to  be inputs and
%	scans and displays the logic level of all bits in a tight loop.  The display detects rising and falling 
%	edges and displays the last transition. 
%
%	This function part of the Vanderbilt Matlab-IFIS FMRI software interface package.  NiPS is used
%	to diagnose problems with the hardware by reporting the status of bits on the interface.   
%
%	8/28/99	Allen Ingling wrote it.
%	1/27/00	Updated documentation
%	

% _______________________________________________________________________
%Set display parameters

bulb_size = 10;		%size of bulb indicating bit state, in pixels.
bulb_distance = 25;	%space between bulbs, in pixels.


%build a matrix holding the image of an up arrow to indicating rising edge

up_img = [
	0	0	0	0	1	0	0	0	0	;	
	0	0	0	1	1	1	0	0	0	;
	0	0	1	1	1	1	1	0	0	;
	0	0	0	0	1	0	0	0	0	;
	0	0	0	0	1	0	0	0	0	;
	0	0	0	0	1	0	0	0	0	;
	0	0	0	0	1	0	0	0	0	;
	0	0	0	0	1	0	0	0	0	;	
	0	0	0	0	1	0	0	0	0	;	
	0	0	0	0	1	0	0	0	0	;	
	0	0	0	0	1	0	0	0	0 ] ;
	
	
side_img = [
	0	0	0	0	0	0	0	0	0	;	
	0	0	0	0	0	0	0	0	0	;
	0	0	0	0	0	0	0	0	0	;
	0	0	0	0	0	0	0	0	0	;
	0	0	0	0	0	0	0	0	0	;
	1	1	1	1	1	1	1	1	1	;
	0	0	0	0	0	0	0	0	0	;
	0	0	0	0	0	0	0	0	0	;	
	0	0	0	0	0	0	0	0	0	;	
	0	0	0	0	0	0	0	0	0	;	
	0	0	0	0	0	0	0	0	0 ] ;

	
%invert and amplify contrast of the up arrow and side line;
up_img(find(up_img == 0)) = 255;
up_img(find(up_img == 1)) = 0;

side_img(find(side_img == 0)) = 255;
side_img(find(side_img == 1)) = 0;

%invert the up arrow to make a down arrow
down_img = flipud(up_img);
	
% _______________________________________________________________________
% Open onscreen windows and load CLUT

w = screen(0,'OpenWindow');
myCLUT = [[0:255]' [0:255]' [0:255]'];
myCLUT(2,:) = [255,0,0];	%red indicates bit value of logic 1
bulb_on = 1;
myCLUT(3,:) = [0,0,255];	%blue indicates bit value of logic 0
bulb_off = 2;
screen(w,'SetClut',myCLUT);
screen(w,'FillRect',255);

% _______________________________________________________________________
% establish coordinates of screen objects

protoFrame = [0 0 bulb_distance (2*bulb_distance)];
protoFrameTop = [0 0 bulb_distance bulb_distance];
protoFrameBottom = [0 bulb_distance bulb_distance (2 * bulb_distance)];
protoBulbFrame = [0 0 bulb_size bulb_size];
protoBulbFrame = CenterRect(protoBulbFrame, protoFrameTop);
[edgeHeight, edgeWidth] = size(up_img);
protoEdgeFrame = [0 0 edgeWidth edgeHeight];
protoEdgeFrame = CenterRect(protoEdgeFrame, protoFrameBottom);

for i = 1:3
	for j = 1:8
		frame{i,j} = offsetRect(protoFrame, j * bulb_distance, i * 2 * bulb_distance);
		bulb{i,j} = offsetRect(protoBulbFrame, j * bulb_distance, i * 2 * bulb_distance);
		edge{i,j} = offsetRect(protoEdgeFrame,  j * bulb_distance, i * 2 * bulb_distance);
	end %for j
end %for i

% _______________________________________________________________________
% draw and frame the bulbs on the onscreen window

for i = 1:3
	for j = 1:8
		screen(w,'FrameRect', 0, frame{i,j});
		screen(w,'FillOval', bulb_on, bulb{i,j});
		screen(w,'PutImage', side_img, edge{i,j});
	end %for j
end  %for i

% _______________________________________________________________________
% setup I/O port

%find the card
devNum = FindCard('PCI-DIO-96',[1:3]);

%configure the ports
DIG_Prt_Config(devNum, 0, 0,0);		%configure 8255 port A to be input, no handshake
DIG_Prt_Config(devNum, 1, 0,0);		%configure 8255 port B to be input, no handshake
DIG_Prt_Config(devNum, 2, 0,0);		%configure 8255 portC to be input, no handshake

% _______________________________________________________________________
%loop, scanning ports and updating screen

portBitsPast = ones(3,8);
haltLoop = 0;
while ~haltLoop
	%scan the ports
	for i = 1:3
		portScan(i) = DIG_In_Port(devNum, i - 1);
	end %for i

	%mask scan values to find bits
	for i = 1:3
		for j = 1:8
			portBits(i,j) = bitand(2^(j-1),portScan(i));
		end %for j
	end %for i

	%draw bit values to screen
	for i = 1:3
		for j = 1:8
			if portBits(i,j)
				screen(w,'FillOval',bulb_on,bulb{i,j});
			else
				screen(w,'FillOval',bulb_off,bulb{i,j});
			end %if ..else
			if ( portBitsPast(i,j)  & ~portBits(i,j)) 
				screen(w,'PutImage', down_img, edge{i,j});
			elseif ( ~portBitsPast(i,j) & portBits(i,j))
				screen(w,'PutImage', up_img, edge{i,j});
			end %if.. elseif... 
		end %for j
		haltLoop = kbCheck;
	end %for i
	portBitsPast = portBits; 
end %while




	










