diff --git a/NEWS b/NEWS index 43e8a4009dd23b0d7b361e0af899e2e4d53b6a91..638dde202a5b65fe9ff348b6c4c3b08faaf9ca60 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ Changes for 3.5 (NOT YET RELEASED) - controller.c and moduleLoad.c now split into new files to clean out #defs: - controllerIop.c and moduleLoadIop.c for IOP model builds. - controllerApp.c and moduleLoadApp.c for user application model builds. + - controllerIopUser.c and controllerAppUser.c, which are user space equivalents. - Removed /proc entries from all FE code. This should alleviate issue with change to /proc in later Linux kernels. ================================================================================================== diff --git a/src/fe/controllerApp.c b/src/fe/controllerApp.c index 87994486226cf30c5828ea4c2fafb3eb04447cab..5ed2bb5799255a714449e3feede2e9db7c4b1998 100644 --- a/src/fe/controllerApp.c +++ b/src/fe/controllerApp.c @@ -11,7 +11,7 @@ /* */ /*----------------------------------------------------------------------*/ -/// @file controller.c +/// @file controllerApp.c /// @brief Main scheduler program for compiled real-time kernal object. \n /// @detail More information can be found in the following DCC document: ///< <a href="https://dcc.ligo.org/cgi-bin/private/DocDB/ShowDocument?docid=7688">T0900607 CDS RT Sequencer Software</a> diff --git a/src/fe/controllerIopUser.c b/src/fe/controllerIopUser.c index 9a7b7290908f00298196c44b317b6be5cc30e1f6..ba48cd7e4aa6965c0582dca0bc2673b278050162 100644 --- a/src/fe/controllerIopUser.c +++ b/src/fe/controllerIopUser.c @@ -109,6 +109,7 @@ int usrHoldTime; ///< Max time spent in user app code int cardCountErr = 0; int cycleTime; ///< Current cycle time int timeHold = 0; ///< Max code cycle time within 1 sec period +int cycleOffset = 0; struct rmIpcStr *daqPtr; @@ -469,18 +470,22 @@ usleep(1000); printf("*******************************\n"); printf("* Running on timer! *\n"); printf("*******************************\n"); + int timeoff = BILLION-(60000000 * cycleOffset); /// Sync up to the 1Hz boundary do { usleep(1); - clock_gettime(CLOCK_MONOTONIC, &myTimer[0]); - cycleTime = myTimer[0].tv_nsec / 1000; - } while(cycleTime > 10); - timeSec = getGpsTimeProc() - 1; + clock_gettime(CLOCK_REALTIME, &myTimer[0]); + cycleTime = myTimer[0].tv_nsec; + } while(cycleTime > timeoff && cycleTime < (timeoff - 10000)); +printf("cycle time = %d\n",cycleTime); + timeSec = getGpsTimeProc() ; startGpsTime = timeSec; pLocalEpics->epicsOutput.startgpstime = startGpsTime; printf("Triggered the ADC at %d and %d usec\n",timeSec,cycleTime); onePpsTime = cycleNum; + nextstep = timeoff + 20000; + /// ******************************************************************************\n /// Enter the infinite FE control loop ******************************************\n @@ -510,10 +515,14 @@ usleep(1000); { for(ii=0;ii<IO_MEMORY_SLOT_VALS;ii++) { - ioMemData->iodata[jj][ioMemCntr].data[ii] = cycleNum/4; + ioMemData->iodata[jj][ioMemCntr].data[ii] = ioMemDataIop->iodata[jj][cycleNum].data[ii]; + dWord[jj][ii] = ioMemData->iodata[jj][ioMemCntr].data[ii]; + ioMemDataIop->iodata[jj][cycleNum].data[ii] = 0; } ioMemData->iodata[jj][ioMemCntr].timeSec = timeSec;; ioMemData->iodata[jj][ioMemCntr].cycle = cycleNum; + ioMemDataIop->gpsSecond = timeSec; + ioMemDataIop->cycleNum = cycleNum; } ioMemData->gpsSecond = timeSec; clock_gettime(CLOCK_MONOTONIC, &cpuClock[CPU_TIME_CYCLE_START]); @@ -525,10 +534,13 @@ usleep(1000); // Increment GPS second on cycle 0 timeSec ++; pLocalEpics->epicsOutput.timeDiag = timeSec; - int pll = myTimer[0].tv_nsec / 1000; + int pll = myTimer[0].tv_nsec / 1000 + (1000000 - (timeoff / 1000)); + pll %= 1000000; if(pll > 500000) pdiff = (1000000 - pll) * -1 ; else pdiff = pll; - pLocalEpics->epicsOutput.irigbTime = (pdiff + 11); + pLocalEpics->epicsOutput.irigbTime = pdiff + 10; + // pLocalEpics->epicsOutput.irigbTime = (pdiff + (timeoff / 1000) + 11) ; + cycle_gps_time = timeSec; } @@ -907,7 +919,7 @@ usleep(1000); /// \> Update internal cycle counters cycleNum += 1; cycleNum %= CYCLE_PER_SECOND; - nextstep = cycleNum * cyclensec; + nextstep = ((cycleNum * cyclensec) + timeoff)% 1000000000; clock1Min += 1; clock1Min %= CYCLE_PER_MINUTE; if(subcycle == DAQ_CYCLE_CHANGE) diff --git a/src/fe/moduleLoadIop.c b/src/fe/moduleLoadIop.c index 1cc05a9800a42bda2ad4a6328a5fa1c3344a761a..500cd36ef9e69a4454721080946ae68655bb0403 100644 --- a/src/fe/moduleLoadIop.c +++ b/src/fe/moduleLoadIop.c @@ -12,6 +12,7 @@ extern int mbuf_allocate_area(char *name, int size, struct file *file); extern void *fe_start(void *arg); extern int run_on_timer; extern char daqArea[2*DAQ_DCU_SIZE]; // Space allocation for daqLib buffers +struct task_struct *sthread; // MAIN routine: Code starting point **************************************************************** diff --git a/src/fe/rcguserIop.c b/src/fe/rcguserIop.c index f95ec9254c1ce79ea29e7ccd512fcb6e17429d5b..a0c63d71d5e1c71bc5ce26de5c6d269815fecef5 100644 --- a/src/fe/rcguserIop.c +++ b/src/fe/rcguserIop.c @@ -22,6 +22,7 @@ extern int fe_start(); extern char daqArea[2*DAQ_DCU_SIZE]; // Space allocation for daqLib buffers extern char *addr; +extern int cycleOffset; // Scan a double #if 0 @@ -57,7 +58,7 @@ void usage() int main (int argc, char **argv) { int status; - int ii,jj,kk; /// @param ii,jj,kk default loop counters + int ii,jj,kk,mm; /// @param ii,jj,kk default loop counters char fname[128]; /// @param fname[128] Name of shared mem area to allocate for DAQ data int cards; /// @param cards Number of PCIe cards found on bus int adcCnt; /// @param adcCnt Number of ADC cards found by slave model. @@ -74,13 +75,19 @@ int main (int argc, char **argv) char *sysname; char shm_name[64]; int c; + char *modelname; + cycleOffset = 0; - while ((c = getopt(argc, argv, "m:help")) != EOF) switch(c) { + while ((c = getopt(argc, argv, "m:t:help")) != EOF) switch(c) { case 'm': sysname = optarg; printf("sysname = %s\n",sysname); break; + case 't': + cycleOffset = atoi(optarg); + printf("cycle offset = %d\n",cycleOffset); + break; case 'help': default: usage(); @@ -90,7 +97,19 @@ int main (int argc, char **argv) kk = 0; jj = 0; - // printf("cpu clock %u\n",cpu_khz); + int i = 0; + char *p = strtok (argv[0], "/"); + char *array[5]; + + while (p != NULL) + { + array[i++] = p; + p = strtok (NULL, "/"); + } + modelname = array[i-1]; + sysname = array[i-1]; + + printf("model name is %s \n",sysname); sprintf(shm_name,"%s",sysname); @@ -139,6 +158,17 @@ int main (int argc, char **argv) } printf("GDSSM at 0x%lx\n",_gds_shm); +// Open new IO shared memory in support of no hardware I/O + sprintf(shm_name, "%s_io_space", sysname); + findSharedMemory(shm_name); + _io_shm = (char *)addr; + if (_io_shm < 0) { + printf("mbuf_allocate_area() failed; ret = %d\n", _io_shm); + return -1; + } + printf("IO SPACE at 0x%lx\n",_io_shm); + ioMemDataIop = (volatile IO_MEM_DATA_IOP *)(((char *)_io_shm)) ; + // Find and initialize all PCI I/O modules ******************************************************* // Following I/O card info is from feCode cards = sizeof(cards_used)/sizeof(cards_used[0]); @@ -148,7 +178,7 @@ int main (int argc, char **argv) //return -1; printf("Initializing PCI Modules for IOP\n"); for(jj=0;jj<cards;jj++) - printf("Card % type = %d\n",cdsPciModules.cards_used[jj].type); + printf("Card %d type = %d\n",jj,cdsPciModules.cards_used[jj].type); cdsPciModules.adcCount = 0; cdsPciModules.dacCount = 0; cdsPciModules.dioCount = 0; @@ -253,19 +283,26 @@ int main (int argc, char **argv) // Print out all the I/O information printf("***************************************************************************\n"); - // Master send module counds to SLAVE via ipc shm - ioMemData->totalCards = status; - ioMemData->adcCount = cdsPciModules.adcCount; - ioMemData->dacCount = cdsPciModules.dacCount; - ioMemData->bioCount = cdsPciModules.doCount; - // kk will act as ioMem location counter for mapping modules - kk = cdsPciModules.adcCount; + // Master send module counds to SLAVE via ipc shm + ioMemData->totalCards = status; + ioMemData->adcCount = cdsPciModules.adcCount; + ioMemData->dacCount = cdsPciModules.dacCount; + ioMemData->bioCount = cdsPciModules.doCount; + // kk will act as ioMem location counter for mapping modules + kk = cdsPciModules.adcCount; printf("%d ADC cards found\n",cdsPciModules.adcCount); for(ii=0;ii<cdsPciModules.adcCount;ii++) { // MASTER maps ADC modules first in ipc shm for SLAVES ioMemData->model[ii] = cdsPciModules.adcType[ii]; ioMemData->ipc[ii] = ii; // ioData memory buffer location for SLAVE to use + ioMemDataIop->model[ii] = cdsPciModules.adcType[ii]; + ioMemDataIop->ipc[ii] = ii; // ioData memory buffer location for SLAVE to use + for(jj=0;jj<65536;jj++) { + for(mm=0;mm<32;mm++) { + ioMemDataIop->iodata[ii][jj].data[mm] = jj - 32767; + } + } if(cdsPciModules.adcType[ii] == GSC_18AISS6C) { printf("\tADC %d is a GSC_18AISS6C module\n",ii); diff --git a/src/include/controller.h b/src/include/controller.h index 59aa9ba75fc4d4adba5a8a572cf124c8636be594..71e862443d2521d2583437b8b8d537d9f481a679 100644 --- a/src/include/controller.h +++ b/src/include/controller.h @@ -194,11 +194,13 @@ volatile char *_epics_shm; ///< Ptr to EPICS shared memory area char *_ipc_shm; ///< Ptr to inter-process communication area char *_daq_shm; ///< Ptr to frame builder comm shared mem area char *_gds_shm; ///< Ptr to frame builder comm shared mem area +char *_io_shm; ///< Ptr to user space I/O area int daq_fd; ///< File descriptor to share memory file long daqBuffer; // Address for daq dual buffers in daqLib.c CDS_HARDWARE cdsPciModules; // Structure of PCI hardware addresses volatile IO_MEM_DATA *ioMemData; +volatile IO_MEM_DATA_IOP *ioMemDataIop; volatile int vmeDone = 0; // Code kill command volatile int stop_working_threads = 0; @@ -351,6 +353,18 @@ double dDacHistory[(MAX_DAC_MODULES * 16)][MAX_HISTRY]; #endif +typedef struct duotone_diag_t { + float adc[IOP_IO_RATE]; // Duotone timing diagnostic variables + float dac[IOP_IO_RATE]; + float timeDac; + float timeAdc; + float totalAdc; + float meanAdc; + float totalDac; + float meanDac; + int dacDuoEnable; +}duotone_diag_t; + // /proc epics channel interface struct proc_epics { char *name; diff --git a/src/include/drv/cdsHardware.h b/src/include/drv/cdsHardware.h index 8dd6ebe7be66cc4025d727daeb2a865562d85eed..392087f9161a3c2570aea7e1071f97c3e16aeb19 100644 --- a/src/include/drv/cdsHardware.h +++ b/src/include/drv/cdsHardware.h @@ -109,6 +109,28 @@ typedef struct IO_MEM_DATA{ unsigned int ipcDetect[2][8]; }IO_MEM_DATA; +typedef struct IO_MEM_DATA_IOP{ + int gpsSecond; + int cycleNum; + int totalCards; + int adcCount; + int dacCount; + int bioCount; + int model[MAX_IO_MODULES]; + int ipc[MAX_IO_MODULES]; + int rfmCount; + long pci_rfm[MAX_RFM_MODULES]; /* Remapped addresses of RFM modules */ + long pci_rfm_dma[MAX_RFM_MODULES]; /* Remapped addresses of RFM modules */ + int dolphinCount; + volatile unsigned long *dolphinRead[4]; /* read and write Dolphin memory */ + volatile unsigned long *dolphinWrite[4]; /* read and write Dolphin memory */ + MEM_DATA_BLOCK iodata[6][65536]; + // Combined DAC channels map; used to check on slaves DAC channel allocations + unsigned int dacOutUsed[MAX_DAC_MODULES][16]; + unsigned int ipcDetect[2][8]; +}IO_MEM_DATA_IOP; + + // Timing control register definitions for use with Contec1616 control of timing slave.