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

📄 i82527.c

📁 CANOPen通信的一些源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		chipStuff->errorInt = FALSE;		        if(intMask & WNCAN_INT_WAKE_UP)		chipStuff->wakeUpInt = TRUE;	else		chipStuff->wakeUpInt = FALSE;			if((chipStuff->wakeUpInt == TRUE) || (chipStuff->errorInt == TRUE))		regCtrl |= I82527_B_SIE;	else		regCtrl &= ~I82527_B_SIE;		/*     The error warning interrupt is generated when errors on the bus exceed     warning limits and if the controller becomes bus off. The interrupt      is also raised when the controller goes into error active state from      being bus off	*/	if(intMask & WNCAN_INT_BUS_OFF)	{		chipStuff->busOffInt = TRUE;	        regCtrl |= I82527_B_EIE;	}	else	{		chipStuff->busOffInt = FALSE;		regCtrl &= ~I82527_B_EIE;	}		oldLevel = intLock();		pDev->pBrd->canOutByte(pDev, I82527_R_CTRL, regCtrl);	        intUnlock(oldLevel);    }    return retCode;}/************************************************************************** I82527_EnableInt - enable CAN interrupts** This routine enables CAN interrupts on the controller.** RETURNS: N/A*   * ERRNO:   N/A**/static void I82527_EnableInt      (	  struct WNCAN_Device *pDev	  ){    UCHAR       regCtrl;    int         oldLevel;    oldLevel = intLock();        /* read the control register */    regCtrl = pDev->pBrd->canInByte(pDev, I82527_R_CTRL);    	regCtrl |= I82527_B_IE;    /* write control register */    pDev->pBrd->canOutByte(pDev, I82527_R_CTRL, regCtrl);    intUnlock(oldLevel);    return;}/************************************************************************** I82527_DisableInt - disable CAN interrupts** This routine disbles interrupts on the controller.** RETURNS: N/A*   * ERRNO:   N/A**/static void I82527_DisableInt      (	  struct WNCAN_Device *pDev	  ){    int    oldLevel;    UCHAR  regCtrl;    oldLevel = intLock();        regCtrl = pDev->pBrd->canInByte(pDev, I82527_R_CTRL);    	regCtrl &= ~I82527_B_IE;    /* write control register */    pDev->pBrd->canOutByte(pDev, I82527_R_CTRL, regCtrl);    intUnlock(oldLevel);    return;}/************************************************************************** I82527_GetBusStatus - get the bus status** This routine returns the status of the CAN bus. The bus is  either in a* WNCAN_BUS_OFF state resulting from an excessive number of errors, a * WNCAN_BUS_WARN state indicating that there is an abnormal rate of * occurances of errors. ** RETURNS: status of the CAN bus = WNCAN_BUS_OK, WNCAN_BUS_WARN, *          or WNCAN_BUS_OFF*   * ERRNO: N/A**/static WNCAN_BusStatus I82527_GetBusStatus      (	  struct WNCAN_Device *pDev	  ){    /* read the status register */    WNCAN_BusStatus regStatus = pDev->pBrd->canInByte(pDev, I82527_R_SR);    if(regStatus & I82527_B_BOFF)        return(WNCAN_BUS_OFF);    else if (regStatus & I82527_B_WARN)        return(WNCAN_BUS_WARN);    else        return(WNCAN_BUS_OK);}/************************************************************************** I82527_GetBusError - get the bus error** This routine returns the first bus error.** RETURNS: the first bus error*   * ERRNO: N/A**/static WNCAN_BusError I82527_GetBusError      (	  struct WNCAN_Device *pDev	  ){   WNCAN_BusError    error;   UCHAR       regStatus;   /* read the status register */   regStatus = pDev->pBrd->canInByte(pDev, I82527_R_SR);    switch(regStatus & 0x07)    {        case 1:            error = WNCAN_ERR_STUFF;            break;        case 2:            error = WNCAN_ERR_FORM;            break;        case 3:            error = WNCAN_ERR_ACK;            break;        case 4:            error = WNCAN_ERR_BIT; /* Bit1 error */            break;        case 5:            error = WNCAN_ERR_BIT; /* Bit0 error */            break;        case 6:            error = WNCAN_ERR_CRC;            break;        default:            error = WNCAN_ERR_NONE;            break;    }       return error;}/************************************************************************** I82527_GetIntStatus - get the interrupt status on the controller** This routine gets the interrupt status of the controller.* If the interrupt was caused by the transmission or reception of a * message, the channel number that generated the interrupt is set. * Otherwise, the channelNum value is set to an invalid channel number.** RETURNS: the interrupt status = WNCAN_INT_NONE, WNCAN_INT_ERROR,*          WNCAN_INT_TX, or WNCAN_INT_RX*   * ERRNO: N/A**/static WNCAN_IntType I82527_GetIntStatus( struct WNCAN_Device *pDev, UCHAR *channelNum ){	    WNCAN_IntType   intStatus=WNCAN_INT_NONE;    UCHAR       tmpCTRL0;    UCHAR       regInt;    UCHAR       regStatus = WNCAN_INT_NONE;	    struct  i82527ChipSpecific *chipStuff;	    regInt = pDev->pBrd->canInByte(pDev, I82527_R_INT);    	    if(regInt == 0)    {      intStatus = WNCAN_INT_NONE;    }    else if(regInt == 1)    {		/* Set default values in chip specific struct*/		chipStuff = (struct i82527ChipSpecific *)pDev->pCtrl->csData;					/* read the status register */		regStatus = pDev->pBrd->canInByte(pDev, I82527_R_SR);					/*		A status change interrupt has occurred		Unless the user is directly accessing the CAN controller's 		registers, this indicates that the user wants notification of		a BUS OFF, WAKE UP or error interrupt.		I82527 does not have separate interrupt sources for these conditions.		Therefore, the status register must be checked and the correct cause		of the status update returned.		*/		if((chipStuff->wakeUpInt == TRUE) && (regStatus & I82527_B_WAKE))			intStatus = WNCAN_INT_WAKE_UP;						if((chipStuff->busOffInt == TRUE) && (regStatus & I82527_B_BOFF))			intStatus = WNCAN_INT_BUS_OFF;						if((chipStuff->errorInt == TRUE) && (regStatus & 0x07))			intStatus = WNCAN_INT_ERROR;				/*		If neither of the above three conditions are true, the status change		must have been due to a transmission or reception.		We want this status change interrupt ignored. Tx / Rx interrupts should		be flagged by channel interrupt pending bits, therefore the interrupt		status is set to WNCAN_INT_SPURIOUS		*/		if(intStatus == WNCAN_INT_NONE)			intStatus = WNCAN_INT_SPURIOUS;		    }    else if(regInt == 2)    {        *channelNum = 14;        intStatus = WNCAN_INT_RX;    }    else if(regInt <= 0x10)    {        *channelNum = regInt - 3;		        /* reading the control register 0 */        tmpCTRL0 = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +             (I82527_OFFS_MSG * (*channelNum)) + I82527_OFFS_CTRL0));			/* checking if this is an receive interrupt 	(on message object 1 to 14) */        if (tmpCTRL0 & 0x08)        {            intStatus = WNCAN_INT_RX;        }        else        {            intStatus = WNCAN_INT_TX;        }    }    else    {        intStatus = WNCAN_INT_SPURIOUS; /* unallowed interrupt (should not happen) */    }	    return intStatus;}/************************************************************************** I82527_ReadID - read the CAN Id** This function reads the CAN Id corresponding to the channel number on* the controller. The standard or extended flag is set by the function.* The mode of the channel cannot be WNCAN_CHN_INACTIVE or WNCAN_CHN_INVALID** RETURNS:    The CAN Id, or -1 if an input parameter is invalid** ERRNO:      S_can_illegal_channel_no*             S_can_illegal_config**/static long I82527_ReadID(struct WNCAN_Device *pDev, UCHAR channelNum, BOOL* ext){    UCHAR    value;    unsigned long  msgID=0; /* invalid msg id */	    if (channelNum >= I82527_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);				return(-1);    }    	if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) ||		(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID))    {        errnoSet(S_can_illegal_config);        		return(-1);    }	/* mark this message object as invalid */	pDev->pBrd->canOutByte(pDev, (I82527_R_XMT +		(I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0x7f);		/* read the message configuration register to determine if the message	is standard or extended */	value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +		(I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR));		if (value & 0x4)	{		/* extended CAN message ID */		*ext = TRUE;		value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT));				msgID = value << 24;   				value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 1));				msgID |= value << 16;   						value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 2));				msgID |= value << 8;   						value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT+ 3));				msgID |= value;		msgID >>= 3;	}	else	{		/* standard CAN message ID */		*ext = FALSE;		value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT));				msgID = value << 8;   				value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 1));				msgID |= value;   		msgID >>= 5;	}		/* mark this message object as valid */	pDev->pBrd->canOutByte(pDev, (I82527_R_XMT +		(I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0xbf);        return(msgID);}/************************************************************************** I82527_WriteID - write the CAN Id  to the channel number ** This function writes the CAN Id to the channel. The type of Id * (standard or extended) is specified. the behaviour of the function for* every channel mode is specified as follows:* WNCAN_CHN_INVALID: not allowed. ERROR is returned.* WNCAN_CHN_INACTIVE: not allowed. ERROR is returned.* WNCAN_CHN_RECEIVE: CAN messages with this Id will be received.* WNCAN_CHN_TRANSMIT: CAN meesage with the specified ID will be transmitted* when CAN_Tx is called* WNCAN_CHN_RTR_REQUESTER: CAN message with this id and RTR bit set will* be transmitted when CAN_TX is called* WNCAN_CHN_RTR_RESPONDER: CAN message with this id will be automatically* transmitted when a matching RTR request is received. CAN_WriteData should* be called to set up data for response.*** RETURNS:        OK, or ERROR** ERRNO:          S_can_illegal_channel_no,*                 S_can_illegal_config**/static STATUS I82527_WriteID      (	  struct WNCAN_Device *pDev,	  UCHAR channelNum,	  unsigned long canId,	  BOOL ext	  ){    STATUS retCode = ERROR; /* pessimistic */    UCHAR  value;	UCHAR  prevState;	        if (channelNum >= I82527_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);    }    else if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) ||		(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID))    {        errnoSet(S_can_illegal_config);            }    else    {				/*Check if EnableChannel has been called earlier and channel		marked as valid. If yes, store state to restore later */		prevState = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0));		/*		mark message object as invalid:            MsgVal   = 0 1		unchanged transmit interrupt enable:       TXIE     = 1 1 		unchanged receive interrrupt enable:       RXIE     = 1 1		reset interrupt pending:                   IntPnd   = 0 1		7 6      5 4   3 2   1 0		MsgVal   TXIE  RXIE  IntPnd		*/				pDev->pBrd->canOutByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0x7d);			/* 		remote transmission pending unchanged  RmtPnd = 0 1		reset transmit request:                TxRqst = 0 1		reset new data:                        NewDat = 0 1		set CPU update :                       CPUUpd = 1 0			7 6      5 4      3 2      1 0		RmtPnd   TxRqst   NewDat   CPUUpd 		*/			pDev->pBrd->canOutByte(pDev, (I82527_R_XMT +			(I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1), 0x56);					if (ext == FALSE)        {            /* standard message */            value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT +

⌨️ 快捷键说明

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