?? sja1000.c
字號:
pTxMsg = (struct TxMsg *)pDev->pCtrl->csData; retLen = pTxMsg->len; } } return retLen;}/************************************************************************** SJA1000_WriteData - write "len" bytes of data to the channel** This function writes "len" bytes of data to the channel. An error is returned* if the number of bytes to be written exceed 8. The mode of the channel must* WNCAN_CHN_TRANSMIT.** RETURNS: ERROR if an input parameter is invalid, OK otherwise.* * ERRNO: S_can_illegal_channel_no,* S_can_illegal_config,* S_can_illegal_data_length,* S_can_null_input_buffer**/static STATUSSJA1000_WriteData(struct WNCAN_Device *pDev, UCHAR channelNum, UCHAR *data, UCHAR len){ STATUS retCode = ERROR; /* pessimistic */ struct TxMsg *pTxMsg; UINT i; if (channelNum >= SJA1000_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); return retCode; } if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) { errnoSet(S_can_illegal_config); return retCode; } if(len > 8) { errnoSet(S_can_illegal_data_length); return retCode; } if(data == NULL) { errnoSet(S_can_null_input_buffer); return retCode; } pTxMsg = (struct TxMsg *)pDev->pCtrl->csData; pTxMsg->len = len; for(i = 0 ; i < pTxMsg->len; i++) pTxMsg->data[i] = data[i]; retCode = OK; return retCode;}/************************************************************************** SJA1000_TxMsg - transmits a CAN message** This function performs the same function as the following series* of function calls:** 1. CAN_WriteID(context,channelNum,canID,ext);* 2. CAN_WriteData(context,channelNum,data,len);* 3. CAN_Tx(context,channel);** The mode of the channel must be WNCAN_CHN_TRANSMIT. If the length* specified exceeds 8 byes an error will be returned.** RETURNS: ERROR if an input parameter is invalid, OK otherwise.* * ERRNO: S_can_illegal_channel_no,* S_can_illegal_config* S_can_illegal_data_length,* S_can_null_input_buffer**/static STATUS SJA1000_TxMsg ( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext, UCHAR *data, UCHAR len ){ UCHAR value; UINT i; UINT ndx; struct TxMsg *pTxMsg; STATUS retCode = ERROR; /* pessimistic */ if (channelNum >= SJA1000_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); return retCode; } if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) { errnoSet(S_can_illegal_config); return retCode; } if(len > 8) { errnoSet(S_can_illegal_data_length); return retCode; } if(data == NULL) { errnoSet(S_can_null_input_buffer); return retCode; } /* check if tx request is set before transmitting */ value = pDev->pBrd->canInByte(pDev, SJA1000_SR); if((value & SR_TBS) == 0) { errnoSet(S_can_busy); return retCode; } /* save a copy */ pTxMsg = (struct TxMsg *)pDev->pCtrl->csData; pTxMsg->id = canId; pTxMsg->ext = ext; pTxMsg->len = len; /* * write data if channel mode is WNCAN_CHN_TX */ for(i = 0 ; i < len ; i++) pTxMsg->data[i] = data[i]; /* set up the frame info reg. */ value = (ext)? 0x80 : 0; if(pTxMsg->rtr) value |= 0x40; value |= len; pDev->pBrd->canOutByte(pDev, SJA1000_SFF, value); /* write the ID */ ndx = SJA1000_TXID; if (ext == TRUE) { value = canId >> (24 - 3); pDev->pBrd->canOutByte(pDev, ndx++, value); value = canId >> (16 - 3); pDev->pBrd->canOutByte(pDev, ndx++, value); value = canId >> (8 - 3); pDev->pBrd->canOutByte(pDev, ndx++, value); value = canId << 3; pDev->pBrd->canOutByte(pDev, ndx++, value); } else { value = canId >> ( 8 - 5); pDev->pBrd->canOutByte(pDev, ndx++, value); value = canId << 5; pDev->pBrd->canOutByte(pDev, ndx++, value); } /* write data */ for(i = 0 ; i < len ; i++) pDev->pBrd->canOutByte(pDev, ndx++, data[i]); /* Request a transmission */ pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_TR); retCode = OK; return retCode;}/************************************************************************** SJA1000_Tx - transmit the CAN message** This function transmits the CAN Id and data currently in the channel of* the specified controller on the device. The mode of the channel must be* WNCAN_CHN_TRANSMIT** RETURNS: OK, or ERROR** ERRNO: S_can_illegal_channel_no, S_can_illegal_config**/static STATUS SJA1000_Tx ( struct WNCAN_Device *pDev, UCHAR channelNum ){ UCHAR value; UINT ndx; UINT i; struct TxMsg *pTxMsg; STATUS retCode = ERROR; /* pessimistic */ if (channelNum >= SJA1000_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); return retCode; } if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) { errnoSet(S_can_illegal_config); return retCode; } /* Check the transmit request buffer. If locked, return CAN_BUSY. */ value = pDev->pBrd->canInByte(pDev, SJA1000_SR); if ((value & SR_TBS) == 0) { errnoSet(S_can_busy); return retCode; } pTxMsg = (struct TxMsg *)pDev->pCtrl->csData; value = (pTxMsg->ext)? 0x80 : 0; if(pTxMsg->rtr) value |= 0x40; value |= pTxMsg->len; pDev->pBrd->canOutByte(pDev, SJA1000_SFF, value); ndx = SJA1000_TXID; /* write the identifier */ if(pTxMsg->ext) { pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id >> (24 - 3)); pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id >> (16 - 3)); pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id >> (8 - 3)); pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id << 3); } else { pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id >> (8 - 5)); pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->id << 5); } /* write data */ for (i = 0; i < pTxMsg->len ; i++) pDev->pBrd->canOutByte(pDev, ndx++, pTxMsg->data[i]); /* Request a transmission */ pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_TR); retCode = OK; return retCode;}/************************************************************************** SJA1000_SetGlobalRxFilter - set the global receive filter** This function sets the global HW filter mask for incoming messages on the * device controller. If the controller does not have a global filter this* function is a no-op. If the ext parameter is TRUE, the mask value applies* to extended messages; otherwise, the mask values applies to standard * messages. A value of "0" for a particular bit position of the mask means * don't care (i.e. the incoming message Id could have a value of zero or * one for this bit position); otherwise, a value of 1 means the * corresponding bit of the message Id must match identically.** WARNING: Only one global filter exists on the controller. This is shared* by standard and extended identifiers. These routines cannot be called from* an interript level.** RETURNS: OK ** ERRNO: N/A**/static STATUS SJA1000_SetGlobalRxFilter( struct WNCAN_Device *pDev, long inputMask, BOOL ext){ STATUS retCode=OK; UCHAR value; UCHAR regMod; ULONG mask; /* Take the complement of the mask because a 1 means don't care with the SJA1000 */ mask = ~inputMask; /* Put the controller into reset mode */ regMod = pDev->pBrd->canInByte(pDev, SJA1000_MOD); pDev->pBrd->canOutByte(pDev, SJA1000_MOD, regMod | MOD_RM); if (ext == FALSE) { value = mask >> 3; pDev->pBrd->canOutByte(pDev, SJA1000_AMR0, value); value = (mask << 5) | 0x1f; pDev->pBrd->canOutByte(pDev, SJA1000_AMR1, value); /* write don't care in the rest */ pDev->pBrd->canOutByte(pDev, SJA1000_AMR2, 0xff); pDev->pBrd->canOutByte(pDev, SJA1000_AMR3, 0xff); } else { value = mask >> (24-3); pDev->pBrd->canOutByte(pDev, SJA1000_AMR0, value); value = mask >> (16-3); pDev->pBrd->canOutByte(pDev, SJA1000_AMR1, value); value = mask >> (8-3); pDev->pBrd->canOutByte(pDev, SJA1000_AMR2, value); value = (mask << 3) | 0x07; pDev->pBrd->canOutByte(pDev, SJA1000_AMR3, value); } /* put controller back into normal mode */ pDev->pBrd->canOutByte(pDev, SJA1000_MOD, regMod); /* Wait until the controller comes out of reset */ while(pDev->pBrd->canInByte(pDev, SJA1000_MOD) != regMod) {}; /* Wait for Bus OK*/ if(SJA1000_GetBusStatus != WNCAN_BUS_OK) taskDelay(1); return retCode;}/************************************************************************** SJA1000_GetGlobalRxFilter - Gets the global HW filter mask programmed.** This function return the programmed value in the Global filter resgiter* Based on the value of ext passed to the function, this function reads the * appropriate format of the global mask, and returns the value in the specified,* extended or standard identifier format.* If the controller does not have a global mask, a value of -1 is returned.** RETURNS: long: mask** ERRNO: N/A**/static long SJA1000_GetGlobalRxFilter( struct WNCAN_Device *pDev, BOOL ext){ ULONG mask; UCHAR value; UCHAR regMod; /* Put the controller into reset mode */ regMod = pDev->pBrd->canInByte(pDev, SJA1000_MOD); pDev->pBrd->canOutByte(pDev, SJA1000_MOD, regMod | MOD_RM); if(ext == FALSE) { value = pDev->pBrd->canInByte(pDev, SJA1000_AMR0); mask = (UINT)(value) << 3; value = pDev->pBrd->canInByte(pDev, SJA1000_AMR1) & 0xe0; mask |= ((UINT)(value) >> 5); /* Take the complement of the mask because a 1 means don't care with the SJA1000 */ mask = (~mask) & 0x000007ff; } else { value = pDev->pBrd->canInByte(pDev, SJA1000_AMR0); mask = (UINT)(value) << (24-3); value = pDev->pBrd->canInByte(pDev, SJA1000_AMR1); mask |= (UINT)(value) << (16-3); value = pDev->pBrd->canInByte(pDev, SJA1000_AMR2); mask |= (UINT)value << (8-3); value = pDev->pBrd->canInByte(pDev, SJA1000_AMR3) & 0xf8; mask |= ((UINT)(value) >> 3); /* Take the complement of the mask because a 1 means don't care with the SJA1000 */ mask = (~mask) & 0x1fffffff; } /* put controller back into normal mode */ pDev->pBrd->canOutByte(pDev, SJA1000_MOD, regMod); /* Wait until the controller comes out of reset */ while(pDev->pBrd->canInByte(pDev, SJA1000_MOD) != regMod) {}; /* Wait for Bus OK or a count of 1000*/ if(SJA1000_GetBusStatus != WNCAN_BUS_OK) taskDelay(1); return (long)mask;}/************************************************************************* SJA1000_SetLocalMsgFilter - set local message object filter** This function sets a local message object filter for incoming messages on a * particular channel. ** If the ext parameter is TRUE, the mask value applies to extended messages;* otherwise, the mask value applies to standard messages. A value of "0" for* a particular bit position of the mask means don't care (i.e. the incoming* message Id could have a value of zero or one for this bit position);* otherwise, a value of 1 means the corresponding bit of the message Id must* match identically. Channel number is provided for controllers that have* more than one local message object filter. ** RETURNS: ERROR** ERRNO: S_can_hwfeature_not_available**/static STATUS SJA1000_SetLocalMsgFilter ( struct WNCAN_Device *pDev, UCHAR channel, long mask, BOOL ext ){ errnoSet(S_can_hwfeature_not_available); return ERROR;}/************************************************************************** SJA1000_GetLocalMsgFilter - get local message object filter** This function returns the programmed value in the local filter resgiter* Based on the value of ext passed to the function, this function reads the * appropriate format of the local mask, and returns the value in the specified,* extended or standard identifier format.* The channel argument identifies the local filter associated with the particular* channel number** If the controller does not have a global mask, a value of -1 is returned.* This is not a valid CAN ID.** RETURNS: -1 ** ERRNO: S_can_hwfeature_not_available**/static long SJA1000_GetLocalMsgFilter ( struct WNCAN_Device *pDev, UCHAR channel, BOOL ext ){ errnoSet(S_can_hwfeature_not_available); return -1;}/************************************************************************** SJA1000_IsMessageLost - test if the message is lost** This function tests if the current message data in the channel overwrote * the old message data before CAN_ReadData() was called. Valid only for * channels with mode = WNCAN_CHN_RECEIVE.** RETURNS: 0 if FALSE, 1 if TRUE, or -1 if ERROR** ERRNO: S_can_illegal_channel_no, S_can_illegal_config**/static int SJA1000_IsMessageLost ( struct WNCAN_Device *pDev, UCHAR channelNum ){ int retCode = -1; /* pessimistic */ UCHAR value; if (channelNum >= SJA1000_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); } else if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RECEIVE)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -