📄 universedmavme_dy4.c
字号:
/* ------------------------------------------------------------------------ *\** universeDmaVme_dy4.c - Tundra UNIVERSE II PCI-VME DMA interface library **** ------------------------------------------------------------------------ **** **** DY 4 Universe II VxWorks demonstration DMA driver for SVME-179 **** **** Copyright (C) 2001 **** DY 4 Systems, Inc. **** **** Project: EB955 **** **** ------------------------------------------------------------------------ **** **** Prepared by Applied Microelectronics Incorporated **** **** ------------------------------------------------------------------------ **** **** DESCRIPTION **** This library contains routines which relate to the VMEbus functions of **** the Universe VMEbus chip. **** **** The functions addressed here include: **** **** - VME DMA functions: **** - copy blocks via DMA **** - lock DMA operation **** - initialize DMA **** - set/get DMA parameters **** **** ------------------------------------------------------------------------ **** **** Author: Neil.Hamilton@appliedmicro.ns.ca **** **** Language: C **** **\* ------------------------------------------------------------------------ *//*01a,08jun01.dy4 tis updated to support all valid Voff values for both UniverseIIand Universe IIB PT#522 *//* ------------------------------------------------------------------------ *\ Filename: $Source: D:\tornadoppc\target\config\svme179\src\drv\vme\universeDmaVme.c Current Revision: $Revision: 1.17 $ Last Updated: $Date: 1999/06/30 14:02:21 $ Last Modified by: $Author: DUD Informission $ Currently Locked by: $Locker: $ Change History: $Log: universeDmaVme.c,v $ Revision 1.17 1999/06/30 14:02:21 DUD Informission - Transport all functions to SVME-179. Revision 1.16 1999/01/28 15:07:21 Neil.Hamilton - Changed name of default ISR to async_sysVmeDmaExampleISR() to highlight its typical use. Revision 1.15 1999/01/27 15:53:10 Neil.Hamilton - Removed sysVmeDmaReleaseMutex() as this operation is now handled within the sysVmeDmaIsAsyncDone() function. Revision 1.14 1999/01/26 19:09:24 Neil.Hamilton - Added error checking on ALL semaphore activity!!!! Revision 1.13 1999/01/26 18:53:14 Neil.Hamilton - Mutex semaphores not allowed to be given or taken in ISRs. Provided support functions to 1) examine the binary semaphore indicating DMA ISR done, and 2) release mutex semaphore when done with async functions. Revision 1.12 1999/01/26 13:50:54 Neil.Hamilton - Added support for non-blocking DMA transfers. Still having problems with semaphores. Revision 1.11 1999/01/20 19:04:50 Neil.Hamilton - As delivered to DY4 15Jan1999. Revision 1.10 1999/01/15 01:51:01 Neil.Hamilton - Repaired DCAP mode in sysVmeDmaSet and Get (bad masks). - Heavily commented and re-arranged some code for clarity. Revision 1.9 1999/01/14 21:17:04 Neil.Hamilton - Corrected several latent bugs from origial code: - No check if driver initialized before attempting lock and unlock. This meant that the mutexes could be called before being created. - Several error returns from copy did not release the mutex. - Split out the initialization of the Universe DMA registers from the main initialization code. This function (sysVmeDmaClr) can now be called independantly. Revision 1.8 1999/01/13 19:23:23 Neil.Hamilton - Corrected DMA initialization sequence. Was asking for AM code User 1 and second '178 did not like this. Changed to supervisor data code. Revision 1.7 1999/01/12 20:18:38 Neil.Hamilton - Removed double ;; in function. Revision 1.6 1999/01/12 20:06:10 Neil.Hamilton - Modified variable names. Revision 1.5 1999/01/10 17:12:28 Neil.Hamilton - Fixed typo in DMA copy (UNIT32 instead of UINT32). Revision 1.4 1999/01/10 16:26:05 Neil.Hamilton - Change DMA block copy size from int to UINT32 to prevent it from going negative. Revision 1.3 1999/01/08 01:41:18 Neil.Hamilton - Added functions to get and set debug flag state. Revision 1.1 1999/01/07 18:40:12 Neil.Hamilton Initial revision\* ------------------------------------------------------------------------ *//* * NOTE: This source file is included via the modified universe.c file. *//* ------------------------------------------------------------------------ *//* * Define the maximum amount of time to wait for the DMA transaction to * complete. If the transaction is not complete within this time, the * copy function bombs out with an error. */#define MAX_SECONDS_FOR_DMA_COMPLETION 3 /* seconds *//* globals */BOOL universeDmaDebug = FALSE; /* enable debugging messages *//* locals */LOCAL BOOL vmeDmaInitialised = FALSE;LOCAL SEM_ID vmeDmaSyncSem;LOCAL SEM_ID vmeDmaMutexSem;LOCAL int vmeDmaLockId;LOCAL FUNCPTR sysVmeDmaRoutine = NULL; /* Pointer to the DMA Handler */LOCAL STATUS sysVmeDmaLastAsyncStatus = ERROR; /* last async status */LOCAL void sysVmeDmaIntr(UINT32);extern UINT32 sysUNIVERSE_LINT_EN;extern UINT32 sysVmeIntrPreemptCnt;/****************************************************************************** sysVmeDmaSetDebugState - set the state of the debug flag** This routine sets the state of the debug flag.** RETURNS: state of universeDmaDebug** NOMANUAL*/BOOL sysVmeDmaSetDebugState ( BOOL newDebugState ){ universeDmaDebug = newDebugState; return( universeDmaDebug );}/****************************************************************************** sysVmeDmaGetDebugState - get the state of the debug flag** This routine gets the state of the debug flag.** RETURNS: state of universeDmaDebug** NOMANUAL*/BOOL sysVmeDmaGetDebugState ( void ){ return( universeDmaDebug );}/***************************************************************************** sysVmeDmaInit - initialize the VMEbus DMA copy function** This routine initializes the Universe II ASIC for DMA transfers. It is* normally only called from sysUniverseHwInit2(). It sets up the various* semaphores required by the code sections and initializes the Universe II* DMA engine registers to a known state via the sysVmeDmaClr() function.** If function is called subsequently, it will have the same effect as calling* sysVmeDmaClr() directly. (If universeDmaDebug is set to TRUE, the function* will report a warning about the multiple invocations.)** RETURNS: OK, or Error** SEE ALSO: sysVmeDmaClr()*/STATUS sysVmeDmaInit (void){ /* DEBUG */ /* logMsg( "DMA being initialized\n", 0, 0, 0, 0, 0, 0 ); */ /* * Check if driver is already initialised. */ if( vmeDmaInitialised ) { if( universeDmaDebug ) { logMsg( "VMEBus DMA already initialized!\n", 0, 0, 0, 0, 0, 0 ); } } else { /* * Create semaphore for signaling when DMA interrupt has been * processed. This will indicate that the DMA has completed * something - good or bad. */ if( (vmeDmaSyncSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY)) == NULL ) { logMsg ("sysVmeDmaInit: Cannot create vmeDmaSyncSem semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } /* * Create a semaphore for locking critical sections of code. If this * semaphore is taken, another task is already running in the critcal * code sections. */ if( (vmeDmaMutexSem = semMCreate (SEM_Q_PRIORITY)) == NULL ) { logMsg ("sysVmeDmaInit: Cannot create vmeDmaMutexSem semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } /* Install the actual VME DMA handler in the interrupt table: */ sysVmeIntConnect (INUM_TO_IVEC (UNIV_DMA_INT_VEC), sysVmeDmaIntr, 0); } /* * Flag that we have initailized the DMA driver. This must be set before * we "clear" the registers since the sysVmeDmaClr() function expects * the semaphores to be initialized before it executes. This flag tells * the function that the semaphores have been created. */ vmeDmaInitialised = TRUE; /* * Set the DMA registers to a known good state. */ sysVmeDmaClr(); /* DEBUG */ /* logMsg( "DMA cleared\n", 0, 0, 0, 0, 0, 0 ); */ return( OK );}/***************************************************************************** sysVmeDmaIntr - VME DMA interrupt handler** This routine is the interrupt handler for the VME DMA of the Universe chip.** RETURNS: N/A.** NOMANUAL*/LOCAL void sysVmeDmaIntr(UINT32 notused){ STATUS sem_result; /* * Check to see if the task is using the non-blocking DMA * functions. If non-blocking functions are being used, * the sysVmeDmaRoutine pointer will be something other * than NULL. Therefore call user handler if this is detected. * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * NOTE NOTE NOTE: The mixed use of blocking and non-blocking * DMA functions is NOT RECOMMENDED. If this is required, the * task using non-block calls MUST DISCONNECT the sysVmeDmaRoutine * after DMA use by connecting a NULL vector using the * sysVmeDmaConnect() function. This MUST be done BEFORE a * blocking call is used. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * NOTE NOTE NOTE: Since the user function is executing at * interrupt level, the user should be aware that this function * might have a significant impact on interrupt performance. It * is advisable to execute as little as possible in the user * function. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * */ if(sysVmeDmaRoutine) { /* Vector to the interrupt rountine specified by the user. : */ (* sysVmeDmaRoutine) (); } /* Signal that the interrupt has been seen by releasing the binary synchronizing semaphore: */ sem_result = semGive(vmeDmaSyncSem); if(sem_result != OK) { logMsg("sysUniverseIntr: Cannot give vmeDmaSyncSem semaphore\n", 0, 0, 0, 0, 0, 0); }}/***************************************************************************** sysVmeDmaClr - Set the DMA control registers to a known good state.** This routine sets up the Universe II DMA engine for default operation.* The current defaults are as follows:* - LINT_EN (0x300) DMA = 1 Enable DMA interrupt* - DCTL (0x200) VDW = 11 64-bit data path* VAS = 010 A32 address space* PGM = 00 Data AM codes* SUPER = 01 Supervisor AM codes* VCT = 1 BLT enabled* LD64EN = 0 64-bit PCI disabled* - DGCS (0x220) CHAIN = 0 Direct mode* VON = 000 max block size* VOFF = 0000 immediate tenure* INT_DONE = 1 Interrupt when done* INT_LERR = 1 Interrupt when PCI error* INT_VERR = 1 Interrupt when VME error* INT_P_ERR = 1 Interrupt when Master enable error** RETURNS: OK, or Error** SEE ALSO: sysVmeDmaInit()*/STATUS sysVmeDmaClr (void){ UINT32 temp; STATUS sem_result; UINT32 lockKey; /* * Check if not 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 ("sysVmeDmaClr: Cannot take Mutex semaphore\n", 0, 0, 0, 0, 0, 0); return( ERROR ); } /* * Enable the DMA interrupts. */ lockKey = intLock(); /* Lock the interrupts before changing the Masks */ /* Modify the Mask register mirror */ sysUNIVERSE_LINT_EN |= LONGSWAP(LINT_EN_DMA); /* If not called from a VME interrupt modify the actual register */ if (sysVmeIntrPreemptCnt ==0) { /* enable the interrupt */ *UNIVERSE_LINT_EN |= LONGSWAP(LINT_EN_DMA); } intUnlock(lockKey); /* * Set parameters of general control/status reg. The default * is (binary): * CHAIN (bit 27) = 0 - direct mode * VON (bits 22..20) = 000 - VON "until done" * VOFF (bits 19..16) = 0000 - VOFF 0us * INT_DONE (bit 3) = 1 - Interrupt when Done * INT_LERR (bit 2) = 1 - Interrupt when PCI error * INT_VERR (bit 1) = 1 - Interrupt when VME error * INT_P_ERR (bit 0) = 1 - Interrupt when Master Enable error */ temp = ( (0x00 << 27) | (0x00 << 20) | (0x00 << 16) | (0x01 << 3) | (0x01 << 2) | (0x01 << 1) | (0x01 << 0) ); *UNIVERSE_DGCS = LONGSWAP( temp ); /* * Set parameters of transfer control reg. The default is (binary): * VDW (bits 23..22) = 11 - 64-bit data path * VAS (bits 18..16) = 010 - A32 address space * PGM (bits 15..14) = 00 - Data AM code * SUPER (bits 13..12) = 01 - Supervisor AM code * VCT (bit 8) = 1 - BLT enabled * LD64EN (bit 7) = 0 - 64-bit PCI disabled */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -