Ejemplo n.º 1
0
int vme_close()
{
    /* Check for status errors */
    status = bt_chkerr(btd);
    if ( BT_SUCCESS != status) {
        bt_perror(btd, status, "Engine ERROR: Status error from SBS VME-PCI");
    }

    /* Close SBS VME-PCI */
    status = bt_close(btd);
    if ( BT_SUCCESS != status) {
        bt_perror(btd, status, "Engine ERROR: Could not close SBS VME-PCI");
    }
	
	/* Remove the lock file (if it is not done already) */
	remove("/Applications/sirius/system/engine.lock");

   	return 0;
}
Ejemplo n.º 2
0
int vme_open()
{
   /*  Open SBS VME-PCI  */
    status = bt_open(&btd, bt_gen_name(unit, type, &devname[0], BT_MAX_DEV_NAME), BT_RD | BT_WR);
    if (BT_SUCCESS != status) {
        bt_perror(btd, status, "Engine ERROR: Could not open SBS VME-PCI");
		remove("/Applications/sirius/system/engine.lock");
        return -1;
    }
	
    /* Clear any outstanding errors */
    status = bt_clrerr(btd);
    if (BT_SUCCESS != status) {
        bt_perror(btd, status, "Engine ERROR: Could not clear errors from SBS VME-PCI");
		remove("/Applications/sirius/system/engine.lock");
        (void) bt_close(btd);
        return -1;
    }
	return 0;
}
Ejemplo n.º 3
0
int mvme_write(MVME_INTERFACE *vme, mvme_addr_t vme_addr, void *src, mvme_size_t n_bytes)
{
   mvme_size_t n;
   bt_error_t status;
   BT617_TABLE *ptab;

   ptab = ((BT617_TABLE *)vme->table)+vme->handle;

   status = bt_write(ptab->btd, src, vme_addr, n_bytes, (size_t *)&n);
   if (status != BT_SUCCESS)
      bt_perror(ptab->btd, status, "bt_write error");

   return n;
}
Ejemplo n.º 4
0
int mvme_open(MVME_INTERFACE **vme, int index)
{
   BT617_TABLE *ptab;
   bt_devdata_t flag;
   int status;

   *vme = (MVME_INTERFACE *)malloc(sizeof(MVME_INTERFACE));
   if (*vme == NULL)
      return MVME_NO_MEM;

   (*vme)->am       = MVME_AM_DEFAULT;
   (*vme)->dmode    = MVME_DMODE_DEFAULT;
   (*vme)->blt_mode = MVME_BLT_NONE;

   (*vme)->handle = 0; /* use first entry in BT617_TABLE by default */

   (*vme)->table = (void *)malloc(sizeof(BT617_TABLE)*MAX_BT617_TABLES);
   if ((*vme)->table == NULL)
      return MVME_NO_MEM;

   memset((*vme)->table, 0, sizeof(BT617_TABLE)*MAX_BT617_TABLES);   
   ptab = (BT617_TABLE *) (*vme)->table;

   ptab->am = MVME_AM_DEFAULT;
   
   bt_gen_name(index, BT_DEV_A32, ptab->devname, BT_MAX_DEV_NAME);
   status = bt_open(&ptab->btd, ptab->devname, BT_RDWR);
   if (status != BT_SUCCESS) {
      bt_perror(ptab->btd, status, "bt_open error");
      return MVME_NO_INTERFACE;
   }
   bt_init(ptab->btd);
   bt_clrerr(ptab->btd);

   /* select swapping mode */
   flag = BT_SWAP_NONE;
   bt_set_info(ptab->btd, BT_INFO_SWAP, flag);

   /* set data mode */
   flag = BT_WIDTH_D32;
   bt_set_info(ptab->btd, BT_INFO_DATAWIDTH, flag);

   /* switch off block transfer */
   flag = FALSE;
   bt_set_info(ptab->btd, BT_INFO_BLOCK, flag);

   return MVME_SUCCESS;
}
Ejemplo n.º 5
0
int mvme_exit(MVME_INTERFACE *vme)
{
   int i;
   bt_error_t status;
   BT617_TABLE *ptab;

   for (i=0 ; i<MAX_BT617_TABLES ; i++) {
      ptab = ((BT617_TABLE *)vme->table)+i;
      if (ptab->btd != NULL) {
         status = bt_close(ptab->btd);
         if (status != BT_SUCCESS)
            bt_perror(ptab->btd, status, "bt_close error");
         }
      }

   return MVME_SUCCESS;
}
Ejemplo n.º 6
0
int mvme_write_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr, DWORD value)
{
   mvme_size_t n;
   bt_error_t status;
   BT617_TABLE *ptab;
 
   ptab = ((BT617_TABLE *)vme->table)+vme->handle;

   if (vme->dmode == MVME_DMODE_D8)
      n = 1;
   else if (vme->dmode == MVME_DMODE_D16)
      n = 2;
   else
      n = 4;

   status = bt_write(ptab->btd, &value, vme_addr, n, (size_t *)&n);
   if (status != BT_SUCCESS)
      bt_perror(ptab->btd, status, "bt_write error");

   return n;
}
Ejemplo n.º 7
0
DWORD mvme_read_value(MVME_INTERFACE *vme, mvme_addr_t vme_addr)
{
   mvme_size_t n;
   DWORD data;
   bt_error_t status;
   BT617_TABLE *ptab;

   ptab = ((BT617_TABLE *)vme->table)+vme->handle;

   if (vme->dmode == MVME_DMODE_D8)
      n = 1;
   else if (vme->dmode == MVME_DMODE_D16)
      n = 2;
   else
      n = 4;

   data = 0;
   status = bt_read(ptab->btd, &data, vme_addr, n, (size_t *)&n);
   if (status != BT_SUCCESS)
      bt_perror(ptab->btd, status, "bt_read error");

   return data;
}
Ejemplo n.º 8
0
int bt617_set_am(MVME_INTERFACE *vme, int am)
{
   int i;
   BT617_TABLE *ptab;
   bt_error_t status;
   bt_devdata_t flag;

   for (i=0 ; i<MAX_BT617_TABLES ; i++)
      if (((BT617_TABLE *)vme->table)[i].am == am)
         break;

   if (((BT617_TABLE *)vme->table)[i].am == am) {

      vme->handle = i;
      ptab = ((BT617_TABLE *)vme->table)+i;
      bt_set_info(ptab->btd, BT_INFO_DMA_AMOD, am);
      bt_set_info(ptab->btd, BT_INFO_PIO_AMOD, am);
      bt_set_info(ptab->btd, BT_INFO_MMAP_AMOD, am);
      return MVME_SUCCESS;
   }

   /* search free slot */
   for (i=0 ; i<MAX_BT617_TABLES ; i++)
      if (((BT617_TABLE *)vme->table)[i].am == 0)
         break;
   if (i==MAX_BT617_TABLES)
      return MVME_NO_MEM;

   /* mode not yet open, open it */
   vme->handle = i;
   ptab = ((BT617_TABLE *)vme->table)+i;

   ptab->am = am;
   if (am == MVME_AM_A16_SD || am == MVME_AM_A16_ND)
      bt_gen_name(vme->index, BT_DEV_A16, ptab->devname, BT_MAX_DEV_NAME);
   else if (am == MVME_AM_A24_SB     ||
            am == MVME_AM_A24_SP     ||
            am == MVME_AM_A24_SD     ||
            am == MVME_AM_A24_NB     ||
            am == MVME_AM_A24_NP     ||
            am == MVME_AM_A24_ND     ||
            am == MVME_AM_A24_SMBLT  ||
            am == MVME_AM_A24_NMBLT  ||
            am == MVME_AM_A24        ||
            am == MVME_AM_A24_D64)
      bt_gen_name(vme->index, BT_DEV_A24, ptab->devname, BT_MAX_DEV_NAME);
   else
      bt_gen_name(vme->index, BT_DEV_A32, ptab->devname, BT_MAX_DEV_NAME);

   status = bt_open(&ptab->btd, ptab->devname, BT_RDWR);
   if (status != BT_SUCCESS) {
      bt_perror(ptab->btd, status, "bt_open error");
      return MVME_NO_INTERFACE;
   }
   bt_init(ptab->btd);
   bt_clrerr(ptab->btd);

   /* select swapping mode */
   flag = BT_SWAP_NONE;
   bt_set_info(ptab->btd, BT_INFO_SWAP, flag);

   /* set data mode */
   flag = BT_WIDTH_D16;
   bt_set_info(ptab->btd, BT_INFO_DATAWIDTH, flag);

   /* switch off block transfer */
   flag = FALSE;
   bt_set_info(ptab->btd, BT_INFO_BLOCK, flag);

   /* set amod */
   bt_set_info(ptab->btd, BT_INFO_DMA_AMOD, am);
   bt_set_info(ptab->btd, BT_INFO_PIO_AMOD, am);
   bt_set_info(ptab->btd, BT_INFO_MMAP_AMOD, am);

   return MVME_SUCCESS;
}
Ejemplo n.º 9
0
int main(void) 
{
 	key_t		skey=SEMAPHORE_KEY;
	int			nsems=NSEM;
	int			semid;
	int			semno;

   	union		semun {
      	int 			val;
      	struct 			semid_ds *buf;
      	unsigned short 	*array;
   	} arg;
	int       shmid1, shmid2;
	int       shmemsize=BUFFER_LENGTH;
	int       *shm1ptr, *shm2ptr;
	key_t     bkey=SHAREDMEM_KEY;
	key_t     mkey=MESSAGE_KEY;
	int       i;
	FILE      *strm;
	int       fd;
	int       exades;                /* File descriptor for Exabyte            */
	int       opendes;               /* File descripter of opened file         */
	int       new_des_min = 10;      /* Offset for new file descriptor ?       */
	int       write_data = 0;        /* Write raw data to tape or not          */
	ssize_t   bytes_written;

   	int       	*bufp;                 	/* Pointer to databuffer in shared memory	*/
   	int       	*messp;                	/* Pointer to message_box in shared memory	*/
   	int       	*buf1p, *buf2p, *buf3p, *buf4p;

   	long      	message_length = 40;   	/* VME Message_Box is 10 Words long			*/
   	long      	*mess_p;               	/* Pointer to Message_Box					*/

   	long      	movebytes;            	/* Length (bytes) of movebuffer from RIO3	*/
   	long      	Message_Box[10];      	/* Vector to hold Message_Box				*/
   	unsigned long moveaddress;     		/* Data buffer address in VME				*/
   	long      	*sem1ptr;             	/* Pointer to VME semaphore 1				*/
   	long      	*sem2ptr;             	/* Pointer to VME semaphore 2				*/
   	long      	*sem3ptr;             	/* Pointer to VME semaphore 3				*/
   	long      	*sem4ptr;             	/* Pointer to VME semaphore 4				*/
   	long      	sem1val, sem2val, sem3val, sem4val;
  	long      	*engstatptr;
   	long      	engstatval;
   	long      	semph1, semph2, semph3, semph4, tiger, stbox;

   	int       	*sortp;               	/* Pointer to message_box(0) - sort flag	*/
   	int       	*engp;                	/* Pointer to message_box(1) - engine flag	*/
   	int       	*stgp;                	/* Pointer to message_box(2) - storage		*/
   	int       	*vmesp;               	/* Pointer to message_box(3) - VME status	*/
   	int       	*recp;                	/* Pointer to message_box(5) - record count	*/
   	int       	sort_off      = 0;    	/* Offset for pointer to message_box[0]		*/
   	int       	engine_off    = 1;    	/* Offset for pointer to message_box[1]		*/
   	int       	stgflag_off   = 2;    	/* Offset for pointer to message_box[2]		*/
   	int       	vmes_off      = 3;    	/* Offset for pointer to message_box[3]		*/
   	int       	reccount_off  = 5;    	/* Offset for pointer to message_box[5]		*/
   	int       	part_offset   = 8192; 	/* Pointer off in databuffer part			*/

    size_t		amt_read;				/* Amount of data read from device			*/
 
   	arg.buf 	= (void *) malloc (100); 
   	mess_p  	= &Message_Box[0];
   	sem1ptr 	= &sem1val;
   	sem2ptr 	= &sem2val;
   	sem3ptr 	= &sem3val;
   	sem4ptr 	= &sem4val;
    engstatptr 	= &engstatval;
	
   	/* Check if the engine lock-file is present, create if not. This is */
   	/* a security precaution, multiple engine processes cause system crash*/
   	if((fd = open("/Applications/sirius/system/engine.lock",O_CREAT|O_EXCL,PERMS)) == -1 )
   	{
      	printf("Engine ERROR: Could not start engine due to lock file /Applications/sirius/system/engine.lock\n");
      	exit(errno);
   	}

   	/* Get semaphore identifier */
   	semid = semget(skey, nsems, PERMS );
   	if (semid == -1) {
      	printf("Engine ERROR: Get semaphore identifier failed \n");
      	exit(errno);
   	}  

   	/* Initialize VME front-end system link */
   	if (vme_open() != 0) {
      	printf("Engine ERROR: Could not initialize and open SBS VME-PCI interface\n");
      	exit(errno);
   	}
	
	/* Attach shared message_box segment to process */
   	shmemsize = 80;
   	shmid2 = shmget(mkey, shmemsize, PERMS);
   	if (shmid2 == -1) {
      	printf("Engine ERROR: Shared message_box memory allocation failed\n");
      	exit(errno);
  		}

   	shm2ptr = shmat(shmid2, NULL, 0);
   	if (*shm2ptr == -1) {
      	printf("Engine ERROR: Attach shared message_box to process failed\n");
      	exit(errno);
   	} 
	
   	/* Attach shared data buffer segment to process */
   	shmemsize = BUFFER_LENGTH;
   	shmid1 = shmget(bkey, shmemsize, IPC_CREAT | PERMS);
   	if (shmid1 == -1) {
      	printf("Engine ERROR: Shared data buffer memory allocation failed %d\n", errno);
      	exit(errno);
   	}

   	shm1ptr = shmat(shmid1, NULL, 0);
   	if (*shm1ptr == -1) {
      	printf("Engine ERROR: Attach shared data buffer to process failed\n");
      	exit(errno);
   	} 

   	/* Take a copy of the pointers to shared memory segments           */
   	bufp  = shm1ptr;          /* Points to databuffer in shared memory */
   	messp = shm2ptr;          /* Points to message_box n shared memory */

   	/* Pointers used in write to Exabyte, buffer is divided into 4     */
   	buf1p = shm1ptr;                 /* Points to part 1 of databuffer */
   	buf2p = shm1ptr + part_offset;   /* Points to part 2 of databuffer */
   	buf3p = shm1ptr + part_offset*2; /* Points to part 3 of databuffer */
   	buf4p = shm1ptr + part_offset*3; /* Points to part 4 of databuffer */

   	/* Initialize pointers to message_box variables */
   	sortp = messp + sort_off;
   	recp  = messp + reccount_off;
   	stgp  = messp + stgflag_off;
   	engp  = messp + engine_off;
   	vmesp = messp + vmes_off;

   	/* Clear data buffer segment */
   	for (i = 0; i < 32768; i++)  {  
      	*(bufp+i) = 0;
   	} 
   	bufp = shm1ptr;									/* Restore pointer	*/

   	/* Signal to VME front-end system that the acquisition is running	*/
   	/* This is done by setting the VME Message_Box[1] to '1'            */
   	engstatval = 1;
   	status = bt_write(btd, engstatptr, ENGSTATUS, 4, &amt_read);
	if ( BT_SUCCESS != status) { /* At first VME write failure, we print out a lot of errors*/
        if (amt_read != 4) {
            fprintf(stderr, "Engine ERROR: Only %d bytes written to SBS VME-PCI.\n", (int) amt_read);
        }
        else {
            fprintf(stderr, "Engine ERROR: Could not write to %s.\n", &devname[0]);
        }
        bt_perror(btd, status, "Engine ERROR: Could not write engine status to SBS VME-PCI");
        vme_close();
        return EXIT_FAILURE;
    }
   

   	/* Read the whole VME Message_box to get info from bobcat (installed in the VME crate) */
   	status = bt_read(btd, mess_p, MESSAGE_ADDRESS, message_length, &amt_read);
	if ( BT_SUCCESS != status) { /* At first VME read error, we print out a lot of messages*/
        if (amt_read != message_length) {
            fprintf(stderr, "Engine ERROR: Only %d bytes read from device.\n", (int) amt_read);
        }
        else {
            fprintf(stderr, "Engine ERROR: Could not read from %s.\n", &devname[0]);
        }
        bt_perror(btd, status, "Engine ERROR: Could not read VME Message_box from VME A24 memory");
        vme_close();
        return EXIT_FAILURE;
    }

   	if ( Message_Box[6] == 1) {
      	*vmesp = 1;                     /* VME system is in running state */
   	}else {
      	*vmesp = 0;
   	}
   	movebytes = BUFFER_LENGTH/4;      	/* Bufferlength is in bytes */
   	moveaddress = Message_Box[0];		/* Address of VME A24 event buffer */

   	/* Write status to file /help/vmestatus.tmp */
   	strm = fopen("/Applications/sirius/help/vmestatus.tmp","w");
   	if ( Message_Box[6] == 1 ) {
      	fprintf(strm," VME system status\t\t: RUNNING\n");
   	}
   	else if ( Message_Box[6] == 0 ) {
      	fprintf(strm," VME system status\t\t: STOPPED\n");
   	}else {
      	fprintf(strm," VME system status\t\t: UNKNOWN ?\n");
   	}
   	fprintf(strm, " Buffer address\t\t: %lx (hex) \n", moveaddress);
   	fprintf(strm, " Buffer length\t\t: %lx (hex) \n", Message_Box[1]);
	fprintf(strm," ---------------------------------------------\n");
   	fclose( strm );

   	/* Take a copy of the file descriptor for storage unit if used */
   	if (*stgp > 0) {
      	opendes = *stgp;
      	exades = fcntl( opendes, F_DUPFD, new_des_min );
      	write_data = 1;
      	if ( exades == -1) {
         	perror("\n Engine ERROR: Could not copy file descriptor \n");
         	write_data = 0;
      	}
   	}

   	semph1 = Message_Box[2]&0x00000001;               /*Test on the last 4 bits*/
   	semph2 = Message_Box[3]&0x00000001;
   	semph3 = Message_Box[4]&0x00000001;               /*Test on the last 4 bits*/
   	semph4 = Message_Box[5]&0x00000001;
   	tiger  = Message_Box[7]&0x00000001;
   	stbox  = MESSAGE_ADDRESS;
	
	printf("\n --------------------------------------------------------- \n");
   	printf(  "|                    E N G I N E 1.0                      |\n");
	printf(  "|                     Apr. 10. 2008                       |\n");
	printf(  "|---------------------------------------------------------|\n");
   	printf(  "| VME message box starts at                  : 0x%8lx |\n",stbox);
   	printf(  "| Buffer starts at                           : 0x%8lx |\n",moveaddress);
   	printf(  "| Start of buffer address     (messagebox 0) : 0x%8lx |\n",Message_Box[0]);
   	printf(  "| Buffer length (words)       (messagebox 1) :   %8ld |\n",Message_Box[1]);
   	printf(  "| Semaphore # 1               (messagebox 2) :   %8ld |\n",semph1);
   	printf(  "| Semaphore # 2               (messagebox 3) :   %8ld |\n",semph2);
   	printf(  "| Semaphore # 3               (messagebox 4) :   %8ld |\n",semph3);
   	printf(  "| Semaphore # 4               (messagebox 5) :   %8ld |\n",semph4);
   	printf(  "| VME ready(1) or not(0)      (messagebox 6) :   %8ld |\n",Message_Box[6]);
   	printf(  "| Linux ready(1) or not(0)    (messagebox 7) :   %8ld |\n",tiger);
   	printf(  "| Not used                    (messagebox 8) :   %8ld |\n",Message_Box[8]);
   	printf(  "| Not used                    (messagebox 9) :   %8ld |\n",Message_Box[9]);
	printf(  " --------------------------------------------------------- \n");

   	for(;;) {                               /*MAIN DATA ACQUISITION LOOP*/
		if ( *engp == 9 ) goto exitengine;   /*STOP COMMAND FROM MASTER */

/**********************************************************************	*/
/*                            B U F F E R                              	*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::	*/
/* 	Since A32 slave DRAM gives crash 									*/
/*  after typically 2 - 5 hours, we use A24 SRAM. However, this space  	*/
/*  is only 128 kbytes. Thus, we cannot use the 2 buffer technique   	*/
/*  from the original version designed by Tore Ramsoey. We				*/
/*  have to segment 1 eventbuffer (32 kwords) into 4 movebuffers,      	*/
/*  each 32 kbytes. Tests show that this is almost as fast as before,  	*/
/*  and no more crashes of the eventbuilder running on bobcat RIO2!!!  	*/
/*  First buffer is called for every 100 us, the next three other		*/
/*  buffers is called for every 1 us.									*/
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::	*/

/************************************************************************/ 
/*1.0 Check if movebuffer is ready                                     	*/
/*		Loop on VME semaphore #	1 until it becomes 1 (FULL)				*/
/*		The call to usleep suspends the process 100 us                  */
		for (;;) {
			status = bt_read(btd, sem1ptr, SEM_1, 4, &amt_read);
			if ( BT_SUCCESS != status) {
				bt_perror(btd, status, "Engine ERROR: Could not read VME semaphore # 1");
				vme_close();
				return EXIT_FAILURE;
			}
			if (sem1val == 1 ) break;				/* Buffer in VME is FULL, go and fetch it		*/    
			if (*engp	== 9) goto exitengine;		/* User has requested to stop acquisition		*/
			usleep(100);							/* Buffer is EMPTY, continue asking (polling)	*/
		}

/*1.1 Signal the sorting task to disrupt sorting						*/
/*		This is done by setting message_box[0] to '3'                   */
		*sortp = 3;

/*1.2 Fetch movebuffer #1 from the VMEbus system						*/
		status = bt_read(btd, bufp + 0x0000, moveaddress, movebytes, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not read VME event buffer 1");
			vme_close();
			return EXIT_FAILURE;
		}

/*1.3 Reset VMEbus semaphore # 1 to empty								*/
		sem1val = 0;
		status = bt_write(btd, sem1ptr, SEM_1, 4, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not reset VME semaphore # 1 to empty");
			vme_close();
			return EXIT_FAILURE;
		}

/************************************************************************/ 
/*2.0 Check if movebuffer is ready                                     	*/
/*		Loop on VME semaphore # 2 until it becomes 1 (FULL)				*/
/*		The call to usleep suspends the process 1 us                    */
		for (;;) {
			status = bt_read(btd, sem2ptr, SEM_2, 4, &amt_read);
			if ( BT_SUCCESS != status) {
				bt_perror(btd, status, "Engine ERROR: Could not read VME semaphore # 2");
				vme_close();
				return EXIT_FAILURE;
			}
			if (sem2val == 1 ) break;				/* Buffer in VME is FULL, go and fetch it		*/    
			if (*engp	== 9) goto exitengine;		/* User has requested to stop acquisition		*/
			usleep(1);								/* Buffer is EMPTY, continue asking (polling)	*/
		}

/*2.1 Signal the sorting task to disrupt sorting						*/
/*		This is done by setting message_box[0] to	3                   */
		*sortp = 3;

/*2.2 Fetch movebuffer #2 from the VMEbus system						*/
		status = bt_read(btd, bufp + 0x2000, moveaddress, movebytes, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not read VME event buffer 2");
			vme_close();
			return EXIT_FAILURE;
		}

/*2.3 Reset VMEbus semaphore # 2 to empty								*/
		sem2val = 0;
		status = bt_write(btd, sem2ptr, SEM_2, 4, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not reset VME semaphore # 2 to empty");
			vme_close();
			return EXIT_FAILURE;
		}
       
/************************************************************************/ 
/*3.0 Check if movebuffer is ready                                     	*/
/*		Loop on VME semaphore # 3 until it becomes 1 (FULL)				*/
/*		The call to usleep suspends the process 1 us                    */
		for (;;) {
			status = bt_read(btd, sem3ptr, SEM_3, 4, &amt_read);
			if ( BT_SUCCESS != status) {
				bt_perror(btd, status, "Engine ERROR: Could not read VME semaphore # 3");
				vme_close();
				return EXIT_FAILURE;
			}
			if (sem3val == 1 ) break;				/* Buffer in VME is FULL, go and fetch it		*/    
			if (*engp	== 9) goto exitengine;		/* User has requested to stop acquisition		*/
			usleep(1);								/* Buffer is EMPTY, continue asking (polling)	*/
		}

/*3.1 Signal the sorting task to disrupt sorting						*/
/*		This is done by setting message_box[0] to 3						*/
		*sortp = 3;

/*3.2 Fetch movebuffer #3 from the VMEbus system						*/
		status = bt_read(btd, bufp + 0x4000, moveaddress, movebytes, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not read VME event buffer 3");
			vme_close();
			return EXIT_FAILURE;
		}

/*3.3 Reset VMEbus semaphore # 3 to empty								*/
		sem3val = 0;
		status = bt_write(btd, sem3ptr, SEM_3, 4, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not reset VME semaphore #3 to empty");
			vme_close();
			return EXIT_FAILURE;
		}
		
/************************************************************************/ 
/*4.0 Check if movebuffer is ready                                     	*/
/*		Loop on VME semaphore # 4 until it becomes 1 (FULL)				*/
/*		The call to usleep suspends the process 1 us                    */
		for (;;) {
			status = bt_read(btd, sem4ptr, SEM_4, 4, &amt_read);
			if ( BT_SUCCESS != status) {
				bt_perror(btd, status, "Engine ERROR: Could not read VME semaphore # 4");
				vme_close();
				return EXIT_FAILURE;
			}
			if (sem4val == 1 ) break;				/* Buffer in VME is FULL, go and fetch it		*/    
			if (*engp	== 9) goto exitengine;		/* User has requested to stop acquisition		*/
			usleep(1);								/* Buffer is EMPTY, continue asking (polling)	*/
		}

/*4.1 Signal the sorting task to disrupt sorting						*/
/*		This is done by setting message_box[0] to 3						*/
		*sortp = 3;

/*4.2 Fetch movebuffer # 4 from the VMEbus system						*/
		status = bt_read(btd, bufp + 0x6000, moveaddress, movebytes, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not read VME event buffer 4");
			vme_close();
			return EXIT_FAILURE;
		}

/*4.3 Reset VMEbus semaphore # 4 to empty								*/
		sem4val = 0;
		status = bt_write(btd, sem4ptr, SEM_4, 4, &amt_read);
		if ( BT_SUCCESS != status) {
			bt_perror(btd, status, "Engine ERROR: Could not reset VME semaphore # 4 to empty");
			vme_close();
			return EXIT_FAILURE;
		}


/* testing, magne
   for (i = 0; i < 32768; i++)  {  
   if(*(bufp+i) < 40000 ){
   printf(" no %d buffer read = %d \n",i, *(bufp+i) );}
   } 
   exit(0);
*/

/***********************************************************************/ 
/*5.0 Activate sorting task                                            */
/*		This is done by setting the sort semaphore to 0                */
		*sortp  = 0;                              /*Remove disrupt flag*/
		semno   = 0;
		arg.val = 0;
		if ( semctl(semid, semno, SETVAL, arg) == -1) {
			printf("Engine ERROR: Set Sort Semaphore to Zero Failed\n");
			exit(errno);
		}

/*6.0 Start dump of total eventbuffer to exabyte tape or disk			*/
/*		Buffer is segmented into 4 records, each 32 kbytes long			*/
		if ( write_data == 1 ) {
			bytes_written = write(exades, buf1p, RECORD_LENGTH);
			bytes_written = write(exades, buf2p, RECORD_LENGTH);
			bytes_written = write(exades, buf3p, RECORD_LENGTH);
			bytes_written = write(exades, buf4p, RECORD_LENGTH);
			if (bytes_written != RECORD_LENGTH) {
				printf("Engine ERROR: Could not write event buffer to disk (or tape)\n");
			}
		} 

/*7.0 Update record count message_box[9] variable						*/
		*recp = *recp + 1;
	}                               /*END OF MAIN DATA ACQUISITION LOOP	*/

	exitengine:

/*	Signal to VME front-end system that the acquisition is stopped		*/
/*	This is done by setting the VME Message_Box[1] to 0					*/
  	engstatval = 0;
   	status = bt_write(btd, engstatptr, ENGSTATUS, 4, &amt_read);
	if ( BT_SUCCESS != status) { 
		if (amt_read != 4) {
            fprintf(stderr, "Engine ERROR: Only %d bytes written to SBS VME-PCI\n", (int) amt_read);
        }
        else {
            fprintf(stderr, "Engine ERROR: Could not write to %s\n", &devname[0]);
        }
        bt_perror(btd, status, "Engine ERROR: Could not write engine status to SBS VME-PCI");
	}

/*	Detach shared memory */
	if ( shmdt( shm1ptr ) == -1) {
		printf("Engine ERROR: Could not detach databuffer shared memory\n");
	}
	if ( shmdt( shm2ptr ) == -1) {
		printf("Engine ERROR: Could not detach message_box shared memory\n");
	} 

/*	Remove the lock file */
	if ( remove("/Applications/sirius/system/engine.lock") == -1) {
		printf("Engine ERROR: Could not remove engine.lock file\n");      
	}

/* Closing VME front-end system */
	if (vme_close() != 0) {
		printf("Engine ERROR: Problems to close SBS VME_PCI\n");
		exit(errno);
	}
	exit(0);
}