📄 ppc5xxcan.c
字号:
/* ppc5xxCAN.c - implementation of Board Interface for PPC5XX *//* Copyright 2001 Wind River Systems, Inc. *//* modification history --------------------14jan02,lsg written*//* DESCRIPTIONThis file contains the functions that provide a board-level interfaceto the PPC5xx.*//* includes */#include <vxWorks.h>#include <errnoLib.h>#include <intLib.h>#include <iv.h>#include <sysLib.h>#include <CAN/wnCAN.h>#include <CAN/canController.h>#include <CAN/canBoard.h>#if (CPU==PPC555)#include <CAN/toucan.h>#include <CAN/PRIVATE/ppc5xxCAN.h>static const char ppc5xxCAN_deviceName[] ="PPC5xx CAN Controller";#define VECTOR_TABLE_OFFSET_FROM_LEVEL(n) (2*n + 1)UINT max_ppc5xx_can_devices;struct ppc5xxCAN_DeviceEntry *ppc5xxCAN_DeviceArray;/*external references*/ extern UINT32 vxImemBaseGet(void);extern STATUS CAN_DEVICE_establishLinks(WNCAN_DEVICE *pDev, WNCAN_BoardType brdType,WNCAN_ControllerType ctrlType);extern void TouCANISR(ULONG context);/************************************************************************** ppc5xxCAN_new - install driver for ppc board*** RETURNS: OK or ERROR* * ERRNO: N/A**/STATUS ppc5xxCAN_new(XtalFreq xf, UINT ppc5xxIlevel, UINT ppc5xxRxmode, UINT ppc5xxTxmode, UINT devnum){ int oldLevel; STATUS retCode; struct WNCAN_Device *pDev; struct ppc5xxCAN_DeviceEntry *pDeviceEntry; struct canAccess *pcanAccess; UINT32 tblOffset = 0; volatile USHORT irl = 0; volatile USHORT ilbs = 0; retCode = ERROR; /* pessimistic */ pDeviceEntry = 0; /* find a free device data structure */ if(ppc5xxCAN_DeviceArray[devnum].inUse == 0) { ppc5xxCAN_DeviceArray[devnum].inUse = 1; pDeviceEntry = &ppc5xxCAN_DeviceArray[devnum]; if(!pDeviceEntry) { errnoSet(S_can_out_of_memory); goto exit; } }/*if device in use ends*/ /* setup data structures */ pDev = &pDeviceEntry->canDevice; pDev->pCtrl = &pDeviceEntry->canController; pDev->pBrd = &pDeviceEntry->canBoard; /*Initialise parameters in the WNCAN_Board struct*/ /*Oscillator frequency is fixed for a particular board */ pDev->pBrd->xtalFreq = xf; /*Initialise all other non applicable parameters to 0 value*/ pDev->pBrd->irq = 0; pDev->pBrd->ioAddress = 0; pDev->pBrd->bar0 = 0; pDev->pBrd->bar1 = 0; pDev->pBrd->bar2 = 0; /* * The rest of the members of the WNCAN_Board struct, * namely the function pointers will be assigned values * by calling CAN_Device_establishLinks shortly */ /* * Initialise parameters in the WNCAN_CanController struct * for each CAN controller contained in the board */ pDev->pCtrl->ctrlID = (UCHAR)devnum; pDev->pCtrl->pDev = pDev; pDev->pCtrl->chnType = &g_TOUCANchnType[0]; pDev->pCtrl->numChn = TOUCAN_MAX_MSG_OBJ; pDev->pCtrl->chnMode = &pDeviceEntry->TouCANchnMode[0]; pDev->pCtrl->csData = &pDeviceEntry->canRegAccess; /* * Get pointer to TouCAN registers. */ pcanAccess = (struct canAccess *)pDev->pCtrl->csData; pcanAccess->pTouCanRegs = (TouCAN)(TOUCAN_CHANNEL_A_BASE + (pDev->pCtrl->ctrlID * TOUCAN_REGS_OFFSET)); pcanAccess->pTouCanBufs = (TouCANBuf)(TOUCAN_BUFFERS_A_BASE + (pDev->pCtrl->ctrlID * TOUCAN_REGS_OFFSET)); pcanAccess->TouCANAutoPowersSave = 0; pcanAccess->TouCANSupv = 0; pcanAccess->TouCANLBuf = TOUCAN_LBUF_LOWEST_ID_FIRST; pcanAccess->TouCANTimerSync = TOUCAN_TSYNC_ENABLE; /*Initialise hardware related controller parameters*/ /************************************************************************/ /* Compute ILBS and IRL values from user chosen ILEVEL */ /* * TouCAN_ILEVEL can have a value between 0 and 31, as there are 32 possible * interrupt levels. The value of IRL is the least significant three bits * and ILBS is the first two most significant bits * TouCAN_ILEVEL -> 4 3 2 1 0 * ilbs irl */ irl = ((USHORT)ppc5xxIlevel) & 0x7; ilbs = ((USHORT)ppc5xxIlevel & 0x0018) >> 3; pcanAccess->pTouCanRegs->can_ICR = (USHORT)((irl << 8) | (ilbs << 6)); /*Set RxMode and TxMode*/ pcanAccess->pTouCanRegs->can_CR0 = (ppc5xxRxmode << 2) | ppc5xxTxmode; /*Set default baud rate to 250 Kbp/s*/ /*Assuming a sys clock frequency of 40 MHz*/ /* * These value will be directly written into the control regsiters. The values have been * decremented by 1 * 1 bittime = 1 + (PROPSEG + 1) + (TSEG1 + 1) + (TSEG2 + 1) time quanta */ pcanAccess->ToucanPropseg = 7; pDev->pCtrl->brp = 7; pDev->pCtrl->sjw = 0; pDev->pCtrl->tseg1 = 7; pDev->pCtrl->tseg2 = 2; pDev->pCtrl->samples = 0; if(CAN_DEVICE_establishLinks(pDev, WNCAN_PPC5XX, WNCAN_TOUCAN) == ERROR) { pDev = 0; goto exit; } /*Assign the device name and id*/ pDev->deviceName = ppc5xxCAN_deviceName; /*brdnum is 0*/ pDev->deviceId = devnum; /* connect to isr */ oldLevel = intLock(); tblOffset = VECTOR_TABLE_OFFSET_FROM_LEVEL(ppc5xxIlevel); intConnect((void *)tblOffset,TouCANISR,(ULONG)pDev); intUnlock(oldLevel); retCode = OK;exit: return retCode;}/************************************************************************** ppc5xxCAN_establishLinks - set up function pointers*** RETURNS: OK always* * ERRNO: N/A**/STATUS ppc5xxCAN_establishLinks(struct WNCAN_Device *pDev){ pDev->pBrd->onEnterISR = 0; pDev->pBrd->onLeaveISR = 0; pDev->pBrd->enableIrq = 0; pDev->pBrd->disableIrq = 0; pDev->pBrd->canInByte = 0; pDev->pBrd->canOutByte = 0; return OK;}/************************************************************************** ppc5xxCAN_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 *ppc5xxCAN_open(UINT deviceNdx){ struct WNCAN_Device *pRet = 0; /* pessimistic */ if((deviceNdx >= max_ppc5xx_can_devices) || (ppc5xxCAN_DeviceArray[deviceNdx].inUse == 0)) { errnoSet(S_can_illegal_board_no); } else if(ppc5xxCAN_DeviceArray[deviceNdx].allocated == 1) { errnoSet(S_can_busy); } else { ppc5xxCAN_DeviceArray[deviceNdx].allocated = 1; pRet = &ppc5xxCAN_DeviceArray[deviceNdx].canDevice; } return pRet;}/************************************************************************** ppc5xxCAN_close - close a CAN device** RETURNS: OK or ERROR* * ERRNO: S_can_illegal_board_no* S_can_illegal_ctrl_no**/STATUS ppc5xxCAN_close( struct WNCAN_Device *pDev){ STATUS retVal = ERROR; /* pessimistic */ UINT deviceNdx; if(pDev != 0) { deviceNdx = (pDev->deviceId) & 0xFF; if((deviceNdx >= max_ppc5xx_can_devices) || (ppc5xxCAN_DeviceArray[deviceNdx].inUse == 0)) { errnoSet(S_can_illegal_ctrl_no); } else { ppc5xxCAN_DeviceArray[deviceNdx].allocated = 0; retVal = OK; } } return retVal;}#endif /* CPU == PPC555 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -