?? sja1000.c
字號:
** 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 + -