?? i82527.c
字號:
(I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)); value &= ~0x4; pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR),value); value = canId >> 3; pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT),value); value = canId << 5; pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 1),value); } else { /* extended message */ value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)); value |= 0x4; pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR),value); value = canId >> (24 - 3); pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT),value); value = canId >> (16 - 3); pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 1),value); value = canId >> (8 - 3); pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 2),value); value = canId << 3; pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_ARBIT + 3),value); } /* Set/ Reset RTR bit */ value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)); if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RTR_REQUESTER) { /* * If channel is marked as a remote requester, * set direction to receive */ value &= 0xf7; } else if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_TRANSMIT) { /* * If channel is marked as transmit, * set direction to transmit */ value |= 0x08; } pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR),value); /* reset remote pending: RmtPnd = 0 1 reset transmit request: TxRqst = 0 1 reset cpu upate: CpuUdt = 0 1 set new data bit: NewDat = 1 0 */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1),0x56); /* If EnableChannel is called earlier, state of channel is restored to valid*/ /* Else transmit request is set but channel is not marked as valid */ if(prevState & 0x80) pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0xbf); retCode = OK; } return retCode;}/************************************************************************** I82527_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 or WNCAN_CHN_REQUESTER 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,**/static STATUS I82527_ReadData ( struct WNCAN_Device *pDev, UCHAR channelNum, UCHAR *data, UCHAR *len, BOOL *newData ){ UCHAR value; UINT i; STATUS retCode = ERROR; /* pessimistic */ UCHAR hwLength; 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 { /* mark this message object as invalid */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0x7f); /* Check if the new data bit is set */ value = pDev->pBrd->canInByte(pDev,(I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1)); *newData = (value & 0x02)? TRUE : FALSE; /* read the message configuration register */ value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)); /* set the data len */ hwLength = ((value >> 4) & 0x0f); 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; } do { if(channelNum < 14) /* reset the NewDat bit */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1), 0xfd); for(i = 0 ; i < *len; i++) data[i] = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_DATA + i)); /* re-read until NewDat bit is unset to ensure consistency of data */ if(channelNum < 14) { value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_DATA + I82527_OFFS_CTRL1)); } else { value = 0; /* terminate loop */ } } while((value & 0x03) == 2); /* mark this message object as valid */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0xbf); retCode = OK; } return retCode;}/************************************************************************** I82527_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 I82527_GetMessageLength ( struct WNCAN_Device *pDev, UCHAR channelNum ){ int retLen = -1; /* pessimistic */ 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 { retLen = (pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)) >> 4) & 0x0f; } return retLen;}/************************************************************************** I82527_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 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 I82527_WriteData ( struct WNCAN_Device *pDev, UCHAR channelNum, UCHAR *data, UCHAR len ){ STATUS retCode = ERROR; /* pessimistic */ UCHAR value; UCHAR prevState; unsigned int i; if (channelNum >= I82527_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); } else if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) && (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_RESPONDER)) { errnoSet(S_can_illegal_config); } else if(len > 8) { errnoSet(S_can_illegal_data_length); } 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 unchanged 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); /* Write the data length code to the message config reg. */ value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR)); value &= 0x0f; value |= (len << 4); pDev->pBrd->canOutByte(pDev, I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_MCR,value); /* Write the data */ for( i = 0 ; i < len ; i++) pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_DATA + i), data[i]); /* reset remote pending: RmtPnd = 0 1 reset transmit request: TxRqst = 0 1 reset cpu upate: CpuUdt = 0 1 set new data bit: NewDat = 1 0 */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1),0x56); /* If EnableChannel is called earlier, state of channel is restored to valid*/ /* Else transmit request is set but channel is not marked as valid */ if(prevState & 0x80) pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL0), 0xbf); retCode = OK; } return retCode; }/************************************************************************** I82527_Tx - transmit the CAN message** This routine transmits the CAN Id and data currently in the channel of* the controller on the device. The mode of the channel must be* WNCAN_CHN_TRANSMIT or WNCAN_CHN_RTR_REQUESTER** RETURNS: OK, or ERROR* * ERRNO: S_can_illegal_channel_no,* S_can_illegal_config,* S_can_busy**/static STATUS I82527_Tx ( struct WNCAN_Device *pDev, UCHAR channelNum ){ STATUS retCode = ERROR; /* pessimistic */ UCHAR value; if (channelNum >= I82527_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit; } else if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) && (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_REQUESTER)) { errnoSet(S_can_illegal_config); goto exit; } /* check if tx request is set before modifying*/ value = pDev->pBrd->canInByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1)); if(value & 0x20) { errnoSet(S_can_busy); goto exit; } /* Transmit the message: reset remote pending: RmtPnd = 0 1 set transmit request: TxRqst = 1 0 reset CPU update: CpuUdt = 0 1 set new data bit: NewDat = 1 0 */ pDev->pBrd->canOutByte(pDev, (I82527_R_XMT + (I82527_OFFS_MSG * channelNum) + I82527_OFFS_CTRL1),0x66); retCode = OK; exit: return retCode;}/************************************************************************** I82527_TxMsg - transmit the CAN message ** This routine performs the same function as the following series* of function calls:** 1. I82527_WriteID(context,channelNum,canID,ext);* 2. I82527_WriteData(context,channelNum,data,len);* 3. I82527_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: OK, or ERROR* * ERRNO: S_can_illegal_channel_no,* S_can_illegal_config* S_can_illegal_data_length* S_can_busy**/static STATUS I82527_TxMsg ( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext, UCHAR *data, UCHAR len ){ STATUS retCode = ERROR; /* pessimistic */ UCHAR value; UCHAR prevState; unsigned int i; if (channelNum >= I82527_MAX_MSG_OBJ) { errnoSet(S_can_illegal_channel_no); goto exit;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -