Beispiel #1
0
/***************************************************************************//**
 * @brief
 *  Start a LDMA transfer.
 *
 * @details
 *  This function can only be used on LDMA when @ref EMDRV_DMADRV_USE_NATIVE_API
 *  is defined. It is a wrapper around similar emlib ldma function.
 *
 * @param[in] channelId
 *  The channel Id to use.
 *
 * @param[in] transfer
 *  DMA transfer configuration data structure.
 *
 * @param[in] descriptor
 *  DMA transfer descriptor, can be an array of descriptors linked together.
 *
 * @param[in] callback
 *  Optional callback function for signalling completion. May be NULL if not
 *  needed.
 *
 * @param[in] cbUserParam
 *  Optional user parameter to feed to the callback function. May be NULL if
 *  not needed.
 *
 * @return
 *   @ref ECODE_EMDRV_DMADRV_OK on success. On failure an appropriate
 *   DMADRV @ref Ecode_t is returned.
 ******************************************************************************/
Ecode_t DMADRV_LdmaStartTransfer( int                channelId,
                                  LDMA_TransferCfg_t *transfer,
                                  LDMA_Descriptor_t  *descriptor,
                                  DMADRV_Callback_t  callback,
                                  void               *cbUserParam )
{
  ChTable_t *ch;

  if ( !initialized )
  {
    return ECODE_EMDRV_DMADRV_NOT_INITIALIZED;
  }

  if ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
  {
    return ECODE_EMDRV_DMADRV_PARAM_ERROR;
  }

  ch = &chTable[ channelId ];
  if ( ch->allocated == false )
  {
    return ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED;
  }

  ch->callback      = callback;
  ch->userParam     = cbUserParam;
  ch->callbackCount = 0;
  LDMA_StartTransfer( channelId, transfer, descriptor );

  return ECODE_EMDRV_DMADRV_OK;
}
Beispiel #2
0
void LDMAx_StartTransfer(  int ch,
                           LDMA_TransferCfg_t *transfer,
                           LDMA_Descriptor_t  *descriptor,
                           LDMAx_CBFunc_t cbFunc,
                           void *userData )
{
    ldmaCallback[ch].callback = cbFunc;
    ldmaCallback[ch].userdata = userData;

    LDMA_StartTransfer(ch, transfer, descriptor);
}
Beispiel #3
0
/***************************************************************************//**
 * @brief
 *  Start a LDMA transfer.
 ******************************************************************************/
static Ecode_t StartTransfer( DmaMode_t             mode,
                              DmaDirection_t        direction,
                              unsigned int          channelId,
                              DMADRV_PeripheralSignal_t
                                                    peripheralSignal,
                              void                  *buf0,
                              void                  *buf1,
                              void                  *buf2,
                              bool                  bufInc,
                              int                   len,
                              DMADRV_DataSize_t     size,
                              DMADRV_Callback_t     callback,
                              void                  *cbUserParam )
{
  ChTable_t *ch;
  LDMA_TransferCfg_t xfer;
  LDMA_Descriptor_t *desc;

  if ( !initialized )
  {
    return ECODE_EMDRV_DMADRV_NOT_INITIALIZED;
  }

  if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
       || ( buf0 == NULL )
       || ( buf1 == NULL )
       || ( len > DMADRV_MAX_XFER_COUNT )
       || ( ( mode == dmaModePingPong ) && ( buf2 == NULL ) ) )
  {
    return ECODE_EMDRV_DMADRV_PARAM_ERROR;
  }

  ch = &chTable[ channelId ];
  if ( ch->allocated == false )
  {
    return ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED;
  }

  xfer = xferCfg;
  desc = &dmaXfer[ channelId ].desc[0];

  if ( direction == dmaDirectionMemToPeripheral )
  {
    *desc = m2p;
    if ( !bufInc )
    {
      desc->xfer.srcInc = ldmaCtrlSrcIncNone;
    }
  }
  else
  {
    *desc = p2m;
    if ( !bufInc )
    {
      desc->xfer.dstInc = ldmaCtrlDstIncNone;
    }
  }
  xfer.ldmaReqSel    = peripheralSignal;
  desc->xfer.xferCnt = len - 1;
  desc->xfer.dstAddr = (uint32_t)buf0;
  desc->xfer.srcAddr = (uint32_t)buf1;
  desc->xfer.size    = size;

  if ( mode == dmaModePingPong )
  {
    desc->xfer.linkMode = ldmaLinkModeRel;
    desc->xfer.link     = 1;
    desc->xfer.linkAddr = 4;      /* Refer to "pong" descriptor. */

    /* Set the "pong" descriptor equal to the "ping" descriptor. */
    dmaXfer[ channelId ].desc[1] = *desc;
    /* Refer to "ping" descriptor. */
    dmaXfer[ channelId ].desc[1].xfer.linkAddr = -4;
    dmaXfer[ channelId ].desc[1].xfer.srcAddr = (uint32_t)buf2;

    if ( direction == dmaDirectionPeripheralToMem )
    {
      dmaXfer[ channelId ].desc[1].xfer.dstAddr = (uint32_t)buf1;
      desc->xfer.srcAddr = (uint32_t)buf2;
    }
  }

  /* Interrupt needed ? */
  if ( ( callback == NULL ) && ( mode == dmaModeBasic ) )
  {
    desc->xfer.doneIfs = 0;
  }

  ch->callback      = callback;
  ch->userParam     = cbUserParam;
  ch->callbackCount = 0;
  ch->mode          = mode;

  LDMA_StartTransfer( channelId, &xfer, desc );

  return ECODE_EMDRV_DMADRV_OK;
}