示例#1
0
static void InitDMA(void) {
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&transmitBuf[0]); /* set source address */
  DMA_PDD_SetSourceAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_DISABLED); /* no circular buffer */
  DMA_PDD_EnableSourceAddressIncrement(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* source address will be incremented by transfer size */
  DMA_PDD_SetSourceDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_16_BIT); /* Transfer size from source is 16bit */

  DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&TPM0_C1V); /* set destination address */
  DMA_PDD_SetDestinationAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_DISABLED); /* no circular buffer */
  DMA_PDD_EnableDestinationAddressIncrement(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_DISABLE); /* no auto-increment for destination address */
  DMA_PDD_SetDestinationDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_16_BIT); /* Transfer to destination size is 16bit */

  DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, NEO_DMA_NOF_BYTES); /* set number of bytes to transfer */
  DMA_PDD_EnableTransferCompleteInterrupt(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* request interrupt at the end of the DMA transfer to set new byte count */
  DMA_PDD_EnableRequestAutoDisable(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* disable DMA request at the end of the sequence */
  DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* enable request from peripheral */
}
示例#2
0
void DMA_Run(void) {
  for(;;) {
    //DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, 0, (uint32_t)&TPM0_C1V); /* set destination address */

    DMA_PDD_SetSourceAddress(DMA_BASE_PTR, 0, (uint32_t)&dmaSrc[0]); /* set source address */
    DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, 0, (uint32_t)&dmaDst[0]); /* set destination address */

    DMA_PDD_SetByteCount(DMA_BASE_PTR, 0, sizeof(dmaSrc));
    DMACH1_EnableRequest(DMACH1_DeviceData); /* enable first transfer */
    Cpu_EnableInt(); /* enable interrupts */
    for(;;) {
      //WAIT1_Waitms(200);
      //DMA1_SetTransactionCount(DMACH1_DeviceData, 3);
  #if SW_DMA_REQUEST
      DMA1_SetRequestCount(DMACH1_DeviceData, 1); /* 1: 100->101->102->103->104  3: 100->103->106 */
      DMACH1_StartTransfer(DMACH1_DeviceData);
  #endif
      //errors = DMACH1_GetError(DMACH1_DeviceData);
    }
  }
}
示例#3
0
static uint8_t Transfer(uint32_t src) {
  TMOUT1_CounterHandle handle;
  bool isTimeout;

  transferComplete = FALSE;
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, src); /* set source address */
  DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, NEO_DMA_NOF_BYTES); /* set number of bytes to transfer */
  DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* enable request from peripheral */
  handle = TMOUT1_GetCounter(100/TMOUT1_TICK_PERIOD_MS);
  isTimeout = FALSE;
  while(!transferComplete) {
    /* wait until transfer is complete */
    if (TMOUT1_CounterExpired(handle)) {
      isTimeout = TRUE;
      break; /* leave loop */
    }
  }
  TMOUT1_LeaveCounter(handle);
  if (isTimeout) {
    return ERR_BUSY;
  }
  return ERR_OK;
}
示例#4
0
/* DMA Functions */
static void InitDMA(void) {
  /* enable DMA MUX0: */
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_ENABLE); /* enable DMA MUX0 */
  /* PIT triggering for DMA0: */
  DMAMUX_PDD_EnableTrigger(DMAMUX0_BASE_PTR, 0, PDD_DISABLE); /* disable PIT Trigger */
  /* use TPM0 overflow for DMA0 request: */
  DMAMUX_PDD_SetChannelSource(DMAMUX0_BASE_PTR, 0, 25); /* KL25Z reference manual, 3.4.8.1, p64: source number 25 TPM0 CH1 DMA source */
  
  /* DMA channel 0 source configuration: */
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&GPIOC_PDIR); /* set source address */
  DMA_PDD_SetSourceAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_DISABLED); /* no circular buffer */
  DMA_PDD_EnableSourceAddressIncrement(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_DISABLE); /* source address will be incremented by transfer size */
  DMA_PDD_SetSourceDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_8_BIT); /* Transfer size from source  */
  
  /* DMA channel 0 destination configuration: */
  DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&sampleBuffer[0]); /* set destination address */
  DMA_PDD_SetDestinationAddressModulo(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_CIRCULAR_BUFFER_DISABLED); /* no circular buffer */
  DMA_PDD_EnableDestinationAddressIncrement(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* auto-increment for destination address */
  DMA_PDD_SetDestinationDataTransferSize(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, DMA_PDD_8_BIT); /* Transfer to destination size */
  
  /* DMA channel 0 transfer configuration: */
  DMA_PDD_EnableTransferCompleteInterrupt(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* request interrupt at the end of the DMA transfer */
  (void)DMA_PDD_GetRequestAutoDisableEnabled(DMA_BASE_PTR, DMA_PDD_CHANNEL_0); /* disable DMA request at the end of the sequence */
}
示例#5
0
static uint8_t Transfer(uint32_t dataAddress, size_t nofBytes) {
  static const uint8_t OneValue = 0xFF; /* value to clear or set the port bits */
  TMOUT1_CounterHandle handle;
  bool isTimeout;
  uint32_t done0, done1, done2;

  /* clear any pending done flags for DMA channels */
  DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_0);
  DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_1);
  DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_2);
  /* set DMA source addresses */
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, (uint32_t)&OneValue); /* set source address */
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, dataAddress); /* set source address */
  DMA_PDD_SetSourceAddress(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, (uint32_t)&OneValue); /* set source address */
  /* set byte count addresses */
  DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, nofBytes); /* set number of bytes to transfer */
  DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, nofBytes); /* set number of bytes to transfer */
  DMA_PDD_SetByteCount(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, nofBytes); /* set number of bytes to transfer */
  /* reset TPM counter */
  TPM_PDD_InitializeCounter(TPM0_DEVICE); /* reset timer counter */
  TPM_PDD_ClearChannelFlags(TPM0_DEVICE, 0x00);
  TPM_PDD_ClearOverflowInterruptFlag(TPM0_DEVICE);
  /* re-enable DMA Muxing: it will disabled at the end of the transfer */
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_ENABLE);
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 1, PDD_ENABLE);
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 2, PDD_ENABLE);
  /* enable DMA peripheral requests */
  DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_2, PDD_ENABLE); /* enable request from peripheral */
  DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_1, PDD_ENABLE); /* enable request from peripheral */
  DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, DMA_PDD_CHANNEL_0, PDD_ENABLE); /* enable request from peripheral */
  /* clear timer flags and status so it starts from a clean starting point */
  TPM_PDD_ClearChannelFlags(TPM0_DEVICE, 0x00);
  TPM_PDD_ClearOverflowInterruptFlag(TPM0_DEVICE);
  /* enable TPM DMA */
  TPM_PDD_WriteStatusControlReg(TPM0_DEVICE,TPM_PDD_ReadStatusControlReg(TPM0_DEVICE)|TPM_SC_DMA_MASK);
  TPM_PDD_EnableChannelDma(TPM0_DEVICE, 1);
  TPM_PDD_EnableChannelDma(TPM0_DEVICE, 0);
  /* start the TPM timer */
  StartTimer();

  isTimeout = FALSE;
  handle = TMOUT1_GetCounter(100/TMOUT1_TICK_PERIOD_MS);
  for(;;) {
    /* wait until transfer is complete */
    if (TMOUT1_CounterExpired(handle)) {
      isTimeout = TRUE;
      break; /* leave loop */
    }
    done0 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_0);
    done1 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_1);
    done2 = DMA_PDD_GetDoneFlag(DMA_BASE_PTR, DMA_PDD_CHANNEL_2);
    if (done0 && done1 && done2) {
      break; /* done! */
    }
    WAIT1_WaitOSms(1); /* give back some time */
  }
  TMOUT1_LeaveCounter(handle);
  WAIT1_Waitus(50); /* latch, low for at least 50 us (40x1.25us) */

  /* disable DMA-Muxing: necessary, otherwise DMA events on TPM0 channel 0 might be still latched.
   * Will enable muxing for next transfer */
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 0, PDD_DISABLE);
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 1, PDD_DISABLE);
  DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, 2, PDD_DISABLE);
  /* disable peripheral DMA */
  TPM_PDD_WriteStatusControlReg(TPM0_DEVICE,TPM_PDD_ReadStatusControlReg(TPM0_DEVICE)&(~TPM_SC_DMA_MASK));
  TPM_PDD_DisableChannelDma(TPM0_DEVICE, 1);
  TPM_PDD_DisableChannelDma(TPM0_DEVICE, 0);

  StopTimer(); /* stop TPM */

  if (isTimeout) {
    return ERR_BUSY;
  }
  return ERR_OK;
}
/* ===================================================================*/
LDD_TError DMA1_EnableChannel(LDD_TDeviceData *DeviceDataPtr, LDD_DMA_TTransferDescriptor *DescriptorPtr)
{
  LDD_DMA_TChannelNumber ChannelNumber;
  DMA1_TDescriptorRecord *DescriptorRecordPtr;

  /* Check channel allocation for the transfer descriptor and eventually store pointer to associated descriptor record. */
  if (!GetRecord(DeviceDataPtr, DescriptorPtr, &DescriptorRecordPtr)) {
    return ERR_NOTAVAIL;               /* No channel allocated for the transfer. */
  }
  /* Transfer descriptor consistency test - this test can be disabled by setting the "Ignore range checking"
     property to the "yes" value in the "Configuration inspector" */
  if (!VerifyDescriptor(DescriptorPtr)) {
    return ERR_PARAM_DATA;
  }
  ChannelNumber = DescriptorRecordPtr->ChannelNumber; /* Save local auxiliary channel number. */
  if (!DescriptorRecordPtr->Initialized) { /* Is channel already initialized? */
    /* If channel is not initialized yet, initialize and enable it */
    DMA_PDD_WriteControlReg(DMA_BASE_PTR, ChannelNumber, 0U); /* Clear control register. Disable requests. */
    DMA_PDD_ClearDoneFlag(DMA_BASE_PTR, ChannelNumber); /* Clear DMA transfer done status flag. */
    /* Source address */
    DMA_PDD_SetSourceAddress(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->SourceAddress);
    /* Source address increment */
    if (DescriptorPtr->SourceAddressIncrement) {
      DMA_PDD_EnableSourceAddressIncrement(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
    }
    /* Destination address */
    DMA_PDD_SetDestinationAddress(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->DestinationAddress);
    /* Destination address increment */
    if (DescriptorPtr->DestinationAddressIncrement) {
      DMA_PDD_EnableDestinationAddressIncrement(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
    }
    /* Transfer attributes: source transfer size, destination transfer size, source modulo, destination modulo */
    DMA_PDD_SetSourceAddressModulo(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->SourceModuloSize);
    DMA_PDD_SetSourceDataTransferSize(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->SourceTransferSize);
    DMA_PDD_SetDestinationAddressModulo(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->DestinationModuloSize);
    DMA_PDD_SetDestinationDataTransferSize(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->DestinationTransferSize);
    /* Transfer mode */
    if (DescriptorPtr->TransferMode == LDD_DMA_CYCLE_STEAL_TRANSFERS) {
      DMA_PDD_EnableCycleSteal(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE); /* Enable cycle-steal mode. */
    }
    /* Byte count */
    DMA_PDD_SetByteCount(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->ByteCount);
    /* Auto-align mode settings. */
    if (DescriptorPtr->AutoAlign) {
      DMA_PDD_EnableAutoAlign(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
    }
    /* Asynchronous requests settings. */
    if (DescriptorPtr->AsynchronousRequests) {
      DMA_PDD_EnableAsynchronousRequests(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
    }
    /* Channel linking settings. */
    switch (DescriptorPtr->ChannelLinkingMode) {
      case LDD_DMA_LINKING_DISABLED:
        /* Initialization not needed. */
        break;
      case LDD_DMA_CYCLE_STEAL_AND_TRANSFER_COMPLETE_LINKING:
        DMA_PDD_SetChannelLinkingMode(DMA_BASE_PTR, ChannelNumber, DMA_PDD_CYCLE_STEAL_AND_TRANSFER_COMPLETE_LINKING); /* Set channel linking mode. */
        DMA_PDD_SetLinkChannel1(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->InnerLoopLinkedChannel); /* Set channel linked after each particular read-write operation. */
        DMA_PDD_SetLinkChannel2(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->OuterLoopLinkedChannel); /* Set channel linked after transfer byte count reaches zero. */
        break;
      case LDD_DMA_CYCLE_STEAL_LINKING:
        DMA_PDD_SetChannelLinkingMode(DMA_BASE_PTR, ChannelNumber, DMA_PDD_CYCLE_STEAL_LINKING); /* Set channel linking mode. */
        DMA_PDD_SetLinkChannel1(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->InnerLoopLinkedChannel); /* Set channel linked after each particular read-write operation. */
        break;
      case LDD_DMA_TRANSFER_COMPLETE_LINKING:
        DMA_PDD_SetChannelLinkingMode(DMA_BASE_PTR, ChannelNumber, DMA_PDD_TRANSFER_COMPLETE_LINKING); /* Set channel linking mode. */
        DMA_PDD_SetLinkChannel1(DMA_BASE_PTR, ChannelNumber, DescriptorPtr->OuterLoopLinkedChannel); /* Set channel linked after transfer byte count reaches zero. */
        break;
    }
    if (DescriptorPtr->DisableAfterRequest) { /* Disable after request? */
      DMA_PDD_EnableRequestAutoDisable(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
    }
    /* {Default RTOS Adapter} Critical section begin, general PE function is used */
    EnterCritical();
    DescriptorRecordPtr->Initialized = TRUE; /* Mark channel as initialized. */
    DescriptorRecordPtr->Enabled = TRUE; /* Mark channel as enabled. */
    DescriptorPtr->ChannelEnabled = TRUE; /* Mark channel as enabled in transfer descriptor. */
    if (DescriptorPtr->Interrupts) {   /* Interrupts enabled? */
      DMA_PDD_EnableTransferCompleteInterrupt(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE);
      if (DescriptorPtr->OnComplete) { /* Is transfer complete event enabled? */
        ((DMA1_TDeviceData *)DeviceDataPtr)->EventMask[ChannelNumber] |= LDD_DMA_ON_COMPLETE;
      }
      if (DescriptorPtr->OnError) {    /* Is transfer error event enabled? */
        ((DMA1_TDeviceData *)DeviceDataPtr)->EventMask[ChannelNumber] |= LDD_DMA_ON_ERROR;
      }
    }
    /* DMA channel HW requests source settings */
    DMAMUX_PDD_WriteChannelConfigurationReg(DMAMUX0_BASE_PTR, ChannelNumber, 0U); /* Clear DMA MUX channel source register. */
    if (DescriptorPtr->TriggerType != LDD_DMA_SW_TRIGGER) { /* SW trigger doesn't need MUX channel nor enabled hardware requests. */
      DMAMUX_PDD_SetChannelSource(DMAMUX0_BASE_PTR, ChannelNumber, DescriptorPtr->TriggerSource); /* Set MUX channel source. */
      if (DescriptorPtr->PeriodicTrigger) { /* Periodic trigger needed? */
        DMAMUX_PDD_EnableTrigger(DMAMUX0_BASE_PTR, ChannelNumber, PDD_ENABLE);
      }
      DMAMUX_PDD_EnableChannel(DMAMUX0_BASE_PTR, ChannelNumber, PDD_ENABLE); /* Enable channel. */
    }
    DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE); /* Enable HW requests. */
    /* {Default RTOS Adapter} Critical section end, general PE function is used */
    ExitCritical();
  }
  else {
    /* If channel has already been initialized then enable it only */
    /* {Default RTOS Adapter} Critical section begin, general PE function is used */
    EnterCritical();
    DescriptorRecordPtr->Enabled = TRUE; /* Mark channel as enabled. */
    DescriptorPtr->ChannelEnabled = TRUE; /* Mark channel as enabled in transfer descriptor. */
    if (DescriptorPtr->TriggerType != LDD_DMA_SW_TRIGGER) { /* SW trigger doesn't need enabled hardware requests. */
      DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, ChannelNumber, PDD_ENABLE); /* Enable HW requests */
    }
    /* {Default RTOS Adapter} Critical section end, general PE function is used */
    ExitCritical();
  }
  return ERR_OK;
}