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

📄 cpfifo.c

📁 Controller Area Network Programming Interface Environment Ver0.8。 CanPie版本0.8. CAN总线通讯编程接口源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************\
*  CANpie                                                                     *
*                                                                             *
*  File        : cpfifo.c                                                     *
*  Description :                                                              *
*  Author      : Uwe Koppe                                                    *
*  e-mail      : koppe@microcontrol.net                                       *
*                                                                             *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
*                                                                             *
*   This program is free software; you can redistribute it and/or modify      *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - *
*                                                                             *
*  History                                                                    *
*  Vers.    Date        Comment                                         Aut.  *
*  -----    ----------  ---------------------------------------------   ----  *
*  0.1      04.09.1999  Initial version                                 UK    *
*  0.2      18.01.2000  Fixed bug in pointer calculation                UK    *
*  0.3                  - no changes -                                        *
*  0.4                  - no changes -                                        *
*  0.5                  - no changes -                                        *
*  0.6      15.06.2000  added fixed FIFO size support                   UK    *
*                       set to CANpie release 0.6                             *
*  0.7      30.11.2000  Bugfix for static FIFO (overflow)               UK    *
*  0.8      14.02.2001  complete rewrite, check FIFO status             UK    *
*                                                                             *
\*****************************************************************************/

#include "cpfifo.h"



/*------------------------------------------------------------------------
** there are two types of FIFO implementations
** CP_FIFO_TYPE == 0 : use dynamic FIFO memory, malloc() function
** CP_FIFO_TYPE == 1 : use fixed FIFO memory size
** the definition is done in the cpconfig.h file
*/


//-----------------------------------------------
// holds the status of the FIFO
// Bit 0 = 1: Receive FIFO full
// Bit 1 = 1: Transmit FIFO full
//
_U08           CpVar_FifoStatus[CP_CHANNEL_MAX];

#define  RCV_FIFO_FULL     0x01
#define  TRM_FIFO_FULL     0x02


//----------------------------------------------------------------------------//
//                                                                            //
// Dynamic memory size FIFO implementation                                    //
//                                                                            //
//----------------------------------------------------------------------------//

#if CP_FIFO_TYPE == 0


#include <stdlib.h>     // for malloc() and free()


/*------------------------------------------------------------------------
** variables used for the FIFO functions
**
*/

CpStruct_CAN * CpVar_FifoRcv[CP_CHANNEL_MAX];
_U16           CpVar_FifoRcvSize[CP_CHANNEL_MAX];
_U16           CpVar_FifoRcvHead[CP_CHANNEL_MAX];
_U16           CpVar_FifoRcvTail[CP_CHANNEL_MAX];

CpStruct_CAN * CpVar_FifoTrm[CP_CHANNEL_MAX];
_U16           CpVar_FifoTrmSize[CP_CHANNEL_MAX];
_U16           CpVar_FifoTrmHead[CP_CHANNEL_MAX];
_U16           CpVar_FifoTrmTail[CP_CHANNEL_MAX];




//----------------------------------------------------------------------------//
// CpFifoSetup()                                                              //
// Setup FIFO size                                                            //
//----------------------------------------------------------------------------//
_U08 Cp_PREFIX CpFifoSetup(_U08 channel, _U08 buffer, _U16 size)
{
#if   CP_SMALL_CODE == 0
   //--- test the channel number --------------------------
   if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);
#endif

   //--- allocate memory for Receive FIFO -----------------
   if(buffer == CP_FIFO_RCV)
   {
      CpVar_FifoRcv[channel] = malloc(CP_CAN_MESSAGE_SIZE * size);
      if(CpVar_FifoRcv[channel] == 0L) return (CpErr_FIFO_SIZE);

      /*----------------------------------
      ** store FIFO size and make it
      ** empty (head = tail = 0)
      */
      CpVar_FifoRcvSize[channel] = size;
      CpVar_FifoRcvHead[channel] = 0;
      CpVar_FifoRcvTail[channel] = 0;
   }

   //--- allocate memory for Transmit FIFO ----------------
   if(buffer == CP_FIFO_TRM)
   {
      CpVar_FifoTrm[channel] = malloc(CP_CAN_MESSAGE_SIZE * size);
      if(CpVar_FifoTrm[channel] == 0L) return (CpErr_FIFO_SIZE);

      /*----------------------------------
      ** store FIFO size and make it
      ** empty (head = tail = 0)
      */
      CpVar_FifoTrmSize[channel] = size;
      CpVar_FifoTrmHead[channel] = 0;
      CpVar_FifoTrmTail[channel] = 0;
   }

   //--- FIFOs are not full -----------------------------------------
   CpVar_FifoStatus[channel] = 0;

   return (CpErr_OK);
}


