MCUXpresso: Update SDK EDMA driver

Update to the latest version from K66F

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/11308/head
Mahesh Mahadevan 2019-08-21 15:38:37 -05:00 committed by adbridge
parent cc70640ff4
commit 8022ca918f
8 changed files with 2745 additions and 860 deletions

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -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. */ /*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; 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. */ /*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; 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. */ /*! @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. */ /*! @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]; 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; uint32_t instance;
/* Find the instance index from base address mappings. */ /* 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) 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; return instance;
} }
@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg; uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */ /* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */ /* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->CR; tmpreg = base->CR;
tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); 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) void EDMA_Deinit(DMA_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate EDMA periphral clock */ /* Gate EDMA periphral clock */
CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EDMA_GetDefaultConfig(edma_config_t *config) 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); assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
uint32_t nbytes = 0; uint32_t remainingCount = 0;
uint32_t remainingBytes = 0;
if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)
{ {
remainingBytes = 0; remainingCount = 0;
} }
else 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 */ /* Calculate the unfinished bytes */
if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)
{ {
remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> remainingCount =
DMA_CITER_ELINKYES_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT;
nbytes;
} }
else else
{ {
remainingBytes = remainingCount =
((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT;
nbytes;
} }
} }
return remainingBytes; return remainingCount;
} }
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) 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; uint32_t channelIndex;
edma_tcd_t *tcdRegs; edma_tcd_t *tcdRegs;
/* Zero the handle */
memset(handle, 0, sizeof(*handle));
handle->base = base; handle->base = base;
handle->channel = channel; handle->channel = channel;
/* Get the DMA instance number */ /* Get the DMA instance number */
edmaInstance = EDMA_GetInstance(base); edmaInstance = EDMA_GetInstance(base);
channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
s_EDMAHandle[channelIndex] = handle; s_EDMAHandle[channelIndex] = handle;
/* Enable NVIC interrupt */ /* 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), 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 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); (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 = handle->base->TCD[handle->channel].DLAST_SGA;
uint32_t sga_index; uint32_t sga_index;
@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Check if transfer is already finished. */ /* Check if transfer is already finished. */
transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); 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; 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); sga_index = sga / sizeof(edma_tcd_t);
/* Adjust header positions. */ /* Adjust header positions. */
if (transfer_done) 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; new_header = sga_index;
} }
else 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; new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U;
} }
/* Calculate the number of finished TCDs */ /* Calculate the number of finished TCDs */
@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
} }
else else
{ {
/* Internal error occurs. */ /* No TCD in the memory are going to be loaded or internal error occurs. */
tcds_done = 0; tcds_done = 0;
} }
} }
@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
tcds_done += handle->tcdSize; 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; 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; handle->tcdUsed -= tcds_done;
/* Invoke callback function. */ /* Invoke callback function. */
if (handle->callback) if (handle->callback)
@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void)
EDMA_HandleIRQ(s_EDMAHandle[7]); 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) */ #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 */ /* 32 channels (Shared): k80 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U #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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void)
} }
#endif /* 32 channels (Shared) */ #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 */ /* 4 channels (No Shared): kv10 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -45,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief eDMA 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 */ /*! @brief Compute the offset unit from DCHPRI3 */
@ -177,7 +177,7 @@ typedef struct _edma_config
the link channel is itself. */ the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. 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.*/ 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 */ arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of 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. */ 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. */ form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */ 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. */ uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t; } edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */ /*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config typedef struct _edma_channel_Preemption_config
{ {
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */ uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t; } 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 enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination 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; } edma_minor_offset_config_t;
/*! /*!
@ -255,7 +255,7 @@ typedef struct _edma_tcd
/*! @brief Callback for eDMA */ /*! @brief Callback for eDMA */
struct _edma_handle; 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); typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */ /*! @brief eDMA transfer handle structure */
@ -266,9 +266,10 @@ typedef struct _edma_handle
DMA_Type *base; /*!< eDMA peripheral base address. */ DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */ uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. */ 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. */ 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. */ 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. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */ uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t; } edma_handle_t;
@ -281,24 +282,24 @@ extern "C" {
#endif /* __cplusplus */ #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 * This function ungates the eDMA clock and configures the eDMA peripheral according
* to the configuration structure. * to the configuration structure.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param config Pointer to configuration structure, see "edma_config_t". * @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enable the minor loop map feature. * @note This function enables the minor loop map feature.
*/ */
void EDMA_Init(DMA_Type *base, const edma_config_t *config); 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. * This function gates the eDMA clock.
* *
@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base);
/*! /*!
* @brief Gets the eDMA default configuration structure. * @brief Gets the eDMA default configuration structure.
* *
* This function sets the configuration structure to a default value. * This function sets the configuration structure to default values.
* The default configuration is set to the following value: * The default configuration is set to the following values.
* @code * @code
* config.enableContinuousLinkMode = false; * config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true; * config.enableHaltOnError = true;
@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base);
* config.enableDebugMode = false; * config.enableDebugMode = false;
* @endcode * @endcode
* *
* @param config Pointer to eDMA configuration structure. * @param config A pointer to the eDMA configuration structure.
*/ */
void EDMA_GetDefaultConfig(edma_config_t *config); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * or it causes unpredictable results.
* @note This function enables the auto stop request feature. * @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. * do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature is enabled * @note If nextTcd is not NULL, it means scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * 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, void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base,
/*! /*!
* @brief Configures the eDMA minor offset feature. * @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. * address after each minor loop.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number * @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, static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
/*! /*!
* @brief Sets the channel link for the eDMA transfer. * @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 * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted. * exhausted.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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_LinkNone
* @arg kEDMA_MinorLink * @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink * @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. * @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 * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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 kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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); 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) * 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination 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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); 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. * @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. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* STCD is used in scatter-gather mode. * The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address, * 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 * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address. * 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 config Pointer to eDMA transfer configuration structure.
* @param nextTcd Pointer to the next TCD structure. It can be NULL if users * @param nextTcd Pointer to the next TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature. * 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 * @note If the nextTcd is not NULL, the scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * and DREQ bit is cleared in the previous transfer configuration, which
* is set in the EDMA_TcdReset. * 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. * @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. * address after each minor loop.
* *
* @param tcd Point to the TCD structure. * @param tcd A point to the TCD structure.
* @param config Pointer to Minor offset configuration 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); 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 * 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 * 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. * @brief Sets the bandwidth for the eDMA TCD.
* *
* 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. Bandwidth forces the eDMA to stall after the completion of * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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) * 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 * calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily. * queue easily.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); 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. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) 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. * This function starts a minor loop transfer.
* *
@ -702,18 +703,27 @@ 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return Bytes have not been transferred yet for the current TCD. * @return Major loop count which has not been transferred yet for the current TCD.
* @note This function can only be used to get unfinished bytes of transfer without * @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. * 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. * @brief Gets the eDMA channel error status flags.
@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas
/*! /*!
* @brief Creates the eDMA handle. * @brief Creates the eDMA handle.
* *
* This function is called if using transaction API for eDMA. This function * This function is called if using the transactional API for eDMA. This function
* initializes the internal state of eDMA handle. * initializes the internal state of the eDMA handle.
* *
* @param handle eDMA handle pointer. The eDMA handle stores callback function and * @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters. * 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); 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. * This function is called after the EDMA_CreateHandle to use scatter/gather feature.
* *
* @param handle eDMA handle pointer. * @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. * @param tcdSize The number of TCD slots.
*/ */
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); 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. * @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. * the current major loop transfer completes.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param callback eDMA callback function 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); void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
@ -802,7 +812,7 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD
* @param transferBytes eDMA transfer bytes to be transferred. * @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type. * @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC * @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 * is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error (SAE). * source address error (SAE).
*/ */
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void EDMA_PrepareTransfer(edma_transfer_config_t *config,
@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
* @brief Submits the eDMA transfer request. * @brief Submits the eDMA transfer request.
* *
* This function submits the eDMA transfer request according to the transfer configuration structure. * 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. * a TCD and enables scatter/gather feature to process it in the next time.
* *
* @param handle eDMA handle pointer. * @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); 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 * This function enables the channel request. Users can call this function after submitting the transfer request
* or before 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); 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() * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
* again to resume the transfer. * again to resume the transfer.
@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle);
void EDMA_StopTransfer(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. * This function disables the channel request and clear transfer status bits.
* Users can submit another transfer after calling this API. * 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); 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. * 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. * @param handle eDMA handle pointer.
*/ */
void EDMA_HandleIRQ(edma_handle_t *handle); void EDMA_HandleIRQ(edma_handle_t *handle);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -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. */ /*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; 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. */ /*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; 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. */ /*! @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. */ /*! @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]; 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; uint32_t instance;
/* Find the instance index from base address mappings. */ /* 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) 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; return instance;
} }
@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg; uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */ /* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */ /* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->CR; tmpreg = base->CR;
tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); 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) void EDMA_Deinit(DMA_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate EDMA periphral clock */ /* Gate EDMA periphral clock */
CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EDMA_GetDefaultConfig(edma_config_t *config) 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); assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
uint32_t nbytes = 0; uint32_t remainingCount = 0;
uint32_t remainingBytes = 0;
if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)
{ {
remainingBytes = 0; remainingCount = 0;
} }
else 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 */ /* Calculate the unfinished bytes */
if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)
{ {
remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> remainingCount =
DMA_CITER_ELINKYES_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT;
nbytes;
} }
else else
{ {
remainingBytes = remainingCount =
((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT;
nbytes;
} }
} }
return remainingBytes; return remainingCount;
} }
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) 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; uint32_t channelIndex;
edma_tcd_t *tcdRegs; edma_tcd_t *tcdRegs;
/* Zero the handle */
memset(handle, 0, sizeof(*handle));
handle->base = base; handle->base = base;
handle->channel = channel; handle->channel = channel;
/* Get the DMA instance number */ /* Get the DMA instance number */
edmaInstance = EDMA_GetInstance(base); edmaInstance = EDMA_GetInstance(base);
channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
s_EDMAHandle[channelIndex] = handle; s_EDMAHandle[channelIndex] = handle;
/* Enable NVIC interrupt */ /* 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), 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 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); (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 = handle->base->TCD[handle->channel].DLAST_SGA;
uint32_t sga_index; uint32_t sga_index;
@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Check if transfer is already finished. */ /* Check if transfer is already finished. */
transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); 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; 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); sga_index = sga / sizeof(edma_tcd_t);
/* Adjust header positions. */ /* Adjust header positions. */
if (transfer_done) 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; new_header = sga_index;
} }
else 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; new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U;
} }
/* Calculate the number of finished TCDs */ /* Calculate the number of finished TCDs */
@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
} }
else else
{ {
/* Internal error occurs. */ /* No TCD in the memory are going to be loaded or internal error occurs. */
tcds_done = 0; tcds_done = 0;
} }
} }
@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
tcds_done += handle->tcdSize; 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; 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; handle->tcdUsed -= tcds_done;
/* Invoke callback function. */ /* Invoke callback function. */
if (handle->callback) if (handle->callback)
@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void)
EDMA_HandleIRQ(s_EDMAHandle[7]); 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) */ #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 */ /* 32 channels (Shared): k80 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U #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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void)
} }
#endif /* 32 channels (Shared) */ #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 */ /* 4 channels (No Shared): kv10 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -45,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief eDMA 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 */ /*! @brief Compute the offset unit from DCHPRI3 */
@ -177,7 +177,7 @@ typedef struct _edma_config
the link channel is itself. */ the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. 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.*/ 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 */ arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of 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. */ 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. */ form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */ 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. */ uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t; } edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */ /*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config typedef struct _edma_channel_Preemption_config
{ {
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */ uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t; } 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 enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination 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; } edma_minor_offset_config_t;
/*! /*!
@ -255,7 +255,7 @@ typedef struct _edma_tcd
/*! @brief Callback for eDMA */ /*! @brief Callback for eDMA */
struct _edma_handle; 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); typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */ /*! @brief eDMA transfer handle structure */
@ -266,9 +266,10 @@ typedef struct _edma_handle
DMA_Type *base; /*!< eDMA peripheral base address. */ DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */ uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. */ 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. */ 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. */ 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. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */ uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t; } edma_handle_t;
@ -281,24 +282,24 @@ extern "C" {
#endif /* __cplusplus */ #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 * This function ungates the eDMA clock and configures the eDMA peripheral according
* to the configuration structure. * to the configuration structure.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param config Pointer to configuration structure, see "edma_config_t". * @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enable the minor loop map feature. * @note This function enables the minor loop map feature.
*/ */
void EDMA_Init(DMA_Type *base, const edma_config_t *config); 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. * This function gates the eDMA clock.
* *
@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base);
/*! /*!
* @brief Gets the eDMA default configuration structure. * @brief Gets the eDMA default configuration structure.
* *
* This function sets the configuration structure to a default value. * This function sets the configuration structure to default values.
* The default configuration is set to the following value: * The default configuration is set to the following values.
* @code * @code
* config.enableContinuousLinkMode = false; * config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true; * config.enableHaltOnError = true;
@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base);
* config.enableDebugMode = false; * config.enableDebugMode = false;
* @endcode * @endcode
* *
* @param config Pointer to eDMA configuration structure. * @param config A pointer to the eDMA configuration structure.
*/ */
void EDMA_GetDefaultConfig(edma_config_t *config); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * or it causes unpredictable results.
* @note This function enables the auto stop request feature. * @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. * do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature is enabled * @note If nextTcd is not NULL, it means scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * 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, void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base,
/*! /*!
* @brief Configures the eDMA minor offset feature. * @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. * address after each minor loop.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number * @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, static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
/*! /*!
* @brief Sets the channel link for the eDMA transfer. * @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 * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted. * exhausted.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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_LinkNone
* @arg kEDMA_MinorLink * @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink * @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. * @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 * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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 kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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); 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) * 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination 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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); 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. * @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. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* STCD is used in scatter-gather mode. * The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address, * 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 * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address. * 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 config Pointer to eDMA transfer configuration structure.
* @param nextTcd Pointer to the next TCD structure. It can be NULL if users * @param nextTcd Pointer to the next TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature. * 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 * @note If the nextTcd is not NULL, the scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * and DREQ bit is cleared in the previous transfer configuration, which
* is set in the EDMA_TcdReset. * 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. * @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. * address after each minor loop.
* *
* @param tcd Point to the TCD structure. * @param tcd A point to the TCD structure.
* @param config Pointer to Minor offset configuration 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); 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 * 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 * 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. * @brief Sets the bandwidth for the eDMA TCD.
* *
* 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. Bandwidth forces the eDMA to stall after the completion of * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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) * 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 * calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily. * queue easily.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); 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. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) 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. * This function starts a minor loop transfer.
* *
@ -702,18 +703,27 @@ 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return Bytes have not been transferred yet for the current TCD. * @return Major loop count which has not been transferred yet for the current TCD.
* @note This function can only be used to get unfinished bytes of transfer without * @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. * 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. * @brief Gets the eDMA channel error status flags.
@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas
/*! /*!
* @brief Creates the eDMA handle. * @brief Creates the eDMA handle.
* *
* This function is called if using transaction API for eDMA. This function * This function is called if using the transactional API for eDMA. This function
* initializes the internal state of eDMA handle. * initializes the internal state of the eDMA handle.
* *
* @param handle eDMA handle pointer. The eDMA handle stores callback function and * @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters. * 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); 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. * This function is called after the EDMA_CreateHandle to use scatter/gather feature.
* *
* @param handle eDMA handle pointer. * @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. * @param tcdSize The number of TCD slots.
*/ */
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); 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. * @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. * the current major loop transfer completes.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param callback eDMA callback function 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); void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
@ -802,7 +812,7 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD
* @param transferBytes eDMA transfer bytes to be transferred. * @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type. * @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC * @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 * is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error (SAE). * source address error (SAE).
*/ */
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void EDMA_PrepareTransfer(edma_transfer_config_t *config,
@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
* @brief Submits the eDMA transfer request. * @brief Submits the eDMA transfer request.
* *
* This function submits the eDMA transfer request according to the transfer configuration structure. * 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. * a TCD and enables scatter/gather feature to process it in the next time.
* *
* @param handle eDMA handle pointer. * @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); 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 * This function enables the channel request. Users can call this function after submitting the transfer request
* or before 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); 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() * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
* again to resume the transfer. * again to resume the transfer.
@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle);
void EDMA_StopTransfer(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. * This function disables the channel request and clear transfer status bits.
* Users can submit another transfer after calling this API. * 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); 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. * 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. * @param handle eDMA handle pointer.
*/ */
void EDMA_HandleIRQ(edma_handle_t *handle); void EDMA_HandleIRQ(edma_handle_t *handle);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -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. */ /*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; 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. */ /*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; 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. */ /*! @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. */ /*! @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]; 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; uint32_t instance;
/* Find the instance index from base address mappings. */ /* 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) 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; return instance;
} }
@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg; uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */ /* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */ /* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->CR; tmpreg = base->CR;
tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); 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) void EDMA_Deinit(DMA_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate EDMA periphral clock */ /* Gate EDMA periphral clock */
CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EDMA_GetDefaultConfig(edma_config_t *config) 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); assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
uint32_t nbytes = 0; uint32_t remainingCount = 0;
uint32_t remainingBytes = 0;
if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)
{ {
remainingBytes = 0; remainingCount = 0;
} }
else 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 */ /* Calculate the unfinished bytes */
if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)
{ {
remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> remainingCount =
DMA_CITER_ELINKYES_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT;
nbytes;
} }
else else
{ {
remainingBytes = remainingCount =
((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT;
nbytes;
} }
} }
return remainingBytes; return remainingCount;
} }
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) 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; uint32_t channelIndex;
edma_tcd_t *tcdRegs; edma_tcd_t *tcdRegs;
/* Zero the handle */
memset(handle, 0, sizeof(*handle));
handle->base = base; handle->base = base;
handle->channel = channel; handle->channel = channel;
/* Get the DMA instance number */ /* Get the DMA instance number */
edmaInstance = EDMA_GetInstance(base); edmaInstance = EDMA_GetInstance(base);
channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
s_EDMAHandle[channelIndex] = handle; s_EDMAHandle[channelIndex] = handle;
/* Enable NVIC interrupt */ /* 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), 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 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); (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 = handle->base->TCD[handle->channel].DLAST_SGA;
uint32_t sga_index; uint32_t sga_index;
@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Check if transfer is already finished. */ /* Check if transfer is already finished. */
transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); 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; 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); sga_index = sga / sizeof(edma_tcd_t);
/* Adjust header positions. */ /* Adjust header positions. */
if (transfer_done) 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; new_header = sga_index;
} }
else 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; new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U;
} }
/* Calculate the number of finished TCDs */ /* Calculate the number of finished TCDs */
@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
} }
else else
{ {
/* Internal error occurs. */ /* No TCD in the memory are going to be loaded or internal error occurs. */
tcds_done = 0; tcds_done = 0;
} }
} }
@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
tcds_done += handle->tcdSize; 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; 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; handle->tcdUsed -= tcds_done;
/* Invoke callback function. */ /* Invoke callback function. */
if (handle->callback) if (handle->callback)
@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void)
EDMA_HandleIRQ(s_EDMAHandle[7]); 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) */ #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 */ /* 32 channels (Shared): k80 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U #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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void)
} }
#endif /* 32 channels (Shared) */ #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 */ /* 4 channels (No Shared): kv10 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -45,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief eDMA 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 */ /*! @brief Compute the offset unit from DCHPRI3 */
@ -177,7 +177,7 @@ typedef struct _edma_config
the link channel is itself. */ the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. 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.*/ 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 */ arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of 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. */ 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. */ form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */ 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. */ uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t; } edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */ /*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config typedef struct _edma_channel_Preemption_config
{ {
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */ uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t; } 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 enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination 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; } edma_minor_offset_config_t;
/*! /*!
@ -255,7 +255,7 @@ typedef struct _edma_tcd
/*! @brief Callback for eDMA */ /*! @brief Callback for eDMA */
struct _edma_handle; 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); typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */ /*! @brief eDMA transfer handle structure */
@ -266,9 +266,10 @@ typedef struct _edma_handle
DMA_Type *base; /*!< eDMA peripheral base address. */ DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */ uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. */ 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. */ 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. */ 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. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */ uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t; } edma_handle_t;
@ -281,24 +282,24 @@ extern "C" {
#endif /* __cplusplus */ #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 * This function ungates the eDMA clock and configures the eDMA peripheral according
* to the configuration structure. * to the configuration structure.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param config Pointer to configuration structure, see "edma_config_t". * @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enable the minor loop map feature. * @note This function enables the minor loop map feature.
*/ */
void EDMA_Init(DMA_Type *base, const edma_config_t *config); 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. * This function gates the eDMA clock.
* *
@ -309,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base);
/*! /*!
* @brief Gets the eDMA default configuration structure. * @brief Gets the eDMA default configuration structure.
* *
* This function sets the configuration structure to a default value. * This function sets the configuration structure to default values.
* The default configuration is set to the following value: * The default configuration is set to the following values.
* @code * @code
* config.enableContinuousLinkMode = false; * config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true; * config.enableHaltOnError = true;
@ -318,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base);
* config.enableDebugMode = false; * config.enableDebugMode = false;
* @endcode * @endcode
* *
* @param config Pointer to eDMA configuration structure. * @param config A pointer to the eDMA configuration structure.
*/ */
void EDMA_GetDefaultConfig(edma_config_t *config); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * or it causes unpredictable results.
* @note This function enables the auto stop request feature. * @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. * do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature is enabled * @note If nextTcd is not NULL, it means scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * 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, void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -374,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base,
/*! /*!
* @brief Configures the eDMA minor offset feature. * @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. * address after each minor loop.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number * @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, static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -407,13 +408,13 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
/*! /*!
* @brief Sets the channel link for the eDMA transfer. * @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 * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
* exhausted. * exhausted.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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_LinkNone
* @arg kEDMA_MinorLink * @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink * @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. * @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 * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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 kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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); 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) * 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination 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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); 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. * @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. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* STCD is used in scatter-gather mode. * The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address, * 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 * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address. * 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 config Pointer to eDMA transfer configuration structure.
* @param nextTcd Pointer to the next TCD structure. It can be NULL if users * @param nextTcd Pointer to the next TCD structure. It can be NULL if users
* do not want to enable scatter/gather feature. * 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 * @note If the nextTcd is not NULL, the scatter gather feature is enabled
* and DREQ bit is cleared in the previous transfer configuration, which * and DREQ bit is cleared in the previous transfer configuration, which
* is set in the EDMA_TcdReset. * 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. * @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. * address after each minor loop.
* *
* @param tcd Point to the TCD structure. * @param tcd A point to the TCD structure.
* @param config Pointer to Minor offset configuration 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); 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 * 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 * 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. * @brief Sets the bandwidth for the eDMA TCD.
* *
* 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. Bandwidth forces the eDMA to stall after the completion of * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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) * 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 * calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily. * queue easily.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); 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. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) 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. * This function starts a minor loop transfer.
* *
@ -702,18 +703,27 @@ 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return Bytes have not been transferred yet for the current TCD. * @return Major loop count which has not been transferred yet for the current TCD.
* @note This function can only be used to get unfinished bytes of transfer without * @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. * 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. * @brief Gets the eDMA channel error status flags.
@ -755,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas
/*! /*!
* @brief Creates the eDMA handle. * @brief Creates the eDMA handle.
* *
* This function is called if using transaction API for eDMA. This function * This function is called if using the transactional API for eDMA. This function
* initializes the internal state of eDMA handle. * initializes the internal state of the eDMA handle.
* *
* @param handle eDMA handle pointer. The eDMA handle stores callback function and * @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters. * 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); 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. * This function is called after the EDMA_CreateHandle to use scatter/gather feature.
* *
* @param handle eDMA handle pointer. * @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. * @param tcdSize The number of TCD slots.
*/ */
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); 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. * @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. * the current major loop transfer completes.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param callback eDMA callback function 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); void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
@ -802,7 +812,7 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD
* @param transferBytes eDMA transfer bytes to be transferred. * @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type. * @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC * @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 * is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error (SAE). * source address error (SAE).
*/ */
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void EDMA_PrepareTransfer(edma_transfer_config_t *config,
@ -818,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
* @brief Submits the eDMA transfer request. * @brief Submits the eDMA transfer request.
* *
* This function submits the eDMA transfer request according to the transfer configuration structure. * 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. * a TCD and enables scatter/gather feature to process it in the next time.
* *
* @param handle eDMA handle pointer. * @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); 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 * This function enables the channel request. Users can call this function after submitting the transfer request
* or before 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); 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() * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
* again to resume the transfer. * again to resume the transfer.
@ -850,7 +860,7 @@ void EDMA_StartTransfer(edma_handle_t *handle);
void EDMA_StopTransfer(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. * This function disables the channel request and clear transfer status bits.
* Users can submit another transfer after calling this API. * 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); 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. * 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. * @param handle eDMA handle pointer.
*/ */
void EDMA_HandleIRQ(edma_handle_t *handle); void EDMA_HandleIRQ(edma_handle_t *handle);

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -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. */ /*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; 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. */ /*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; 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. */ /*! @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. */ /*! @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]; 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; uint32_t instance;
/* Find the instance index from base address mappings. */ /* 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) 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; return instance;
} }
@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg; uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */ /* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */ /* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->CR; tmpreg = base->CR;
tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); 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) void EDMA_Deinit(DMA_Type *base)
{ {
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate EDMA periphral clock */ /* Gate EDMA periphral clock */
CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
} }
void EDMA_GetDefaultConfig(edma_config_t *config) 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); assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL);
uint32_t nbytes = 0; uint32_t remainingCount = 0;
uint32_t remainingBytes = 0;
if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)
{ {
remainingBytes = 0; remainingCount = 0;
} }
else 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 */ /* Calculate the unfinished bytes */
if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)
{ {
remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> remainingCount =
DMA_CITER_ELINKYES_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT;
nbytes;
} }
else else
{ {
remainingBytes = remainingCount =
((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT;
nbytes;
} }
} }
return remainingBytes; return remainingCount;
} }
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) 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; uint32_t channelIndex;
edma_tcd_t *tcdRegs; edma_tcd_t *tcdRegs;
/* Zero the handle */
memset(handle, 0, sizeof(*handle));
handle->base = base; handle->base = base;
handle->channel = channel; handle->channel = channel;
/* Get the DMA instance number */ /* Get the DMA instance number */
edmaInstance = EDMA_GetInstance(base); edmaInstance = EDMA_GetInstance(base);
channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
s_EDMAHandle[channelIndex] = handle; s_EDMAHandle[channelIndex] = handle;
/* Enable NVIC interrupt */ /* 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), 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 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(config != NULL);
assert(srcAddr != NULL); assert(srcAddr != NULL);
assert(destAddr != NULL); assert(destAddr != NULL);
assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U || srcWidth == 16U || srcWidth == 32U); assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U));
assert(destWidth == 1U || destWidth == 2U || destWidth == 4U || destWidth == 16U || destWidth == 32U); assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U));
assert(transferBytes % bytesEachRequest == 0); assert(transferBytes % bytesEachRequest == 0);
config->destAddr = (uint32_t)destAddr; config->destAddr = (uint32_t)destAddr;
@ -825,11 +822,11 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Clear EDMA interrupt flag */ /* Clear EDMA interrupt flag */
handle->base->CINT = handle->channel; handle->base->CINT = handle->channel;
if (handle->tcdPool == NULL) if ((handle->tcdPool == NULL) && (handle->callback != NULL))
{ {
(handle->callback)(handle, handle->userData, true, 0); (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 = handle->base->TCD[handle->channel].DLAST_SGA;
uint32_t sga_index; uint32_t sga_index;
@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
/* Check if transfer is already finished. */ /* Check if transfer is already finished. */
transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); 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; 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); sga_index = sga / sizeof(edma_tcd_t);
/* Adjust header positions. */ /* Adjust header positions. */
if (transfer_done) 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; new_header = sga_index;
} }
else 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; new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U;
} }
/* Calculate the number of finished TCDs */ /* Calculate the number of finished TCDs */
@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
} }
else else
{ {
/* Internal error occurs. */ /* No TCD in the memory are going to be loaded or internal error occurs. */
tcds_done = 0; tcds_done = 0;
} }
} }
@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle)
tcds_done += handle->tcdSize; 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; 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; handle->tcdUsed -= tcds_done;
/* Invoke callback function. */ /* Invoke callback function. */
if (handle->callback) if (handle->callback)
@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void)
EDMA_HandleIRQ(s_EDMAHandle[7]); 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) */ #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 */ /* 32 channels (Shared): k80 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U #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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) 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) if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U)
{ {
@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void)
} }
#endif /* 32 channels (Shared) */ #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 */ /* 4 channels (No Shared): kv10 */
#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved. * Copyright 2016-2017 NXP
* *
* Redistribution and use in source and binary forms, with or without modification, * Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met: * are permitted provided that the following conditions are met:
@ -12,7 +12,7 @@
* list of conditions and the following disclaimer in the documentation and/or * list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution. * other materials provided with the distribution.
* *
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its * 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 * contributors may be used to endorse or promote products derived from this
* software without specific prior written permission. * software without specific prior written permission.
* *
@ -34,11 +34,10 @@
#include "fsl_common.h" #include "fsl_common.h"
/*! /*!
* @addtogroup edma_driver * @addtogroup edma
* @{ * @{
*/ */
/*! @file */
/******************************************************************************* /*******************************************************************************
* Definitions * Definitions
******************************************************************************/ ******************************************************************************/
@ -46,7 +45,7 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief eDMA 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 */ /*! @brief Compute the offset unit from DCHPRI3 */
@ -143,7 +142,7 @@ enum _edma_error_status_flags
#if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 #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. */ kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */
#endif #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 */ /*! @brief eDMA interrupt source */
@ -178,7 +177,7 @@ typedef struct _edma_config
the link channel is itself. */ the link channel is itself. */
bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. 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.*/ 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 */ arbitration is used for channel selection */
bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of 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. */ 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. */ form the next-state value as each source read is completed. */
int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to
form the next-state value as each destination write is completed. */ 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. */ uint32_t majorLoopCounts; /*!< Major loop iteration count. */
} edma_transfer_config_t; } edma_transfer_config_t;
/*! @brief eDMA channel priority configuration */ /*! @brief eDMA channel priority configuration */
typedef struct _edma_channel_Preemption_config typedef struct _edma_channel_Preemption_config
{ {
bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */
bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */
uint8_t channelPriority; /*!< Channel priority */ uint8_t channelPriority; /*!< Channel priority */
} edma_channel_Preemption_config_t; } 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 enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */
bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination 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; } edma_minor_offset_config_t;
/*! /*!
* @brief eDMA TCD. * @brief eDMA TCD.
* *
* This structure is same as TCD register which is described in reference manual, * 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 typedef struct _edma_tcd
{ {
@ -256,7 +255,7 @@ typedef struct _edma_tcd
/*! @brief Callback for eDMA */ /*! @brief Callback for eDMA */
struct _edma_handle; 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); typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds);
/*! @brief eDMA transfer handle structure */ /*! @brief eDMA transfer handle structure */
@ -267,9 +266,10 @@ typedef struct _edma_handle
DMA_Type *base; /*!< eDMA peripheral base address. */ DMA_Type *base; /*!< eDMA peripheral base address. */
edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */
uint8_t channel; /*!< eDMA channel number. */ uint8_t channel; /*!< eDMA channel number. */
volatile int8_t header; /*!< The first TCD index. */ 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. */ 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. */ 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. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */
uint8_t flags; /*!< The status of the current channel. */ uint8_t flags; /*!< The status of the current channel. */
} edma_handle_t; } edma_handle_t;
@ -282,24 +282,24 @@ extern "C" {
#endif /* __cplusplus */ #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. * to the configuration structure.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param config Pointer to configuration structure, see "edma_config_t". * @param config A pointer to the configuration structure, see "edma_config_t".
* @note This function enable the minor loop map feature. * @note This function enables the minor loop map feature.
*/ */
void EDMA_Init(DMA_Type *base, const edma_config_t *config); 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. * This function gates the eDMA clock.
* *
@ -310,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base);
/*! /*!
* @brief Gets the eDMA default configuration structure. * @brief Gets the eDMA default configuration structure.
* *
* This function sets the configuration structure to a default value. * This function sets the configuration structure to default values.
* The default configuration is set to the following value: * The default configuration is set to the following values.
* @code * @code
* config.enableContinuousLinkMode = false; * config.enableContinuousLinkMode = false;
* config.enableHaltOnError = true; * config.enableHaltOnError = true;
@ -319,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base);
* config.enableDebugMode = false; * config.enableDebugMode = false;
* @endcode * @endcode
* *
* @param config Pointer to eDMA configuration structure. * @param config A pointer to the eDMA configuration structure.
*/ */
void EDMA_GetDefaultConfig(edma_config_t *config); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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 will case unpredicated results. * or it causes unpredictable results.
* @note This function will enable auto stop request feature. * @note This function enables the auto stop request feature.
*/ */
void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
/*! /*!
* @brief Configures the eDMA transfer attribute. * @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 * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the TCD address. * user supplies the TCD address.
* Example: * Example:
@ -361,11 +361,11 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel);
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param config Pointer to eDMA transfer configuration structure. * @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. * do not want to enable scatter/gather feature.
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled. * @note If nextTcd is not NULL, it means scatter gather feature is enabled
* And DREQ bit will be cleared in the previous transfer configuration which * and DREQ bit is cleared in the previous transfer configuration, which
* will be set in eDMA_ResetChannel. * is set in the eDMA_ResetChannel.
*/ */
void EDMA_SetTransferConfig(DMA_Type *base, void EDMA_SetTransferConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -375,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base,
/*! /*!
* @brief Configures the eDMA minor offset feature. * @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. * address after each minor loop.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number * @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, static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
uint32_t channel, uint32_t channel,
@ -408,30 +408,31 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base,
/*! /*!
* @brief Sets the channel link for the eDMA transfer. * @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. * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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_LinkNone
* @arg kEDMA_MinorLink * @arg kEDMA_MinorLink
* @arg kEDMA_MajorLink * @arg kEDMA_MajorLink
* @param linkedChannel The linked channel number. * @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); 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. * @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 * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @param channel eDMA channel number. * @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 kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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); 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) * 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination 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); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); 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. * This function sets all fields for this TCD structure to default value.
* *
* @param tcd Pointer to the TCD structure. * @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); void EDMA_TcdReset(edma_tcd_t *tcd);
/*! /*!
* @brief Configures the eDMA TCD transfer attribute. * @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. * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
* STCD is used in scatter-gather mode. * The STCD is used in the scatter-gather mode.
* This function configures the TCD transfer attribute, including source address, destination address, * 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 * transfer size, address offset, and so on. It also configures the scatter gather feature if the
* user supplies the next TCD address. * 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 tcd Pointer to the TCD structure.
* @param config Pointer to eDMA transfer configuration 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. * do not want to enable scatter/gather feature.
* @note TCD address should be 32 bytes aligned, or it will cause eDMA error. * @note TCD address should be 32 bytes aligned or it causes an eDMA error.
* @note If nextTcd is not NULL, it means scatter gather feature will be enabled. * @note If the nextTcd is not NULL, the scatter gather feature is enabled
* And DREQ bit will be cleared in the previous transfer configuration which * and DREQ bit is cleared in the previous transfer configuration, which
* will be set in EDMA_TcdReset. * is set in the EDMA_TcdReset.
*/ */
void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); 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. * @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. * address after each minor loop.
* *
* @param tcd Point to the TCD structure. * @param tcd A point to the TCD structure.
* @param config Pointer to Minor offset configuration 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); 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 * 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 tcd Point to the TCD structure.
* @param type Channel link type, it can be one of: * @param type Channel link type, it can be one of:
* @arg kEDMA_LinkNone * @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. * @brief Sets the bandwidth for the eDMA TCD.
* *
* 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. Bandwidth forces the eDMA to stall after the completion of * 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. * each read/write access to control the bus request bandwidth seen by the crossbar switch.
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param bandWidth Bandwidth setting, it can be one of: * @param bandWidth A bandwidth setting, which can be one of the following:
* @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStallNone
* @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall4Cycle
* @arg kEDMABandwidthStall8Cycle * @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) * 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 * calculation is performed or the original register value. It provides the ability to implement a circular data
* queue easily. * queue easily.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param srcModulo Source modulo value. * @param srcModulo A source modulo value.
* @param destModulo Destination modulo value. * @param destModulo A destination modulo value.
*/ */
void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); 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. * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request.
* *
* @param tcd Point to the TCD structure. * @param tcd A pointer to the TCD structure.
* @param enable The command for enable(ture) or disable(false). * @param enable The command to enable (true) or disable (false).
*/ */
static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) 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. * @brief Enables the interrupt source for the eDMA TCD.
* *
* @param tcd Point to the TCD structure. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); 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. * @brief Disables the interrupt source for the eDMA TCD.
* *
* @param tcd Point to the TCD structure. * @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. * the defined edma_interrupt_enable_t type.
*/ */
void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); 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. * This function starts a minor loop transfer.
* *
@ -701,24 +703,33 @@ 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 * 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @param channel eDMA channel number.
* @return Bytes have not been transferred yet for the current TCD. * @return Major loop count which has not been transferred yet for the current TCD.
* @note This function can only be used to get unfinished bytes of transfer without * @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. * 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. * @brief Gets the eDMA channel error status flags.
* *
* @param base eDMA peripheral base address. * @param base eDMA peripheral base address.
* @return The mask of error status flags. User need to use the * @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) 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * _edma_channel_status_flags type to decode the return variables.
*/ */
uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); 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 base eDMA peripheral base address.
* @param channel eDMA channel number. * @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. * the defined _edma_channel_status_flags type.
*/ */
void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); 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. * @brief Creates the eDMA handle.
* *
* This function is called if using transaction API for eDMA. This function * This function is called if using the transactional API for eDMA. This function
* initializes the internal state of eDMA handle. * initializes the internal state of the eDMA handle.
* *
* @param handle eDMA handle pointer. The eDMA handle stores callback function and * @param handle eDMA handle pointer. The eDMA handle stores callback function and
* parameters. * 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); 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. * This function is called after the EDMA_CreateHandle to use scatter/gather feature.
* *
* @param handle eDMA handle pointer. * @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. * @param tcdSize The number of TCD slots.
*/ */
void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); 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. * @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. * the current major loop transfer completes.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
* @param callback eDMA callback function 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); void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData);
@ -801,7 +812,7 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD
* @param transferBytes eDMA transfer bytes to be transferred. * @param transferBytes eDMA transfer bytes to be transferred.
* @param type eDMA transfer type. * @param type eDMA transfer type.
* @note The data address and the data width must be consistent. For example, if the SRC * @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 * is 4 bytes, the source address must be 4 bytes aligned, or it results in
* source address error (SAE). * source address error (SAE).
*/ */
void EDMA_PrepareTransfer(edma_transfer_config_t *config, void EDMA_PrepareTransfer(edma_transfer_config_t *config,
@ -817,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config,
* @brief Submits the eDMA transfer request. * @brief Submits the eDMA transfer request.
* *
* This function submits the eDMA transfer request according to the transfer configuration structure. * 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. * a TCD and enables scatter/gather feature to process it in the next time.
* *
* @param handle eDMA handle pointer. * @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); 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. * or before submitting the transfer request.
* *
* @param handle eDMA handle pointer. * @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); 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. * again to resume the transfer.
* *
* @param handle eDMA handle pointer. * @param handle eDMA handle pointer.
@ -849,21 +860,41 @@ void EDMA_StartTransfer(edma_handle_t *handle);
void EDMA_StopTransfer(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. * 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. * @param handle DMA handle pointer.
*/ */
void EDMA_AbortTransfer(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. * 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. * @param handle eDMA handle pointer.
*/ */
void EDMA_HandleIRQ(edma_handle_t *handle); void EDMA_HandleIRQ(edma_handle_t *handle);