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

📄 toucan.c

📁 美国wind river 公司的CAN总线源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE) ||        (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RTR_RESPONDER))       {        if(buffer->Control & TOUCAN_BUFFER_BUSY)        {            errnoSet(S_can_busy);                goto exit;        }    }        hwLength = (UCHAR)(buffer->Control & 0x000F);        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,        or data buffer size is larger, copy message DLC into *len        and continue */        *len = hwLength;        retCode = OK;    }    /*    * Write data bytes equal to length of message    */        for(i = 0; i < *len; i++)        data[i] = buffer->Data[i];            /*check the channel control field to see if the message was new*/            regCtrl = buffer->Control & 0x00f0;        if(regCtrl == TOUCAN_BUFFER_FULL)        *newData = 1;        retCode = OK;    /*Read the free running timer to unlock channel accessed*/    timerRead = pTouCanRegs->can_TIMER; exit:    return retCode;}/************************************************************************** TouCAN_GetMessageLength - get the message length** This function returns the length of the message data in the channel* 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 TouCAN_GetMessageLength( struct WNCAN_Device *pDev, UCHAR channelNum ){    struct canAccess *pcanAccess;    TouCAN            pTouCanRegs;    TouCANBuf         pTouCanBufs;    volatile TouCAN_StandardMsgType *buffer;    int               retLen = -1; /* pessimistic */            if (channelNum >= TOUCAN_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);        goto exit;            }        if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) ||        (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID))    {        errnoSet(S_can_illegal_config);                goto exit;    }            /*    * Get pointer to TouCAN registers and channels.        */        pcanAccess = (struct canAccess *)pDev->pCtrl->csData;    pTouCanRegs = (TouCAN)pcanAccess->pTouCanRegs;    pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs;           buffer = &pTouCanBufs->can_MSG[channelNum];        /*next test busy bit only for Rx buffers*/        if(pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT)    {        if(buffer->Control & TOUCAN_BUFFER_BUSY)        {            errnoSet(S_can_busy);                            goto exit;        }    }        /* Copy number of bytes in data*/    retLen = (UCHAR)(buffer->Control & 0x000F);         /*Read the free running timer to unlock channel accessed*/    timerRead = pTouCanRegs->can_TIMER;        exit:        return retLen;}      /************************************************************************** TouCAN_WriteID - write the CAN Id  to the channel number ** This function writes the CAN Id to the channel. The type of Id * (standard or extended) is specified. the behaviour of the function for* every channel mode is specified as follows:* WNCAN_CHN_INVALID: not allowed. ERROR is returned.* WNCAN_CHN_INACTIVE: not allowed. ERROR is returned.* WNCAN_CHN_RECEIVE: CAN messages with this Id will be received.* WNCAN_CHN_TRANSMIT: CAN meesage with the specified ID will be transmitted* when CAN_Tx is called* WNCAN_CHN_RTR_REQUESTER: CAN message with this id and RTR bit set will* be transmitted when CAN_TX is called* WNCAN_CHN_RTR_RESPONDER: CAN message with this id will be automatically* transmitted when a matching RTR request is received. CAN_WriteData should* be called to set up data for response.*** RETURNS:        OK, or ERROR** ERRNO:          S_can_illegal_channel_no,*                 S_can_illegal_config**/      static STATUS TouCAN_WriteID( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext ){        struct canAccess *pcanAccess;    TouCANBuf         pTouCanBufs;    volatile TouCAN_StandardMsgType *buffer;    ULONG             Longsrr=0;        ULONG             temp,id;         volatile USHORT   len=0;    USHORT            setRtr=0;       USHORT            ctrlReg;    STATUS            retCode = ERROR; /* pessimistic */        /*    * Get pointer to TouCAN registers and channels.        */    pcanAccess = (struct canAccess *)pDev->pCtrl->csData;    pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs;        buffer = &pTouCanBufs->can_MSG[channelNum];                  /*    * Check if channel number is within range    * or if it is marked invalid    */        if (channelNum >= TOUCAN_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);        goto exit;    }              if((pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INACTIVE) ||        (pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_INVALID))    {        errnoSet(S_can_illegal_config);                goto exit;    }        /*Save and later restore data length, in case previously set*/    len = buffer->Control & 0x000f;              /*store code in buffer control register*/    ctrlReg = buffer->Control & 0x00f0;              switch(pDev->pCtrl->chnMode[channelNum]) {    case WNCAN_CHN_RTR_REQUESTER:        /*If channel is marked as a remote requester, set RTR bit*/        setRtr = 0x0001;              case WNCAN_CHN_TRANSMIT:        if(ext)            Longsrr = (ULONG)0x00100000;                        default:        /*mark channel as inactive while id is set up*/        buffer->Control = TOUCAN_INACTIVE_BUFFER;    }        /*Write identifier*/    if (ext == TRUE)    {        /* extended format*/        /* Make bit 28 MSB*/        temp = canId << 3;                id = (temp & TOUCAN_M28TO18)| Longsrr | 0x00080000;        id |= ((temp & TOUCAN_M17TO0) >> 2);                      buffer->Id2_OR_TimeStamp = ((USHORT)id) | setRtr;        buffer->Id = (USHORT)(id>>16);    }    else    {        /* standard format */        /* Prepare second word of message structure */        id = (canId << 5) | (setRtr << 4);                /* Write second word containing Id, IDE, SRR */        buffer->Id = (USHORT)id;        buffer->Id2_OR_TimeStamp = 0;   /* time-stamp, ignored */    }        /* Mark channel as valid */    if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RECEIVE)    {        /*Mark channel ready for reception*/        buffer->Control = TOUCAN_BUFFER_READY_TO_RX;    }    else    {        /*         * Restore original code in control register, if channel is          * RTR responder, in case data has been previously set         */        buffer->Control = ctrlReg | len;    }    retCode = OK;          exit:    return retCode;}/******************************************************************************** TouCAN_WriteData - writes "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 be* WNCAN_CHN_TRANSMIT, or WNCAN_CHN_RTR_RESPONDER** 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**/static STATUS TouCAN_WriteData( struct WNCAN_Device *pDev, UCHAR channelNum, UCHAR *data, UCHAR len ){    struct canAccess *pcanAccess;       TouCANBuf         pTouCanBufs;    volatile TouCAN_StandardMsgType *buffer;        STATUS            retCode = ERROR; /* pessimistic */        USHORT            temp = 0;     UCHAR             i;            if (channelNum >= TOUCAN_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);        goto exit;    }        if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) &&        (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_RESPONDER))     {        errnoSet(S_can_illegal_config);                goto exit;    }        /*    * Get pointer to TouCAN registers and channels.        */    pcanAccess = (struct canAccess *)pDev->pCtrl->csData;           pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs;                   buffer = &pTouCanBufs->can_MSG[channelNum];        /* Lock buffer*/         temp = buffer->Control & 0xfff0;    buffer->Control = TOUCAN_TX_NOT_READY;           if(len > 8)    {        errnoSet(S_can_illegal_data_length);        goto exit;    }        /*Write message length*/    temp |= (USHORT)len ;         for(i = 0 ; i < len; i++)        buffer->Data[i] = data[i];        buffer->Control = temp | len;        retCode = OK;            exit:       return retCode;}/************************************************************************** TouCAN_TxMsg - transmits a CAN message** This function performs the same function as the following series* of function calls:** 1. TouCAN_WriteID(context,channelNum,canID,ext);* 2. TouCAN_WriteData(context,channelNum,data,len);* 3. TouCAN_Tx(context,channel);** The mode of the channel must be WNCAN_CHN_TRANSMIT or WNCAN_CHN_RTR_REQUESTER* 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_busy**/static STATUS TouCAN_TxMsg( struct WNCAN_Device *pDev, UCHAR channelNum, ULONG canId, BOOL ext, UCHAR *data, UCHAR len ){    struct canAccess *pcanAccess;    TouCAN            pTouCanRegs;    TouCANBuf         pTouCanBufs;    volatile TouCAN_StandardMsgType *buffer;    ULONG             temp;    UINT              i;    ULONG             id;    USHORT            setRtr=0;       STATUS            retCode = ERROR; /* pessimistic */        if (channelNum >= TOUCAN_MAX_MSG_OBJ)    {        errnoSet(S_can_illegal_channel_no);        goto exit;    }        if((pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_TRANSMIT) &&        (pDev->pCtrl->chnMode[channelNum] != WNCAN_CHN_RTR_REQUESTER))        {        errnoSet(S_can_illegal_config);                goto exit;    }        if(len > 8)    {        errnoSet(S_can_illegal_data_length);        goto exit;    }        /*    * Get pointer to TouCAN registers and channels.        */    pcanAccess = (struct canAccess *)pDev->pCtrl->csData;    pTouCanRegs = (TouCAN)pcanAccess->pTouCanRegs;    pTouCanBufs = (TouCANBuf)pcanAccess->pTouCanBufs;           buffer = &pTouCanBufs->can_MSG[channelNum];                 /*    * Check if tx request is set before transmitting     * only a write access will deactivate a transmit     * buffer, so this is safe    */       if((buffer->Control & 0x00c0) == 0x00c0)    {        errnoSet(S_can_busy);                    goto exit;    }        /*Lock channel*/    buffer->Control = TOUCAN_TX_NOT_READY;                    if(pDev->pCtrl->chnMode[channelNum] == WNCAN_CHN_RTR_REQUESTER)        setRtr = 0x0001;    else    {        /* write data */        for(i = 0 ; i < len ; i++)        {            buffer->Data[i] = data[i];        }    }        /*Write identifier*/    if (ext)    {        /*Write extended identifier to channel*/        /* Make bit 28 MSB*/        temp = canId << 3;                id = (temp & TOUCAN_M28TO18)| 0x00100000 | 0x00080000;        id |= ((temp & TOUCAN_M17TO0) >> 2);                buffer->Id2_OR_TimeStamp = ((USHORT)id) | setRtr;             buffer->Id = (USHORT)(id>>16);                          }    else    {        /*Write standard identifier to channel*/        id = (canId << 5) | (setRtr << 4);                buffer->Id = (USHORT)id;        buffer->Id2_OR_TimeStamp = 0;   /* time-stamp, ignored */    }        /*    * Request a transmission and write length if channel is marked    * as a transmit or remote requester channel    */                    buffer->Control = (TOUCAN_TX | len);                        retCode = OK;                exit:    return retCode;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -