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

📄 esd_pc104_200.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
字号:
/* esd_can_pc104_200.c - implementation of Board Interface for ESD CAN PC104/200 */

/* Copyright 2001 Wind River Systems, Inc. */

/* 
modification history 
--------------------
01b,03sep04,lag set default baud rate to 125 Kbps
01a,27nov01,dnb written

*/

/* 

  DESCRIPTION
  This file contains the functions that provide a board-level interface
  to 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;

    sja1000ISR((ULONG)&pDE->canDevice[0]);

}

/************************************************************************
*
* 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 < 1/*ESD_CAN_PC104_200_MAX_CONTROLLERS */; 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 =12000000/* _16MHZ*/; /*12M*/

	/* set default baud rate to 125 Kbits/sec */
	pDev[i]->pCtrl->brp = 0x42/*3*/;       
	pDev[i]->pCtrl->sjw = 0;  
	pDev[i]->pCtrl->tseg1 = 0xc;
	pDev[i]->pCtrl->tseg2 = 0x1;
	pDev[i]->pCtrl->samples = 0;

	pDev[i]->pCtrl->chnType = g_sja1000chnType;
	pDev[i]->pCtrl->numChn  = SJA1000_MAX_MSG_OBJ;
	pDev[i]->pCtrl->chnMode = &pDeviceEntry->sja1000chnMode[0];
	pDev[i]->pCtrl->csData  = &pDeviceEntry->txMsg;

    }
	
    if(CAN_DEVICE_establishLinks(pDev[0], 
        WNCAN_ESD_PC104_200, WNCAN_SJA1000) == ERROR)
    {
        pDev[0] = 0;
        goto exit;
    }
    
    pDev[0]->deviceId = (brdNdx << 8);            
    
     intConnect(irq,esd_can_pc104_200_isr,(ULONG)pDeviceEntry);
    sysIntEnablePIC(irq);

    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: 
*
*/
UCHAR esd_can_pc104_canInByteForSJA1000
(
 struct WNCAN_Device *pDev,
 unsigned int offset
 )
{	
	*(volatile UINT8 *)(pDev->pBrd->ioAddress) = offset;
	
	return *(volatile UINT8 *)(pDev->pBrd->ioAddress+0x100000);
}

/************************************************************************
*
* esd_can_pc104_canOutByteForSJA1000
*
*
* RETURNS: 
*   
* ERRNO: 
*
*/
void esd_can_pc104_canOutByteForSJA1000
(
 struct WNCAN_Device *pDev,
 unsigned int offset,
 UCHAR value
 )
{
	*(volatile UINT8 *)(pDev->pBrd->ioAddress) = offset;
	
	*(volatile UINT8 *)(pDev->pBrd->ioAddress+0x100000) = value;

}

void sja1000_out(int offset,UINT8 value)
{
	*(volatile UINT8 *)(0xffa00000) = offset;
	
	*(volatile UINT8 *)(0xffb00000) = value;

}
UINT8 sja1000_in(int offset)
{
	*(volatile UINT8 *)(0xffa00000) = offset;
	
	return *(volatile UINT8 *)(0xffb00000);
}

/************************************************************************
*
* 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;
    }
 */   
     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 >= 1/*ESD_CAN_PC104_200_MAX_CONTROLLERS*/)
    {
        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 + -