diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.c index 8ad12fcf2c..be51f4c1a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_edma.h" @@ -63,11 +63,13 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); /*! @brief Array to map EDMA instance number to base pointer. */ static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Array to map EDMA instance number to clock name. */ static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Array to map EDMA instance number to IRQ number. */ -static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS; +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; /*! @brief Pointers to transfer handle for each EDMA channel. */ static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; @@ -81,7 +83,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) { if (s_edmaBases[instance] == base) { @@ -89,7 +91,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) } } - assert(instance < FSL_FEATURE_SOC_EDMA_COUNT); + assert(instance < ARRAY_SIZE(s_edmaBases)); return instance; } @@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) uint32_t tmpreg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate EDMA periphral clock */ CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure EDMA peripheral according to the configuration structure. */ tmpreg = base->CR; tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); @@ -134,8 +138,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) void EDMA_Deinit(DMA_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate EDMA periphral clock */ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void EDMA_GetDefaultConfig(edma_config_t *config) @@ -409,46 +415,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) } } -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) { assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); - uint32_t nbytes = 0; - uint32_t remainingBytes = 0; + uint32_t remainingCount = 0; if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) { - remainingBytes = 0; + remainingCount = 0; } else { - /* Calculate the nbytes */ - if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK)) - { - nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >> - DMA_NBYTES_MLOFFYES_NBYTES_SHIFT; - } - else - { - nbytes = - (base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT; - } /* Calculate the unfinished bytes */ if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) { - remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; } else { - remainingBytes = - ((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; } } - return remainingBytes; + return remainingCount; } uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) @@ -497,14 +489,19 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) uint32_t channelIndex; edma_tcd_t *tcdRegs; + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + handle->base = base; handle->channel = channel; /* Get the DMA instance number */ edmaInstance = EDMA_GetInstance(base); channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; s_EDMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt */ - EnableIRQ(s_edmaIRQNumber[channelIndex]); + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + /* Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), CSR will be 0. Because in order to suit EDMA busy check mechanism in @@ -829,7 +826,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) { (handle->callback)(handle, handle->userData, true, 0); } - else /* Use the TCD queue. */ + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ { uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga_index; @@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Check if transfer is already finished. */ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); - /* Get the offset of the current transfer TCD blcoks. */ + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga -= (uint32_t)handle->tcdPool; - /* Get the index of the current transfer TCD blcoks. */ + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga_index = sga / sizeof(edma_tcd_t); /* Adjust header positions. */ if (transfer_done) { - /* New header shall point to the next TCD (current one is already finished) */ + /* New header shall point to the next TCD to be loaded (current one is already finished) */ new_header = sga_index; } else { - /* New header shall point to this descriptor (not finished yet) */ + /* New header shall point to this descriptor currently loaded (not finished yet) */ new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; } /* Calculate the number of finished TCDs */ @@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) } else { - /* Internal error occurs. */ + /* No TCD in the memory are going to be loaded or internal error occurs. */ tcds_done = 0; } } @@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle) tcds_done += handle->tcdSize; } } - /* Advance header to the point beyond the last finished TCD block. */ + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ handle->header = new_header; - /* Release TCD blocks. */ + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ handle->tcdUsed -= tcds_done; /* Invoke callback function. */ if (handle->callback) @@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void) EDMA_HandleIRQ(s_EDMAHandle[7]); } } + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif #endif /* 8 channels (Shared) */ +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + /* 32 channels (Shared): k80 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -void DMA0_DMA16_IRQHandler(void) +void DMA0_DMA16_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) { @@ -954,7 +1199,7 @@ void DMA0_DMA16_IRQHandler(void) } } -void DMA1_DMA17_IRQHandler(void) +void DMA1_DMA17_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) { @@ -966,7 +1211,7 @@ void DMA1_DMA17_IRQHandler(void) } } -void DMA2_DMA18_IRQHandler(void) +void DMA2_DMA18_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) { @@ -978,7 +1223,7 @@ void DMA2_DMA18_IRQHandler(void) } } -void DMA3_DMA19_IRQHandler(void) +void DMA3_DMA19_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) { @@ -990,7 +1235,7 @@ void DMA3_DMA19_IRQHandler(void) } } -void DMA4_DMA20_IRQHandler(void) +void DMA4_DMA20_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) { @@ -1002,7 +1247,7 @@ void DMA4_DMA20_IRQHandler(void) } } -void DMA5_DMA21_IRQHandler(void) +void DMA5_DMA21_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) { @@ -1014,7 +1259,7 @@ void DMA5_DMA21_IRQHandler(void) } } -void DMA6_DMA22_IRQHandler(void) +void DMA6_DMA22_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) { @@ -1026,7 +1271,7 @@ void DMA6_DMA22_IRQHandler(void) } } -void DMA7_DMA23_IRQHandler(void) +void DMA7_DMA23_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) { @@ -1038,7 +1283,7 @@ void DMA7_DMA23_IRQHandler(void) } } -void DMA8_DMA24_IRQHandler(void) +void DMA8_DMA24_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) { @@ -1050,7 +1295,7 @@ void DMA8_DMA24_IRQHandler(void) } } -void DMA9_DMA25_IRQHandler(void) +void DMA9_DMA25_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) { @@ -1062,7 +1307,7 @@ void DMA9_DMA25_IRQHandler(void) } } -void DMA10_DMA26_IRQHandler(void) +void DMA10_DMA26_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) { @@ -1074,7 +1319,7 @@ void DMA10_DMA26_IRQHandler(void) } } -void DMA11_DMA27_IRQHandler(void) +void DMA11_DMA27_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) { @@ -1086,7 +1331,7 @@ void DMA11_DMA27_IRQHandler(void) } } -void DMA12_DMA28_IRQHandler(void) +void DMA12_DMA28_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) { @@ -1098,7 +1343,7 @@ void DMA12_DMA28_IRQHandler(void) } } -void DMA13_DMA29_IRQHandler(void) +void DMA13_DMA29_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) { @@ -1110,7 +1355,7 @@ void DMA13_DMA29_IRQHandler(void) } } -void DMA14_DMA30_IRQHandler(void) +void DMA14_DMA30_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) { @@ -1122,7 +1367,7 @@ void DMA14_DMA30_IRQHandler(void) } } -void DMA15_DMA31_IRQHandler(void) +void DMA15_DMA31_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) { @@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void) } #endif /* 32 channels (Shared) */ +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + /* 4 channels (No Shared): kv10 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.h index 02c4fabf72..a97622d7e1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_edma.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_EDMA_H_ #define _FSL_EDMA_H_ @@ -45,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief eDMA driver version */ -#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @brief Compute the offset unit from DCHPRI3 */ @@ -77,28 +77,28 @@ typedef enum _edma_modulo kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ - kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ - kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ - kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ - kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ - kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ - kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ - kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ - kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ - kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ - kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ - kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ - kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ - kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ - kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ - kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ - kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ - kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ - kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ - kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ - kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ - kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ - kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ } edma_modulo_t; /*! @brief Bandwidth control */ @@ -177,7 +177,7 @@ typedef struct _edma_config the link channel is itself. */ bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared.*/ - bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority arbitration is used for channel selection */ bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of a new channel. Executing channels are allowed to complete. */ @@ -211,15 +211,15 @@ typedef struct _edma_transfer_config form the next-state value as each source read is completed. */ int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */ - uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t majorLoopCounts; /*!< Major loop iteration count. */ } edma_transfer_config_t; /*! @brief eDMA channel priority configuration */ typedef struct _edma_channel_Preemption_config { - bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ - bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ uint8_t channelPriority; /*!< Channel priority */ } edma_channel_Preemption_config_t; @@ -228,7 +228,7 @@ typedef struct _edma_minor_offset_config { bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ - uint32_t minorOffset; /*!< Offset for minor loop mapping. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ } edma_minor_offset_config_t; /*! @@ -255,20 +255,21 @@ typedef struct _edma_tcd /*! @brief Callback for eDMA */ struct _edma_handle; -/*! @brief Define Callback function for eDMA. */ +/*! @brief Define callback function for eDMA. */ typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); /*! @brief eDMA transfer handle structure */ typedef struct _edma_handle { - edma_callback callback; /*!< Callback function for major count exhausted. */ - void *userData; /*!< Callback function parameter. */ - DMA_Type *base; /*!< eDMA peripheral base address. */ - edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ - uint8_t channel; /*!< eDMA channel number. */ - volatile int8_t header; /*!< The first TCD index. */ - volatile int8_t tail; /*!< The last TCD index. */ - volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ uint8_t flags; /*!< The status of the current channel. */ } edma_handle_t; @@ -281,24 +282,24 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name eDMA initialization and De-initialization + * @name eDMA initialization and de-initialization * @{ */ /*! - * @brief Initializes eDMA peripheral. + * @brief Initializes the eDMA peripheral. * * This function ungates the eDMA clock and configures the eDMA peripheral according * to the configuration structure. * * @param base eDMA peripheral base address. - * @param config Pointer to configuration structure, see "edma_config_t". - * @note This function enable the minor loop map feature. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. */ void EDMA_Init(DMA_Type *base, const edma_config_t *config); /*! - * @brief Deinitializes eDMA peripheral. + * @brief Deinitializes the eDMA peripheral. * * This function gates the eDMA clock. * @@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base); /*! * @brief Gets the eDMA default configuration structure. * - * This function sets the configuration structure to a default value. - * The default configuration is set to the following value: + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. * @code * config.enableContinuousLinkMode = false; * config.enableHaltOnError = true; @@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base); * config.enableDebugMode = false; * @endcode * - * @param config Pointer to eDMA configuration structure. + * @param config A pointer to the eDMA configuration structure. */ void EDMA_GetDefaultConfig(edma_config_t *config); @@ -329,13 +330,13 @@ void EDMA_GetDefaultConfig(edma_config_t *config); */ /*! - * @brief Sets all TCD registers to a default value. + * @brief Sets all TCD registers to default values. * - * This function sets TCD registers for this channel to default value. + * This function sets TCD registers for this channel to default values. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @note This function must not be called while the channel transfer is on-going, + * @note This function must not be called while the channel transfer is ongoing * or it causes unpredictable results. * @note This function enables the auto stop request feature. */ @@ -364,7 +365,7 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); * do not want to enable scatter/gather feature. * @note If nextTcd is not NULL, it means scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which - * is set in eDMA_ResetChannel. + * is set in the eDMA_ResetChannel. */ void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, @@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base, /*! * @brief Configures the eDMA minor offset feature. * - * Minor offset means signed-extended value added to source address or destination + * The minor offset means that the signed-extended value is added to the source address or destination * address after each minor loop. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param config Pointer to Minor offset configuration structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); @@ -390,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino * * @param base eDMA peripheral base address. * @param channel eDMA channel number - * @param config Pointer to channel preemption configuration structure. + * @param config A pointer to the channel preemption configuration structure. */ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, @@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, /*! * @brief Sets the channel link for the eDMA transfer. * - * This function configures minor link or major link mode. The minor link means that the channel link is + * This function configures either the minor link or the major link mode. The minor link means that the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is * exhausted. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param type Channel link type, it can be one of: + * @param type A channel link type, which can be one of the following: * @arg kEDMA_LinkNone * @arg kEDMA_MinorLink * @arg kEDMA_MajorLink @@ -425,13 +426,13 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ /*! * @brief Sets the bandwidth for the eDMA transfer. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences + * Because the eDMA processes the minor loop, it continuously generates read/write sequences * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param bandWidth Bandwidth setting, it can be one of: + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); /*! - * @brief Sets the source modulo and destination modulo for eDMA transfer. + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data @@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable(ture) or disable(false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable (true) or disable (false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. Use + * @param mask The mask of the interrupt source to be set. Use * the defined edma_interrupt_enable_t type. */ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -523,8 +524,8 @@ void EDMA_TcdReset(edma_tcd_t *tcd); /*! * @brief Configures the eDMA TCD transfer attribute. * - * TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. - * STCD is used in scatter-gather mode. + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. * This function configures the TCD transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the next TCD address. @@ -542,7 +543,7 @@ void EDMA_TcdReset(edma_tcd_t *tcd); * @param config Pointer to eDMA transfer configuration structure. * @param nextTcd Pointer to the next TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note TCD address should be 32 bytes aligned, or it causes an eDMA error. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. * @note If the nextTcd is not NULL, the scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which * is set in the EDMA_TcdReset. @@ -552,16 +553,16 @@ void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *co /*! * @brief Configures the eDMA TCD minor offset feature. * - * Minor offset is a signed-extended value added to the source address or destination + * A minor offset is a signed-extended value added to the source address or a destination * address after each minor loop. * - * @param tcd Point to the TCD structure. - * @param config Pointer to Minor offset configuration structure. + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); /*! - * @brief Sets the channel link for eDMA TCD. + * @brief Sets the channel link for the eDMA TCD. * * This function configures either a minor link or a major link. The minor link means the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is @@ -580,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint /*! * @brief Sets the bandwidth for the eDMA TCD. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * @param tcd Point to the TCD structure. - * @param bandWidth Bandwidth setting, it can be one of: + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -598,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi } /*! - * @brief Sets the source modulo and destination modulo for eDMA TCD. + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data * queue easily. * - * @param tcd Point to the TCD structure. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -615,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d * * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * - * @param tcd Point to the TCD structure. - * @param enable The command for enable(ture) or disable(false). + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) { @@ -681,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) } /*! - * @brief Starts the eDMA transfer by software trigger. + * @brief Starts the eDMA transfer by using the software trigger. * * This function starts a minor loop transfer. * @@ -702,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) */ /*! - * @brief Gets the Remaining bytes from the eDMA current channel TCD. + * @brief Gets the remaining major loop count from the eDMA current channel TCD. * * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the the number of bytes that have not finished. + * eDMA channel and returns the the number of major loop count that has not finished. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return Bytes have not been transferred yet for the current TCD. - * @note This function can only be used to get unfinished bytes of transfer without - * the next TCD, or it might be inaccuracy. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) */ -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); /*! * @brief Gets the eDMA channel error status flags. * * @param base eDMA peripheral base address. * @return The mask of error status flags. Users need to use the - * _edma_error_status_flags type to decode the return variables. +* _edma_error_status_flags type to decode the return variables. */ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) { @@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas /*! * @brief Creates the eDMA handle. * - * This function is called if using transaction API for eDMA. This function - * initializes the internal state of eDMA handle. + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. * * @param handle eDMA handle pointer. The eDMA handle stores callback function and * parameters. @@ -766,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); /*! - * @brief Installs the TCDs memory pool into eDMA handle. + * @brief Installs the TCDs memory pool into the eDMA handle. * * This function is called after the EDMA_CreateHandle to use scatter/gather feature. * * @param handle eDMA handle pointer. - * @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdSize The number of TCD slots. */ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); @@ -779,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t /*! * @brief Installs a callback function for the eDMA transfer. * - * This callback is called in eDMA IRQ handler. Use the callback to do something after + * This callback is called in the eDMA IRQ handler. Use the callback to do something after * the current major loop transfer completes. * * @param handle eDMA handle pointer. * @param callback eDMA callback function pointer. - * @param userData Parameter for callback function. + * @param userData A parameter for the callback function. */ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); @@ -802,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD * @param transferBytes eDMA transfer bytes to be transferred. * @param type eDMA transfer type. * @note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in - * source address error(SAE). + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). */ void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, @@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, * @brief Submits the eDMA transfer request. * * This function submits the eDMA transfer request according to the transfer configuration structure. - * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * If submitting the transfer request repeatedly, this function packs an unprocessed request as * a TCD and enables scatter/gather feature to process it in the next time. * * @param handle eDMA handle pointer. @@ -830,7 +840,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); /*! - * @brief eDMA start transfer. + * @brief eDMA starts transfer. * * This function enables the channel request. Users can call this function after submitting the transfer request * or before submitting the transfer request. @@ -840,7 +850,7 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t void EDMA_StartTransfer(edma_handle_t *handle); /*! - * @brief eDMA stop transfer. + * @brief eDMA stops transfer. * * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() * again to resume the transfer. @@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle); /*! - * @brief eDMA abort transfer. + * @brief eDMA aborts transfer. * * This function disables the channel request and clear transfer status bits. * Users can submit another transfer after calling this API. @@ -860,11 +870,31 @@ void EDMA_StopTransfer(edma_handle_t *handle); void EDMA_AbortTransfer(edma_handle_t *handle); /*! - * @brief eDMA IRQ handler for current major loop transfer complete. + * @brief eDMA IRQ handler for the current major loop transfer completion. * - * This function clears the channel major interrupt flag and call + * This function clears the channel major interrupt flag and calls * the callback function if it is not NULL. * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * * @param handle eDMA handle pointer. */ void EDMA_HandleIRQ(edma_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.c index 8ad12fcf2c..be51f4c1a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_edma.h" @@ -63,11 +63,13 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); /*! @brief Array to map EDMA instance number to base pointer. */ static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Array to map EDMA instance number to clock name. */ static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Array to map EDMA instance number to IRQ number. */ -static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS; +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; /*! @brief Pointers to transfer handle for each EDMA channel. */ static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; @@ -81,7 +83,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) { if (s_edmaBases[instance] == base) { @@ -89,7 +91,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) } } - assert(instance < FSL_FEATURE_SOC_EDMA_COUNT); + assert(instance < ARRAY_SIZE(s_edmaBases)); return instance; } @@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) uint32_t tmpreg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate EDMA periphral clock */ CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure EDMA peripheral according to the configuration structure. */ tmpreg = base->CR; tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); @@ -134,8 +138,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) void EDMA_Deinit(DMA_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate EDMA periphral clock */ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void EDMA_GetDefaultConfig(edma_config_t *config) @@ -409,46 +415,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) } } -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) { assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); - uint32_t nbytes = 0; - uint32_t remainingBytes = 0; + uint32_t remainingCount = 0; if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) { - remainingBytes = 0; + remainingCount = 0; } else { - /* Calculate the nbytes */ - if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK)) - { - nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >> - DMA_NBYTES_MLOFFYES_NBYTES_SHIFT; - } - else - { - nbytes = - (base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT; - } /* Calculate the unfinished bytes */ if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) { - remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; } else { - remainingBytes = - ((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; } } - return remainingBytes; + return remainingCount; } uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) @@ -497,14 +489,19 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) uint32_t channelIndex; edma_tcd_t *tcdRegs; + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + handle->base = base; handle->channel = channel; /* Get the DMA instance number */ edmaInstance = EDMA_GetInstance(base); channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; s_EDMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt */ - EnableIRQ(s_edmaIRQNumber[channelIndex]); + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + /* Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), CSR will be 0. Because in order to suit EDMA busy check mechanism in @@ -829,7 +826,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) { (handle->callback)(handle, handle->userData, true, 0); } - else /* Use the TCD queue. */ + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ { uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga_index; @@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Check if transfer is already finished. */ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); - /* Get the offset of the current transfer TCD blcoks. */ + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga -= (uint32_t)handle->tcdPool; - /* Get the index of the current transfer TCD blcoks. */ + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga_index = sga / sizeof(edma_tcd_t); /* Adjust header positions. */ if (transfer_done) { - /* New header shall point to the next TCD (current one is already finished) */ + /* New header shall point to the next TCD to be loaded (current one is already finished) */ new_header = sga_index; } else { - /* New header shall point to this descriptor (not finished yet) */ + /* New header shall point to this descriptor currently loaded (not finished yet) */ new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; } /* Calculate the number of finished TCDs */ @@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) } else { - /* Internal error occurs. */ + /* No TCD in the memory are going to be loaded or internal error occurs. */ tcds_done = 0; } } @@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle) tcds_done += handle->tcdSize; } } - /* Advance header to the point beyond the last finished TCD block. */ + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ handle->header = new_header; - /* Release TCD blocks. */ + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ handle->tcdUsed -= tcds_done; /* Invoke callback function. */ if (handle->callback) @@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void) EDMA_HandleIRQ(s_EDMAHandle[7]); } } + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif #endif /* 8 channels (Shared) */ +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + /* 32 channels (Shared): k80 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -void DMA0_DMA16_IRQHandler(void) +void DMA0_DMA16_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) { @@ -954,7 +1199,7 @@ void DMA0_DMA16_IRQHandler(void) } } -void DMA1_DMA17_IRQHandler(void) +void DMA1_DMA17_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) { @@ -966,7 +1211,7 @@ void DMA1_DMA17_IRQHandler(void) } } -void DMA2_DMA18_IRQHandler(void) +void DMA2_DMA18_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) { @@ -978,7 +1223,7 @@ void DMA2_DMA18_IRQHandler(void) } } -void DMA3_DMA19_IRQHandler(void) +void DMA3_DMA19_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) { @@ -990,7 +1235,7 @@ void DMA3_DMA19_IRQHandler(void) } } -void DMA4_DMA20_IRQHandler(void) +void DMA4_DMA20_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) { @@ -1002,7 +1247,7 @@ void DMA4_DMA20_IRQHandler(void) } } -void DMA5_DMA21_IRQHandler(void) +void DMA5_DMA21_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) { @@ -1014,7 +1259,7 @@ void DMA5_DMA21_IRQHandler(void) } } -void DMA6_DMA22_IRQHandler(void) +void DMA6_DMA22_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) { @@ -1026,7 +1271,7 @@ void DMA6_DMA22_IRQHandler(void) } } -void DMA7_DMA23_IRQHandler(void) +void DMA7_DMA23_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) { @@ -1038,7 +1283,7 @@ void DMA7_DMA23_IRQHandler(void) } } -void DMA8_DMA24_IRQHandler(void) +void DMA8_DMA24_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) { @@ -1050,7 +1295,7 @@ void DMA8_DMA24_IRQHandler(void) } } -void DMA9_DMA25_IRQHandler(void) +void DMA9_DMA25_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) { @@ -1062,7 +1307,7 @@ void DMA9_DMA25_IRQHandler(void) } } -void DMA10_DMA26_IRQHandler(void) +void DMA10_DMA26_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) { @@ -1074,7 +1319,7 @@ void DMA10_DMA26_IRQHandler(void) } } -void DMA11_DMA27_IRQHandler(void) +void DMA11_DMA27_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) { @@ -1086,7 +1331,7 @@ void DMA11_DMA27_IRQHandler(void) } } -void DMA12_DMA28_IRQHandler(void) +void DMA12_DMA28_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) { @@ -1098,7 +1343,7 @@ void DMA12_DMA28_IRQHandler(void) } } -void DMA13_DMA29_IRQHandler(void) +void DMA13_DMA29_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) { @@ -1110,7 +1355,7 @@ void DMA13_DMA29_IRQHandler(void) } } -void DMA14_DMA30_IRQHandler(void) +void DMA14_DMA30_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) { @@ -1122,7 +1367,7 @@ void DMA14_DMA30_IRQHandler(void) } } -void DMA15_DMA31_IRQHandler(void) +void DMA15_DMA31_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) { @@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void) } #endif /* 32 channels (Shared) */ +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + /* 4 channels (No Shared): kv10 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.h index 02c4fabf72..a97622d7e1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_edma.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_EDMA_H_ #define _FSL_EDMA_H_ @@ -45,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief eDMA driver version */ -#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @brief Compute the offset unit from DCHPRI3 */ @@ -77,28 +77,28 @@ typedef enum _edma_modulo kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ - kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ - kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ - kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ - kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ - kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ - kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ - kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ - kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ - kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ - kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ - kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ - kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ - kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ - kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ - kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ - kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ - kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ - kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ - kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ - kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ - kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ - kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ } edma_modulo_t; /*! @brief Bandwidth control */ @@ -177,7 +177,7 @@ typedef struct _edma_config the link channel is itself. */ bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared.*/ - bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority arbitration is used for channel selection */ bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of a new channel. Executing channels are allowed to complete. */ @@ -211,15 +211,15 @@ typedef struct _edma_transfer_config form the next-state value as each source read is completed. */ int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */ - uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t majorLoopCounts; /*!< Major loop iteration count. */ } edma_transfer_config_t; /*! @brief eDMA channel priority configuration */ typedef struct _edma_channel_Preemption_config { - bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ - bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ uint8_t channelPriority; /*!< Channel priority */ } edma_channel_Preemption_config_t; @@ -228,7 +228,7 @@ typedef struct _edma_minor_offset_config { bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ - uint32_t minorOffset; /*!< Offset for minor loop mapping. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ } edma_minor_offset_config_t; /*! @@ -255,20 +255,21 @@ typedef struct _edma_tcd /*! @brief Callback for eDMA */ struct _edma_handle; -/*! @brief Define Callback function for eDMA. */ +/*! @brief Define callback function for eDMA. */ typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); /*! @brief eDMA transfer handle structure */ typedef struct _edma_handle { - edma_callback callback; /*!< Callback function for major count exhausted. */ - void *userData; /*!< Callback function parameter. */ - DMA_Type *base; /*!< eDMA peripheral base address. */ - edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ - uint8_t channel; /*!< eDMA channel number. */ - volatile int8_t header; /*!< The first TCD index. */ - volatile int8_t tail; /*!< The last TCD index. */ - volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ uint8_t flags; /*!< The status of the current channel. */ } edma_handle_t; @@ -281,24 +282,24 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name eDMA initialization and De-initialization + * @name eDMA initialization and de-initialization * @{ */ /*! - * @brief Initializes eDMA peripheral. + * @brief Initializes the eDMA peripheral. * * This function ungates the eDMA clock and configures the eDMA peripheral according * to the configuration structure. * * @param base eDMA peripheral base address. - * @param config Pointer to configuration structure, see "edma_config_t". - * @note This function enable the minor loop map feature. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. */ void EDMA_Init(DMA_Type *base, const edma_config_t *config); /*! - * @brief Deinitializes eDMA peripheral. + * @brief Deinitializes the eDMA peripheral. * * This function gates the eDMA clock. * @@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base); /*! * @brief Gets the eDMA default configuration structure. * - * This function sets the configuration structure to a default value. - * The default configuration is set to the following value: + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. * @code * config.enableContinuousLinkMode = false; * config.enableHaltOnError = true; @@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base); * config.enableDebugMode = false; * @endcode * - * @param config Pointer to eDMA configuration structure. + * @param config A pointer to the eDMA configuration structure. */ void EDMA_GetDefaultConfig(edma_config_t *config); @@ -329,13 +330,13 @@ void EDMA_GetDefaultConfig(edma_config_t *config); */ /*! - * @brief Sets all TCD registers to a default value. + * @brief Sets all TCD registers to default values. * - * This function sets TCD registers for this channel to default value. + * This function sets TCD registers for this channel to default values. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @note This function must not be called while the channel transfer is on-going, + * @note This function must not be called while the channel transfer is ongoing * or it causes unpredictable results. * @note This function enables the auto stop request feature. */ @@ -364,7 +365,7 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); * do not want to enable scatter/gather feature. * @note If nextTcd is not NULL, it means scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which - * is set in eDMA_ResetChannel. + * is set in the eDMA_ResetChannel. */ void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, @@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base, /*! * @brief Configures the eDMA minor offset feature. * - * Minor offset means signed-extended value added to source address or destination + * The minor offset means that the signed-extended value is added to the source address or destination * address after each minor loop. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param config Pointer to Minor offset configuration structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); @@ -390,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino * * @param base eDMA peripheral base address. * @param channel eDMA channel number - * @param config Pointer to channel preemption configuration structure. + * @param config A pointer to the channel preemption configuration structure. */ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, @@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, /*! * @brief Sets the channel link for the eDMA transfer. * - * This function configures minor link or major link mode. The minor link means that the channel link is + * This function configures either the minor link or the major link mode. The minor link means that the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is * exhausted. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param type Channel link type, it can be one of: + * @param type A channel link type, which can be one of the following: * @arg kEDMA_LinkNone * @arg kEDMA_MinorLink * @arg kEDMA_MajorLink @@ -425,13 +426,13 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ /*! * @brief Sets the bandwidth for the eDMA transfer. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences + * Because the eDMA processes the minor loop, it continuously generates read/write sequences * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param bandWidth Bandwidth setting, it can be one of: + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); /*! - * @brief Sets the source modulo and destination modulo for eDMA transfer. + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data @@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable(ture) or disable(false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable (true) or disable (false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. Use + * @param mask The mask of the interrupt source to be set. Use * the defined edma_interrupt_enable_t type. */ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -523,8 +524,8 @@ void EDMA_TcdReset(edma_tcd_t *tcd); /*! * @brief Configures the eDMA TCD transfer attribute. * - * TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. - * STCD is used in scatter-gather mode. + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. * This function configures the TCD transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the next TCD address. @@ -542,7 +543,7 @@ void EDMA_TcdReset(edma_tcd_t *tcd); * @param config Pointer to eDMA transfer configuration structure. * @param nextTcd Pointer to the next TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note TCD address should be 32 bytes aligned, or it causes an eDMA error. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. * @note If the nextTcd is not NULL, the scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which * is set in the EDMA_TcdReset. @@ -552,16 +553,16 @@ void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *co /*! * @brief Configures the eDMA TCD minor offset feature. * - * Minor offset is a signed-extended value added to the source address or destination + * A minor offset is a signed-extended value added to the source address or a destination * address after each minor loop. * - * @param tcd Point to the TCD structure. - * @param config Pointer to Minor offset configuration structure. + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); /*! - * @brief Sets the channel link for eDMA TCD. + * @brief Sets the channel link for the eDMA TCD. * * This function configures either a minor link or a major link. The minor link means the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is @@ -580,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint /*! * @brief Sets the bandwidth for the eDMA TCD. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * @param tcd Point to the TCD structure. - * @param bandWidth Bandwidth setting, it can be one of: + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -598,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi } /*! - * @brief Sets the source modulo and destination modulo for eDMA TCD. + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data * queue easily. * - * @param tcd Point to the TCD structure. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -615,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d * * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * - * @param tcd Point to the TCD structure. - * @param enable The command for enable(ture) or disable(false). + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) { @@ -681,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) } /*! - * @brief Starts the eDMA transfer by software trigger. + * @brief Starts the eDMA transfer by using the software trigger. * * This function starts a minor loop transfer. * @@ -702,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) */ /*! - * @brief Gets the Remaining bytes from the eDMA current channel TCD. + * @brief Gets the remaining major loop count from the eDMA current channel TCD. * * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the the number of bytes that have not finished. + * eDMA channel and returns the the number of major loop count that has not finished. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return Bytes have not been transferred yet for the current TCD. - * @note This function can only be used to get unfinished bytes of transfer without - * the next TCD, or it might be inaccuracy. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) */ -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); /*! * @brief Gets the eDMA channel error status flags. * * @param base eDMA peripheral base address. * @return The mask of error status flags. Users need to use the - * _edma_error_status_flags type to decode the return variables. +* _edma_error_status_flags type to decode the return variables. */ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) { @@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas /*! * @brief Creates the eDMA handle. * - * This function is called if using transaction API for eDMA. This function - * initializes the internal state of eDMA handle. + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. * * @param handle eDMA handle pointer. The eDMA handle stores callback function and * parameters. @@ -766,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); /*! - * @brief Installs the TCDs memory pool into eDMA handle. + * @brief Installs the TCDs memory pool into the eDMA handle. * * This function is called after the EDMA_CreateHandle to use scatter/gather feature. * * @param handle eDMA handle pointer. - * @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdSize The number of TCD slots. */ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); @@ -779,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t /*! * @brief Installs a callback function for the eDMA transfer. * - * This callback is called in eDMA IRQ handler. Use the callback to do something after + * This callback is called in the eDMA IRQ handler. Use the callback to do something after * the current major loop transfer completes. * * @param handle eDMA handle pointer. * @param callback eDMA callback function pointer. - * @param userData Parameter for callback function. + * @param userData A parameter for the callback function. */ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); @@ -802,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD * @param transferBytes eDMA transfer bytes to be transferred. * @param type eDMA transfer type. * @note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in - * source address error(SAE). + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). */ void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, @@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, * @brief Submits the eDMA transfer request. * * This function submits the eDMA transfer request according to the transfer configuration structure. - * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * If submitting the transfer request repeatedly, this function packs an unprocessed request as * a TCD and enables scatter/gather feature to process it in the next time. * * @param handle eDMA handle pointer. @@ -830,7 +840,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); /*! - * @brief eDMA start transfer. + * @brief eDMA starts transfer. * * This function enables the channel request. Users can call this function after submitting the transfer request * or before submitting the transfer request. @@ -840,7 +850,7 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t void EDMA_StartTransfer(edma_handle_t *handle); /*! - * @brief eDMA stop transfer. + * @brief eDMA stops transfer. * * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() * again to resume the transfer. @@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle); /*! - * @brief eDMA abort transfer. + * @brief eDMA aborts transfer. * * This function disables the channel request and clear transfer status bits. * Users can submit another transfer after calling this API. @@ -860,11 +870,31 @@ void EDMA_StopTransfer(edma_handle_t *handle); void EDMA_AbortTransfer(edma_handle_t *handle); /*! - * @brief eDMA IRQ handler for current major loop transfer complete. + * @brief eDMA IRQ handler for the current major loop transfer completion. * - * This function clears the channel major interrupt flag and call + * This function clears the channel major interrupt flag and calls * the callback function if it is not NULL. * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * * @param handle eDMA handle pointer. */ void EDMA_HandleIRQ(edma_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.c index 8ad12fcf2c..be51f4c1a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_edma.h" @@ -63,11 +63,13 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); /*! @brief Array to map EDMA instance number to base pointer. */ static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Array to map EDMA instance number to clock name. */ static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Array to map EDMA instance number to IRQ number. */ -static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS; +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; /*! @brief Pointers to transfer handle for each EDMA channel. */ static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; @@ -81,7 +83,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) { if (s_edmaBases[instance] == base) { @@ -89,7 +91,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) } } - assert(instance < FSL_FEATURE_SOC_EDMA_COUNT); + assert(instance < ARRAY_SIZE(s_edmaBases)); return instance; } @@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) uint32_t tmpreg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate EDMA periphral clock */ CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure EDMA peripheral according to the configuration structure. */ tmpreg = base->CR; tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); @@ -134,8 +138,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) void EDMA_Deinit(DMA_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate EDMA periphral clock */ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void EDMA_GetDefaultConfig(edma_config_t *config) @@ -409,46 +415,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) } } -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) { assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); - uint32_t nbytes = 0; - uint32_t remainingBytes = 0; + uint32_t remainingCount = 0; if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) { - remainingBytes = 0; + remainingCount = 0; } else { - /* Calculate the nbytes */ - if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK)) - { - nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >> - DMA_NBYTES_MLOFFYES_NBYTES_SHIFT; - } - else - { - nbytes = - (base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT; - } /* Calculate the unfinished bytes */ if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) { - remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; } else { - remainingBytes = - ((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; } } - return remainingBytes; + return remainingCount; } uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) @@ -497,14 +489,19 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) uint32_t channelIndex; edma_tcd_t *tcdRegs; + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + handle->base = base; handle->channel = channel; /* Get the DMA instance number */ edmaInstance = EDMA_GetInstance(base); channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; s_EDMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt */ - EnableIRQ(s_edmaIRQNumber[channelIndex]); + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + /* Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), CSR will be 0. Because in order to suit EDMA busy check mechanism in @@ -829,7 +826,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) { (handle->callback)(handle, handle->userData, true, 0); } - else /* Use the TCD queue. */ + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ { uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga_index; @@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Check if transfer is already finished. */ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); - /* Get the offset of the current transfer TCD blcoks. */ + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga -= (uint32_t)handle->tcdPool; - /* Get the index of the current transfer TCD blcoks. */ + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga_index = sga / sizeof(edma_tcd_t); /* Adjust header positions. */ if (transfer_done) { - /* New header shall point to the next TCD (current one is already finished) */ + /* New header shall point to the next TCD to be loaded (current one is already finished) */ new_header = sga_index; } else { - /* New header shall point to this descriptor (not finished yet) */ + /* New header shall point to this descriptor currently loaded (not finished yet) */ new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; } /* Calculate the number of finished TCDs */ @@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) } else { - /* Internal error occurs. */ + /* No TCD in the memory are going to be loaded or internal error occurs. */ tcds_done = 0; } } @@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle) tcds_done += handle->tcdSize; } } - /* Advance header to the point beyond the last finished TCD block. */ + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ handle->header = new_header; - /* Release TCD blocks. */ + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ handle->tcdUsed -= tcds_done; /* Invoke callback function. */ if (handle->callback) @@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void) EDMA_HandleIRQ(s_EDMAHandle[7]); } } + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif #endif /* 8 channels (Shared) */ +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + /* 32 channels (Shared): k80 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -void DMA0_DMA16_IRQHandler(void) +void DMA0_DMA16_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) { @@ -954,7 +1199,7 @@ void DMA0_DMA16_IRQHandler(void) } } -void DMA1_DMA17_IRQHandler(void) +void DMA1_DMA17_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) { @@ -966,7 +1211,7 @@ void DMA1_DMA17_IRQHandler(void) } } -void DMA2_DMA18_IRQHandler(void) +void DMA2_DMA18_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) { @@ -978,7 +1223,7 @@ void DMA2_DMA18_IRQHandler(void) } } -void DMA3_DMA19_IRQHandler(void) +void DMA3_DMA19_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) { @@ -990,7 +1235,7 @@ void DMA3_DMA19_IRQHandler(void) } } -void DMA4_DMA20_IRQHandler(void) +void DMA4_DMA20_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) { @@ -1002,7 +1247,7 @@ void DMA4_DMA20_IRQHandler(void) } } -void DMA5_DMA21_IRQHandler(void) +void DMA5_DMA21_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) { @@ -1014,7 +1259,7 @@ void DMA5_DMA21_IRQHandler(void) } } -void DMA6_DMA22_IRQHandler(void) +void DMA6_DMA22_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) { @@ -1026,7 +1271,7 @@ void DMA6_DMA22_IRQHandler(void) } } -void DMA7_DMA23_IRQHandler(void) +void DMA7_DMA23_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) { @@ -1038,7 +1283,7 @@ void DMA7_DMA23_IRQHandler(void) } } -void DMA8_DMA24_IRQHandler(void) +void DMA8_DMA24_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) { @@ -1050,7 +1295,7 @@ void DMA8_DMA24_IRQHandler(void) } } -void DMA9_DMA25_IRQHandler(void) +void DMA9_DMA25_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) { @@ -1062,7 +1307,7 @@ void DMA9_DMA25_IRQHandler(void) } } -void DMA10_DMA26_IRQHandler(void) +void DMA10_DMA26_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) { @@ -1074,7 +1319,7 @@ void DMA10_DMA26_IRQHandler(void) } } -void DMA11_DMA27_IRQHandler(void) +void DMA11_DMA27_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) { @@ -1086,7 +1331,7 @@ void DMA11_DMA27_IRQHandler(void) } } -void DMA12_DMA28_IRQHandler(void) +void DMA12_DMA28_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) { @@ -1098,7 +1343,7 @@ void DMA12_DMA28_IRQHandler(void) } } -void DMA13_DMA29_IRQHandler(void) +void DMA13_DMA29_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) { @@ -1110,7 +1355,7 @@ void DMA13_DMA29_IRQHandler(void) } } -void DMA14_DMA30_IRQHandler(void) +void DMA14_DMA30_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) { @@ -1122,7 +1367,7 @@ void DMA14_DMA30_IRQHandler(void) } } -void DMA15_DMA31_IRQHandler(void) +void DMA15_DMA31_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) { @@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void) } #endif /* 32 channels (Shared) */ +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + /* 4 channels (No Shared): kv10 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.h index 02c4fabf72..a97622d7e1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_edma.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_EDMA_H_ #define _FSL_EDMA_H_ @@ -45,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief eDMA driver version */ -#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @brief Compute the offset unit from DCHPRI3 */ @@ -77,28 +77,28 @@ typedef enum _edma_modulo kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ - kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ - kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ - kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ - kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ - kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ - kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ - kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ - kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ - kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ - kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ - kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ - kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ - kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ - kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ - kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ - kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ - kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ - kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ - kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ - kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ - kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ - kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ } edma_modulo_t; /*! @brief Bandwidth control */ @@ -177,7 +177,7 @@ typedef struct _edma_config the link channel is itself. */ bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared.*/ - bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority arbitration is used for channel selection */ bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of a new channel. Executing channels are allowed to complete. */ @@ -211,15 +211,15 @@ typedef struct _edma_transfer_config form the next-state value as each source read is completed. */ int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */ - uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t majorLoopCounts; /*!< Major loop iteration count. */ } edma_transfer_config_t; /*! @brief eDMA channel priority configuration */ typedef struct _edma_channel_Preemption_config { - bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ - bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ uint8_t channelPriority; /*!< Channel priority */ } edma_channel_Preemption_config_t; @@ -228,7 +228,7 @@ typedef struct _edma_minor_offset_config { bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ - uint32_t minorOffset; /*!< Offset for minor loop mapping. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ } edma_minor_offset_config_t; /*! @@ -255,20 +255,21 @@ typedef struct _edma_tcd /*! @brief Callback for eDMA */ struct _edma_handle; -/*! @brief Define Callback function for eDMA. */ +/*! @brief Define callback function for eDMA. */ typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); /*! @brief eDMA transfer handle structure */ typedef struct _edma_handle { - edma_callback callback; /*!< Callback function for major count exhausted. */ - void *userData; /*!< Callback function parameter. */ - DMA_Type *base; /*!< eDMA peripheral base address. */ - edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ - uint8_t channel; /*!< eDMA channel number. */ - volatile int8_t header; /*!< The first TCD index. */ - volatile int8_t tail; /*!< The last TCD index. */ - volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ uint8_t flags; /*!< The status of the current channel. */ } edma_handle_t; @@ -281,24 +282,24 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name eDMA initialization and De-initialization + * @name eDMA initialization and de-initialization * @{ */ /*! - * @brief Initializes eDMA peripheral. + * @brief Initializes the eDMA peripheral. * * This function ungates the eDMA clock and configures the eDMA peripheral according * to the configuration structure. * * @param base eDMA peripheral base address. - * @param config Pointer to configuration structure, see "edma_config_t". - * @note This function enable the minor loop map feature. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. */ void EDMA_Init(DMA_Type *base, const edma_config_t *config); /*! - * @brief Deinitializes eDMA peripheral. + * @brief Deinitializes the eDMA peripheral. * * This function gates the eDMA clock. * @@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base); /*! * @brief Gets the eDMA default configuration structure. * - * This function sets the configuration structure to a default value. - * The default configuration is set to the following value: + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. * @code * config.enableContinuousLinkMode = false; * config.enableHaltOnError = true; @@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base); * config.enableDebugMode = false; * @endcode * - * @param config Pointer to eDMA configuration structure. + * @param config A pointer to the eDMA configuration structure. */ void EDMA_GetDefaultConfig(edma_config_t *config); @@ -329,13 +330,13 @@ void EDMA_GetDefaultConfig(edma_config_t *config); */ /*! - * @brief Sets all TCD registers to a default value. + * @brief Sets all TCD registers to default values. * - * This function sets TCD registers for this channel to default value. + * This function sets TCD registers for this channel to default values. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @note This function must not be called while the channel transfer is on-going, + * @note This function must not be called while the channel transfer is ongoing * or it causes unpredictable results. * @note This function enables the auto stop request feature. */ @@ -364,7 +365,7 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); * do not want to enable scatter/gather feature. * @note If nextTcd is not NULL, it means scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which - * is set in eDMA_ResetChannel. + * is set in the eDMA_ResetChannel. */ void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, @@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base, /*! * @brief Configures the eDMA minor offset feature. * - * Minor offset means signed-extended value added to source address or destination + * The minor offset means that the signed-extended value is added to the source address or destination * address after each minor loop. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param config Pointer to Minor offset configuration structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); @@ -390,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino * * @param base eDMA peripheral base address. * @param channel eDMA channel number - * @param config Pointer to channel preemption configuration structure. + * @param config A pointer to the channel preemption configuration structure. */ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, @@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, /*! * @brief Sets the channel link for the eDMA transfer. * - * This function configures minor link or major link mode. The minor link means that the channel link is + * This function configures either the minor link or the major link mode. The minor link means that the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is * exhausted. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param type Channel link type, it can be one of: + * @param type A channel link type, which can be one of the following: * @arg kEDMA_LinkNone * @arg kEDMA_MinorLink * @arg kEDMA_MajorLink @@ -425,13 +426,13 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ /*! * @brief Sets the bandwidth for the eDMA transfer. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences + * Because the eDMA processes the minor loop, it continuously generates read/write sequences * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param bandWidth Bandwidth setting, it can be one of: + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); /*! - * @brief Sets the source modulo and destination modulo for eDMA transfer. + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data @@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable(ture) or disable(false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable (true) or disable (false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. Use + * @param mask The mask of the interrupt source to be set. Use * the defined edma_interrupt_enable_t type. */ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -523,8 +524,8 @@ void EDMA_TcdReset(edma_tcd_t *tcd); /*! * @brief Configures the eDMA TCD transfer attribute. * - * TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. - * STCD is used in scatter-gather mode. + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. * This function configures the TCD transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the next TCD address. @@ -542,7 +543,7 @@ void EDMA_TcdReset(edma_tcd_t *tcd); * @param config Pointer to eDMA transfer configuration structure. * @param nextTcd Pointer to the next TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note TCD address should be 32 bytes aligned, or it causes an eDMA error. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. * @note If the nextTcd is not NULL, the scatter gather feature is enabled * and DREQ bit is cleared in the previous transfer configuration, which * is set in the EDMA_TcdReset. @@ -552,16 +553,16 @@ void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *co /*! * @brief Configures the eDMA TCD minor offset feature. * - * Minor offset is a signed-extended value added to the source address or destination + * A minor offset is a signed-extended value added to the source address or a destination * address after each minor loop. * - * @param tcd Point to the TCD structure. - * @param config Pointer to Minor offset configuration structure. + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); /*! - * @brief Sets the channel link for eDMA TCD. + * @brief Sets the channel link for the eDMA TCD. * * This function configures either a minor link or a major link. The minor link means the channel link is * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is @@ -580,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint /*! * @brief Sets the bandwidth for the eDMA TCD. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * @param tcd Point to the TCD structure. - * @param bandWidth Bandwidth setting, it can be one of: + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -598,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi } /*! - * @brief Sets the source modulo and destination modulo for eDMA TCD. + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data * queue easily. * - * @param tcd Point to the TCD structure. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -615,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d * * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * - * @param tcd Point to the TCD structure. - * @param enable The command for enable(ture) or disable(false). + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) { @@ -681,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) } /*! - * @brief Starts the eDMA transfer by software trigger. + * @brief Starts the eDMA transfer by using the software trigger. * * This function starts a minor loop transfer. * @@ -702,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) */ /*! - * @brief Gets the Remaining bytes from the eDMA current channel TCD. + * @brief Gets the remaining major loop count from the eDMA current channel TCD. * * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the the number of bytes that have not finished. + * eDMA channel and returns the the number of major loop count that has not finished. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return Bytes have not been transferred yet for the current TCD. - * @note This function can only be used to get unfinished bytes of transfer without - * the next TCD, or it might be inaccuracy. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) */ -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); /*! * @brief Gets the eDMA channel error status flags. * * @param base eDMA peripheral base address. * @return The mask of error status flags. Users need to use the - * _edma_error_status_flags type to decode the return variables. +* _edma_error_status_flags type to decode the return variables. */ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) { @@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas /*! * @brief Creates the eDMA handle. * - * This function is called if using transaction API for eDMA. This function - * initializes the internal state of eDMA handle. + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. * * @param handle eDMA handle pointer. The eDMA handle stores callback function and * parameters. @@ -766,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); /*! - * @brief Installs the TCDs memory pool into eDMA handle. + * @brief Installs the TCDs memory pool into the eDMA handle. * * This function is called after the EDMA_CreateHandle to use scatter/gather feature. * * @param handle eDMA handle pointer. - * @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdSize The number of TCD slots. */ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); @@ -779,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t /*! * @brief Installs a callback function for the eDMA transfer. * - * This callback is called in eDMA IRQ handler. Use the callback to do something after + * This callback is called in the eDMA IRQ handler. Use the callback to do something after * the current major loop transfer completes. * * @param handle eDMA handle pointer. * @param callback eDMA callback function pointer. - * @param userData Parameter for callback function. + * @param userData A parameter for the callback function. */ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); @@ -802,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD * @param transferBytes eDMA transfer bytes to be transferred. * @param type eDMA transfer type. * @note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in - * source address error(SAE). + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). */ void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, @@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, * @brief Submits the eDMA transfer request. * * This function submits the eDMA transfer request according to the transfer configuration structure. - * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * If submitting the transfer request repeatedly, this function packs an unprocessed request as * a TCD and enables scatter/gather feature to process it in the next time. * * @param handle eDMA handle pointer. @@ -830,7 +840,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); /*! - * @brief eDMA start transfer. + * @brief eDMA starts transfer. * * This function enables the channel request. Users can call this function after submitting the transfer request * or before submitting the transfer request. @@ -840,7 +850,7 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t void EDMA_StartTransfer(edma_handle_t *handle); /*! - * @brief eDMA stop transfer. + * @brief eDMA stops transfer. * * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() * again to resume the transfer. @@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle); /*! - * @brief eDMA abort transfer. + * @brief eDMA aborts transfer. * * This function disables the channel request and clear transfer status bits. * Users can submit another transfer after calling this API. @@ -860,11 +870,31 @@ void EDMA_StopTransfer(edma_handle_t *handle); void EDMA_AbortTransfer(edma_handle_t *handle); /*! - * @brief eDMA IRQ handler for current major loop transfer complete. + * @brief eDMA IRQ handler for the current major loop transfer completion. * - * This function clears the channel major interrupt flag and call + * This function clears the channel major interrupt flag and calls * the callback function if it is not NULL. * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * * @param handle eDMA handle pointer. */ void EDMA_HandleIRQ(edma_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c index 1f09025fe7..be51f4c1a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_edma.h" @@ -63,11 +63,13 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd); /*! @brief Array to map EDMA instance number to base pointer. */ static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Array to map EDMA instance number to clock name. */ static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Array to map EDMA instance number to IRQ number. */ -static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS; +static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; /*! @brief Pointers to transfer handle for each EDMA channel. */ static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; @@ -81,7 +83,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) { if (s_edmaBases[instance] == base) { @@ -89,7 +91,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base) } } - assert(instance < FSL_FEATURE_SOC_EDMA_COUNT); + assert(instance < ARRAY_SIZE(s_edmaBases)); return instance; } @@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) uint32_t tmpreg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate EDMA periphral clock */ CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure EDMA peripheral according to the configuration structure. */ tmpreg = base->CR; tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); @@ -134,8 +138,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) void EDMA_Deinit(DMA_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate EDMA periphral clock */ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void EDMA_GetDefaultConfig(edma_config_t *config) @@ -409,46 +415,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) } } -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) { assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); - uint32_t nbytes = 0; - uint32_t remainingBytes = 0; + uint32_t remainingCount = 0; if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) { - remainingBytes = 0; + remainingCount = 0; } else { - /* Calculate the nbytes */ - if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK)) - { - nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >> - DMA_NBYTES_MLOFFYES_NBYTES_SHIFT; - } - else - { - nbytes = - (base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT; - } /* Calculate the unfinished bytes */ if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) { - remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; } else { - remainingBytes = - ((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; } } - return remainingBytes; + return remainingCount; } uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) @@ -497,14 +489,19 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) uint32_t channelIndex; edma_tcd_t *tcdRegs; + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + handle->base = base; handle->channel = channel; /* Get the DMA instance number */ edmaInstance = EDMA_GetInstance(base); channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; s_EDMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt */ - EnableIRQ(s_edmaIRQNumber[channelIndex]); + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + /* Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), CSR will be 0. Because in order to suit EDMA busy check mechanism in @@ -558,8 +555,8 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, assert(config != NULL); assert(srcAddr != NULL); assert(destAddr != NULL); - assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U || srcWidth == 16U || srcWidth == 32U); - assert(destWidth == 1U || destWidth == 2U || destWidth == 4U || destWidth == 16U || destWidth == 32U); + assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U)); + assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U)); assert(transferBytes % bytesEachRequest == 0); config->destAddr = (uint32_t)destAddr; @@ -825,11 +822,11 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Clear EDMA interrupt flag */ handle->base->CINT = handle->channel; - if (handle->tcdPool == NULL) + if ((handle->tcdPool == NULL) && (handle->callback != NULL)) { (handle->callback)(handle, handle->userData, true, 0); } - else /* Use the TCD queue. */ + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ { uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga_index; @@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Check if transfer is already finished. */ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); - /* Get the offset of the current transfer TCD blcoks. */ + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga -= (uint32_t)handle->tcdPool; - /* Get the index of the current transfer TCD blcoks. */ + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga_index = sga / sizeof(edma_tcd_t); /* Adjust header positions. */ if (transfer_done) { - /* New header shall point to the next TCD (current one is already finished) */ + /* New header shall point to the next TCD to be loaded (current one is already finished) */ new_header = sga_index; } else { - /* New header shall point to this descriptor (not finished yet) */ + /* New header shall point to this descriptor currently loaded (not finished yet) */ new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; } /* Calculate the number of finished TCDs */ @@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) } else { - /* Internal error occurs. */ + /* No TCD in the memory are going to be loaded or internal error occurs. */ tcds_done = 0; } } @@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle) tcds_done += handle->tcdSize; } } - /* Advance header to the point beyond the last finished TCD block. */ + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ handle->header = new_header; - /* Release TCD blocks. */ + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ handle->tcdUsed -= tcds_done; /* Invoke callback function. */ if (handle->callback) @@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void) EDMA_HandleIRQ(s_EDMAHandle[7]); } } + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif #endif /* 8 channels (Shared) */ +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + /* 32 channels (Shared): k80 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -void DMA0_DMA16_IRQHandler(void) +void DMA0_DMA16_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) { @@ -954,7 +1199,7 @@ void DMA0_DMA16_IRQHandler(void) } } -void DMA1_DMA17_IRQHandler(void) +void DMA1_DMA17_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) { @@ -966,7 +1211,7 @@ void DMA1_DMA17_IRQHandler(void) } } -void DMA2_DMA18_IRQHandler(void) +void DMA2_DMA18_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) { @@ -978,7 +1223,7 @@ void DMA2_DMA18_IRQHandler(void) } } -void DMA3_DMA19_IRQHandler(void) +void DMA3_DMA19_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) { @@ -990,7 +1235,7 @@ void DMA3_DMA19_IRQHandler(void) } } -void DMA4_DMA20_IRQHandler(void) +void DMA4_DMA20_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) { @@ -1002,7 +1247,7 @@ void DMA4_DMA20_IRQHandler(void) } } -void DMA5_DMA21_IRQHandler(void) +void DMA5_DMA21_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) { @@ -1014,7 +1259,7 @@ void DMA5_DMA21_IRQHandler(void) } } -void DMA6_DMA22_IRQHandler(void) +void DMA6_DMA22_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) { @@ -1026,7 +1271,7 @@ void DMA6_DMA22_IRQHandler(void) } } -void DMA7_DMA23_IRQHandler(void) +void DMA7_DMA23_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) { @@ -1038,7 +1283,7 @@ void DMA7_DMA23_IRQHandler(void) } } -void DMA8_DMA24_IRQHandler(void) +void DMA8_DMA24_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) { @@ -1050,7 +1295,7 @@ void DMA8_DMA24_IRQHandler(void) } } -void DMA9_DMA25_IRQHandler(void) +void DMA9_DMA25_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) { @@ -1062,7 +1307,7 @@ void DMA9_DMA25_IRQHandler(void) } } -void DMA10_DMA26_IRQHandler(void) +void DMA10_DMA26_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) { @@ -1074,7 +1319,7 @@ void DMA10_DMA26_IRQHandler(void) } } -void DMA11_DMA27_IRQHandler(void) +void DMA11_DMA27_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) { @@ -1086,7 +1331,7 @@ void DMA11_DMA27_IRQHandler(void) } } -void DMA12_DMA28_IRQHandler(void) +void DMA12_DMA28_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) { @@ -1098,7 +1343,7 @@ void DMA12_DMA28_IRQHandler(void) } } -void DMA13_DMA29_IRQHandler(void) +void DMA13_DMA29_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) { @@ -1110,7 +1355,7 @@ void DMA13_DMA29_IRQHandler(void) } } -void DMA14_DMA30_IRQHandler(void) +void DMA14_DMA30_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) { @@ -1122,7 +1367,7 @@ void DMA14_DMA30_IRQHandler(void) } } -void DMA15_DMA31_IRQHandler(void) +void DMA15_DMA31_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) { @@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void) } #endif /* 32 channels (Shared) */ +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + /* 4 channels (No Shared): kv10 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h index ca9632e247..a97622d7e1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_edma.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without modification, -* are permitted provided that the following conditions are met: -* -* o Redistributions of source code must retain the above copyright notice, this list -* of conditions and the following disclaimer. -* -* o Redistributions in binary form must reproduce the above copyright notice, this -* list of conditions and the following disclaimer in the documentation and/or -* other materials provided with the distribution. -* -* o Neither the name of Freescale Semiconductor, Inc. nor the names of its -* contributors may be used to endorse or promote products derived from this -* software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_EDMA_H_ #define _FSL_EDMA_H_ @@ -34,11 +34,10 @@ #include "fsl_common.h" /*! - * @addtogroup edma_driver + * @addtogroup edma * @{ */ -/*! @file */ /******************************************************************************* * Definitions ******************************************************************************/ @@ -46,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief eDMA driver version */ -#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @brief Compute the offset unit from DCHPRI3 */ @@ -78,28 +77,28 @@ typedef enum _edma_modulo kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ - kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ - kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ - kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ - kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ - kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ - kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ - kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ - kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ - kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ - kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ - kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ - kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ - kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ - kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ - kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ - kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ - kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ - kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ - kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ - kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ - kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ - kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ } edma_modulo_t; /*! @brief Bandwidth control */ @@ -143,7 +142,7 @@ enum _edma_error_status_flags #if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ #endif - kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit will be 0, otherwise be 1 */ + kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */ }; /*! @brief eDMA interrupt source */ @@ -178,7 +177,7 @@ typedef struct _edma_config the link channel is itself. */ bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared.*/ - bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority arbitration is used for channel selection */ bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of a new channel. Executing channels are allowed to complete. */ @@ -212,15 +211,15 @@ typedef struct _edma_transfer_config form the next-state value as each source read is completed. */ int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */ - uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t majorLoopCounts; /*!< Major loop iteration count. */ } edma_transfer_config_t; /*! @brief eDMA channel priority configuration */ typedef struct _edma_channel_Preemption_config { - bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ - bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ uint8_t channelPriority; /*!< Channel priority */ } edma_channel_Preemption_config_t; @@ -229,14 +228,14 @@ typedef struct _edma_minor_offset_config { bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ - uint32_t minorOffset; /*!< Offset for minor loop mapping. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ } edma_minor_offset_config_t; /*! * @brief eDMA TCD. * * This structure is same as TCD register which is described in reference manual, - * and is used to configure scatter/gather feature as a next hardware TCD. + * and is used to configure the scatter/gather feature as a next hardware TCD. */ typedef struct _edma_tcd { @@ -256,20 +255,21 @@ typedef struct _edma_tcd /*! @brief Callback for eDMA */ struct _edma_handle; -/*! @brief Define Callback function for eDMA. */ +/*! @brief Define callback function for eDMA. */ typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); /*! @brief eDMA transfer handle structure */ typedef struct _edma_handle { - edma_callback callback; /*!< Callback function for major count exhausted. */ - void *userData; /*!< Callback function parameter. */ - DMA_Type *base; /*!< eDMA peripheral base address. */ - edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ - uint8_t channel; /*!< eDMA channel number. */ - volatile int8_t header; /*!< The first TCD index. */ - volatile int8_t tail; /*!< The last TCD index. */ - volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ uint8_t flags; /*!< The status of the current channel. */ } edma_handle_t; @@ -282,24 +282,24 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name eDMA initialization and De-initialization + * @name eDMA initialization and de-initialization * @{ */ /*! - * @brief Initializes eDMA peripheral. + * @brief Initializes the eDMA peripheral. * - * This function ungates the eDMA clock and configure eDMA peripheral according + * This function ungates the eDMA clock and configures the eDMA peripheral according * to the configuration structure. * * @param base eDMA peripheral base address. - * @param config Pointer to configuration structure, see "edma_config_t". - * @note This function enable the minor loop map feature. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. */ void EDMA_Init(DMA_Type *base, const edma_config_t *config); /*! - * @brief Deinitializes eDMA peripheral. + * @brief Deinitializes the eDMA peripheral. * * This function gates the eDMA clock. * @@ -310,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base); /*! * @brief Gets the eDMA default configuration structure. * - * This function sets the configuration structure to a default value. - * The default configuration is set to the following value: + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. * @code * config.enableContinuousLinkMode = false; * config.enableHaltOnError = true; @@ -319,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base); * config.enableDebugMode = false; * @endcode * - * @param config Pointer to eDMA configuration structure. + * @param config A pointer to the eDMA configuration structure. */ void EDMA_GetDefaultConfig(edma_config_t *config); @@ -330,22 +330,22 @@ void EDMA_GetDefaultConfig(edma_config_t *config); */ /*! - * @brief Sets all TCD registers to a default value. + * @brief Sets all TCD registers to default values. * - * This function sets TCD registers for this channel to default value. + * This function sets TCD registers for this channel to default values. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @note This function must not be called while the channel transfer is on-going, - * or it will case unpredicated results. - * @note This function will enable auto stop request feature. + * @note This function must not be called while the channel transfer is ongoing + * or it causes unpredictable results. + * @note This function enables the auto stop request feature. */ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); /*! * @brief Configures the eDMA transfer attribute. * - * This function configure the transfer attribute, including source address, destination address, + * This function configures the transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the TCD address. * Example: @@ -361,11 +361,11 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); * @param base eDMA peripheral base address. * @param channel eDMA channel number. * @param config Pointer to eDMA transfer configuration structure. - * @param nextTcd Point to TCD structure. It can be NULL if user + * @param nextTcd Point to TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note If nextTcd is not NULL, it means scatter gather feature will be enabled. - * And DREQ bit will be cleared in the previous transfer configuration which - * will be set in eDMA_ResetChannel. + * @note If nextTcd is not NULL, it means scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the eDMA_ResetChannel. */ void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, @@ -375,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base, /*! * @brief Configures the eDMA minor offset feature. * - * Minor offset means signed-extended value added to source address or destination + * The minor offset means that the signed-extended value is added to the source address or destination * address after each minor loop. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param config Pointer to Minor offset configuration structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); @@ -391,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino * * @param base eDMA peripheral base address. * @param channel eDMA channel number - * @param config Pointer to channel preemption configuration structure. + * @param config A pointer to the channel preemption configuration structure. */ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, @@ -408,30 +408,31 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, /*! * @brief Sets the channel link for the eDMA transfer. * - * This function configures minor link or major link mode. The minor link means that the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. + * This function configures either the minor link or the major link mode. The minor link means that the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param type Channel link type, it can be one of: + * @param type A channel link type, which can be one of the following: * @arg kEDMA_LinkNone * @arg kEDMA_MinorLink * @arg kEDMA_MajorLink * @param linkedChannel The linked channel number. - * @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. */ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); /*! * @brief Sets the bandwidth for the eDMA transfer. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences + * Because the eDMA processes the minor loop, it continuously generates read/write sequences * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param bandWidth Bandwidth setting, it can be one of: + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); /*! - * @brief Sets the source modulo and destination modulo for eDMA transfer. + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data @@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable(ture) or disable(false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable (true) or disable (false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -489,7 +490,7 @@ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. Use + * @param mask The mask of the interrupt source to be set. Use * the defined edma_interrupt_enable_t type. */ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -516,15 +517,15 @@ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t ma * This function sets all fields for this TCD structure to default value. * * @param tcd Pointer to the TCD structure. - * @note This function will enable auto stop request feature. + * @note This function enables the auto stop request feature. */ void EDMA_TcdReset(edma_tcd_t *tcd); /*! * @brief Configures the eDMA TCD transfer attribute. * - * TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. - * STCD is used in scatter-gather mode. + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. * This function configures the TCD transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the next TCD address. @@ -540,33 +541,34 @@ void EDMA_TcdReset(edma_tcd_t *tcd); * * @param tcd Pointer to the TCD structure. * @param config Pointer to eDMA transfer configuration structure. - * @param nextTcd Pointer to the next TCD structure. It can be NULL if user + * @param nextTcd Pointer to the next TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note TCD address should be 32 bytes aligned, or it will cause eDMA error. - * @note If nextTcd is not NULL, it means scatter gather feature will be enabled. - * And DREQ bit will be cleared in the previous transfer configuration which - * will be set in EDMA_TcdReset. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. + * @note If the nextTcd is not NULL, the scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the EDMA_TcdReset. */ void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); /*! * @brief Configures the eDMA TCD minor offset feature. * - * Minor offset is a signed-extended value added to the source address or destination + * A minor offset is a signed-extended value added to the source address or a destination * address after each minor loop. * - * @param tcd Point to the TCD structure. - * @param config Pointer to Minor offset configuration structure. + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); /*! - * @brief Sets the channel link for eDMA TCD. + * @brief Sets the channel link for the eDMA TCD. * * This function configures either a minor link or a major link. The minor link means the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. * - * @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. * @param tcd Point to the TCD structure. * @param type Channel link type, it can be one of: * @arg kEDMA_LinkNone @@ -579,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint /*! * @brief Sets the bandwidth for the eDMA TCD. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * @param tcd Point to the TCD structure. - * @param bandWidth Bandwidth setting, it can be one of: + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -597,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi } /*! - * @brief Sets the source modulo and destination modulo for eDMA TCD. + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data * queue easily. * - * @param tcd Point to the TCD structure. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -614,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d * * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * - * @param tcd Point to the TCD structure. - * @param enable The command for enable(ture) or disable(false). + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) { @@ -629,7 +631,7 @@ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) * @brief Enables the interrupt source for the eDMA TCD. * * @param tcd Point to the TCD structure. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); @@ -638,7 +640,7 @@ void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); * @brief Disables the interrupt source for the eDMA TCD. * * @param tcd Point to the TCD structure. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); @@ -680,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) } /*! - * @brief Starts the eDMA transfer by software trigger. + * @brief Starts the eDMA transfer by using the software trigger. * * This function starts a minor loop transfer. * @@ -701,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) */ /*! - * @brief Gets the Remaining bytes from the eDMA current channel TCD. + * @brief Gets the remaining major loop count from the eDMA current channel TCD. * * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the the number of bytes that have not finished. + * eDMA channel and returns the the number of major loop count that has not finished. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return Bytes have not been transferred yet for the current TCD. - * @note This function can only be used to get unfinished bytes of transfer without - * the next TCD, or it might be inaccuracy. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) */ -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); /*! * @brief Gets the eDMA channel error status flags. * * @param base eDMA peripheral base address. - * @return The mask of error status flags. User need to use the - * _edma_error_status_flags type to decode the return variables. + * @return The mask of error status flags. Users need to use the +* _edma_error_status_flags type to decode the return variables. */ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) { @@ -731,7 +742,7 @@ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return The mask of channel status flags. User need to use the + * @return The mask of channel status flags. Users need to use the * _edma_channel_status_flags type to decode the return variables. */ uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); @@ -741,7 +752,7 @@ uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of channel status to be cleared. User need to use + * @param mask The mask of channel status to be cleared. Users need to use * the defined _edma_channel_status_flags type. */ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -754,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas /*! * @brief Creates the eDMA handle. * - * This function is called if using transaction API for eDMA. This function - * initializes the internal state of eDMA handle. + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. * * @param handle eDMA handle pointer. The eDMA handle stores callback function and * parameters. @@ -765,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); /*! - * @brief Installs the TCDs memory pool into eDMA handle. + * @brief Installs the TCDs memory pool into the eDMA handle. * * This function is called after the EDMA_CreateHandle to use scatter/gather feature. * * @param handle eDMA handle pointer. - * @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdSize The number of TCD slots. */ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); @@ -778,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t /*! * @brief Installs a callback function for the eDMA transfer. * - * This callback is called in eDMA IRQ handler. Use the callback to do something after + * This callback is called in the eDMA IRQ handler. Use the callback to do something after * the current major loop transfer completes. * * @param handle eDMA handle pointer. * @param callback eDMA callback function pointer. - * @param userData Parameter for callback function. + * @param userData A parameter for the callback function. */ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); @@ -801,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD * @param transferBytes eDMA transfer bytes to be transferred. * @param type eDMA transfer type. * @note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in - * source address error(SAE). + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). */ void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, @@ -817,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, * @brief Submits the eDMA transfer request. * * This function submits the eDMA transfer request according to the transfer configuration structure. - * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * If submitting the transfer request repeatedly, this function packs an unprocessed request as * a TCD and enables scatter/gather feature to process it in the next time. * * @param handle eDMA handle pointer. @@ -829,9 +840,9 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); /*! - * @brief eDMA start transfer. + * @brief eDMA starts transfer. * - * This function enables the channel request. User can call this function after submitting the transfer request + * This function enables the channel request. Users can call this function after submitting the transfer request * or before submitting the transfer request. * * @param handle eDMA handle pointer. @@ -839,9 +850,9 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t void EDMA_StartTransfer(edma_handle_t *handle); /*! - * @brief eDMA stop transfer. + * @brief eDMA stops transfer. * - * This function disables the channel request to pause the transfer. User can call EDMA_StartTransfer() + * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() * again to resume the transfer. * * @param handle eDMA handle pointer. @@ -849,21 +860,41 @@ void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle); /*! - * @brief eDMA abort transfer. + * @brief eDMA aborts transfer. * * This function disables the channel request and clear transfer status bits. - * User can submit another transfer after calling this API. + * Users can submit another transfer after calling this API. * * @param handle DMA handle pointer. */ void EDMA_AbortTransfer(edma_handle_t *handle); /*! - * @brief eDMA IRQ handler for current major loop transfer complete. + * @brief eDMA IRQ handler for the current major loop transfer completion. * - * This function clears the channel major interrupt flag and call + * This function clears the channel major interrupt flag and calls * the callback function if it is not NULL. * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * * @param handle eDMA handle pointer. */ void EDMA_HandleIRQ(edma_handle_t *handle);