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

📄 sja1000.c

📁 cpc-1631的BSP包for VxWorks操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
*                 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 + -