Esempio n. 1
0
/* ===================================================================*/
LDD_TDeviceData* DMA1_Init(LDD_TUserData *UserDataPtr)
{
  uint8_t i;
  DMA1_TDeviceData *DeviceDataPtr;     /* LDD device structure */
  DMA1_TDescriptorRecord *DescriptorRecordPtr; /* Auxiliary local pointer to internal descriptor records. */

  /* Allocate HAL device structure */
  /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */
  DeviceDataPtr = &DeviceDataPtr__DEFAULT_RTOS_ALLOC;
  DeviceDataPtr->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */
  /* Enable device clock gate */
  /* SIM_SCGC7: DMA=1 */
  SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;
  /* SIM_SCGC6: DMAMUX=1 */
  SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
  /* Transfer compete interrupt vector(s) allocation */
  /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */
  INT_DMA2__DEFAULT_RTOS_ISRPARAM = DeviceDataPtr;
  /* Transfer compete interrupt vector(s) priority setting */
  /* NVIC_IPR0: PRI_2=0x80 */
  NVIC_IPR0 = (uint32_t)((NVIC_IPR0 & (uint32_t)~(uint32_t)(
               NVIC_IP_PRI_2(0x7F)
              )) | (uint32_t)(
               NVIC_IP_PRI_2(0x80)
              ));
  /* NVIC_ISER: SETENA|=4 */
  NVIC_ISER |= NVIC_ISER_SETENA(0x04);
  for (i = 0U; i < DMA1_DMA_CHANNELS_NUMBER; i++) {
    DMA_PDD_WriteControlReg(DMA_BASE_PTR, i, 0U); /* Clear control register. Disable all interrupts and HW requests. */
    DMA_PDD_ClearInterruptFlags(DMA_BASE_PTR, i, DMA_PDD_TRANSFER_COMPLETE_FLAG); /* Clear request interrupt flags */
  }
  /* Initialization of channels record field. */
  memset(DeviceDataPtr->ChannelRecord, 0, DMA1_DMA_CHANNELS_NUMBER * sizeof(DeviceDataPtr->ChannelRecord[0]));
  //for(i = 0U; i < DMA1_DMA_CHANNELS_NUMBER; i++) {
  //  DeviceDataPtr->ChannelRecord[i] = NULL; /* Clear pointer to descriptor record of all channels. */
  //}
  /* Initialization of channel and descriptor record fields. */
  for(i = 0U; i < DMA1_CONFIGURED_CHANNELS_NUMBER; i++) {
    DescriptorRecordPtr = &(DeviceDataPtr->DescriptorRecord[i]); /* Store local pointer to descriptor record. */
    DescriptorRecordPtr->ChannelNumber = DMA1_ChannelNumbers[i]; /* Store associated channel number. */
    DescriptorRecordPtr->DescriptorPtr = NULL; /* Set channel as free. */
    DescriptorRecordPtr->Interrupts = DMA1_ChannelInterrupts[i]; /* Store associated channel interrupts enabled/disabled status. */
    DescriptorRecordPtr->Initialized = FALSE; /* Set channel as not initialized. */
    DescriptorRecordPtr->Enabled = FALSE; /* Set channel as disabled. */
    DeviceDataPtr->ChannelRecord[DMA1_ChannelNumbers[i]] = DescriptorRecordPtr; /* Store pointers to descriptor records of fixed channels. */
    DeviceDataPtr->EventMask[DMA1_ChannelNumbers[i]] = 0U; /* Clear channel event mask. */
  }
  /* Registration of the device structure */
  PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_DMA1_ID,DeviceDataPtr);
  return ((LDD_TDeviceData *)DeviceDataPtr); /* Return pointer to the data structure */
}
/* ===================================================================*/
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;
}