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

📄 zl5011xgm.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
*
*  File name:              zl5011xGm.c
*
*  Version:                21
*
*  Author:                 MRC
*
*  Date created:           04/04/2002
*
*  Copyright 2002, 2003, 2004, 2005, Zarlink Semiconductor Limited.
*  All rights reserved.
*
*  Module Description:
*
*  This file contains all the functions that will initialise and control
*  the Granule Manager block. A granule is a block of memory that the device
*  uses to transfer data between the functional blocks. Each granule has a
*  corresponding descriptor, which is used to link granules into chains.
*
*  Revision History:
*
*  Rev:  Date:       Author:  Comments:
*  1     04/04/2002  MRC      Creation
*  2     04/04/2002  MRC      Last entry in the chain is initialised
*                             differently.
*  3     04/04/2002  MRC      Added comments
*  4     04/04/2002  MRC      Update
*  5     24/04/2002  MRC      Changed the granule chain to start at 1 not 0
*  6     24/04/2002  MRC      The granule chain cannot include granule 0,
*                             renumbering did not work.
*  7     26/04/2002  MRC      Changed some data names in response to comments
*                             from Thomas, regarding the MIB interface.
*  8     07/06/2002  MRC      Added granule check functions
*  9     10/06/2002  LCW      Added extra functions
*  10    13/06/2002  LCW      Fixed the interrupt functions
*  11    04/07/2002  PJE      modified headers to interrupt funcs as per reveiew
*  12    18/07/2002  MRC      Updated GM configure fn
*  13    22/07/2002  MRC      Updated following review
*  14    27/08/2002  MRC      Turned granule 0 into a loop!
*  15    28/08/2002  PJE      First clear the interrupts before enabling.
*  16    01/10/2002  DJA      File header modified
*  17    31/10/2002  MRC      Added variants + minor fixes
*  18    20/11/2002  MRC      Made the last granule in the chain unusable
*  19    21/05/2003  MRC      Changed granule chain initialisation to avoid
*                             RTP statistics memory
*  20    23/07/2004  MRC      Fixed some compiler warnings
*  21    08/06/2005  MRC      Amended memory area checks in GmConfigure
*
*******************************************************************************/

/*****************   INCLUDE FILES                *****************************/

#include "zl5011x.h"
#include "zl5011xGm.h"
#include "zl5011xGmMap.h"
#include "zl5011xAdm.h"
#include "zl5011xAdmMap.h"
#include "zl5011xRtpMap.h"
#include "zl5011xUtilLib.h"

/*******************************************************************************

 Function:
    zl5011xGmInit

 Description:
    This function initialises the GM block and  data structure.

 Inputs:
    zl5011xParams      Pointer to the structure for this device instance

 Outputs:
    None

 Returns:
   zlStatusE

 Remarks:
    None

*******************************************************************************/

zlStatusE zl5011xGmInit(zl5011xParamsS *zl5011xParams)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmInit:", 0, 0, 0, 0, 0, 0);

   zl5011xParams->packetMemory.granuleHeadIndex = (Uint32T)ZL5011X_NOT_INITIALISED;
   zl5011xParams->packetMemory.granuleTailIndex = (Uint32T)ZL5011X_NOT_INITIALISED;

   return(status);
}

/*******************************************************************************

 Function:
    zl5011xGmConfigure

 Description:
   This function configures the granule manager. The memory manager must
   already be initialised, since the base addresses for the granules and
   descriptors is used in this function.
   The number of granules is configured, and the granules initialised.
   The head granule is number 1.

 Inputs:
    zl5011xParams      Pointer to the structure for this device instance

 Outputs:
    None

 Returns:
   zlStatusE

 Remarks:
    The number of granules actually available will be numGranules - 2, to
    provide an empty granule at each end of the chain.

*******************************************************************************/

