📄 universedmavme_dy4.c
字号:
temp = ( (0x03 << 22) | (0x02 << 16) | (0x00 << 14) | (0x01 << 12) | (0x01 << 8) | (0x00 << 7) ); *UNIVERSE_DCTL = LONGSWAP( temp ); sem_result = semGive( vmeDmaMutexSem ); if( sem_result != OK ) { logMsg ("sysVmeDmaClr: Cannot give Mutex semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } return( OK );}/****************************************************************************** sysVmeDmaSet - set parameters for the VMEbus DMA copy routine** This routine sets the parameters for the VME DMA transfer.** RETURNS: OK, or ERROR in case of a wrong parameter.** SEE ALSO: sysVmeDmaCopy(), sysVmeDmaGet(), sysVmeDmaLock()*/STATUS sysVmeDmaSet ( UINT8 type, /* type of parameter */ UINT32 value /* parameter */ ){ STATUS status = OK; STATUS sem_result; UINT32 dctl; UINT32 dgcs; /* * Check if the driver is initialised. */ if( !vmeDmaInitialised ) { if( universeDmaDebug ) logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 ); return( ERROR ); } /* * Ensure that only one task is in this critical section at * any one time. */ sem_result = semTake( vmeDmaMutexSem, WAIT_FOREVER ); if( sem_result != OK ) { logMsg ("sysVmeDmaSet: Cannot take Mutex semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } /* * Check to see if this task owns the lock (if it is set) or * that the there is no lock set. If not, give the semaphore back * and return an error. */ if( (vmeDmaLockId != taskIdSelf()) && (vmeDmaLockId != 0) ) { if( universeDmaDebug ) logMsg( "VMEBus DMA locked by another task!\n", 0, 0, 0, 0, 0, 0 ); sem_result = semGive( vmeDmaMutexSem ); if( sem_result != OK ) { logMsg ("sysVmeDmaSet: Cannot give Mutex semaphore\n", 0, 0, 0, 0, 0, 0); } return( ERROR ); } /* * Read the DMA control registers for potential modification below. */ dctl = LONGSWAP( *UNIVERSE_DCTL ); dgcs = LONGSWAP( *UNIVERSE_DGCS ); /* * Find out which portion of the registers we are being asked to modify. */ switch( type ) { /* * Set the VME data width to D08, D16, D32, D64, BLT, or MBLT. * (Bits 23..22) */ case UNIVERSE_VME_DMA_DCAP: switch( value ) { /* * Modes D08, D16, D32, and D64 all clear the VCT bit to disble * the xBLT modes. * * Mode BLT sets VCT and D32. * * Mode MBLT sets VCT and D64. */ case UNIVERSE_DCAP_D8: /* No bits set is D08 mode. */ dctl = (dctl & ~DCTL_DMA_VDW_MASK & ~DCTL_VCT_EN); break; case UNIVERSE_DCAP_D16: dctl = (dctl & ~DCTL_DMA_VDW_MASK & ~DCTL_VCT_EN) | (DCTL_VDW_16); /* << 22 remove because already done in universe.h */ break; case UNIVERSE_DCAP_D32: dctl = (dctl & ~DCTL_DMA_VDW_MASK & ~DCTL_VCT_EN) | (DCTL_VDW_32); /* << 22 remove because already done in universe.h */ break; case UNIVERSE_DCAP_D64: dctl = (dctl & ~DCTL_DMA_VDW_MASK & ~DCTL_VCT_EN) | (DCTL_VDW_64); /* << 22 remove because already done in universe.h */ break; case UNIVERSE_DCAP_BLT: dctl = (dctl & ~DCTL_DMA_VDW_MASK) | (DCTL_VDW_32) /* << 22 remove because already done in universe.h */ | DCTL_VCT_EN; break; case UNIVERSE_DCAP_MBLT: dctl = (dctl & ~DCTL_DMA_VDW_MASK) | (DCTL_VDW_64) /* << 22 remove because already done in universe.h */ | DCTL_VCT_EN; break; default: status = ERROR; break; } break; /* * Set the VME address mode. (Bits 18..16) */ case UNIVERSE_VME_DMA_ACAP: switch( value ) { case UNIVERSE_ACAP_A16: /* No bits set is A16 mode. */ dctl = (dctl & ~DCTL_DMA_VAS_MASK); break; case UNIVERSE_ACAP_A24: dctl = (dctl & ~DCTL_DMA_VAS_MASK) | (DCTL_VAS_A24); /* << 16 remove because already done in universe.h */ break; case UNIVERSE_ACAP_A32: dctl = (dctl & ~DCTL_DMA_VAS_MASK) | (DCTL_VAS_A32); /* << 16 remove because already done in universe.h */ break; default: status = ERROR; break; } break; /* * Set the User/Supervisor portion of the AM codes. (Bits 13..12) */ case UNIVERSE_VME_DMA_UCAP: if( (value != UNIVERSE_UCAP_USR) && (value != UNIVERSE_UCAP_SUP) ) status = ERROR; else dctl = (dctl & ~DCTL_DMA_AM_USR_MASK) | (value << 12); break; /* * Set the Data/Code portion of the AM codes. (Bits 15..14) */ case UNIVERSE_VME_DMA_PCAP: if( (value != PCAP_DATA) && (value != PCAP_PGM) ) status = ERROR; else dctl = (dctl & ~DCTL_DMA_AM_PGM_MASK) | (value << 14); break; /* * Set the VON portion of the register. This sets an effective upper * limit on the length of the VME blocks. If this is set to 0, this * limit is disabled. (Bits 23..20) */ case UNIVERSE_VME_DMA_BSIZE: /* Only values between 0 and 7 are allowed */ if( (value < 0) || (value > 7) ) status = ERROR; else dgcs = (dgcs & ~DGCS_DMA_SIZE_MASK) | (value << 20); break; /* * Set the VOFF portion of the register. This sets the "tenure" time * which the DMA engine will be forced to stay off the VME bus. At the * expiration of this timer, the DMA can re-arbitrate for the VME bus. * (Bits 19..16) */ case UNIVERSE_VME_DMA_DELAY: /* Only values between 0 and 10 are allowed */ if( (value < 0) || (value > 10) ) status = ERROR; else dgcs = (dgcs & ~DGCS_DMA_DELAY_MASK) | (value << 16); break; default: status = ERROR; break; } /* * Write the results of the above manipluations back DCTL and DGCS * registers. */ *UNIVERSE_DCTL = LONGSWAP( dctl ); *UNIVERSE_DGCS = LONGSWAP( dgcs ); /* * Give back the mutex to release other tasks to enter these critical * sections. */ sem_result = semGive( vmeDmaMutexSem ); if( sem_result != OK ) { logMsg ("sysVmeDmaSet: Cannot give Mutex semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } return( status );}/****************************************************************************** sysVmeDmaGet - get parameters of the VMEbus DMA copy function** This routine gets the parameters of the VME DMA transfer.** RETURNS: OK, or ERROR in case of a wrong parameter.** SEE ALSO: sysVmeDmaCopy(), sysVmeDmaSet()*/STATUS sysVmeDmaGet ( UINT8 type, /* type of parameter */ UINT32 * pval /* pointer to parameter */ ){ STATUS status = OK; UINT32 dctl; UINT32 dgcs; /* * Check if the driver is initialised. */ if( !vmeDmaInitialised ) { if( universeDmaDebug ) { logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 ); } return( ERROR ); } /* * Read DCTL and DGCS registers */ dctl = LONGSWAP( *UNIVERSE_DCTL ); dgcs = LONGSWAP( *UNIVERSE_DGCS ); /* * Find out which portion of the registers are being requested. */ switch( type ) { /* * Check which VME data width is set: D08, D16, D32, D64, BLT, * or MBLT. (Bits 23..22) */ case UNIVERSE_VME_DMA_DCAP: if( (dctl & DCTL_VCT_EN) == DCTL_VCT_EN ) { if( (dctl & DCTL_DMA_VDW_MASK) == DCTL_VDW_32 ) *pval = (UINT32)UNIVERSE_DCAP_BLT; else *pval = (UINT32)UNIVERSE_DCAP_MBLT; } else { if( (dctl & DCTL_DMA_VDW_MASK) == DCTL_VDW_64 ) *pval = (UINT32)UNIVERSE_DCAP_D64; else *pval = (UINT32)((dctl >> 22) & 0x3) + 1; } break; /* * Get the VME address mode. (Bits 18..16) */ case UNIVERSE_VME_DMA_ACAP: *pval = (UINT32)((dctl >> 16) & 0x7) + 1; break; /* * Get the User/Supervisor portion of the AM codes. (Bits 13..12) */ case UNIVERSE_VME_DMA_UCAP: *pval = (UINT32)(dctl >> 12) & 0x3; break; /* * Get the Data/Code portion of the AM codes. (Bits 15..14) */ case UNIVERSE_VME_DMA_PCAP: *pval = (UINT32)(dctl >> 14) & 0x3; break; /* * Get the VON portion of the register. This sets an effective upper * limit on the length of the VME blocks. If this is set to 0, this * limit is disabled. (Bits 23..20) */ case UNIVERSE_VME_DMA_BSIZE: *pval = (UINT32)(dgcs >> 20) & 0xf; break; /* * Get the VOFF portion of the register. This sets the "tenure" time * which the DMA engine will be forced to stay off the VME bus. At the * expiration of this timer, the DMA can re-arbitrate for the VME bus. * (Bits 19..16) */ case UNIVERSE_VME_DMA_DELAY: *pval = (UINT32)(dgcs >> 16) & 0xf; break; default: status = ERROR; break; } return( status );}/****************************************************************************** sysVmeDmaLock - lock VME DMA transfer operation** This routine locks the VME DMA transfer operation for the calling task.* The calling task is the only task that can use the functions sysVmeDmaSet(),* sysVmeDmaCopy(), or sysVmeDmaClr() functions until sysVmeDmaUnlock() is* called.** RETURNS: OK, or ERROR if already locked.** SEE ALSO: sysVmeDmaUnlock(), sysVmeDmaSet(), sysVmeDmaCopy(), sysVmeDmaClr()*/STATUS sysVmeDmaLock (void){ STATUS status; STATUS sem_result; /* * Check if the driver is initialised. */ if( !vmeDmaInitialised ) { if( universeDmaDebug ) { logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 ); } return( ERROR ); } /* * Ensure that only one task is in this critical section at * any one time. */ sem_result = semTake( vmeDmaMutexSem, WAIT_FOREVER ); if( sem_result != OK ) { logMsg ("sysVmeDmaLock: Cannot take Mutex semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } /* * See if the lock is free. This is signified by the lock being 0. If * so, set the lock equal to the current task ID. */ if( vmeDmaLockId == 0 ) { /* set vmeDmaLock to the current task ID */ vmeDmaLockId = taskIdSelf(); status = OK; } /* * If it is not free, declare an error (and display an warning if the * debug flag is turned on). */ else { status = ERROR; if( universeDmaDebug ) logMsg( "VMEBus DMA already locked!\n", 0, 0, 0, 0, 0, 0 ); } /* * Give back the mutex to release other tasks to enter these critical * sections.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -