pRORC driver and API library =============================== version 2.2 May 24, 2002. This version supposes the physmem memory management module being installed. driver INSTALLATION ==================== - get sources from /afs.cern.ch/alice/daq/ddl/prorc/vers.2.2/pRorc - if you have afs: use directly the driver and API library from /afs.cern.ch/alice/daq/ddl/prorc/vers.2.2/pRorc/Linux - if you have no afs: - create a directory pRorc: mkdir pRorc - ftp /afs/cern.ch/alice/daq/ddl/prorc/vers.2.2/pRorc_2002.05.24.tgz (or any newer version of the tgz file) - untar the compressed file: gtar -xvzf pRorc_2002.05.24.tgz pRorc - cd pRorc - create the driver source file corresponding to the kernel version 2.2 or 2.4 with ./configure - compile the prorc driver library and the test programs with make -f Makefile clean make -f Makefile - as root create the 4 device files /dev/prorc0 ... /dev/prorc3 with make -f Makefile dev - as root load the driver for testing purpose with /sbin/insmod Linux/prorc_driver.o - to load the driver at boot time add the following line in the /etc/rc.d/rc.local file /sbin/insmod //pRorc/Linux/prorc_driver.o - check if physmem and pRORC driver modules are loaded: cat /proc/modules - check if the pRORC card is plugged in: Linux/prorc_find USAGE ====== Utility programs ================= - to find pRorc cards use prorc_find - prorc_reset resets the RORC card and/or the DIU. If you reset the DIU the link will be cut. to reset the pRORC card use: prorc_reset to reset the pRORC card and the DIU (i.e. cat the link): prorc_reset -b - init_link tries to establish the link. use: init_link - a simple test can be done with the programs sr, ss, prorc_id, diu_status, siu_status sr (show regisers) list the pRORC's registers status. ss (show status) write out the pRORC's status. prorc_id shows the hardware and firmware identity words. diu_status shows the status of the DIU siu_status shows the status of the SIU at the other end of the link. - more complex test can be done with the program prorc_test. It uses the physmem memory management module. The user has to specify the size of memory blocks where he wants to receive the events. Also the user specifies whether to start to Data Generator or not. The program fills the Free FIFO with the memory addresses and wait for events. When an event arrives the program checks it (its length and every data words) and stops if an error occures. The data check can be switched off for speed tests. The program can be stoped by pressing ^C. API routines ============ #include "prorc_ddl.h" #define MAX_DEV 4 pRorcDescriptor_t prorc; stword_t stw; __u32 hw, fw; pRorcReadyFifo_t *rf; pRorcHwSerial_t hw_serial[MAX_DEV]; int minor[MAX_DEV]; int err, p_minor, fwvers, max_fifo, time_out; int block_len_word, rf_index; int data_len, max_event, pattern_no; int n, n1, n2; unsigned long init_word; unsigned long dtsw; unsigned long block_phys_addr; volatile unsigned long *readyFifoUserAddres; unsigned long readyFifoBaseAddress; 0) find pRORC devices: n = pRorcFindAll(hw_serial, minor, MAX_DEV); n will contain the number of devices found, hw_serial[i].serial contains the serial number, while minor[i] the minor number of each devices (i = 0, 1, ... n-1). 1) open the device: err = pRorcOpen(&prorc, p_minor); 2) check firmware version: pRorcReadId(&prorc, &hw, &fw); fwvers = pRorcFWVers(fw); max_fifo = pRorcFFSize(fw); 3) reset pRORC: pRorcReset(&prorc, PRORC_CMD_RESET_RORC); 4) reset DIU: pRorcReset(&prorc, PRORC_CMD_RESET_DIU); 5) check and init link (if you use a DDL link): if (pRorcCheckLink(&prorc) != PRORC_STATUS_OK) { printf("\nThe DDL link is not on. I try to set up the link.\n"); if (pRorcArmDDL(&prorc, PRORC_LINK_UP) != PRORC_STATUS_OK) { printf("Could not set up the link. I stop.\n"); pRorcClose(&prorc); exit (EXIT_FAILURE); } } 6) empty Free FIFO: pRorcReset(&prorc, PRORC_CMD_CLEAR_FF); 7) start pRORC's data receiver: err = pRorcStartDataReceiver(&prorc, readyFifoBaseAdress, readyFifoUserAddress); 8a) (if you use DDL link) send "start trigger" command to front end: err = pRorcStartTrigger(&prorc, timeout, &stw); if (err == PRORC_STATUS_ERROR) { printf(" RDYRX command can not be sent. I stop\n"); pRorcClose(&prorc); exit (EXIT_FAILURE); } if (err == PRORC_NOT_ACCEPTED) printf(" No reply arrived for RDYRX in timeout %d\n", timeout); else printf(" FEE accepted the RDYDX command. Its reply: 0x%08lx\n", stw.stw); 8b) if you use the Data Generator feature of the pRorc then you have to set Data Generator parameters, set pRorc in loopback mode and start Data Generator: err = pRorArmDataGenerator(&prorc, init_word, pattern_no, data_len, PRORC_DG_NO_RANDOM_LEN, 0, PRORC_DG_NO_RANDOM_TIME, 40); if (err != PRORC_STATUS_OK) { printf(" DG returned error %d. I stop\n", err); pRorcClose(&prorc); exit (EXIT_FAILURE); } else printf(" DG armed.\n"); pRorcParamOn(&prorc, PRORC_PARAM_LOOPB); pRorcStartDataGenerator(&prorc, max_event); 9) push Free FIFO (any time after pRorc Reset): rf = (pRorcReadyFifo_t *)readyFifoUserAddress; rf[rf_index].length = -1; rf[rf_index].status = -1; pRorcPushFreeFifo (&prorc, block_phys_addr, block_len_word, rf_index); 10) check Free FIFO status: n = pRorcCheckFreeFifo(&prorc); if (n == PRORC_FF_FULL) printf("Free FIFO is full\n"); else { n2 = (n + 1) * 8; n1 = n == 0 ? 0 : n2 - 7; printf("number of entries loaded is between %d and %d\n", n1, n2); } 11) check if data arrived: err = pRorcHasData(rf, rf_index); if (err !=RORC_DATA_BLOCK_NOT_ARRIVED) { data_len = rf[rf_index].length; if (err == PRORC_LAST_BLOCK_OF_EVENT_ARRIVED) { dtsw = rf[rf_index].status; /* end of event */ } else { /* not end of event */ } } 12a) (if you use DDL link) send "stop trigger" command to the front end: err = pRorcStopTrigger(&prorc, timeout, &stw); printf(" EOBTR command sent to the FEE\n"); if (err == PRORC_STATUS_ERROR) { printf(" EOBTR command can not be sent.\n"); ..... } if (err != PRORC_NOT_ACCEPTED) { printf(" FEE accepted the EOBTR command. Its reply: 0x%08lx\n", stw.stw); ..... } 12b) if you use Data Generator stop it: pRorcStopDataGenerator(&prorc); 13) stop pRORC's data reciever: pRorcStopDataReceiver(&prorc); 14) close the device: err = pRorcClose(&prorc); - Notes on the routine usage: Step 0 gives you the list of available pRORC devices. Steps 1-8 are all for initialization of a pRORC device, Steps 2-6 are not obligatory. You can reset the card and init the link outside your program. If you reset the card do not need to empty the Free FIFO. You can empty the Free FIFO anywhere in your program if you like. You can check the link status (step 5) any time you like. You can try to re- init the link, like in step 5, or you can stop your program if the link is down. Steps 7 and 8 are necessary to start data collecting. The order of this two steps can be as it is the the description or in revers order as well. Steps 8a and 11a are only necessary if there is a front-end or front-end simulator at the other end of the link. If you want to use the data generator feature of the card (which is not fully working yet) you will need steps 8b and 12b. The Data Generator can produce fixed length events with different data patterns. Generation of random length events are not possible yet. Because of that fact you have to use the pRorcArmDataGenerator routine with the last 4 paramters fixed as it is given in step 8b. The patter_no paramter can have values between 1 and 6: 1 means constant data (= init_word) 2 means alternating data (init_word and its binary negate) 3 means flying 0 data starting from 0xfffffffe 4 means flying 1 data starting from 0x00000001 5 means incremental data starting from init_word 6 means decremental data starting from init_word. In the case of any other pattern_no value: incremental data will be generated. The minimum data length (parameter data_len) is 1 word, the maximum is (2^19-1) words. (It corresponds to (2MB - 1 word) maximum event length). Normaly the pRorc sends generated data to the link. Because of that you have to put pRorc into loopback mode before starting the Generator. The number of events to be generated is specified in the pRorcStartDataGenerator routine. The maximum value could be 2^31-1, 0 means inifinit number of events to be generated. Pushing Free FIFO (step 9) can be done before and after start data collecting. Steps 9-11 do the actual readout which need to be executed in a loop. The pRorcPushFreeFifo routine is a macro call without return value. It pushes the next entry (address, length and readyFifo index of a free memory page) into the card's Free FIFO. If you are interested to the status of the Free FIFO you can get it with the routine pRorcCheckFreeFIFO as it is shown in step 10. It returns an aproximative value of the number of entries in the FIFO. In step 11 the macro pRorcHasData checks the readyFifo at one particular index. Finally steps 12-14 shut down the link. Step 13 stops the data collection. The link remains active. After step 12 some events can still arrive. If you do not want to read them out you have to reset the card, perhaps reset the link. - For compilation/linking the libraries prorc_lib.o, prorc_aux.o and prorc_ddl.o are needed with the full path in case the user program is not in the same directory. Also -I has to be given to find the prorc_ddl.h and other .h files. Make compilation as: gcc -o \ -I/pRorc/ \ \ /pRorc/Linux/prorc_lib.o \ /pRorc/Linux/prorc_aux.o \ /pRorc/Linux/prorc_ddl.o