zlStatusE zl5011xGmConfigure(zl5011xParamsS *zl5011xParams, Uint32T numGranules)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T loop, statsAddress, headGranule, prevGranule[2], granuleCount;
   Uint32T endInternal, endExternal;
   zl5011xBooleanE descInternal, dataInternal;

   ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmConfigure: num granules %d",
         numGranules, 0, 0, 0, 0, 0);

   /* work out where the RTP stats are going to be in the memory map */
   statsAddress = ZL5011X_RTP_STATS_BASE;
   statsAddress &= (zl5011xParams->packetMemory.extMemSizeBytes - 1);

   /* use variables to hold the end address of the internal and external memory areas */
   endInternal = ZL5011X_INT_MEM_BASE + ZL5011X_INT_MEMORY_SIZE_IN_BYTES;
   endExternal = ZL5011X_EXT_MEM_BASE + zl5011xParams->packetMemory.extMemSizeBytes;

   /* determine whether the descriptors are in internal or external memory */
   if (zl5011xParams->packetMemory.granDescBaseAddr >= ZL5011X_INT_MEM_BASE)
   {
      descInternal = ZL5011X_TRUE;
   }
   else
   {
      descInternal = ZL5011X_FALSE;
   }

   /* determine whether the granules are in internal or external memory */
   if (zl5011xParams->packetMemory.granBaseAddr >= ZL5011X_INT_MEM_BASE)
   {
      dataInternal = ZL5011X_TRUE;
   }
   else
   {
      dataInternal = ZL5011X_FALSE;
   }

   /* determine whether the heap is in internal or external memory and then
      update the relevant end address */
   if (zl5011xParams->packetMemory.heapStartAddress >= ZL5011X_INT_MEM_BASE)
   {
      endInternal = zl5011xParams->packetMemory.heapStartAddress;
   }
   else
   {
      endExternal = zl5011xParams->packetMemory.heapStartAddress;
   }

   /* Option 1 : Granules INTERNAL, Descriptors INTERNAL */
   if ((dataInternal == ZL5011X_TRUE) && (descInternal == ZL5011X_TRUE))
   {
      /* Do the memory check, assuming that the granules will be at a
         lower address than the granule descriptors */
      if ((zl5011xParams->packetMemory.granDescBaseAddr +
         (numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endInternal)
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
      else
      {
         if ((zl5011xParams->packetMemory.granBaseAddr +
            (numGranules * ZL5011X_GRANULE_DATA_SIZE)) > zl5011xParams->packetMemory.granDescBaseAddr)
         {
            status = ZL5011X_PARAMETER_INVALID;
         }
      }
   }

   /* Option 2 : Granules EXTERNAL, Descriptors INTERNAL */
   if ((dataInternal == ZL5011X_FALSE) && (descInternal == ZL5011X_TRUE))
   {
      /* check that the memory sizes do not exceed the memory available */
      if ((zl5011xParams->packetMemory.granDescBaseAddr +
         (numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endInternal)
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
      else
      {
         if ((zl5011xParams->packetMemory.granBaseAddr +
            (numGranules * ZL5011X_GRANULE_DATA_SIZE)) > endExternal)
         {
            status = ZL5011X_PARAMETER_INVALID;
         }
      }
   }

   /* Option 3 : Granules EXTERNAL, Descriptors EXTERNAL */
   if ((dataInternal == ZL5011X_FALSE) && (descInternal == ZL5011X_FALSE))
   {
      /* Do the memory check, assuming that the granules will be at a
         lower address than the granule descriptors */
      if ((zl5011xParams->packetMemory.granDescBaseAddr +
         (numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endExternal)
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
      else
      {
         if ((zl5011xParams->packetMemory.granBaseAddr +
            (numGranules * ZL5011X_GRANULE_DATA_SIZE)) > zl5011xParams->packetMemory.granDescBaseAddr)
         {
            status = ZL5011X_PARAMETER_INVALID;
         }
      }
   }

   /* Option 4 : Granules INTERNAL, Descriptors EXTERNAL
                 bad choice, but included for completeness */
   if ((dataInternal == ZL5011X_TRUE) && (descInternal == ZL5011X_FALSE))
   {
      /* check that the memory sizes do not exceed the memory available */
      if ((zl5011xParams->packetMemory.granDescBaseAddr +
         (numGranules * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) > endExternal)
      {
         status = ZL5011X_PARAMETER_INVALID;
      }
      else
      {
         if ((zl5011xParams->packetMemory.granBaseAddr +
            (numGranules * ZL5011X_GRANULE_DATA_SIZE)) > endInternal)
         {
            status = ZL5011X_PARAMETER_INVALID;
         }
      }
   }

   /* initialise the granule chain */
   granuleCount = 0;
   headGranule = (Uint32T)-1;
   prevGranule[0] = 1;

   /* granule 0 is not included in the granule chain, and is a special case,
      since the next granule is set to 0 i.e. a loop. */
   if (status == ZL5011X_OK)
   {
      status = zl5011xWrite(zl5011xParams,
         zl5011xParams->packetMemory.granDescBaseAddr,
         0);
   }

   for (loop = 1; loop < numGranules - 1; loop++)
   {
      /* if a failure has occured, or occurs during the initialisation
         then bomb out */
      if (status != ZL5011X_OK)
      {
         break;
      }

      if ((((zl5011xParams->packetMemory.granDescBaseAddr + (loop * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) < statsAddress) ||
         ((zl5011xParams->packetMemory.granDescBaseAddr + (loop * ZL5011X_GRANULE_DESCRIPTOR_SIZE)) >= (statsAddress + ZL5011X_RTP_STATS_MEM_SIZE))) &&
         (((zl5011xParams->packetMemory.granBaseAddr + (loop * ZL5011X_GRANULE_DATA_SIZE)) < statsAddress) ||
         ((zl5011xParams->packetMemory.granBaseAddr + (loop * ZL5011X_GRANULE_DATA_SIZE)) >= (statsAddress + ZL5011X_RTP_STATS_MEM_SIZE))))
      {
         /* not in the region used for RTP statistics, so okay to define a
            granule and descriptor */
         if (headGranule == (Uint32T)-1)
         {
            /* if not already seen a valid granule then mark this as the
               head of the chain */
            headGranule = loop;
         }

         /* setup the granule descriptor for the previous granule, now that we
            know the next one on in the chain */
         status = zl5011xWrite(zl5011xParams,
               zl5011xParams->packetMemory.granDescBaseAddr + (prevGranule[0] * ZL5011X_GRANULE_DESCRIPTOR_SIZE),
               (loop & ZL5011X_GRANULE_NEXT_GRN_MASK) << ZL5011X_GRANULE_NEXT_GRN_BITS);

         prevGranule[1] = prevGranule[0];
         prevGranule[0] = loop;
         granuleCount++;
      }
   }

   if (status == ZL5011X_OK)
   {
      /* for the last granule descriptor in the chain, set the NEXT_GRN to 0 */
      status = zl5011xWrite(zl5011xParams,
            zl5011xParams->packetMemory.granDescBaseAddr + (prevGranule[0] * ZL5011X_GRANULE_DESCRIPTOR_SIZE),
            0);
   }

   /* set the head granule */
   if (status == ZL5011X_OK)
   {
      status = zl5011xGmSetHeadGranule(zl5011xParams, headGranule);
   }

   /* set the tail granule to be the 2nd granule from the end of the chain */
   if (status == ZL5011X_OK)
   {
      status = zl5011xGmSetTailGranule(zl5011xParams, prevGranule[1]);
   }

   /* set the number of free granules */
   if (status == ZL5011X_OK)
   {
      status = zl5011xGmSetNumFreeGranules(zl5011xParams, granuleCount - 1);
   }

   /* by default, set the threshold to the maximum number of granules */
   if (status == ZL5011X_OK)
   {
      status = zl5011xGmSetGranuleThreshold(zl5011xParams, granuleCount - 1);
   }

   return(status);
}

/*******************************************************************************

 Function:
    zl5011xGmSetHeadGranule

 Description:
    Sets the index number of the head granule.

 Inputs:
   zl5011xParams      Pointer to the structure for this device instance
   index             sets the index number of the head granule

 Outputs:
    None

 Returns:
   zlStatusE

 Remarks:
    None

*******************************************************************************/

zlStatusE zl5011xGmSetHeadGranule(zl5011xParamsS *zl5011xParams, Uint32T index)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmSetHeadGranule: index %d",
         index, 0, 0, 0, 0, 0);

   if ((index & ~ZL5011X_GM_GRANULE_INDEX_MASK) != 0)
   {
      status = ZL5011X_PARAMETER_INVALID;
   }

   if (status == ZL5011X_OK)
   {
      status = zl5011xWrite(zl5011xParams, ZL5011X_GM_GRANULE_HEAD,
            index << ZL5011X_GM_GRANULE_HEAD_BITS);

      zl5011xParams->packetMemory.granuleHeadIndex = index;
   }

   return(status);
}

/*******************************************************************************

 Function:
   zl5011xGmGetHeadGranule

 Description:
   Gets the index number of the head granule.

 Inputs:
   zl5011xParams      Pointer to the structure for this device instance

 Outputs:
   index             gets the index number of the head granule

 Returns:
   zlStatusE

 Remarks:
   None

*******************************************************************************/

zlStatusE zl5011xGmGetHeadGranule(zl5011xParamsS *zl5011xParams, Uint32T *index)
{
   zlStatusE status = ZL5011X_OK;
   Uint32T readValue;

   ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmGetHeadGranule:", 0, 0, 0, 0, 0, 0);

   status = zl5011xRead(zl5011xParams, ZL5011X_GM_GRANULE_HEAD,
         &readValue);

   if (status == ZL5011X_OK)
   {
      *index = (readValue >> ZL5011X_GM_GRANULE_HEAD_BITS) & ZL5011X_GM_GRANULE_INDEX_MASK;

      ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmGetHeadGranule: index %d", *index, 0, 0, 0, 0, 0);
   }

   return(status);
}

/*******************************************************************************

 Function:
    zl5011xGmSetTailGranule

 Description:
   Sets the index number of the tail granule. This function will be called during
   initialisation of the granule chain, so the granules will have been sequentially
   assigned. The tail granule is therefore the last granule.

 Inputs:
   zl5011xParams      Pointer to the structure for this device instance
   index             sets the index number of the tail granule

 Outputs:
    None

 Returns:
   zlStatusE

 Remarks:
    None

*******************************************************************************/

zlStatusE zl5011xGmSetTailGranule(zl5011xParamsS *zl5011xParams, Uint32T index)
{
   zlStatusE status = ZL5011X_OK;

   ZL5011X_TRACE(ZL5011X_GM_FN_ID, "zl5011xGmSetTailGranule: index %d", index, 0, 0, 0, 0, 0);

   if ((index & ~ZL5011X_GM_GRANULE_INDEX_MASK) != 0)
   {
      status = ZL5011X_PARAMETER_INVALID;
   }

⌨️ 快捷键说明

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