//----------------------------------------------------------------------------//
// CpFifoRemove()                                                             //
// remove FIFO and free memory                                                //
//----------------------------------------------------------------------------//
_U08 Cp_PREFIX CpFifoRemove(_U08 channel, _U08 buffer)
{
#if   CP_SMALL_CODE == 0
   //--- test the channel number --------------------------
   if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);
#endif

   if(buffer == CP_FIFO_RCV) free(CpVar_FifoRcv[channel]);
   if(buffer == CP_FIFO_TRM) free(CpVar_FifoTrm[channel]);

   return (CpErr_OK);
}


//----------------------------------------------------------------------------//
// CpFifoClear()                                                              //
// clear contents of FIFO                                                     //
//----------------------------------------------------------------------------//
_U08 Cp_PREFIX CpFifoClear(_U08 channel, _U08 buffer)
{
#if   CP_SMALL_CODE == 0
   //--- test the channel number ------------------------------------
   if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);
#endif

   //--- delete messages from Receive FIFO ----------------
   if(buffer == CP_FIFO_RCV)
   {
      CpVar_FifoRcvHead[channel] = 0;
      CpVar_FifoRcvTail[channel] = 0;
      
      CpVar_FifoStatus[channel]  &= ~RCV_FIFO_FULL;
   }

   //--- delete messages from Transmit FIFO ---------------
   if(buffer == CP_FIFO_TRM)
   {
      CpVar_FifoTrmHead[channel] = 0;
      CpVar_FifoTrmTail[channel] = 0;

      CpVar_FifoStatus[channel]  &= ~TRM_FIFO_FULL;
   }

   return (CpErr_OK);
}


//----------------------------------------------------------------------------//
// CpFifoPush()                                                               //
// push message to FIFO                                                       //
//----------------------------------------------------------------------------//
_U08 Cp_PREFIX CpFifoPush(_U08 channel, _U08 buffer, CpStruct_CAN * msg)
{
   CpStruct_CAN * fifoPtr = 0;
   register _U08  cnt;
   register _U16  uwFifoHeadT;   // head position of FIFO
   register _U16  uwFifoTailT;   // tail position of FIFO
   register _U16  uwFifoSizeT;   // max number of entries in FIFO


#if   CP_SMALL_CODE == 0
   //--- test the channel number ------------------------------------
   if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);
#endif


   //--- setup variables for Receive/Transmit FIFOs------------------
   if(buffer == CP_FIFO_RCV)
   {
      //--- test if FIFO is full --------------------------
      if(CpVar_FifoStatus[channel] & RCV_FIFO_FULL) return (CpErr_FIFO_FULL);

      uwFifoHeadT = CpVar_FifoRcvHead[channel];
      uwFifoTailT = CpVar_FifoRcvTail[channel];
      uwFifoSizeT = CpVar_FifoRcvSize[channel];

      fifoPtr = CpVar_FifoRcv[channel];
   }
   else
   {
      //--- test if FIFO is full --------------------------
      if(CpVar_FifoStatus[channel] & TRM_FIFO_FULL) return (CpErr_FIFO_FULL);

      uwFifoHeadT = CpVar_FifoTrmHead[channel];
      uwFifoTailT = CpVar_FifoTrmTail[channel];
      uwFifoSizeT = CpVar_FifoTrmSize[channel];

      fifoPtr = CpVar_FifoTrm[channel];
   }

   
   //----------------------------------------------------------------
   // FIFO is not full, insert the message
   //
   fifoPtr = fifoPtr + uwFifoTailT;

   fifoPtr->v_MsgId     = msg->v_MsgId;
   fifoPtr->v_MsgFlags  = msg->v_MsgFlags;
   for (cnt = 0; cnt < 8; cnt++)
   {
      fifoPtr->v_MsgData[cnt] = msg->v_MsgData[cnt];
   }

