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

📄 zl5011xdmampc8260.c

📁 Zalink50114----TDMoIP芯片驱动源码
💻 C
📖 第 1 页 / 共 4 页
字号:
                     ZL5011X_FALSE,
                     {NULL,NULL}
                   };
#else
static zl5011xIdmaMonitorS IdmaMonitor =
                  {
                     {ZL5011X_FALSE,ZL5011X_FALSE,ZL5011X_FALSE,ZL5011X_FALSE},
                     OS_ERROR,
                     ZL5011X_FALSE,
                     {NULL,NULL,NULL,NULL}
                   };
#endif

/*****************   EXPORTED FUNCTION DEFINTIONS   ***************************/

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

 Function:
   zl5011xDmaDetermineStatus

 Description:
    This function will determine the status of the DMA channel

 Inputs:
    dmaChannel        DMA channel that requires checking

 Outputs:
   None

 Returns:
   zl5011xDmaStatusE   Any of: ZL5011X_DMA_STOPPED (DMA has responded to stop
                              command),
                              ZL5011X_DMA_OUT_OF_BUFFERS (DMA has no valid
                              buffers to process),
                              ZL5011X_DMA_EXTERNAL_ABORT (DMA received an
                              external abort command,
                              ZL5011X_DMA_BUFFER_DONE, (DMA processed a buffer
                              with interrupt (I) bit set)
                              ZL5011X_DMA_ACTIVE (DMA still active)

 Remarks:

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

extern zl5011xDmaStatusE zl5011xDmaDetermineStatus(zl5011xDmaChannelS *dmaChannel)
{
   zl5011xDmaStatusE dmaStatus;
   zl5011xDmaStructS *dma = (zl5011xDmaStructS *)dmaChannel->dma;
   Uint32T regValue;

   //ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaDetermineStatus:", 0, 0, 0, 0, 0, 0);

   /* Read idsr status register to determine status                         */
   regValue = dma->reg->idsr;

   /* Process register to determine status                                  */
   if ((regValue & PPC8260_IDMA_IDSR_SC) != 0)
   {
     dmaStatus = ZL5011X_DMA_STOPPED;
   }
   else
   {
     if ((regValue & PPC8260_IDMA_IDSR_OB) != 0)
     {
       dmaStatus = ZL5011X_DMA_OUT_OF_BUFFERS;
     }
     else
     {
       if ((regValue & PPC8260_IDMA_IDSR_EDN) != 0)
       {
         dmaStatus = ZL5011X_DMA_EXTERNAL_ABORT;
       }
       else
       {
         if ((regValue & PPC8260_IDMA_IDSR_BC) != 0)
         {
           dmaStatus = ZL5011X_DMA_BUFFER_DONE;
         }
         else
         {
           /* Assume that DMA is active because no other bits are set!      */
           dmaStatus = ZL5011X_DMA_ACTIVE;
         }
       }
     }
   }

   return dmaStatus;
}

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

 Function:
   zl5011xDmaIssueCommand

 Description:
    This function will gain access to the Communication Processor Module (CPM),
    and issue the appropriate IDMA command (start or stop)

 Inputs:
    dmaChannel      DMA channel to issue command to
    dmaCommand      Any of: ZL5011X_DMA_START_COMMAND,
                            ZL5011X_DMA_STOP_COMMAND

 Outputs:
   None

 Returns:
   zlStatusE

 Remarks:

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

extern zlStatusE zl5011xDmaIssueCommand(zl5011xDmaChannelS *dmaChannel,
                                               zl5011xDmaCommandE dmaCommand)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xDmaStructS *dma = (zl5011xDmaStructS *)dmaChannel->dma;
   Uint32T timeout;
   volatile Uint32T *cpmRegister =
                          (Uint32T *)(dmaChannel->imm + PPC8260_IMM_CPM_CPCR);

   if (status == ZL5011X_OK)
   {
     ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaIssueCommand:", 0, 0, 0, 0, 0, 0);

     /* Wait for CPM to become free for new command                           */
     for(timeout=0;timeout<ZL5011X_CPM_MODULE_TIMEOUT;timeout++)
     {
       if ((*cpmRegister & PPC8260_CPM_BUSY) == 0)
       {
         break;
       }
       OS_TICK_DELAY(1); /* Wait 1 processor tick before checking again       */
     }

     if (timeout == ZL5011X_CPM_MODULE_TIMEOUT)
     {
       status = ZL5011X_DMA_QUEUE_FAIL;
     }

     /* issue IDMA command                                                    */
     if (status == ZL5011X_OK)
     {
       /* Clear IDSR register                                                 */
       dma->reg->idsr = PPC8260_IDMA_IDSR_BC
                         | PPC8260_IDMA_IDSR_EDN
                         | PPC8260_IDMA_IDSR_OB
                         | PPC8260_IDMA_IDSR_SC;

       if (dmaCommand == ZL5011X_DMA_START_COMMAND)
       {
         dma->params->istate  =  0;       /* Clear before every start command */
         zl5011xConnectDreq(dmaChannel);

         /* Formulate CPM start command for DMA channel                       */
         *cpmRegister = PPC8260_CPM_IDMA_START
                           +(PPC8260_CPM_COMMAND_INC*dmaChannel->channelNumber);
       }
       else
       {
         zl5011xDisconnectDreq(dmaChannel);

         /* Formulate CPM stop command for DMA channel                        */
         *cpmRegister = PPC8260_CPM_IDMA_STOP
                           +(PPC8260_CPM_COMMAND_INC*dmaChannel->channelNumber);

         /* Wait for DMA to stop                                              */
         for(timeout=0;timeout<ZL5011X_IDMA_STOP_TIMEOUT;timeout++)
         {
           if ((dma->reg->idsr & PPC8260_IDMA_IDSR_SC) != 0)
           {
             break;
           }
         }

         if (timeout == ZL5011X_IDMA_STOP_TIMEOUT)
         {
           status = ZL5011X_DMA_QUEUE_FAIL;
         }
       }
     }
   }

   return status;
}

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

 Function:
   zl5011xDmaInitialise

 Description:
   Initialises the the IDMA channel and creates the chain of descriptor buffers

 Inputs:
   dmaChannel        DMA channel to initialise

 Outputs
   None

 Returns:
   zlStatusE

 Remarks:
   Note: This function also sets the device to use active
   high signalling for its DREQ signal and active low
   signalling for its DACK signal.

