/************************************************************************************* * utilities.c * * synopsis: Contains functions not associated with a particular package but * possibly used by many. * * in this file: calculateChecksum, waitDmaComplete, setMem, copyMem, * setLedState, getLedState, chkSlaves, waitRegister, codeVersion. ************************************************************************************/ #include /* must be included 1st */ #include #include #include #include #include #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) ) #include #elif (defined(REV_E)) #include #endif #include "resources.h" #include "comRegDfns.h" #ifdef I_AM_MASTER_DSP #include "registerIndices.h" #endif extern char genStr[], versionStr[]; extern TIMER_Handle timer1; /* general purpose timer, started in main() */ #pragma CODE_SECTION(calculateChecksum, "icode"); #pragma CODE_SECTION(waitDmaComplete, "icode"); #pragma CODE_SECTION(setMem, "icode"); #pragma CODE_SECTION(copyMem, "icode"); //#pragma CODE_SECTION(setMem, "xcode"); //#pragma CODE_SECTION(copyMem, "xcode"); #pragma CODE_SECTION(setLedState, "xcode"); #pragma CODE_SECTION(getLedState, "xcode"); #ifdef I_AM_MASTER_DSP #pragma CODE_SECTION(chkSlaves, "icode"); #pragma CODE_SECTION(parseInmem, "xcode"); #endif #pragma CODE_SECTION(waitRegister, "xcode"); #pragma CODE_SECTION(codeVersion, "xcode"); #pragma CODE_SECTION(setMem0, "xcode"); //File-level variables: utility DMA handle & structure for set & copyMem #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) ) DMA_Handle utilDmaCh= NULL; DMA_Config utilDmaConfig= {0,0,0,0,0}; #elif (defined(REV_E)) #define EDMA_SETMEM_ID 15 #define EDMA_COPYMEM_ID 14 EDMA_Handle utilDmaCh= NULL; EDMA_Config utilDmaConfig= {0,0,0,0,0,0}; #endif #define UTIL_DMA_FRAME_LENGTH 0x1000 /************************************************************************************ * calculateChecksum: Gives an exclusive-or checksum for the input words. ************************************************************************************/ UINT32 calculateChecksum(UINT32 *baseAddress, INT32 checksumWC) { INT32 word; UINT32 checksum; for (checksum= 0, word= 0; word < checksumWC; ++word) { checksum= checksum ^ *(baseAddress + word); } return checksum; } #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) ) #elif (defined(REV_E)) #endif /************************************************************************************ * waitDmaComplete: Wait for the DMA to complete. This little code stub should be * kept in IDRAM. That way the rest of the two functions which use * it (setMem & copyMem) can be put in SDRAM, without a large slowdown resulting * if the CSL fxn DMA_wait() is allowed to be inlined in the code (& thus in * SDRAM too). ************************************************************************************/ #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) ) void waitDmaComplete(DMA_Handle dmaCh); void waitDmaComplete(DMA_Handle dmaCh) {DMA_wait(dmaCh); } #elif (defined(REV_E)) void waitDmaComplete(UINT8 edmaId); void waitDmaComplete(UINT8 edmaId) { //UINT32 t0; //t0= TIMER_getCount(timer1); //while ( (!EDMA_intTest(edmaId)) &&(delta_t(t0) < 0x05f5e100) ); //100 sec max. //EDMA_intClear(edmaId); } #endif #if (defined(REV_E)||defined(SIM)) INT32 setMem(void *dest, UINT32 len, UINT32 val) { UINT32 *dst= (UINT32 *) dest; int i; for (i=0; i src) for (i= len-1; i>=0; --i) *(dst+i)= *(src+i); else for (i=0; i #frames= 1, (cnt == 1) ==> #frames= 2, etc. //For DMA, (cnt == 0 or 1) ==> #frames= 1, and from there on #frames= cnt. src= val; if ((xfrcnt_mod=len%(UTIL_DMA_FRAME_LENGTH))==0) { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH) -1; xfrcnt= EDMA_CNT_RMK(xfrcnt_frames, (UTIL_DMA_FRAME_LENGTH)); } else { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH); xfrcnt= EDMA_CNT_RMK(xfrcnt_frames, xfrcnt_mod); } utilDmaConfig.opt= EDMA_OPT_RMK(EDMA_OPT_PRI_LOW, EDMA_OPT_ESIZE_32BIT, EDMA_OPT_2DS_NO, EDMA_OPT_SUM_NONE, EDMA_OPT_2DD_NO, EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_YES, EDMA_OPT_TCC_OF(EDMA_SETMEM_ID), EDMA_OPT_LINK_NO, EDMA_OPT_FS_NO); utilDmaConfig.cnt= xfrcnt; utilDmaConfig.idx= EDMA_IDX_RMK(0,4); utilDmaConfig.rld= EDMA_RLD_RMK((UTIL_DMA_FRAME_LENGTH),0); utilDmaConfig.src= (UINT32) &src; utilDmaConfig.dst= (UINT32) dst; EDMA_config(utilDmaCh, &utilDmaConfig); EDMA_setChannel(utilDmaCh); //Start the EDMA by manually setting an event. t0= TIMER_getCount(timer1); waitDmaComplete(EDMA_SETMEM_ID); dt= delta_t(t0); sprintf(genStr, "%s %08x %s", "setMem: delta t in 1/10 us= ", dt, ".\n"); newInformation(__FILE__, __LINE__, genStr); return SUCCESS; } #endif #else INT32 setMem0(void *dest, UINT32 len, UINT32 val) { UINT32 *dst= (UINT32 *) dest; INT32 rval; rval= setMem(dst, len, val); return rval; } /************************************************************************************ * setMem(...): fill a block of memory with selected value, using DMA channel 3; * length is in words. The routine works using the excess of the * (arbitrarily chosen) frame element count (UTIL_DMA_FRAME_LENGTH) (len%(UTIL_DMA_FRAME_LENGTH)) as the element * count of the 1st transfer; if len <= (UTIL_DMA_FRAME_LENGTH) this is the only frame. Any other * frames have the element count loaded into them through the allocated global * count reload register. ************************************************************************************/ INT32 setMem(void *dest, UINT32 len, UINT32 val) { UINT32 *dst= (UINT32 *) dest; UINT32 src; //dpsf: Need a local non-pointer variable to hold data to be blitted. UINT32 xfrcnt, xfrcnt_frames, xfrcnt_mod; UINT32 reloadReg, init; //Multi-frame transfers which do not end on a frame boundary are treated by //1st transferring the partial frame, and then using a DMA global reload register //to transfer any remaining whole frames. Note that only the element count from //the reload register is loaded at the end of each frame. src= val; if ((xfrcnt_mod=len%(UTIL_DMA_FRAME_LENGTH))==0) { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH); xfrcnt= DMA_XFRCNT_RMK(xfrcnt_frames, (UTIL_DMA_FRAME_LENGTH)); } else { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH) +1; xfrcnt= DMA_XFRCNT_RMK(xfrcnt_frames, xfrcnt_mod); } utilDmaCh = DMA_open(DMA_CHA3,DMA_OPEN_RESET); if (utilDmaCh==INV) {return SET_MEMORY_ERROR;} if (xfrcnt_frames > 1) { /* must allocate register */ init= DMA_GBLCNT_RMK(xfrcnt_frames, (UTIL_DMA_FRAME_LENGTH)); reloadReg= DMA_allocGlobalReg(DMA_GBL_CNTRLD, init); if (reloadReg==0) {DMA_close(utilDmaCh); return SET_MEMORY_ERROR;} } utilDmaConfig.prictl= DMA_PRICTL_RMK( /* see Peripherals R.G., sect. 5 */ DMA_PRICTL_DSTRLD_NONE, DMA_PRICTL_SRCRLD_NONE, DMA_PRICTL_EMOD_NOHALT, DMA_PRICTL_FS_DISABLE, DMA_PRICTL_TCINT_DISABLE, DMA_PRICTL_PRI_DMA, DMA_PRICTL_WSYNC_NONE, DMA_PRICTL_RSYNC_NONE, DMA_PRICTL_INDEX_NA, /* reload element cnt at end of each frame transfer from the global register if there are more than 1 frames. */ ((xfrcnt_frames>1) ? reloadReg : DMA_PRICTL_CNTRLD_NA), DMA_PRICTL_SPLIT_DISABLE, DMA_PRICTL_ESIZE_32BIT, DMA_PRICTL_DSTDIR_INC, DMA_PRICTL_SRCDIR_NONE, DMA_PRICTL_START_STOP); utilDmaConfig.secctl= 0x00; /* no IE */ utilDmaConfig.src= (UINT32) &src; utilDmaConfig.dst= (UINT32) dst; utilDmaConfig.xfrcnt= xfrcnt; DMA_config(utilDmaCh, &utilDmaConfig); DMA_start(utilDmaCh); waitDmaComplete(utilDmaCh); DMA_close(utilDmaCh); if (xfrcnt_frames > 1) DMA_freeGlobalReg(reloadReg); return SUCCESS; } /************************************************************************************ * copyMem(...): copy a block of memory from one location to another. ************************************************************************************/ INT32 copyMem(void *source, void *dest, UINT32 len) { UINT32 *src= (UINT32 *) source, *dst= (UINT32 *) dest; UINT32 xfrcnt= 0, xfrcnt_mod= 0, init= 0; UINT32 reloadReg= 0, xfrcnt_frames= 0, offset; UINT8 srcDir, dstDir; if (len == 0) return SUCCESS; if ((xfrcnt_mod=len%(UTIL_DMA_FRAME_LENGTH))==0) { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH); xfrcnt= DMA_XFRCNT_RMK(xfrcnt_frames, (UTIL_DMA_FRAME_LENGTH)); } else { xfrcnt_frames= len/(UTIL_DMA_FRAME_LENGTH) +1; xfrcnt= DMA_XFRCNT_RMK(xfrcnt_frames, xfrcnt_mod); } utilDmaCh = DMA_open(DMA_CHA3,DMA_OPEN_RESET); if (utilDmaCh==INV) { return COPY_MEMORY_ERROR;} if (dst > src) { offset= len -1; srcDir= DMA_PRICTL_SRCDIR_DEC; dstDir= DMA_PRICTL_DSTDIR_DEC; } else { offset= 0; srcDir= DMA_PRICTL_SRCDIR_INC; dstDir= DMA_PRICTL_DSTDIR_INC; } if (xfrcnt_frames > 1) { /* must allocate register */ init= DMA_GBLCNT_RMK(xfrcnt_frames, (UTIL_DMA_FRAME_LENGTH)); reloadReg= DMA_allocGlobalReg(DMA_GBL_CNTRLD, init); if (reloadReg==0) {DMA_close(utilDmaCh); return COPY_MEMORY_ERROR;} } utilDmaConfig.prictl= DMA_PRICTL_RMK( /* see Peripherals R.G., sect. 5 */ DMA_PRICTL_DSTRLD_NONE, DMA_PRICTL_SRCRLD_NONE, DMA_PRICTL_EMOD_NOHALT, DMA_PRICTL_FS_DISABLE, DMA_PRICTL_TCINT_DISABLE, DMA_PRICTL_PRI_DMA, DMA_PRICTL_WSYNC_NONE, DMA_PRICTL_RSYNC_NONE, DMA_PRICTL_INDEX_NA, /* reload element cnt at end of each frame transfer from the global register if there are more than 1 frames. */ ((xfrcnt_frames>1) ? reloadReg : DMA_PRICTL_CNTRLD_NA), DMA_PRICTL_SPLIT_DISABLE, DMA_PRICTL_ESIZE_32BIT, dstDir, srcDir, DMA_PRICTL_START_STOP); utilDmaConfig.secctl= 0x00; /* no IE */ utilDmaConfig.xfrcnt= xfrcnt; utilDmaConfig.src= (UINT32) (src +offset); utilDmaConfig.dst= (UINT32) (dst +offset); DMA_config(utilDmaCh, &utilDmaConfig); DMA_start(utilDmaCh); waitDmaComplete(utilDmaCh); DMA_close(utilDmaCh); if (xfrcnt_frames > 1) DMA_freeGlobalReg(reloadReg); return SUCCESS; } #endif /************************************************************************************ * setLedState, getLedState : Set & get the state of an LED. The master DSP has 3 * available; slave DSPs have one. ************************************************************************************/ void setLedState(UINT8 led, UINT8 state){ #if defined(I_AM_MASTER_DSP) static UINT32 *mcbspPCR[3]= { (UINT32 *) 0x018c0024, /* 0,1,2= y, g & r */ (UINT32 *) 0x01900024, (UINT32 *) 0x018c0024 }; static UINT32 ledMask[3]= {0x00000001, 0x00000001, 0x00000004}; #elif defined(I_AM_SLAVE_DSP) #if (defined(REV_B)||defined(REV_C)||defined(SIM)) static UINT32 *ledReg= (UINT32 *) 0x01900024, ledMask= 0x00000002; #elif (defined(REV_E)) static UINT32 *ledReg= (UINT32 *) 0x01b00008, ledMask= 0x00000080; #endif #endif if (state == TOGGLE) { if (getLedState(led) == ON) setLedState(led, OFF); else setLedState(led, ON); } else if (state == ON) { #if defined(I_AM_MASTER_DSP) *mcbspPCR[led]= *mcbspPCR[led] | ledMask[led]; #elif defined(I_AM_SLAVE_DSP) *ledReg= *ledReg & ~ledMask; /* c'est la vie: bit == 0 => led on. */ #endif } else if (state == OFF) { #if defined(I_AM_MASTER_DSP) *mcbspPCR[led]= *mcbspPCR[led] & ~ledMask[led]; #elif defined(I_AM_SLAVE_DSP) *ledReg= *ledReg | ledMask; #endif } } UINT8 getLedState(UINT8 led){ #if defined(I_AM_MASTER_DSP) static UINT32 *mcbspPCR[3]= { (UINT32 *) 0x018c0024, (UINT32 *) 0x01900024, (UINT32 *) 0x018c0024 }; static UINT32 ledMask[3]= {0x00000001, 0x00000001, 0x00000004}; #elif defined(I_AM_SLAVE_DSP) #if (defined(REV_B)||defined(REV_C)||defined(SIM)) static UINT32 *ledReg= (UINT32 *) 0x01900024, ledMask= 0x00000002; #elif (defined(REV_E)) static UINT32 *ledReg= (UINT32 *) 0x01b00008, ledMask= 0x00000080; #endif #endif #if defined(I_AM_MASTER_DSP) if (*mcbspPCR[led] & ledMask[led]) return ON; else return OFF; #elif defined(I_AM_SLAVE_DSP) if (*ledReg & ledMask) return OFF; /* port bit = 0 => led on. */ else return ON; #endif } #ifdef I_AM_MASTER_DSP UINT32 *linkBufferBase[2][48]; /************************************************************************************ * parseInmem : Parse the input memory, dumping the data it contains inside the input * link fields into memory. ************************************************************************************/ INT32 parseInmem(UINT8 inmem, UINT32 linkFieldHi, UINT32 linkFieldLow, UINT32 *inLinkBufferBase) { INT32 returnCode= SUCCESS; UINT32 *latchAdr, *strobeAdr; UINT8 i, j; static UINT8 first= TRUE; if (inLinkBufferBase == (UINT32 *) DEFAULT) { if (first) { first= FALSE; //dpsf allocate from heap for (i=0; i<2; ++i) { for (j=0; j<47; ++j) { linkBufferBase[i][j]= ((UINT32 *) 0x02e00000) +(0xc000)*i +0x400*j; } } } } else { for (i=0; i<2; ++i) { for (j=0; j<47; ++j) { linkBufferBase[i][j]= inLinkBufferBase +(0xc000)*i +0x400*j; } } } /* The inmems are read from the FPGA by strobing the input and then accessing the results from inside the latch addresses. The decoded data is put inside the appropriate link array. */ //latchAdr = (UINT32 *)(EVT_MEM_DATA_ADR); //strobeAdr = (UINT32 *)(EVT_MEM_STR_ADR); return returnCode; } /************************************************************************************ * chkSlaves : Loop over the slaves, ignoring the ones without the corresponding * bit set in slvBits. Check that they are still configured, and * optionally get the indicated status bit and return a status bitfield. The * routine returns a fatal error if one of the slaves is no longer configured (or * is invalid). If no slaves are defined, it returns a non-fatal error. The routine * is intended to be used as a comparitor when all is normal (ie no config errors); * the output bitfield should be checked against the input; if all slaves have the * bit set they will be equal. ************************************************************************************/ INT32 chkSlaves(UINT8 slvBits, UINT8 *slvOut, UINT32 reg, UINT8 regBit) { INT32 returnCode= SUCCESS, slaveStat; UINT8 slv; UINT32 t0; *slvOut= 0; if (slvBits == 0) { sprintf(genStr, "%s%s","WARNING: Routine is executing without " "any slaves defined.\n"); newError(&returnCode, NO_SLAVES_ERROR, ERROR_0, "chkSlaves", genStr, __FILE__, __LINE__); return returnCode; } for (slv= 0; slv< N_SDSP; ++slv) { t0= TIMER_getCount(timer1); if (!(slvBits & (1<>15) & 1) { //Pixel formatter code if (((fmtVer>>13) & 3) == 0) strcat(MHzStr, "40 MHz"); else if (((fmtVer>>13) & 3) == 1) strcat(MHzStr, "80 MHz"); else if (((fmtVer>>13) & 3) == 2) strcat(MHzStr, "160 MHz"); } else strcat(MHzStr, "40 MHz"); //strcat(MHzStr, " "); error= readRegister(EFB_CODE_VERSION, 16, 0, &efbVer); error= readRegister(RTR_CODE_VERSION, 16, 0, &rtrVer); error= readRegister(RRIF_CODE_VERSION, 16, 0, &rcfVer); sprintf(genStr, " %s%s%s\n %s%s %x %x %s\n %s%x %x\n %s%x %x\n %s%x %x\n", #if defined(SCT_ROD) "SCT ", #elif defined(PIXEL_ROD) "Pixel ", #endif "DSP code v", &versionStr[1], "Formatter code version ",( (((fmtVer>>15) & 1) == 0)? "SCT":"Pixel"), ((fmtVer>>8)&0x1f), (fmtVer & 0xff), MHzStr, "EFB code version ", ((efbVer>>8)&0x7f), (efbVer & 0xff), "Router code version ", ((rtrVer>>8)&0x7f), (rtrVer & 0xff), "Controller code version ", (rcfVer>>8), (rcfVer & 0xff) ); #elif defined(I_AM_SLAVE_DSP) #if defined(SCT_ROD) sprintf(genStr, "SCT DSP code v%s\n", &versionStr[1]); #elif defined(PIXEL_ROD) sprintf(genStr, "Pixel DSP code v%s\n", &versionStr[1]); #endif #endif newInformation(__FILE__, __LINE__, genStr); } /************************************************************************************ * memAlloc: Allocate a block of DSP memory from the indicated segment: * IDRAM/SRAM, MDSP/SDSP 6701: SDRAM, SDSP 6713: SDRAM0[2], SDRAM1[2]. * The multiple external memory spaces on the 6713 deal with the fact that for * this DSP, external memory in the two CE spaces is non-contiguous, and each is * divided into two halves of cachable & non-cachable memory. ************************************************************************************/