📄 sja1000.c
字号:
}
else
{
if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_TRANSMIT)
{
pTxMsg = (struct TxMsg *)pDev->pCtrl->csData;
if(pTxMsg->rtr)
retCode = 1;
else
retCode = 0;
}
else
{
/* Read RTR field in the received channel hardware */
value = pDev->pBrd->canInByte(pDev,SJA1000_RXID+2);
if(value & 0x10)
retCode = 1;
else
retCode = 0;
}
}
return retCode;
}
/************************************************************************
*
* SJA1000_SetRTR - set the RTR bit
*
* This routine sets the RTR bit in the CAN message. The mode of the channel
* must be WNCAN_CHN_TRANSMIT.
*
* RETURNS: OK, or ERROR
*
* ERRNO: S_can_illegal_channel_no,
* S_can_illegal_channel_mode
*
*/
static STATUS SJA1000_SetRTR
(
struct WNCAN_Device *pDev,
UCHAR channelNum,
BOOL rtr
)
{
STATUS retCode = ERROR; /* pessimistic */
struct TxMsg *pTxMsg;
if (channelNum >= SJA1000_MAX_MSG_OBJ)
{
errnoSet(S_can_illegal_channel_no);
}
else if(pDev->pCtrl->chnType[channelNum] != WNCAN_CHN_TRANSMIT)
{
errnoSet(S_can_illegal_channel_mode);
}
else
{
pTxMsg = (struct TxMsg *)pDev->pCtrl->csData;
pTxMsg->rtr = rtr;
retCode = OK;
}
return retCode;
}
/************************************************************************
*
* SJA1000_TxAbort - abort the current CAN transmission
*
* This routine aborts any current CAN transmissions on the controller.
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
static void SJA1000_TxAbort
(
struct WNCAN_Device *pDev
)
{
UCHAR value;
value = pDev->pBrd->canInByte(pDev, SJA1000_CMR);
pDev->pBrd->canOutByte(pDev, SJA1000_CMR, value | CMR_AT);
return;
}
/************************************************************************
*
* SJA1000_Sleep - put the CAN controller to sleep.
*
* This routine puts the CAN controller of the device into sleep mode
* if the hardware supports this functionality; otherwise, this function
* is a no-op.aborts any current CAN transmissions on the controller
*
* RETURNS: Ok or ERROR
*
* ERRNO: S_can_cannot_sleep_in_reset_mode
*
*/
static STATUS SJA1000_Sleep
(
struct WNCAN_Device *pDev
)
{
UCHAR value;
STATUS retCode = ERROR;
/*Setting of the Sleep bit is not possible in reset mode
Check if controller is in reset mode, if yes set error no and
return error
*/
value = pDev->pBrd->canInByte(pDev, SJA1000_MOD);
if(value & MOD_RM)
{
errnoSet(S_can_cannot_sleep_in_reset_mode);
return retCode;
}
/*Set Sleep bit */
pDev->pBrd->canOutByte(pDev, SJA1000_MOD, value | MOD_SM);
retCode = OK;
return retCode;
}
/************************************************************************
*
* SJA1000_WakeUp - brings CAN controller out of sleep mode
*
* Auto awake feature is always enabled
*
* RETURNS: OK always
*
* ERRNO: N/A
*/
static STATUS SJA1000_WakeUp
(
struct WNCAN_Device *pDev
)
{
volatile UCHAR value;
/*Reset Sleep bit */
value = pDev->pBrd->canInByte(pDev, SJA1000_MOD);
/*MOD.4 is sleep bit*/
value &= ~(MOD_SM);
pDev->pBrd->canOutByte(pDev, SJA1000_MOD, value);
return OK;
}
/************************************************************************
*
* SJA1000_EnableChannel - enable channel and set interrupts
*
* This function marks the channel valid. It also sets the type of channel
* interrupt requested. If the channel type does not match the type of
* interrupt requested it returns an error.
*
* RETURNS: OK if successful, ERROR otherwise
*
* ERRNO: S_can_illegal_channel_no
* S_can_illegal_config
* S_can_invalid_parameter
* S_can_incompatible_int_type
*
*/
static STATUS SJA1000_EnableChannel
(
struct WNCAN_Device *pDev,
UCHAR channelNum,
WNCAN_IntType intSetting
)
{
UCHAR regVal;
STATUS retCode = ERROR; /* pessimistic */
if (channelNum >= SJA1000_MAX_MSG_OBJ)
{
errnoSet(S_can_illegal_channel_no);
return retCode;
}
regVal = pDev->pBrd->canInByte(pDev,SJA1000_IER);
switch(pDev->pCtrl->chnMode[channelNum]) {
case WNCAN_CHN_TRANSMIT:
if(intSetting == WNCAN_INT_RX)
{
errnoSet(S_can_incompatible_int_type);
return retCode;
}
if(intSetting == WNCAN_INT_TX)
regVal |= IER_TIE;
else
regVal &= ~(IER_TIE);
pDev->pBrd->canOutByte(pDev, SJA1000_IER, regVal);
retCode = OK;
break;
case WNCAN_CHN_RECEIVE:
if(intSetting == WNCAN_INT_TX)
{
errnoSet(S_can_incompatible_int_type);
return retCode;
}
if(intSetting == WNCAN_INT_RX)
regVal |= IER_RIE;
else
regVal &= ~(IER_RIE);
pDev->pBrd->canOutByte(pDev, SJA1000_IER, regVal);
retCode = OK;
break;
default:
errnoSet(S_can_illegal_config);
break;
}
return retCode;
}
/************************************************************************
*
* SJA1000_DisableChannel - reset channel interrupts and mark channel
* invalid
*
* RETURNS: OK if successful, ERROR otherwise
*
* ERRNO: S_can_illegal_channel_no
* S_can_illegal_config
*
*/
static STATUS SJA1000_DisableChannel
(
struct WNCAN_Device *pDev,
UCHAR channelNum
)
{
UCHAR regVal;
STATUS retCode = ERROR; /* pessimistic */
if (channelNum >= SJA1000_MAX_MSG_OBJ)
{
errnoSet(S_can_illegal_channel_no);
}
else
{
regVal = pDev->pBrd->canInByte(pDev,SJA1000_IER);
switch(pDev->pCtrl->chnMode[channelNum])
{
case WNCAN_CHN_TRANSMIT:
regVal &= ~(IER_TIE);
retCode = OK;
break;
case WNCAN_CHN_RECEIVE:
regVal &= ~(IER_RIE);
pDev->pBrd->canOutByte(pDev, SJA1000_IER, regVal);
retCode = OK;
break;
default:
errnoSet(S_can_illegal_config);
break;
}
pDev->pBrd->canOutByte(pDev, SJA1000_IER, regVal);
}
return retCode;
}
/******************************************************************************
*
* SJA1000_WriteReg - Access hardware register and write data
*
* This function accesses the CAN controller memory at the offset specified.
* A list of valid offsets are defined as macros in a CAN controller specific
* header file, named as controllerOffsets.h (e.g. toucanOffsets.h or sja1000Offsets.h)
* A pointer to the data buffer holding the data to be written is passed to the
* function in UBYTE *data. The number of data bytes to be copied from the data
* buffer to the CAN controller's memory area is specified by the length parameter.
*
* RETURNS: OK or ERROR
*
* ERRNO: S_can_illegal_offset
*
*/
static STATUS SJA1000_WriteReg
(
struct WNCAN_Device *pDev,
UINT offset,
UCHAR * data,
UINT length
)
{
STATUS retCode = ERROR;
UINT i;
if((offset + length) > SJA1000_MAX_OFFSET)
{
errnoSet(S_can_illegal_offset);
return retCode;
}
for(i=0;i<length;i++)
{
pDev->pBrd->canOutByte(pDev, (offset + i),data[i]);
}
retCode = OK;
return retCode;
}
/******************************************************************************
*
* SJA1000_ReadReg - Access hardware register and reads data
*
* This function accesses the CAN controller memory at the offset specified. A list
* of valid offsets are defined as macros in a CAN controller specific header file,
* named as controllerOffsets.h (e.g. toucanOffsets.h or sja1000Offsets.h)
* A pointer to the data buffer to hold the data to be read, is passed through
* UINT *data. The length of the data to be copied is specified through the
* length parameter.
*
*
* RETURNS: N/A
*
* ERRNO: S_can_illegal_offset
*
*/
static STATUS SJA1000_ReadReg
(
struct WNCAN_Device *pDev,
UINT offset,
UCHAR *data,
UINT length
)
{
UINT i;
STATUS retCode = ERROR;
if(data == NULL)
{
errnoSet(S_can_null_input_buffer);
return retCode;
}
if(offset > SJA1000_MAX_OFFSET)
{
errnoSet(S_can_illegal_offset);
return retCode;
}
for(i=0;i<length;i++)
{
data[i] = (UCHAR)pDev->pBrd->canInByte(pDev, (offset + i));
}
retCode = OK;
return retCode;
}
/************************************************************************
*
* SJA1000_establishLinks - set up function pointers in CAN_Device
*
*
* RETURNS: N/A
*
* ERRNO: N/A
*
*/
void SJA1000_establishLinks(struct WNCAN_Device *pDev)
{
/* it is assumed that the calling routine has checked
that pDev is not null */
pDev->Init = SJA1000_Init;
pDev->Start = SJA1000_Start;
pDev->Stop = SJA1000_Stop;
pDev->SetBitTiming = SJA1000_SetBitTiming;
pDev->GetBaudRate = SJA1000_GetBaudRate;
pDev->SetIntMask = SJA1000_SetIntMask;
pDev->EnableInt = SJA1000_EnableInt;
pDev->DisableInt = SJA1000_DisableInt;
pDev->GetBusStatus = SJA1000_GetBusStatus;
pDev->GetBusError = SJA1000_GetBusError;
pDev->ReadID = SJA1000_ReadID;
pDev->WriteID = SJA1000_WriteID;
pDev->ReadData = SJA1000_ReadData;
pDev->GetMessageLength = SJA1000_GetMessageLength;
pDev->WriteData = SJA1000_WriteData;
pDev->Tx = SJA1000_Tx;
pDev->TxMsg = SJA1000_TxMsg;
pDev->SetGlobalRxFilter = SJA1000_SetGlobalRxFilter;
pDev->GetGlobalRxFilter = SJA1000_GetGlobalRxFilter;
pDev->SetLocalMsgFilter = SJA1000_SetLocalMsgFilter;
pDev->GetLocalMsgFilter = SJA1000_GetLocalMsgFilter;
pDev->GetIntStatus = SJA1000_GetIntStatus;
pDev->IsMessageLost = SJA1000_IsMessageLost;
pD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -