📄 sja1000.c
字号:
/* Request a transmission */
pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_AT|CMR_SRR/*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 & SJA1000_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)
{
errnoSet(S_can_illegal_config);
}
else
{
value = pDev->pBrd->canInByte(pDev, SJA1000_SR);
if (value & SJA1000_SR_DOS)
retCode = 1;
else
retCode = 0;
}
return retCode;
}
/************************************************************************
*
* SJA1000_ClearMessageLost - Clear message lost indication
*
* This function clears data overrun flag for a particular channel
* Valid only for channels with mode = WNCAN_CHN_RECEIVE
*
* RETURNS: OK or ERROR
*
* ERRNO: S_can_illegal_channel_no,
* S_can_illegal_config
*
*/
static STATUS SJA1000_ClearMessageLost
(
struct WNCAN_Device *pDev,
UCHAR channelNum
)
{
STATUS retCode = ERROR;
if (channelNum >= SJA1000_MAX_MSG_OBJ)
{
errnoSet(S_can_illegal_channel_no);
}
else if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RECEIVE)
{
errnoSet(S_can_illegal_config);
}
else
{
/* clear data overrun */
pDev->pBrd->canOutByte(pDev, SJA1000_CMR, CMR_CDO);
retCode = OK;
}
return retCode;
}
/************************************************************************
* SJA1000_IsRTR - test if the RTR bit is set
*
* This function tests if the message has the RTR bit set. The mode of the
* channel must be WNCAN_CHN_TRANSMIT or WNCAN_CHN_RECEIVE
* This function can be used on simple controllers such as the SJA1000 only
*
* RETURNS: 0 if FALSE, 1 if TRUE, or -1 if ERROR
*
* ERRNO: S_can_illegal_channel_no,
* S_can_illegal_channel_mode,
*
*/
static int SJA1000_IsRTR
(
struct WNCAN_Device *pDev,
UCHAR channelNum
)
{
int retCode = -1; /* pessimistic */
struct TxMsg *pTxMsg;
UCHAR value;
if (channelNum >= SJA1000_MAX_MSG_OBJ)
{
errnoSet(S_can_illegal_channel_no);
}
else if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) &&
(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RECEIVE))
{
errnoSet(S_can_illegal_channel_mode);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -