Files
m241Neelima/vxworks-6.9/target/src/drv/CAN/msmcan.c
T
2026-07-30 11:19:44 +05:30

347 lines
7.0 KiB
C

/* msmcan.c - implementation of Board Interface for MSM CAN PC104 */
/* Copyright 2001, 2013 Wind River Systems, Inc. */
/*
modification history
--------------------
01b,09sep13,xms fix CHECKED_RETURN error. (WIND00414265)
01a,03sep04,??? set default baud rate to 125 Kbps
14dec01,dnb written
*/
/*
DESCRIPTION
This file contains the functions that provide a board-level interface
to the MSM CAN PC104 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/private/msmcan.h>
#if (CPU != SH7750)
static const char deviceName[] ="MSMCAN PC104";
struct MSMCAN_PC104_DeviceEntry *msmcan_pc104_DeviceArray;
UINT max_msmcan_pc104_boards;
/* external reference */
STATUS CAN_DEVICE_establishLinks(WNCAN_DEVICE *pDev, WNCAN_BoardType brdType,
WNCAN_ControllerType ctrlType);
/************************************************************************
*
* msmcan_pc104_isr - board-level isr
*
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
static void msmcan_pc104_isr
(
ULONG param
)
{
struct MSMCAN_PC104_DeviceEntry *pDE;
pDE = (struct MSMCAN_PC104_DeviceEntry *)param;
if(pDE->allocated)
{
i82527ISR((ULONG)&pDE->canDevice);
}
return;
}
/************************************************************************
*
* msmcan_pc104_enableIrq - enable irq on board
*
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
static void msmcan_pc104_enableIrq
(
struct WNCAN_Device *pDev
)
{
return;
}
/************************************************************************
*
* msmcan_pc104_disableIrq - disable irq on board
*
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
static void msmcan_pc104_disableIrq
(
struct WNCAN_Device *pDev
)
{
return;
}
/************************************************************************
*
* msmcan_pc104_200_new - install driver for pc104 board
*
*
* RETURNS: OK or ERROR
*
* ERRNO: N/A
*
*/
STATUS msmcan_pc104_new
(
ULONG ioAddress,
UINT irq
)
{
UINT i;
UINT brdNdx=0xff;
int oldLevel;
STATUS retCode;
VOIDFUNCPTR* irqVec = 0;
struct WNCAN_Device *pDev;
struct MSMCAN_PC104_DeviceEntry *pDeviceEntry;
retCode = ERROR; /* pessimistic */
pDeviceEntry = 0;
/* find a free device data structure */
for(i = 0 ; i < max_msmcan_pc104_boards; i++)
{
if(msmcan_pc104_DeviceArray[i].inUse == 0)
{
msmcan_pc104_DeviceArray[i].inUse = 1;
pDeviceEntry = &msmcan_pc104_DeviceArray[i];
brdNdx = i;
break;
}
}
if(!pDeviceEntry)
{
errnoSet(S_can_out_of_memory);
goto exit;
}
/* setup data structures */
pDev = &pDeviceEntry->canDevice;
pDev->pCtrl = &pDeviceEntry->canController;
pDev->pBrd = &pDeviceEntry->canBoard;
pDev->deviceName = deviceName;
pDev->pBrd->irq = irq;
pDev->pBrd->ioAddress = ioAddress;
pDev->pBrd->xtalFreq = _16MHZ;
/* set default baud rate to 125 Kbits/sec */
pDev->pCtrl->brp = 3;
pDev->pCtrl->sjw = 0;
pDev->pCtrl->tseg1 = 0xc;
pDev->pCtrl->tseg2 = 0x1;
pDev->pCtrl->samples = 0;
pDev->pCtrl->chnType = g_i82527chnType;
pDev->pCtrl->chnMode = &pDeviceEntry->i82527chnMode[0];
pDev->pCtrl->numChn = I82527_MAX_MSG_OBJ;
pDev->pCtrl->csData = &pDeviceEntry->can82527;
if(CAN_DEVICE_establishLinks(pDev, WNCAN_MSMCAN, WNCAN_I82527) == ERROR)
{
pDev = 0;
goto exit;
}
pDev->deviceId = brdNdx; /* index into deviceEntry array */
/* 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
/* don't need return from function call */
(void) intConnect(irqVec,msmcan_pc104_isr, (ULONG)pDeviceEntry);
/* activate interrupt at board and cpu level */
#if (CPU_FAMILY == I80X86)
sysIntEnablePIC(pDev->pBrd->irq);
#elif CPU_FAMILY == PPC
intEnable(pDev->pBrd->irq+0x40);
#else
#warning interrupts cannot be enabled
#endif
intUnlock(oldLevel);
pDeviceEntry->ioAddress = ioAddress;
pDeviceEntry->irq = irq;
retCode = OK;
exit:
return retCode;
}
/************************************************************************
*
* msmcan_pc104_canInByte
*
*
* RETURNS:
*
* ERRNO:
*
*/
static UCHAR msmcan_pc104_canInByte
(
struct WNCAN_Device *pDev,
unsigned int offset
)
{
sysOutByte(pDev->pBrd->ioAddress + 1,offset);
return sysInByte(pDev->pBrd->ioAddress);
}
/************************************************************************
*
* msmcan_pc104_canOutByte
*
*
* RETURNS:
*
* ERRNO:
*
*/
static void msmcan_pc104_canOutByte
(
struct WNCAN_Device *pDev,
unsigned int offset,
UCHAR value
)
{
sysOutByte(pDev->pBrd->ioAddress + 1,offset);
sysOutByte(pDev->pBrd->ioAddress, value);
}
/************************************************************************
*
* msmcan_pc104_establishLinks - set up function pointers
*
*
* RETURNS: OK always
*
* ERRNO: N/A
*
*/
STATUS msmcan_pc104_establishLinks(struct WNCAN_Device *pDev)
{
pDev->pBrd->onEnterISR = 0;
pDev->pBrd->onLeaveISR = 0;
pDev->pBrd->enableIrq = msmcan_pc104_enableIrq;
pDev->pBrd->disableIrq = msmcan_pc104_disableIrq;
pDev->pBrd->canInByte = msmcan_pc104_canInByte;
pDev->pBrd->canOutByte = msmcan_pc104_canOutByte;
return OK;
}
/************************************************************************
*
* msmcan_pc104_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 *msmcan_pc104_open(UINT brdNdx, UINT ctrlNdx)
{
struct WNCAN_Device *pRet = 0; /* pessimistic */
if((brdNdx >= max_msmcan_pc104_boards) ||
(msmcan_pc104_DeviceArray[brdNdx].inUse == 0))
{
errnoSet(S_can_illegal_board_no);
}
else if(msmcan_pc104_DeviceArray[brdNdx].allocated == 1)
{
errnoSet(S_can_busy);
}
else if(ctrlNdx >= MSMCAN_PC104_MAX_CONTROLLERS)
{
errnoSet(S_can_illegal_ctrl_no);
}
else
{
msmcan_pc104_DeviceArray[brdNdx].allocated = 1;
pRet = &msmcan_pc104_DeviceArray[brdNdx].canDevice;
}
return pRet;
}
/************************************************************************
*
* msmcan_pc104_close - close the specified CAN device
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
void msmcan_pc104_close(struct WNCAN_Device *pDev)
{
UINT brdNdx;
if (pDev != 0)
{
brdNdx = pDev->deviceId;
msmcan_pc104_DeviceArray[brdNdx].allocated = 0;
}
return;
}
#endif