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

📄 plx9054.c

📁 plx9054总线在vxworks系统下的bsp开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
            sprintf(pPlxSpace->spaceName, "Pci I/O For Local Reg");
            pPlxSpace->dwPciBar = pDrvCtrl->pDevice[index]->PlxPciRsrc.iobaseCsr;
            pPlxSpace->dwRange = 256;
            pPlxSpace->fIsEnable = TRUE;
            pPlxSpace->fIsMemory = FALSE;
            return OK;
            break;
           
        case P9054_ADDR_SPACE0:  /* local space 0*/
            PLX9054_Local_Reg_Read(index, P9054_LAS0RR, &range);
            PLX9054_Local_Reg_Read(index, P9054_LAS0BA, &localBase);
            PLX9054_Pci_Reg_Read(index, PCI_BAR2, &pciBase, DATA_DWORD);
            sprintf(pPlxSpace->spaceName, "PLX9054 Local Space 0");
            break;
        case P9054_ADDR_SPACE1:  /* local space 1*/
            PLX9054_Local_Reg_Read(index, P9054_LAS1RR, &range);
            PLX9054_Local_Reg_Read(index, P9054_LAS1BA, &localBase);
            PLX9054_Pci_Reg_Read(index, PCI_BAR3, &pciBase, DATA_DWORD);
            sprintf(pPlxSpace->spaceName, "PLX9054 Local Space 1");
            break;
        case P9054_ADDR_EPROM:  /* local EPROM space*/
            PLX9054_Local_Reg_Read(index, P9054_EROMRR, &range);
            PLX9054_Local_Reg_Read(index, P9054_EROMBA, &localBase);
            PLX9054_Pci_Reg_Read(index, PCI_ERBAR, &pciBase, DATA_DWORD);
            sprintf(pPlxSpace->spaceName, "PLX9054 Local Eprom Space");
            break;
        default:
            return ERROR;
            break;
    }
    
    /*初始化结构体*/
    pPlxSpace->fIsMemory = (BIT0 == (range & BIT0)); 
    if(pPlxSpace->fIsMemory)
    {
        pPlxSpace->fIsPrefetch = (BIT3 == (range & BIT3));  
        pPlxSpace->dwRange = (~(range & PCI_MEMBASE_MASK)) + 1; 
    }
    else
    {
        pPlxSpace->dwRange = (~(range & 0xfffffff8)) + 1;
    }

    pPlxSpace->fIsEnable = (BIT0 == (localBase & BIT0));
    
    if(pPlxSpace->fIsMemory) /* memory base */
    {
        pPlxSpace->dwLocalBase = (localBase & PCI_MEMBASE_MASK);
    }
    else  /* i/o base */
    {
        pPlxSpace->dwLocalBase = (localBase & 0xfffffffc);
    }

    if(pPlxSpace->fIsEnable)
    {
        pPlxSpace->dwPciBar = pciBase & PCI_MEMBASE_MASK;
    }

    return OK;
}

/*
PLX9054_GetSpaceInfo
获取PLX9054 所有本地空间信息Space0、Space1、Programe ROM Space
input
      int index: 设备索引
*/
STATUS PLX9054_GetAllSpaceInfo(int index)
{
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_SPACE_DESC plxSpace;
    int i;
    
    pDrvCtrl = pPlxDrvCtrl;
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index(%d) out of range file:%s, line:%d.\n", index, __FILE__, __LINE__);
        return ERROR;
    }

    for(i = 0; i < AD_PCI_BAR_EPROM; i++)
    {
        memset((void *)(&plxSpace), 0, sizeof(PLX9054_SPACE_DESC));
        if(OK == PLX9054_GetSpaceInfo(index, (PLX9054_SPACE_INDEX)i, &plxSpace))
        {
            pDrvCtrl->pDevice[index]->spaceDesc[i] = plxSpace;
        }    
    }

    return OK;
}

