/************************************************/ /* */ /* File : calbhard.c */ /* Description : CALB hardware base access */ /* */ /* Authors: G.Cabibbo, A.Passeri */ /* */ /* Created : 10.02.1997 */ /* Last modified: 03.04.1997 */ /* */ /************************************************/ #include <stdio.h> #include <Error.h> #include <Vme.h> #include <Vme_am.h> #include <GeoVme.h> #include "calbhard.h" #include "calbbits.h" /*********************************************************************/ /* Initialization routines */ /*********************************************************************/ int calbh_open(int chain, /* IN */ int crate, /* IN */ int slot, /* IN */ CALBH_id *calb_id) /* OUT */ { GeoBoardAddr Calb_Addr; if(GeoVmeOpen(chain,crate,slot,&Calb_Addr)!=GEOVME_ERROR_OK) { ErrorSetF(CALBH_ERROR_UNKNOWN,"calbh_open_tmp","GeoVmeOpen error: %s",ErrorGetMessage()); return CALBH_ERROR_UNKNOWN; } *calb_id = (CALBH_id) malloc(sizeof(CALBH_id_base)); (*calb_id)->cid = Calb_Addr.cid; (*calb_id)->map_ptr = Calb_Addr.map_ptr; (*calb_id)->vme_addr = Calb_Addr.addr; (*calb_id)->offs = Calb_Addr.offs; (*calb_id)->vme_am = Calb_Addr.am; if ((*calb_id)->map_ptr==NULL) { ErrorSetF(CALBH_ERROR_UNKNOWN,"calbh_open_tmp","VmeMapAddress error: %s",ErrorGetMessage()); return CALBH_ERROR_UNKNOWN; } #ifdef DEBUG printf("map: %x\naddr: %x\noffs: %x\n",(*calb_id)->map_ptr, (*calb_id)->vme_addr, (*calb_id)->offs); #endif VmeSetProperty((*calb_id)->cid,Vme_SET_COPY_FIFO,1); return CALBH_ERROR_OK; } int calbh_close(int chain, /* IN */ int crate, /* IN */ int slot, /* IN */ CALBH_id calb_id) /* IN */ { int geoc; free(calb_id); geoc=GeoVmeClose(chain,crate,slot); if(geoc!=GEOVME_ERROR_OK) { ErrorSetF(CALBH_ERROR_UNKNOWN,"calbh_close","VmeCloseChannel error: %s", ErrorGetMessage()); return CALBH_ERROR_UNKNOWN; } return CALBH_ERROR_OK; } /*********************************************************************/ /* read routines */ /* return the read value */ /*********************************************************************/ unsigned short calbh_read_reg16(CALBH_id calb_id, /* IN */ unsigned int offset) /* IN */ { unsigned short reg16; unsigned short *aptr; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG if (offset<0x4000) printf("read addr: %x \n",aptr); #endif /* Vme_D16READ(calb_id->vme_addr,aptr,reg16); */ Vme_D16READ(calb_id->map_ptr,aptr,reg16); return reg16; } unsigned int calbh_read_reg32(CALBH_id calb_id, /* IN */ unsigned int offset) /* IN */ { unsigned int reg32; unsigned int *aptr; aptr = (unsigned int *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG if (offset<0x4000) printf("read addr: %x \n",aptr); #endif Vme_D32READ(calb_id->map_ptr,aptr,reg32); return reg32; } /*********************************************************************/ /* write routines */ /*********************************************************************/ int calbh_write_reg16(CALBH_id calb_id, /* IN */ unsigned int offset, /* IN */ unsigned short reg, /* IN */ unsigned short testmask)/* IN, test if >0 */ { unsigned short *aptr; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG if (offset<0x4000) printf("write addr: %x \n",aptr); #endif /* Vme_D16WRITE(calb_id->vme_addr,aptr,reg); */ Vme_D16WRITE(calb_id->map_ptr,aptr,reg); if (testmask!=0) { unsigned short testreg; /* Vme_D16READ(calb_id->vme_addr,aptr,testreg); */ Vme_D16READ(calb_id->map_ptr,aptr,testreg); if ((testreg&testmask)!=(reg&testmask)) return CALBH_ERROR_TEST; } return CALBH_ERROR_OK; } /*********************************************************************/ /* readLatches routines */ /*********************************************************************/ int calbh_readlatch_i_chan(CALBH_id calb_id /* IN */, /* OUT */ unsigned int chan) { unsigned short latch; unsigned short *aptr; unsigned int offset; if ( chan>29 ) { ErrorSetF(CALBH_ERROR_OUTRANGE,"calbh_readlatch_i_chan","Error: channel number %d out of range",chan); return CALBH_ERROR_OUTRANGE; } offset = CALBH_PAGE_LATCH_ofs + chan*2 ; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16READ(calb_id->map_ptr,aptr,latch); return latch&0x1fff; } int calbh_readlatch_i_all (CALBH_id calb_id /* IN */, /* OUT */ CHANNELS latch) { unsigned short *aptr; unsigned int offset; unsigned short reg16; int chan; for(chan=0;chan<30;chan++) { offset = CALBH_PAGE_LATCH_ofs+chan*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16READ(calb_id->map_ptr,aptr,reg16); latch[chan]=reg16&0x1fff; } return CALBH_ERROR_OK; } /*********************************************************************/ /* readpage routines */ /*********************************************************************/ int calbh_readpage_i_csr(CALBH_id calb_id, /* IN */ CALBH_CSR_regs *csr) /* OUT */ { csr->creg = calbh_read_creg(calb_id); csr->sreg = calbh_read_sreg(calb_id); return CALBH_ERROR_OK; } int calbh_readpage_i_ped (CALBH_id calb_id /* IN */, /* OUT */ CALBH_PEDS_val *peds) { unsigned short *aptr; unsigned int offset; unsigned short reg16; int chan; for(chan=0;chan<30;chan++) { /* section A peds */ offset = CALBH_PAGE_PED_A_ofs+chan*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16READ(calb_id->map_ptr,aptr,reg16); peds->ped_a[chan]=reg16&0xfff; /* section B peds */ offset = CALBH_PAGE_PED_B_ofs+chan*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16READ(calb_id->map_ptr,aptr,reg16); peds->ped_b[chan]=reg16&0xfff; } return CALBH_ERROR_OK; } int calbh_readpage_i_zsup(CALBH_id calb_id /* IN */, /* OUT */ CALBH_ZSUP_val *zsup) { int chret; chret=calbh_readpage_zsup_elem(calb_id,CALBH_PAGE_ZSUP1_A_ofs,zsup->zlow1_a,zsup->zhig1_a); if (chret != -1) ErrorSetF(CALBH_WARNING_ZSUP,"calbh_writepage_i_zsup_elem", "WARNING: more then 1 suppressed window for channel %d ",chret); chret=calbh_readpage_zsup_elem(calb_id,CALBH_PAGE_ZSUP1_B_ofs,zsup->zlow1_b,zsup->zhig1_b); if (chret != -1) ErrorSetF(CALBH_WARNING_ZSUP,"calbh_writepage_i_zsup_elem", "WARNING: more then 1 suppressed window for channel %d ",chret+0xF); chret=calbh_readpage_zsup_elem(calb_id,CALBH_PAGE_ZSUP2_A_ofs,zsup->zlow2_a,zsup->zhig2_a); if (chret != -1) ErrorSetF(CALBH_WARNING_ZSUP,"calbh_writepage_i_zsup_elem", "WARNING: more then 1 suppressed window for channel %d ",chret); chret=calbh_readpage_zsup_elem(calb_id,CALBH_PAGE_ZSUP2_B_ofs,zsup->zlow2_b,zsup->zhig2_b); if (chret != -1) ErrorSetF(CALBH_WARNING_ZSUP,"calbh_writepage_i_zsup_elem", "WARNING: more then 1 suppressed window for channel %d ",chret+0xF); return CALBH_ERROR_OK; } int calbh_readpage_i_zsup_elem(CALBH_id calb_id /* IN */,/* IN */ int zofs, /* OUT */ CHALF zlow, /* OUT */ CHALF zhig) { unsigned short *aptr; unsigned int offset; unsigned short reg16; int i,chan,bit,prev; int chret=-1; for(chan=0;chan<15;chan++) { zlow[chan]=0; zhig[chan]=0x1000; } reg16 = 0xffff; for(i=0;i<0x1000;i++) { offset = zofs+i*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); /* #ifdef DEBUG printf("read addr: %x \n",aptr); #endif */ prev = reg16; Vme_D16READ(calb_id->map_ptr,aptr,reg16); for(chan=0;chan<15;chan++) { bit = bits_get_bit(reg16,chan); if(bit != bits_get_bit(prev,chan) ) { if( bit ) { /* if(zhig[chan]!=0x1000) chret=chan; */ zhig[chan] = i-1; } else { if(zlow[chan]!=0) chret=chan; zlow[chan]=i; } } } } return chret; } /*********************************************************************/ /* writepage routines */ /*********************************************************************/ int calbh_writepage_i_ped (CALBH_id calb_id /* IN */, /* IN */ CALBH_PEDS_val *peds) { unsigned short *aptr; unsigned int offset; unsigned short reg16; int chan; for(chan=0;chan<30;chan++) { /* section A peds */ offset = CALBH_PAGE_PED_A_ofs+chan*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); reg16=peds->ped_a[chan]; #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16WRITE(calb_id->map_ptr,aptr,reg16); /* section B peds */ offset = CALBH_PAGE_PED_B_ofs+chan*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); reg16=peds->ped_b[chan]; #ifdef DEBUG printf("read addr: %x \n",aptr); #endif Vme_D16WRITE(calb_id->map_ptr,aptr,reg16); } return CALBH_ERROR_OK; } int calbh_writepage_i_zsup (CALBH_id calb_id /* IN */, /* IN */ CALBH_ZSUP_val *zsup) { calbh_writepage_zsup_elem(calb_id,CALBH_PAGE_ZSUP1_A_ofs,zsup->zlow1_a,zsup->zhig1_a); calbh_writepage_zsup_elem(calb_id,CALBH_PAGE_ZSUP1_B_ofs,zsup->zlow1_b,zsup->zhig1_b); calbh_writepage_zsup_elem(calb_id,CALBH_PAGE_ZSUP2_A_ofs,zsup->zlow2_a,zsup->zhig2_a); calbh_writepage_zsup_elem(calb_id,CALBH_PAGE_ZSUP2_B_ofs,zsup->zlow2_b,zsup->zhig2_b); return CALBH_ERROR_OK; } int calbh_writepage_i_zsup_elem(CALBH_id calb_id /* IN */,/* IN */ int zofs, /* IN */ CHALF zlow, /* IN */ CHALF zhig) { unsigned short *aptr; unsigned int offset; unsigned short reg16; int i,chan,min,max; min = 0x1000; max = 0; for(chan=0;chan<15;chan++) { if(zlow[chan]<min) min=zlow[chan]; if(zhig[chan]>max) max=zhig[chan]; } for(i=0;i<0x1000;i++) { reg16 = 0xffff; if( (i>=min) && (i<=max) ) { for(chan=0;chan<15;chan++) { if( (i>=zlow[chan]) && (i<=zhig[chan]) ) reg16=bits_set_bit(reg16,chan,0); } } offset = zofs+i*2; aptr = (unsigned short *) ((unsigned char *)calb_id->map_ptr+calb_id->offs+offset); /* #ifdef DEBUG printf("read addr: %x \n",aptr); #endif */ Vme_D16WRITE(calb_id->map_ptr,aptr,reg16); } return CALBH_ERROR_OK; } /*********************************************************************/ /* Readfifo routines */ /*********************************************************************/ int calbh_read_pio_i_hfifo (CALBH_id calb_id, /* IN */ unsigned int nels, /* IN */ unsigned int *buffer, /* OUT */ unsigned int *count) /* OUT, nr of els really read */ { int i,iCount,tempbuf; CALBB_HFIFO_bits bits; #ifdef DEBUG printf("readfifo size: %x \n",nels); #endif if (nels==0) { /* Nothing to do */ *count=0; return CALBH_ERROR_OK; } iCount=0; for (i=0;i<nels;i++) { tempbuf=calbh_read_hfifo(calb_id); calbb_nrtohfifo(tempbuf,bits); #ifdef DEBUG printf("readfifo: el %x fifodata %x \n",i,tempbuf); #endif buffer[iCount++]=bits.fifodata; if (bits.nvd!=CALBB_BIT_OFF) break; } *count = iCount; #ifdef DEBUG printf("readfifo count: %x \n",*count); #endif return CALBH_ERROR_OK; } int calbh_read_pio_i_dfifo (CALBH_id calb_id, /* IN */ unsigned int nels, /* IN */ unsigned int *buffer, /* OUT */ unsigned int *count) /* OUT, nr of els really read */ { int i,iCount,tempbuf; CALBB_DFIFO_bits bits; #ifdef DEBUG printf("readfifo size: %x \n",nels); #endif if (nels==0) { /* Nothing to do */ *count=0; return CALBH_ERROR_OK; } iCount=0; for (i=0;i<nels;i++) { tempbuf=calbh_read_dfifo(calb_id); calbb_nrtodfifo(tempbuf,bits); #ifdef DEBUG printf("readfifo: el %x fifodata %x \n",i,tempbuf); #endif buffer[iCount++]=bits.fifodata; if (bits.nvd!=CALBB_BIT_OFF) break; } *count = iCount; #ifdef DEBUG printf("readfifo count: %x \n",*count); #endif return CALBH_ERROR_OK; } int calbh_read_blt_fifo(CALBH_id calb_id, /* IN */ unsigned int offset, /* IN */ unsigned int nrels, /* IN */ unsigned int *buffer, /* IN/OUT */ unsigned int *count) /* OUT, nr of els. really read */ { int res; unsigned int *DMAbuffer; unsigned int nrbytes; #ifdef DEBUG printf("readfifo size: %x \n",nrels); #endif if (nrels==0) { /* Nothing to do */ *count=0; return CALBH_ERROR_OK; } nrbytes = nrels*4; /* alloc a buffer for DMA */ /* DMAbuffer = (unsigned int *) VmeAllocateMemory(calb_id->cid,NULL,nrbytes,Vme_MEMORY_FASTEST);*/ DMAbuffer = (unsigned int *) malloc(nrbytes); if (DMAbuffer==NULL) { ErrorSetF(CALBH_ERROR_UNKNOWN,"calbh_readfifo_fifo","VmeAllocateBuffer error: %s",ErrorGetMessage()); return CALBH_ERROR_UNKNOWN; } /* set VME channel AM to block transfer */ VmeSetProperty(calb_id->cid,Vme_SET_COPY_AM,0xB); res = VmeRead(calb_id->cid,calb_id->offs+offset,(char *) DMAbuffer,nrbytes); if (res==0) { ErrorSetF(CALBH_ERROR_UNKNOWN,"calbh_readfifo_fifo","VmeRead error: %s",ErrorGetMessage()); free(DMAbuffer); *count=0; return CALBH_ERROR_UNKNOWN; } res=res>>2; /* convert in nr of elements */ #ifdef DEBUG printf("readfifo res size: %x \n",res); #endif /*** { unsigned int iDMA,iCount; iCount=0; for (iDMA=0;iDMA<res;iDMA++) { CALBB_EDFIFO_bits bits; calbb_nr2edfifo(DMAbuffer[iDMA],bits); #ifdef DEBUG printf("readfifo %x el: %x fifodata %x \n",iDMA,DMAbuffer[iDMA],bits.fifodata); #endif buffer[iCount++]=bits.fifodata; if (bits.nvd!=CALBB_BIT_OFF) break; } *count = iCount; } ***/ #ifdef DEBUG printf("readfifo count: %x \n",*count); #endif free(DMAbuffer); return CALBH_ERROR_OK; }