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

📄 sja1000.c

📁 can总线c语言 canopen 源程序
💻 C
📖 第 1 页 / 共 4 页
字号:
** ERRNO:   N/A**/static void SJA1000_DisableInt(struct WNCAN_Device *pDev){    int    oldLevel;    oldLevel = intLock();    pDev->pBrd->canOutByte(pDev, SJA1000_IER, 0);    intUnlock(oldLevel);    return;}/************************************************************************** SJA1000_GetBusError - get the bus error** This function returns an ORed bit mask of all the bus errors that have* occured during the last bus activity.* Bus errors returned by this function can have the following values:* WNCAN_ERR_NONE: No errors detected* WNCAN_ERR_BIT: Bit error. * WNCAN_ERR_ACK: Acknowledgement error. * WNCAN_ERR_CRC: CRC error* WNCAN_ERR_FORM: Form error* WNCAN_ERR_STUFF: Stuff error* WNCAN_ERR_UNKNOWN: this condition should not occur* The five errors are not mutually exclusive. * The occurence of an error will be indicated by an interrupt. Typically, * this function will be called from the error interrupt handling case in the* user's ISR callback function, to find out the kind of error that occured* on the bus.** RETURNS: the bus error** ERRNO: N/A**/static WNCAN_BusError SJA1000_GetBusError(struct WNCAN_Device *pDev){    UCHAR value;    WNCAN_BusError error=0;    /* read the error code capture register */    value = pDev->pBrd->canInByte(pDev, SJA1000_ECC);    switch(value >> 6)    {        case 0:            error |= WNCAN_ERR_BIT;            break;        case 1:            error |= WNCAN_ERR_FORM;            break;        case 2:            error |= WNCAN_ERR_STUFF;            break;        case 3:            switch(value & 0x1F)            {                case 8:                    error |= WNCAN_ERR_CRC;                    break;                case 24:                    error |= WNCAN_ERR_CRC;                    break;                case 25:                    error |= WNCAN_ERR_ACK;                    break;                case 27:                    error |= WNCAN_ERR_ACK;                    break;                default:                    error |= WNCAN_ERR_NONE;                    break;            }            break;    }    return error;}/************************************************************************** SJA1000_GetIntStatus - get the interrupt status on the controller** This function returns the interrupt status on the controller: **    WNCAN_INT_NONE     = no interrupt occurred*    WNCAN_INT_ERROR    = bus error*    WNCAN_INT_TX       = interrupt resuting from a CAN transmission*    WNCAN_INT_RX       = interrupt resulting form message reception*    WNCAN_INT_BUS_OFF  = interrupt resulting from bus off condition*    WNCAN_INT_WAKE_UP  = interrupt resulting from controller waking up*                         after being put in sleep mode*    WNCAN_INT_SPURIOUS = unknown interrupt** NOTE: If the interrupt was caused by the transmission or reception of a * message, the channel number that generated the interrupt is set; otherwise,* this value is undefined.** ERRNO: N/A**/static WNCAN_IntType SJA1000_GetIntStatus      (	  struct WNCAN_Device *pDev,	  UCHAR *channelNum	  ){    UCHAR       regInt;    WNCAN_IntType   intStatus=WNCAN_INT_NONE;	UCHAR regStatus;    /* read the interrupt register */    regInt = pDev->pBrd->canInByte(pDev, SJA1000_IR);	if(regInt & IR_RI) {		/*receive interrupt*/        intStatus = WNCAN_INT_RX;        *channelNum = 0;	}		if( regInt & IR_TI) {		/*transmit interrupt*/        intStatus = WNCAN_INT_TX;        *channelNum = 1;	}	if(regInt & IR_WUI)	{		intStatus = WNCAN_INT_WAKE_UP;	}	/*flag WNCAN_INT_ERROR, if data overrun error int, or	  bus error int is detected */	if(regInt & IR_BEI) {		/*error interrupt*/        intStatus = WNCAN_INT_ERROR;	}	if(regInt & IR_EI) {		/*bus off interrupt*/		/* read the status register */        regStatus = pDev->pBrd->canInByte(pDev, SJA1000_SR);		if(regStatus & SR_BS)			intStatus = WNCAN_INT_BUS_OFF;	}	    return intStatus;}/************************************************************************** sja1000ISR - interrupt service routine** RETURNS: N/A** ERRNO: N/A**/void sja1000ISR(ULONG context){    WNCAN_DEVICE     *pDev;    WNCAN_IntType  intStatus=WNCAN_INT_NONE;    UCHAR          chnNum;	    pDev = (WNCAN_DEVICE *)context;    /* notify board that we're entering isr */    if(pDev->pBrd->onEnterISR)        pDev->pBrd->onEnterISR(pDev);    /* Get the interrupt status */    intStatus = SJA1000_GetIntStatus((void*)context, &chnNum);	 if (intStatus != WNCAN_INT_NONE)	 {		 		 pDev->pISRCallback(pDev, intStatus, chnNum);		 		 if (intStatus == WNCAN_INT_RX)		 {			 /* release the receive buffer */			 /* this will temporarily cleat RI bit */			 pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_RRB);		 }		 else if (intStatus == WNCAN_INT_ERROR)		 {			 /* clear bei interrupt flag */			 pDev->pBrd->canInByte(pDev, SJA1000_ECC);		 }	 }		    /* notify board that we're leaving isr */    if(pDev->pBrd->onLeaveISR)        pDev->pBrd->onLeaveISR(pDev);   return;}/************************************************************************** SJA1000_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:        LONG: the CAN Id; on error return -1** ERRNO:          S_can_illegal_channel_no,*                 S_can_illegal_config**/static long SJA1000_ReadID(struct WNCAN_Device *pDev, UCHAR channelNum,                            BOOL* ext){    UCHAR           value;    struct TxMsg    *pTxMsg;    ULONG           msgID=0xffffffff;    if (channelNum >= SJA1000_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    {        /* Set up frame and ID registers based on channel mode */        if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE)        {            /* get the frame format */            value = pDev->pBrd->canInByte(pDev, SJA1000_SFF);            /* test if message ID is extended or standard */            if (value & 0x80)            {                *ext = 1;                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID);                msgID = (value << (24-3));                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID+1);                msgID |= (value << (16-3));                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID+2);                msgID |= (value << (8-3));                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID+3);                msgID |= (value >> 3);            }            else            {                *ext = 0;                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID);                msgID = (value << (8-5));                value = pDev->pBrd->canInByte(pDev,SJA1000_RXID+1);                msgID |= (value >> 5);            }        }        else        {            pTxMsg = (struct TxMsg *)pDev->pCtrl->csData;            *ext = pTxMsg->ext;            msgID = pTxMsg->id;        }    }    return ((long) msgID);}/************************************************************************** SJA1000_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** If this function is called while the controller is online, receive errors* may occur while the receive buffer id is being changed. *** RETURNS:        OK, or ERROR** ERRNO:          S_can_illegal_channel_no,*                 S_can_illegal_config**/static STATUS SJA1000_WriteID(struct WNCAN_Device *pDev, UCHAR channelNum,                             unsigned long canId, BOOL ext){	struct TxMsg    *pTxMsg;    UCHAR           value, regVal, rxIEOff;     	    STATUS          retCode = ERROR; /* pessimistic */		    if (channelNum >= SJA1000_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    {        if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE)        {			/*check if receive interrupts are turned on. If yes, disable			interrupts */			regVal = pDev->pBrd->canInByte(pDev,SJA1000_IER);			if(regVal & IER_RIE)			{				rxIEOff = regVal & ~(IER_RIE);				pDev->pBrd->canOutByte(pDev, SJA1000_IER, rxIEOff);							}			            if (ext == TRUE)            {                value = canId >> (24-3);                pDev->pBrd->canOutByte(pDev, SJA1000_ACR0, value);                value = canId >> (16-3);                pDev->pBrd->canOutByte(pDev, SJA1000_ACR1, value);                value = canId >> (8-3);                pDev->pBrd->canOutByte(pDev, SJA1000_ACR2, value);                value = canId << 3;                pDev->pBrd->canOutByte(pDev, SJA1000_ACR3, value);				            }            else            {                value = canId >> 3;                pDev->pBrd->canOutByte(pDev, SJA1000_ACR0, value);                value = canId << 5;                pDev->pBrd->canOutByte(pDev, SJA1000_ACR1, value);							}			            /* restore receive interrupts if previously set*/			if(regVal & IER_RIE)			{				pDev->pBrd->canOutByte(pDev, SJA1000_IER, regVal);			}			                    }        else        {            pTxMsg = (struct TxMsg *)pDev->pCtrl->csData;            pTxMsg->id = canId;            pTxMsg->ext = ext;        }		        retCode = OK;    }	    return retCode;}/************************************************************************** SJA1000_ReadData - read 0 to 8 bytes of data from channel** This function reads "len" bytes of data from the channel and sets the value* of len to the number of bytes read. The range of "len" is zero (for zero * length data) to a maximum of eight. The mode of the channel must not be * WNCAN_CHN_INVALID or WNCAN_CHN_INACTIVE; however, the newData flag is valid * WNCAN_CHN_RECEIVE channel mode.* For receive channels, if no new data has been received since the last* CAN_ReadData  function call, the newData flag is set to FALSE; * otherwise, the flag is TRUE. In both cases, the data and length of the* data currently in the channel are read. ** RETURNS:        OK, or ERROR** ERRNO:          S_can_illegal_channel_no,*                 S_can_illegal_config,*                 S_can_buffer_overflow,*                 S_can_null_input_buffer**/static STATUS SJA1000_ReadData(struct WNCAN_Device *pDev, UCHAR channelNum,                       UCHAR *data, UCHAR *len, BOOL *newData){    UCHAR           value;    UCHAR           hwLength=0;    UINT            i;    UINT            offset;    struct TxMsg    *pTxMsg;    STATUS          retCode = ERROR; /* pessimistic */    if (channelNum >= SJA1000_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    {        if(data == NULL)        {         errnoSet(S_can_null_input_buffer);	     return retCode;             }        if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE)        {            /* get the frame info and read the data */            value = pDev->pBrd->canInByte(pDev, SJA1000_SFF);            offset = (value & 0x80)? 2 : 0;            hwLength = value & 0xF;            if (hwLength > *len)            {             /*              If the actual number of bytes in the message are greater than              expected bytes by user, set error no and do not copy message              DLC into *len             */             errnoSet(S_can_buffer_overflow);            }            else            {             /*If the message DLC and the expected data length is equal,               copy message DLC into *len and continue */               *len = hwLength;               retCode = OK;            }            for (i = 0; i < *len; i++)                data[i] = pDev->pBrd->canInByte(pDev, (SJA1000_SFDATA + i + offset));            /* check the status register to see if the message was new */            value = pDev->pBrd->canInByte(pDev, SJA1000_SR);            if(value & SR_RBS)            {                *newData = 1;                /* release the receive buffer */                pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_RRB);            }            else                *newData = FALSE;        }        else        {            pTxMsg = (struct TxMsg *)pDev->pCtrl->csData;						/*transmit channel*/			/*check for overflow*/			if(pTxMsg->len > *len)			{				errnoSet(S_can_buffer_overflow);			}			else			{				*len = pTxMsg->len;				retCode = OK;			}            			for(i = 0 ; i < *len ; i++)                data[i] = pTxMsg->data[i];            			        }    }    return retCode;}/************************************************************************** SJA1000_GetMessageLength - get the message length** This function returns the length of the message data in the channel on the * controller. The minimum value returned is 0, and the maximum value is 8. * This number is equal to the "len" argument in CAN_ReadData. If the data * has zero length, this function returns zero. The mode of the channel* must not be WNCAN_CHN_INACTIVE or WNCAN_CHN_INVALID** RETURNS:        length of data or -1 if error** ERRNO:          S_can_illegal_channel_no, S_can_illegal_config**/static int SJA1000_GetMessageLength      (	  struct WNCAN_Device *pDev,	  UCHAR channelNum	  ){    struct TxMsg *pTxMsg;    int retLen = -1; /* pessimistic */    if (channelNum >= SJA1000_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    {        if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT)		{            retLen = pDev->pBrd->canInByte(pDev, SJA1000_SFF ) & 0x0f;		}        else        {

⌨️ 快捷键说明

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