📄 sja1000.c
字号:
* 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 & SJA1000_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
{
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 STATUS
SJA1000_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 & SJA1000_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]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -