From 1296b045a36e7688219bb3536118dc5133d474b4 Mon Sep 17 00:00:00 2001 From: Rolf Bork <rolf.bork@ligo.org> Date: Wed, 31 Jan 2018 17:10:04 +0000 Subject: [PATCH] Work on userspace IOP code: - Better IOP sync at 64K - Addition of memory space for a virtual ADC for IOP to read input from. git-svn-id: https://redoubt.ligo-wa.caltech.edu/svn/advLigoRTS/trunk@4647 6dcd42c9-f523-4c6d-aada-af552506706e --- NEWS | 1 + src/fe/controllerApp.c | 2 +- src/fe/controllerIopUser.c | 28 ++++++++++++----- src/fe/moduleLoadIop.c | 1 + src/fe/rcguserIop.c | 59 ++++++++++++++++++++++++++++------- src/include/controller.h | 14 +++++++++ src/include/drv/cdsHardware.h | 22 +++++++++++++ 7 files changed, 107 insertions(+), 20 deletions(-) diff --git a/NEWS b/NEWS index 43e8a4009..638dde202 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 879944862..5ed2bb579 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 9a7b72909..ba48cd7e4 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 1cc05a980..500cd36ef 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 f95ec9254..a0c63d71d 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 59aa9ba75..71e862443 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 8dd6ebe7b..392087f91 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. -- GitLab