/********************************************************************
PLX9054_Int
PLX9054中断入口函数
*/
void PLX9054_Int(int index)
{
  
    UINT32 intcsr, intSource;
    UCHAR dmacsr;
    int level;
    
    PLX9054_DMA_CH ch;
    PLX9054_DRVCTRL * pDrvCtrl;

    level = intLock ();
    
    pDrvCtrl = PLX9054_GetDrvCtrl( );
    ch = pDrvCtrl->pDevice[index]->channel;
      
    /* 读取中断控制/状态寄存器*/
    PLX9054_Local_Reg_Read (index, P9054_INTCSR, &intcsr);

    /* 计算中断源*/
    if(0xffffffff == intcsr)
    {
        return;
    }
    
    /* Check for master PCI interrupt enable */
    if ((intcsr & (1 << 8)) == 0)
        return;

    #if 0
    intSource = INTR_TYPE_NONE;

     /* Check if PCI Doorbell Interrupt is active and not masked*/
    if ((intcsr & (1 << 13)) && (intcsr & (1 << 9)))
    {
        intSource |= INTR_TYPE_DOORBELL;
    }

    /* Check if PCI Abort Interrupt is active and not masked */
    if ((intcsr & (1 << 14)) && (intcsr & (1 << 10)))
    {
        intSource |= INTR_TYPE_PCI_ABORT;
    }

    /* Check if Local->PCI Interrupt is active and not masked */
    if ((intcsr & (1 << 15)) && (intcsr & (1 << 11)))
    {
        intSource |= INTR_TYPE_LOCAL_1;
    }
    #endif
    
    if((intcsr & BIT21) && (intcsr & BIT18))  /* DMA 通道0 产生中断*/
    {
        /*采集来的数据已经经DMA 传输到内存中,这里通过 释放信号量激活数据处理任务*/
        semGive(pDrvCtrl->pDevice[index]->dmaCh[ch].syncSem);
        /* 清中断*/
        dmacsr = *(UCHAR *)(pPlxDrvCtrl->pDevice[index]->spaceDesc[AD_PCI_BAR0].dwPciBar + P9054_DMACSR);
        *(UCHAR *)(pPlxDrvCtrl->pDevice[index]->spaceDesc[AD_PCI_BAR0].dwPciBar + P9054_DMACSR) = dmacsr | (1 << 3);
    }
    
    intUnlock(level);
}

/********************************************************************
PLX9054_Ioctl
PLX9054的配置与控制接口函数
*/
STATUS PLX9054_Ioctl(int index, PLX9054_IOCTL_CMD cmd, UINT32 * pData)
{
    return OK;
}

/*
PLX9054_IntEnable
开中断
*/
void PLX9054_IntEnable (int index)
{
    UINT32 dwIntStatus;
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DEVICE * pDevCtrl;

    pDrvCtrl = pPlxDrvCtrl;
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
        return;
    }
    
    if(0) /*如果中断已经使能,直接返回*/
    {
        return;
    }

    pDevCtrl = pDrvCtrl->pDevice[index];

    /* this enables interrupts*/
    PLX9054_Local_Reg_Read (index, P9054_INTCSR, &dwIntStatus);
    PLX9054_Local_Reg_Write (index, P9054_INTCSR, dwIntStatus | (BIT8|BIT10 | BIT18));

    pDevCtrl->intIsEnable = TRUE;
}
 
/*
PLX9054_IntDisable
关中断
*/
void PLX9054_IntDisable (int index)
{
    UINT32 dwIntStatus;
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DEVICE * pDevCtrl;

    pDrvCtrl = pPlxDrvCtrl;
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
        return;
    }
    
    if(0) /*如果中断已经使能,直接返回*/
    {
        return;
    }

    pDevCtrl = pDrvCtrl->pDevice[index];

    /* this disables interrupts*/
    dwIntStatus = PLX9054_Local_Reg_Read (index, P9054_INTCSR, &dwIntStatus);
    PLX9054_Local_Reg_Write (index, P9054_INTCSR, dwIntStatus & ~(BIT8|BIT10));

    pDevCtrl->intIsEnable = FALSE;
}

/**************************************************************************
* PLX9054_DMAReadWriteBlock
* 对外接口
* DMA块方式读写
*/
STATUS PLX9054_DMAReadWriteBlock (int index, UINT32 dwLocalAddr, UINT32 buffer, UINT32 dwBytes, BOOL fIsRead)
{
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DMA * pDmaCtrl = NULL;
    int channel;

    pDrvCtrl = PLX9054_GetDrvCtrl();
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
        return ERROR;
    }

    channel = pDrvCtrl->pDevice[index]->channel;                       /* 获取设置使用的DMA通道*/
    pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[channel]);

    pDmaCtrl->pDmaDesc->pciAddr = buffer;                              /* 设置DMAPADR0/1 寄存器*/
    pDmaCtrl->pDmaDesc->localAddr = dwLocalAddr;                 /* 设置DMALADR0/1 寄存器*/
    pDmaCtrl->pDmaDesc->nBytes = dwBytes;                            /* 设置DMASIZ0/1 寄存器*/
    if(fIsRead)
    {
        pDmaCtrl->pDmaDesc->descPointer = BIT3;
    }
    else
    {
        pDmaCtrl->pDmaDesc->descPointer = 0;
    }
    
    PLX9054_DMAStart(pDmaCtrl);
    
    return OK;
}
/*
PLX9054_DmaCtrl
对外接口
DMA控制与配置模块,与IOCTL类似
input 
       index: 设备索引
       cmd: 命令(设置项索引)
       pData: 数据指针
*/
STATUS PLX9054_DMACtl(int index, PLX9054_DMA_CMD cmd, UINT32 * pData)
{
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DMA * pDmaCtrl = NULL;
    int channel;
    UINT32 data;

    pDrvCtrl = PLX9054_GetDrvCtrl();
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
        return ERROR;
    }

    channel = pDrvCtrl->pDevice[index]->channel;
    pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[channel]);

    switch(cmd)
    {
        case DMA_CHANNEL_SET: /* 设置DMA 通道号*/
            pDrvCtrl->pDevice[index]->channel = (PLX9054_DMA_CH)(pData);
            break;
        case DMA_CHANNEL_GET: /* 获取DMA 通道号*/
            *pData = (UINT32)(pDrvCtrl->pDevice[index]->channel);
            break;
        case DMA_READ_ENABLE: /* 设置DMA 读*/
            pDmaCtrl->fIsRead = TRUE;
            break;
        case DMA_WRITE_ENABLE: /* 设置DMA 写*/
            pDmaCtrl->fIsRead = FALSE;
            break;
        case DMA_BUS_WIDTH_SET: /* Set Local Bus Width*/
            data = *(pDmaCtrl->pDmaMode);
            *(pDmaCtrl->pDmaMode) = (data & (~(BIT0 | BIT1))) | (UINT32)(pData);
            break;
        case DMA_BUS_WIDTH_GET: /* Get Local Bus Width*/
            data = *(pDmaCtrl->pDmaMode);
            *pData = data & (BIT0 | BIT1);
            break;
        case DMA_WAIT_SET:  /* Set Internal Wait States */
            break;
        case DMA_WAIT_GET:  /* Get Internal Wait States */
            break;
        case DMA_BURST_ENABLE:      /* Local Burst Enable */
            data = *(pDmaCtrl->pDmaMode);
            *(pDmaCtrl->pDmaMode) = data | BIT8;
            break;
        case DMA_BURST_DISABLE:    /* Local Burst Disable */
            data = *(pDmaCtrl->pDmaMode);
            *(pDmaCtrl->pDmaMode) = data & (~BIT8);
            break;
        case DMA_GATHER_MODE_ENABLE:  /* Scatter/Gather mode Enable */
            break;
        case DMA_GATHER_MODE_DISABLE: /* Scatter/Gather mode Disable */
            break;
        case DMA_INT_ENABLE:      /* Done Interrupt Enable */
            break; 
        case DMA_INT_DISABLE:    /* Done Interrupt Disable */
            break;
        case DMA_LOCAL_ADDR_INC: /* 本地地址递增*/
            data = *(pDmaCtrl->pDmaMode);
            *(pDmaCtrl->pDmaMode) = data & (~BIT11);
            break;
        case DMA_LOCAL_ADDR_HOLD: /* 本地地址保持不变*/
            data = *(pDmaCtrl->pDmaMode);
            *(pDmaCtrl->pDmaMode) = data | BIT11;
            break;
        default:
            break;
    }
    
    return OK;
}

/*
PLX9054_DMA_Init
DMA初始化函数
*/
STATUS PLX9054_DMA_Init(int index)
{
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DMA * pDmaCtrl = NULL;
    UINT32  membaseCsr;
    int i;

    pDrvCtrl = PLX9054_GetDrvCtrl();
    
    /* 输入参数判断*/
    if( (index < 0)  || (index > (pDrvCtrl->plxCardNum - 1)))
    {
        printf("Index out of range file:%s, line:%d.\n", __FILE__, __LINE__);
        return ERROR;
    }
    /* 获取寄存器映射到PCI Memory空间的基地址*/
    membaseCsr = pDrvCtrl->pDevice[index]->PlxPciRsrc.membaseCsr;

    /*初始化DMA结构体,包括设置一些初始状态,寄存器地址*/
    for(i = 0; i < PLX9054_DMA_NUM; i++)
    {
        pDmaCtrl = &(pDrvCtrl->pDevice[index]->dmaCh[i]);
        if(NULL == pDmaCtrl)
        {
            break;
        }
        pDmaCtrl->pDmaMode = (UINT32 *)(membaseCsr + P9054_DMAMODE + i * PLX9054_DMA_CHANNEL_SHIFT);
        pDmaCtrl->pDmaDesc  = (PLX9054_DMA_DESC *)(membaseCsr + P9054_DMAPADR + i * PLX9054_DMA_CHANNEL_SHIFT);
        pDmaCtrl->pDmaCs = (UINT8 *)(membaseCsr +  P9054_DMACSR + i);    
        pDmaCtrl->fIschkDone = TRUE;   /* 默认查询模式*/
        pDmaCtrl->fIsRead = TRUE;        /* 默认DMA用于读FIFO*/
        pDmaCtrl->semTimeOut = PLX9054_DMA_TIME_OUT;
        pDmaCtrl->timeOutCount = 0;
        pDmaCtrl->syncSem = semBCreate(SEM_Q_FIFO, SEM_EMPTY);  /*创建信号量*/

        /* DMA 模式初始化 
          BIT0: 16-bit lOCAL bus
          BIT10: Done Interrupt Enable
          BIT11:LocaL address hold        
          BIT17:DMA Interrupt INTA*/
        *(pDmaCtrl->pDmaMode) = BIT0 | BIT10 |BIT11|BIT17;
    }   

    PLX9054_DMACtl(index, DMA_CHANNEL_SET, (UINT32 *)PLX9054_DMA_CH_0);      /* 设置使用DMA 0 */
    PLX9054_DMACtl(index, DMA_BUS_WIDTH_SET, (UINT32 *)PLX9054_BUS_WORD); /* 设置本地总线为16 位*/
    #if 1
    PLX9054_DMACtl(index, DMA_BURST_DISABLE, NULL);  /* 本地总线禁止BURST 操作*/
    #else
    PLX9054_DMACtl(index, DMA_BURST_ENABLE, NULL);  /* 本地总线使能BURST 操作*/
    #endif
    return OK;
}

/*
PLX9054_DMAIsDone
查询DMA传输是否完成
*/
BOOL PLX9054_DMAIsDone (PLX9054_DMA * pDmaCtrl)
{
    return(BIT4 == (*(pDmaCtrl->pDmaCs) & BIT4));
}

/*
PLX9054_DMAStart
启动DMA传输
*/
STATUS PLX9054_DMAStart (PLX9054_DMA * pDmaCtrl)
{
    int semStatus;
    
    *(pDmaCtrl->pDmaCs) = BIT0 | BIT1;

    #if 0
    /* Busy wait for plx to finish DMA transfer*/
    if (pDmaCtrl->fIschkDone) 
    {
        while (!PLX9054_DMAIsDone(pDmaCtrl))
            ;
    }
    printf("DMA Done.\n");
    else  /* 中断方式, 调试用*/
    #else
    {
        semStatus = semTake(pDmaCtrl->syncSem, PLX9054_DMA_TIME_OUT);   /*需要 在中断处理中释放信号量*/

        if(ERROR == semStatus)
        {
            printf("DMA Operation TIME_OUT.file:%s, line:%d.\n", __FILE__, __LINE__);
            pDmaCtrl->timeOutCount++;
            return ERROR;
        }
    }
    #endif
    
    return OK;
}

/*
PLX9054PciShow
显示所有PLX9054扩展卡的PCI资源信息
*/
void PLX9054_Pci_Show(void)
{
    int unit;
    PLX9054_DRVCTRL * pDrvCtrl;
    PLX9054_DEVICE * pDevCtrl;

    pDrvCtrl = PLX9054_GetDrvCtrl();
    
    if (0 == pDrvCtrl->plxCardNum)
    {
        printf("No Plx9054 Card Installed!\n");
        return;
    }
    
    for(unit = 0; unit < (pDrvCtrl->plxCardNum); unit++)
    {
        pDevCtrl = pDrvCtrl->pDevice[unit];
        printf("Bus:%d Device:%d Function:%d MemBase:0x%08x IOBase:0x%04x  Irq:%d\n",
        pDevCtrl->PlxPciRsrc.pciBus, pDevCtrl->PlxPciRsrc.pciDevice, pDevCtrl->PlxPciRsrc.pciFunc,
        pDevCtrl->PlxPciRsrc.membaseCsr, pDevCtrl->PlxPciRsrc.iobaseCsr, pDevCtrl->PlxPciRsrc.irq);       
    }
    
    return;
}

⌨️ 快捷键说明

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