#if CP_MSG_TIME == 1
   fifoPtr->v_MsgTime   = msg->v_MsgTime;
#endif

#if CP_USR_DATA == 1
   fifoPtr->v_UsrData   = msg->v_UsrData;
#endif


   //----------------------------------------------------------------
   // test if FIFO is full:
   //
   if(uwFifoHeadT == uwFifoTailT + 1)
   {
      if(buffer == CP_FIFO_RCV) CpVar_FifoStatus[channel] |= RCV_FIFO_FULL;
      else CpVar_FifoStatus[channel] |= TRM_FIFO_FULL; 

      return (CpErr_OK);
   }

   if( (uwFifoHeadT == 0) && (uwFifoTailT == uwFifoSizeT - 1) )
   {
      if(buffer == CP_FIFO_RCV) CpVar_FifoStatus[channel] |= RCV_FIFO_FULL;
      else CpVar_FifoStatus[channel] |= TRM_FIFO_FULL; 

      return (CpErr_OK);
   }

   //----------------------------------------------------------------
   // increment tail position and save it
   // test overflow condition
   uwFifoTailT += 1;
   if(uwFifoTailT == uwFifoSizeT) uwFifoTailT = 0;
   
   
   if(buffer == CP_FIFO_RCV)
   {
      CpVar_FifoRcvTail[channel] = uwFifoTailT;
   }
   else
   {
      CpVar_FifoTrmTail[channel] = uwFifoTailT;
   }

   return (CpErr_OK);
}


//----------------------------------------------------------------------------//
// CpFifoPop()                                                                //
// pop message from FIFO                                                      //
//----------------------------------------------------------------------------//
_U08 Cp_PREFIX CpFifoPop(_U08 channel, _U08 buffer, CpStruct_CAN * msg)
{
   CpStruct_CAN * fifoPtr = 0;
   register _U08  cnt;
   register _U16  uwFifoHeadT;   // head position of FIFO
   register _U16  uwFifoTailT;   // tail position of FIFO
   register _U16  uwFifoSizeT;   // max number of entries in FIFO

#if   CP_SMALL_CODE == 0
   //--- test the channel number ------------------------------------
   if( (channel + 1) > CP_CHANNEL_MAX) return (CpErr_CHANNEL);
#endif

   //--- setup variables for Receive/Transmit FIFOs------------------
   if(buffer == CP_FIFO_RCV)
   {
      uwFifoHeadT = CpVar_FifoRcvHead[channel];
      uwFifoTailT = CpVar_FifoRcvTail[channel];
      uwFifoSizeT = CpVar_FifoRcvSize[channel];

      fifoPtr = CpVar_FifoRcv[channel];
   }
   else
   {
      uwFifoHeadT = CpVar_FifoTrmHead[channel];
      uwFifoTailT = CpVar_FifoTrmTail[channel];
      uwFifoSizeT = CpVar_FifoTrmSize[channel];

      fifoPtr = CpVar_FifoTrm[channel];
   }


   //----------------------------------------------------------------
   // test if FIFO is empty
   //
   if(uwFifoHeadT == uwFifoTailT)
   {
      return (CpErr_FIFO_EMPTY);
   }

   //--- get message from FIFO --------------------------------------
   fifoPtr = fifoPtr + uwFifoHeadT;


   msg->v_MsgId      = fifoPtr->v_MsgId;
   msg->v_MsgFlags   = fifoPtr->v_MsgFlags;
   for (cnt = 0; cnt < 8; cnt++)
   {
      msg->v_MsgData[cnt] = fifoPtr->v_MsgData[cnt];
   }

#if CP_MSG_TIME == 1
   msg->v_MsgTime = fifoPtr->v_MsgTime;
#endif

#if CP_USR_DATA == 1
   msg->v_UsrData = fifoPtr->v_UsrData;
#endif


   //----------------------------------------------------------------
   // increment head position and save it 
   //

   uwFifoHeadT += 1;
   if(uwFifoHeadT == uwFifoSizeT) uwFifoHeadT = 0;

   if(buffer == CP_FIFO_RCV)
   {
      CpVar_FifoRcvHead[channel] = uwFifoHeadT;

      //---------------------------------------------------
      // if there is a FIFO full condition: clear it
      //

⌨️ 快捷键说明

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