*******************************************************************************/
extern zlStatusE zl5011xDmaInitialise(zl5011xDmaChannelS *dmaChannel)
{
   zlStatusE status = ZL5011X_OK;
   zl5011xDmaStructS *dma;
   Uint32T n;
   Uint16T *dmaChannelBaseAddress;

   /* Allocate IDMA parameter (dual port) RAM                                 */
   if (status == ZL5011X_OK)
   {
     ZL5011X_TRACE(ZL5011X_DMA_FN_ID,"zl5011xDmaInitialise:", 0, 0, 0, 0, 0, 0);

     /* Determine which of the global structures to access                    */
     if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
     {
       dma = &TxRamPtrs;
     }
     else
     {
       dma = &RxRamPtrs;
     }
     dmaChannel->dma = dma;

     /* Get imm base address                                                  */
     dmaChannel->imm = OS_IMMR_GET();

     /* Allocate memory for the DMA channel parameters                        */
     dma->params = (zl5011xDmaParametersS*)sys82xxDpramAlignedMalloc
                    (sizeof(zl5011xDmaParametersS),ZL5011X_DPRAM_BASE_ADDRESS);

     /* Allocate memory for the buffer descriptors and store the lowest 16
        bits                                                                  */
     dma->bufferDescrip =
         (zl5011xDmaBufferDescripS *)sys82xxDpramAlignedMalloc
              (sizeof(zl5011xDmaBufferDescripS)*dmaChannel->numberOfBuffers,
                           ZL5011X_DB_BASE_ADDRESS);
     if ((dma->params == NULL) || (dma->bufferDescrip == NULL))
     {
       status = ZL5011X_RTOS_MEMORY_FAIL;
     }

     dma->params->ibase =
                     (Uint16T)((Uint32T)dma->bufferDescrip & 0xFFFF);
     dma->params->ibdptr = dma->params->ibase;
   }

   if (status == ZL5011X_OK)
   {
     /* Set up the registers for DMA the channel                              */
     dma->reg = (zl5011xDmaRegistersS *)
           (dmaChannel->imm +PPC8260_IMM_IDSR
                          +(PPC8260_IMM_IDSR_INC*dmaChannel->channelNumber));

     /* Disable all interrupts from reaching the core                         */
     dma->reg->idmr = 0;

     /* Store the base address for the DMA in the appropriate place in the
        parameter RAM. Note only the lowest 16 bits are stored                */
     dmaChannelBaseAddress = (Uint16T *)(dmaChannel->imm +PPC8260_IMM_IDMA_BASE
                        +(PPC8260_IMM_IDMA_BASE_INC*dmaChannel->channelNumber));
     *dmaChannelBaseAddress = (Uint16T)(((Uint32T)dma->params) & 0xFFFF);

     /* Setup parameter RAM transfer buffer size                              */
     dma->params->dcm = (ZL5011X_DMA_WRAP << ZL5011X_DMA_WRAP_BIT_SHIFT);

     /* Device present - can do a real transfer                               */
     if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
     {
       dma->params->dcm = dma->params->dcm
                      | PPC8260_IDMA_SD_MEM_PER
                      | PPC8260_IDMA_SINC
                      | PPC8260_IDMA_ERM
                      | PPC8260_IDMA_DT;

       dma->params->ss_max = (Uint16T)zl5011xDmaProps.alignmentSize;
       dma->params->dts = (Uint16T)ZL5011X_PER_PORT_TRANSFER_SIZE;
       dma->params->sts = (Uint16T)zl5011xDmaProps.alignmentSize;
     }
     else
     {
       dma->params->dcm = dma->params->dcm
                      | PPC8260_IDMA_SD_PER_MEM
                      | PPC8260_IDMA_DINC
                      | PPC8260_IDMA_ERM
                      | PPC8260_IDMA_DT;

       dma->params->ss_max = (Uint16T)zl5011xDmaProps.alignmentSize;
       dma->params->dts = (Uint16T)zl5011xDmaProps.alignmentSize;
       dma->params->sts = (Uint16T)ZL5011X_PER_PORT_TRANSFER_SIZE;
     }

     /* Allocate memory in the parameter RAM for the transfer buffer, and store
        the lowest 16 bits of this address                                    */
     dma->params->dpr_buf =
        (Uint16T)(0xFFFF & ((Uint32T)sys82xxDpramAlignedMalloc
        (zl5011xDmaProps.transferBufferSize,zl5011xDmaProps.transferBufferSize)));

     /* Setup buffer descriptors. First allocate the memory to store all the
        memory pointers                                                       */
     dmaChannel->buffer = (Uint8T **)OS_MALLOC(
                                  dmaChannel->numberOfBuffers*sizeof(Uint8T *));
     if (dmaChannel->buffer == NULL)
     {
        status = ZL5011X_RTOS_MEMORY_FAIL;
     }
     else
     {
       dmaChannel->bufferIndex = 0;
       for(n=0;n<dmaChannel->numberOfBuffers && status == ZL5011X_OK;n++)
       {
         /* Allocate a block of non-cached memory, which is aligned to the
          transfer buffer size                                                */
         dmaChannel->buffer[n] = (Uint8T *)OS_CACHE_DMA_MALLOC(
                   (dmaChannel->bufferSize*sizeof(Uint32T))
                                              +zl5011xDmaProps.alignmentSize);

         if (dmaChannel->buffer[n] == NULL)
         {
           status = ZL5011X_RTOS_MEMORY_FAIL;
         }
         else
         {
           if (dmaChannel->dmaDirection == ZL5011X_DMA_TRANSMIT)
           {
             dma->bufferDescrip[n].source =
                          ZL5011X_DMA_BUFFER_BURST_ALIGNED(dmaChannel->buffer[n]);
             dma->bufferDescrip[n].destination =
                       dmaChannel->devParams->baseAdd + ZL5011X_CPU_PACKET_TX;

⌨️ 快捷键说明

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