/* * DIO.c * * Low level routines to initialize the DIO board and communicate * with the hardware. * * MARTest image acquisition software * This software has been written to acquire electron microscope * images using the MARTest IC and a DAQ system based on a * custom FPGA (Xilinx Spartan XC2S15) board, an ADC board (UXO * project - 14-bit 65MHz Analog Device ADC) and a DIO-32HS * board from National Instruments. * * (C) 2005-2007, Jean-Marie Bussat - jmbussat@lbl.gov * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "NIdaqex.h" #include "DIO.h" /************************************************************************ * Initialize all the ports of the DIO board * * Argument: none * * Returns : nothing * ************************************************************************ */ void InitDIO(){ i16 data; /* Default configuration for data bus is read only * Only reads from the FIFO * * create a 16-bit port for the data using DIOA & DIOB * 1 is the group "name" * 2 is the number of 8-bit port to be grouped * 0 indicates that port 0 (DIOA) and 1 (DIOB) are used * 0 indicates that they are configured in read mode */ DIG_Grp_Config(BOARD_ID,1,0,0,0); /* release existing group if any */ DIG_Grp_Config(BOARD_ID,1,2,0,0); /* Configure handshaking for 8255 emulation mode */ DIG_Grp_Mode(BOARD_ID,1,4,0,1,1,0); /* control bus (DIOC) has one output and one input * DIG_Line_Config(,,,direction); * board identifier: get it from MAX * port #: 0 to 3 (DIOA to DIOD) and 4 (handshaking lines) * bit #: 0 to 7 * direction: input=0, output=1 */ DIG_Line_Config(BOARD_ID,CTRL_PORT,DONE,0); /* done */ DIG_Line_Config(BOARD_ID,CTRL_PORT,START,1); /* start */ DIG_Line_Config(BOARD_ID,CTRL_PORT,CLR,1); /* clear */ DIG_Line_Config(BOARD_ID,CTRL_PORT,A0,1); /* timing reg addresss 0 */ DIG_Line_Config(BOARD_ID,CTRL_PORT,A1,1); /* timing reg addresss 1 */ DIG_Line_Config(BOARD_ID,CTRL_PORT,A2,1); /* timing reg addresss 2 */ DIG_Line_Config(BOARD_ID,CTRL_PORT,REG_INC,1); /* timing reg increment */ DIG_Line_Config(BOARD_ID,CTRL_PORT,REG_DEC,1); /* timing reg decrement */ /* Set default values for the outputs */ DIG_Out_Line(BOARD_ID,CTRL_PORT,START,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,CLR,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_INC,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_DEC,0); /* Second control bus */ DIG_Line_Config(BOARD_ID,ADC_PORT,REG_RES,1); /* timing reg reset */ DIG_Line_Config(BOARD_ID,ADC_PORT,REG_WEN,1); /* timing reg write */ DIG_Line_Config(BOARD_ID,ADC_PORT,RENBA,1); /* FIFO select bit 0 */ DIG_Line_Config(BOARD_ID,ADC_PORT,RENBB,1); /* FIFO select bit 1 */ /* Set default values for the outputs */ DIG_Out_Line(BOARD_ID,ADC_PORT,REG_RES,0); DIG_Out_Line(BOARD_ID,ADC_PORT,REG_WEN,0); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,0); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,0); } /************************************************************************ * Send a pulse (width irelevant) on the start line to initiate the * * acquisition of a new image. * * Argument: none * * Returns : nothing * ************************************************************************ */ void startAcquisition(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,START,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,START,0); } /************************************************************************ * Clear the flag indicated that an image has been received * * Argument: none * * Returns : nothing * ************************************************************************ */ void ClearDone(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,CLR,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,CLR,0); } void StartClear(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,CLR,1); } void StopClear(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,CLR,0); } /************************************************************************ * Read a 16-bit word from the FIFO * * Argument: none * * Returns : a 16-bit integer that has been read from the FIFO * ************************************************************************ */ int DIORead( i16 *data){ i16 d; int retVal; retVal=DIG_In_Grp(BOARD_ID,1,&d); d=(d&0x3FFF); /* only 14 bit of useful data */ *data=d; if(d<=0x1FFF){ *data=d+0x2000; } else { *data=d-0x2000; } //fprintf(stderr,"%d (%d)\n",d,retVal); return(retVal); } /************************************************************************ * Check if the image acquisition is done * * Argument: none * * Returns : an integer: 0=not done, 1=acquisition finished * ************************************************************************ */ int isReady(){ i16 LineState; DIG_In_Line(BOARD_ID,CTRL_PORT,DONE,&LineState); return((int)LineState); } /************************************************************************ * Select which FIFO channel to read * * Argument: an integer representing the channel number * * Returns : nothing * ************************************************************************ */ void FIFOselect(int chan){ switch(chan){ case 0: DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,1); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBB,1); break; case 1: DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,1); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBB,0); break; case 2: DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,0); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBB,0); break; case 3: DIG_Out_Line(BOARD_ID,ADC_PORT,RENBA,0); DIG_Out_Line(BOARD_ID,ADC_PORT,RENBB,1); break; } } /************************************************************************ * Control acquisition timing registers * * Argument: register number (0 to 7) * * Returns : nothing * ************************************************************************ */ void TimeRegInc(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_INC,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_INC,0); } void TimeRegDec(){ DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_DEC,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,REG_DEC,0); } void TimeRegRes(){ DIG_Out_Line(BOARD_ID,ADC_PORT,REG_RES,1); DIG_Out_Line(BOARD_ID,ADC_PORT,REG_RES,0); } void TimeRegEn(){ DIG_Out_Line(BOARD_ID,ADC_PORT,REG_WEN,1); } void TimeRegDis(){ DIG_Out_Line(BOARD_ID,ADC_PORT,REG_WEN,0); } void TimeReg_SetAddress(int addr){ switch(addr){ case 0: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,0); break; case 1: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,0); break; case 2: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,0); break; case 3: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,0); break; case 4: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,1); break; case 5: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,1); break; case 6: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,0); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,1); break; case 7: DIG_Out_Line(BOARD_ID,CTRL_PORT,A0,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A1,1); DIG_Out_Line(BOARD_ID,CTRL_PORT,A2,1); break; } }