/************************************************/ /* */ /* File : rockhard.c */ /* Description : ROCK hardware base access */ /* */ /* Author: Sfiligoi Igor */ /* */ /* Created : 20.01.1997 */ /* Last modified: 12.05.1997 */ /* */ /************************************************/ #include <stdlib.h> #include <stdio.h> #include <Error.h> #include <GeoVme.h> #include <Vme.h> #include <Vme_am.h> #include "rockhard.h" #include "rockbits.h" #define ROCKH_SLOT 21 #define ROCKH_DMA_BUFFER_SIZE (20*1024) /*********************************************************************/ /* Query routines */ /*********************************************************************/ /* returns 0 if ROCK not present, 1 else */ int rockh_ispresent(int chain, /* IN, VIC chain */ int crate) /* IN, position in the VIC chain */ { return ((GeoVme_exist(chain,crate,ROCKH_SLOT)==GEOVME_BOARD_EXIST) && (GeoVme_btype(chain,crate,ROCKH_SLOT)==GEOVME_ROCK_BTYPE)); } /*********************************************************************/ /* Initialization routines */ /*********************************************************************/ int rockh_open(int chain, /* IN, VIC chain */ int crate, /* IN, position in the VIC chain */ ROCKH_id *rock_id) /* OUT */ { int result; GeoBoardAddr GeoData; #ifdef DEBUG printf("rockh_open:\nchain %x\ncrate: %x\n",chain,crate); #endif *rock_id = (ROCKH_id) malloc(sizeof(ROCKH_id_base)); if (*rock_id==NULL) { ErrorSet(ROCKH_ERROR_UNKNOWN,"rockh_open","Malloc returned NULL."); return ROCKH_ERROR_UNKNOWN; } result = GeoVmeOpen(chain,crate,ROCKH_SLOT,&GeoData); if (result!=GEOVME_ERROR_OK) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","GeoVmeOpen error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } if (GeoData.btype!=GEOVME_ROCK_BTYPE) { GeoVmeClose(chain,crate,ROCKH_SLOT); ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","Chain %i Crate %i do not have a ROCK!",chain,crate); return ROCKH_ERROR_UNKNOWN; } (*rock_id)->chain = chain; (*rock_id)->crate = crate; (*rock_id)->cid = GeoData.cid; (*rock_id)->map_ptr = GeoData.map_ptr; (*rock_id)->vme_addr = GeoData.addr; (*rock_id)->offs = GeoData.offs; (*rock_id)->vme_am = GeoData.am; /* alloc a buffer for DMA */ (*rock_id)->DMAbuffer = (unsigned int *) VmeAllocateMemory((*rock_id)->cid,NULL,ROCKH_DMA_BUFFER_SIZE*sizeof(unsigned int),Vme_MEMORY_FASTEST); /* (*rock_id)->DMAbuffer = (unsigned int *) malloc(ROCKH_DMA_BUFFER_SIZE*sizeof(unsigned int)); */ if ((*rock_id)->DMAbuffer==NULL) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","VmeAllocateMemory error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } #ifdef DEBUG printf("map: %x\naddr: %p\noffs: %x\nDMAbuffer: %p\n", (*rock_id)->map_ptr, (*rock_id)->vme_addr, (*rock_id)->offs, (*rock_id)->DMAbuffer); #endif VmeSetProperty((*rock_id)->cid,Vme_SET_COPY_FIFO,1); return ROCKH_ERROR_OK; } int rockh_open_raw(unsigned int vme_addr, /* IN */ int vme_size, /* IN */ int vme_am, /* IN */ int offs, /* IN, ROCK offset */ ROCKH_id *rock_id) /* OUT */ { *rock_id = (ROCKH_id) malloc(sizeof(ROCKH_id_base)); if (*rock_id==NULL) { ErrorSet(ROCKH_ERROR_UNKNOWN,"rockh_open","Malloc returned NULL."); return ROCKH_ERROR_UNKNOWN; } (*rock_id)->cid = VmeOpenChannel("Rock","pio,dma"); if ((*rock_id)->cid==Vme_FAILURE) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","VmeOpenChannel error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } /* alloc a buffer for DMA */ (*rock_id)->DMAbuffer = (unsigned int *) VmeAllocateMemory((*rock_id)->cid,NULL,ROCKH_DMA_BUFFER_SIZE*sizeof(unsigned int),Vme_MEMORY_FASTEST); /* (*rock_id)->DMAbuffer = (unsigned int *) malloc(ROCKH_DMA_BUFFER_SIZE*sizeof(unsigned int)); */ if ((*rock_id)->DMAbuffer==NULL) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","VmeAllocateMemory error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } (*rock_id)->map_ptr=VmeMapAddress((*rock_id)->cid,vme_addr,vme_size,vme_am); (*rock_id)->vme_addr = vme_addr; (*rock_id)->vme_am = vme_am; (*rock_id)->offs = offs; (*rock_id)->chain = -1; /* set to an invalid vaule */ (*rock_id)->crate = -1; /* set to an invalid vaule */ if ((*rock_id)->map_ptr==NULL) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_open","VmeMapAddress error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } #ifdef DEBUG printf("map: %x\naddr: %p\noffs: %x\nDMAbuffer: %p\n", (*rock_id)->map_ptr, (*rock_id)->vme_addr, (*rock_id)->offs, (*rock_id)->DMAbuffer); #endif VmeSetProperty((*rock_id)->cid,Vme_SET_COPY_FIFO,1); return ROCKH_ERROR_OK; } int rockh_close(ROCKH_id rock_id) /* IN */ { int result; if ((rock_id->chain>=0)&&(rock_id->crate>=0)) { /* normal opened */ result = GeoVmeClose(rock_id->chain,rock_id->crate,ROCKH_SLOT); free(rock_id); if (result!=GEOVME_ERROR_OK) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_close","GeoVmeClose(%i,%i) error: %s",rock_id->chain,rock_id->crate,ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } else return ROCKH_ERROR_OK; } else { /* raw opened */ result = VmeCloseChannel(rock_id->cid); free(rock_id); if (result!=Vme_SUCCESS) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_close","VmeCloseChannel error: %s",ErrorGetMessage()); return ROCKH_ERROR_UNKNOWN; } else return ROCKH_ERROR_OK; } } /*********************************************************************/ /* read routines */ /* return the read value */ /*********************************************************************/ unsigned char rockh_read_reg08(ROCKH_id rock_id, /* IN */ unsigned int offset) /* IN */ { unsigned char reg08; unsigned char *aptr; aptr = (unsigned char *)rock_id->map_ptr+rock_id->offs+offset; #ifdef DEBUG printf("read addr: %p",aptr); #endif Vme_D08READ(rock_id->map_ptr,aptr,reg08); #ifdef DEBUG printf(" : %x\n",reg08); #endif return reg08; } unsigned short rockh_read_reg16(ROCKH_id rock_id, /* IN */ unsigned int offset) /* IN */ { unsigned short reg16; unsigned short *aptr; aptr = (unsigned short *) ((unsigned char *)rock_id->map_ptr+rock_id->offs+offset); #ifdef DEBUG printf("read addr: %p",aptr); #endif Vme_D16READ(rock_id->map_ptr,aptr,reg16); #ifdef DEBUG printf(" : %x\n",reg16); #endif return reg16; } unsigned int rockh_read_reg32(ROCKH_id rock_id, /* IN */ unsigned int offset) /* IN */ { unsigned int reg32; unsigned int *aptr; aptr = (unsigned int *) ((unsigned char *)rock_id->map_ptr+rock_id->offs+offset); #ifdef DEBUG printf("read addr: %p",aptr); #endif Vme_D32READ(rock_id->map_ptr,aptr,reg32); #ifdef DEBUG printf(" : %x\n",reg32); #endif return reg32; } /*********************************************************************/ /* write routines */ /*********************************************************************/ int rockh_write_reg08(ROCKH_id rock_id, /* IN */ unsigned int offset, /* IN */ unsigned char reg, /* IN */ unsigned char testmask) /* IN, test if >0*/ { unsigned char *aptr; aptr = (unsigned char *)rock_id->map_ptr+rock_id->offs+offset; #ifdef DEBUG printf("write addr: %p : %x\n",aptr,reg); #endif Vme_D08WRITE(rock_id->map_ptr,aptr,reg); if (testmask!=0) { unsigned char testreg; Vme_D08READ(rock_id->map_ptr,aptr,testreg); if ((testreg&testmask)!=(reg&testmask)) { unsigned int aread,awrite; aread = testreg; awrite = reg; ErrorSetF(ROCKH_ERROR_TEST,"rockh_write_reg08","Error during test: written %x read %x\n",awrite,aread); return ROCKH_ERROR_TEST; } } return ROCKH_ERROR_OK; } int rockh_write_reg16(ROCKH_id rock_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 *)rock_id->map_ptr+rock_id->offs+offset); #ifdef DEBUG printf("write addr: %p : %x\n",aptr,reg); #endif Vme_D16WRITE(rock_id->map_ptr,aptr,reg); if (testmask!=0) { unsigned short testreg; Vme_D16READ(rock_id->map_ptr,aptr,testreg); if ((testreg&testmask)!=(reg&testmask)) { unsigned int aread,awrite; aread = testreg; awrite = reg; ErrorSetF(ROCKH_ERROR_TEST,"rockh_write_reg16","Error during test: written %x read %x\n",awrite,aread); return ROCKH_ERROR_TEST; } } return ROCKH_ERROR_OK; } int rockh_write_reg32(ROCKH_id rock_id, /* IN */ unsigned int offset, /* IN */ unsigned int reg, /* IN */ unsigned int testmask) /* IN, test if >0 */ { unsigned int *aptr; aptr = (unsigned int *) ((unsigned char *)rock_id->map_ptr+rock_id->offs+offset); #ifdef DEBUG printf("write addr: %p : %x\n",aptr,reg); #endif Vme_D32WRITE(rock_id->map_ptr,aptr,reg); if (testmask!=0) { unsigned int testreg; Vme_D32READ(rock_id->map_ptr,aptr,testreg); if ((testreg&testmask)!=(reg&testmask)) { unsigned int aread,awrite; aread = testreg; awrite = reg; ErrorSetF(ROCKH_ERROR_TEST,"rockh_write_reg32","Error during test: written %x read %x\n",awrite,aread); return ROCKH_ERROR_TEST; } } return ROCKH_ERROR_OK; } /*********************************************************************/ /* readpage routines */ /*********************************************************************/ int rockh_readpage_i_internal(ROCKH_id rock_id, /* IN */ ROCKH_INTERNAL_regs *internal) /* OUT */ { internal->reset = rockh_read_reset(rock_id); internal->fifo = rockh_read_fifo(rock_id); internal->watchdog = rockh_read_watchdog(rock_id); internal->csr0 = rockh_read_csr0(rock_id); internal->csr1 = rockh_read_csr1(rock_id); internal->csr2 = rockh_read_csr2(rock_id); internal->elapsed = rockh_read_elapsed(rock_id); internal->trigger = rockh_read_trigger(rock_id); return ROCKH_ERROR_OK; } int rockh_readpage_i_info(ROCKH_id rock_id, /* IN */ ROCKH_INFO_regs *info) /* OUT */ { info->tque = rockh_read_tque(rock_id); info->tnow = rockh_read_tnow(rock_id); info->rockinfo = rockh_read_rockinfo(rock_id); info->golden = rockh_read_golden(rock_id); return ROCKH_ERROR_OK; } /*********************************************************************/ /* readfifo routines */ /*********************************************************************/ int rockh_readfifo_fifo(ROCKH_id rock_id, /* IN */ unsigned int offset, /* IN */ unsigned int nrels, /* IN */ unsigned char raw, /* IN, if >0, raw fifo values are returned */ unsigned int *buffer, /* IN/OUT */ unsigned int *count) /* OUT, nr of els. really read */ { int res; unsigned int nrbytes; unsigned int recCount; #ifdef DEBUG unsigned char *aptr; aptr = (unsigned char *)rock_id->map_ptr+rock_id->offs+offset; printf("readfifo addr: %p\n",aptr); #endif #ifdef DEBUG printf("readfifo size: %x\n",nrels); #endif if (nrels==0) { /* Nothing to do */ *count=0; return ROCKH_ERROR_OK; } recCount=0; if (nrels>ROCKH_DMA_BUFFER_SIZE) { /* if cannot be read in one step, recurse */ res = rockh_readfifo_fifo(rock_id,offset,nrels-ROCKH_DMA_BUFFER_SIZE,raw,buffer,&recCount); if (res!=ROCKH_ERROR_OK) { /* if something get wrong, exit with the same error */ *count = recCount; return res; } nrels=ROCKH_DMA_BUFFER_SIZE; buffer=&(buffer[recCount]); } nrbytes = nrels*sizeof(unsigned int); res = VmeRead(rock_id->cid,rock_id->offs+offset,(char *) rock_id->DMAbuffer,nrbytes); if (res==0) { ErrorSetF(ROCKH_ERROR_UNKNOWN,"rockh_readfifo_fifo","VmeRead error: %s",ErrorGetMessage()); *count=recCount; return ROCKH_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++) { if (rockb_get_nvd(rock_id->DMAbuffer[iDMA])==ROCKB_BIT_OFF) { /* the rest of the data is valid */ if (raw) buffer[iCount++]=rock_id->DMAbuffer[iDMA]; else buffer[iCount++]=rockb_get_fifodata(rock_id->DMAbuffer[iDMA]); } } *count = recCount+iCount; } #ifdef DEBUG printf("readfifo count: %x\n",*count); #endif return ROCKH_ERROR_OK; }