?? toucan.c
字號:
if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE) || (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RTR_RESPONDER)) { if(buffer->Control & TOUCAN_BUFFER_BUSY) { errnoSet(S_can_busy); goto exit; } } hwLength = (UCHAR)(buffer->Control & 0x000F); 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, or data buffer size is larger, copy message DLC into *len and continue */ *len = hwLength; retCode = OK; } /* * Write data bytes equal to length of message */ for(i = 0; i < *len; i++) data[i] = buffer->Data[i]; /*check the channel control field to see if the message was new*/ regCtrl = buffer->Control & 0x00f0; if(regCtrl == TOUCAN_BUFFER_FULL) *newData = 1; retCode = OK; /*Read the free running timer to unlock channel accessed*/ timerRead = pTouCanRegs->can_TIMER; exit: return retCode;}/************************************************************************** TouCAN_GetMessageLength - get the message length** This function returns the length of the message data in the channel* 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 TouCAN_GetMessageLength( struct WNCAN_Device *pDev, UCHAR channelNum ){ struct canAccess *pcanAccess; TouCAN pTouCanRegs; TouCANBuf pTouCanBufs; volatile TouCAN_StandardMsgType *buffer; int retLen = -1; /* pessimistic */ if (channelNum >= TOUCAN_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit; } if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) || (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID)) { errnoSet(S_can_illegal_config); goto exit; } /* * Get pointer to TouCAN registers and channels. */ pcanAccess = (struct canAccess *)pDev->pCtrl->csData; pTouCanRegs = (TouCAN)pcanAccess->pTouCanRegs; pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs; buffer = &pTouCanBufs->can_MSG[channelNum]; /*next test busy bit only for Rx buffers*/ if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) { if(buffer->Control & TOUCAN_BUFFER_BUSY) { errnoSet(S_can_busy); goto exit; } } /* Copy number of bytes in data*/ retLen = (UCHAR)(buffer->Control & 0x000F); /*Read the free running timer to unlock channel accessed*/ timerRead = pTouCanRegs->can_TIMER; exit: return retLen;} /************************************************************************** TouCAN_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 TouCAN_WriteID( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext ){ struct canAccess *pcanAccess; TouCANBuf pTouCanBufs; volatile TouCAN_StandardMsgType *buffer; ULONG Longsrr=0; ULONG temp,id; volatile USHORT len=0; USHORT setRtr=0; USHORT ctrlReg; STATUS retCode = ERROR; /* pessimistic */ /* * Get pointer to TouCAN registers and channels. */ pcanAccess = (struct canAccess *)pDev->pCtrl->csData; pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs; buffer = &pTouCanBufs->can_MSG[channelNum]; /* * Check if channel number is within range * or if it is marked invalid */ if (channelNum >= TOUCAN_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit; } if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) || (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID)) { errnoSet(S_can_illegal_config); goto exit; } /*Save and later restore data length, in case previously set*/ len = buffer->Control & 0x000f; /*store code in buffer control register*/ ctrlReg = buffer->Control & 0x00f0; switch(pDev->pCtrl->chnMode[channelNum]) { case WNCAN_CHN_RTR_REQUESTER: /*If channel is marked as a remote requester, set RTR bit*/ setRtr = 0x0001; case WNCAN_CHN_TRANSMIT: if(ext) Longsrr = (ULONG)0x00100000; default: /*mark channel as inactive while id is set up*/ buffer->Control = TOUCAN_INACTIVE_BUFFER; } /*Write identifier*/ if (ext == TRUE) { /* extended format*/ /* Make bit 28 MSB*/ temp = canId << 3; id = (temp & TOUCAN_M28TO18)| Longsrr | 0x00080000; id |= ((temp & TOUCAN_M17TO0) >> 2); buffer->Id2_OR_TimeStamp = ((USHORT)id) | setRtr; buffer->Id = (USHORT)(id>>16); } else { /* standard format */ /* Prepare second word of message structure */ id = (canId << 5) | (setRtr << 4); /* Write second word containing Id, IDE, SRR */ buffer->Id = (USHORT)id; buffer->Id2_OR_TimeStamp = 0; /* time-stamp, ignored */ } /* Mark channel as valid */ if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE) { /*Mark channel ready for reception*/ buffer->Control = TOUCAN_BUFFER_READY_TO_RX; } else { /* * Restore original code in control register, if channel is * RTR responder, in case data has been previously set */ buffer->Control = ctrlReg | len; } retCode = OK; exit: return retCode;}/******************************************************************************** TouCAN_WriteData - writes "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 be* WNCAN_CHN_TRANSMIT, or WNCAN_CHN_RTR_RESPONDER** 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**/static STATUS TouCAN_WriteData( struct WNCAN_Device *pDev, UCHAR channelNum, UCHAR *data, UCHAR len ){ struct canAccess *pcanAccess; TouCANBuf pTouCanBufs; volatile TouCAN_StandardMsgType *buffer; STATUS retCode = ERROR; /* pessimistic */ USHORT temp = 0; UCHAR i; if (channelNum >= TOUCAN_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit; } if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) && (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_RESPONDER)) { errnoSet(S_can_illegal_config); goto exit; } /* * Get pointer to TouCAN registers and channels. */ pcanAccess = (struct canAccess *)pDev->pCtrl->csData; pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs; buffer = &pTouCanBufs->can_MSG[channelNum]; /* Lock buffer*/ temp = buffer->Control & 0xfff0; buffer->Control = TOUCAN_TX_NOT_READY; if(len > 8) { errnoSet(S_can_illegal_data_length); goto exit; } /*Write message length*/ temp |= (USHORT)len ; for(i = 0 ; i < len; i++) buffer->Data[i] = data[i]; buffer->Control = temp | len; retCode = OK; exit: return retCode;}/************************************************************************** TouCAN_TxMsg - transmits a CAN message** This function performs the same function as the following series* of function calls:** 1. TouCAN_WriteID(context,channelNum,canID,ext);* 2. TouCAN_WriteData(context,channelNum,data,len);* 3. TouCAN_Tx(context,channel);** The mode of the channel must be WNCAN_CHN_TRANSMIT or WNCAN_CHN_RTR_REQUESTER* 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_busy**/static STATUS TouCAN_TxMsg( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext, UCHAR *data, UCHAR len ){ struct canAccess *pcanAccess; TouCAN pTouCanRegs; TouCANBuf pTouCanBufs; volatile TouCAN_StandardMsgType *buffer; ULONG temp; UINT i; ULONG id; USHORT setRtr=0; STATUS retCode = ERROR; /* pessimistic */ if (channelNum >= TOUCAN_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit; } if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) && (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_REQUESTER)) { errnoSet(S_can_illegal_config); goto exit; } if(len > 8) { errnoSet(S_can_illegal_data_length); goto exit; } /* * Get pointer to TouCAN registers and channels. */ pcanAccess = (struct canAccess *)pDev->pCtrl->csData; pTouCanRegs = (TouCAN)pcanAccess->pTouCanRegs; pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs; buffer = &pTouCanBufs->can_MSG[channelNum]; /* * Check if tx request is set before transmitting * only a write access will deactivate a transmit * buffer, so this is safe */ if((buffer->Control & 0x00c0) == 0x00c0) { errnoSet(S_can_busy); goto exit; } /*Lock channel*/ buffer->Control = TOUCAN_TX_NOT_READY; if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RTR_REQUESTER) setRtr = 0x0001; else { /* write data */ for(i = 0 ; i < len ; i++) { buffer->Data[i] = data[i]; } } /*Write identifier*/ if (ext) { /*Write extended identifier to channel*/ /* Make bit 28 MSB*/ temp = canId << 3; id = (temp & TOUCAN_M28TO18)| 0x00100000 | 0x00080000; id |= ((temp & TOUCAN_M17TO0) >> 2); buffer->Id2_OR_TimeStamp = ((USHORT)id) | setRtr; buffer->Id = (USHORT)(id>>16); } else { /*Write standard identifier to channel*/ id = (canId << 5) | (setRtr << 4); buffer->Id = (USHORT)id; buffer->Id2_OR_TimeStamp = 0; /* time-stamp, ignored */ } /* * Request a transmission and write length if channel is marked * as a transmit or remote requester channel */ buffer->Control = (TOUCAN_TX | len); retCode = OK; exit: return retCode;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -