⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sja1000.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:

        /* 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 + -