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

📄 altera_lib.c

📁 Jungo公司确实为VxWorks开发了类似于WinDriver的驱动开发辅助套件DriverBuilder (for VxWorks)!
💻 C
📖 第 1 页 / 共 2 页
字号:
                    hALTERA->addrDesc[ad_sp].fIsMemory = fIsMemory;
                    hALTERA->addrDesc[ad_sp].dwMask = 0;
                    for (j=1; j<dwBytes && j!=0x80000000; j *= 2)
                    {
                        hALTERA->addrDesc[ad_sp].dwMask = 
                            (hALTERA->addrDesc[ad_sp].dwMask << 1) | 1;
                    }
                }
            }
            break;
        case ITEM_INTERRUPT:
            if (hALTERA->Int.Int.hInterrupt) return FALSE;
            hALTERA->Int.Int.hInterrupt = pItem->I.Int.hInterrupt;
            break;
        }
    }

    // check that at least one memory space was found
    for (i = 0; i<ALTERA_ITEMS; i++)
        if (ALTERA_IsAddrSpaceActive(hALTERA, (ALTERA_ADDR) i)) break;
    if (i==ALTERA_ITEMS) return FALSE;

    return TRUE;
}

BOOL ALTERA_IsAddrSpaceActive(ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace)
{
    return hALTERA->addrDesc[addrSpace].fActive;
}

void ALTERA_GetPciSlot(ALTERA_HANDLE hALTERA, WD_PCI_SLOT *pPciSlot)
{
    memcpy((PVOID)pPciSlot, &(hALTERA->pciSlot), sizeof(WD_PCI_SLOT));
}

// General read/write function
void ALTERA_ReadWriteBlock(ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, BOOL fRead, PVOID buf, DWORD dwBytes, ALTERA_MODE mode)
{
    WD_TRANSFER trans;
    BOOL fMem = hALTERA->addrDesc[addrSpace].fIsMemory;
    // safety check: is the address range active
    if (!ALTERA_IsAddrSpaceActive(hALTERA, addrSpace)) return;
    BZERO(trans);
    if (fRead)
    {
        if (mode==ALTERA_MODE_BYTE) trans.cmdTrans = fMem ? RM_SBYTE : RP_SBYTE;
        else if (mode==ALTERA_MODE_WORD) trans.cmdTrans = fMem ? RM_SWORD : RP_SWORD;
        else if (mode==ALTERA_MODE_DWORD) trans.cmdTrans = fMem ? RM_SDWORD : RP_SDWORD;
    }
    else
    {
        if (mode==ALTERA_MODE_BYTE) trans.cmdTrans = fMem ? WM_SBYTE : WP_SBYTE;
        else if (mode==ALTERA_MODE_WORD) trans.cmdTrans = fMem ? WM_SWORD : WP_SWORD;
        else if (mode==ALTERA_MODE_DWORD) trans.cmdTrans = fMem ? WM_SDWORD : WP_SDWORD;
    }
    if (fMem)
        trans.dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwTransAddr;
    else trans.dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.IO.dwAddr;
    trans.dwPort += dwOffset;

    trans.fAutoinc = TRUE;
    trans.dwBytes = dwBytes;
    trans.dwOptions = 0;
    trans.Data.pBuffer = buf;
    WD_Transfer (hALTERA->hWD, &trans);
}

BYTE ALTERA_ReadByte (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
{
    BYTE data;
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PBYTE pData = (PBYTE) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        data = *pData; // read from the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (BYTE), ALTERA_MODE_BYTE);
    return data;
}

WORD ALTERA_ReadWord (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
{
    WORD data;
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PWORD pData = (PWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        data = *pData; // read from the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (WORD), ALTERA_MODE_WORD);
    return data;
}

DWORD ALTERA_ReadDword (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset)
{
    DWORD data;
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PDWORD pData = (PDWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        data = *pData; // read from the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, TRUE, &data, sizeof (DWORD), ALTERA_MODE_DWORD);
    return data;
}

void ALTERA_WriteByte (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, BYTE data)
{
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PBYTE pData = (PBYTE) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        *pData = data; // write to the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (BYTE), ALTERA_MODE_BYTE);
}

void ALTERA_WriteWord (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, WORD data)
{
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PWORD pData = (PWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        *pData = data; // write to the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (WORD), ALTERA_MODE_WORD);
}

void ALTERA_WriteDword (ALTERA_HANDLE hALTERA, ALTERA_ADDR addrSpace, DWORD dwOffset, DWORD data)
{
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        PDWORD pData = (PDWORD) (hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwUserDirectAddr + dwOffset);
        *pData = data; // write to the memory mapped range directly
    }
    else ALTERA_ReadWriteBlock( hALTERA, addrSpace, dwOffset, FALSE, &data, sizeof (DWORD), ALTERA_MODE_DWORD);
}

BOOL ALTERA_IntIsEnabled (ALTERA_HANDLE hALTERA)
{
    if (!hALTERA->Int.hThread)
        return FALSE;
    return TRUE;
}

void ALTERA_IntHandler (PVOID pData)
{
    ALTERA_HANDLE hALTERA = (ALTERA_HANDLE) pData;
    ALTERA_INT_RESULT intResult;
    intResult.dwCounter = hALTERA->Int.Int.dwCounter;
    intResult.dwLost = hALTERA->Int.Int.dwLost;
    intResult.fStopped = hALTERA->Int.Int.fStopped;
    hALTERA->Int.funcIntHandler(hALTERA, &intResult);
}

BOOL ALTERA_IntEnable (ALTERA_HANDLE hALTERA, ALTERA_INT_HANDLER funcIntHandler)
{
    ALTERA_ADDR addrSpace;

    // check if interrupt is already enabled
    if (hALTERA->Int.hThread)
        return FALSE;

    BZERO(hALTERA->Int.Trans);
    // This is a sample of handling interrupts:
    // One transfer command is issued to CANCEL the source of the interrupt,
    // otherwise, the PC will hang when an interrupt occurs!
    // You will need to modify this code to fit your specific hardware.
    addrSpace = ALTERA_AD_BAR0; // put the address space of the register here
    if (hALTERA->addrDesc[addrSpace].fIsMemory)
    {
        hALTERA->Int.Trans[0].dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.Mem.dwTransAddr;
        hALTERA->Int.Trans[0].cmdTrans = WM_DWORD;
    }
    else
    {
        hALTERA->Int.Trans[0].dwPort = hALTERA->cardReg.Card.Item[hALTERA->addrDesc[addrSpace].index].I.IO.dwAddr;
        hALTERA->Int.Trans[0].cmdTrans = WP_DWORD;
    }
    hALTERA->Int.Trans[0].dwPort += 0; // put the offset of the register from the beginning of the address space here
    hALTERA->Int.Trans[0].Data.Dword = 0x0;
    hALTERA->Int.Int.dwCmds = 1;
    hALTERA->Int.Int.Cmd = hALTERA->Int.Trans;
    hALTERA->Int.Int.dwOptions |= INTERRUPT_CMD_COPY;

    // this calls WD_IntEnable() and creates an interrupt handler thread
    hALTERA->Int.funcIntHandler = funcIntHandler;
    if (!InterruptThreadEnable(&hALTERA->Int.hThread, hALTERA->hWD, &hALTERA->Int.Int, ALTERA_IntHandler, (PVOID) hALTERA))
        return FALSE;

    return TRUE;
}

void ALTERA_IntDisable (ALTERA_HANDLE hALTERA)
{
    if (!hALTERA->Int.hThread)
        return;

    // this calls WD_IntDisable()
    InterruptThreadDisable(hALTERA->Int.hThread);

    hALTERA->Int.hThread = NULL;
}

BOOL ALTERA_DMAWait(ALTERA_HANDLE hALTERA)
{
    BOOL fOk = FALSE;
    DWORD i = 10*1000*1000/2; // wait 10 seconds (each loop waits 2 microseconds
    for(;i;i--)
    {
        DWORD dwDMAISR = ALTERA_ReadDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMAISR);
        WD_SLEEP sleep;
        if (dwDMAISR & TX_COMP)
        {
            fOk = TRUE;
            break;
        }

        if (dwDMAISR & ERROR_PENDING) 
        {
            sprintf(ALTERA_ErrorString, "hardware dma failure\n");
            break;
        }
        BZERO(sleep);
        sleep.dwMicroSeconds = 2;
        WD_Sleep(hALTERA->hWD, &sleep);
    }
    if (!i)
        sprintf(ALTERA_ErrorString, "dma transfer timeout\n");

    return fOk;
}

BOOL ALTERA_DMAReadWriteBlock(ALTERA_HANDLE hALTERA, DWORD dwLocalAddr, PVOID pBuffer, BOOL fRead, DWORD dwBytes, BOOL fChained)
{
    BOOL fOk = FALSE;
    WD_DMA dma;
    DWORD DMACsr;
    DWORD i;

    if (dwBytes == 0)
        return fOk;
    BZERO(dma);
    dma.pUserAddr = pBuffer;
    dma.dwBytes = dwBytes;
    dma.dwOptions = 0;
    WD_DMALock(hALTERA->hWD, &dma);
    if (!dma.hDma)
    {
        sprintf(ALTERA_ErrorString, "cannot lock down buffer\n");
        return FALSE;
    }
    DMACsr = fRead ? DIRECTION : 0;
    DMACsr |= DMA_ENABLE | TRXCOMPINTDIS | INTERRUPT_ENABLE;
    if (dma.dwPages>ALTERA_DMA_FIFO_REGS)
    {
        sprintf(ALTERA_ErrorString, "too many pages for chain transfer\n");
        // not enough pages
        goto Exit;
    }
    if (fChained)
    {
        DMACsr |= CHAINEN;
        for (i=0;i<dma.dwPages;i++)
        {
            ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, FIFO_BASE_OFFSET, (DWORD) dma.Page[i].pPhysicalAddr);
            ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, FIFO_BASE_OFFSET, dma.Page[i].dwBytes);
        }
        ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMALAR, dwLocalAddr);
        ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMACSR, DMACsr); //this starts the dma
        fOk = ALTERA_DMAWait(hALTERA);
    }
    else
    {
        DWORD dwTotalBytes = 0;
        ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMACSR, DMACsr);
        for (i=0;i<dma.dwPages;i++)
        {
            ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMALAR, dwLocalAddr+dwTotalBytes);
            ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMABCR, dma.Page[i].dwBytes);
            ALTERA_WriteDword (hALTERA, ALTERA_AD_BAR0, ALTERA_REG_DMAACR, (DWORD) dma.Page[i].pPhysicalAddr); // this starts the dma
            fOk = ALTERA_DMAWait(hALTERA);
            if (!fOk)
                break;
            dwTotalBytes += dma.Page[i].dwBytes;
        }

    }

Exit:
     WD_DMAUnlock(hALTERA->hWD, &dma);
     return fOk;
}   

⌨️ 快捷键说明

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