/************************************************************************** ** ** ircommand.c - IR Commands ** *************************************************************************** */ /*-------------------------- ** include files **-------------------------- */ #if LINUX #include #include #include #include #include #include "common.h" #else #include /* uboot general include file */ #include /* uboot general include file */ #include /* uboot command_opt stuff */ #endif #include "ce.h" #include "ircommand.h" #include "ir.h" #include "al.h" #include "h2.h" #include "pnp.h" //#define DEBUG_IRCOMMAND /*-------------------------- ** defines **-------------------------- */ struct ir_param_t /* IR parameter are in Ip. */ { /*----------------------- parameter for all ir devices ------------------------*/ int irdevice; /* irdevice: AL, H2 */ int acqmode; /* acquisition mode: basic, movie */ int cbmode; /* clock&buffer mode (fs, fd, ramp) */ int itime_msec; /* observer requested exposure time in milliseconds */ int coadd; /* basic, movie: coadd this many frames per image */ int ndr; /* requested number of readout for fowler sampling */ int rsample; /* requested readout for sample up the ramp */ int num_darray; /* number of data arrays */ struct ir_array_t darray[3]; /* 3 data array with X, Y, Wid, Hgt */ int numsample; /* ADC numsamples */ int numchannels; /* ADC numchannels */ int multisample_gap; /* ADC multisample gap */ int slowcnt; /* controls clocking waveform time resolution */ int bgr_wait_ms; /* time to wait between BGR and GO in milliseconds */ unsigned long long bgr_last_ticks; /* when the last background reset was done (beg time) */ /*----------------------- parameter for all aladdin devices ------------------------*/ int al_glr_period_usec; /* Global Reset Period in usec; 1 to 250000 */ int al_bgr_period_usec; /* background _reset period in usec; 1 to 250000 */ /*----------------------- parameter for H2RG devices ------------------------*/ int h2_glr_enable; /* Global Reset Enable: T=GlobalReset; F=PixelByPixels; */ int h2_glr_period_usec; /* Global Reset Period in usec; 1 to 250000 */ int h2_bgr_flag; /* if bgr_flag == 0 => regular readout, else bgr readout */ int h2_bgr_period_usec; /* background _reset period in usec; 1 to 250000 */ int h2_bgr_gowait_ms; /* background reset wait time before a GO. 1 to 60000 */ }; struct go_vars_t /* Varaible need during a GO */ { /* tk_ are recording of get_tick() */ unsigned long long tk_beg; /* beginning of GO */ unsigned long long tk_setup_done; /* after go_setup() */ unsigned long long tk_start_done; /* after go_start() - when CE engine starts */ /* general status */ int done; /* True when the GO is done */ /* ck status */ int ck_done; /* True when clocking is done */ int ck_si; /* Seq.seq[] index */ int ck_ci; /* CE_s/r index */ }; /*-------------------------- ** global variables **-------------------------- */ struct ir_param_t Ip; /* IR Parameters */ struct ir_seq_t Seq; /* Sequence Table */ struct alst_table_t STable; /* Scan Table (for al device) */ struct ir_ce_buf_t CE_sam; /* CE buffer for array reaout */ struct ir_ce_buf_t CE_reset; /* CE buffer for array reset */ struct go_vars_t Go; /* Varaible need during a GO */ ce_t * Ce0; /* reference to ce_t for dev 0 */ ce_t * Ce1; /* reference to ce_t for dev 1 */ /* for selection list */ char * Irdevice_selection[NUM_IRDEVICE+1] = {"h2", "al", NULL}; char * Acqmode_selection[NUM_ACQMODE+1] = {"basic", "movie", NULL}; char * Cbmode_selection[NUM_CBMODE+1] = {"fs", "fd", "ramp", NULL}; extern struct h2rg_settings_t h2rg_settings; /*-------------------------------- ** (static ) function prototype **-------------------------------- */ static int go_setup_data( void ); static int go_start( void ); static int go_clocking( void ); static void printf_ir_param ( FILE * fp, struct ir_param_t *ip ); static void ir_execute_ce( struct ir_ce_buf_t * ceb, int gps ); static int parseSelection( char * buf, char * tok, char ** list); /***************************************************************************/ /* controller camera commands */ /***************************************************************************/ /*-------------------------------------------------------------------------------- ** acqmode_app() - set acqmode or acquisition mode. ** syntax: acqmode { basic | movie } **-------------------------------------------------------------------------------- */ int acqmode_app( int argc, char * argv[] ) { int acqmode; if ( argc != 2 ) return FAIL; if ( (acqmode = parseSelection( argv[1], " ", Acqmode_selection )) < 0 ) return FAIL; Ip.acqmode = acqmode; return PASS; } /*-------------------------------------------------------------------------------- ** bgr_go() - perform a Background Reset. The linux host should use this command ** to perform periodically reset of the array. ** syntax: bgr.go **-------------------------------------------------------------------------------- */ int bgr_go( int argc, char * argv[] ) { return PASS; } /*-------------------------------------------------------------------------------- ** bgr_wait_ms() - sets the minimum period in ms. ** syntax: bgr.wait.ms ms ** ms - minimum period after a BRG, before the GO can begin. **-------------------------------------------------------------------------------- */ int bgr_wait_ms( int argc, char * argv[] ) { int ms; // get arguments if ( argc != 2 ) return FAIL; ms = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, ms, 60000) ) return FAIL; Ip.bgr_wait_ms = ms; return PASS; } /*-------------------------------------------------------------------------------- ** cbmode_app() - set cbmode or clock/buffer mode. ** syntax: cbmode { fs | fd | ramp } **-------------------------------------------------------------------------------- */ int cbmode_app( int argc, char * argv[] ) { int cbmode; if ( argc != 2 ) return FAIL; if ( (cbmode = parseSelection( argv[1], " ", Cbmode_selection )) < 0 ) return FAIL; Ip.cbmode = cbmode; return PASS; } /*-------------------------------------------------------------------------------- ** coadd_app() - set coadd parameter. Used for basic & movie mode to specify ** how many images are added together before being 'saved'. ** syntax: coadd N **-------------------------------------------------------------------------------- */ int coadd_app( int argc, char * argv[] ) { int coadd; if ( argc != 2 ) return FAIL; coadd = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, coadd, 32000) ) return FAIL; Ip.coadd = coadd; return PASS; } /*-------------------------------------------------------------------------------- ** darray_app() - define the location and size of a data array (or sub array). ** syntax: darray i x y wid hgt **-------------------------------------------------------------------------------- */ int darray_app( int argc, char * argv[] ) { int i, x, y, wid, hgt; if ( argc != 6 ) return FAIL; i = simple_strtol( argv[1], NULL, 10 ); x = simple_strtol( argv[2], NULL, 10 ); y = simple_strtol( argv[3], NULL, 10 ); wid = simple_strtol( argv[4], NULL, 10 ); hgt = simple_strtol( argv[5], NULL, 10 ); if ( Ip.irdevice == IRDEVICE_AL ) { /* for aladdin arrays: */ /* x,wid must be on 16 pixel boundary. wid must be 6 or greater. */ /* y,hgt must be on 4 pixel boundary. */ x -= x%16; y -= y%4; if ( wid < 16 ) wid = 16; wid -= wid%16; hgt -= hgt%4; if ( !INRANGE(0, x, AL_NAXIS1-1) || !INRANGE(0, y, AL_NAXIS2-1) || !INRANGE(1, x+wid, AL_NAXIS1) || !INRANGE(1, y+hgt, AL_NAXIS2) ) return FAIL; } if ( !INRANGE( 0, i, 2 )) return FAIL; Ip.darray[i].x = x; Ip.darray[i].y = y; Ip.darray[i].wid = wid; Ip.darray[i].hgt = hgt; return PASS; } /*-------------------------------------------------------------------------------- ** irinit_app() - Initialize stuff ** syntax: irinit { al | h2 } **-------------------------------------------------------------------------------- */ int irinit_app( int argc, char * argv[] ) { int irdevice; if ( (argc != 2 ) || (irdevice = parseSelection( argv[1], " ", Irdevice_selection )) < 0 ) { //irdevice = IRDEVICE_AL; irdevice = IRDEVICE_H2; } Ip.irdevice = irdevice; ircommand_initial_setup( Ip.irdevice ); return PASS; } /*-------------------------------------------------------------------------------- ** itime_msec_app() - set integration time in msec. itime is request exposure time. ** syntax: itime_msec msec **-------------------------------------------------------------------------------- */ int itime_msec_app( int argc, char * argv[] ) { unsigned long itime_msec; if ( argc != 2 ) return FAIL; itime_msec = simple_strtol( argv[1], NULL, 10 ); /* bigger that 2174 sec would overflow a int - that would */ /* be 33 min, so let's make it 1800 sec or 30 minutes */ if ( !INRANGE( 1, itime_msec, 1800000) ) return FAIL; Ip.itime_msec = itime_msec; return PASS; } /*-------------------------------------------------------------------------------- ** ndr_app() - set ndr parameter. ** Specifies how many array readout are used in fowler sampling. ** syntax: ndr N **-------------------------------------------------------------------------------- */ int ndr_app( int argc, char * argv[] ) { int ndr; if ( argc != 2 ) return FAIL; ndr = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, ndr, 128) ) return FAIL; Ip.ndr = ndr; return PASS; } /*-------------------------------------------------------------------------------- ** num_darray_app() - set num_darray, tell controller how many darray to use ** to determine what pixels are read out. ** syntax: NumDArray N **-------------------------------------------------------------------------------- */ int num_darray_app( int argc, char * argv[] ) { int num_darray; if ( argc != 2 ) return FAIL; num_darray = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, num_darray, 3) ) return FAIL; Ip.num_darray = num_darray; return PASS; } /*-------------------------------------------------------------------------------- ** rsample() - Or RampSamples. Used for Ramp image. Indicate how many array ** readout are needed for the resulting sample of the ramp image. 3 to 10. ** syntax: rsample N **-------------------------------------------------------------------------------- */ int rsample_app( int argc, char * argv[] ) { int rsample; if ( argc != 2 ) return FAIL; rsample = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 3, rsample, 10) ) return FAIL; Ip.rsample = rsample; return PASS; } /*-------------------------------------------------------------------------------- ** slowcnt() - Sets the basic period of the clocking wave forms. ** Slowcnts defines the small TimeSlice in the clocking wave form, the ** values 0, 1, 2, .. result in 40, 60, 80, 100 nsec timeslice in clocking. ** or T_nsec = 40 + (slowcnt*20) ** A digout_lo & delay command takes 70ns to execute: ** CE_PARAM_UPDWR_LO(50ns)+CE_CMD_NOP(20ns)=70ns. ** So slowcount of 0, 1, 2 are impossible/impractial (FIFO starves). ** The minimum accepted value is 3 (100ns)... but not guarantee to work. ** syntax: slowcnt N **-------------------------------------------------------------------------------- */ int slowcnt_app( int argc, char * argv[] ) { int slowcnt; if ( argc != 2 ) return FAIL; slowcnt = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 3, slowcnt, 200) ) return FAIL; Ip.slowcnt = slowcnt; return PASS; } /********************************************************************************/ /* controller command - aladdin optons */ /********************************************************************************/ /*-------------------------------------------------------------------------------- ** al_bgr_app() - Sets the backgrond reset period for the AL device. ** syntax: al.bgr.usec usec ** usec: How long to hold the reset line on the array. **-------------------------------------------------------------------------------- */ int al_bgr_usec_app( int argc, char * argv[] ) { int usec; // get arguments if ( argc != 2 ) return FAIL; usec = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, usec, 250000) ) return FAIL; Ip.al_bgr_period_usec = usec; return PASS; } /*-------------------------------------------------------------------------------- ** al_glr_app() - glr sets the global reset period ** syntax: al.glr.usec usec ** usec: How long to hold the reset line on the array. **-------------------------------------------------------------------------------- */ int al_glr_usec_app( int argc, char * argv[] ) { int usec; // get arguments if ( argc != 2 ) return FAIL; usec = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 1, usec, 250000) ) return FAIL; Ip.al_glr_period_usec = usec; return PASS; } /********************************************************************************/ /* controller command - H2RG optons */ /********************************************************************************/ /*-------------------------------------------------------------------------------- ** h2_bgr_app() - bgr sets the background reset options. ** syntax: bgr flag period_usec bgr_gowait_ms **-------------------------------------------------------------------------------- */ int h2_bgr_app( int argc, char * argv[] ) { int bgr_flag, bgr_period_usec, bgr_gowait_ms; // get arguments if ( argc != 4 ) return FAIL; bgr_flag = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 0, bgr_flag, 1) ) return FAIL; bgr_period_usec = simple_strtol( argv[2], NULL, 10 ); if ( !INRANGE( 1, bgr_period_usec, 250000) ) return FAIL; bgr_gowait_ms = simple_strtol( argv[3], NULL, 10 ); if ( !INRANGE( 1, bgr_gowait_ms, 60000) ) return FAIL; Ip.h2_bgr_flag = bgr_flag; Ip.h2_bgr_period_usec = bgr_period_usec; Ip.h2_bgr_gowait_ms = bgr_gowait_ms; return PASS; } /*-------------------------------------------------------------------------------- ** h2_glr_app() - glr sets the global reset options ** syntax: glr glr_enable glr_period_usec ** glr_enable: T=GlobalResetOnArray; F=PixelbyPixelResets ** glr_period_usec: How long to hold the reset line on the array. **-------------------------------------------------------------------------------- */ int h2_glr_app( int argc, char * argv[] ) { int glr_enable, glr_period_usec; // get arguments if ( argc != 3 ) return FAIL; glr_enable = simple_strtol( argv[1], NULL, 10 ); if ( !INRANGE( 0, glr_enable, 1) ) return FAIL; glr_period_usec = simple_strtol( argv[2], NULL, 10 ); if ( !INRANGE( 1, glr_period_usec, 250000) ) return FAIL; Ip.h2_glr_enable = glr_enable; Ip.h2_glr_period_usec = glr_period_usec; return PASS; } int h2rg_t1_app(int argc, char *argv[]) { return h2rg_t1_ir(Ce0); } int h2rg_init_app(int argc, char *argv[]) { h2rg_init_ir(); return PASS; } int h2rg_check_subarray_app(int argc, char *argv[]) { return 0; } int h2rg_bgrclock_app(int argc, char *argv[]) { int usecs = 0; if(argc != 2) return FAIL; usecs = simple_strtol(argv[1], NULL, 10); if( !INRANGE(0, usecs, 10) ) return FAIL; return h2rg_bgrclock(usecs); } int h2rg_bgren_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "on") == 0) h2rg_bgren(1); else if(strcmp(argv[1], "off") == 0) h2rg_bgren(0); else return FAIL; return PASS; } int h2rg_bgrrest_app(int argc, char *argv[]) { int usecs = 0; if(argc != 2) return FAIL; usecs = simple_strtol(argv[1], NULL, 10); if( !INRANGE(0, usecs, 10) ) return FAIL; return h2rg_bgrrest(usecs); } int h2rg_bgrwait_app(int argc, char *argv[]) { int usecs = 0; if(argc != 2) return FAIL; usecs = simple_strtol(argv[1], NULL, 10); if( !INRANGE(0, usecs, 10) ) return FAIL; return h2rg_bgrwait(usecs); } int h2rg_itime_app(int argc, char *argv[]) { #ifdef FIXME double itime; int rc = 0; if(argc != 2) return FAIL; rc = parseDouble_r(&itime, argv[1], ' ', NULL); h2rg_itime(itime); #endif return PASS; } int h2rg_rdr_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "on") == 0) return h2rg_rdr(1); else if(strcmp(argv[1], "off") == 0) return h2rg_rdr(0); else return FAIL; } int h2rg_rom_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "single") == 0) return h2rg_rom(0); else if(strcmp(argv[1], "double") == 0) return h2rg_rom(1); else if(strcmp(argv[1], "sur") == 0) return h2rg_rom(2); else return FAIL; } int h2rg_rren_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "on") == 0) return h2rg_rren(1); else if(strcmp(argv[1], "off") == 0) return h2rg_rren(0); else return FAIL; } int h2rg_setrstm_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "pixel") == 0) return h2rg_setrstm(0); else if(strcmp(argv[1], "line") == 0) return h2rg_setrstm(1); else if(strcmp(argv[1], "global") == 0) return h2rg_setrstm(2); else return FAIL; } int h2rg_setttf_app(int argc, char *argv[]) { return PASS; } int h2rg_setttl_app(int argc, char *argv[]) { return PASS; } int h2rg_setvrd_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "up") == 0) return h2rg_setvrd(1); else if(strcmp(argv[1], "down") == 0) return h2rg_setvrd(0); else return FAIL; } int h2rg_setwd_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "none") == 0) return h2rg_setwd(0); else if(strcmp(argv[1], "low") == 0) return h2rg_setwd(1); else if(strcmp(argv[1], "high") == 0) return h2rg_setwd(2); else return FAIL; } int h2rg_slowcnt_app(int argc, char *argv[]) { int sc = 0; if(argc != 2) return FAIL; sc = simple_strtol(argv[1], NULL, 10); if( !INRANGE(0, sc, 100) ) return FAIL; return h2rg_slowcnt(sc); } int h2rg_surwt_app(int argc, char *argv[]) { int wait = 0; if(argc != 2) return FAIL; wait = simple_strtol(argv[1], NULL, 10); if( !INRANGE(0, wait, 1000000) ) return FAIL; return h2rg_surwt(wait); } int h2rge_suram_app(int argc, char *argv[]) { if(argc != 2) return FAIL; if(strcmp(argv[1], "prsur") == 0) return h2rge_suram(1); else return h2rge_suram(0); } int h2rge_setreg_app(int argc, char *argv[]) { return PASS; } int h2rge_setemd_app(int argc, char *argv[]) { return PASS; } int h2rge_setspr_app(int argc, char *argv[]) { return PASS; } int h2rge_selsp_app(int argc, char *argv[]) { return PASS; } int h2rge_selsl_app(int argc, char *argv[]) { return PASS; } int h2rge_vbg_app(int argc, char *argv[]) { return PASS; } int h2rge_vds_app(int argc, char *argv[]) { return PASS; } int h2rge_vrst_app(int argc, char *argv[]) { return PASS; } int h2rge_psswd_app(int argc, char *argv[]) { return PASS; } /** * Peak and poke functions */ int pnp_shutter_open_app(int argc, char *argv[]) { return PASS; } int pnp_shutter_close_app(int argc, char *argv[]) { return PASS; } int pnp_fifo_run_app(int argc, char *argv[]) { return PASS; } int pnp_fifo_stop_app(int argc, char *argv[]) { return PASS; } int pnp_digio_app(int argc, char *argv[]) { return PASS; } int pnp_ppg4_app(int argc, char *argv[]) { return PASS; } int pnp_ppg4_run_app(int argc, char *argv[]) { return PASS; } int pnp_spg4_app(int argc, char *argv[]) { return PASS; } int pnp_spg3_app(int argc, char *argv[]) { return PASS; } int pnp_spg_run_app(int argc, char *argv[]) { return PASS; } /********************************************************************************/ /* controller command - GO */ /* for pclock, GO generates the data need to clock out the irdevices */ /********************************************************************************/ /*-------------------------------------------------------------------------------- ** go_app() - Acquire an image. ** syntax: go **-------------------------------------------------------------------------------- */ int go_app( int argc, char * argv[] ) { int rc; memset( &Go, 0, sizeof(Go)); Go.tk_beg = get_ticks(); Go.done = 0; rc = PASS; printf("go_app\n"); //ir_printf(fp, "go_app\n"); /*--------------------------------------- ** Generate Clocking and Sequence data */ if ( (rc = go_setup_data( )) == FAIL ) goto ldone; Go.tk_setup_done = get_ticks(); printf("setup done\n"); /*--------------------------------------- ** setup & starts data buffering and transfer */ /*--------------------------------------- ** setup & starts clocking */ if ( (rc = go_start( )) == FAIL ) goto ldone; Go.tk_start_done = get_ticks(); /*--------------------------------------- ** execute ... */ while ( !Go.done ) { /* ** service clocking fifo */ if ( (rc = go_clocking( )) == FAIL ) { printf("go_clocking(...) failed\n"); goto ldone; } /* ** service data acquisition */ /* ** user IO */ /* ** call to sock_serv() */ if ( Go.ck_done ) Go.done = 1; } ldone: return rc; } /*-------------------------------------------------------------------- ** go_setup_data() - setups the data need for a GO. **-------------------------------------------------------------------- */ static int go_setup_data( void ) { int rc; #if LINUX FILE * fp = fopen( "go_setup.txt", "w+t"); #else FILE * fp = NULL; #endif rc = PASS; #if LINUX /* print ir parameter (on host system) */ printf_ir_param( fp, &Ip); #endif /* ** generate clocking data: STable, CE_sam, CE_reset... */ if ( Ip.irdevice == IRDEVICE_AL ) { struct al_ck_in_t al_ck_in; al_ck_in.slowcnt = Ip.slowcnt; al_ck_in.num_darray = Ip.num_darray; memcpy( al_ck_in.darray, Ip.darray, sizeof(al_ck_in.darray)); al_ck_in.numsample = Ip.numsample; al_ck_in.numchannels = Ip.numchannels; al_ck_in.multisample_gap = Ip.multisample_gap; al_ck_in.glr_period_usec = Ip.al_glr_period_usec; /* AL uses Scan Table to keep when converts happens */ alst_clear( &STable ); if ( (rc=alst_setTable( &STable, Ip.num_darray, Ip.darray )) == FAIL ) goto ldone; /* AL sample clocks */ alst_showTable( &STable, fp); if ( (rc=al_ck_generate_ce_sample( &CE_sam, &STable, &al_ck_in, fp)) == FAIL ) goto ldone; /* AL reset clocks */ if ( (rc=al_ck_generate_ce_reset( &CE_reset, &al_ck_in, fp)) == FAIL ) goto ldone; } else if ( Ip.irdevice == IRDEVICE_H2 ) { if( (rc = h2rg_generate_ce_array_setup_ir( &CE_reset, &h2rg_settings, fp)) == FAIL) { printf("h2rg_generate_ce_array_setup_ir(...) failed\n"); goto ldone; } if( (rc = h2rg_generate_ce_reset_s_ir( &CE_reset, &h2rg_settings, fp)) == FAIL) { printf("h2rg_generate_ce_reset_s_ir(...) failed\n"); goto ldone; } if( (rc = h2rg_generate_ce_readout_s_ir( &CE_sam, &h2rg_settings, fp)) == FAIL) { printf("h2rg_generate_ce_readout_s_ir(...) failed\n"); goto ldone; } } else { rc = FAIL; goto ldone; } /* ** Generate Sequence Table: Seq */ { struct ir_seq_in_t seq_in; seq_in.cbmode = Ip.cbmode; seq_in.itime_msec = Ip.itime_msec; seq_in.coadd = Ip.coadd; seq_in.ndr = Ip.ndr; seq_in.rsample = Ip.rsample; seq_in.frame_usec = (CE_sam.nsec/1000LL); seq_in.reset_usec = (CE_reset.nsec/1000LL); if ( Ip.irdevice == IRDEVICE_AL ) { seq_in.glr_enable = 1; /* Aladdin uses global resets */ } else { seq_in.glr_enable = 0; /* H2 reset clocks the array. */ } if ( (rc=ir_seq_generate_ce_data ( &Seq, &seq_in, fp )) == FAIL ) goto ldone; } ldone: #if LINUX fclose( fp ); #endif return rc; } /*-------------------------------------------------------------------- ** go_start() - do setup need to start the GO. **-------------------------------------------------------------------- */ static int go_start( void ) { int rc; rc = PASS; /*------------------------------------------------- ** pixel acquistion setup */ /*------------------------------------------------- ** clocking setup */ Go.ck_done = 0; Go.ck_si = 0; /* sequence index */ Go.ck_ci = 0; /* CE_xx.cmd[] index */ /* Prefill the CE Fifo and start it! */ ce_go( Ce0, 0 ); if ( (rc = go_clocking()) == FAIL ) goto ldone; ce_go( Ce0, 1 ); /* start the CE */ /*------------------- ** done */ ldone: return rc; } /*-------------------------------------------------------------------- ** go_clocking() - Periodic call this function to keep the clocing ** data flowing to the fifo **-------------------------------------------------------------------- */ static int go_clocking( void ) { int ce_free, n, i; #if LINUX FILE * fp = stdout; #else FILE * fp = NULL; #endif if ( Go.ck_done ) return PASS; ce_free = ce_fifostatus_free( Ce0 ); /* how free is the fifo? */ while ( 1 ) { /* All Seq.seq[] item were done, clocking is finished */ if ( Go.ck_si >= Seq.n ) { Go.ck_done = 1; return PASS; } /* Fill the CE buffer, then exit */ if ( ce_free <= 0 ) return PASS; if (Seq.seq[Go.ck_si] == IR_SEQ_GPS_HIGH ) { #ifdef DEBUG_IRCOMMAND printf("go_clocking(...) IR_SEQ_GPS_HIGH\n"); #endif /* set gps (shutter) signal high */ if ( ce_free > 1 ) { ce_put( Ce0, CE_CMD_SHUTTEROPEN); ce_free--; Go.ck_si++; /* goto next seq[] item */ ir_printf( fp, "go: CE_CMD_SHUTTEROPEN\n"); } else return PASS; /* wait until FIFO has room */ } else if (Seq.seq[Go.ck_si] == IR_SEQ_GPS_LOW ) { #ifdef DEBUG_IRCOMMAND printf("go_clocking(...) IR_SEQ_GPS_LOW\n"); #endif /* set gps (shutter) signal low */ if ( ce_free > 1 ) { ce_put( Ce0, CE_CMD_SHUTTERCLOS); ce_free--; Go.ck_si++; /* goto next seq[] item */ ir_printf( fp, "go: CE_CMD_SHUTTERCLOS\n"); } else return PASS; /* wait until FIFO has room */ } else if (Seq.seq[Go.ck_si] == IR_SEQ_RESET_ARRAY ) { unsigned int * d; #ifdef DEBUG_IRCOMMAND printf("go_clocking(...) IR_SEQ_RESET_ARRAY\n"); #endif /* copy data to FIFO */ n = MIN(ce_free, CE_reset.n-Go.ck_ci); /* How many word to copy to the fifo */ d = &CE_reset.cmd[Go.ck_ci]; for (i=0; i= CE_reset.n ) { ir_printf( fp, "go: IR_SEQ_RESET_ARRAY frame_usec=%10d si=%d\n", (int)(CE_reset.nsec/1000LL), Go.ck_ci); Go.ck_si++; /* goto next seq[] item */ Go.ck_ci = 0; /* reset CE_r/s.cmd[] index */ } } else if (Seq.seq[Go.ck_si] == IR_SEQ_SAMPLE_ARRAY ) { unsigned int * d; #ifdef DEBUG_IRCOMMAND printf("go_clocking(...) IR_SEQ_SAMPLE_ARRAY\n"); #endif /* copy data to FIFO */ n = MIN(ce_free, CE_sam.n-Go.ck_ci); /* How many word to copy to the fifo */ d = &CE_sam.cmd[Go.ck_ci]; for (i=0; i= CE_sam.n ) { ir_printf( fp, "go: IR_SEQ_SAMPLE_ARRAY frame_usec=%10d si=%d\n", (int)(CE_sam.nsec/1000LL), Go.ck_ci); Go.ck_si++; /* goto next seq[] item */ Go.ck_ci = 0; /* reset CE_r/s.cmd[] index */ } } else if (Seq.seq[Go.ck_si] == IR_SEQ_WAIT_USEC ) { n = (Seq.wait_usec / 2000000) + 2; /* delay could generate this may CE commands */ if ( ce_free >= n ) { ir_cep_delay_usec( Ce0, Seq.wait_usec); /* write delay CMD to the FIFO */ ce_free -= n; Go.ck_si++; /* goto next seq[] item */ ir_printf( fp, "go: IR_SEQ_WAIT_USEC wait_usec=%10d\n", Seq.wait_usec); } else return PASS; /* wait until FIFO has room */ } else { return FAIL; /* bad data in Seq.seq[] */ } } /* while(1) */ return PASS; } /**************************** End of go_app() & friends ************************/ /*---------------------------------------------------------------------- ** show_app() - show the GLOBAL_DATA/HOST_DATA values. **---------------------------------------------------------------------- */ int show_app( int argc, char * argv[] ) { #if LINUX printf_ir_param ( stdout, &Ip); #endif return PASS; } /*-------------------------------------------------------------------------------- ** t1_app() - test digiout ** syntax: t1 reps **-------------------------------------------------------------------------------- */ int t1_app( int argc, char * argv[] ) { unsigned short digout, data; int i, reps; int e_usec; unsigned long long tk_beg, tk_end; #if LINUX FILE * fp = stdout; #else FILE * fp = NULL; #endif reps = 512; if ( argc >= 2 ) reps = simple_strtol( argv[1], NULL, 10 ); printf("t1 -- test DIGOUT ---reps = %d --------\n", reps); /*------------------------------ ** generate CE commands to RAM */ tk_beg = get_ticks(); ir_ce_clear( &CE_sam ); // ir_ce_cmd_delay_usec( &CE_sam, 1000, fp ); /* 1000 usec */ digout=0; ir_ce_digout_lo( &digout, 0xFFFF, 0, &CE_sam, 0 ); /* set to 0 */ ir_ce_digout_hi( &digout, 0xFFFF, 0, &CE_sam, 0 ); /* set to 0 AND enables output */ ir_ce_gps( 1, &CE_sam, fp); /* toggle GPS - use for trigger */ ir_ce_gps( 0, &CE_sam, fp); for ( i=0; in, n ); for ( i=0; icmd[ci++] ); /* Start CE execution */ tk_beg = get_ticks(); ce_go( Ce0, 1 ); /* Do remaining CE commands */ while ( ci < ceb->n ) { n = ce_fifostatus_free( Ce0 ); while ( (n > 0 ) && (ci < ceb->n)) { ce_put( Ce0, ceb->cmd[ci++] ); n--; } } ce_flush(Ce0); tk_end = get_ticks(); e_usec = ticks2usec(tk_end-tk_beg); printf("ir_execute_ce() e_usec=%d ticks=%d i=%d\n", e_usec, (int)(tk_end-tk_beg), i ); #endif } /*-------------------------------------------------------------------------------- ** t2_app() - test CE delays commands ** syntax: t2 usec **-------------------------------------------------------------------------------- */ int t2_app( int argc, char * argv[] ) { int delay_usec; int e_usec; unsigned long long tk_beg, tk_end; #if LINUX FILE * fp = stdout; #else FILE * fp = NULL; #endif /* ** parse args */ if ( argc == 2 ) delay_usec = simple_strtol( argv[1], NULL, 10 ); else delay_usec = 100; printf("t2 ---TEST CMD Delay witb %d usec -----\n", delay_usec); /*------------------------------ ** generate CE commands to RAM */ tk_beg = get_ticks(); ir_ce_clear( &CE_sam ); ir_ce_cmd_delay_usec( &CE_sam, 1000, fp ); /* 1000 usec */ ir_ce_gps( 1, &CE_sam, fp); /* toggle GPS - use for trigger */ ir_ce_cmd_delay_usec( &CE_sam, delay_usec, fp ); ir_ce_gps( 0, &CE_sam, fp); ir_ce_put( CE_CMD_NOP, 20, &CE_sam, fp); /* last fifo command */ tk_end = get_ticks(); printf("wrote digouts: ce.n=%d ce.usec=%d \n", CE_sam.n, (int)(CE_sam.nsec/1000) ); /* all done, measure time */ e_usec = ticks2usec(tk_end-tk_beg); printf("1. e_usec=%d ticks=%d\n", e_usec, (int)(tk_end-tk_beg) ); /*------------------------------ ** execute CE instructions */ ir_execute_ce( &CE_sam, 0 ); return PASS; } /*-------------------------------------------------------------------------------- ** t3_app() - test Parallel Seq ** syntax: **-------------------------------------------------------------------------------- */ int t3_app( int argc, char * argv[] ) { int slowcnt, iter, reps; struct ir_ce_pseq_t pseq; int dur; int i, e_usec; unsigned long long tk_beg, tk_end; #if LINUX FILE * fp = stdout; #else FILE * fp = NULL; #endif /* ** parse args */ slowcnt = 3; /* 3 is 100 ns timeslice */ iter = 1; reps = 1; if ( argc >= 2 ) slowcnt = simple_strtol( argv[1], NULL, 10 ); if ( argc >= 3 ) iter = simple_strtol( argv[2], NULL, 10 ); if ( argc >= 4 ) reps = simple_strtol( argv[3], NULL, 10 ); printf("t3 --- test PSEQ -- slowcnt=%d or %d ns, iter=%d reps=%d\n", slowcnt, ir_ce_slowcnt_to_ns(slowcnt), iter, reps); /*------------------------------ ** generate CE commands to RAM */ tk_beg = get_ticks(); /* build ParSEQ table */ pseq.scale = IR_CE_PSEQ_SCALE_10; /* always use 10ns for scale */ dur = ir_ce_slowcnt_to_pseqdur( slowcnt ); for ( i=0; i= 2 ) slowcnt = simple_strtol( argv[1], NULL, 10 ); if ( argc >= 3 ) iter = simple_strtol( argv[2], NULL, 10 ); if ( argc >= 4 ) reps = simple_strtol( argv[3], NULL, 10 ); if ( argc >= 5 ) sam = simple_strtol( argv[4], NULL, 10 ); if ( argc >= 6 ) ch = simple_strtol( argv[5], NULL, 10 ); if ( argc >= 7 ) gap = simple_strtol( argv[6], NULL, 10 ); printf("t4 --- fun with VIDSEQ --slowcnt=%d or %d ns, iter=%d reps=%d\n", slowcnt, ir_ce_slowcnt_to_ns(slowcnt), iter, reps); /*------------------------------ ** generate CE commands to RAM */ tk_beg = get_ticks(); ir_ce_clear( &CE_sam ); ir_ce_cmd_delay_usec( &CE_sam, 1000, fp ); /* 1000 usec */ /* build VidSEQ PG3 */ vseq.reps = 1; /* VIDSEQ Reps */ dur = ir_ce_slowcnt_to_vseqdur( slowcnt ); for ( i=0; i \n"); cli_opts_free(opts); /* free any allocated memory */ return FAIL; } if ( wid_s ) wid = simple_strtoul( wid_s, NULL, 10 ); if ( hgt_s ) hgt = simple_strtoul( hgt_s, NULL, 10 ); if ( dopt_s ) dopt = simple_strtoul( dopt_s, NULL, 10 ); if ( pinx_s ) pinx = simple_strtoul( pinx_s, NULL, 10 ); cli_opts_free(opts); /* free any allocated memory */ if ( !INRANGE( 1, wid, 2048) || !INRANGE( 1, hgt, 2048) || !INRANGE( 0, dopt, 2) || !INRANGE( 0, pinx, 7) ) { printf("error: usage: t9 invalid range for arg.\n"); return FAIL; } printf("t9 wid=%d hgt=%d dopt=%d pinx=%d \n", wid, hgt, dopt, pinx); /*--------------------------------------------------- ** allocate data pool */ tk_beg = get_ticks(); if (gd->catp_pool[0][pinx]) { free((void*)gd->catp_pool[0][pinx]); gd->catp_pool[0][pinx] = 0; } /* allocate memory for wid*hgt*word_size + 20% (extra needed for catp headers (about 10%). */ psize = (wid*hgt*sizeof(long)*12)/10; /* psize = data_size + 20% */ gd->catp_pool[0][pinx] = pool = catp_xmitter_open( 0, psize); /* pass it the pool address */ if ( !pool ) { printf("error: not enough RAM\n"); return FAIL; } tk_end = get_ticks(); e_usec = ticks2usec(tk_end-tk_beg); printf("1. e_usec=%d ticks=%d\n", e_usec, (int)(tk_end-tk_beg) ); /*----------------------------------------------- ** Fill catp buffer with data (and setup header) */ tk_beg = get_ticks(); pool->offset = 0; npixels = CATP_PAYLOAD_NBYTES / sizeof(long); /* pixels per packet */ npacks = (wid*hgt + npixels-1) / npixels; /* number of packet to hold the data */ n = wid*hgt; /* size of data array */ i = 0; for ( np=0; np< npacks; np++) { catp_packet_t* pack = catp_xmitter_nextpack_in(pool); /* get a packet */ ldata = (long*)pack; /* copy data at start of packet */ if ( dopt == 0 ) /* data = incrementing integers .. */ { for ( p=0; p< npixels; p++) { *ldata++ = i++; } } else if ( dopt == 1 ) /* data = x,y location of pixel. xxxx,yyyy */ { for ( p=0; p< npixels; p++) { *ldata++ = 10000*(i%wid) + (i/hgt); i++; } } else /* 1000 + saw_tooth_pattern(16) */ { for ( p=0; p< npixels; p++) { static int d = 1; static int v = 0; v += d; if ( v >= 16 ) d = -1; if ( v <= 0 ) d = 1; *ldata++ = 1000 + v; i++; } } /* fix up header */ CATP_DATA_STREAM_SET(pack, 0); CATP_DATA_OFFSET_SET(pack, pool->offset); CATP_DATA_LEN_SET(pack, npixels*sizeof(long)); pool->offset += npixels*sizeof(long); catp_xmitter_pack_filled(pool, pack); /* make packet available for ouput */ } catp_xmitter_close(pool); tk_end = get_ticks(); e_usec = ticks2usec(tk_end-tk_beg); printf("2. e_usec=%d ticks=%d\n", e_usec, (int)(tk_end-tk_beg) ); return PASS; #endif /* LINUX */ } /********************************************************************************/ /* other functions */ /********************************************************************************/ /*------------------------------------------------------------------------- ** ircommand_statup() - this function should be call during or just after ** boot up: set up internal variable, etc. **------------------------------------------------------------------------- */ int ircommand_initial_setup( int irdevice ) { int naxis1, naxis2; printf("ircommand_statup() with irdevice = %s \n", Irdevice_selection[irdevice]); /*------------------------------------ ** allocate memory for buffers */ if ( irdevice == IRDEVICE_H2 ) { ir_seq_open( &Seq, 1024*1024, 0/*clear_opt*/); ir_ce_open( &CE_sam, 2*1024*1024, 0/*clear_opt*/); ir_ce_open( &CE_reset, 2*1024*1024, 0/*clear_opt*/); } else /* device is IRDEVICE_AL */ { ir_seq_open( &Seq, 1024*1024, 0/*clear_opt*/); ir_ce_open( &CE_sam, 2*1024*1024, 0/*clear_opt*/); ir_ce_open( &CE_reset, 100, 0/*clear_opt*/); /* AL uses global resets */ } /*------------------------------------ ** set default values for parameters */ alst_clear( &STable ); /* zero the scan table data */ /* ir parameters defaults */ Ip.irdevice = irdevice; Ip.acqmode = ACQMODE_BASIC; Ip.cbmode = CBMODE_FD; Ip.coadd = 1; Ip.itime_msec = 1000; Ip.ndr = 1; Ip.rsample = 10; Ip.num_darray = 1; Ip.bgr_wait_ms = 250; Ip.bgr_last_ticks = 0; if ( irdevice == IRDEVICE_H2 ) { Ip.slowcnt = 8; /* 8 is 200 ns TimeSlices */ Ip.numsample = 2; Ip.numchannels = 2; /* RG */ Ip.multisample_gap = 0; naxis1 = H2_NAXIS1; naxis2 = H2_NAXIS2; h2rg_init_ir(); } else /* device is IRDEVICE_AL */ { Ip.slowcnt = 20; /* 20 is 440 ns TimeSlices */ Ip.numsample = 2; Ip.numchannels = 1; /* R */ Ip.multisample_gap = 0; naxis1 = AL_NAXIS1; naxis2 = AL_NAXIS2; } Ip.darray[0].x = 0; Ip.darray[0].y = 0; Ip.darray[0].wid = naxis1; Ip.darray[0].hgt = naxis2; Ip.darray[1].x = 0; Ip.darray[1].y = 0; Ip.darray[1].wid = naxis1; Ip.darray[1].hgt = naxis2; Ip.darray[2].x = 0; Ip.darray[2].y = 0; Ip.darray[2].wid = naxis1; Ip.darray[2].hgt = naxis2; /* AL parameters defaults */ Ip.al_glr_period_usec = 20; /* global reset period for INSB device is 20 usec */ Ip.al_bgr_period_usec = 40; /* background reset period for INSB is 40 usec */ /* H2 parameters defaults */ Ip.h2_glr_enable = 1; /* use global reset for array_reset */ Ip.h2_glr_period_usec = 20; /* global reset period for H2RG device is ?? usec */ Ip.h2_bgr_flag = 1; /* 0=regular readout, 1=bgr reaout */ Ip.h2_bgr_period_usec = 40; /* background reset period for H2R2 is ?? usec */ Ip.h2_bgr_gowait_ms = 250; /* how long to wait between BGR and a GO */ /*------------------------------------ ** Initial Hardware */ #if !LINUX { /*-------------------- ** Dev0 */ Ce0 = ce_open( 0 ); /* initialize Digout HI & Low Register */ ce_put( Ce0, CE_PARAM_UPDWR_HI | IR_CE_UPD_OUTPUT_EN | 0 ); ce_put( Ce0, CE_PARAM_UPDWR_LO | 0 ); ce_put( Ce0, CE_CMD_UPDWR ); /* shutter IO bit low - our gps latch */ ce_put( Ce0, CE_CMD_SHUTTERCLOS); ce_flush( Ce0 ); /* dev0 */ /*-------------------- ** Dev1 */ Ce1 = ce_open( 1 ); /* initialize Digout HI & Low Register */ ce_put( Ce1, CE_PARAM_UPDWR_HI | IR_CE_UPD_OUTPUT_EN | 0 ); ce_put( Ce1, CE_PARAM_UPDWR_LO | 0 ); ce_put( Ce1, CE_CMD_UPDWR ); ce_flush( Ce1 ); /* dev1 */ } #endif return PASS; } /********************************************************************************/ /* static functions */ /********************************************************************************/ /*-------------------------------------------------------------- ** printf_ir_param() - print the variable of ir_param_t to fp. **-------------------------------------------------------------- */ static void printf_ir_param ( FILE * fp, /* O: output to this */ struct ir_param_t *ip /* I: Display these prarmeters */ ) { #if LINUX int i; fprintf( fp, "GLOBAL DATA \n"); fprintf( fp, "ir parameters -------\n"); fprintf( fp, " irdevice %s \n", Irdevice_selection[ip->irdevice]); fprintf( fp, " acqmode %s \n", Acqmode_selection[ip->acqmode]); fprintf( fp, " cbmode %s \n", Cbmode_selection[ip->cbmode]); fprintf( fp, " itime_msec %d msec\n", ip->itime_msec); fprintf( fp, " coadd %d \n", ip->coadd); fprintf( fp, " ndr %d \n", ip->ndr); fprintf( fp, " rsample %d \n", ip->rsample); fprintf( fp, " num_darray %d \n", ip->num_darray); for ( i=0; i< 3; i++ ) fprintf( fp, " darray %d %d %d, %d x %d\n", i, ip->darray[i].x, ip->darray[i].y, ip->darray[i].wid, ip->darray[i].hgt); fprintf( fp, " numsample %d \n", ip->numsample); fprintf( fp, " numchannels %d \n", ip->numchannels); fprintf( fp, " multisample_gap %d \n", ip->multisample_gap); fprintf( fp, " slowcnt %d or %d ns TimeSlices\n", ip->slowcnt, ir_ce_slowcnt_to_ns(ip->slowcnt)); fprintf( fp, " bgr_wait_ms %d \n", ip->bgr_wait_ms); fprintf( fp, "al parameters -------\n"); fprintf( fp, " al_glr_period_usec %d \n", ip->al_glr_period_usec); fprintf( fp, " al_bgr_period_usec %d \n", ip->al_bgr_period_usec); fprintf( fp, "h2 parameters -------\n"); fprintf( fp, " h2_glr_enable %d \n", ip->h2_glr_enable); fprintf( fp, " h2_glr_period_usec %d \n", ip->h2_glr_period_usec); fprintf( fp, " h2_bgr_flag %d \n", ip->h2_bgr_flag ); fprintf( fp, " h2_bgr_period_usec %d \n", ip->h2_bgr_period_usec); fprintf( fp, " h2_bgr_gowait_ms %d \n", ip->h2_bgr_gowait_ms); #endif } /*-------------------------------------------------------------- ** parseSelection() - search a list for item. ** Return: >= 0 = the index of the matching item. ** FAIL = Item is not in list. **-------------------------------------------------------------- */ static int parseSelection( char * buf, /* parameter for item to locate */ char * tok, /* token for parsing */ char ** list /* This list must be NULL terminaled */ ) { int i; char *c; if ( (c = strtok( buf, tok ) ) == NULL) return FAIL; for ( i=0; list[i] != NULL; i++) { if ( !strcmp( c, list[i] )) return i; } return FAIL; } /***************************************************************************/ /***************************************************************************/