• Main Page
  • Related Pages
  • Data Structures
  • Files
  • File List
  • Globals

llcontrol-acq216-core.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * File: llcontrol-acq216-core.c
00004  *
00005  * $RCSfile: llcontrol-acq216-core.c,v $
00006  * 
00007  * Copyright (C) 2001 D-TACQ Solutions Ltd
00008  * not to be used without owner's permission
00009  *
00010  * Description:
00011  *     application implementing the LOW LATENCY CONTROL feature
00012  *
00013  * $Id: llcontrol-acq216-core.c,v 1.2 2009/04/02 13:19:01 pgm Exp $
00014  * $Log: llcontrol-acq216-core.c,v $
00015  * Revision 1.2  2009/04/02 13:19:01  pgm
00016  * docs away
00017  *
00018  * Revision 1.1  2009/03/26 14:52:03  pgm
00019  * split sync2v, acq216 from main core
00020  *
00021  * Revision 1.1.4.27  2009/03/26 12:40:36  pgm
00022  * reuse same dac_src for each card, avoid data overrun
00023  */
00024 
00025 /** @file llcontrol-acq216-core.c demonstrates ACQ216 useage. */
00026 
00027 #include "local.h"
00028 
00029 #include <assert.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 
00033 #include <errno.h>
00034 #include <fcntl.h>
00035 #include <sys/ioctl.h>
00036 #include <sys/mman.h>
00037 #include <sys/stat.h>
00038 #include <sys/time.h>
00039 #include <sys/types.h>
00040 #include <stdio.h>
00041 #include <unistd.h>
00042 
00043 #include <popt.h>
00044 
00045 #include "acq32ioctl.h"
00046 #include "acq32busprot.h"
00047 
00048 #include "llif.h"
00049 #include "llprotocol.h"
00050 
00051 
00052 #include "llcontrol.h"
00053 #include "x86timer.h"
00054 
00055 #ifdef __ACQ196__
00056 #define FLAVOR "ACQ196"
00057 #else
00058 #define FLAVOR "ACQ32"
00059 #endif
00060 
00061 #include "llcontrol-core.h"
00062 
00063 void setAcq216Parameters(
00064         struct TestDescription* td, 
00065         struct LLC200_INIT *buffer, 
00066         int card,
00067         int iter)
00068 /** configure card parameters for iteration iter */
00069 {
00070         if (td->llc200_init_count){
00071                 memcpy(buffer, &td->llc200_init[iter%td->llc200_init_count],
00072                        sizeof(struct LLC200_INIT));
00073         }
00074 }
00075 
00076 /* WORKTODO: cache issue when prams overwritten, don't see next write?? 
00077  * so we boost it right out of the way ..
00078  */
00079 #define PRAMS_OFFSET 0x100000  
00080 
00081 
00082 static void doApplicationWork216(struct TestDescription* td, u32 offset)
00083 /* copy data to a user buffer. A real app may do more than this ;-) */
00084 {
00085         EACHCARD_INIT;
00086         int work_len = td->samples * td->channels*sizeof(short);
00087         int work_offset = td->iter * work_len;
00088 
00089         FOREACHCARD{
00090                 memcpy(td->work_buf[icard]+work_offset,
00091                        getVaddr(EACHBUF(td), offset),
00092                        work_len);
00093 
00094 /* now apply shot-based calibration factor to each value */
00095         }
00096 }
00097 
00098 
00099 
00100 int runSCM216(struct TestDescription* td)
00101 {
00102 /** runs the test SCM mode, ACQ216 only.
00103  * PSEUDO-CODE:
00104  *
00105  - (1) Clear the latch timer
00106  - (2) Set a local memory target address and arm the capture
00107  - (3) Poll for counter running (hardware counter starts on external gate)
00108  - (4) Iterate for required number of samples:
00109  - (5)     [optionally send a soft clock command]  trigger an acquisition
00110  - (6)     Wait for DMA Done - at this point data is available in target mem.
00111  *         A "real" control application is probably getting most of its calcs 
00112  *         done here rather than simply polling
00113  - (7)     [Get the latch (sample) and current uSec counters from the boards - 
00114  *          only if interested]
00115  - (8)     Check the process has not stopped (external gate high)
00116  - (9)     [optionally update the target address - else it gets overwritten]
00117  */
00118         struct LLC200_INIT *bbb[MAXCARDS];
00119 #define EACHBBB bbb[icard]
00120         struct TimingStats tstats[MAXCARDS] = {};
00121         u32 cmd = LLC_MAKE_DECIM(td->decimation);
00122         u32 offset = 0;
00123 #define POLLOFF(td) (offset + (td->samples-1) * td_sample_size(td))
00124         unsigned ipoll = 0;
00125         u32 cmd2;
00126 
00127         EACHCARD_INIT;
00128 
00129         FOREACHCARD{ /* (1) */
00130                 llSetTlatch(EACHMBX(td), tstats[icard].tlatch = 0xffffffff);
00131         }
00132    
00133         FOREACHCARD{ /* (2) */
00134                 EACHBBB = (struct LLC200_INIT *)getVaddr(EACHBUF(td), 0);
00135                 updateTargetAddr(cmd+LLC_CSR_M_ARM, EACHCARD(td), offset);
00136         }
00137 
00138 
00139         // wait for gate /* (3) */
00140 
00141         while( !llCounterRunning(FIRSTMBX(td), cmd) ){ 
00142                 POLLALERT(ipoll, "Polling for Counter Running\n");
00143         }
00144 
00145         INIT_TIMER;
00146         /* WORKTODO - assumes all cards now running */
00147 
00148         
00149         for ( td->iter = 0; td->iter != td->iterations; ++td->iter ){ /* (4) */
00150                 cmd2 = cmd;
00151                 FOREACHCARD{ /* (5) */
00152                         hbPrimePoll(
00153                                 EACHBUF(td), POLLOFF(td), td_sample_size(td));
00154 
00155                         if (td->llc200_init_count){
00156                                 setAcq216Parameters(
00157                                         td, 
00158                                         (struct LLC200_INIT *)
00159                                            getVaddr(EACHBUF(td),PRAMS_OFFSET), 
00160                                         THIS_CARD, td->iter);
00161                                 setMbox(EACHMBX(td), BP_MB_A4, 
00162                                         getBusAddr(EACHBUF(td),PRAMS_OFFSET));
00163                                 cmd2 |= LLC_CSR_M_LLC200_INIT;
00164                         }
00165                 }
00166 
00167                 FOREACHCARD{
00168                         llSetCmd(EACHMBX(td), cmd2+LLC_CSR_M_SOFTCLOCK);
00169                 }
00170         
00171                 if (td->hb_polling) FOREACHCARD{
00172                         MARK_TIME(0, "hb_polling");
00173                         tstats[icard].hb_poll = hbPoll(
00174                                 EACHBUF(td), POLLOFF(td), 
00175                                         td_sample_size(td), &user_abort);
00176                 }
00177 
00178                 
00179                 FOREACHCARD{                                  /* (6)+(7) */
00180                         MARK_TIME(1, "waitDmaDone() before");
00181                         tstats[icard].tlatch = waitDmaDone(EACHCARD(td));
00182                         MARK_TIME(2, "waitDmaDone() after");
00183                 }
00184 
00185                 if (!td->min_latency_test) FOREACHCARD{        /* (6)+(7) */
00186                         updateTstats(cmd, EACHCARD(td), &tstats[icard]);    
00187                 }
00188 
00189                 
00190                 if (td->do_work){
00191                         doApplicationWork216(td, offset);
00192                 }
00193 
00194                 /* check process completion.
00195                  * if hardware_gateoff is employed, then the app would need
00196                  * to make use of a pre-arranged DIO encoding for on/off instead                 */
00197                  
00198                 if (!td->hardware_gate_off &&
00199                      !llCounterRunning(FIRSTMBX(td), cmd )){          /* (8) */
00200                         fprintf( stderr, "Trigger is off - stop\n" );
00201                         break;
00202                 }
00203                 
00204                 FOREACHCARD_MARK_TIME(6, "after llCounterRunning check");
00205 
00206                 // maybe set new target addr
00207 
00208                 if ( !td->overwrite ){
00209                         offset += td->sample_offset;
00210 
00211                         FOREACHCARD{                                    /* 9 */
00212                                 updateTargetAddr(cmd, EACHCARD(td), offset);
00213                                 MARK_TIME(7, "after updateTargetAddr");
00214                         }
00215                 }else{
00216                         if (td->hb_polling) FOREACHCARD{
00217                                 hbPrimePoll(EACHBUF(td), 
00218                                             offset, td_sample_size(td));
00219                                 MARK_TIME(7, "after hbPrimePoll");
00220                         }
00221                 }
00222 
00223                 if (td->tlog){          
00224                         FOREACHCARD{
00225                                 tstats[icard].target_poll =
00226                                         getMboxPollcount(EACHMBX(td));
00227                                 MARK_TIME(10, "10");
00228                                 updateTimingStats(
00229                                         td->stats_buf[icard], 
00230                                         td->iter, 
00231                                         &tstats[icard]);
00232                                 MARK_TIME(11, "11");
00233                         }
00234                 }       
00235                 TIMER_CHECK_OVERFLOW;
00236         }
00237 
00238         G_quit = 1;
00239         return 0;
00240 }
00241 

Generated on Wed Jan 5 2011 for llcontrol by  doxygen 1.7.1