diff --git a/arch/arm/src/kinetis/Kconfig b/arch/arm/src/kinetis/Kconfig index 5cdc32bf6a6..78a868fe351 100644 --- a/arch/arm/src/kinetis/Kconfig +++ b/arch/arm/src/kinetis/Kconfig @@ -751,7 +751,7 @@ config KINETIS_FTFL ---help--- Support FLASH -config KINETIS_DMA +config KINETIS_EDMA bool "DMA" default n depends on KINETIS_HAVE_DMA @@ -1114,6 +1114,96 @@ config KINETIS_SD4BIT_FREQ endif endmenu # Kinetis SDHC Configuration +menu "eDMA Configuration" + depends on KINETIS_EDMA + +config KINETIS_EDMA_NTCD + int "Number of transfer descriptors" + default 0 + ---help--- + Number of pre-allocated transfer descriptors. Needed for scatter- + gather DMA. Make to be set to zero to disable in-memory TCDs in + which case only the TCD channel registers will be used and scatter- + will not be supported. + +config KINETIS_EDMA_ELINK + bool "Channeling Linking" + default n + ---help--- + This option enables optional minor or major loop channel linking: + + Minor loop channel linking: As the channel completes the minor + loop, this flag enables linking to another channel. The link target + channel initiates a channel service request via an internal + mechanism that sets the TCDn_CSR[START] bit of the specified + channel. + + If minor loop channel linking is disabled, this link mechanism is + suppressed in favor of the major loop channel linking. + + Major loop channel linking: As the channel completes the minor + loop, this option enables the linking to another channel. The link + target channel initiates a channel service request via an internal + mechanism that sets the TCDn_CSR[START] bit of the linked channel. + +config KINETIS_EDMA_ERCA + bool "Round Robin Channel Arbitration" + default n + ---help--- + Normally, a fixed priority arbitration is used for channel + selection. If this option is selected, round robin arbitration is + used for channel selection. + +config KINETIS_EDMA_ERGA + bool "Round Robin Group Arbitration" + default n + ---help--- + Normally, a fixed priority arbitration is used for channel + selection among the groups. If this option is selected, + round Round robin arbitration is used for selection among + the groups. + +config KINETIS_EDMA_HOE + bool "Halt On Error" + default y + ---help--- + Any error causes the HALT bit to set. Subsequently, all service + requests are ignored until the HALT bit is cleared. + +config KINETIS_EDMA_CLM + bool "Continuous Link Mode" + default n + ---help--- + By default, A minor loop channel link made to itself goes through + channel arbitration before being activated again. If this option is + selected, a minor loop channel link made to itself does not go + through channel arbitration before being activated again. Upon minor + loop completion, the channel activates again if that channel has a + minor loop channel link enabled and the link channel is itself. This + effectively applies the minor loop offsets and restarts the next + minor loop. + +config KINETIS_EDMA_EMLIM + bool "Minor Loop Mapping" + default n + ---help--- + Normally TCD word 2 is a 32-bit NBYTES field. When this option is + enabled, TCD word 2 is redefined to include individual enable fields, + an offset field, and the NBYTES field. The individual enable fields + allow the minor loop offset to be applied to the source address, the + destination address, or both. The NBYTES field is reduced when either + offset is enabled. + +config KINETIS_EDMA_EDBG + bool "Enable Debug" + default n + ---help--- + When in debug mode, the DMA stalls the start of a new channel. Executing + channels are allowed to complete. Channel execution resumes when the + system exits debug mode or the EDBG bit is cleared + +endmenu # eDMA Global Configuration + if KINETIS_USBHS && USBHOST menu "USB host controller driver (HCD) options" @@ -1208,42 +1298,42 @@ config KINETIS_UARTFIFOS config KINETIS_UART0_RXDMA bool "UART0 Rx DMA" default n - depends on KINETIS_UART0 && KINETIS_DMA + depends on KINETIS_UART0 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors config KINETIS_UART1_RXDMA bool "UART1 Rx DMA" default n - depends on KINETIS_UART1 && KINETIS_DMA + depends on KINETIS_UART1 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors config KINETIS_UART2_RXDMA bool "UART2 Rx DMA" default n - depends on KINETIS_UART2 && KINETIS_DMA + depends on KINETIS_UART2 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors config KINETIS_UART3_RXDMA bool "UART3 Rx DMA" default n - depends on KINETIS_UART3 && KINETIS_DMA + depends on KINETIS_UART3 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors config KINETIS_UART4_RXDMA bool "UART4 Rx DMA" default n - depends on KINETIS_UART4 && KINETIS_DMA + depends on KINETIS_UART4 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors config KINETIS_UART5_RXDMA bool "UART5 Rx DMA" default n - depends on KINETIS_UART5 && KINETIS_DMA + depends on KINETIS_UART5 && KINETIS_EDMA ---help--- In high data rate usage, Rx DMA may eliminate Rx overrun errors diff --git a/arch/arm/src/kinetis/Make.defs b/arch/arm/src/kinetis/Make.defs index 6b3426647e9..6fd81e4a006 100644 --- a/arch/arm/src/kinetis/Make.defs +++ b/arch/arm/src/kinetis/Make.defs @@ -140,8 +140,8 @@ CHIP_CSRCS += kinetis_usbhshost.c endif endif -ifeq ($(CONFIG_KINETIS_DMA),y) -CHIP_CSRCS += kinetis_dma.c kinetis_pindma.c +ifeq ($(CONFIG_KINETIS_EDMA),y) +CHIP_CSRCS += kinetis_edma.c kinetis_pindma.c endif ifeq ($(CONFIG_PWM),y) diff --git a/arch/arm/src/kinetis/hardware/kinetis_dma.h b/arch/arm/src/kinetis/hardware/kinetis_dma.h deleted file mode 100644 index bd2b941c72f..00000000000 --- a/arch/arm/src/kinetis/hardware/kinetis_dma.h +++ /dev/null @@ -1,776 +0,0 @@ -/**************************************************************************** - * arch/arm/src/kinetis/hardware/kinetis_dma.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_DMA_H -#define __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_DMA_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include "chip.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Register Offsets *********************************************************/ - -#define KINETIS_DMA_CR_OFFSET 0x0000 /* Control Register */ -#define KINETIS_DMA_ES_OFFSET 0x0004 /* Error Status Register */ -#define KINETIS_DMA_ERQ_OFFSET 0x000c /* Enable Request Register */ -#define KINETIS_DMA_EEI_OFFSET 0x0014 /* Enable Error Interrupt Register */ -#define KINETIS_DMA_CEEI_OFFSET 0x0018 /* Clear Enable Error Interrupt Register */ -#define KINETIS_DMA_SEEI_OFFSET 0x0019 /* Set Enable Error Interrupt Register */ -#define KINETIS_DMA_CERQ_OFFSET 0x001a /* Clear Enable Request Register */ -#define KINETIS_DMA_SERQ_OFFSET 0x001b /* Set Enable Request Register */ -#define KINETIS_DMA_CDNE_OFFSET 0x001c /* Clear DONE Status Bit Register */ -#define KINETIS_DMA_SSRT_OFFSET 0x001d /* Set START Bit Register */ -#define KINETIS_DMA_CERR_OFFSET 0x001e /* Clear Error Register */ -#define KINETIS_DMA_CINT_OFFSET 0x001f /* Clear Interrupt Request Register */ -#define KINETIS_DMA_INT_OFFSET 0x0024 /* Interrupt Request Register */ -#define KINETIS_DMA_ERR_OFFSET 0x002c /* Error Register */ -#define KINETIS_DMA_HRS_OFFSET 0x0034 /* Hardware Request Status Register */ - -#define KINETIS_DMA_DCHPRI3_OFFSET 0x0100 /* Channel 3 Priority Register */ -#define KINETIS_DMA_DCHPRI2_OFFSET 0x0101 /* Channel 2 Priority Register */ -#define KINETIS_DMA_DCHPRI1_OFFSET 0x0102 /* Channel 1 Priority Register */ -#define KINETIS_DMA_DCHPRI0_OFFSET 0x0103 /* Channel 0 Priority Register */ -#define KINETIS_DMA_DCHPRI7_OFFSET 0x0104 /* Channel 7 Priority Register */ -#define KINETIS_DMA_DCHPRI6_OFFSET 0x0105 /* Channel 6 Priority Register */ -#define KINETIS_DMA_DCHPRI5_OFFSET 0x0106 /* Channel 5 Priority Register */ -#define KINETIS_DMA_DCHPRI4_OFFSET 0x0107 /* Channel 4 Priority Register */ -#define KINETIS_DMA_DCHPRI11_OFFSET 0x0108 /* Channel 11 Priority Register */ -#define KINETIS_DMA_DCHPRI10_OFFSET 0x0109 /* Channel 10 Priority Register */ -#define KINETIS_DMA_DCHPRI9_OFFSET 0x010a /* Channel 9 Priority Register */ -#define KINETIS_DMA_DCHPRI8_OFFSET 0x010b /* Channel 8 Priority Register */ -#define KINETIS_DMA_DCHPRI15_OFFSET 0x010c /* Channel 15 Priority Register */ -#define KINETIS_DMA_DCHPRI14_OFFSET 0x010d /* Channel 14 Priority Register */ -#define KINETIS_DMA_DCHPRI13_OFFSET 0x010e /* Channel 13 Priority Register */ -#define KINETIS_DMA_DCHPRI12_OFFSET 0x010f /* Channel 12 Priority Register */ - -#define KINETIS_DMA_DCHPRI_OFFSET(n) 0x0100 + (n - (n % 4)) + (3 - (n % 4)) /* Channel n Priority Register */ - -#define KINETIS_DMA_TCD_OFFSET(n) (0x0000 + ((n) << 5)) -#define KINETIS_DMA_TCD_SADDR_OFFSET 0x0000 /* TCD Source Address */ -#define KINETIS_DMA_TCD_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD_DADDR_OFFSET 0x0010 /* TCD Destination Address */ -#define KINETIS_DMA_TCD_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD_CSR_OFFSET 0x001c /* TCD Control and Status */ -#define KINETIS_DMA_TCD_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD0_SADDR_OFFSET 0x0000 /* TCD Source Address */ -#define KINETIS_DMA_TCD0_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD0_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD0_NBYTES_OFFSET 0x0008 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD0_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD0_DADDR_OFFSET 0x0010 /* TCD Destination Address */ -#define KINETIS_DMA_TCD0_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD0_CITER_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD0_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD0_CSR_OFFSET 0x001c /* TCD Control and Status */ -#define KINETIS_DMA_TCD0_BITER_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD1_SADDR_OFFSET 0x0020 /* TCD Source Address */ -#define KINETIS_DMA_TCD1_SOFF_OFFSET 0x0024 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD1_ATTR_OFFSET 0x0026 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD1_NBYTES_OFFSET 0x0028 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD1_SLAST_OFFSET 0x002c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD1_DADDR_OFFSET 0x0030 /* TCD Destination Address */ -#define KINETIS_DMA_TCD1_DOFF_OFFSET 0x0034 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD1_CITER_OFFSET 0x0036 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD1_DLASTSGA_OFFSET 0x0038 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD1_CSR_OFFSET 0x003c /* TCD Control and Status */ -#define KINETIS_DMA_TCD1_BITER_OFFSET 0x003e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD2_SADDR_OFFSET 0x0040 /* TCD Source Address */ -#define KINETIS_DMA_TCD2_SOFF_OFFSET 0x0044 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD2_ATTR_OFFSET 0x0046 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD2_NBYTES_OFFSET 0x0048 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD2_SLAST_OFFSET 0x004c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD2_DADDR_OFFSET 0x0050 /* TCD Destination Address */ -#define KINETIS_DMA_TCD2_DOFF_OFFSET 0x0054 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD2_CITER_OFFSET 0x0056 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD2_DLASTSGA_OFFSET 0x0058 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD2_CSR_OFFSET 0x005c /* TCD Control and Status */ -#define KINETIS_DMA_TCD2_BITER_OFFSET 0x005e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD3_SADDR_OFFSET 0x0060 /* TCD Source Address */ -#define KINETIS_DMA_TCD3_SOFF_OFFSET 0x0064 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD3_ATTR_OFFSET 0x0066 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD3_NBYTES_OFFSET 0x0068 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD3_SLAST_OFFSET 0x006c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD3_DADDR_OFFSET 0x0070 /* TCD Destination Address */ -#define KINETIS_DMA_TCD3_DOFF_OFFSET 0x0074 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD3_CITER_OFFSET 0x0076 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD3_DLASTSGA_OFFSET 0x0078 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD3_CSR_OFFSET 0x007c /* TCD Control and Status */ -#define KINETIS_DMA_TCD3_BITER_OFFSET 0x007e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD4_SADDR_OFFSET 0x0080 /* TCD Source Address */ -#define KINETIS_DMA_TCD4_SOFF_OFFSET 0x0084 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD4_ATTR_OFFSET 0x0086 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD4_NBYTES_OFFSET 0x0088 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD4_SLAST_OFFSET 0x008c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD4_DADDR_OFFSET 0x0090 /* TCD Destination Address */ -#define KINETIS_DMA_TCD4_DOFF_OFFSET 0x0094 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD4_CITER_OFFSET 0x0096 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD4_DLASTSGA_OFFSET 0x0098 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD4_CSR_OFFSET 0x009c /* TCD Control and Status */ -#define KINETIS_DMA_TCD4_BITER_OFFSET 0x009e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD5_SADDR_OFFSET 0x00a0 /* TCD Source Address */ -#define KINETIS_DMA_TCD5_SOFF_OFFSET 0x00a4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD5_ATTR_OFFSET 0x00a6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD5_NBYTES_OFFSET 0x00a8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD5_SLAST_OFFSET 0x00ac /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD5_DADDR_OFFSET 0x00b0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD5_DOFF_OFFSET 0x00b4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD5_CITER_OFFSET 0x00b6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD5_DLASTSGA_OFFSET 0x00b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD5_CSR_OFFSET 0x00bc /* TCD Control and Status */ -#define KINETIS_DMA_TCD5_BITER_OFFSET 0x00be /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD6_SADDR_OFFSET 0x00c0 /* TCD Source Address */ -#define KINETIS_DMA_TCD6_SOFF_OFFSET 0x00c4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD6_ATTR_OFFSET 0x00c6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD6_NBYTES_OFFSET 0x00c8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD6_SLAST_OFFSET 0x00cc /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD6_DADDR_OFFSET 0x00d0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD6_DOFF_OFFSET 0x00d4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD6_CITER_OFFSET 0x00d6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD6_DLASTSGA_OFFSET 0x00d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD6_CSR_OFFSET 0x00dc /* TCD Control and Status */ -#define KINETIS_DMA_TCD6_BITER_OFFSET 0x00de /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD7_SADDR_OFFSET 0x00e0 /* TCD Source Address */ -#define KINETIS_DMA_TCD7_SOFF_OFFSET 0x00e4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD7_ATTR_OFFSET 0x00e6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD7_NBYTES_OFFSET 0x00e8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD7_SLAST_OFFSET 0x00ec /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD7_DADDR_OFFSET 0x00f0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD7_DOFF_OFFSET 0x00f4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD7_CITER_OFFSET 0x00f6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD7_DLASTSGA_OFFSET 0x00f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD7_CSR_OFFSET 0x00fc /* TCD Control and Status */ -#define KINETIS_DMA_TCD7_BITER_OFFSET 0x00fe /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD8_SADDR_OFFSET 0x0100 /* TCD Source Address */ -#define KINETIS_DMA_TCD8_SOFF_OFFSET 0x0104 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD8_ATTR_OFFSET 0x0106 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD8_NBYTES_OFFSET 0x0108 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD8_SLAST_OFFSET 0x010c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD8_DADDR_OFFSET 0x0110 /* TCD Destination Address */ -#define KINETIS_DMA_TCD8_DOFF_OFFSET 0x0114 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD8_CITER_OFFSET 0x0116 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD8_DLASTSGA_OFFSET 0x0118 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD8_CSR_OFFSET 0x011c /* TCD Control and Status */ -#define KINETIS_DMA_TCD8_BITER_OFFSET 0x011e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD9_SADDR_OFFSET 0x0120 /* TCD Source Address */ -#define KINETIS_DMA_TCD9_SOFF_OFFSET 0x0124 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD9_ATTR_OFFSET 0x0126 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD9_NBYTES_OFFSET 0x0128 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD9_SLAST_OFFSET 0x012c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD9_DADDR_OFFSET 0x0130 /* TCD Destination Address */ -#define KINETIS_DMA_TCD9_DOFF_OFFSET 0x0134 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD9_CITER_OFFSET 0x0136 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD9_DLASTSGA_OFFSET 0x0138 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD9_CSR_OFFSET 0x013c /* TCD Control and Status */ -#define KINETIS_DMA_TCD9_BITER_OFFSET 0x013e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD10_SADDR_OFFSET 0x0140 /* TCD Source Address */ -#define KINETIS_DMA_TCD10_SOFF_OFFSET 0x0144 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD10_ATTR_OFFSET 0x0146 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD10_NBYTES_OFFSET 0x0148 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD10_SLAST_OFFSET 0x014c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD10_DADDR_OFFSET 0x0150 /* TCD Destination Address */ -#define KINETIS_DMA_TCD10_DOFF_OFFSET 0x0154 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD10_CITER_OFFSET 0x0156 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD10_DLASTSGA_OFFSET 0x0158 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD10_CSR_OFFSET 0x015c /* TCD Control and Status */ -#define KINETIS_DMA_TCD10_BITER_OFFSET 0x015e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD11_SADDR_OFFSET 0x0160 /* TCD Source Address */ -#define KINETIS_DMA_TCD11_SOFF_OFFSET 0x0164 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD11_ATTR_OFFSET 0x0166 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD11_NBYTES_OFFSET 0x0168 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD11_SLAST_OFFSET 0x016c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD11_DADDR_OFFSET 0x0170 /* TCD Destination Address */ -#define KINETIS_DMA_TCD11_DOFF_OFFSET 0x0174 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD11_CITER_OFFSET 0x0176 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD11_DLASTSGA_OFFSET 0x0178 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD11_CSR_OFFSET 0x017c /* TCD Control and Status */ -#define KINETIS_DMA_TCD11_BITER_OFFSET 0x017e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD12_SADDR_OFFSET 0x0180 /* TCD Source Address */ -#define KINETIS_DMA_TCD12_SOFF_OFFSET 0x0184 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD12_ATTR_OFFSET 0x0186 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD12_NBYTES_OFFSET 0x0188 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD12_SLAST_OFFSET 0x018c /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD12_DADDR_OFFSET 0x0190 /* TCD Destination Address */ -#define KINETIS_DMA_TCD12_DOFF_OFFSET 0x0194 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD12_CITER_OFFSET 0x0196 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD12_DLASTSGA_OFFSET 0x0198 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD12_CSR_OFFSET 0x019c /* TCD Control and Status */ -#define KINETIS_DMA_TCD12_BITER_OFFSET 0x019e /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD13_SADDR_OFFSET 0x01a0 /* TCD Source Address */ -#define KINETIS_DMA_TCD13_SOFF_OFFSET 0x01a4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD13_ATTR_OFFSET 0x01a6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD13_NBYTES_OFFSET 0x01a8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD13_SLAST_OFFSET 0x01ac /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD13_DADDR_OFFSET 0x01b0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD13_DOFF_OFFSET 0x01b4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD13_CITER_OFFSET 0x01b6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD13_DLASTSGA_OFFSET 0x01b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD13_CSR_OFFSET 0x01bc /* TCD Control and Status */ -#define KINETIS_DMA_TCD13_BITER_OFFSET 0x01be /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD14_SADDR_OFFSET 0x01c0 /* TCD Source Address */ -#define KINETIS_DMA_TCD14_SOFF_OFFSET 0x01c4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD14_ATTR_OFFSET 0x01c6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD14_NBYTES_OFFSET 0x01c8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD14_SLAST_OFFSET 0x01cc /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD14_DADDR_OFFSET 0x01d0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD14_DOFF_OFFSET 0x01d4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD14_CITER_OFFSET 0x01d6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD14_DLASTSGA_OFFSET 0x01d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD14_CSR_OFFSET 0x01dc /* TCD Control and Status */ -#define KINETIS_DMA_TCD14_BITER_OFFSET 0x01de /* TCD Beginning Minor Loop Link, Major Loop Count */ - -#define KINETIS_DMA_TCD15_SADDR_OFFSET 0x01e0 /* TCD Source Address */ -#define KINETIS_DMA_TCD15_SOFF_OFFSET 0x01e4 /* TCD Signed Source Address Offset */ -#define KINETIS_DMA_TCD15_ATTR_OFFSET 0x01e6 /* TCD Transfer Attributes */ -#define KINETIS_DMA_TCD15_NBYTES_OFFSET 0x01e8 /* TCD Minor Byte Count */ -#define KINETIS_DMA_TCD15_SLAST_OFFSET 0x01ec /* TCD Last Source Address Adjustment */ -#define KINETIS_DMA_TCD15_DADDR_OFFSET 0x01f0 /* TCD Destination Address */ -#define KINETIS_DMA_TCD15_DOFF_OFFSET 0x01f4 /* TCD Signed Destination Address Offset */ -#define KINETIS_DMA_TCD15_CITER_OFFSET 0x01f6 /* TCD Current Minor Loop Link, Major Loop Count */ -#define KINETIS_DMA_TCD15_DLASTSGA_OFFSET 0x01f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ -#define KINETIS_DMA_TCD15_CSR_OFFSET 0x01fc /* TCD Control and Status */ -#define KINETIS_DMA_TCD15_BITER_OFFSET 0x01fe /* TCD Beginning Minor Loop Link, Major Loop Count */ - -/* Register Addresses *******************************************************/ - -#define KINETIS_DMA_CR (KINETIS_DMAC_BASE + KINETIS_DMA_CR_OFFSET) -#define KINETIS_DMA_ES (KINETIS_DMAC_BASE + KINETIS_DMA_ES_OFFSET) -#define KINETIS_DMA_ERQ (KINETIS_DMAC_BASE + KINETIS_DMA_ERQ_OFFSET) -#define KINETIS_DMA_EEI (KINETIS_DMAC_BASE + KINETIS_DMA_EEI_OFFSET) -#define KINETIS_DMA_CEEI (KINETIS_DMAC_BASE + KINETIS_DMA_CEEI_OFFSET) -#define KINETIS_DMA_SEEI (KINETIS_DMAC_BASE + KINETIS_DMA_SEEI_OFFSET) -#define KINETIS_DMA_CERQ (KINETIS_DMAC_BASE + KINETIS_DMA_CERQ_OFFSET) -#define KINETIS_DMA_SERQ (KINETIS_DMAC_BASE + KINETIS_DMA_SERQ_OFFSET) -#define KINETIS_DMA_CDNE (KINETIS_DMAC_BASE + KINETIS_DMA_CDNE_OFFSET) -#define KINETIS_DMA_SSRT (KINETIS_DMAC_BASE + KINETIS_DMA_SSRT_OFFSET) -#define KINETIS_DMA_CERR (KINETIS_DMAC_BASE + KINETIS_DMA_CERR_OFFSET) -#define KINETIS_DMA_CINT (KINETIS_DMAC_BASE + KINETIS_DMA_CINT_OFFSET) -#define KINETIS_DMA_INT (KINETIS_DMAC_BASE + KINETIS_DMA_INT_OFFSET) -#define KINETIS_DMA_ERR (KINETIS_DMAC_BASE + KINETIS_DMA_ERR_OFFSET) -#define KINETIS_DMA_HRS (KINETIS_DMAC_BASE + KINETIS_DMA_HRS_OFFSET) - -#define KINETIS_DMA_DCHPRI(n) (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI_OFFSET(n)) - -#define KINETIS_DMA_DCHPRI3 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI3_OFFSET) -#define KINETIS_DMA_DCHPRI2 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI2_OFFSET) -#define KINETIS_DMA_DCHPRI1 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI1_OFFSET) -#define KINETIS_DMA_DCHPRI0 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI0_OFFSET) -#define KINETIS_DMA_DCHPRI7 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI7_OFFSET) -#define KINETIS_DMA_DCHPRI6 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI6_OFFSET) -#define KINETIS_DMA_DCHPRI5 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI5_OFFSET) -#define KINETIS_DMA_DCHPRI4 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI4_OFFSET) -#define KINETIS_DMA_DCHPRI11 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI11_OFFSET) -#define KINETIS_DMA_DCHPRI10 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI10_OFFSET) -#define KINETIS_DMA_DCHPRI9 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI9_OFFSET) -#define KINETIS_DMA_DCHPRI8 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI8_OFFSET) -#define KINETIS_DMA_DCHPRI15 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI15_OFFSET) -#define KINETIS_DMA_DCHPRI14 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI14_OFFSET) -#define KINETIS_DMA_DCHPRI13 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI13_OFFSET) -#define KINETIS_DMA_DCHPRI12 (KINETIS_DMAC_BASE + KINETIS_DMA_DCHPRI12_OFFSET) - -#define KINETIS_DMA_TCD_BASE(n) (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD_OFFSET(n)) - -#define KINETIS_DMA_TCD_SADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SADDR_OFFSET) -#define KINETIS_DMA_TCD_SOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SOFF_OFFSET) -#define KINETIS_DMA_TCD_ATTR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_ATTR_OFFSET) -#define KINETIS_DMA_TCD_NBYTES(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_NBYTES_OFFSET) -#define KINETIS_DMA_TCD_SLAST(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_SLAST_OFFSET) -#define KINETIS_DMA_TCD_DADDR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DADDR_OFFSET) -#define KINETIS_DMA_TCD_DOFF(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DOFF_OFFSET) -#define KINETIS_DMA_TCD_CITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CITER_OFFSET) -#define KINETIS_DMA_TCD_DLASTSGA(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD_CSR(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_CSR_OFFSET) -#define KINETIS_DMA_TCD_BITER(n) (KINETIS_DMA_TCD_BASE(n)+KINETIS_DMA_TCD_BITER_OFFSET) - -#define KINETIS_DMA_TCD0_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SADDR_OFFSET) -#define KINETIS_DMA_TCD0_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SOFF_OFFSET) -#define KINETIS_DMA_TCD0_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_ATTR_OFFSET) -#define KINETIS_DMA_TCD0_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_NBYTES_OFFSET) -#define KINETIS_DMA_TCD0_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_SLAST_OFFSET) -#define KINETIS_DMA_TCD0_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DADDR_OFFSET) -#define KINETIS_DMA_TCD0_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DOFF_OFFSET) -#define KINETIS_DMA_TCD0_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_CITER_OFFSET) -#define KINETIS_DMA_TCD0_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD0_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_CSR_OFFSET) -#define KINETIS_DMA_TCD0_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD0_BITER_OFFSET) - -#define KINETIS_DMA_TCD1_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SADDR_OFFSET) -#define KINETIS_DMA_TCD1_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SOFF_OFFSET) -#define KINETIS_DMA_TCD1_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_ATTR_OFFSET) -#define KINETIS_DMA_TCD1_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_NBYTES_OFFSET) -#define KINETIS_DMA_TCD1_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_SLAST_OFFSET) -#define KINETIS_DMA_TCD1_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DADDR_OFFSET) -#define KINETIS_DMA_TCD1_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DOFF_OFFSET) -#define KINETIS_DMA_TCD1_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_CITER_OFFSET) -#define KINETIS_DMA_TCD1_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD1_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_CSR_OFFSET) -#define KINETIS_DMA_TCD1_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD1_BITER_OFFSET) - -#define KINETIS_DMA_TCD2_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SADDR_OFFSET) -#define KINETIS_DMA_TCD2_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SOFF_OFFSET) -#define KINETIS_DMA_TCD2_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_ATTR_OFFSET) -#define KINETIS_DMA_TCD2_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_NBYTES_OFFSET) -#define KINETIS_DMA_TCD2_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_SLAST_OFFSET) -#define KINETIS_DMA_TCD2_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DADDR_OFFSET) -#define KINETIS_DMA_TCD2_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DOFF_OFFSET) -#define KINETIS_DMA_TCD2_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_CITER_OFFSET) -#define KINETIS_DMA_TCD2_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD2_CSR_ (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_CSR_OFFSET) -#define KINETIS_DMA_TCD2_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD2_BITER_OFFSET) - -#define KINETIS_DMA_TCD3_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SADDR_OFFSET) -#define KINETIS_DMA_TCD3_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SOFF_OFFSET) -#define KINETIS_DMA_TCD3_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_ATTR_OFFSET) -#define KINETIS_DMA_TCD3_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_NBYTES_OFFSET) -#define KINETIS_DMA_TCD3_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_SLAST_OFFSET) -#define KINETIS_DMA_TCD3_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DADDR_OFFSET) -#define KINETIS_DMA_TCD3_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DOFF_OFFSET) -#define KINETIS_DMA_TCD3_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_CITER_OFFSET) -#define KINETIS_DMA_TCD3_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_DLASTSGA_OFFSET -#define KINETIS_DMA_TCD3_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_CSR_OFFSET) -#define KINETIS_DMA_TCD3_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD3_BITER_OFFSET) - -#define KINETIS_DMA_TCD4_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SADDR_OFFSET) -#define KINETIS_DMA_TCD4_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SOFF_OFFSET) -#define KINETIS_DMA_TCD4_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_ATTR_OFFSET0) -#define KINETIS_DMA_TCD4_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_NBYTES_OFFSET) -#define KINETIS_DMA_TCD4_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_SLAST_OFFSET) -#define KINETIS_DMA_TCD4_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DADDR_OFFSET) -#define KINETIS_DMA_TCD4_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DOFF_OFFSET) -#define KINETIS_DMA_TCD4_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_CITER_OFFSET) -#define KINETIS_DMA_TCD4_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD4_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_CSR_OFFSET) -#define KINETIS_DMA_TCD4_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD4_BITER_OFFSET) - -#define KINETIS_DMA_TCD5_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SADDR_OFFSET) -#define KINETIS_DMA_TCD5_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SOFF_OFFSET) -#define KINETIS_DMA_TCD5_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_ATTR_OFFSET) -#define KINETIS_DMA_TCD5_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_NBYTES_OFFSET) -#define KINETIS_DMA_TCD5_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_SLAST_OFFSET) -#define KINETIS_DMA_TCD5_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DADDR_OFFSET) -#define KINETIS_DMA_TCD5_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DOFF_OFFSET) -#define KINETIS_DMA_TCD5_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_CITER_OFFSET) -#define KINETIS_DMA_TCD5_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD5_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_CSR_OFFSET) -#define KINETIS_DMA_TCD5_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD5_BITER_OFFSET) - -#define KINETIS_DMA_TCD6_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SADDR_OFFSET) -#define KINETIS_DMA_TCD6_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SOFF_OFFSET) -#define KINETIS_DMA_TCD6_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_ATTR_OFFSET) -#define KINETIS_DMA_TCD6_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_NBYTES_OFFSET) -#define KINETIS_DMA_TCD6_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_SLAST_OFFSET) -#define KINETIS_DMA_TCD6_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DADDR_OFFSET) -#define KINETIS_DMA_TCD6_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DOFF_OFFSET) -#define KINETIS_DMA_TCD6_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_CITER_OFFSET) -#define KINETIS_DMA_TCD6_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD6_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_CSR_OFFSET) -#define KINETIS_DMA_TCD6_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD6_BITER_OFFSET) - -#define KINETIS_DMA_TCD7_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SADDR_OFFSET) -#define KINETIS_DMA_TCD7_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SOFF_OFFSET) -#define KINETIS_DMA_TCD7_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_ATTR_OFFSET) -#define KINETIS_DMA_TCD7_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_NBYTES_OFFSET) -#define KINETIS_DMA_TCD7_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_SLAST_OFFSET) -#define KINETIS_DMA_TCD7_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DADDR_OFFSET) -#define KINETIS_DMA_TCD7_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DOFF_OFFSET) -#define KINETIS_DMA_TCD7_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_CITER_OFFSET) -#define KINETIS_DMA_TCD7_DLASTSGA_ (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD7_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_CSR_OFFSET) -#define KINETIS_DMA_TCD7_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD7_BITER_OFFSET) - -#define KINETIS_DMA_TCD8_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SADDR_OFFSET) -#define KINETIS_DMA_TCD8_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SOFF_OFFSET) -#define KINETIS_DMA_TCD8_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_ATTR_OFFSET) -#define KINETIS_DMA_TCD8_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_NBYTES_OFFSET) -#define KINETIS_DMA_TCD8_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_SLAST_OFFSET) -#define KINETIS_DMA_TCD8_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DADDR_OFFSET) -#define KINETIS_DMA_TCD8_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DOFF_OFFSET) -#define KINETIS_DMA_TCD8_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_CITER_OFFSET) -#define KINETIS_DMA_TCD8_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD8_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_CSR_OFFSET) -#define KINETIS_DMA_TCD8_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD8_BITER_OFFSET) - -#define KINETIS_DMA_TCD9_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SADDR_OFFSET) -#define KINETIS_DMA_TCD9_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SOFF_OFFSET) -#define KINETIS_DMA_TCD9_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_ATTR_OFFSET) -#define KINETIS_DMA_TCD9_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_NBYTES_OFFSET) -#define KINETIS_DMA_TCD9_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_SLAST_OFFSET) -#define KINETIS_DMA_TCD9_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DADDR_OFFSET) -#define KINETIS_DMA_TCD9_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DOFF_OFFSET) -#define KINETIS_DMA_TCD9_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_CITER_OFFSET) -#define KINETIS_DMA_TCD9_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD9_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_CSR_OFFSET) -#define KINETIS_DMA_TCD9_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD9_BITER_OFFSET) - -#define KINETIS_DMA_TCD10_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SADDR_OFFSET) -#define KINETIS_DMA_TCD10_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SOFF_OFFSET) -#define KINETIS_DMA_TCD10_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_ATTR_OFFSET) -#define KINETIS_DMA_TCD10_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_NBYTES_OFFSET) -#define KINETIS_DMA_TCD10_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_SLAST_OFFSET) -#define KINETIS_DMA_TCD10_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DADDR_OFFSET) -#define KINETIS_DMA_TCD10_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DOFF_OFFSET) -#define KINETIS_DMA_TCD10_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_CITER_OFFSET) -#define KINETIS_DMA_TCD10_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD10_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_CSR_OFFSET) -#define KINETIS_DMA_TCD10_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD10_BITER_OFFSET) - -#define KINETIS_DMA_TCD11_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SADDR_OFFSET) -#define KINETIS_DMA_TCD11_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SOFF_OFFSET) -#define KINETIS_DMA_TCD11_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_ATTR_OFFSET) -#define KINETIS_DMA_TCD11_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_NBYTES_OFFSET) -#define KINETIS_DMA_TCD11_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_SLAST_OFFSET) -#define KINETIS_DMA_TCD11_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DADDR_OFFSET) -#define KINETIS_DMA_TCD11_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DOFF_OFFSET) -#define KINETIS_DMA_TCD11_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_CITER_OFFSET) -#define KINETIS_DMA_TCD11_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD11_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_CSR_OFFSET) -#define KINETIS_DMA_TCD11_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD11_BITER_OFFSET) - -#define KINETIS_DMA_TCD12_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SADDR_OFFSET) -#define KINETIS_DMA_TCD12_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SOFF_OFFSET) -#define KINETIS_DMA_TCD12_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_ATTR_OFFSET) -#define KINETIS_DMA_TCD12_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_NBYTES_OFFSET) -#define KINETIS_DMA_TCD12_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_SLAST_OFFSET) -#define KINETIS_DMA_TCD12_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DADDR_OFFSET) -#define KINETIS_DMA_TCD12_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DOFF_OFFSET) -#define KINETIS_DMA_TCD12_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_CITER_OFFSET) -#define KINETIS_DMA_TCD12_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD12_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_CSR_OFFSET) -#define KINETIS_DMA_TCD12_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD12_BITER_OFFSET) - -#define KINETIS_DMA_TCD13_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SADDR_OFFSET) -#define KINETIS_DMA_TCD13_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SOFF_OFFSET) -#define KINETIS_DMA_TCD13_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_ATTR_OFFSET) -#define KINETIS_DMA_TCD13_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_NBYTES_OFFSET) -#define KINETIS_DMA_TCD13_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_SLAST_OFFSET) -#define KINETIS_DMA_TCD13_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DADDR_OFFSET) -#define KINETIS_DMA_TCD13_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DOFF_OFFSET) -#define KINETIS_DMA_TCD13_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_CITER_OFFSET) -#define KINETIS_DMA_TCD13_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD13_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_CSR_OFFSET) -#define KINETIS_DMA_TCD13_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD13_BITER_OFFSET) - -#define KINETIS_DMA_TCD14_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SADDR_OFFSET) -#define KINETIS_DMA_TCD14_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SOFF_OFFSET) -#define KINETIS_DMA_TCD14_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_ATTR_OFFSET) -#define KINETIS_DMA_TCD14_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_NBYTES_OFFSET) -#define KINETIS_DMA_TCD14_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_SLAST_OFFSET) -#define KINETIS_DMA_TCD14_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DADDR_OFFSET) -#define KINETIS_DMA_TCD14_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DOFF_OFFSET) -#define KINETIS_DMA_TCD14_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_CITER_OFFSET) -#define KINETIS_DMA_TCD14_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD14_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_CSR_OFFSET) -#define KINETIS_DMA_TCD14_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD14_BITER_OFFSET) - -#define KINETIS_DMA_TCD15_SADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SADDR_OFFSET) -#define KINETIS_DMA_TCD15_SOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SOFF_OFFSET) -#define KINETIS_DMA_TCD15_ATTR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_ATTR_OFFSET) -#define KINETIS_DMA_TCD15_NBYTES (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_NBYTES_OFFSET) -#define KINETIS_DMA_TCD15_SLAST (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_SLAST_OFFSET) -#define KINETIS_DMA_TCD15_DADDR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DADDR_OFFSET) -#define KINETIS_DMA_TCD15_DOFF (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DOFF_OFFSET) -#define KINETIS_DMA_TCD15_CITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_CITER_OFFSET) -#define KINETIS_DMA_TCD15_DLASTSGA (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_DLASTSGA_OFFSET) -#define KINETIS_DMA_TCD15_CSR (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_CSR_OFFSET) -#define KINETIS_DMA_TCD15_BITER (KINETIS_DMADESC_BASE + KINETIS_DMA_TCD15_BITER_OFFSET) - -/* Register Bit Definitions *************************************************/ - -/* Control Register (32-bit) */ - - /* Bit 0: Reserved */ -#define DMA_CR_EDBG (1 << 1) /* Bit 1: Enable debug */ -#define DMA_CR_ERCA (1 << 2) /* Bit 2: Enable round robin channel arbitration */ -#if defined KINETIS_DMA_HAS_CR_ERGA -# define DMA_CR_ERGA (1 << 3) /* Bit 3: Enable round robin group arbitration */ -#endif -#define DMA_CR_HOE (1 << 4) /* Bit 4: Halt on error */ -#define DMA_CR_HALT (1 << 5) /* Bit 5: Halt DMA operations */ -#define DMA_CR_CLM (1 << 6) /* Bit 6: Continuous link mode */ -#define DMA_CR_EMLM (1 << 7) /* Bit 7: Enable minor loop mapping */ -#ifdef KINETIS_DMA_HAS_CR_GRP0PRI -# define DMA_CR_GRP0PRI (1 << 8) /* Bit 8: Channel Group 0 Priority */ -#endif - /* Bit 9: Reserved */ -#ifdef KINETIS_DMA_HAS_CR_GRP1PRI -# define DMA_CR_GRP1PRI (1 << 10) /* Bit 10: Channel Group 1 Priority */ -#endif - /* Bits 11-15: Reserved */ -#define DMA_CR_ECX (1 << 16) /* Bit 16: Error cancel transfer */ -#define DMA_CR_CX (1 << 17) /* Bit 17: Cancel transfer */ - /* Bits 18-31: Reserved */ - -/* Error Status Register */ - -#define DMA_ES_DBE (1 << 0) /* Bit 0: Destination bus error */ -#define DMA_ES_SBE (1 << 1) /* Bit 1: Source bus error */ -#define DMA_ES_SGE (1 << 2) /* Bit 2: Scatter/gather configuration error */ -#define DMA_ES_NCE (1 << 3) /* Bit 3: NBYTES/CITER configuration error */ -#define DMA_ES_DOE (1 << 4) /* Bit 4: Destination offset error */ -#define DMA_ES_DAE (1 << 5) /* Bit 5: Destination address error */ -#define DMA_ES_SOE (1 << 6) /* Bit 6: Source offset error */ -#define DMA_ES_SAE (1 << 7) /* Bit 7: Source address error */ -#define DMA_ES_ERRCHN_SHIFT (8) /* Bits 8-11/12: Error channel number or cancelled channel number */ -#define DMA_ES_ERRCHN_MASK (((1 << KINETIS_DMA_HAS_ES_ERRCHN_BITS) - 1) << DMA_ES_ERRCHN_SHIFT) - /* Bits 13: Reserved */ -#define DMA_ES_CPE (1 << 14) /* Bit 14: Channel priority error */ -#ifdef KINETIS_DMA_HAS_ES_GPE -# define DMA_ES_GPE (1 << 15) /* Bit 15: Group priority error */ -#endif -#define DMA_ES_ECX (1 << 16) /* Bit 16: Transfer cancelled */ - /* Bits 17-30: Reserved */ -#define DMA_ES_VLD (1 << 31) /* Bit 31: Logical OR of all ERR status bits */ - -/* Enable Request Register (ERQ), Enable Error Interrupt Register (EEI), - * Interrupt Request Register (INT), Error Register (ERR), - * Hardware Request Status Register (HRS) common bit definitions - */ - -#define DMA_REQ(n) (1 << (n)) /* Bit n: DMA Request n, n=0.. +#include "hardware/kinetis_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define KINETIS_EDMA_NCHANNELS 16 + +/* eDMA Register Offsets ****************************************************/ + +#define KINETIS_EDMA_CR_OFFSET 0x0000 /* Control */ +#define KINETIS_EDMA_ES_OFFSET 0x0004 /* Error Status */ +#define KINETIS_EDMA_ERQ_OFFSET 0x000c /* Enable Request */ +#define KINETIS_EDMA_EEI_OFFSET 0x0014 /* Enable Error Interrupt */ +#define KINETIS_EDMA_CEEI_OFFSET 0x0018 /* Clear Enable Error Interrupt */ +#define KINETIS_EDMA_SEEI_OFFSET 0x0019 /* Set Enable Error Interrupt */ +#define KINETIS_EDMA_CERQ_OFFSET 0x001a /* Clear Enable Request */ +#define KINETIS_EDMA_SERQ_OFFSET 0x001b /* Set Enable Request */ +#define KINETIS_EDMA_CDNE_OFFSET 0x001c /* Clear DONE Status Bit */ +#define KINETIS_EDMA_SSRT_OFFSET 0x001d /* Set START Bit */ +#define KINETIS_EDMA_CERR_OFFSET 0x001e /* Clear Error */ +#define KINETIS_EDMA_CINT_OFFSET 0x001f /* Clear Interrupt Request */ +#define KINETIS_EDMA_INT_OFFSET 0x0024 /* Interrupt Request */ +#define KINETIS_EDMA_ERR_OFFSET 0x002c /* Error */ +#define KINETIS_EDMA_HRS_OFFSET 0x0034 /* Hardware Request Status */ +#define KINETIS_EDMA_EARS_OFFSET 0x0044 /* Enable Asynchronous Request in Stop */ + +#define KINETIS_EDMA_DCHPRI_OFFSET(n) (0x0100 + ((n) & ~3) + (3 - ((n) & 3))) + +#define KINETIS_EDMA_DCHPRI3_OFFSET 0x0100 /* Channel 3 Priority */ +#define KINETIS_EDMA_DCHPRI2_OFFSET 0x0101 /* Channel 2 Priority */ +#define KINETIS_EDMA_DCHPRI1_OFFSET 0x0102 /* Channel 1 Priority */ +#define KINETIS_EDMA_DCHPRI0_OFFSET 0x0103 /* Channel 0 Priority */ +#define KINETIS_EDMA_DCHPRI7_OFFSET 0x0104 /* Channel 7 Priority */ +#define KINETIS_EDMA_DCHPRI6_OFFSET 0x0105 /* Channel 6 Priority */ +#define KINETIS_EDMA_DCHPRI5_OFFSET 0x0106 /* Channel 5 Priority */ +#define KINETIS_EDMA_DCHPRI4_OFFSET 0x0107 /* Channel 4 Priority */ +#define KINETIS_EDMA_DCHPRI11_OFFSET 0x0108 /* Channel 11 Priority */ +#define KINETIS_EDMA_DCHPRI10_OFFSET 0x0109 /* Channel 10 Priority */ +#define KINETIS_EDMA_DCHPRI9_OFFSET 0x010a /* Channel 9 Priority */ +#define KINETIS_EDMA_DCHPRI8_OFFSET 0x010b /* Channel 8 Priority */ +#define KINETIS_EDMA_DCHPRI15_OFFSET 0x010c /* Channel 15 Priority */ +#define KINETIS_EDMA_DCHPRI14_OFFSET 0x010d /* Channel 14 Priority */ +#define KINETIS_EDMA_DCHPRI13_OFFSET 0x010e /* Channel 13 Priority */ +#define KINETIS_EDMA_DCHPRI12_OFFSET 0x010f /* Channel 12 Priority */ + +/* Transfer Control Descriptor (TCD) */ + +#define KINETIS_EDMA_TCD_OFFSET(n) (0x1000 + ((n) << 5)) +#define KINETIS_EDMA_TCD_SADDR_OFFSET 0x0000 /* TCD Source Address */ +#define KINETIS_EDMA_TCD_SOFF_OFFSET 0x0004 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD_ATTR_OFFSET 0x0006 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD_NBYTES_ML_OFFSET 0x0008 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD_SLAST_OFFSET 0x000c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD_DADDR_OFFSET 0x0010 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD_DOFF_OFFSET 0x0014 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD_CITER_ELINK_OFFSET 0x0016 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD_DLASTSGA_OFFSET 0x0018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD_CSR_OFFSET 0x001c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD_BITER_ELINK_OFFSET 0x001e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD0_SADDR_OFFSET 0x1000 /* TCD Source Address */ +#define KINETIS_EDMA_TCD0_SOFF_OFFSET 0x1004 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD0_ATTR_OFFSET 0x1006 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD0_NBYTES_ML_OFFSET 0x1008 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD0_SLAST_OFFSET 0x100c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD0_DADDR_OFFSET 0x1010 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD0_DOFF_OFFSET 0x1014 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD0_CITER_ELINK_OFFSET 0x1016 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD0_DLASTSGA_OFFSET 0x1018 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD0_CSR_OFFSET 0x101c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD0_BITER_ELINK_OFFSET 0x101e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD1_SADDR_OFFSET 0x1020 /* TCD Source Address */ +#define KINETIS_EDMA_TCD1_SOFF_OFFSET 0x1024 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD1_ATTR_OFFSET 0x1026 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET 0x1028 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD1_SLAST_OFFSET 0x102c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD1_DADDR_OFFSET 0x1030 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD1_DOFF_OFFSET 0x1034 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET 0x1036 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD1_DLASTSGA_OFFSET 0x1038 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD1_CSR_OFFSET 0x103c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET 0x103e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD1_SADDR_OFFSET 0x1020 /* TCD Source Address */ +#define KINETIS_EDMA_TCD1_SOFF_OFFSET 0x1024 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD1_ATTR_OFFSET 0x1026 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET 0x1028 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD1_SLAST_OFFSET 0x102c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD1_DADDR_OFFSET 0x1030 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD1_DOFF_OFFSET 0x1034 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET 0x1036 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD1_DLASTSGA_OFFSET 0x1038 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD1_CSR_OFFSET 0x103c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET 0x103e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD2_SADDR_OFFSET 0x1040 /* TCD Source Address */ +#define KINETIS_EDMA_TCD2_SOFF_OFFSET 0x1044 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD2_ATTR_OFFSET 0x1046 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD2_NBYTES_ML_OFFSET 0x1048 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD2_SLAST_OFFSET 0x104c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD2_DADDR_OFFSET 0x1050 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD2_DOFF_OFFSET 0x1054 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD2_CITER_ELINK_OFFSET 0x1056 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD2_DLASTSGA_OFFSET 0x1058 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD2_CSR_OFFSET 0x105c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD2_BITER_ELINK_OFFSET 0x105e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD3_SADDR_OFFSET 0x1060 /* TCD Source Address */ +#define KINETIS_EDMA_TCD3_SOFF_OFFSET 0x1064 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD3_ATTR_OFFSET 0x1066 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD3_NBYTES_ML_OFFSET 0x1068 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD3_SLAST_OFFSET 0x106c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD3_DADDR_OFFSET 0x1070 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD3_DOFF_OFFSET 0x1074 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD3_CITER_ELINK_OFFSET 0x1076 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD3_DLASTSGA_OFFSET 0x1078 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD3_CSR_OFFSET 0x107c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD3_BITER_ELINK_OFFSET 0x107e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD4_SADDR_OFFSET 0x1080 /* TCD Source Address */ +#define KINETIS_EDMA_TCD4_SOFF_OFFSET 0x1084 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD4_ATTR_OFFSET 0x1086 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD4_NBYTES_ML_OFFSET 0x1088 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD4_SLAST_OFFSET 0x108c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD4_DADDR_OFFSET 0x1090 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD4_DOFF_OFFSET 0x1094 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD4_CITER_ELINK_OFFSET 0x1096 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD4_DLASTSGA_OFFSET 0x1098 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD4_CSR_OFFSET 0x109c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD4_BITER_ELINK_OFFSET 0x109e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD5_SADDR_OFFSET 0x10a0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD5_SOFF_OFFSET 0x10a4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD5_ATTR_OFFSET 0x10a6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD5_NBYTES_ML_OFFSET 0x10a8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD5_SLAST_OFFSET 0x10ac /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD5_DADDR_OFFSET 0x10b0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD5_DOFF_OFFSET 0x10b4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD5_CITER_ELINK_OFFSET 0x10b6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD5_DLASTSGA_OFFSET 0x10b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD5_CSR_OFFSET 0x10bc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD5_BITER_ELINK_OFFSET 0x10be /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD6_SADDR_OFFSET 0x10c0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD6_SOFF_OFFSET 0x10c4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD6_ATTR_OFFSET 0x10c6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD6_NBYTES_ML_OFFSET 0x10c8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD6_SLAST_OFFSET 0x10cc /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD6_DADDR_OFFSET 0x10d0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD6_DOFF_OFFSET 0x10d4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD6_CITER_ELINK_OFFSET 0x10d6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD6_DLASTSGA_OFFSET 0x10d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD6_CSR_OFFSET 0x10dc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD6_BITER_ELINK_OFFSET 0x10de /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD7_SADDR_OFFSET 0x10e0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD7_SOFF_OFFSET 0x10e4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD7_ATTR_OFFSET 0x10e6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD7_NBYTES_ML_OFFSET 0x10e8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD7_SLAST_OFFSET 0x10ec /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD7_DADDR_OFFSET 0x10f0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD7_DOFF_OFFSET 0x10f4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD7_CITER_ELINK_OFFSET 0x10f6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD7_DLASTSGA_OFFSET 0x10f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD7_CSR_OFFSET 0x10fc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD7_BITER_ELINK_OFFSET 0x10fe /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD8_SADDR_OFFSET 0x1100 /* TCD Source Address */ +#define KINETIS_EDMA_TCD8_SOFF_OFFSET 0x1104 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD8_ATTR_OFFSET 0x1106 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD8_NBYTES_ML_OFFSET 0x1108 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD8_SLAST_OFFSET 0x110c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD8_DADDR_OFFSET 0x1110 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD8_DOFF_OFFSET 0x1114 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD8_CITER_ELINK_OFFSET 0x1116 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD8_DLASTSGA_OFFSET 0x1118 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD8_CSR_OFFSET 0x111c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD8_BITER_ELINK_OFFSET 0x111e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD9_SADDR_OFFSET 0x1120 /* TCD Source Address */ +#define KINETIS_EDMA_TCD9_SOFF_OFFSET 0x1124 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD9_ATTR_OFFSET 0x1126 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD9_NBYTES_ML_OFFSET 0x1128 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD9_SLAST_OFFSET 0x112c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD9_DADDR_OFFSET 0x1130 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD9_DOFF_OFFSET 0x1134 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD9_CITER_ELINK_OFFSET 0x1136 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD9_DLASTSGA_OFFSET 0x1138 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD9_CSR_OFFSET 0x113c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD9_BITER_ELINK_OFFSET 0x113e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD10_SADDR_OFFSET 0x1140 /* TCD Source Address */ +#define KINETIS_EDMA_TCD10_SOFF_OFFSET 0x1144 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD10_ATTR_OFFSET 0x1146 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD10_NBYTES_ML_OFFSET 0x1148 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD10_SLAST_OFFSET 0x114c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD10_DADDR_OFFSET 0x1150 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD10_DOFF_OFFSET 0x1154 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD10_CITER_ELINK_OFFSET 0x1156 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD10_DLASTSGA_OFFSET 0x1158 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD10_CSR_OFFSET 0x115c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD10_BITER_ELINK_OFFSET 0x115e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD11_SADDR_OFFSET 0x1160 /* TCD Source Address */ +#define KINETIS_EDMA_TCD11_SOFF_OFFSET 0x1164 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD11_ATTR_OFFSET 0x1166 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD11_NBYTES_ML_OFFSET 0x1168 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD11_SLAST_OFFSET 0x116c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD11_DADDR_OFFSET 0x1170 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD11_DOFF_OFFSET 0x1174 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD11_CITER_ELINK_OFFSET 0x1176 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD11_DLASTSGA_OFFSET 0x1178 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD11_CSR_OFFSET 0x117c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD11_BITER_ELINK_OFFSET 0x117e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD12_SADDR_OFFSET 0x1180 /* TCD Source Address */ +#define KINETIS_EDMA_TCD12_SOFF_OFFSET 0x1184 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD12_ATTR_OFFSET 0x1186 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD12_NBYTES_ML_OFFSET 0x1188 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD12_SLAST_OFFSET 0x118c /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD12_DADDR_OFFSET 0x1190 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD12_DOFF_OFFSET 0x1194 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD12_CITER_ELINK_OFFSET 0x1196 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD12_DLASTSGA_OFFSET 0x1198 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD12_CSR_OFFSET 0x119c /* TCD Control and Status */ +#define KINETIS_EDMA_TCD12_BITER_ELINK_OFFSET 0x119e /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD13_SADDR_OFFSET 0x11a0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD13_SOFF_OFFSET 0x11a4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD13_ATTR_OFFSET 0x11a6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD13_NBYTES_ML_OFFSET 0x11a8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD13_SLAST_OFFSET 0x11ac /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD13_DADDR_OFFSET 0x11b0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD13_DOFF_OFFSET 0x11b4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD13_CITER_ELINK_OFFSET 0x11b6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD13_DLASTSGA_OFFSET 0x11b8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD13_CSR_OFFSET 0x11bc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD13_BITER_ELINK_OFFSET 0x11be /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD14_SADDR_OFFSET 0x11c0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD14_SOFF_OFFSET 0x11c4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD14_ATTR_OFFSET 0x11c6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD14_NBYTES_ML_OFFSET 0x11c8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD14_SLAST_OFFSET 0x11cc /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD14_DADDR_OFFSET 0x11d0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD14_DOFF_OFFSET 0x11d4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD14_CITER_ELINK_OFFSET 0x11d6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD14_DLASTSGA_OFFSET 0x11d8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD14_CSR_OFFSET 0x11dc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD14_BITER_ELINK_OFFSET 0x11de /* TCD Beginning Minor Loop Link, Major Loop Count */ + +#define KINETIS_EDMA_TCD15_SADDR_OFFSET 0x11e0 /* TCD Source Address */ +#define KINETIS_EDMA_TCD15_SOFF_OFFSET 0x11e4 /* TCD Signed Source Address Offset */ +#define KINETIS_EDMA_TCD15_ATTR_OFFSET 0x11e6 /* TCD Transfer Attributes */ +#define KINETIS_EDMA_TCD15_NBYTES_ML_OFFSET 0x11e8 /* TCD Signed Minor Loop Offset / Byte Count */ +#define KINETIS_EDMA_TCD15_SLAST_OFFSET 0x11ec /* TCD Last Source Address Adjustment */ +#define KINETIS_EDMA_TCD15_DADDR_OFFSET 0x11f0 /* TCD Destination Address */ +#define KINETIS_EDMA_TCD15_DOFF_OFFSET 0x11f4 /* TCD Signed Destination Address Offset */ +#define KINETIS_EDMA_TCD15_CITER_ELINK_OFFSET 0x11f6 /* TCD Current Minor Loop Link, Major Loop Count */ +#define KINETIS_EDMA_TCD15_DLASTSGA_OFFSET 0x11f8 /* TCD Last Destination Address Adjustment/Scatter Gather Address */ +#define KINETIS_EDMA_TCD15_CSR_OFFSET 0x11fc /* TCD Control and Status */ +#define KINETIS_EDMA_TCD15_BITER_ELINK_OFFSET 0x11fe /* TCD Beginning Minor Loop Link, Major Loop Count */ + +/* eDMA Register Addresses **************************************************/ + +#define KINETIS_EDMA_CR (KINETIS_DMAC_BASE + KINETIS_EDMA_CR_OFFSET) +#define KINETIS_EDMA_ES (KINETIS_DMAC_BASE + KINETIS_EDMA_ES_OFFSET) +#define KINETIS_EDMA_ERQ (KINETIS_DMAC_BASE + KINETIS_EDMA_ERQ_OFFSET) +#define KINETIS_EDMA_EEI (KINETIS_DMAC_BASE + KINETIS_EDMA_EEI_OFFSET) +#define KINETIS_EDMA_CEEI (KINETIS_DMAC_BASE + KINETIS_EDMA_CEEI_OFFSET) +#define KINETIS_EDMA_SEEI (KINETIS_DMAC_BASE + KINETIS_EDMA_SEEI_OFFSET) +#define KINETIS_EDMA_CERQ (KINETIS_DMAC_BASE + KINETIS_EDMA_CERQ_OFFSET) +#define KINETIS_EDMA_SERQ (KINETIS_DMAC_BASE + KINETIS_EDMA_SERQ_OFFSET) +#define KINETIS_EDMA_CDNE (KINETIS_DMAC_BASE + KINETIS_EDMA_CDNE_OFFSET) +#define KINETIS_EDMA_SSRT (KINETIS_DMAC_BASE + KINETIS_EDMA_SSRT_OFFSET) +#define KINETIS_EDMA_CERR (KINETIS_DMAC_BASE + KINETIS_EDMA_CERR_OFFSET) +#define KINETIS_EDMA_CINT (KINETIS_DMAC_BASE + KINETIS_EDMA_CINT_OFFSET) +#define KINETIS_EDMA_INT (KINETIS_DMAC_BASE + KINETIS_EDMA_INT_OFFSET) +#define KINETIS_EDMA_ERR (KINETIS_DMAC_BASE + KINETIS_EDMA_ERR_OFFSET) +#define KINETIS_EDMA_HRS (KINETIS_DMAC_BASE + KINETIS_EDMA_HRS_OFFSET) +#define KINETIS_EDMA_EARS (KINETIS_DMAC_BASE + KINETIS_EDMA_EARS_OFFSET) + +#define KINETIS_EDMA_DCHPRI(n) (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI_OFFSET(n)) + +#define KINETIS_EDMA_DCHPRI0 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI0_OFFSET) +#define KINETIS_EDMA_DCHPRI1 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI1_OFFSET) +#define KINETIS_EDMA_DCHPRI2 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI2_OFFSET) +#define KINETIS_EDMA_DCHPRI3 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI3_OFFSET) +#define KINETIS_EDMA_DCHPRI4 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI4_OFFSET) +#define KINETIS_EDMA_DCHPRI5 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI5_OFFSET) +#define KINETIS_EDMA_DCHPRI6 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI6_OFFSET) +#define KINETIS_EDMA_DCHPRI7 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI7_OFFSET) +#define KINETIS_EDMA_DCHPRI8 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI8_OFFSET) +#define KINETIS_EDMA_DCHPRI9 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI9_OFFSET) +#define KINETIS_EDMA_DCHPRI10 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI10_OFFSET) +#define KINETIS_EDMA_DCHPRI11 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI11_OFFSET) +#define KINETIS_EDMA_DCHPRI12 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI12_OFFSET) +#define KINETIS_EDMA_DCHPRI13 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI13_OFFSET) +#define KINETIS_EDMA_DCHPRI14 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI14_OFFSET) +#define KINETIS_EDMA_DCHPRI15 (KINETIS_DMAC_BASE + KINETIS_EDMA_DCHPRI15_OFFSET) + +/* Transfer Control Descriptor (TCD) */ + +#define KINETIS_EDMA_TCD_BASE(n) (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD_OFFSET(n)) +#define KINETIS_EDMA_TCD_SADDR(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SADDR_OFFSET) +#define KINETIS_EDMA_TCD_SOFF(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SOFF_OFFSET) +#define KINETIS_EDMA_TCD_ATTR(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_ATTR_OFFSET) +#define KINETIS_EDMA_TCD_NBYTES_ML(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD_SLAST(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_SLAST_OFFSET) +#define KINETIS_EDMA_TCD_DADDR(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DADDR_OFFSET) +#define KINETIS_EDMA_TCD_DOFF(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DOFF_OFFSET) +#define KINETIS_EDMA_TCD_CITER_ELINK(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD_DLASTSGA(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD_CSR(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_CSR_OFFSET) +#define KINETIS_EDMA_TCD_BITER_ELINK(n) (KINETIS_EDMA_TCD_BASE(n) + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD0_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SADDR_OFFSET) +#define KINETIS_EDMA_TCD0_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SOFF_OFFSET) +#define KINETIS_EDMA_TCD0_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_ATTR_OFFSET) +#define KINETIS_EDMA_TCD0_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD0_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_SLAST_OFFSET) +#define KINETIS_EDMA_TCD0_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DADDR_OFFSET) +#define KINETIS_EDMA_TCD0_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DOFF_OFFSET) +#define KINETIS_EDMA_TCD0_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD0_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD0_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_CSR_OFFSET) +#define KINETIS_EDMA_TCD0_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD0_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD1_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SADDR_OFFSET) +#define KINETIS_EDMA_TCD1_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SOFF_OFFSET) +#define KINETIS_EDMA_TCD1_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_ATTR_OFFSET) +#define KINETIS_EDMA_TCD1_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD1_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_SLAST_OFFSET) +#define KINETIS_EDMA_TCD1_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DADDR_OFFSET) +#define KINETIS_EDMA_TCD1_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DOFF_OFFSET) +#define KINETIS_EDMA_TCD1_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD1_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD1_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_CSR_OFFSET) +#define KINETIS_EDMA_TCD1_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD1_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD2_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SADDR_OFFSET) +#define KINETIS_EDMA_TCD2_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SOFF_OFFSET) +#define KINETIS_EDMA_TCD2_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_ATTR_OFFSET) +#define KINETIS_EDMA_TCD2_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD2_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_SLAST_OFFSET) +#define KINETIS_EDMA_TCD2_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DADDR_OFFSET) +#define KINETIS_EDMA_TCD2_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DOFF_OFFSET) +#define KINETIS_EDMA_TCD2_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD2_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD2_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_CSR_OFFSET) +#define KINETIS_EDMA_TCD2_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD2_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD3_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SADDR_OFFSET) +#define KINETIS_EDMA_TCD3_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SOFF_OFFSET) +#define KINETIS_EDMA_TCD3_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_ATTR_OFFSET) +#define KINETIS_EDMA_TCD3_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD3_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_SLAST_OFFSET) +#define KINETIS_EDMA_TCD3_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DADDR_OFFSET) +#define KINETIS_EDMA_TCD3_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DOFF_OFFSET) +#define KINETIS_EDMA_TCD3_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD3_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD3_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_CSR_OFFSET) +#define KINETIS_EDMA_TCD3_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD3_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD4_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SADDR_OFFSET) +#define KINETIS_EDMA_TCD4_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SOFF_OFFSET) +#define KINETIS_EDMA_TCD4_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_ATTR_OFFSET) +#define KINETIS_EDMA_TCD4_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD4_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_SLAST_OFFSET) +#define KINETIS_EDMA_TCD4_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DADDR_OFFSET) +#define KINETIS_EDMA_TCD4_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DOFF_OFFSET) +#define KINETIS_EDMA_TCD4_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD4_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD4_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_CSR_OFFSET) +#define KINETIS_EDMA_TCD4_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD4_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD5_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SADDR_OFFSET) +#define KINETIS_EDMA_TCD5_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SOFF_OFFSET) +#define KINETIS_EDMA_TCD5_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_ATTR_OFFSET) +#define KINETIS_EDMA_TCD5_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD5_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_SLAST_OFFSET) +#define KINETIS_EDMA_TCD5_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DADDR_OFFSET) +#define KINETIS_EDMA_TCD5_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DOFF_OFFSET) +#define KINETIS_EDMA_TCD5_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD5_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD5_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_CSR_OFFSET) +#define KINETIS_EDMA_TCD5_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD5_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD6_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SADDR_OFFSET) +#define KINETIS_EDMA_TCD6_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SOFF_OFFSET) +#define KINETIS_EDMA_TCD6_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_ATTR_OFFSET) +#define KINETIS_EDMA_TCD6_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD6_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_SLAST_OFFSET) +#define KINETIS_EDMA_TCD6_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DADDR_OFFSET) +#define KINETIS_EDMA_TCD6_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DOFF_OFFSET) +#define KINETIS_EDMA_TCD6_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD6_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD6_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_CSR_OFFSET) +#define KINETIS_EDMA_TCD6_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD6_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD7_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SADDR_OFFSET) +#define KINETIS_EDMA_TCD7_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SOFF_OFFSET) +#define KINETIS_EDMA_TCD7_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_ATTR_OFFSET) +#define KINETIS_EDMA_TCD7_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD7_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_SLAST_OFFSET) +#define KINETIS_EDMA_TCD7_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DADDR_OFFSET) +#define KINETIS_EDMA_TCD7_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DOFF_OFFSET) +#define KINETIS_EDMA_TCD7_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD7_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD7_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_CSR_OFFSET) +#define KINETIS_EDMA_TCD7_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD7_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD8_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SADDR_OFFSET) +#define KINETIS_EDMA_TCD8_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SOFF_OFFSET) +#define KINETIS_EDMA_TCD8_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_ATTR_OFFSET) +#define KINETIS_EDMA_TCD8_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD8_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_SLAST_OFFSET) +#define KINETIS_EDMA_TCD8_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DADDR_OFFSET) +#define KINETIS_EDMA_TCD8_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DOFF_OFFSET) +#define KINETIS_EDMA_TCD8_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD8_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD8_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_CSR_OFFSET) +#define KINETIS_EDMA_TCD8_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD8_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD9_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SADDR_OFFSET) +#define KINETIS_EDMA_TCD9_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SOFF_OFFSET) +#define KINETIS_EDMA_TCD9_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_ATTR_OFFSET) +#define KINETIS_EDMA_TCD9_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD9_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_SLAST_OFFSET) +#define KINETIS_EDMA_TCD9_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DADDR_OFFSET) +#define KINETIS_EDMA_TCD9_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DOFF_OFFSET) +#define KINETIS_EDMA_TCD9_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD9_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD9_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_CSR_OFFSET) +#define KINETIS_EDMA_TCD9_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD9_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD10_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SADDR_OFFSET) +#define KINETIS_EDMA_TCD10_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SOFF_OFFSET) +#define KINETIS_EDMA_TCD10_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_ATTR_OFFSET) +#define KINETIS_EDMA_TCD10_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD10_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_SLAST_OFFSET) +#define KINETIS_EDMA_TCD10_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DADDR_OFFSET) +#define KINETIS_EDMA_TCD10_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DOFF_OFFSET) +#define KINETIS_EDMA_TCD10_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD10_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD10_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_CSR_OFFSET) +#define KINETIS_EDMA_TCD10_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD10_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD11_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SADDR_OFFSET) +#define KINETIS_EDMA_TCD11_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SOFF_OFFSET) +#define KINETIS_EDMA_TCD11_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_ATTR_OFFSET) +#define KINETIS_EDMA_TCD11_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD11_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_SLAST_OFFSET) +#define KINETIS_EDMA_TCD11_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DADDR_OFFSET) +#define KINETIS_EDMA_TCD11_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DOFF_OFFSET) +#define KINETIS_EDMA_TCD11_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD11_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD11_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_CSR_OFFSET) +#define KINETIS_EDMA_TCD11_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD11_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD12_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SADDR_OFFSET) +#define KINETIS_EDMA_TCD12_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SOFF_OFFSET) +#define KINETIS_EDMA_TCD12_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_ATTR_OFFSET) +#define KINETIS_EDMA_TCD12_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD12_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_SLAST_OFFSET) +#define KINETIS_EDMA_TCD12_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DADDR_OFFSET) +#define KINETIS_EDMA_TCD12_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DOFF_OFFSET) +#define KINETIS_EDMA_TCD12_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD12_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD12_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_CSR_OFFSET) +#define KINETIS_EDMA_TCD12_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD12_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD13_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SADDR_OFFSET) +#define KINETIS_EDMA_TCD13_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SOFF_OFFSET) +#define KINETIS_EDMA_TCD13_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_ATTR_OFFSET) +#define KINETIS_EDMA_TCD13_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD13_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_SLAST_OFFSET) +#define KINETIS_EDMA_TCD13_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DADDR_OFFSET) +#define KINETIS_EDMA_TCD13_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DOFF_OFFSET) +#define KINETIS_EDMA_TCD13_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD13_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD13_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_CSR_OFFSET) +#define KINETIS_EDMA_TCD13_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD13_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD14_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SADDR_OFFSET) +#define KINETIS_EDMA_TCD14_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SOFF_OFFSET) +#define KINETIS_EDMA_TCD14_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_ATTR_OFFSET) +#define KINETIS_EDMA_TCD14_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD14_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_SLAST_OFFSET) +#define KINETIS_EDMA_TCD14_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DADDR_OFFSET) +#define KINETIS_EDMA_TCD14_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DOFF_OFFSET) +#define KINETIS_EDMA_TCD14_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD14_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD14_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_CSR_OFFSET) +#define KINETIS_EDMA_TCD14_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD14_BITER_ELINK_OFFSET) + +#define KINETIS_EDMA_TCD15_SADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SADDR_OFFSET) +#define KINETIS_EDMA_TCD15_SOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SOFF_OFFSET) +#define KINETIS_EDMA_TCD15_ATTR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_ATTR_OFFSET) +#define KINETIS_EDMA_TCD15_NBYTES_ML (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_NBYTES_ML_OFFSET) +#define KINETIS_EDMA_TCD15_SLAST (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_SLAST_OFFSET) +#define KINETIS_EDMA_TCD15_DADDR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DADDR_OFFSET) +#define KINETIS_EDMA_TCD15_DOFF (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DOFF_OFFSET) +#define KINETIS_EDMA_TCD15_CITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_CITER_ELINK_OFFSET) +#define KINETIS_EDMA_TCD15_DLASTSGA (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_DLASTSGA_OFFSET) +#define KINETIS_EDMA_TCD15_CSR (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_CSR_OFFSET) +#define KINETIS_EDMA_TCD15_BITER_ELINK (KINETIS_DMAC_BASE + KINETIS_EDMA_TCD15_BITER_ELINK_OFFSET) + +/* eDMA Bit-Field Definitions ***********************************************/ + +/* Control */ + + /* Bit 0: Reserved */ +#define EDMA_CR_EDBG (1 << 1) /* Bit 1: Enable Debug */ +#define EDMA_CR_ERCA (1 << 2) /* Bit 2: Enable Round Robin Channel Arbitration */ +#define EDMA_CR_ERGA (1 << 3) /* Bit 3: Enable Round Robin Group Arbitration */ +#define EDMA_CR_HOE (1 << 4) /* Bit 4: Halt On Error */ +#define EDMA_CR_HALT (1 << 5) /* Bit 5: Halt DMA Operations */ +#define EDMA_CR_CLM (1 << 6) /* Bit 6: Continuous Link Mode */ +#define EDMA_CR_EMLM (1 << 7) /* Bit 7: Enable Minor Loop Mapping */ + /* Bit 8-15: Reserved */ +#define EDMA_CR_ECX (1 << 16) /* Bit 16: Error Cancel Transfer */ +#define EDMA_CR_CX (1 << 17) /* Bit 17: Cancel Transfer */ + /* Bits 18-23: Reserved */ + /* Bits 24-30: eDMA version number (reserved) */ +#define EDMA_CR_ACTIVE (1 << 31) /* Bit 31: DMA Active Status */ + +/* Error Status */ + +#define EDMA_ES_DBE (1 << 0) /* Bit 0: Destination Bus Error */ +#define EDMA_ES_SBE (1 << 1) /* Bit 1: Source Bus Error */ +#define EDMA_ES_SGE (1 << 2) /* Bit 2: Scatter/Gather Configuration Error */ +#define EDMA_ES_NCE (1 << 3) /* Bit 3: NBYTES/CITER Configuration Error */ +#define EDMA_ES_DOE (1 << 4) /* Bit 4: Destination Offset Error */ +#define EDMA_ES_DAE (1 << 5) /* Bit 5: Destination Address Error */ +#define EDMA_ES_SOE (1 << 6) /* Bit 6: Source Offset Error */ +#define EDMA_ES_SAE (1 << 7) /* Bit 7: Source Address Error */ +#define EDMA_ES_ERRCHN_SHIFT (8) /* Bits 8-11: Error Channel Number or + * Canceled Channel Number */ +#define EDMA_ES_ERRCHN_MASK (15 << EDMA_ES_ERRCHN_SHIFT) + /* Bits 23-13: Reserved */ +#define EDMA_ES_CPE (1 << 14) /* Bit 14: Channel Priority Error */ + /* Bit 15: Reserved */ +#define EDMA_ES_ECX (1 << 16) /* Bit 16: Transfer Canceled */ + /* Bits 17-30: Reserved */ +#define EDMA_ES_VLD (1 << 31) /* Bit 31: Logical OR of all ERR status bits */ + +/* Enable Request */ + +#define EDMA_ERQ(n) ((uint32_t)1 << (n)) /* Bit n: Enable DMA request n */ + +/* Enable Error Interrupt */ + +#define EDMA_EEI(n) ((uint32_t)1 << (n)) /* Bit n: Enable error interrupt n */ + +/* Clear Enable Error Interrupt */ + +#define EDMA_CEEI_SHIFT (0) /* Bits 0-3: Clear Enable Error Interrupt */ +#define EDMA_CEEI_MASK (15 << EDMA_CEEI_SHIFT) +# define EDMA_CEEI(n) ((uint32_t)(n) << EDMA_CEEI_SHIFT) + /* Bit 54-: Reserved */ +#define EDMA_CEEI_CAEE (1 << 6) /* Bit 6: Clear All Enable Error Interrupts */ +#define EDMA_CEEI_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Set Enable Error Interrupt */ + +#define EDMA_SEEI_SHIFT (0) /* Bits 0-3: Set Enable Error Interrupt */ +#define EDMA_SEEI_MASK (15 << EDMA_SEEI_SHIFT) +# define EDMA_SEEI(n) ((uint32_t)(n) << EDMA_SEEI_SHIFT) + /* Bit 54-: Reserved */ +#define EDMA_SEEI_SAEE (1 << 6) /* Bit 6: Set All Enable Error Interrupts */ +#define EDMA_SEEI_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Clear Enable Request */ + +#define EDMA_CERQ_SHIFT (0) /* Bits 0-3: Clear Enable Request */ +#define EDMA_CERQ_MASK (15 << EDMA_CERQ_SHIFT) +# define EDMA_CERQ(n) ((uint32_t)(n) << EDMA_CERQ_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_CERQ_CAER (1 << 6) /* Bit 6: Clear All Enable Requests */ +#define EDMA_CERQ_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Set Enable Request */ + +#define EDMA_SERQ_SHIFT (0) /* Bits 0-3: Set Enable Request */ +#define EDMA_SERQ_MASK (15 << EDMA_SERQ_SHIFT) +# define EDMA_SERQ(n) ((uint32_t)(n) << EDMA_SERQ_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_SERQ_SAER (1 << 6) /* Bit 6: Set All Enable Requests */ +#define EDMA_SERQ_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Clear DONE Status Bit */ + +#define EDMA_CDNE_SHIFT (0) /* Bits 0-3: Clear DONE Bit */ +#define EDMA_CDNE_MASK (15 << EDMA_CDNE_SHIFT) +# define EDMA_CDNE(n) ((uint32_t)(n) << EDMA_CDNE_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_CDNE_CADN (1 << 6) /* Bit 6: Clears All DONE Bits */ +#define EDMA_CDNE_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Set START Bit */ + +#define EDMA_SSRT_SHIFT (0) /* Bits 0-3: Set START Bit */ +#define EDMA_SSRT_MASK (15 << EDMA_SSRT_SHIFT) +# define EDMA_SSRT(n) ((uint32_t)(n) << EDMA_SSRT_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_SSRT_SAST (1 << 6) /* Bit 6: Set All START Bits (activates all channels) */ +#define EDMA_SSRT_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Clear Error */ + +#define EDMA_CERR_SHIFT (0) /* Bits 0-3: Clear Error Indicator */ +#define EDMA_CERR_MASK (15 << EDMA_CERR_SHIFT) +# define EDMA_CERR(n) ((uint32_t)(n) << EDMA_CERR_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_CERR_CAEI (1 << 6) /* Bit 6: Clear All Error Indicators */ +#define EDMA_CERR_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Clear Interrupt Request */ + +#define EDMA_CINT_SHIFT (0) /* Bits 0-3: Clear Interrupt Request */ +#define EDMA_CINT_MASK (15 << EDMA_CINT_SHIFT) +# define EDMA_CINT(n) ((uint32_t)(n) << EDMA_CINT_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_CINT_CAIR (1 << 6) /* Bit 6: Clear All Interrupt Requests */ +#define EDMA_CINT_NOP (1 << 7) /* Bit 7: No Op enable */ + +/* Interrupt Request */ + +#define EDMA_INT(n) ((uint32_t)1 << (n)) /* Bit n: Interrupt Request n */ + +/* Error */ + +#define EDMA_ERR(n) ((uint32_t)1 << (n)) /* Bit n: Error In Channel n */ + +/* Hardware Request Status */ + +#define EDMA_HRS(n) ((uint32_t)1 << (n)) /* Bit n: Hardware Request Status + * Channel n */ + +/* Enable Asynchronous Request in Stop */ + +#define EDMA_EARS(n) ((uint32_t)1 << (n)) /* Bit n: Enable asynchronous DMA + * request in stop mode for channel n */ + +/* Channel n Priority */ + +#define EDMA_DCHPRI_CHPRI_SHIFT (0) /* Bits 0-3: Channel n Arbitration Priority */ +#define EDMA_DCHPRI_CHPRI_MASK (15 << EDMA_DCHPRI_CHPRI_SHIFT) +# define EDMA_DCHPRI_CHPRI(n) ((uint32_t)(n) << EDMA_DCHPRI_CHPRI_SHIFT) + /* Bit 4-5: Reserved */ +#define EDMA_DCHPRI_DPA (1 << 6) /* Bit 6: Disable Preempt Ability */ +#define EDMA_DCHPRI_ECP (1 << 7) /* Bit 7: Enable Channel Preemption */ + +/* TCD Source Address (32-bit address) */ + +/* TCD Signed Source Address Offset (16-bit offset) */ + +/* TCD Transfer Attributes */ + +#define TCD_ATTR_SIZE_8BIT (0) /* 8-bit */ +#define TCD_ATTR_SIZE_16BIT (1) /* 16-bit */ +#define TCD_ATTR_SIZE_32BIT (2) /* 32-bit */ +#define TCD_ATTR_SIZE_64BIT (3) /* 64-bit */ +#define TCD_ATTR_SIZE_256BIT (5) /* 32-byte burst (4 beats of 64 bits) */ + +#define EDMA_TCD_ATTR_DSIZE_SHIFT (0) /* Bits 0-2: Destination data transfer size */ +#define EDMA_TCD_ATTR_DSIZE_MASK (7 << EDMA_TCD_ATTR_DSIZE_SHIFT) +# define EDMA_TCD_ATTR_DSIZE(n) ((uint32_t)(n) << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */ +# define EDMA_TCD_ATTR_DSIZE_8BIT (TCD_ATTR_SIZE_8BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 8-bit */ +# define EDMA_TCD_ATTR_DSIZE_16BIT (TCD_ATTR_SIZE_16BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 16-bit */ +# define EDMA_TCD_ATTR_DSIZE_32BIT (TCD_ATTR_SIZE_32BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 32-bit */ +# define EDMA_TCD_ATTR_DSIZE_64BIT (TCD_ATTR_SIZE_64BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 64-bit */ +# define EDMA_TCD_ATTR_DSIZE_256BIT (TCD_ATTR_SIZE_256BIT << EDMA_TCD_ATTR_DSIZE_SHIFT) /* 32-byte burst */ + +#define EDMA_TCD_ATTR_DMOD_SHIFT (3) /* Bits 3-7: Destination Address Modulo */ +#define EDMA_TCD_ATTR_DMOD_MASK (31 << EDMA_TCD_ATTR_DMOD_SHIFT) +# define EDMA_TCD_ATTR_DMOD(n) ((uint32_t)(n) << EDMA_TCD_ATTR_DMOD_SHIFT) +#define EDMA_TCD_ATTR_SSIZE_SHIFT (8) /* Bits 8-10: Source data transfer size */ +#define EDMA_TCD_ATTR_SSIZE_MASK (7 << EDMA_TCD_ATTR_SSIZE_SHIFT) +# define EDMA_TCD_ATTR_SSIZE(n) ((uint32_t)(n) << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */ +# define EDMA_TCD_ATTR_SSIZE_8BIT (TCD_ATTR_SIZE_8BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 8-bit */ +# define EDMA_TCD_ATTR_SSIZE_16BIT (TCD_ATTR_SIZE_16BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 16-bit */ +# define EDMA_TCD_ATTR_SSIZE_32BIT (TCD_ATTR_SIZE_32BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-bit */ +# define EDMA_TCD_ATTR_SSIZE_64BIT (TCD_ATTR_SIZE_64BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 64-bit */ +# define EDMA_TCD_ATTR_SSIZE_256BIT (TCD_ATTR_SIZE_256BIT << EDMA_TCD_ATTR_SSIZE_SHIFT) /* 32-byte burst */ + +#define EDMA_TCD_ATTR_SMOD_SHIFT (11) /* Bits 11-15: Source Address Modulo */ +#define EDMA_TCD_ATTR_SMOD_MASK (31 << EDMA_TCD_ATTR_SMOD_SHIFT) +# define EDMA_TCD_ATTR_SMOD(n) ((uint32_t)(n) << EDMA_TCD_ATTR_SMOD_SHIFT) + +/* TCD Signed Minor Loop Offset / Byte Count */ + +/* Minor Byte Count (Minor Loop Mapping Disabled -- 32-bit byte count) */ + +/* TCD Signed Minor Loop Offset / Byte Count */ + +/* Minor Byte Count (Minor Loop Mapping Enabled, offset disabled) */ + +#define EDMA_TCD_NBYTES_ML_NBYTES_SHIFT (0) /* Bits 0-29: Minor Byte Transfer Count */ +#define EDMA_TCD_NBYTES_ML_NBYTES_MASK (0x3fffffff << EDMA_TCD_NBYTES_ML_NBYTES_SHIFT) +# define EDMA_TCD_NBYTES_ML_NBYTES(n) ((uint32_t)(n) << EDMA_TCD_NBYTES_ML_NBYTES_SHIFT) +#define EDMA_TCD_NBYTES_ML_DMLOE (1 << 30) /* Bit 30: Destination Minor Loop Offset enable */ +#define EDMA_TCD_NBYTES_ML_SMLOE (1 << 31) /* Bit 31: Source Minor Loop Offset Enable */ + +/* TCD Signed Minor Loop Offset / Byte Count */ + +/* Minor Byte Count (Minor Loop Mapping Enabled, offset enabled) */ + +#define EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT (0) /* Bits 0-9: Minor Byte Transfer Count */ +#define EDMA_TCD_NBYTES_MLOFF_NBYTES_MASK (0x3ff << EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT) +# define EDMA_TCD_NBYTES_MLOFF_NBYTES(n) ((uint32_t)(n) << EDMA_TCD_NBYTES_MLOFF_NBYTES_SHIFT) +#define EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT (10) /* Bits 10-29: Minor Byte Transfer Count */ +#define EDMA_TCD_NBYTES_MLOFF_MLOFF_MASK (0xfffff << EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT) +# define EDMA_TCD_NBYTES_MLOFF_MLOFF(n) ((uint32_t)(n) << EDMA_TCD_NBYTES_MLOFF_MLOFF_SHIFT) +#define EDMA_TCD_NBYTES_MLOFF_DMLOE (1 << 30) /* Bit 30: Destination Minor Loop Offset enable */ +#define EDMA_TCD_NBYTES_MLOFF_SMLOE (1 << 31) /* Bit 31: Source Minor Loop Offset Enable */ + +/* TCD Last Source Address Adjustment (32-bit address adjustment) */ + +/* TCD Destination Address (32-bit address) */ + +/* TCD Signed Destination Address Offset (16-bit signed address offset) */ + +/* TCD Current Minor Loop Link, Major Loop Count (Channel linking disabled) */ + +#define EDMA_TCD_CITER_CITER_SHIFT (0) /* Bit 0-14: Starting Major Iteration Count */ +#define EDMA_TCD_CITER_CITER_MASK (0x7fff << EDMA_TCD_CITER_CITER_SHIFT) +# define EDMA_TCD_CITER_CITER(n) ((uint32_t)(n) << EDMA_TCD_CITER_CITER_SHIFT) +#define EDMA_TCD_CITER_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking + * on minor-loop complete */ + +/* TCD Current Minor Loop Link, Major Loop Count + * (Channel linking enabled) + */ + +#define EDMA_TCD_CITER_ELINK_CITER_SHIFT (0) /* Bit 0-8: Current major iteration count */ +#define EDMA_TCD_CITER_ELINK_CITER_MASK (0x1ff << EDMA_TCD_CITER_ELINK_CITER_SHIFT) +# define EDMA_TCD_CITER_ELINK_CITER(n) ((uint32_t)(n) << EDMA_TCD_CITER_ELINK_CITER_SHIFT) +#define EDMA_TCD_CITER_ELINK_LINKCH_SHIFT (9) /* Bit 9-12: Minor Loop Link Channel Number */ +#define EDMA_TCD_CITER_ELINK_LINKCH_MASK (15 << EDMA_TCD_CITER_ELINK_LINKCH_SHIFT) +# define EDMA_TCD_CITER_ELINK_LINKCH(n) ((uint32_t)(n) << EDMA_TCD_CITER_ELINK_LINKCH_SHIFT) + /* Bit 13-14: Reserved */ +#define EDMA_TCD_CITER_ELINK_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking + * on minor-loop complete */ + +/* TCD Last Destination Address Adjustment/Scatter Gather Address + * (32-bit address) + */ + +/* TCD Control and Status */ + +#define EDMA_TCD_CSR_START (1 << 0) /* Bit 0: Channel Start */ +#define EDMA_TCD_CSR_INTMAJOR (1 << 1) /* Bit 1: Enable an interrupt when major + * iteration count completes */ +#define EDMA_TCD_CSR_INTHALF (1 << 2) /* Bit 2: Enable an interrupt when major + * counter is half complete */ +#define EDMA_TCD_CSR_DREQ (1 << 3) /* Bit 3: Disable Request */ +#define EDMA_TCD_CSR_ESG (1 << 4) /* Bit 4: Enable Scatter/Gather Processing */ +#define EDMA_TCD_CSR_MAJORELINK (1 << 5) /* Bit 5: Enable channel-to-channel linking + * on major loop complete */ +#define EDMA_TCD_CSR_ACTIVE (1 << 6) /* Bit 6: Channel Active */ +#define EDMA_TCD_CSR_DONE (1 << 7) /* Bit 7: Channel Done */ +#define EDMA_TCD_CSR_MAJORLINKCH_SHIFT (8) /* Bits 8-11: Major Loop Link Channel Number */ +#define EDMA_TCD_CSR_MAJORLINKCH_MASK (15 << EDMA_TCD_CSR_MAJORLINKCH_SHIFT) +# define EDMA_TCD_CSR_MAJORLINKCH(n) ((uint32_t)(n) << EDMA_TCD_CSR_MAJORLINKCH_SHIFT) + /* Bit 112-3: Reserved */ +#define EDMA_TCD_CSR_BWC_SHIFT (14) /* Bits 14-15: Bandwidth Control */ +#define EDMA_TCD_CSR_BWC_MASK (3 << EDMA_TCD_CSR_BWC_SHIFT) +# define EDMA_TCD_CSR_BWC_NONE (0 << EDMA_TCD_CSR_BWC_SHIFT) /* No eDMA engine stalls */ +# define EDMA_TCD_CSR_BWC_4CYCLES (2 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 4 + * cycles after each R/W */ +# define EDMA_TCD_CSR_BWC_8CYCLES (3 << EDMA_TCD_CSR_BWC_SHIFT) /* eDMA engine stalls for 8 + * cycles after each R/W */ + +/* TCD Beginning Minor Loop Link, Major Loop Count + * (Channel linking disabled) + */ + +#define EDMA_TCD_BITER_BITER_SHIFT (0) /* Bit 0-14: Starting Major Iteration Count */ +#define EDMA_TCD_BITER_BITER_MASK (0x7fff << EDMA_TCD_BITER_BITER_SHIFT) +# define EDMA_TCD_BITER_BITER(n) ((uint32_t)(n) << EDMA_TCD_BITER_BITER_SHIFT) +#define EDMA_TCD_BITER_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking + * on minor-loop complete */ + +/* TCD Beginning Minor Loop Link, Major Loop Count + * (Channel linking enabled) + */ + +#define EDMA_TCD_BITER_ELINK_BITER_SHIFT (0) /* Bit 0-8: Current major iteration count */ +#define EDMA_TCD_BITER_ELINK_BITER_MASK (0x1ff << EDMA_TCD_BITER_ELINK_BITER_SHIFT) +# define EDMA_TCD_BITER_ELINK_BITER(n) ((uint32_t)(n) << EDMA_TCD_BITER_ELINK_BITER_SHIFT) +#define EDMA_TCD_BITER_ELINK_LINKCH_SHIFT (9) /* Bit 9-12: Link Channel Number */ +#define EDMA_TCD_BITER_ELINK_LINKCH_MASK (15 << EDMA_TCD_BITER_ELINK_LINKCH_SHIFT) +# define EDMA_TCD_BITER_ELINK_LINKCH(n) ((uint32_t)(n) << EDMA_TCD_BITER_ELINK_LINKCH_SHIFT) + /* Bit 13-4: Reserved */ +#define EDMA_TCD_BITER_ELINK_ELINK (1 << 15) /* Bit 15: Enable channel-to-channel linking + * on minor-loop complete */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* In-memory representation of the 32-byte Transfer Control Descriptor + * (TCD) + */ + +struct kinetis_edmatcd_s +{ + sq_entry_t node; + uint8_t flags; /* See EDMA_CONFIG_* definitions */ + uint32_t saddr; /* Offset: 0x0000 TCD Source Address */ + uint16_t soff; /* Offset: 0x0004 TCD Signed Source Address Offset */ + uint16_t attr; /* Offset: 0x0006 TCD Transfer Attributes */ + uint32_t nbytes; /* Offset: 0x0008 TCD Signed Minor Loop Offset / Byte Count */ + uint32_t slast; /* Offset: 0x000c TCD Last Source Address Adjustment */ + uint32_t daddr; /* Offset: 0x0010 TCD Destination Address */ + uint16_t doff; /* Offset: 0x0014 TCD Signed Destination Address Offset */ + uint16_t citer; /* Offset: 0x0016 TCD Current Minor Loop Link, Major Loop Count */ + uint32_t dlastsga; /* Offset: 0x0018 TCD Last Destination Address Adjustment/Scatter Gather Address */ + uint16_t csr; /* Offset: 0x001c TCD Control and Status */ + uint16_t biter; /* Offset: 0x001e TCD Beginning Minor Loop Link, Major Loop Count */ +}; + +#endif /* __ARCH_ARM_SRC_KINETIS_HARDWARE_KINETIS_EDMA_H */ diff --git a/arch/arm/src/kinetis/kinetis_dma.c b/arch/arm/src/kinetis/kinetis_dma.c deleted file mode 100644 index 9287560128e..00000000000 --- a/arch/arm/src/kinetis/kinetis_dma.c +++ /dev/null @@ -1,455 +0,0 @@ -/**************************************************************************** - * arch/arm/src/kinetis/kinetis_dma.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "arm_arch.h" -#include "arm_internal.h" - -#include "kinetis_config.h" -#include "chip.h" -#include "kinetis_dma.h" -#include "hardware/kinetis_dmamux.h" -#include "hardware/kinetis_sim.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifndef DMA_CHN_PER_GROUP -# define DMA_CHN_PER_GROUP KINETIS_NDMACH /* Number of channels per group */ -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct kinetis_dma_ch -{ - bool used; - uint8_t ind; - uint8_t irq; - enum kinetis_dma_direction_e dir; - enum kinetis_dma_data_sz_e data_sz; - dma_callback_t callback; - void *arg; -}; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct kinetis_dma_ch g_channels[KINETIS_NDMACH]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static int kinetis_dmainterrupt_int(int irq, void *context, - struct kinetis_dma_ch *ch) -{ - /* Clear bit in the interrupt */ - - putreg8(ch->ind, KINETIS_DMA_CINT); - - /* Invoke the callback */ - - if (ch->callback) - { - ch->callback((DMA_HANDLE)&ch, ch->arg, 0); - } - - return OK; -} - -static int kinetis_dmainterrupt(int irq, void *context, void *arg) -{ - uint8_t irq_int = *(uint8_t *)arg; - uint32_t regval; - regval = getreg32(KINETIS_DMA_INT); - - /* Channel irq_int and irq_int + DMA_CHN_PER_GROUP use the same arg. Check - * which one requested an interrupt - */ - - if ((regval & (1 << irq_int)) != 0) - { - kinetis_dmainterrupt_int(irq, context, &g_channels[irq_int]); - } - - if ((regval & (1 << (irq_int + DMA_CHN_PER_GROUP))) != 0) - { - kinetis_dmainterrupt_int(irq, context, - &g_channels[irq_int + DMA_CHN_PER_GROUP]); - } - - return OK; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -size_t kinetis_dmaresidual(DMA_HANDLE handle) -{ - struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle; - - /* Channel Linking Disabled */ - - return ((getreg16(KINETIS_DMA_TCD_CITER(ch->ind)) >> - DMA_TCD_CITER2_SHIFT) & DMA_TCD_CITER2_MASK); -} - -/**************************************************************************** - * Name: kinetis_dmainitialize - * - * Description: - * Initialize the DMA subsystem. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void weak_function arm_dma_initialize(void) -{ - int i; - uint32_t regval; - int ret; - - for (i = KINETIS_NDMACH - 1; i >= 0; i--) - { - g_channels[i].ind = i; - g_channels[i].used = false; - g_channels[i].irq = KINETIS_IRQ_FIRST + (i % DMA_CHN_PER_GROUP); - - if (i < DMA_CHN_PER_GROUP) - { - /* Attach DMA interrupt */ - - ret = irq_attach(g_channels[i].irq, kinetis_dmainterrupt, - (void *)&g_channels[i].ind); - - if (ret == OK) - { - /* Enable the IRQ at the NVIC (still disabled at the DMA - * controller) - */ - - up_enable_irq(g_channels[i].irq); - } - else - { - g_channels[i].used = true; - g_channels[i + DMA_CHN_PER_GROUP].used = true; - } - } - } - - /* Enable clocking for DMA */ - - regval = getreg32(KINETIS_SIM_SCGC7); - regval |= SIM_SCGC7_DMA; - putreg32(regval, KINETIS_SIM_SCGC7); - - /* Configure DMA for round robin arbitration */ - - regval = 0; - regval |= DMA_CR_ERCA | DMA_CR_ERGA; - putreg32(regval, KINETIS_DMA_CR); - - /* Enable clocking for the DMA mux */ - - regval = getreg32(KINETIS_SIM_SCGC6); - regval |= SIM_SCGC6_DMAMUX0; - putreg32(regval, KINETIS_SIM_SCGC6); -} - -/**************************************************************************** - * Name: kinetis_dmachannel - * - * Description: - * Allocate a DMA channel. This function sets aside a DMA channel and - * gives the caller exclusive access to the DMA channel. - * - * Returned Value: - * On success, this function returns a non-NULL, void* DMA channel handle. - * NULL is returned on any failure. This function can fail only if no DMA - * channel is available. - * - ****************************************************************************/ - -DMA_HANDLE kinetis_dmachannel(uint8_t src, uint32_t per_addr, - enum kinetis_dma_data_sz_e per_data_sz, - enum kinetis_dma_direction_e dir) -{ - int i; - int ch_ind; - uint8_t regval8; - uint16_t regval16; - irqstate_t flags; - struct kinetis_dma_ch *ch; - - /* Find available channel */ - - ch_ind = -1; - flags = enter_critical_section(); - for (i = 0; i < KINETIS_NDMACH; i++) - { - if (!g_channels[i].used) - { - ch_ind = i; - g_channels[ch_ind].used = true; - break; - } - } - - leave_critical_section(flags); - - if (ch_ind == -1) - { - /* No available channel */ - - return NULL; - } - - ch = &g_channels[ch_ind]; - - /* Copy arguments */ - - ch->dir = dir; - ch->data_sz = per_data_sz; - - /* DMAMUX Set DMA channel source and enable it */ - - regval8 = ((((uint8_t)src) << DMAMUX_CHCFG_SOURCE_SHIFT) & - DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_ENBL; - putreg8(regval8, KINETIS_DMAMUX_CHCFG(ch_ind)); - - /* DMA Set peripheral address in TCD */ - - if (ch->dir == KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY) - { - putreg32(per_addr, KINETIS_DMA_TCD_SADDR(ch->ind)); - putreg16(0, KINETIS_DMA_TCD_SOFF(ch->ind)); - putreg32(0, KINETIS_DMA_TCD_SLAST(ch->ind)); - } - else if (ch->dir == KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL) - { - putreg32(per_addr, KINETIS_DMA_TCD_DADDR(ch->ind)); - putreg16(0, KINETIS_DMA_TCD_DOFF(ch->ind)); - putreg32(0, KINETIS_DMA_TCD_DLASTSGA(ch->ind)); - } - else - { - ch->used = false; - return NULL; - } - - /* Set data sizes */ - - regval16 = (DMA_TCD_ATTR_SSIZE_MASK & ((uint16_t)per_data_sz) << - DMA_TCD_ATTR_SSIZE_SHIFT); - regval16 |= (DMA_TCD_ATTR_DSIZE_MASK & ((uint16_t)per_data_sz) << - DMA_TCD_ATTR_DSIZE_SHIFT); - putreg16(regval16, KINETIS_DMA_TCD_ATTR(ch->ind)); - - /* Set minor loop count */ - - putreg32(1 << (uint8_t)per_data_sz, KINETIS_DMA_TCD_NBYTES(ch->ind)); - return (DMA_HANDLE)ch; -} - -/**************************************************************************** - * Name: kinetis_dmafree - * - * Description: - * Release a DMA channel. NOTE: The 'handle' used in this argument must - * NEVER be used again until kinetis_dmachannel() is called again to - * re-gain a valid handle. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void kinetis_dmafree(DMA_HANDLE handle) -{ - struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle; - irqstate_t flags; - - DEBUGASSERT(handle != NULL); - - /* Disable DMA channel in the dmamux */ - - putreg8(0, KINETIS_DMAMUX_CHCFG(ch->ind)); - - flags = enter_critical_section(); - ch->used = false; - leave_critical_section(flags); -} - -/**************************************************************************** - * Name: kinetis_dmasetup - * - * Description: - * Configure DMA for one transfer. - * - ****************************************************************************/ - -int kinetis_dmasetup(DMA_HANDLE handle, uint32_t mem_addr, size_t ntransfers, - uint16_t control) -{ - struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle; - uint16_t regval = 0; - uint32_t nbytes; - - if (ntransfers > (DMA_TCD_CITER2_MASK >> DMA_TCD_CITER2_SHIFT)) - { - return -EINVAL; - } - - DEBUGASSERT(handle != NULL); - - nbytes = (uint32_t)ntransfers * (uint32_t)(1 << (uint8_t)ch->data_sz); - - if (ch->dir == KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY) - { - putreg32(mem_addr, KINETIS_DMA_TCD_DADDR(ch->ind)); - putreg16(1 << (uint8_t)ch->data_sz, KINETIS_DMA_TCD_DOFF(ch->ind)); - putreg32(-nbytes, KINETIS_DMA_TCD_DLASTSGA(ch->ind)); - } - else if (ch->dir == KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL) - { - putreg32(mem_addr, KINETIS_DMA_TCD_SADDR(ch->ind)); - putreg16(1 << (uint8_t)ch->data_sz, KINETIS_DMA_TCD_SOFF(ch->ind)); - putreg32(-nbytes, KINETIS_DMA_TCD_SLAST(ch->ind)); - } - else - { - return -EINVAL; - } - - /* Set up channel with control word */ - - regval = (control & DMA_TCD_CSR_MAJORELINK) ? ch->ind : 0; - regval <<= DMA_TCD_CSR_MAJORLINKCH_SHIFT; - regval &= DMA_TCD_CSR_MAJORLINKCH_MASK; - regval |= (DMA_TCD_CSR_INTMAJOR | - (control & (DMA_TCD_CSR_INTHALF | DMA_TCD_CSR_MAJORELINK))); - putreg16(regval, KINETIS_DMA_TCD_CSR(ch->ind)); - - /* Set major loop count */ - - putreg16(ntransfers, KINETIS_DMA_TCD_BITER(ch->ind)); - putreg16(ntransfers, KINETIS_DMA_TCD_CITER(ch->ind)); - - return OK; -} - -/**************************************************************************** - * Name: kinetis_dmastart - * - * Description: - * Start the DMA transfer - * - ****************************************************************************/ - -int kinetis_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg) -{ - struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle; - - DEBUGASSERT(handle != NULL); - - ch->callback = callback; - ch->arg = arg; - - /* Enable request register for this channel */ - - putreg8(ch->ind, KINETIS_DMA_SERQ); - - return OK; -} - -/**************************************************************************** - * Name: kinetis_dmastop - * - * Description: - * Cancel the DMA. After kinetis_dmastop() is called, the DMA channel is - * reset and kinetis_dmasetup() must be called before kinetis_dmastart() - * can be called again - * - ****************************************************************************/ - -void kinetis_dmastop(DMA_HANDLE handle) -{ - struct kinetis_dma_ch *ch = (struct kinetis_dma_ch *)handle; - - DEBUGASSERT(handle != NULL); - - putreg8(ch->ind, KINETIS_DMA_CERQ); -} - -/**************************************************************************** - * Name: kinetis_dmasample - * - * Description: - * Sample DMA register contents - * - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_DMA -void kinetis_dmasample(DMA_HANDLE handle, struct kinetis_dmaregs_s *regs) -{ - DEBUGASSERT(handle != NULL); -} -#endif - -/**************************************************************************** - * Name: kinetis_dmadump - * - * Description: - * Dump previously sampled DMA register contents - * - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_DMA -void kinetis_dmadump(DMA_HANDLE handle, const struct kinetis_dmaregs_s *regs, - const char *msg) -{ - DEBUGASSERT(handle != NULL); -} -#endif diff --git a/arch/arm/src/kinetis/kinetis_dma.h b/arch/arm/src/kinetis/kinetis_dma.h deleted file mode 100644 index fc2cdb4b140..00000000000 --- a/arch/arm/src/kinetis/kinetis_dma.h +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** - * arch/arm/src/kinetis/kinetis_dma.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - ****************************************************************************/ - -#ifndef __ARCH_ARM_SRC_KINETEIS_KINETEIS_DMA_H -#define __ARCH_ARM_SRC_KINETEIS_KINETEIS_DMA_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -#include "hardware/kinetis_dma.h" - -/**************************************************************************** - * Pre-processor Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -typedef FAR void *DMA_HANDLE; -typedef void (*dma_callback_t)(DMA_HANDLE handle, void *arg, int result); - -/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is - * selected. - */ - -#ifdef CONFIG_DEBUG_DMA -struct kinetis_dmaglobalregs_s -{ -#warning "Missing logic" - /* Global Registers */ -}; - -struct kinetis_dmachanregs_s -{ -#warning "Missing logic" - /* Channel Registers */ -}; - -struct kinetis_dmaregs_s -{ - /* Global Registers */ - - struct kinetis_dmaglobalregs_s gbl; - - /* Channel Registers */ - - struct kinetis_dmachanregs_s ch; -}; -#endif - -enum kinetis_dma_direction_e -{ - KINETIS_DMA_DIRECTION_PERIPHERAL_TO_MEMORY, - KINETIS_DMA_DIRECTION_MEMORY_TO_PERIPHERAL -}; - -/* Kinetis data transfer size */ - -enum kinetis_dma_data_sz_e -{ - KINETIS_DMA_DATA_SZ_8BIT = 0, - KINETIS_DMA_DATA_SZ_16BIT = 1, - KINETIS_DMA_DATA_SZ_32BIT = 2, -}; - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -#ifndef __ASSEMBLY__ - -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -/**************************************************************************** - * Public Functions Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Name: kinetis_dmainitialize - * - * Description: - * Initialize the GPDMA subsystem. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void kinetis_dmainitialize(void); - -/**************************************************************************** - * Name: kinetis_dmachannel - * - * Description: - * Allocate a DMA channel. This function sets aside a DMA channel and - * gives the caller exclusive access to the DMA channel. - * - * Input Parameters: - * src - DMA request source - * per_addr - Address of the peripheral data - * per_data_sz - Peripheral data size (register size). Note that if this - * does not agree with the peripheral register size, DMA - * transfers will silently fail during operation. - * dir - transfer direction - * - * Returned Value: - * On success, this function returns a non-NULL, void* DMA channel handle. - * NULL is returned on any failure. This function can fail only if no DMA - * channel is available. - * - ****************************************************************************/ - -DMA_HANDLE kinetis_dmachannel(uint8_t src, - uint32_t per_addr, - enum kinetis_dma_data_sz_e per_data_sz, - enum kinetis_dma_direction_e dir); - -/**************************************************************************** - * Name: kinetis_dmafree - * - * Description: - * Release a DMA channel. NOTE: The 'handle' used in this argument must - * NEVER be used again until kinetis_dmachannel() is called again to re- - * gain a valid handle. - * - * Returned Value: - * None - * - ****************************************************************************/ - -void kinetis_dmafree(DMA_HANDLE handle); - -/**************************************************************************** - * Name: kinetis_dmasetup - * - * Description: - * Configure DMA for one transfer. - * - * Input Parameters: - * mem_addr - Memory address - * ntransfers - Number of transfers. Must be 0<= ntransfers <= 0x7FFF - * control - Channel control configuration - * - * Returned Value: - * result: 0 if ok, negative else - * - ****************************************************************************/ - -int kinetis_dmasetup(DMA_HANDLE handle, uint32_t mem_addr, - size_t ntransfers, uint16_t control); - -/**************************************************************************** - * Name: kinetis_dmastart - * - * Description: - * Start the DMA transfer - * - ****************************************************************************/ - -int kinetis_dmastart(DMA_HANDLE handle, dma_callback_t callback, void *arg); - -/**************************************************************************** - * Name: kinetis_dmastop - * - * Description: - * Cancel the DMA. After kinetis_dmastop() is called, the DMA channel is - * reset and kinetis_dmasetup() must be called before kinetis_dmastart() - * can be called again - * - ****************************************************************************/ - -void kinetis_dmastop(DMA_HANDLE handle); - -/**************************************************************************** - * Name: kinetis_dmaresidual - * - * Description: - * Returns the number of transfers left - * - * Returned Value: - * Residual transfers - ****************************************************************************/ - -size_t kinetis_dmaresidual(DMA_HANDLE handle); - -/**************************************************************************** - * Name: kinetis_dmasample - * - * Description: - * Sample DMA register contents - * - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_DMA -void kinetis_dmasample(DMA_HANDLE handle, struct kinetis_dmaregs_s *regs); -#else -# define kinetis_dmasample(handle,regs) -#endif - -/**************************************************************************** - * Name: kinetis_dmadump - * - * Description: - * Dump previously sampled DMA register contents - * - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_DMA -void kinetis_dmadump(DMA_HANDLE handle, const struct kinetis_dmaregs_s *regs, - const char *msg); -#else -# define kinetis_dmadump(handle,regs,msg) -#endif - -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ -#endif /* __ARCH_ARM_SRC_KINETEIS_KINETEIS_DMA_H */ diff --git a/arch/arm/src/kinetis/kinetis_edma.c b/arch/arm/src/kinetis/kinetis_edma.c new file mode 100644 index 00000000000..f0b14bee923 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_edma.c @@ -0,0 +1,1464 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_edma.c + * + * Copyright (C) 2019, 2021 Gregory Nutt. All rights reserved. + * Authors: Gregory Nutt + * David Sidrane + * + * This file was leveraged from the NuttX S32K port. Portions of that eDMA + * logic derived from NXP sample code which has a compatible BSD 3-clause + * license: + * + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "arm_arch.h" +#include "arm_internal.h" +#include "sched/sched.h" + +#include "chip.h" +#include "hardware/kinetis_edma.h" +#include "hardware/kinetis_dmamux.h" +#include "kinetis_edma.h" +#include "hardware/kinetis_sim.h" + +#ifdef CONFIG_KINETIS_EDMA + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* TCD Alignment. + * + * eDMA TCDs must be aligned with the D-Cache line boundaries to facilitate + * cache operations on the TCDs when the D-Cache is enabled. + * + * NOTE: The TCDs are 32-bytes in length. We implicitly assume that the + * D-Cache line size is also 32-bits. Otherwise, padding would be required + * at the ends of the TCDS and buffers to protect data after the end of from + * invalidation. + */ + +#ifdef CONFIG_ARMV7M_DCACHE +/* Align to the cache line size which we assume is >= 8 */ + +# define EDMA_ALIGN ARMV7M_DCACHE_LINESIZE +# define EDMA_ALIGN_MASK (EDMA_ALIGN-1) +# define EDMA_ALIGN_UP(n) (((n) + EDMA_ALIGN_MASK) & ~EDMA_ALIGN_MASK) + +#else +/* Special alignment is not required in this case, + * but we will align to 8-bytes + */ + +# define EDMA_ALIGN 8 +# define EDMA_ALIGN_MASK 7 +# define EDMA_ALIGN_UP(n) (((n) + 7) & ~7) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* State of a DMA channel */ + +enum kinetis_dmastate_e +{ + KINETIS_DMA_IDLE = 0, /* No DMA in progress */ + KINETIS_DMA_CONFIGURED, /* DMA configured, but not yet started */ + KINETIS_DMA_ACTIVE /* DMA has been started and is in progress */ +}; + +/* This structure describes one DMA channel */ + +struct kinetis_dmach_s +{ + uint8_t chan; /* DMA channel number (0-KINETIS_EDMA_NCHANNELS) */ + bool inuse; /* true: The DMA channel is in use */ + uint8_t dmamux; /* The DMAMUX channel selection */ + uint8_t ttype; /* Transfer type: M2M, M2P, P2M, or P2P */ + uint8_t state; /* Channel state. See enum kinetis_dmastate_e */ + uint32_t flags; /* DMA channel flags */ + edma_callback_t callback; /* Callback invoked when the DMA completes */ + void *arg; /* Argument passed to callback function */ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 + /* That TCD list is linked through the DLAST SGA field. The first transfer + * to be performed is at the head of the list. Subsequent TCDs are added + * at the tail of the list. + */ + + struct kinetis_edmatcd_s *head; /* First TCD in the list */ + struct kinetis_edmatcd_s *tail; /* Last TCD in the list */ +#endif +}; + +/* This structure describes the state of the eDMA controller */ + +struct kinetis_edma_s +{ + /* These semaphores protect the DMA channel and descriptor tables */ + + sem_t chsem; /* Protects channel table */ +#if CONFIG_KINETIS_EDMA_NTCD > 0 + sem_t dsem; /* Supports wait for free descriptors */ +#endif + + /* This array describes each DMA channel */ + + struct kinetis_dmach_s dmach[KINETIS_EDMA_NCHANNELS]; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The state of the eDMA */ + +static struct kinetis_edma_s g_edma; + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +/* This is a singly-linked list of free TCDs */ + +static sq_queue_t g_tcd_free; + +/* This is a pool of pre-allocated TCDs */ + +static struct kinetis_edmatcd_s g_tcd_pool[CONFIG_KINETIS_EDMA_NTCD] + __attribute__((aligned(EDMA_ALIGN))); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_takechsem() and kinetis_givechsem() + * + * Description: + * Used to get exclusive access to the DMA channel table for channel + * allocation. + * + ****************************************************************************/ + +static int kinetis_takechsem(void) +{ + return nxsem_wait_uninterruptible(&g_edma.chsem); +} + +static inline void kinetis_givechsem(void) +{ + nxsem_post(&g_edma.chsem); +} + +/**************************************************************************** + * Name: kinetis_takedsem() and kinetis_givedsem() + * + * Description: + * Used to wait for availability of descriptors in the descriptor table. + * + ****************************************************************************/ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +static void kinetis_takedsem(void) +{ + nxsem_wait_uninterruptible(&g_edma.dsem); +} + +static inline void kinetis_givedsem(void) +{ + nxsem_post(&g_edma.dsem); +} +#endif + +/**************************************************************************** + * Name: kinetis_tcd_alloc + * + * Description: + * Allocate an in-memory, TCD + * + ****************************************************************************/ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +static struct kinetis_edmatcd_s *kinetis_tcd_alloc(void) +{ + struct kinetis_edmatcd_s *tcd; + irqstate_t flags; + + /* Take the 'dsem'. When we hold the the 'dsem', then we know that one + * TCD is reserved for us in the free list. + * + * NOTE: We use a critical section here because we may block waiting for + * the 'dsem'. The critical section will be suspended while we are + * waiting. + */ + + flags = enter_critical_section(); + kinetis_takedsem(); + + /* Now there should be a TCD in the free list reserved just for us */ + + tcd = (struct kinetis_edmatcd_s *)sq_remfirst(&g_tcd_free); + DEBUGASSERT(tcd != NULL); + + leave_critical_section(flags); + return tcd; +} +#endif + +/**************************************************************************** + * Name: kinetis_tcd_free + * + * Description: + * Free an in-memory, TCD + * + ****************************************************************************/ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +static void kinetis_tcd_free(struct kinetis_edmatcd_s *tcd) +{ + irqstate_t flags; + + /* Add the the TCD to the end of the free list and post the 'dsem', + * possibly waking up another thread that might be waiting for + * a TCD. + */ + + flags = spin_lock_irqsave(NULL); + sq_addlast((sq_entry_t *)tcd, &g_tcd_free); + kinetis_givedsem(); + spin_unlock_irqrestore(NULL, flags); +} +#endif + +/**************************************************************************** + * Name: kinetis_tcd_initialize() + * + * Description: + * Initialize the TCD free list from the pool of pre-allocated TCDs. + * + * Assumptions: + * Called early in the initialization sequence so no special protection is + * necessary. + * + ****************************************************************************/ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +static inline void kinetis_tcd_initialize(void) +{ + sq_entry_t *tcd; + int i; + + /* Add each pre-allocated TCD to the tail of the TCD free list */ + + sq_init(&g_tcd_free); + for (i = 0; i < CONFIG_KINETIS_EDMA_NTCD; i++) + { + tcd = (sq_entry_t *)&g_tcd_pool[i]; + sq_addlast(tcd, &g_tcd_free); + } +} +#endif + +/**************************************************************************** + * Name: kinetis_tcd_chanlink + * + * Description: + * 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. + * + * NOTE: Users should ensure that DONE flag is cleared before calling this + * interface, or the configuration is invalid. + * + * Input Parameters: + * tcd - Point to the TCD structure. + * type - Channel link type. + * chan - The linked channel number. + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_KINETIS_EDMA_ELINK +static inline void kinetis_tcd_chanlink(uint8_t flags, + struct kinetis_dmach_s *linkch, + struct kinetis_edmatcd_s *tcd) +{ + uint16_t regval16; + + flags &= EDMA_CONFIG_LINKTYPE_MASK; + + if (linkch == NULL || flags == EDMA_CONFIG_LINKTYPE_LINKNONE) + { +#if 0 /* Already done */ + /* No link or no link channel provided */ + + /* Disable minor links */ + + tcd->citer &= ~EDMA_TCD_CITER_ELINK; + tcd->biter &= ~EDMA_TCD_BITER_ELINK; + + /* Disable major link */ + + tcd->csr &= ~EDMA_TCD_CSR_MAJORELINK; +#endif + } + else if (flags == EDMA_CONFIG_LINKTYPE_MINORLINK) /* Minor link config */ + { + /* Enable minor link */ + + tcd->citer |= EDMA_TCD_CITER_ELINK_ELINK; + tcd->biter |= EDMA_TCD_BITER_ELINK_ELINK; + + /* Set linked channel */ + + regval16 = tcd->citer; + regval16 &= ~EDMA_TCD_CITER_ELINK_LINKCH_MASK; + regval16 |= EDMA_TCD_CITER_ELINK_LINKCH(linkch->chan); + tcd->citer = regval16; + + regval16 = tcd->biter; + regval16 &= ~EDMA_TCD_BITER_ELINK_LINKCH_MASK; + regval16 |= EDMA_TCD_BITER_ELINK_LINKCH(linkch->chan); + tcd->biter = regval16; + } + else /* if (flags == EDMA_CONFIG_LINKTYPE_MAJORLINK) Major link config */ + { + /* Enable major link */ + + regval16 = tcd->csr; + regval16 |= EDMA_TCD_CSR_MAJORELINK; + tcd->csr = regval16; + + /* Set major linked channel */ + + regval16 &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK; + regval16 |= EDMA_TCD_CSR_MAJORLINKCH(linkch->chan); + tcd->csr = regval16; + } +} +#endif + +/**************************************************************************** + * Name: kinetis_tcd_configure + * + * Description: + * Configure all TCD registers to the specified values. 'tcd' is an + * 'overlay' that may refer either to either the TCD register set or to an + * in-memory TCD structure. + * + ****************************************************************************/ + +static inline void kinetis_tcd_configure(struct kinetis_edmatcd_s *tcd, + const struct kinetis_edma_xfrconfig_s *config) +{ + tcd->flags = config->flags; + tcd->saddr = config->saddr; + tcd->soff = config->soff; + tcd->attr = EDMA_TCD_ATTR_SSIZE(config->ssize) | /* Transfer Attributes */ + EDMA_TCD_ATTR_DSIZE(config->dsize); + tcd->nbytes = config->nbytes; + tcd->slast = config->flags & EDMA_CONFIG_LOOPSRC ? -config->iter : 0; + tcd->daddr = config->daddr; + tcd->doff = config->doff; + tcd->citer = config->iter & EDMA_TCD_CITER_CITER_MASK; + tcd->biter = config->iter & EDMA_TCD_BITER_BITER_MASK; + tcd->csr = config->flags & EDMA_CONFIG_LOOPDEST ? + 0 : EDMA_TCD_CSR_DREQ; + tcd->csr |= config->flags & EDMA_CONFIG_INTHALF ? + EDMA_TCD_CSR_INTHALF : 0; + tcd->dlastsga = config->flags & EDMA_CONFIG_LOOPDEST ? -config->iter : 0; + + /* And special case flags */ + +#ifdef CONFIG_KINETIS_EDMA_ELINK + /* Configure major/minor link mapping */ + + kinetis_tcd_chanlink(config->flags, + (struct kinetis_dmach_s *)config->linkch, + tcd); +#endif +} + +/**************************************************************************** + * Name: kinetis_tcd_instantiate + * + * Description: + * Copy an in-memory TCD into eDMA channel TCD registers + * + ****************************************************************************/ + +#if CONFIG_KINETIS_EDMA_NTCD > 0 +static void kinetis_tcd_instantiate(struct kinetis_dmach_s *dmach, + const struct kinetis_edmatcd_s *tcd) +{ + uintptr_t base = KINETIS_EDMA_TCD_BASE(dmach->chan); + + /* Push tcd into hardware TCD register */ + + putreg32(tcd->saddr, base + KINETIS_EDMA_TCD_SADDR_OFFSET); + putreg16(tcd->soff, base + KINETIS_EDMA_TCD_SOFF_OFFSET); + putreg16(tcd->attr, base + KINETIS_EDMA_TCD_ATTR_OFFSET); + putreg32(tcd->nbytes, base + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET); + putreg32(tcd->slast, base + KINETIS_EDMA_TCD_SLAST_OFFSET); + putreg32(tcd->daddr, base + KINETIS_EDMA_TCD_DADDR_OFFSET); + putreg16(tcd->doff, base + KINETIS_EDMA_TCD_DOFF_OFFSET); + putreg16(tcd->citer, base + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET); + putreg32(tcd->dlastsga, base + KINETIS_EDMA_TCD_DLASTSGA_OFFSET); + + /* Clear DONE bit first, otherwise ESG cannot be set */ + + putreg16(0, base + KINETIS_EDMA_TCD_CSR_OFFSET); + putreg16(tcd->csr, base + KINETIS_EDMA_TCD_CSR_OFFSET); + + putreg16(tcd->biter, base + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET); +} +#endif + +/**************************************************************************** + * Name: kinetis_dmaterminate + * + * Description: + * Terminate the DMA transfer and disable the DMA channel + * + ****************************************************************************/ + +static void kinetis_dmaterminate(struct kinetis_dmach_s *dmach, int result) +{ +#if CONFIG_KINETIS_EDMA_NTCD > 0 + struct kinetis_edmatcd_s *tcd; + struct kinetis_edmatcd_s *next; +#endif + uintptr_t regaddr; + uint8_t regval8; + uint8_t chan; + + /* Disable channel ERROR interrupts */ + + chan = dmach->chan; + regval8 = EDMA_CEEI(chan); + putreg8(regval8, KINETIS_EDMA_CEEI); + + /* Disable channel IRQ requests */ + + regval8 = EDMA_CERQ(chan); + putreg8(regval8, KINETIS_EDMA_CERQ); + + /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */ + + if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_PERIPH2MEM) + { + /* Invalidate the cache to force reloads from memory. */ + +#warning Missing logic + } + + /* Perform the DMA complete callback */ + + if (dmach->callback) + { + dmach->callback((DMACH_HANDLE)dmach, dmach->arg, true, result); + } + + /* Clear CSR to disable channel. Because if the given channel started, + * transfer CSR will be not zero. Because if it is the last transfer, DREQ + * will be set. If not, ESG will be set. + */ + + regaddr = KINETIS_EDMA_TCD_CSR(chan); + putreg16(0, regaddr); + + /* Cancel next TCD transfer. */ + + regaddr = KINETIS_EDMA_TCD_DLASTSGA(chan); + putreg16(0, regaddr); + +#if CONFIG_KINETIS_EDMA_NTCD > 0 + /* Return all allocated TCDs to the free list */ + + for (tcd = dmach->head; tcd != NULL; tcd = next) + { + /* If channel looped to itself we are done + * if not continue to free tcds in chain + */ + + next = tcd->flags & EDMA_CONFIG_LOOPDEST ? + NULL : (struct kinetis_edmatcd_s *)tcd->dlastsga; + + kinetis_tcd_free(tcd); + } + + dmach->head = NULL; + dmach->tail = NULL; +#endif + + dmach->callback = NULL; + dmach->arg = NULL; + dmach->state = KINETIS_DMA_IDLE; +} + +/**************************************************************************** + * Name: kinetis_edma_interrupt + * + * Description: + * DMA interrupt handler. This function clears the channel major + * interrupt flag and calls the callback function if it is not NULL. + * + * NOTE: For the case using TCD queue, when the major iteration count is + * exhausted, additional operations are performed. These include the + * final address adjustments and reloading of the BITER field into the + * CITER. Assertion of an optional interrupt request also occurs at this + * time, as does a possible fetch of a new TCD from memory using the + * scatter/gather address pointer included in the descriptor (if scatter/ + * gather is enabled). + * + ****************************************************************************/ + +static int kinetis_edma_interrupt(int irq, void *context, FAR void *arg) +{ + struct kinetis_dmach_s *dmach; + uintptr_t regaddr; + uint8_t regval8; + uint16_t regval16; + uint32_t regval32; + uint8_t chan; + int result; + + /* 'arg' should the DMA channel instance. */ + + dmach = (struct kinetis_dmach_s *)arg; + DEBUGASSERT(dmach != NULL); + + chan = dmach->chan; + DEBUGASSERT(chan < KINETIS_EDMA_NCHANNELS && dmach == &g_edma.dmach[chan]); + + /* Check for an eDMA pending interrupt on this channel */ + + regval32 = getreg32(KINETIS_EDMA_INT); + if ((regval32 & EDMA_INT(chan)) != 0) + { + /* An interrupt is pending. This should only happen if the channel is + * active. + */ + + DEBUGASSERT(dmach->state == KINETIS_DMA_ACTIVE); + + /* Clear the pending eDMA channel interrupt */ + + regval8 = EDMA_CINT(chan); + putreg8(regval8, KINETIS_EDMA_CINT); + + /* Get the eDMA TCD Control and Status register value. */ + + regaddr = KINETIS_EDMA_TCD_CSR(chan); + regval16 = getreg16(regaddr); + + /* Check if transfer has finished. */ + + if ((regval16 & EDMA_TCD_CSR_DONE) != 0) + { + /* Clear the pending DONE interrupt status. */ + + regval8 = EDMA_CDNE(chan); + putreg8(regval8, KINETIS_EDMA_CDNE); + result = OK; + } + else + { +#if CONFIG_KINETIS_EDMA_NTCD > 0 + /* Perform the end-of-major-cycle DMA callback */ + + if (dmach->callback != NULL) + { + dmach->callback((DMACH_HANDLE)dmach, dmach->arg, + false, 0); + } + + return OK; +#else + /* Otherwise the interrupt was not expected! */ + + DEBUGPANIC(); + result = -EPIPE; +#endif + } + + /* Terminate the transfer when it is done. */ + + kinetis_dmaterminate(dmach, result); + } + + return OK; +} + +/**************************************************************************** + * Name: kinetis_error_interrupt + * + * Description: + * DMA error interrupt handler + * + ****************************************************************************/ + +static int kinetis_error_interrupt(int irq, void *context, FAR void *arg) +{ + uint32_t errstatus; + uint32_t errmask; + uint8_t regval8; + unsigned int chan; + + /* Get the set of pending error interrupts */ + + errstatus = getreg32(KINETIS_EDMA_ERR); + + /* Check for an error on each channel */ + + for (chan = 0; chan < KINETIS_EDMA_NCHANNELS && errstatus != 0; chan++) + { + /* Check for a pending error interrupt on each channel */ + + errmask = EDMA_ERR(chan); + if ((errstatus & errmask) != 0) + { + dmaerr("ERROR: DMACH%u ES=%08lx\n", + chan, (unsigned long)getreg32(KINETIS_EDMA_ES)); + + /* Clear the pending error interrupt status. */ + + regval8 = EDMA_CERR(chan); + putreg8(regval8, KINETIS_EDMA_CERR); + + /* Remove the bit from the sample ERR register so that perhaps we + * can exit this loop early. + */ + + errstatus &= ~errmask; + + /* Terminate the transfer on any error */ + + kinetis_dmaterminate(&g_edma.dmach[chan], -EIO); + } + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arm_dma_initialize + * + * Description: + * Initialize the DMA subsystem + * + * Returned Value: + * None + * + ****************************************************************************/ + +void weak_function arm_dma_initialize(void) +{ + uintptr_t regaddr; + uint32_t regval; + int i; + + dmainfo("Initialize eDMA\n"); + + /* Enable clocking for DMA */ + + regval = getreg32(KINETIS_SIM_SCGC7); + regval |= SIM_SCGC7_DMA; + putreg32(regval, KINETIS_SIM_SCGC7); + + /* Enable clocking for the DMA mux */ + + regval = getreg32(KINETIS_SIM_SCGC6); + regval |= SIM_SCGC6_DMAMUX0; + putreg32(regval, KINETIS_SIM_SCGC6); + + /* Configure the eDMA controller */ + + regval = getreg32(KINETIS_EDMA_CR); + regval &= ~(EDMA_CR_EDBG | EDMA_CR_ERCA | EDMA_CR_HOE | EDMA_CR_CLM | + EDMA_CR_EMLM); + +#ifdef CONFIG_KINETIS_EDMA_EDBG + regval |= EDMA_CR_EDBG; /* Enable Debug */ +#endif +#ifdef CONFIG_KINETIS_EDMA_ERCA + regval |= EDMA_CR_ERCA; /* Enable Round Robin Channel Arbitration */ +#endif +#ifdef CONFIG_KINETIS_EDMA_ERGA + regval |= EDMA_CR_ERGA; /* Enable Round Robin Group Arbitration */ +#endif +#ifdef CONFIG_KINETIS_EDMA_HOE + regval |= EDMA_CR_HOE; /* Halt On Error */ +#endif +#ifdef CONFIG_KINETIS_EDMA_CLM + regval |= EDMA_CR_CLM; /* Continuous Link Mode */ +#endif +#ifdef CONFIG_KINETIS_EDMA_EMLIM + regval |= EDMA_CR_EMLM; /* Enable Minor Loop Mapping */ +#endif + + putreg32(regval, KINETIS_EDMA_CR); + + /* Initialize data structures */ + + memset(&g_edma, 0, sizeof(struct kinetis_edma_s)); + for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++) + { + g_edma.dmach[i].chan = i; + } + + /* Initialize semaphores */ + + nxsem_init(&g_edma.chsem, 0, 1); +#if CONFIG_KINETIS_EDMA_NTCD > 0 + nxsem_init(&g_edma.dsem, 0, CONFIG_KINETIS_EDMA_NTCD); + + /* The 'dsem' is used for signaling rather than mutual exclusion and, + * hence, should not have priority inheritance enabled. + */ + + nxsem_set_protocol(&g_edma.dsem, SEM_PRIO_NONE); + + /* Initialize the list of free TCDs from the pool of pre-allocated TCDs. */ + + kinetis_tcd_initialize(); +#endif + + /* Attach DMA interrupt vectors. */ + + for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++) + { + irq_attach(KINETIS_IRQ_DMACH0 + i, + kinetis_edma_interrupt, &g_edma.dmach[i]); + } + + /* Attach the DMA error interrupt vector */ + + irq_attach(KINETIS_IRQ_DMAERR, kinetis_error_interrupt, NULL); + + /* Disable and clear all error interrupts */ + + putreg32(0, KINETIS_EDMA_EEI); + putreg32(0xffffffff, KINETIS_EDMA_ERR); + + /* Disable all DMA channel interrupts at the eDMA controller */ + + for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++) + { + /* Disable all DMA channels and DMA channel interrupts */ + + regaddr = KINETIS_EDMA_TCD_CSR(i); + putreg16(0, regaddr); + } + + /* Clear all pending DMA channel interrupts */ + + putreg32(0xffffffff, KINETIS_EDMA_INT); + + /* Enable the channel interrupts at the NVIC (still disabled at the eDMA + * controller). + */ + + for (i = 0; i < KINETIS_EDMA_NCHANNELS; i++) + { + up_enable_irq(KINETIS_IRQ_DMACH0 + i); + } + + /* Enable the DMA error interrupt */ + + up_enable_irq(KINETIS_IRQ_DMAERR); +} + +/**************************************************************************** + * Name: kinetis_dmach_alloc + * + * Allocate a DMA channel. This function sets aside a DMA channel, + * initializes the DMAMUX for the channel, then gives the caller exclusive + * access to the DMA channel. + * + * Input Parameters: + * dmamux - DMAMUX configuration see DMAMUX channel configuration register + * bit-field definitions in hardware/kinetis_dmamux.h. + * Settings include: + * + * DMAMUX_CHCFG_SOURCE Chip-specific DMA source (required) + * DMAMUX_CHCFG_TRIG DMA Channel Trigger Enable (optional) + * DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required) + * + * A value of zero will disable the DMAMUX channel. + * dchpri - DCHPRI channel priority configuration. See DCHPRI channel + * configuration register bit-field definitions in + * hardware/kinetis_edma.h. Meaningful settings include: + * + * EDMA_DCHPRI_CHPRI Channel Arbitration Priority + * DCHPRI_DPA Disable Preempt Ability + * DCHPRI_ECP Enable Channel Preemption + * + * The power-on default, 0x05, is a reasonable choice. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* + * DMA channel handle. NULL is returned on any failure. + * + ****************************************************************************/ + +DMACH_HANDLE kinetis_dmach_alloc(uint8_t dmamux, uint8_t dchpri) +{ + struct kinetis_dmach_s *dmach; + unsigned int chndx; + int ret; + + /* Search for an available DMA channel */ + + dmach = NULL; + ret = kinetis_takechsem(); + if (ret < 0) + { + return NULL; + } + + for (chndx = 0; chndx < KINETIS_EDMA_NCHANNELS; chndx++) + { + struct kinetis_dmach_s *candidate = &g_edma.dmach[chndx]; + uintptr_t regaddr; + uint8_t regval8; + + if (!candidate->inuse) + { + dmach = candidate; + dmach->inuse = true; + dmach->state = KINETIS_DMA_IDLE; + dmach->dmamux = dmamux; + + /* Clear any pending interrupts on the channel */ + + DEBUGASSERT(chndx == dmach->chan); + regaddr = KINETIS_EDMA_TCD_CSR(chndx); + putreg16(0, regaddr); + + /* Make sure that the channel is disabled. */ + + regval8 = EDMA_CERQ(chndx); + putreg8(regval8, KINETIS_EDMA_CERQ); + + /* Disable the associated DMAMUX for now */ + + putreg8(0, KINETIS_DMAMUX_CHCFG(chndx)); + break; + } + } + + kinetis_givechsem(); + + /* Show the result of the allocation */ + + if (dmach != NULL) + { + dmainfo("CH%d: returning dmach: %p\n", dmach->chan, dmach); + } + else + { + dmaerr("ERROR: Failed allocate eDMA channel\n"); + } + + return (DMACH_HANDLE)dmach; +} + +/**************************************************************************** + * Name: kinetis_dmach_free + * + * Description: + * Release a DMA channel. NOTE: The 'handle' used in this argument must + * NEVER be used again until kinetis_dmach_alloc() is called again to + * re-gain a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void kinetis_dmach_free(DMACH_HANDLE handle) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; + uint8_t regval8; + + dmainfo("dmach: %p\n", dmach); + DEBUGASSERT(dmach != NULL && dmach->inuse && + dmach->state != KINETIS_DMA_ACTIVE); + + /* Mark the channel no longer in use. Clearing the inuse flag is an atomic + * operation and so should be safe. + */ + + dmach->flags = 0; + dmach->inuse = false; /* No longer in use */ + dmach->state = KINETIS_DMA_IDLE; /* Better not be active! */ + + /* Make sure that the channel is disabled. */ + + regval8 = EDMA_CERQ(dmach->chan); + putreg8(regval8, KINETIS_EDMA_CERQ); + + /* Disable the associated DMAMUX */ + + putreg8(0, KINETIS_DMAMUX_CHCFG(dmach->chan)); +} + +/**************************************************************************** + * Name: kinetis_dmach_xfrsetup + * + * Description: + * This function adds the eDMA transfer to the DMA sequence. The request + * is setup according to the content of the transfer configuration + * structure. For "normal" DMA, kinetis_dmach_xfrsetup is called only once. + * Scatter/gather DMA is accomplished by calling this function repeatedly, + * once for each transfer in the sequence. Scatter/gather DMA processing + * is enabled automatically when the second transfer configuration is + * received. + * + * This function may be called multiple times to handle multiple, + * discontinuous transfers (scatter-gather) + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * config - A DMA transfer configuration instance, populated by the + * The content of 'config' describes the transfer + * + * Returned Value + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int kinetis_dmach_xfrsetup(DMACH_HANDLE *handle, + const struct kinetis_edma_xfrconfig_s *config) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; +#if CONFIG_KINETIS_EDMA_NTCD > 0 + struct kinetis_edmatcd_s *tcd; + struct kinetis_edmatcd_s *prev; +#endif + uintptr_t regaddr; + uint16_t regval16; + + DEBUGASSERT(dmach != NULL); + dmainfo("dmach%u: %p config: %p\n", dmach->chan, dmach, config); + +#if CONFIG_KINETIS_EDMA_NTCD > 0 + /* Scatter/gather DMA is supported */ + + /* Allocate a TCD, waiting if necessary */ + + tcd = kinetis_tcd_alloc(); + + /* Configure current TCD block transfer. */ + + kinetis_tcd_configure(tcd, config); + + /* Enable the interrupt when the major iteration count completes for this + * TCD. For "normal" DMAs, this will correspond to the DMA DONE + * interrupt; for scatter gather DMAs, multiple interrupts will be + * generated with the final being the DONE interrupt. + */ + + tcd->csr |= EDMA_TCD_CSR_INTMAJOR; + + /* Is looped to it's self? */ + + if (config->flags & EDMA_CONFIG_LOOP_MASK) + { + /* Enable major link */ + + tcd->csr |= EDMA_TCD_CSR_MAJORELINK; + + /* Set major linked channel back to this one */ + + tcd->csr &= ~EDMA_TCD_CSR_MAJORLINKCH_MASK; + tcd->csr |= EDMA_TCD_CSR_MAJORLINKCH(dmach->chan); + } + + /* Is this the first descriptor in the list? */ + + if (dmach->head == NULL) + { + /* Yes.. add it to the list */ + + dmach->head = tcd; + dmach->tail = tcd; + dmach->ttype = config->ttype; + + /* And instantiate the first TCD in the DMA channel TCD registers. */ + + kinetis_tcd_instantiate(dmach, tcd); + } + else + { + /* Cannot mix transfer types (only because of cache-related operations. + * this restriction could be removed with some effort). + */ + + if (dmach->ttype != config->ttype || + dmach->flags & EDMA_CONFIG_LOOPDEST) + { + kinetis_tcd_free(tcd); + return -EINVAL; + } + + /* Chain from previous descriptor in the list. */ + + /* Enable scatter/gather feature in the previous TCD. */ + + prev = dmach->tail; + regval16 = prev->csr; + regval16 &= ~EDMA_TCD_CSR_DREQ; + regval16 |= EDMA_TCD_CSR_ESG; + prev->csr = regval16; + + prev->dlastsga = (uint32_t)tcd; + dmach->tail = tcd; + + /* Clean cache associated with the previous TCD memory */ + + up_clean_dcache((uintptr_t)prev, + (uintptr_t)prev + sizeof(struct kinetis_edmatcd_s)); + + /* Check if the TCD block in the DMA channel registers is the same as + * the previous previous TCD. This can happen if the previous TCD was + * the first TCD and has already be loaded into the TCD registers. + */ + + if (dmach->head == prev) + { + /* Enable scatter/gather also in the TCD registers. */ + + regaddr = KINETIS_EDMA_TCD_CSR(dmach->chan); + regval16 = getreg16(regaddr); + regval16 &= ~EDMA_TCD_CSR_DREQ; + regval16 |= EDMA_TCD_CSR_ESG; + putreg16(regval16, regaddr); + + regaddr = KINETIS_EDMA_TCD_DLASTSGA(dmach->chan); + putreg32((uint32_t)tcd, regaddr); + } + } + + /* Clean cache associated with the TCD memory */ + + up_clean_dcache((uintptr_t)tcd, + (uintptr_t)tcd + sizeof(struct kinetis_edmatcd_s)); +#else + /* Scatter/gather DMA is NOT supported */ + + /* Check if eDMA is busy: if the channel has started transfer, CSR will be + * non-zero. + */ + + regaddr = KINETIS_EDMA_TCD_CSR(dmach->chan); + regval16 = getreg16(regaddr); + + if (regval16 != 0 && (regval16 & EDMA_TCD_CSR_DONE) == 0) + { + return -EBUSY; + } + + /* Configure channel TCD registers to the values specified in config. */ + + kinetis_tcd_configure((struct kinetis_edmatcd_s *) + KINETIS_EDMA_TCD_BASE(dmach->chan), config); + + /* Enable the DONE interrupt when the major iteration count completes. */ + + regaddr = KINETIS_EDMA_TCD_CSR(dmach->chan); + modifyreg16(regaddr, 0, EDMA_TCD_CSR_INTMAJOR); +#endif + + /* Check for an Rx (memory-to-peripheral/memory-to-memory) DMA transfer */ + + if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_PERIPH2MEM) + { + /* Invalidate caches associated with the destination DMA memory. + * REVISIT: nbytes is the number of bytes transferred on each + * minor loop. The following is only valid when the major loop + * is one. + */ + + up_invalidate_dcache((uintptr_t)config->daddr, + (uintptr_t)config->daddr + config->nbytes); + } + + /* Check for an Tx (peripheral-to-memory/memory-to-memory) DMA transfer */ + + if (dmach->ttype == EDMA_MEM2MEM || dmach->ttype == EDMA_MEM2PERIPH) + { + /* Clean caches associated with the source DMA memory. + * REVISIT: nbytes is the number of bytes transferred on each + * minor loop. The following is only valid when the major loop + * is one. + */ +#warning Missing logic + + up_clean_dcache((uintptr_t)config->saddr, + (uintptr_t)config->saddr + config->nbytes); + } + + /* Set the DMAMUX source and enable and optional trigger */ + + putreg8(dmach->dmamux, KINETIS_DMAMUX_CHCFG(dmach->chan)); + + dmach->state = KINETIS_DMA_CONFIGURED; + return OK; +} + +/**************************************************************************** + * Name: kinetis_dmach_start + * + * Description: + * Start the DMA transfer. This function should be called after the final + * call to kinetis_dmach_xfrsetup() in order to avoid race conditions. + * + * At the conclusion of each major DMA loop, a callback to the user + * provided function is made: |For "normal" DMAs, this will correspond to + * the DMA DONE interrupt; for scatter gather DMAs, multiple interrupts + * will be generated with the final being the DONE interrupt. + * + * At the conclusion of the DMA, the DMA channel is reset, all TCDs are + * freed, and the callback function is called with the the success/fail + * result of the DMA. + * + * NOTE: On Rx DMAs (peripheral-to-memory or memory-to-memory), it is + * necessary to invalidate the destination memory. That is not done + * automatically by the DMA module. Invalidation of the destination memory + * regions is the responsibility of the caller. + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * callback - The callback to be invoked when the DMA is completes or is + * aborted. + * arg - An argument that accompanies the callback + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int kinetis_dmach_start(DMACH_HANDLE handle, edma_callback_t callback, + void *arg) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; + irqstate_t flags; + uint8_t regval8; + uint8_t chan; + + DEBUGASSERT(dmach != NULL && dmach->state == KINETIS_DMA_CONFIGURED); + chan = dmach->chan; + dmainfo("dmach%u: %p callback: %p arg: %p\n", chan, dmach, callback, arg); + + /* Save the callback info. This will be invoked when the DMA completes */ + + flags = spin_lock_irqsave(NULL); + dmach->callback = callback; + dmach->arg = arg; + +#if CONFIG_KINETIS_EDMA_NTCD > 0 + /* Although it is not recommended, it might be possible to call this + * function multiple times while adding TCDs on the fly. + */ + + if (dmach->state != KINETIS_DMA_ACTIVE) +#endif + { + dmach->state = KINETIS_DMA_ACTIVE; + + /* Enable channel ERROR interrupts */ + + regval8 = EDMA_SEEI(chan); + putreg8(regval8, KINETIS_EDMA_SEEI); + + /* Enable the DMA request for this channel */ + + regval8 = EDMA_SERQ(chan); + putreg8(regval8, KINETIS_EDMA_SERQ); + } + + spin_unlock_irqrestore(NULL, flags); + return OK; +} + +/**************************************************************************** + * Name: kinetis_dmach_stop + * + * Description: + * Cancel the DMA. After kinetis_dmach_stop() is called, the DMA channel + * is reset, all TCDs are freed, and kinetis_dmarx/txsetup() must be called + * before kinetis_dmach_start() can be called again. + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void kinetis_dmach_stop(DMACH_HANDLE handle) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; + irqstate_t flags; + + dmainfo("dmach: %p\n", dmach); + DEBUGASSERT(dmach != NULL); + + flags = spin_lock_irqsave(NULL); + kinetis_dmaterminate(dmach, -EINTR); + spin_unlock_irqrestore(NULL, flags); +} + +/**************************************************************************** + * Name: kinetis_dmach_getcount + * + * Description: + * This function checks the TCD (Task Control Descriptor) status for a + * specified eDMA channel and returns the the number of major loop counts + * that have not finished. + * + * NOTES: + * 1. This function can only be used to get unfinished major loop count of + * transfer without the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly + * from registers while the channel is running. + * + * Because to calculate the remaining bytes, the initial NBYTES configured + * in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not + * support getting it while a channel is active. In another words, 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) + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * + * Returned Value: + * Major loop count which has not been transferred yet for the current TCD. + * + ****************************************************************************/ + +unsigned int kinetis_dmach_getcount(DMACH_HANDLE *handle) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; + unsigned int remaining = 0; + uintptr_t regaddr; + uint16_t regval16; + + DEBUGASSERT(dmach != NULL); + + /* If the DMA is done, then the remaining count is zero */ + + regaddr = KINETIS_EDMA_TCD_CSR(dmach->chan); + regval16 = getreg16(regaddr); + + if ((regval16 & EDMA_TCD_CSR_DONE) == 0) + { + /* Calculate the unfinished bytes */ + + regaddr = KINETIS_EDMA_TCD_CITER_ELINK(dmach->chan); + regval16 = getreg16(regaddr); + + if ((regval16 & EDMA_TCD_CITER_ELINK) != 0) + { + remaining = (regval16 & EDMA_TCD_CITER_ELINK_CITER_MASK) >> + EDMA_TCD_CITER_ELINK_CITER_SHIFT; + } + else + { + remaining = (regval16 & EDMA_TCD_CITER_CITER_MASK) >> + EDMA_TCD_CITER_CITER_SHIFT; + } + } + + return remaining; +} + +/**************************************************************************** + * Name: kinetis_dmasample + * + * Description: + * Sample DMA register contents + * + * Assumptions: + * - DMA handle allocated by kinetis_dmach_alloc() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs) +{ + struct kinetis_dmach_s *dmach = (struct kinetis_dmach_s *)handle; + uintptr_t regaddr; + unsigned int chan; + irqstate_t flags; + + DEBUGASSERT(dmach != NULL && regs != NULL); + chan = dmach->chan; + regs->chan = chan; + + /* eDMA Global Registers */ + + flags = spin_lock_irqsave(NULL); + + regs->cr = getreg32(KINETIS_EDMA_CR); /* Control */ + regs->es = getreg32(KINETIS_EDMA_ES); /* Error Status */ + regs->erq = getreg32(KINETIS_EDMA_ERQ); /* Enable Request */ + regs->req = getreg32(KINETIS_EDMA_INT); /* Interrupt Request */ + regs->err = getreg32(KINETIS_EDMA_ERR); /* Error */ + regs->hrs = getreg32(KINETIS_EDMA_HRS); /* Hardware Request Status */ + regs->ears = getreg32(KINETIS_EDMA_EARS); /* Enable Asynchronous Request in Stop */ + + /* eDMA Channel registers */ + + regaddr = KINETIS_EDMA_DCHPRI(chan); + regs->dchpri = getreg8(regaddr); /* Channel priority */ + + /* eDMA TCD */ + + base = KINETIS_EDMA_TCD_BASE(chan); + regs->saddr = getreg32(base + KINETIS_EDMA_TCD_SADDR_OFFSET); + regs->soff = getreg16(base + KINETIS_EDMA_TCD_SOFF_OFFSET); + regs->attr = getreg16(base + KINETIS_EDMA_TCD_ATTR_OFFSET); + regs->nbml = getreg32(base + KINETIS_EDMA_TCD_NBYTES_ML_OFFSET); + regs->slast = getreg32(base + KINETIS_EDMA_TCD_SLAST_OFFSET); + regs->daddr = getreg32(base + KINETIS_EDMA_TCD_DADDR_OFFSET); + regs->doff = getreg16(base + KINETIS_EDMA_TCD_DOFF_OFFSET); + regs->citer = getreg16(base + KINETIS_EDMA_TCD_CITER_ELINK_OFFSET); + regs->dlastsga = getreg32(base + KINETIS_EDMA_TCD_DLASTSGA_OFFSET); + regs->csr = getreg16(base + KINETIS_EDMA_TCD_CSR_OFFSET); + regs->biter = getreg16(base + KINETIS_EDMA_TCD_BITER_ELINK_OFFSET); + + /* DMAMUX registers */ + + regaddr = KINETIS_DMAMUX_CHCFG(chan); + regs->dmamux = getreg32(regaddr); /* Channel configuration */ + + spin_unlock_irqrestore(NULL, flags); +} +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Name: kinetis_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + * Assumptions: + * - DMA handle allocated by kinetis_dmach_alloc() + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmadump(const struct kinetis_dmaregs_s *regs, const char *msg) +{ + unsigned int chan; + + DEBUGASSERT(regs != NULL && msg != NULL); + + chan = regs->chan; + DEBUGASSERT(chan < KINETIS_EDMA_NCHANNELS); + + dmainfo("%s\n", msg); + dmainfo(" eDMA Global Registers:\n"); + dmainfo(" CR: %08x\n", regs->cr); + dmainfo(" ES: %08x\n", regs->es); + dmainfo(" ERQ: %08x\n", regs->erq); + dmainfo(" INT: %08x\n", regs->req); + dmainfo(" ERR: %08x\n", regs->err); + dmainfo(" EARS: %08x\n", regs->hrs); + + /* eDMA Channel registers */ + + dmainfo(" eDMA Channel %u Registers:\n", chan); + dmainfo(" DCHPRI: %02x\n", regs->dchpri); + + /* eDMA TCD */ + + dmainfo(" eDMA Channel %u TCD Registers:\n", chan); + dmainfo(" SADDR: %08x\n", regs->saddr); + dmainfo(" SOFF: %04x\n", regs->soff); + dmainfo(" ATTR: %04x\n", regs->attr); + dmainfo(" NBML: %05x\n", regs->nbml); + dmainfo(" SLAST: %05x\n", regs->slast); + dmainfo(" DADDR: %05x\n", regs->daddr); + dmainfo(" DOFF: %04x\n", regs->doff); + dmainfo(" CITER: %04x\n", regs->citer); + dmainfo(" DLASTSGA: %08x\n", regs->dlastsga); + dmainfo(" CSR: %04x\n", regs->csr); + dmainfo(" BITER: %04x\n", regs->biter); + + /* DMAMUX registers */ + + dmainfo(" DMAMUX Channel %u Registers:\n", chan); + dmainfo(" DMAMUX: %08x\n", regs->dmamux); +} +#endif /* CONFIG_DEBUG_DMA */ +#endif /* CONFIG_KINETIS_EDMA */ diff --git a/arch/arm/src/kinetis/kinetis_edma.h b/arch/arm/src/kinetis/kinetis_edma.h new file mode 100644 index 00000000000..72ba8383376 --- /dev/null +++ b/arch/arm/src/kinetis/kinetis_edma.h @@ -0,0 +1,455 @@ +/**************************************************************************** + * arch/arm/src/kinetis/kinetis_edma.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * This file was leveraged from the NuttX i.MXRT port. + * Portions of that eDMA logic derived from NXP sample code which has + * a compatible BSD 3-clause license: + * + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H +#define __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H + +/* General Usage: + * + * 1. Allocate a DMA channel + * + * DMACH_HANDLE handle; + * handle = edma_dmach_alloc(dmamux, dchpri); + * + * Where 'dmamux' is the channel DMAMUX configuration register setting and + * 'dchpri' is the channel DCHPRIO priority register setting. + * + * 2. Create the transfer configuration: + * + * struct kinetis_edma_xfrconfig_s config; + * config.saddr = ..; + * config.daddr = ..; + * etc. + * + * 3. Setup the transfer in hardware: + * + * int ret; + * ret = kinetis_dmach_xfrsetup(handle, &config); + * + * 4. If you are setting up a scatter gather DMA + * (with CONFIG_KINETIS_EDMA_NTCD > 0), then repeat steps 2 and 3 for + * each segment of the transfer. + * + * 5. Start the DMA: + * + * ret = kinetis_dmach_start(handle, my_callback_func, priv); + * + * Where my_callback_func() is called when the DMA completes or an error + * occurs. 'priv' represents some internal driver state that will be + * provided with the callback. + * + * 6. If you need to stop the DMA and free resources (such as if a timeout + * occurs), then: + * + * i mxrt_dmach_stop(handle); + * + * 7. The callback will be received when the DMA completes (or an error + * occurs). After that, you may free the DMA channel, or re-use it on + * subsequent DMAs. + * + * kinetis_dmach_free(handle); + * + * Almost non-invasive debug instrumentation is available. You may call + * kinetis_dmasample() to save the current state of the eDMA registers at + * any given point in time. At some later, postmortem analysis, you can + * dump the content of the buffered registers with kinetis_dmadump(). + * kinetis_dmasample() is also available for monitoring DMA progress. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include "hardware/kinetis_edma.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration flags. + * + * REVISIT: Many missing options that should be represented as flags: + * 1. Bandwidth + * 2. Source/Destination modulo + */ + +#define EDMA_CONFIG_LINKTYPE_SHIFT (0) /* Bits 0-1: Link type */ +#define EDMA_CONFIG_LINKTYPE_MASK (3 << EDMA_CONFIG_LINKTYPE_SHIFT) +# define EDMA_CONFIG_LINKTYPE_LINKNONE (0 << EDMA_CONFIG_LINKTYPE_SHIFT) /* No channel link */ +# define EDMA_CONFIG_LINKTYPE_MINORLINK (1 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link after each minor loop */ +# define EDMA_CONFIG_LINKTYPE_MAJORLINK (2 << EDMA_CONFIG_LINKTYPE_SHIFT) /* Channel link when major loop count exhausted */ + +#define EDMA_CONFIG_LOOP_SHIFT (2) /* Bits 2: Loop type */ +#define EDMA_CONFIG_LOOP_MASK (3 << EDMA_CONFIG_LOOP_SHIFT) +# define EDMA_CONFIG_LOOPNONE (0 << EDMA_CONFIG_LOOP_SHIFT) /* No looping */ +# define EDMA_CONFIG_LOOPSRC (1 << EDMA_CONFIG_LOOP_SHIFT) /* Source looping */ +# define EDMA_CONFIG_LOOPDEST (2 << EDMA_CONFIG_LOOP_SHIFT) /* Dest looping */ + +#define EDMA_CONFIG_INTHALF (1 << 3) /* Bits 3: Int on HALF */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +typedef FAR void *DMACH_HANDLE; +typedef void (*edma_callback_t)(DMACH_HANDLE handle, + void *arg, bool done, int result); + +/* eDMA transfer type */ + +enum kinetis_edma_xfrtype_e +{ + EDMA_MEM2MEM = 0, /* Transfer from memory to memory */ + EDMA_PERIPH2MEM, /* Transfer from peripheral to memory */ + EDMA_MEM2PERIPH, /* Transfer from memory to peripheral */ +}; + +/* eDMA transfer sises */ + +enum kinetis_edma_sizes_e +{ + EDMA_8BIT = 0, /* Transfer data size 8 */ + EDMA_16BIT = 1, /* Transfer data size 16 */ + EDMA_32BIT = 2, /* Transfer data size 32 */ +}; + +/* This structure holds the source/destination transfer attribute + * configuration. + */ + +struct kinetis_edma_xfrconfig_s +{ + uint32_t saddr; /* Source data address. */ + uint32_t daddr; /* Destination data address. */ + int16_t soff; /* Sign-extended offset for current source address. */ + int16_t doff; /* Sign-extended offset for current destination address. */ + uint16_t iter; /* Major loop iteration count. */ + uint8_t flags; /* See EDMA_CONFIG_* definitions */ + uint8_t ssize; /* Source data transfer size (see TCD_ATTR_SIZE_* definitions in rdware/. */ + uint8_t dsize; /* Destination data transfer size. */ + uint8_t ttype; /* Transfer type (see enum kinetis_edma_xfrtype_e). */ +#ifdef CONFIG_KINETIS_EDMA_EMLIM + uint16_t nbytes; /* Bytes to transfer in a minor loop */ +#else + uint32_t nbytes; /* Bytes to transfer in a minor loop */ +#endif +#ifdef CONFIG_KINETIS_EDMA_ELINK + DMACH_HANDLE linkch; /* Link channel (With EDMA_CONFIG_LINKTYPE_* flags) */ +#endif +}; + +/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA + * is selected + */ + +#ifdef CONFIG_DEBUG_DMA +struct kinetis_dmaregs_s +{ + uint8_t chan; /* Sampled channel */ + + /* eDMA Global Registers */ + + uint32_t cr; /* Control */ + uint32_t es; /* Error Status */ + uint32_t erq; /* Enable Request */ + uint32_t req; /* Interrupt Request */ + uint32_t err; /* Error */ + uint32_t hrs; /* Hardware Request Status */ + uint32_t ears; /* Enable Asynchronous Request in Stop */ + + /* eDMA Channel registers */ + + uint8_t dchpri; /* Channel priority */ + + /* eDMA TCD */ + + uint32_t saddr; /* TCD Source Address */ + uint16_t soff; /* TCD Signed Source Address Offset */ + uint16_t attr; /* TCD Transfer Attributes */ + uint32_t nbml; /* TCD Signed Minor Loop Offset / Byte Count */ + uint32_t slast; /* TCD Last Source Address Adjustment */ + uint32_t daddr; /* TCD Destination Address */ + uint16_t doff; /* TCD Signed Destination Address Offset */ + uint16_t citer; /* TCD Current Minor Loop Link, Major Loop Count */ + uint32_t dlastsga; /* TCD Last Destination Address Adjustment/Scatter Gather Address */ + uint16_t csr; /* TCD Control and Status */ + uint16_t biter; /* TCD Beginning Minor Loop Link, Major Loop Count */ + + /* DMAMUX registers */ + + uint32_t dmamux; /* Channel configuration */ +}; +#endif /* CONFIG_DEBUG_DMA */ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: kinetis_dmach_alloc + * + * Allocate a DMA channel. This function sets aside a DMA channel, + * initializes the DMAMUX for the channel, then gives the caller exclusive + * access to the DMA channel. + * + * Input Parameters: + * dmamux - DMAMUX configuration see DMAMUX channel configuration register + * bit-field definitions in hardware/kinetis_dmamux.h. + * Settings include: + * + * DMAMUX_CHCFG_SOURCE Chip-specific DMA source (required) + * DMAMUX_CHCFG_TRIG DMA Channel Trigger Enable (optional) + * DMAMUX_CHCFG_ENBL DMA Mux Channel Enable (required) + * + * A value of zero will disable the DMAMUX channel. + * dchpri - DCHPRI channel priority configuration. See DCHPRI channel + * configuration register bit-field definitions in + * hardware/kinetis_edma.h. Meaningful settings include: + * + * EDMA_DCHPRI_CHPRI Channel Arbitration Priority + * DCHPRI_DPA Disable Preempt Ability + * DCHPRI_ECP Enable Channel Preemption + * + * The power-on default, 0x05, is a reasonable choice. + * + * Returned Value: + * If a DMA channel is available, this function returns a non-NULL, void* + * DMA channel handle. NULL is returned on any failure. + * + ****************************************************************************/ + +DMACH_HANDLE kinetis_dmach_alloc(uint8_t dmamux, uint8_t dchpri); + +/**************************************************************************** + * Name: kinetis_dmach_free + * + * Description: + * Release a DMA channel. + * NOTE: The 'handle' used in this argument must NEVER be used again + * until kinetis_dmach_alloc() is called again to re-gain a valid handle. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void kinetis_dmach_free(DMACH_HANDLE handle); + +/**************************************************************************** + * Name: kinetis_dmach_xfrsetup + * + * Description: + * This function adds the eDMA transfer to the DMA sequence. The request + * is setup according to the content of the transfer configuration + * structure. For "normal" DMA, kinetis_dmach_xfrsetup is called only + * once. + * Scatter/gather DMA is accomplished by calling this function repeatedly, + * once for each transfer in the sequence. Scatter/gather DMA processing + * is enabled automatically when the second transfer configuration is + * received. + * + * This function may be called multiple times to handle multiple, + * discontinuous transfers (scatter-gather) + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * config - A DMA transfer configuration instance, populated by the + * The content of 'config' describes the transfer + * + * Returned Value + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int kinetis_dmach_xfrsetup(DMACH_HANDLE *handle, + const struct kinetis_edma_xfrconfig_s *config); + +/**************************************************************************** + * Name: kinetis_dmach_start + * + * Description: + * Start the DMA transfer by enabling the channel DMA request. + * This function should be called after the final call to + * kinetis_dmasetup() in order to avoid race conditions. + * + * At the conclusion of each major DMA loop, a callback to the + * user-provided function is made: |For "normal" DMAs, this will + * correspond to the DMA DONE interrupt; for scatter gather DMAs, multiple + * interrupts will be generated with the final being the DONE interrupt. + * + * At the conclusion of the DMA, the DMA channel is reset, all TCDs are + * freed, and the callback function is called with the the success/fail + * result of the DMA. + * + * NOTE: + * On Rx DMAs (peripheral-to-memory or memory-to-memory), it is necessary + * to invalidate the destination memory. That is not done automatically + * by the DMA module. Invalidation of the destination memory regions is + * the responsibility of the caller. + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * callback - The callback to be invoked when the DMA is completes or is + * aborted. + * arg - An argument that accompanies the callback + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure. + * + ****************************************************************************/ + +int kinetis_dmach_start(DMACH_HANDLE handle, + edma_callback_t callback, void *arg); + +/**************************************************************************** + * Name: kinetis_dmach_stop + * + * Description: + * Cancel the DMA. After kinetis_dmach_stop() is called, the DMA channel + * is reset, all TCDs are freed, and kinetis_dmarx/txsetup() must be called + * before kinetis_dmach_start() can be called again + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void kinetis_dmach_stop(DMACH_HANDLE handle); + +/**************************************************************************** + * Name: kinetis_dmach_getcount + * + * Description: + * This function checks the TCD (Task Control Descriptor) status for a + * specified eDMA channel and returns the the number of major loop counts + * that have not finished. + * + * NOTES: + * 1. This function can only be used to get unfinished major loop count of + * transfer without the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly + * from registers while the channel is running. + * + * Because to calculate the remaining bytes, the initial NBYTES configured + * in DMA_TCDn_NBYTES_MLNO register is needed while the eDMA IP does not + * support getting it while a channel is active. In another words, 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) + * + * Input Parameters: + * handle - DMA channel handle created by kinetis_dmach_alloc() + * + * Returned Value: + * Major loop count which has not been transferred yet for the current TCD. + * + ****************************************************************************/ + +unsigned int kinetis_dmach_getcount(DMACH_HANDLE *handle); + +/**************************************************************************** + * Name: kinetis_dmasample + * + * Description: + * Sample DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmasample(DMACH_HANDLE handle, struct kinetis_dmaregs_s *regs); +#else +# define kinetis_dmasample(handle,regs) +#endif + +/**************************************************************************** + * Name: kinetis_dmadump + * + * Description: + * Dump previously sampled DMA register contents + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_DMA +void kinetis_dmadump(const struct kinetis_dmaregs_s *regs, const char *msg); +#else +# define kinetis_dmadump(handle,regs,msg) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_KINETIS_KINETIS_EDMAC_H */