/* ===================================================================*/ LDD_TDeviceData* DMA1_InitChannel(LDD_TDeviceData *DeviceDataPtr, DMA1_TChnInit *ChIntPtr, LDD_TUserData *UserDataPtr) { uint32_t LogChnNum = ChIntPtr->ChnNum; DMA1_TChnDevData *ChnDevDataPtr; DMA1_TChnDevConst const *ChnDevConstPtr; DMA1_TTCD *TCDPtr; uint8_t PhyChnNum; ChnDevDataPtr = &((DMA1_TDeviceData *)DeviceDataPtr)->ChnDevData[LogChnNum]; ChnDevConstPtr = &(DMA1_DevConst.ChnDevConst[LogChnNum]); TCDPtr = ChnDevConstPtr->TCDPtr; PhyChnNum = ChnDevConstPtr->PhyChnNum; DMA_PDD_EnablePeripheralRequest(DMA_BASE_PTR, PhyChnNum, PDD_DISABLE); /* Disable channel peripheral request (in the DMAMUX) */ CancelTransfer(ChnDevConstPtr); /* Cancel transfer (if pending) */ *TCDPtr = ChIntPtr->TCD; /* Initialize channel TCD (channel registers) */ ChnDevDataPtr->ChnDevConstPtr = ChnDevConstPtr; /* Remember channel constants address */ ChnDevDataPtr->TCDPtr = TCDPtr; /* Remember channel TCD address */ ChnDevDataPtr->UserDataPtr = UserDataPtr; /* Remember channel User data pointer */ ChnDevDataPtr->Events = ChIntPtr->Events; /* Initialize events */ DMA_PDD_EnableErrorInterrupt(DMA_BASE_PTR, PhyChnNum); DMAMUX_PDD_SetChannelSource(DMAMUX_BASE_PTR, PhyChnNum, ChIntPtr->MUX_CHCFG_Reg); /* Set channel peripheral request (in the DMAMUX) */ return ChnDevDataPtr; }
/* 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 */ }
/* ===================================================================*/ 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; }