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

📄 isadma.c

📁 WINDRIVER MCP750 BSP
💻 C
字号:
/* isaDma.c - DMA Controller Device (I8237) Utilities/Support Module *//* Copyright 1984-2001 Wind River Systems, Inc. *//* Copyright 1996,1997,1998 Motorola, Inc., All Rights Reserved *//*modification history--------------------01d,16sep01,dat  Use of WRS_ASM macro01c,15apr99,srr  Changed to WRS address space naming convention.01b,15apr98,dat  added INCLUDE_ISADMA01a,12dec97,rbb  created by Motorola.*//*DESCRIPTIONThis module contains routines that support ISA DMA transfers.  The routinesprovided will initialize the DMA configuration, start and stop DMA transfersand return the status of an ISA DMA transfer.This module is normally included as a source module.  The macro INCLUDE_ISADMAmust be defined if any code is to be compiled.Notes:1. These routines assume that a dual i8237 DMA controller device   is present (e.g., I82378ZB, W83C553F).*//* includes */#include "vxWorks.h"#include "i8237.h"#include "config.h"#ifdef INCLUDE_ISADMA	/* do nothing if not defined *//* defines */#ifndef EIEIO_SYNC# define EIEIO_SYNC  _WRS_ASM (" eieio; sync")#endif  /* EIEIO_SYNC */#define I8237_BASE_ADDRESS	ISA_MSTR_IO_LOCAL#define PCIV_PCIMPU_RAM_OFFSET	PCI_SLV_MEM_BUS/* typedefs *//* globals *//* forward declarations */extern void isaDmaInit();	/* initialize DMA (global configuration) */extern void isaDmaStart();	/* initialize DMA channel for transfer */extern void isaDmaStop();	/* disable DMA channel */extern UINT isaDmaStatus();	/* query DMA channel for transfer status *//* externals *//********************************************************************************* isaDmaInit - DMA controller initialization** This function's purpose is to initialize the dual DMA controller* device to a sane state.  This initialization is from a global* configuration standpoint, and needs only to be performed once.** RETURNS: N/A*/void isaDmaInit (void)    {    register UINT channel;    register UINT rvalue1, rvalue2;    register I8237_DMA1 *pDma1;    register I8237_DMA2 *pDma2;    /* setup pointers to the DMA controller devices */    pDma1 = (I8237_DMA1 *)(I8237_BASE_ADDRESS + I8237_DMA1_OFFSET);    pDma2 = (I8237_DMA2 *)(I8237_BASE_ADDRESS + I8237_DMA2_OFFSET);    /* perform a H/W reset of the devices */    pDma1->mc = 0x00;     EIEIO_SYNC;    pDma2->mc = 0x00;     EIEIO_SYNC;    /* initialize all channels to a sane state */    for (channel = 0; channel < 4; channel++) 	{        /*         * dependent upon the channel, setup the specifics:         *         * demand         * address-increment         * autoinitialize-disable         * read-transfer         */	switch (channel) 	    {	    case 0:		rvalue1 =		(I8237_MODE_TM_DEMAND|I8237_MODE_CH0SEL|I8237_MODE_TT_READ);		rvalue2 =		(I8237_MODE_TM_CASCADE|I8237_MODE_CH0SEL);		break;	    case 1:	        rvalue1 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH1SEL|I8237_MODE_TT_READ);	        rvalue2 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH1SEL|I8237_MODE_TT_READ);	        break;	    case 2:	        rvalue1 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH2SEL|I8237_MODE_TT_READ);	        rvalue2 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH2SEL|I8237_MODE_TT_READ);	        break;	    case 3:	        rvalue1 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH2SEL|I8237_MODE_TT_READ);	        rvalue2 =	        (I8237_MODE_TM_DEMAND|I8237_MODE_CH2SEL|I8237_MODE_TT_READ);	        break;	    default:	        rvalue1 = 0x00;	        rvalue2 = 0x00;	        break;	    }	/* write to write mode registers */	pDma1->wm = rvalue1; 	EIEIO_SYNC;	pDma2->wm = rvalue2; 	EIEIO_SYNC;	}    /* enable all channels */    pDma1->cm = 0x00;     EIEIO_SYNC;    pDma2->cm = 0x00;     EIEIO_SYNC;   /*    * initialize the global DMA configuration    *    * DACK# active low    * DREQ active high    * fixed priority    * channel group enable    */    pDma1->cs = 0x00;     EIEIO_SYNC;    pDma2->cs = 0x00;     EIEIO_SYNC;    }/********************************************************************************* isaDmaStart - start DMA transfer** This function's purpose is to initialize the specified DMA* channel for a DMA transfer.** RETURNS: N/A*/void isaDmaStart    (    register UINT dmaChannelNumber,		/* DMA channel number (0 - 7) */    register UINT dmaTransferMode,		/* DMA transfer mode */    register UINT dmaTransferType,		/* DMA transfer type */    register UINT address,			/* address */    register UINT nBytes			/* number of bytes */    )    {    register UINT rvalue;    register UINT channelNumber;    register I8237_DMA1 *pDma1;    register I8237_DMA2 *pDma2;    register I8237_PAGE *pPage;    register I8237_HIGHPAGE *pHigh;    /* setup pointers to the DMA controller devices */        pDma1 = (I8237_DMA1 *)(I8237_BASE_ADDRESS + I8237_DMA1_OFFSET);    pDma2 = (I8237_DMA2 *)(I8237_BASE_ADDRESS + I8237_DMA2_OFFSET);    pPage = (I8237_PAGE *)(I8237_BASE_ADDRESS + I8237_PAGE_OFFSET);    pHigh = (I8237_HIGHPAGE *)(I8237_BASE_ADDRESS + I8237_HIGH_OFFSET);    /*     * create DMA address (PCI/ISA to system memory)     * create physical i8237 channel number     * number of programmed bytes is less one than the transfer     */    address |= PCIV_PCIMPU_RAM_OFFSET;    channelNumber = dmaChannelNumber & 0x3;    nBytes--;    /*     * disable channel for DMA transfer initialization     * setup the address of the transfer     */    if (dmaChannelNumber < 4) 	{        /* disable the selected channel */        pDma1->wsmb = (I8237_WSMB_CHMASKSEL | channelNumber); 	EIEIO_SYNC;        /*         * initialize the address (A07-A00) of the transfer         * initialize the address (A15-A08) of the transfer         */        pDma1->cbp = 0x00; 	EIEIO_SYNC;        pDma1->bac[channelNumber].bca = (UCHAR)(address >> 0); 	EIEIO_SYNC;        pDma1->bac[channelNumber].bca = (UCHAR)(address >> 8); 	EIEIO_SYNC;        /* initialize the count of the transfer */        pDma1->cbp = 0x00; 	EIEIO_SYNC;        pDma1->bac[channelNumber].bcc = (UCHAR)(nBytes >> 0); 	EIEIO_SYNC;        pDma1->bac[channelNumber].bcc = (UCHAR)(nBytes >> 8); 	EIEIO_SYNC;	}     else 	{        /* disable the selected channel */        pDma2->wsmb = (I8237_WSMB_CHMASKSEL | channelNumber); 	EIEIO_SYNC;        /*         * initialize the address (A07-A00) of the transfer         * initialize the address (A15-A08) of the transfer         */        pDma2->cbp = 0x00; 	EIEIO_SYNC;        pDma2->bac[channelNumber].bca = (UCHAR)(address >> 0); 	EIEIO_SYNC;        pDma2->bac[channelNumber].bca = (UCHAR)(address >> 8); 	EIEIO_SYNC;        /* initialize the count of the transfer */        pDma2->cbp = 0x00; 	EIEIO_SYNC;        pDma2->bac[channelNumber].bcc = (UCHAR)(nBytes >> 0); 	EIEIO_SYNC;        pDma2->bac[channelNumber].bcc = (UCHAR)(nBytes >> 8); 	EIEIO_SYNC;	}    /*     * setup the address (A23-A16) of the transfer     * setup the address (A31-A24) of the transfer     */    switch (dmaChannelNumber) 	{	case 0:	    pPage->p_ch0 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch0 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	    case 1:	    pPage->p_ch1 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch1 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	case 2:	    pPage->p_ch2 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch2 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	case 3:	    pPage->p_ch3 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch3 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	case 5:	    pPage->p_ch5 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch5 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	case 6:	    pPage->p_ch6 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch6 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	case 7:	    pPage->p_ch7 = (UCHAR)(address >> 16); 	    EIEIO_SYNC;	    pHigh->p_ch7 = (UCHAR)(address >> 24); 	    EIEIO_SYNC;	    break;	}    /* initialize the transfer specifics (write mode register) */        switch (channelNumber) 	{	case 0:	    rvalue = dmaTransferMode | dmaTransferType | I8237_MODE_CH0SEL;	    break;	case 1:	    rvalue = dmaTransferMode | dmaTransferType | I8237_MODE_CH1SEL;	    break;	case 2:	    rvalue = dmaTransferMode | dmaTransferType | I8237_MODE_CH2SEL;	    break;	case 3:	    rvalue = dmaTransferMode | dmaTransferType | I8237_MODE_CH3SEL;	    break;	default:	    rvalue = 0x00;	    break;	}    /* enable channel for DMA transfer */       if (dmaChannelNumber < 4) 	{	pDma1->wm = rvalue; 	EIEIO_SYNC;	pDma1->wsmb = channelNumber; 	EIEIO_SYNC;        }    else 	{	pDma2->wm = rvalue; 	EIEIO_SYNC;	pDma2->wsmb = channelNumber; 	EIEIO_SYNC;	}    }/********************************************************************************* isaDmaStop - Stop DMA transfer** This functions purpose is to disable (stop) the specified DMA* channel for a DMA transfer.** RETURNS: N/A*/void isaDmaStop    (    register UINT dmaChannelNumber	/* DMA channel number (0 - 7) */    )    {    register UINT channelNumber;    register I8237_DMA1 *pDma1;    register I8237_DMA2 *pDma2;    /* setup pointers to the DMA controller devices */    pDma1 = (I8237_DMA1 *)(I8237_BASE_ADDRESS + I8237_DMA1_OFFSET);    pDma2 = (I8237_DMA2 *)(I8237_BASE_ADDRESS + I8237_DMA2_OFFSET);    /* create physical i8237 channel number */    channelNumber = dmaChannelNumber & 0x3;    /* disable channel */    if (dmaChannelNumber < 4) 	{        pDma1->wsmb = (I8237_WSMB_CHMASKSEL | channelNumber); 	EIEIO_SYNC;        }     else 	{        pDma2->wsmb = (I8237_WSMB_CHMASKSEL | channelNumber); 	EIEIO_SYNC;        }    }/********************************************************************************* isaDmaStatus - get DMA transfer status** This function's purpose is to query the specified DMA channel* for DMA transfer status.  And to return this status in a* logical format (see values below).** RETURNS: DMA Transfer Status*  	   0: Request=0, TerminalCount=0*	   1: Request=0, TerminalCount=1*	   2: Request=1, TerminalCount=0*	   3: Request=1, TerminalCount=1*/UINT isaDmaStatus    (    register UINT dmaChannelNumber	/* DMA channel number (0 - 7) */    )    {    register UINT rvalue, svalue;    register UINT channelNumber;    register I8237_DMA1 *pDma1;    register I8237_DMA2 *pDma2;    /* setup pointers to the DMA controller devices */    pDma1 = (I8237_DMA1 *)(I8237_BASE_ADDRESS + I8237_DMA1_OFFSET);    pDma2 = (I8237_DMA2 *)(I8237_BASE_ADDRESS + I8237_DMA2_OFFSET);    /* create physical i8237 channel number */     channelNumber = dmaChannelNumber & 0x3;    /* read DMA status register */      if (dmaChannelNumber < 4)         {        rvalue = pDma1->cs; 	EIEIO_SYNC;        }     else         {        rvalue = pDma2->cs; 	EIEIO_SYNC;        }    /* mask off unwanted channels' status */       rvalue &= ((0x10 << channelNumber) | (0x01 << channelNumber));    /* convert to logical status */        svalue = 0;    if (rvalue & 0xF0) 	{ 	svalue |= 0x2; 	}    if (rvalue & 0x0F) 	{ 	svalue |= 0x1; 	}    return (svalue);}#endif /* INCLUDE_ISADMA */

⌨️ 快捷键说明

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