⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 universe.c

📁 VxWorks下 Mv2100的BSP源码
💻 C
📖 第 1 页 / 共 4 页
字号:
* * NOTE: This low-level driver is strictly non-sharable; however,* it contains no guards to prevent multiple tasks from calling* it simultaneously.  It assumes that the application layer will* provide atomic access to this driver through the use of a* semaphore or similar guards.** In addition, the internals of this driver only operates in a* non-interrupt (polled) mode; it uses a busy loop to sample the* DMA transfer status.  This implies that the calling task will* wait until the DMA transfer has terminated.  As a precaution,* it is recommended by the Tundra User's Manual that the calling* task set up a background timer to prevent an infinite wait* caused by a system problem.  Also, tasks transferring large* blocks of data should lower their priority level to allow other* tasks to run, and tasks transferring small blocks of data* should use bcopy() instead of calling this driver.** RETURNS: OK*/STATUS sysVmeDmaInit    (    void    )    {    /* Configure the DMA Transfer Control register */    UNIV_OUT_LONG(UNIVERSE_DCTL, (VME_DMA_XFER_TYPE  |				  VME_DMA_ADDR_SPACE |				  VME_DMA_DATA_TYPE  |				  VME_DMA_USER_TYPE  |				  DCTL_LD64EN ));    sysVmeDmaReady = TRUE;    return (OK);    }/******************************************************************************** sysVmeDmaCnfgGet - Get DMA transfer configuration parameters** This routine will get the DMA transfer parameters.** RETURNS: OK or ERROR*/STATUS sysVmeDmaCnfgGet    (    UINT32 *xferType,	/* output: Ptr to VMEbus data transfer type	*/			/* Valid range:					*/			/* (DCTL_VDW_8  | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_16 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_32 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_64 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_32 | DCTL_VCT_BLK)	       ** BLT  	*/			/* (DCTL_VDW_64 | DCTL_VCT_BLK)	       ** MBLT 	*/    UINT32 *addrSpace,	/* output: Ptr to VMEbus Address Space type	*/			/* Valid range:					*/			/* DCTL_VAS_A16					*/			/* DCTL_VAS_A24					*/			/* DCTL_VAS_A32					*/    UINT32 *dataType,	/* output: Ptr to Program/Data AM Code		*/			/* Valid range:					*/			/* DCTL_PGM_DATA				*/			/* DCTL_PGM_PRGM				*/    UINT32 *userType	/* output: Ptr to Supervisor/User AM Code	*/			/* Valid range:					*/			/* DCTL_SUPER_USER				*/			/* DCTL_SUPER_SUP				*/    )    {    UINT32  dctlReg;    if (!sysVmeDmaReady)	{	return (ERROR);	}    /* Get contents of DMA Transfer Control register */    UNIV_IN_LONG(UNIVERSE_DCTL, &dctlReg);    /* Extract the VMEbus data transfer type */    *xferType = (dctlReg & (DCTL_VDW_MSK | DCTL_VCT_MSK));    /* Extract the VMEbus Address Space type */    *addrSpace = (dctlReg & DCTL_VAS_MSK);    /* Extract the Program/Data AM Code */    *dataType = (dctlReg & DCTL_PGM_MSK);    /* Extract the Supervisor/User AM Code */    *userType = (dctlReg & DCTL_SUPER_MSK);    return (OK);    }/******************************************************************************** sysVmeDmaCnfgSet -  Set DMA transfer configuration parameters** This routine will configure the DMA transfer parameters.** RETURNS: OK or ERROR*/STATUS sysVmeDmaCnfgSet    (    UINT32 xferType,	/* input: VMEbus data transfer type		*/			/* Valid range:					*/			/* (DCTL_VDW_8  | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_16 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_32 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_64 | DCTL_VCT_SINGLE)		*/			/* (DCTL_VDW_32 | DCTL_VCT_BLK)	        ** BLT  */			/* (DCTL_VDW_64 | DCTL_VCT_BLK)	        ** MBLT */    UINT32 addrSpace,	/* input: VMEbus Address Space type		*/			/* Valid range:					*/			/* DCTL_VAS_A16					*/			/* DCTL_VAS_A24					*/			/* DCTL_VAS_A32					*/    UINT32 dataType,	/* imput: Ptr to Program/Data AM Code		*/			/* Valid range:					*/			/* DCTL_PGM_DATA				*/			/* DCTL_PGM_PRGM				*/    UINT32 userType	/* input: Supervisor/User AM Code		*/			/* Valid range:					*/			/* DCTL_SUPER_USER				*/			/* DCTL_SUPER_SUP				*/    )    {    UINT32  dctlReg;    if (!sysVmeDmaReady)	{	return (ERROR);	}    /* Get contents of DMA Transfer Control register */    UNIV_IN_LONG(UNIVERSE_DCTL, &dctlReg);    /* Setup the VMEbus data transfer type */    dctlReg &= ~(DCTL_VDW_MSK | DCTL_VCT_MSK);    dctlReg |= (xferType & (DCTL_VDW_MSK | DCTL_VCT_MSK));    /* Setup the VMEbus Address Space type */    dctlReg &= ~(DCTL_VAS_MSK);    dctlReg |= (addrSpace & DCTL_VAS_MSK);    /* Setup the Program/Data AM Code */    dctlReg &= ~(DCTL_PGM_MSK);    dctlReg |= (dataType & DCTL_PGM_MSK);    /* Setup the Supervisor/User AM Code */    dctlReg &= ~(DCTL_SUPER_MSK);    dctlReg |= (userType & DCTL_SUPER_MSK);    /* Update contents of DMA Transfer Control register */    UNIV_OUT_LONG(UNIVERSE_DCTL, dctlReg);    return (OK);    }/******************************************************************************** sysVmeDmaStatusGet - Get DMA transfer Status** This routine will return the status of the DMA transfer.** RETURNS: OK or ERROR*/STATUS sysVmeDmaStatusGet    (    UINT32  *transferStatus	/* State of DMA transfer defined as	*/				/* DGCS register status bits		*/				/* DGCS_ACT  | DGCS_STOP | DGCS_HALT |	*/				/* DGCS_DONE | DGCS_LERR | DGCS_VERR |	*/				/* DGCS_P_ERR				*/    )    {    UINT32  dgcsReg;    if (!sysVmeDmaReady)	{	return (ERROR);	}    /* Get contents of DMA General Control/Status register */    UNIV_IN_LONG(UNIVERSE_DGCS, &dgcsReg);    /* Return the status of the DMA transfer */    *transferStatus = (dgcsReg & DGCS_STATUS_MSK);    return (OK);    }/******************************************************************************** sysVmeDmaL2VCopy - Copy data from local memory to VMEbus memory** This routine copies data from local memory to VMEbus memory using* the Universe's DMA engine.** NOTE: This routine assumes that the DMA transfer configuration* parameters have been previously set up either at driver init time* (sysVmeDmaInit()) with the default parameters in config.h or* dynamically by calling sysVmeDmaCnfgSet().** .CS* RETURNS: OK,*	   ERROR - driver not initialized or invalid argument,*	   DGCS_LERR - PCI Bus Error,*	   DGCS_VERR - VMEbus Error,*          or*	   DGCS_P_ERR - Protocol Error* .CE*/STATUS sysVmeDmaL2VCopy    (    UCHAR  *localAddr,		/* Local Address as seen by the CPU */    UCHAR  *localVmeAddr,	/* VMEbus Address as seen by the CPU */    UINT32  nbytes    )    {    return (sysVmeDmaCopy(localAddr,			  localVmeAddr,			  nbytes,			  (UINT32)DCTL_L2V_PCI_VME));    }/******************************************************************************** sysVmeDmaV2LCopy - Copy data from VMEbus memory to local memory** This routine copies data from VMEbus memory to local memory using* the Universe's DMA engine.** NOTE: This routine assumes that the DMA transfer configuration* parameters have been previously set up either at driver init time* (sysVmeDmaInit()) with the default parameters in config.h or* dynamically by calling sysVmeDmaCnfgSet().** .CS* RETURNS: OK,*	   ERROR - driver not initialized or invalid argument,*	   DGCS_LERR - PCI Bus Error,*	   DGCS_VERR - VMEbus Error,*          or*	   DGCS_P_ERR - Protocol Error* .CE*/STATUS sysVmeDmaV2LCopy    (    UCHAR  *localVmeAddr,	/* VMEbus Address as seen by the CPU */    UCHAR  *localAddr,		/* Local Address as seen by the CPU */    UINT32  nbytes    )    {    return (sysVmeDmaCopy(localAddr,			  localVmeAddr,			  nbytes,			  (UINT32)DCTL_L2V_VME_PCI));    }/******************************************************************************** sysVmeDmaCopy - Copy data between local and VMEbus memory** This routine copies data between local and VMEbus memory using* the Universe's DMA engine.  In addition to the parameters passed in,* this routine uses the macros VME_DMA_MAX_BURST and VME_DMA_MIN_TIME_OFF_BUS* defined in config.h to set up VON and VOFF, respectfully.** NOTE: This routine assumes that the DMA transfer configuration* parameters have been previously set up either at driver init time* (sysVmeDmaInit()) with the default parameters in config.h or* dynamically by calling sysVmeDmaCnfgSet().** The sampling rate to determine the DMA transfer status* will directly affect the throughput of the DMA transfer.** .CS* RETURNS: OK,*	   ERROR - driver not initialized or invalid argument,*	   DGCS_LERR - PCI Bus Error,*	   DGCS_VERR - VMEbus Error,*          or*	   DGCS_P_ERR - Protocol Error* .CE*/LOCAL STATUS sysVmeDmaCopy    (    UCHAR  *localAddr,		/* Local Address as seen by the CPU */    UCHAR  *localVmeAddr,	/* VMEbus Address as seen by the CPU */    UINT32  nbytes,		/* number of bytes to copy: */				/*	max = DTBC_VALID_BITS_MASK */    UINT32  direction	/* Copy direction: DCTL_L2V_PCI_VME, DCTL_L2V_VME_PCI */    )    {    UCHAR  *pciAddr;    UCHAR  *vmeAddr;    UINT32  dctlReg;    UINT32  dgcsReg;    if (!sysVmeDmaReady)	{	return (ERROR);	}    /* Check addresses for 8-byte alignment to each other */    if (((UINT32)localAddr & 0x7) != ((UINT32)localVmeAddr & 0x7))        {	return (ERROR);	}    /* Check for too large a transfer byte count */    if (nbytes > DTBC_VALID_BITS_MASK)	{	return (ERROR);	}    /*     * Clearing the chain bit and setting the GO bit at the same time     * does not work.  So, clearing the chain bit and setting up VON     * and VOFF is done before setting up the source and destination     * register as called out in the Universe manual.     */    UNIV_IN_LONG(UNIVERSE_DGCS, &dgcsReg);    dgcsReg &= ~(DGCS_CHAIN_MSK | DGCS_VON_MSK | DGCS_VOFF_MSK);    dgcsReg |= (VME_DMA_MAX_BURST | VME_DMA_MIN_TIME_OFF_BUS);    UNIV_OUT_LONG(UNIVERSE_DGCS, dgcsReg);    /* Setup transfer direction */    UNIV_IN_LONG(UNIVERSE_DCTL, &dctlReg);    dctlReg &= ~(DCTL_L2V_MSK);    dctlReg |= (direction & DCTL_L2V_MSK);    UNIV_OUT_LONG(UNIVERSE_DCTL, dctlReg);    /*     * Convert the VME address as seen by the CPU to a     * VMEbus address as seen on the VMEbus, and store     * it in the DMA engine's VMEbus address register.     */    switch (dctlReg & DCTL_VAS_MSK)	{	case DCTL_VAS_A32:            vmeAddr = (UCHAR *)((UINT32)localVmeAddr -				(UINT32)VME_A32_MSTR_LOCAL +				(UINT32)VME_A32_MSTR_BUS);            UNIV_OUT_LONG(UNIVERSE_DVA, vmeAddr);	    break;	case DCTL_VAS_A24:            vmeAddr = (UCHAR *)((UINT32)localVmeAddr -				(UINT32)VME_A24_MSTR_LOCAL +				(UINT32)VME_A24_MSTR_BUS);            UNIV_OUT_LONG(UNIVERSE_DVA, vmeAddr);	    break;	case DCTL_VAS_A16:            vmeAddr = (UCHAR *)((UINT32)localVmeAddr -				(UINT32)VME_A16_MSTR_LOCAL +				(UINT32)VME_A16_MSTR_BUS);            UNIV_OUT_LONG(UNIVERSE_DVA, vmeAddr);	    break;	default:	    return (ERROR);	}    /*     * Convert the local address to a PCI address as seen     * on the PCI Bus, and store it in the DMA engine's     * PCI Bus address register.     */    pciAddr = (UCHAR *)((UINT32)localAddr + (UINT32)PCI_SLV_MEM_BUS);    UNIV_OUT_LONG(UNIVERSE_DLA, pciAddr);    /* Configure DMA engine's byte count */    UNIV_OUT_LONG(UNIVERSE_DTBC, nbytes);    /* Start transfer by clearing status and setting GO bit */    dgcsReg &= ~(DGCS_STATUS_MSK);    dgcsReg |= DGCS_GO;    UNIV_OUT_LONG(UNIVERSE_DGCS, dgcsReg);    /* Wait for transfer to terminate */    UNIV_IN_LONG(UNIVERSE_DGCS, &dgcsReg);    while (dgcsReg & DGCS_ACT)	{	sysUsDelay(25);	UNIV_IN_LONG(UNIVERSE_DGCS, &dgcsReg);	}    if (dgcsReg & DGCS_DONE)	{	return (OK);	}    else	{        return (dgcsReg & (DGCS_LERR | DGCS_VERR | DGCS_P_ERR));	}    }#endif	/* INCLUDE_VME_DMA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -