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

📄 esd_pc104_200.c

📁 CANOPen通信的一些源码
💻 C
字号:
/* esd_can_pc104_200.c - implementation of Board Interface for ESD CAN PC104/200 *//* Copyright 2001 Wind River Systems, Inc. *//* modification history --------------------27nov01,dnb written*//* DESCRIPTIONThis file contains the functions that provide a board-level interfaceto the ESD CAN PC104/200 card.*//* includes */#include <vxWorks.h>#include <errnoLib.h>#include <intLib.h>#include <iv.h>#include <sysLib.h>#include <string.h> /* for strtok_r */#include <CAN/wnCAN.h>#include <CAN/canController.h>#include <CAN/canBoard.h>#include <CAN/i82527.h>#include <CAN/sja1000.h>#include <CAN/private/esd_can_pc104_200.h>#if (CPU != SH7750)static const char deviceName[] ="ESD CAN PC104/200";                      const UINT esd_can_pc104_200_i82527_ndx = 0;const UINT esd_can_pc104_200_sja1000_ndx = 1;UINT max_esd_can_pc104_200_boards;struct ESD_CAN_PC104_200_DeviceEntry *esd_can_pc104_200_DeviceArray;/* external reference */STATUS CAN_DEVICE_establishLinks(WNCAN_DEVICE *pDev, WNCAN_BoardType brdType,                      WNCAN_ControllerType ctrlType);/************************************************************************** esd_can_pc104_200_setirq - sets the IRQ level of the ESD PC104/200 board*** RETURNS: N/A*   * ERRNO: N/A**/    void esd_can_pc104_200_setirq(    ULONG ioBase,    UINT irqLevel){    UINT l, l1, stat;    int oldLevel;    /* Lock out all interrupts */    oldLevel = intLock();    /* Assign interrupt level on card */    l1 = irqLevel;    for (l = 0; l < 4; l++)    {        stat=l;        if (l1 & 0x01)            stat |= 0x80;        sysOutByte(ioBase+3,stat);        l1 = l1 >> 1;    }    /* Change the IRQ-output from Tri-state into driven status. */#if (CPU_FAMILY == I80X86)    sysOutByte(ioBase+3, (char)0x87);#else    sysOutByte(ioBase+3, 0x87);#endif    /* latch 1000 times */    for(l = 0; l < 1000; l++)    {        sysOutByte(ioBase+3, 5);    }       /* Unlock interrupts */    intUnlock(oldLevel);    return;}/************************************************************************** esd_can_pc104_200_isr - board-level isr*** RETURNS: N/A*   * ERRNO: N/A**/    static void esd_can_pc104_200_isr(    ULONG param){    struct ESD_CAN_PC104_200_DeviceEntry *pDE;    pDE = (struct ESD_CAN_PC104_200_DeviceEntry *)param;    /* disabling the interrupt. Deactivate the bits in the latch.*/    sysOutByte(pDE->ioAddress+3,0x06);    if(pDE->allocated[esd_can_pc104_200_i82527_ndx])    {        i82527ISR((ULONG)&pDE->canDevice[esd_can_pc104_200_i82527_ndx]);    }    if(pDE->allocated[esd_can_pc104_200_sja1000_ndx])    {        sja1000ISR((ULONG)&pDE->canDevice[esd_can_pc104_200_sja1000_ndx]);    }    /* Enable the interrupt. This enabling pin is also used for disabling        interrupts without changing the state of the outputs to tristate.        Writing 0x06 to the same address disables interrupts, writing 0x86       reenables interrupts */#if (CPU_FAMILY == I80X86)    sysOutByte(pDE->ioAddress+3, (char)0x86);#else    sysOutByte(pDE->ioAddress+3, 0x86);#endif}/************************************************************************** esd_can_pc104_200_new - install driver for pc104/200 board*** RETURNS: OK or ERROR*   * ERRNO: S_can_out_of_memory**/STATUS esd_can_pc104_200_new(    ULONG ioAddress,    UINT irq){    UINT          i;    UINT          brdNdx=0;    int           oldLevel;    STATUS        retCode;    VOIDFUNCPTR*  irqVec = 0;        struct  WNCAN_Device *pDev[2];    struct  ESD_CAN_PC104_200_DeviceEntry *pDeviceEntry;                retCode = ERROR;      /* pessimistic */    pDeviceEntry = 0;        /* find a free device data structure */    for(i = 0 ; i < max_esd_can_pc104_200_boards; i++)    {        if(esd_can_pc104_200_DeviceArray[i].inUse == 0)        {            esd_can_pc104_200_DeviceArray[i].inUse = 1;            pDeviceEntry = &esd_can_pc104_200_DeviceArray[i];            brdNdx = i;            break;        }                }        if(i == (max_esd_can_pc104_200_boards + 1))    {        retCode = ERROR;        errnoSet(S_can_out_of_memory);        goto exit;    }        if(!pDeviceEntry)    {        errnoSet(S_can_out_of_memory);        retCode = ERROR;        goto exit;    }        /* setup data structures */    for(i = 0 ; i < 2 ; i++)    {        pDev[i]        = &pDeviceEntry->canDevice[i];        pDev[i]->pCtrl = &pDeviceEntry->canControllerArray[i];        pDev[i]->pBrd  =  &pDeviceEntry->canBoardArray[i];        pDev[i]->deviceName = deviceName;        pDev[i]->pBrd->irq = irq;        pDev[i]->pBrd->ioAddress = ioAddress;        pDev[i]->pBrd->xtalFreq = _16MHZ;		/* set default baud rate to 250 Kbits/sec */        pDev[i]->pCtrl->brp = 1;               pDev[i]->pCtrl->sjw = 0;          pDev[i]->pCtrl->tseg1 = 0xc;        pDev[i]->pCtrl->tseg2 = 0x1;		pDev[i]->pCtrl->samples = 0;    }    pDev[esd_can_pc104_200_i82527_ndx]->pCtrl->chnType = g_i82527chnType;    pDev[esd_can_pc104_200_i82527_ndx]->pCtrl->numChn  = I82527_MAX_MSG_OBJ;    pDev[esd_can_pc104_200_i82527_ndx]->pCtrl->chnMode = &pDeviceEntry->i82527chnMode[0];	pDev[esd_can_pc104_200_i82527_ndx]->pCtrl->csData = &pDeviceEntry->can82527;    pDev[esd_can_pc104_200_sja1000_ndx]->pCtrl->chnType = g_sja1000chnType;    pDev[esd_can_pc104_200_sja1000_ndx]->pCtrl->numChn  = SJA1000_MAX_MSG_OBJ;    pDev[esd_can_pc104_200_sja1000_ndx]->pCtrl->chnMode = &pDeviceEntry->sja1000chnMode[0];    pDev[esd_can_pc104_200_sja1000_ndx]->pCtrl->csData  = &pDeviceEntry->txMsg;	 	    if(CAN_DEVICE_establishLinks(pDev[esd_can_pc104_200_i82527_ndx],        WNCAN_ESD_PC104_200, WNCAN_I82527) == ERROR)    {        pDev[esd_can_pc104_200_i82527_ndx] = 0;                    goto exit;    }                if(CAN_DEVICE_establishLinks(pDev[esd_can_pc104_200_sja1000_ndx],        WNCAN_ESD_PC104_200, WNCAN_SJA1000) == ERROR)    {        pDev[esd_can_pc104_200_sja1000_ndx] = 0;        goto exit;    }	pDev[esd_can_pc104_200_i82527_ndx]->deviceId = (brdNdx << 8);                pDev[esd_can_pc104_200_sja1000_ndx]->deviceId = (brdNdx << 8) | esd_can_pc104_200_sja1000_ndx;                        /* set the irq on the board */    esd_can_pc104_200_setirq(ioAddress, irq);    /* connect to isr */    oldLevel = intLock();    #if CPU_FAMILY == I80X86        irqVec = INUM_TO_IVEC(irq+0x20);    #elif CPU_FAMILY == PPC        irqVec = INUM_TO_IVEC(irq+0x40);    #else        #warning irqVec not defined     #endif        intConnect(irqVec,esd_can_pc104_200_isr,(ULONG)pDeviceEntry);        /* activate IRQ at the board and CPU level */    #if (CPU_FAMILY == I80X86)        sysOutByte(ioAddress+3, (char)0x86);        sysIntEnablePIC(irq);    #elif CPU_FAMILY == PPC        sysOutByte(ioAddress+3, 0x86);        intEnable(irq+0x40);    #else        #warning interrupts cannot be enabled    #endif    intUnlock(oldLevel);        pDeviceEntry->ioAddress = ioAddress;    pDeviceEntry->irq       = irq;    retCode = OK;    exit:    return retCode;}/************************************************************************** esd_can_pc104_enableIrq - enable irq on board*** RETURNS: N/A*   * ERRNO: N/A**/static void esd_can_pc104_enableIrq(    struct WNCAN_Device *pDev){ #if (CPU_FAMILY == I80X86)       sysOutByte(pDev->pBrd->ioAddress+3, (char)0x86);#else       sysOutByte(pDev->pBrd->ioAddress+3, 0x86);#endif    return;}/************************************************************************** esd_can_pc104_disableIrq - disable irq on board*** RETURNS: N/A*   * ERRNO: N/A**/static void esd_can_pc104_disableIrq(    struct WNCAN_Device *pDev){    sysOutByte(pDev->pBrd->ioAddress+3, 0x06);    return;}/************************************************************************** esd_can_pc104_canInByteForI82527*** RETURNS: *   * ERRNO: **/static UCHAR esd_can_pc104_canInByteForI82527(    struct WNCAN_Device *pDev,    unsigned int offset){    sysOutByte(pDev->pBrd->ioAddress + 7,offset);    return sysInByte(pDev->pBrd->ioAddress+4);}/************************************************************************** esd_can_pc104_canOutByteForI82527*** RETURNS: *   * ERRNO: **/static void esd_can_pc104_canOutByteForI82527(    struct WNCAN_Device *pDev,    unsigned int offset,    UCHAR value){    sysOutByte(pDev->pBrd->ioAddress + 7,offset);    sysOutByte(pDev->pBrd->ioAddress + 4, value);}        /************************************************************************** esd_can_pc104_canInByteForSJA1000*** RETURNS: *   * ERRNO: **/static UCHAR esd_can_pc104_canInByteForSJA1000(    struct WNCAN_Device *pDev,    unsigned int offset){    sysOutByte(pDev->pBrd->ioAddress + 1,offset);    return sysInByte(pDev->pBrd->ioAddress);}/************************************************************************** esd_can_pc104_canOutByteForSJA1000*** RETURNS: *   * ERRNO: **/static void esd_can_pc104_canOutByteForSJA1000(    struct WNCAN_Device *pDev,    unsigned int offset,    UCHAR value){    sysOutByte(pDev->pBrd->ioAddress + 1,offset);    sysOutByte(pDev->pBrd->ioAddress, value);}/************************************************************************** esd_can_pc104_200_establishLinks - set up function pointers*** RETURNS: OK or ERROR*   * ERRNO: S_can_illegal_config**/STATUS esd_can_pc104_200_establishLinks(struct WNCAN_Device *pDev){    STATUS retCode = OK;    pDev->pBrd->onEnterISR = 0;    pDev->pBrd->onLeaveISR = 0;    pDev->pBrd->enableIrq  = esd_can_pc104_enableIrq;    pDev->pBrd->disableIrq = esd_can_pc104_disableIrq;    if(pDev->pCtrl->ctrlType == WNCAN_I82527)    {        pDev->pBrd->canInByte = esd_can_pc104_canInByteForI82527;        pDev->pBrd->canOutByte = esd_can_pc104_canOutByteForI82527;    }    else if(pDev->pCtrl->ctrlType == WNCAN_SJA1000)    {        pDev->pBrd->canInByte = esd_can_pc104_canInByteForSJA1000;        pDev->pBrd->canOutByte = esd_can_pc104_canOutByteForSJA1000;    }    else    {        errnoSet(S_can_illegal_config);        retCode = ERROR;    }    return retCode;}/************************************************************************** esd_can_pc104_200_open - open a CAN device** RETURNS: pointer to a WNCAN_Device structure or 0 if error*   * ERRNO: S_can_illegal_board_no*        S_can_illegal_ctrl_no*        S_can_busy**/struct WNCAN_Device *esd_can_pc104_200_open(UINT brdNdx, UINT ctrlNdx){    struct WNCAN_Device *pRet = 0;   /* pessimistic */        if((brdNdx >= max_esd_can_pc104_200_boards) ||       (esd_can_pc104_200_DeviceArray[brdNdx].inUse == 0))    {        errnoSet(S_can_illegal_board_no);    }    else if(ctrlNdx >= 2)    {        errnoSet(S_can_illegal_ctrl_no);    }    else if(esd_can_pc104_200_DeviceArray[brdNdx].allocated[ctrlNdx] == 1)    {        errnoSet(S_can_busy);    }    else    {        esd_can_pc104_200_DeviceArray[brdNdx].allocated[ctrlNdx] = 1;        pRet = &esd_can_pc104_200_DeviceArray[brdNdx].canDevice[ctrlNdx];    }    return pRet;}/************************************************************************** esd_can_pc104_200_close - close the CAN device** RETURNS: N/A*   * ERRNO: N/A**/void esd_can_pc104_200_close(struct WNCAN_Device *pDev){    UINT   brdNdx;    UINT   ctrlNdx;        if(pDev != 0)    {        brdNdx = ((pDev->deviceId) & 0xFFFFFF00) >> 8;        ctrlNdx = (pDev->deviceId) & 0xFF;        esd_can_pc104_200_DeviceArray[brdNdx].allocated[ctrlNdx] = 0;    }    return;}#endif

⌨️ 快捷键说明

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