?? esd_pc104_200.c
字號(hào):
/* 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
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -