diff --git a/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.c b/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.c index 714bf37d1..a378602ed 100644 --- a/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.c +++ b/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.c @@ -8,6 +8,9 @@ #include #include "fsl_edma_rev2.h" +#if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET +#include "fsl_memory.h" +#endif #define EDMA_READ(base, access)\ ((access) == kEDMA_RegAccess16 ?\ @@ -169,6 +172,39 @@ static uint32_t EDMA_ConvertTransferWidth(uint32_t width) return 0; } +status_t EDMA_SetChannelLink(edma_config_t *cfg, int channel, edma_channel_link_type_t type, uint32_t linkedChannel) +{ + uint32_t mp_csr; + /* setting global channel linking control */ + mp_csr = EDMA_MPRegRead(cfg, EDMA_MP_CS) | EDMA_MP_CS_GCLC_MASK; + EDMA_MPRegWrite(cfg, EDMA_MP_CS, mp_csr); + if (type == kEDMA_MinorLink) + { + uint16_t biter, citer; + biter = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_BITER); + citer = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_CITER); + biter |= EDMA_BITER_ELINKYES_ELINK_MASK | EDMA_BITER_ELINKYES_LINKCH(linkedChannel); + citer |= EDMA_CITER_ELINKYES_ELINK_MASK | EDMA_CITER_ELINKYES_LINKCH(linkedChannel); + EDMA_ChannelRegWrite(cfg, channel, EDMA_TCD_CITER, citer); + EDMA_ChannelRegWrite(cfg, channel, EDMA_TCD_BITER, biter); + } + else if(type == kEDMA_MajorLink) + { + uint16_t csr; + csr = EDMA_ChannelRegRead(cfg, channel, EDMA_TCD_CSR); + csr |= EDMA_CSR_MAJORELINK_MASK | EDMA_CSR_MAJORLINKCH(linkedChannel); + EDMA_ChannelRegUpdate(cfg, channel, EDMA_TCD_CSR, EDMA_TCD_CSR_MAJORELINK_MASk, 0); + } + else + { + /* disable global channel linking control if no linked channel */ + mp_csr = EDMA_MPRegRead(cfg, EDMA_MP_CS) & (~EDMA_MP_CS_GCLC_MASK); + EDMA_MPRegWrite(cfg, EDMA_MP_CS, mp_csr); + } + + return kStatus_Success; +} + status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel, uint32_t saddr, uint32_t daddr, uint32_t ssize, uint32_t dsize, @@ -237,6 +273,11 @@ status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel, break; } +#if defined FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET + saddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(saddr), kMEMORY_Local2DMA); + daddr = MEMORY_ConvertMemoryMapAddress((uint32_t)(daddr), kMEMORY_Local2DMA); +#endif + /* notes: * 1) SOFF and DOFF are currently set to SSIZE and DSIZE. * 2) channel linking is not currently supported. diff --git a/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.h b/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.h index 12ae0faeb..db1c03d57 100644 --- a/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.h +++ b/mcux/mcux-sdk/drivers/edma_rev2/fsl_edma_rev2.h @@ -74,7 +74,7 @@ extern "C" { #define EDMA_TCD_ATTR_DSIZE(x) ((x) & EDMA_TCD_ATTR_SSIZE_DSIZE_MASK) #define EDMA_TCD_ATTR_SSIZE(x) (((x) & EDMA_TCD_ATTR_SSIZE_DSIZE_MASK) << 8) -#define EDMA_TCD_CITER_ELINKNO_MASK 0xf +#define EDMA_TCD_CITER_ELINKNO_MASK 0x7fff #define EDMA_TCD_CITER_ELINKNO(x) ((x) & EDMA_TCD_CITER_ELINKNO_MASK) #define EDMA_TCD_BITER_ELINKNO_MASK 0xf @@ -83,8 +83,10 @@ extern "C" { #define EDMA_TCD_NBYTES_MLOFFNO_MASK 0x3fffffff #define EDMA_TCD_NBYTES_MLOFFNO(x) ((x) & EDMA_TCD_NBYTES_MLOFFNO_MASK) +#define EDMA_TCD_CSR_MAJORELINK_MASk EDMA_BIT(5) #define EDMA_TCD_CSR_INTHALF_MASK EDMA_BIT(2) #define EDMA_TCD_CSR_INTMAJOR_MASK EDMA_BIT(1) +#define EDMA_TCD_CSR_START_MASK EDMA_BIT(0) #define EDMA_TCD_CH_CSR_ACTIVE_MASK EDMA_BIT(31) #define EDMA_TCD_CH_CSR_DONE_MASK EDMA_BIT(30) @@ -92,12 +94,23 @@ extern "C" { #define EDMA_TCD_CH_INT_MASK BIT(1) +#define EDMA_CSR_MAJORELINK_MASK EDMA_BIT(5) +#define EDMA_CITER_ELINKYES_LINKCH_MASK (0x3E00U) +#define EDMA_BITER_ELINKYES_LINKCH_MASK (0x3E00U) +#define EDMA_BITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U)) +#define EDMA_CITER_ELINKYES_LINKCH(x) (((uint16_t)(((uint16_t)(x)) << (9U))) & (0x3E00U)) +#define EDMA_BITER_ELINKYES_ELINK_MASK EDMA_BIT(15) +#define EDMA_CITER_ELINKYES_ELINK_MASK EDMA_BIT(15) +#define EDMA_CSR_MAJORLINKCH_MASK (0x1F00U) +#define EDMA_CSR_MAJORLINKCH(x) (((uint16_t)(((uint16_t)(x)) << (8U))) & (0x1F00U)) + /* EDMA registers */ /* common MP-related registers */ #define EDMA_MP_CS EDMA_REGISTER_MAKE(EDMA_MP_CS_INDEX, kEDMA_RegAccess32) #define EDMA_MP_ES EDMA_REGISTER_MAKE(EDMA_MP_ES_INDEX, kEDMA_RegAccess32) #define EDMA_MP_INT EDMA_REGISTER_MAKE(EDMA_MP_INT_INDEX, kEDMA_RegAccess32) #define EDMA_MP_HRS EDMA_REGISTER_MAKE(EDMA_MP_HRS_INDEX, kEDMA_RegAccess32) +#define EDMA_MP_CS_GCLC_MASK EDMA_BIT(6) /* TODO: access requires validation */ #define EDMA_MP_CH_GRPRI EDMA_REGISTER_MAKE(EDMA_MP_CH_GRPRI_INDEX, kEDMA_RegAccess32) /* common TCD-related registers */ @@ -159,6 +172,14 @@ enum _edma_transfer_type { kEDMA_TransferTypeP2M, /* Peripheral to memory transfer */ }; +/*! @brief Channel link type */ +typedef enum _edma_channel_link_type +{ + kEDMA_LinkNone = 0x0U, /*!< No channel link */ + kEDMA_MinorLink, /*!< Channel link after each minor loop */ + kEDMA_MajorLink, /*!< Channel link while major loop count exhausted */ +}edma_channel_link_type_t; + typedef struct _edma_config { /* EDMA base address. Should be overwritten by user if working with virtual * addresses. @@ -328,3 +349,4 @@ status_t EDMA_ConfigureTransfer(edma_config_t *cfg, int channel, } #endif #endif /* _FSL_EDMA_REV2_H_ */ +