text: /****************************************************************************************
   * arch/arm/src/sam34/hardware/sam_dmac.h
   * DMA Controller (DMAC) definitions for the SAM3U, SAM3X, SAM3A, and SAM4E
   *
   *   Copyright (C) 2009-2010, 2013-2014 Gregory Nutt. All rights reserved.
   *   Author: Gregory Nutt <gnutt@nuttx.org>
   *
   * 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_SAM34_HARDWARE_SAM_DMAC_H
  #define __ARCH_ARM_SRC_SAM34_HARDWARE_SAM_DMAC_H
  
  /****************************************************************************************
   * Included Files
   ****************************************************************************************/
  
  #include <nuttx/config.h>
  
  #include "chip.h"
  #include "hardware/sam_memorymap.h"
  
  /****************************************************************************************
   * Pre-processor Definitions
   ****************************************************************************************/
  
  /* DMAC register offsets ****************************************************************/
  
  /* Global Registers */
  
  #define SAM_DMAC_GCFG_OFFSET           0x0000 /* DMAC Global Configuration Register */
  #define SAM_DMAC_EN_OFFSET             0x0004 /* DMAC Enable Register */
  #define SAM_DMAC_SREQ_OFFSET           0x0008 /* DMAC Software Single Request Register */
  #define SAM_DMAC_CREQ_OFFSET           0x000c /* DMAC Software Chunk Transfer Request Register */
  #define SAM_DMAC_LAST_OFFSET           0x0010 /* DMAC Software Last Transfer Flag Register */
                                                /* 0x014: Reserved */
  #define SAM_DMAC_EBCIER_OFFSET         0x0018 /* DMAC Error Enable */
  #define SAM_DMAC_EBCIDR_OFFSET         0x001C /* DMAC Error Disable */
  #define SAM_DMAC_EBCIMR_OFFSET         0x0020 /* DMAC Error Mask */
  #define SAM_DMAC_EBCISR_OFFSET         0x0024 /* DMAC Error Status */
  #define SAM_DMAC_CHER_OFFSET           0x0028 /* DMAC Channel Handler Enable Register */
  #define SAM_DMAC_CHDR_OFFSET           0x002c /* DMAC Channel Handler Disable Register */
  #define SAM_DMAC_CHSR_OFFSET           0x0030 /* DMAC Channel Handler Status Register */
                                                /* 0x034-0x38: Reserved */
  /* DMA channel registers */
  
  #define SAM_DMACHAN_OFFSET(n)          (0x003c+((n)*0x28))
  #define SAM_DMACHAN0_OFFSET            0x003c /* 0x003c-0x0060: Channel 0 */
  #define SAM_DMACHAN1_OFFSET            0x0064 /* 0x0064-0x0088: Channel 1 */
  #define SAM_DMACHAN2_OFFSET            0x008c /* 0x008c-0x00b0: Channel 2 */
  #define SAM_DMACHAN3_OFFSET            0x00b4 /* 0x00b4-0x00d8: Channel 3 */
  #define SAM_DMACHAN4_OFFSET            0x00dc /* 0x00dc-0x0103: Channel 4 */
  #define SAM_DMACHAN5_OFFSET            0x0104 /* 0x0104-0x0128: Channel 5 */
  
  #define SAM_DMACHAN_SADDR_OFFSET       0x0000 /* DMAC Channel Source Address Register */
  #define SAM_DMACHAN_DADDR_OFFSET       0x0004 /* DMAC Channel Destination Address Register */
  #define SAM_DMACHAN_DSCR_OFFSET        0x0008 /* DMAC Channel Descriptor Address Register */
  #define SAM_DMACHAN_CTRLA_OFFSET       0x000c /* DMAC Channel Control A Register */
  #define SAM_DMACHAN_CTRLB_OFFSET       0x0010 /* DMAC Channel Control B Register */
  #define SAM_DMACHAN_CFG_OFFSET         0x0014 /* DMAC Channel Configuration Register */
                                              /* 0x18-0x24: Reserved */
  
  /* More Global Registers */
  
  #if defined(CONFIG_ARCH_CHIP_SAM4E)
  #  define SAM_DMAC_WPMR_OFFSET         0x01e4 /* DMAC Write Protect Mode Register  */
  #  define SAM_DMAC_WPSR_OFFSET         0x01e8 /* DMAC Write Protect Status Register DMAC_WPSR */
  #endif
  
  /* DMAC register addresses **************************************************************/
  
  /* Global Registers */
  
  #define SAM_DMAC_GCFG                  (SAM_DMAC_BASE+SAM_DMAC_GCFG_OFFSET)
  #define SAM_DMAC_EN                    (SAM_DMAC_BASE+SAM_DMAC_EN_OFFSET)
  #define SAM_DMAC_SREQ                  (SAM_DMAC_BASE+SAM_DMAC_SREQ_OFFSET)
  #define SAM_DMAC_CREQ                  (SAM_DMAC_BASE+SAM_DMAC_CREQ_OFFSET)
  #define SAM_DMAC_LAST                  (SAM_DMAC_BASE+SAM_DMAC_LAST_OFFSET)
  #define SAM_DMAC_EBCIER                (SAM_DMAC_BASE+SAM_DMAC_EBCIER_OFFSET)
  #define SAM_DMAC_EBCIDR                (SAM_DMAC_BASE+SAM_DMAC_EBCIDR_OFFSET)
  #define SAM_DMAC_EBCIMR                (SAM_DMAC_BASE+SAM_DMAC_EBCIMR_OFFSET)
  #define SAM_DMAC_EBCISR                (SAM_DMAC_BASE+SAM_DMAC_EBCISR_OFFSET)
  #define SAM_DMAC_CHER                  (SAM_DMAC_BASE+SAM_DMAC_CHER_OFFSET)
  #define SAM_DMAC_CHDR                  (SAM_DMAC_BASE+SAM_DMAC_CHDR_OFFSET)
  #define SAM_DMAC_CHSR                  (SAM_DMAC_BASE+SAM_DMAC_CHSR_OFFSET)
  
  /* DMA channel registers */
  
  #define SAM_DMACHAN_BASE(n)            (SAM_DMAC_BASE+SAM_DMACHAN_OFFSET(n))
  #define SAM_DMACHAN0_BASE              (SAM_DMAC_BASE+SAM_DMACHAN0_OFFSET)
  #define SAM_DMACHAN1_BASE              (SAM_DMAC_BASE+SAM_DMACHAN1_OFFSET)
  #define SAM_DMACHAN2_BASE              (SAM_DMAC_BASE+SAM_DMACHAN2_OFFSET)
  #define SAM_DMACHAN3_BASE              (SAM_DMAC_BASE+SAM_DMACHAN3_OFFSET)
  #define SAM_DMACHAN4_BASE              (SAM_DMAC_BASE+SAM_DMACHAN4_OFFSET)
  #define SAM_DMACHAN5_BASE              (SAM_DMAC_BASE+SAM_DMACHAN5_OFFSET)
  
  #define SAM_DMACHAN_SADDR(n)           (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_SADDR_OFFSET)
  #define SAM_DMACHAN_DADDR(n)           (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DADDR_OFFSET)
  #define SAM_DMACHAN_DSCR(n)            (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_DSCR_OFFSET)
  #define SAM_DMACHAN_CTRLA(n)           (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CTRLA_OFFSET)
  #define SAM_DMACHAN_CTRLB(n)           (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CTRLB_OFFSET)
  #define SAM_DMACHAN_CFG(n)             (SAM_DMACHAN_BASE(n)+SAM_DMACHAN_CFG_OFFSET)
  
  #define SAM_DMACHAN0_SADDR             (SAM_DMACHAN0_BASE+SAM_DMACHAN_SADDR_OFFSET)
  #define SAM_DMACHAN0_DADDR             (SAM_DMACHAN0_BASE+SAM_DMACHAN_DADDR_OFFSET)
  #define SAM_DMACHAN0_DSCR              (SAM_DMACHAN0_BASE+SAM_DMACHAN_DSCR_OFFSET)
  #define SAM_DMACHAN0_CTRLA             (SAM_DMACHAN0_BASE+SAM_DMACHAN_CTRLA_OFFSET)
  #define SAM_DMACHAN0_CTRLB             (SAM_DMACHAN0_BASE+SAM_DMACHAN_CTRLB_OFFSET)
  #define SAM_DMACHAN0_CFG               (SAM_DMACHAN0_BASE+SAM_DMACHAN_CFG_OFFSET)
  
  #define SAM_DMACHAN1_SADDR             (SAM_DMACHAN1_BASE+SAM_DMACHAN_SADDR_OFFSET)
  #define SAM_DMACHAN1_DADDR             (SAM_DMACHAN1_BASE+SAM_DMACHAN_DADDR_OFFSET)
  #define SAM_DMACHAN1_DSCR              (SAM_DMACHAN1_BASE+SAM_DMACHAN_DSCR_OFFSET)
  #define SAM_DMACHAN1_CTRLA             (SAM_DMACHAN1_BASE+SAM_DMACHAN_CTRLA_OFFSET)
  #define SAM_DMACHAN1_CTRLB             (SAM_DMACHAN1_BASE+SAM_DMACHAN_CTRLB_OFFSET)
  #define SAM_DMACHAN1_CFG               (SAM_DMACHAN1_BASE+SAM_DMACHAN_CFG_OFFSET)
  
  #define SAM_DMACHAN2_SADDR             (SAM_DMACHAN2_BASE+SAM_DMACHAN_SADDR_OFFSET)
  #define SAM_DMACHAN2_DADDR             (SAM_DMACHAN2_BASE+SAM_DMACHAN_DADDR_OFFSET)
  #define SAM_DMACHAN2_DSCR              (SAM_DMACHAN2_BASE+SAM_DMACHAN_DSCR_OFFSET)
  #define SAM_DMACHAN2_CTRLA             (SAM_DMACHAN2_BASE+SAM_DMACHAN_CTRLA_OFFSET)
  #define SAM_DMACHAN2_CTRLB             (SAM_DMACHAN2_BASE+SAM_DMACHAN_CTRLB_OFFSET)
  #define SAM_DMACHAN2_CFG               (SAM_DMACHAN2_BASE+SAM_DMACHAN_CFG_OFFSET)
  
  #define SAM_DMACHAN3_SADDR             (SAM_DMACHAN3_BASE+SAM_DMACHAN_SADDR_OFFSET)
  #define SAM_DMACHAN3_DADDR             (SAM_DMACHAN3_BASE+SAM_DMACHAN_DADDR_OFFSET)
  #define SAM_DMACHAN3_DSCR              (SAM_DMACHAN3_BASE+SAM_DMACHAN_DSCR_OFFSET)
  #define SAM_DMACHAN3_CTRLA             (SAM_DMACHAN3_BASE+SAM_DMACHAN_CTRLA_OFFSET)
  #define SAM_DMACHAN3_CTRLB             (SAM_DMACHAN3_BASE+SAM_DMACHAN_CTRLB_OFFSET)
  #define SAM_DMACHAN3_CFG               (SAM_DMACHAN3_BASE+SAM_DMACHAN_CFG_OFFSET)
  
  /* More Global Registers */
  
  #if defined(CONFIG_ARCH_CHIP_SAM4E)
  #  define SAM_DMAC_WPMR                  (SAM_DMAC_BASE+SAM_DMAC_WPMR_OFFSET)
  #  define SAM_DMAC_WPSR                  (SAM_DMAC_BASE+SAM_DMAC_WPSR_OFFSET)
  #endif
  
  /* DMAC register bit definitions ********************************************************/
  
  /* Global Registers */
  
  /* DMAC Global Configuration Register */
  
  #define DMAC_GCFG_ARB_CFG              (1 << 4)  /* Bit 4:  Round robin (vs fixed) arbiter */
  
  /* DMAC Enable Register */
  
  #define DMAC_EN_ENABLE                 (1 << 0)  /* Bit 0:  DMA controller enable */
  
  /* DMAC Software Single Request Register */
  
  #define DMAC_SREQ_SHIFT(n)             ((n)<<1)
  #define DMAC_SREQ_MASK(n)              (3 << DMAC_SREQ_SHIFT(n))
  #  define DMAC_SREQ0_SHIFT             (0)      /* Bits 0-1:  Channel 0 */
  #  define DMAC_SREQ0_MASK              (3 << DMAC_SREQ0_SHIFT)
  #  define DMAC_SREQ1_SHIFT             (2)      /* Bits 2-3:  Channel 1 */
  #  define DMAC_SREQ1_MASK              (3 << DMAC_SREQ1_SHIFT)
  #  define DMAC_SREQ2_SHIFT             (4)      /* Bits 4-5:  Channel 2 */
  #  define DMAC_SREQ2_MASK              (3 << DMAC_SREQ2_SHIFT)
  #  define DMAC_SREQ3_SHIFT             (6)      /* Bits 6-7:  Channel 3 */
  #  define DMAC_SREQ3_MASK              (3 << DMAC_SREQ3_SHIFT)
  
  #define DMAC_SREQ_SSREQ_SHIFT          (0)      /* Bits 0, 2, 4, 6:   Request a source single transfer */
  #  define DMAC_SREQ_SSREQ(n)           (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ_SHIFT(n)))
  #  define DMAC_SREQ_SSREQ0             (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ0_SHIFT)
  #  define DMAC_SREQ_SSREQ1             (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ1_SHIFT)
  #  define DMAC_SREQ_SSREQ2             (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ2_SHIFT)
  #  define DMAC_SREQ_SSREQ3             (1 << (DMAC_SREQ_SSREQ_SHIFT+DMAC_SREQ3_SHIFT)
  #define DMAC_SREQ_DSREQ_SHIFT          (1)      /* Bits 1, 3, 5, 7:   Request a destination single transfer */
  #  define DMAC_SREQ_DSREQ(n)           (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ_SHIFT(n))))
  #  define DMAC_SREQ_DSREQ0             (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ0_SHIFT)
  #  define DMAC_SREQ_DSREQ1             (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ1_SHIFT)
  #  define DMAC_SREQ_DSREQ2             (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ2_SHIFT)
  #  define DMAC_SREQ_DSREQ3             (1 << (DMAC_SREQ_DSREQ_SHIFT+DMAC_SREQ3_SHIFT)
  
  /* DMAC Software Chunk Transfer Request Register */
  
  #define DMAC_CREQ_SHIFT(n)             ((n)<<1)
  #define DMAC_CREQ_MASK(n)              (3 << DMAC_CREQ_SHIFT(n))
  #  define DMAC_CREQ0_SHIFT             (0)      /* Bits 0-1:  Channel 0 */
  #  define DMAC_CREQ0_MASK              (3 << DMAC_CREQ0_SHIFT)
  #  define DMAC_CREQ1_SHIFT             (2)      /* Bits 2-3:  Channel 1 */
  #  define DMAC_CREQ1_MASK              (3 << DMAC_CREQ1_SHIFT)
  #  define DMAC_CREQ2_SHIFT             (4)      /* Bits 4-5:  Channel 2 */
  #  define DMAC_CREQ2_MASK              (3 << DMAC_CREQ2_SHIFT)
  #  define DMAC_CREQ3_SHIFT             (6)      /* Bits 6-7:  Channel 3 */
  #  define DMAC_CREQ3_MASK              (3 << DMAC_CREQ3_SHIFT)
  
  #define DMAC_CREQ_SCREQ_SHIFT          (0)      /* Bits 0, 2, 4, 6:   Request a source chunk transfer */
  #  define DMAC_CREQ_SCREQ(n)           (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ_SHIFT(n)))
  #  define DMAC_CREQ_SCREQ0             (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ0_SHIFT))
  #  define DMAC_CREQ_SCREQ1             (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ1_SHIFT))
  #  define DMAC_CREQ_SCREQ2             (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ2_SHIFT))
  #  define DMAC_CREQ_SCREQ3             (1 << (DMAC_CREQ_SCREQ_SHIFT+DMAC_CREQ3_SHIFT))
  #define DMAC_CREQ_DCREQ_SHIFT          (1)      /* Bits 1, 3, 5, 7:   Request a destination chunk transfer */
  #  define DMAC_CREQ_DCREQ(n)           (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ_SHIFT(n)))
  #  define DMAC_CREQ_DCREQ0             (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ0_SHIFT))
  #  define DMAC_CREQ_DCREQ1             (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ1_SHIFT))
  #  define DMAC_CREQ_DCREQ2             (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ2_SHIFT))
  #  define DMAC_CREQ_DCREQ3             (1 << (DMAC_CREQ_DCREQ_SHIFT+DMAC_CREQ3_SHIFT))
  
  /* DMAC Software Last Transfer Flag Register */
  
  #define DMAC_LAST_SHIFT(n)             ((n)<<1)
  #define DMAC_LAST_MASK(n)              (3 << DMAC_LAST_SHIFT(n))
  #  define DMAC_LAST0_SHIFT             (0)      /* Bits 0-1:  Channel 0 */
  #  define DMAC_LAST0_MASK              (3 << DMAC_LAST0_SHIFT)
  #  define DMAC_LAST1_SHIFT             (2)      /* Bits 2-3:  Channel 1 */
  #  define DMAC_LAST1_MASK              (3 << DMAC_LAST1_SHIFT)
  #  define DMAC_LAST2_SHIFT             (4)      /* Bits 4-5:  Channel 2 */
  #  define DMAC_LAST2_MASK              (3 << DMAC_LAST2_SHIFT)
  #  define DMAC_LAST3_SHIFT             (6)      /* Bits 6-7:  Channel 3 */
  #  define DMAC_LAST3_MASK              (3 << DMAC_LAST3_SHIFT)
  
  #define DMAC_LAST_SLAST_SHIFT          (0)      /* Bits 0, 2, 4, 6:   Indicates the last transfer */
  #  define DMAC_LAST_SLAST(n)           (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST_SHIFT(n)))
  #  define DMAC_LAST_SLAST0             (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST0_SHIFT)
  #  define DMAC_LAST_SLAST1             (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST1_SHIFT)
  #  define DMAC_LAST_SLAST2             (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST2_SHIFT)
  #  define DMAC_LAST_SLAST3             (1 << (DMAC_LAST_SLAST_SHIFT+DMAC_LAST3_SHIFT)
  #define DMAC_LAST_DLAST_SHIFT          (1)      /* Bits 1, 3, 5, 7:   Indicates the last transfer */
  #  define DMAC_LAST_DLAST(n)           (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST_SHIFT(n))))
  #  define DMAC_LAST_DLAST0             (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST0_SHIFT)
  #  define DMAC_LAST_DLAST1             (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST1_SHIFT)
  #  define DMAC_LAST_DLAST2             (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST2_SHIFT)
  #  define DMAC_LAST_DLAST3             (1 << (DMAC_LAST_DLAST_SHIFT+DMAC_LAST3_SHIFT)
  
  /* DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Enable Register,
   * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Disable Register,
   * DMAC Error, Buffer Transfer and Chained Buffer Transfer Interrupt Mask Register, and
   * DMAC Error, Buffer Transfer and Chained Buffer Transfer Status Register common
   * bit field definitions
   */
  
  #define DMAC_EBC_BTC_SHIFT             (0)       /* Bits 0-3:  Buffer Transfer Completed Interrupt Enable  */
  #define DMAC_EBC_BTC_MASK              (15 << DMAC_EBC_BTC_SHIFT)
  #  define DMAC_EBC_BTC(n)              (1 << (DMAC_EBC_BTC_SHIFT+(n)))
  #  define DMAC_EBC_BTC0                (1 << (DMAC_EBC_BTC_SHIFT+0))
  #  define DMAC_EBC_BTC1                (1 << (DMAC_EBC_BTC_SHIFT+1))
  #  define DMAC_EBC_BTC2                (1 << (DMAC_EBC_BTC_SHIFT+2))
  #  define DMAC_EBC_BTC3                (1 << (DMAC_EBC_BTC_SHIFT+3))
  #define DMAC_EBC_CBTC_SHIFT            (8)       /* Bits 8-11:  Chained Buffer Transfer Completed Interrupt Enable */
  #define DMAC_EBC_CBTC_MASK             (15 << DMAC_EBC_CBTC_SHIFT)
  #  define DMAC_EBC_CBTC(n)             (1 << (DMAC_EBC_CBTC_SHIFT+(n)))
  #  define DMAC_EBC_CBTC0               (1 << (DMAC_EBC_CBTC_SHIFT+0))
  #  define DMAC_EBC_CBTC1               (1 << (DMAC_EBC_CBTC_SHIFT+1))
  #  define DMAC_EBC_CBTC2               (1 << (DMAC_EBC_CBTC_SHIFT+2))
  #  define DMAC_EBC_CBTC3               (1 << (DMAC_EBC_CBTC_SHIFT+3))
  #define DMAC_EBC_ERR_SHIFT             (16)      /* Bits 16-19:  Access Error Interrupt Enable */
  #define DMAC_EBC_ERR_MASK              (15 << DMAC_EBC_ERR_SHIFT)
  #  define DMAC_EBC_ERR(n)              (1 << (DMAC_EBC_ERR_SHIFT+(n)))
  #  define DMAC_EBC_ERR0                (1 << (DMAC_EBC_ERR_SHIFT+0))
  #  define DMAC_EBC_ERR1                (1 << (DMAC_EBC_ERR_SHIFT+1))
  #  define DMAC_EBC_ERR2                (1 << (DMAC_EBC_ERR_SHIFT+2))
  #  define DMAC_EBC_ERR3                (1 << (DMAC_EBC_ERR_SHIFT+3))
  
  #define DMAC_EBC_BTCINTS(n)            (0x00010001 << (n))  /* BTC + ERR interrupts */
  #define DMAC_EBC_CBTCINTS(n)           (0x00010100 << (n))  /* CBT + ERR interrupts */
  #define DMAC_EBC_CHANINTS(n)           (0x00010101 << (n))  /* All channel interrupts */
  #define DMAC_EBC_ALLINTS               (0x000f0f0f)         /* All interrupts */
  
  /* DMAC Channel Handler Enable Register */
  
  #define DMAC_CHER_ENA_SHIFT            (0)       /* Bits 0-3:  Enable channel  */
  #define DMAC_CHER_ENA_MASK             (15 << DMAC_CHER_ENA_SHIFT)
  #  define DMAC_CHER_ENA(n)             (1 << (DMAC_CHER_ENA_SHIFT+(n)))
  #  define DMAC_CHER_ENA0               (1 << (DMAC_CHER_ENA_SHIFT+0))
  #  define DMAC_CHER_ENA1               (1 << (DMAC_CHER_ENA_SHIFT+1))
  #  define DMAC_CHER_ENA2               (1 << (DMAC_CHER_ENA_SHIFT+2))
  #  define DMAC_CHER_ENA3               (1 << (DMAC_CHER_ENA_SHIFT+3))
  #define DMAC_CHER_SUSP_SHIFT           (8)       /* Bits 8-11: Freeze channel and its context */
  #define DMAC_CHER_SUSP_MASK            (15 << DMAC_CHER_SUSP_SHIFT)
  #  define DMAC_CHER_SUSP(n)            (1 << (DMAC_CHER_SUSP_SHIFT+(n)))
  #  define DMAC_CHER_SUSP0              (1 << (DMAC_CHER_SUSP_SHIFT+0))
  #  define DMAC_CHER_SUSP1              (1 << (DMAC_CHER_SUSP_SHIFT+1))
  #  define DMAC_CHER_SUSP2              (1 << (DMAC_CHER_SUSP_SHIFT+2))
  #  define DMAC_CHER_SUSP3              (1 << (DMAC_CHER_SUSP_SHIFT+3))
  #define DMAC_CHER_KEEP_SHIFT           (24)      /* Bits 24-27:  Resume channel from automatic stall */
  #define DMAC_CHER_KEEP_MASK            (15 << DMAC_CHER_KEEP_SHIFT)
  #  define DMAC_CHER_KEEP(n)            (1 << (DMAC_CHER_KEEP_SHIFT+(n)))
  #  define DMAC_CHER_KEEP0              (1 << (DMAC_CHER_KEEP_SHIFT+0))
  #  define DMAC_CHER_KEEP1              (1 << (DMAC_CHER_KEEP_SHIFT+1))
  #  define DMAC_CHER_KEEP2              (1 << (DMAC_CHER_KEEP_SHIFT+2))
  #  define DMAC_CHER_KEEP3              (1 << (DMAC_CHER_KEEP_SHIFT+3))
  
  /* DMAC Channel Handler Disable Register */
  
  #define DMAC_CHDR_DIS_SHIFT            (0)       /* Bits 0-3:  Disable DMAC channel  */
  #define DMAC_CHDR_DIS_MASK             (15 << DMAC_CHDR_DIS_SHIFT)
  #  define DMAC_CHDR_DIS(n)             (1 << (DMAC_CHDR_DIS_SHIFT+(n)))
  #  define DMAC_CHDR_DIS0               (1 << (DMAC_CHDR_DIS_SHIFT+0))
  #  define DMAC_CHDR_DIS1               (1 << (DMAC_CHDR_DIS_SHIFT+1))
  #  define DMAC_CHDR_DIS2               (1 << (DMAC_CHDR_DIS_SHIFT+2))
  #  define DMAC_CHDR_DIS3               (1 << (DMAC_CHDR_DIS_SHIFT+3))
  #  define DMAC_CHDR_DIS_ALL            DMAC_CHDR_DIS_MASK
  #define DMAC_CHDR_RES_SHIFT            (8)       /* Bits 8-11:  Resume trasnfer, restoring context */
  #define DMAC_CHDR_RES_MASK             (15 << DMAC_CHDR_RES_SHIFT)
  #  define DMAC_CHDR_RES(n)             (1 << (DMAC_CHDR_RES_SHIFT+(n)))
  #  define DMAC_CHDR_RES0               (1 << (DMAC_CHDR_RES_SHIFT+0))
  #  define DMAC_CHDR_RES1               (1 << (DMAC_CHDR_RES_SHIFT+1))
  #  define DMAC_CHDR_RES2               (1 << (DMAC_CHDR_RES_SHIFT+2))
  #  define DMAC_CHDR_RES3               (1 << (DMAC_CHDR_RES_SHIFT+3))
  
  /* DMAC Channel Handler Status Register */
  
  #define DMAC_CHSR_ENA_SHIFT            (0)       /* Bits 0-3:  Indicates that the channel is stalling  */
  #define DMAC_CHSR_ENA_MASK             (15 << DMAC_CHSR_ENA_SHIFT)
  #  define DMAC_CHSR_ENA(n)             (1 << (DMAC_CHSR_ENA_SHIFT+(n)))
  #  define DMAC_CHSR_ENA0               (1 << (DMAC_CHSR_ENA_SHIFT+0))
  #  define DMAC_CHSR_ENA1               (1 << (DMAC_CHSR_ENA_SHIFT+1))
  #  define DMAC_CHSR_ENA2               (1 << (DMAC_CHSR_ENA_SHIFT+2))
  #  define DMAC_CHSR_ENA3               (1 << (DMAC_CHSR_ENA_SHIFT+3))
  #define DMAC_CHSR_SUSP_SHIFT           (8)       /* Bits 8-11:  Indicates that the channel is empty */
  #define DMAC_CHSR_SUSP_MASK            (15 << DMAC_CHSR_SUSP_SHIFT)
  #  define DMAC_CHSR_SUSP(n)            (1 << (DMAC_CHSR_SUSP_SHIFT+(n)))
  #  define DMAC_CHSR_SUSP0              (1 << (DMAC_CHSR_SUSP_SHIFT+0))
  #  define DMAC_CHSR_SUSP1              (1 << (DMAC_CHSR_SUSP_SHIFT+1))
  #  define DMAC_CHSR_SUSP2              (1 << (DMAC_CHSR_SUSP_SHIFT+2))
  #  define DMAC_CHSR_SUSP3              (1 << (DMAC_CHSR_SUSP_SHIFT+3))
  #define DMAC_CHSR_EMPT_SHIFT           (16)      /* Bits 16-19:  Access Error Interrupt Enable */
  #define DMAC_CHSR_EMPT_MASK            (15 << DMAC_CHSR_EMPT_SHIFT)
  #  define DMAC_CHSR_EMPT(n)            (1 << (DMAC_CHSR_EMPT_SHIFT+(n)))
  #  define DMAC_CHSR_EMPT0              (1 << (DMAC_CHSR_EMPT_SHIFT+0))
  #  define DMAC_CHSR_EMPT1              (1 << (DMAC_CHSR_EMPT_SHIFT+1))
  #  define DMAC_CHSR_EMPT2              (1 << (DMAC_CHSR_EMPT_SHIFT+2))
  #  define DMAC_CHSR_EMPT3              (1 << (DMAC_CHSR_EMPT_SHIFT+3))
  #define DMAC_CHSR_STAL_SHIFT           (24)      /* Bits 24-27:  Access Error Interrupt Enable */
  #define DMAC_CHSR_STAL_MASK            (15 << DMAC_CHSR_STAL_SHIFT)
  #  define DMAC_CHSR_STAL(n)            (1 << (DMAC_CHSR_STAL_SHIFT+(n)))
  #  define DMAC_CHSR_STAL0              (1 << (DMAC_CHSR_STAL_SHIFT+0))
  #  define DMAC_CHSR_STAL1              (1 << (DMAC_CHSR_STAL_SHIFT+1))
  #  define DMAC_CHSR_STAL2              (1 << (DMAC_CHSR_STAL_SHIFT+2))
  #  define DMAC_CHSR_STAL3              (1 << (DMAC_CHSR_STAL_SHIFT+3))
  
  /* DMA channel registers */
  /* DMAC Channel n [n = 0..3] Source Address Register -- 32-bit address*/
  /* DMAC Channel n [n = 0..3] Destination Address Register -- 32-bit address*/
  /* DMAC Channel n [n = 0..3] Descriptor Address Register -- 32-bit address*/
  /* DMAC Channel n [n = 0..3] Control A Register */
  
  #if defined(CONFIG_ARCH_CHIP_SAM3U) ||  defined(CONFIG_ARCH_CHIP_SAM3X) || \
      defined(CONFIG_ARCH_CHIP_SAM3A)
  #  define DMACHAN_CTRLA_BTSIZE_MAX     (0xfff)
  #  define DMACHAN_CTRLA_BTSIZE_SHIFT   (0)       /* Bits 0-11: Buffer Transfer Size */
  #  define DMACHAN_CTRLA_BTSIZE_MASK    (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
  #    define DMACHAN_CTRLA_BTSIZE(n)    ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT)
  #elif defined(CONFIG_ARCH_CHIP_SAM3X) ||  defined(CONFIG_ARCH_CHIP_SAM3A) || \
      defined(CONFIG_ARCH_CHIP_SAM4E)
  #  define DMACHAN_CTRLA_BTSIZE_MAX     (0xffff)
  #  define DMACHAN_CTRLA_BTSIZE_SHIFT   (0)       /* Bits 0-15: Buffer Transfer Size */
  #  define DMACHAN_CTRLA_BTSIZE_MASK    (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
  #    define DMACHAN_CTRLA_BTSIZE(n)    ((uint32_t)(n) << DMACHAN_CTRLA_BTSIZE_SHIFT)
  #endif
  
  #if defined(CONFIG_ARCH_CHIP_SAM3U) ||  defined(CONFIG_ARCH_CHIP_SAM3X) || \
      defined(CONFIG_ARCH_CHIP_SAM3A)
  #  define DMACHAN_CTRLA_SCSIZE         (1 << 16) /* Bit 16: Source Chunk Transfer Size */
  #    define DMACHAN_CTRLA_SCSIZE_1     (0)
  #    define DMACHAN_CTRLA_SCSIZE_4     DMACHAN_CTRLA_SCSIZE
  #  define DMACHAN_CTRLA_DCSIZE         (1 << 20) /* Bit 20:  Destination Chunk Transfer size */
  #    define DMACHAN_CTRLA_DCSIZE_1     (0)
  #    define DMACHAN_CTRLA_DCSIZE_4     DMACHAN_CTRLA_DCSIZE
  #endif
  
  #define DMACHAN_CTRLA_SRCWIDTH_SHIFT   (24)      /* Bits 24-25 */
  #define DMACHAN_CTRLA_SRCWIDTH_MASK    (3 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_SRCWIDTH_BYTE  (0 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_SRCWIDTH_HWORD (1 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_SRCWIDTH_WORD  (2 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
  #define DMACHAN_CTRLA_DSTWIDTH_SHIFT   (28)      /* Bits 28-29 */
  #define DMACHAN_CTRLA_DSTWIDTH_MASK    (3 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_DSTWIDTH_BYTE  (0 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_DSTWIDTH_HWORD (1 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
  #  define DMACHAN_CTRLA_DSTWIDTH_WORD  (2 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
  #define DMACHAN_CTRLA_DONE             (1 << 31) /* Bit 31: Auto disable DMAC */
  
  /* DMAC Channel n [n = 0..3] Control B Register */
  
  #define DMACHAN_CTRLB_SRCDSCR          (1 << 16) /* Bit 16: Source buffer descriptor fetch operation disabled */
  #define DMACHAN_CTRLB_DSTDSCR          (1 << 20) /* Bit 20: Dest buffer descriptor fetch operation disabled */
  #define DMACHAN_CTRLB_FC_SHIFT         (21)      /* Bits 21-22:  Flow controller  */
  #define DMACHAN_CTRLB_FC_MASK          (3 << DMACHAN_CTRLB_FC_SHIFT)
  #  define DMACHAN_CTRLB_FC_M2M         (0 << DMACHAN_CTRLB_FC_SHIFT) /* Memory-to-Memory  */
  #  define DMACHAN_CTRLB_FC_M2P         (1 << DMACHAN_CTRLB_FC_SHIFT) /* Memory-to-Peripheral */
  #  define DMACHAN_CTRLB_FC_P2M         (2 << DMACHAN_CTRLB_FC_SHIFT) /* Peripheral-to-Memory  */
  #  define DMACHAN_CTRLB_FC_P2P         (3 << DMACHAN_CTRLB_FC_SHIFT) /* Peripheral-to-Peripheral */
  #define DMACHAN_CTRLB_SRCINCR_SHIFT    (24)      /* Bits 24-25 */
  #define DMACHAN_CTRLB_SRCINCR_MASK     (3 << DMACHAN_CTRLB_SRCINCR_SHIFT)
  #  define DMACHAN_CTRLB_SRCINCR_INCR   (0 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Incrementing address */
  #  if defined(CONFIG_ARCH_CHIP_SAM4E)
  #    define DMACHAN_CTRLB_SRCINCR_DECR (1 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Decrementing address */
  #  endif
  #  define DMACHAN_CTRLB_SRCINCR_FIXED  (2 << DMACHAN_CTRLB_SRCINCR_SHIFT) /* Fixed address */
  #define DMACHAN_CTRLB_DSTINCR_SHIFT    (28)      /* Bits 28-29 */
  #define DMACHAN_CTRLB_DSTINCR_MASK     (3 << DMACHAN_CTRLB_DSTINCR_SHIFT)
  #  define DMACHAN_CTRLB_DSTINCR_INCR   (0 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Incrementing address */
  #  if defined(CONFIG_ARCH_CHIP_SAM4E)
  #    define DMACHAN_CTRLB_DSTINCR_DECR (1 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Decrementing address */
  #  endif
  #  define DMACHAN_CTRLB_DSTINCR_FIXED  (2 << DMACHAN_CTRLB_DSTINCR_SHIFT) /* Fixed address */
  #define DMACHAN_CTRLB_IEN              (1 << 30)  /* Bit 30:  Clear sets BTC[n] flag in EBCISR */
  
  /* DMAC Channel n [n = 0..3] Configuration Register */
  
  #define DMACHAN_CFG_SRCPER_SHIFT       (0)       /* Bits 0-3:  Channel source associated with peripheral ID */
  #define DMACHAN_CFG_SRCPER_MASK        (15 << DMACHAN_CFG_SRCPER_SHIFT)
  #define DMACHAN_CFG_DSTPER_SHIFT       (4)       /* Bits 4-7:  Channel dest associated with peripheral ID */
  #define DMACHAN_CFG_DSTPER_MASK        (15 << DMACHAN_CFG_DSTPER_SHIFT)
  #define DMACHAN_CFG_SRCH2SEL           (1 << 9)  /* Bit 9:  HW handshake triggers transfer */
  #define DMACHAN_CFG_DSTH2SEL           (1 << 13) /* Bit 13: HW handshake trigger transfer */
  #define DMACHAN_CFG_SOD                (1 << 16) /* Bit 16: Stop on done */
  #define DMACHAN_CFG_LOCKIF             (1 << 20) /* Bit 20: Enable lock interface capability */
  #define DMACHAN_CFG_LOCKB              (1 << 21) /* Bit 21: Enable AHB Bus Locking capability */
  #define DMACHAN_CFG_LOCKIFL            (1 << 22) /* Bit 22: Lock Master Interface Arbiter */
  #define DMACHAN_CFG_AHBPROT_SHIFT      (24)      /* Bits 24-26: Bus access privilege */
  #define DMACHAN_CFG_AHBPROT_MASK       (7 << DMACHAN_CFG_AHBPROT_SHIFT)
  #  define DMACHAN_CFG_AHBPROT_PRIV     (1 << DMACHAN_CFG_AHBPROT_SHIFT)
  #  define DMACHAN_CFG_AHBPROT_BUFF     (2 << DMACHAN_CFG_AHBPROT_SHIFT)
  #  define DMACHAN_CFG_AHBPROT_CACHE    (4 << DMACHAN_CFG_AHBPROT_SHIFT)
  #define DMACHAN_CFG_FIFOCFG_SHIFT      (28)      /* Bits 28-29 */
  #define DMACHAN_CFG_FIFOCFG_MASK       (3 << DMACHAN_CFG_FIFOCFG_SHIFT)
  #  define DMACHAN_CFG_FIFOCFG_LARGEST  (0 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Largest length AHB burst */
  #  define DMACHAN_CFG_FIFOCFG_HALF     (1 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Half FIFO size */
  #  define DMACHAN_CFG_FIFOCFG_SINGLE   (2 << DMACHAN_CFG_FIFOCFG_SHIFT) /* Single AHB access */
  
  /* More Global Registers */
  
  /* DMAC Write Protect Mode Register  */
  
  #if defined(CONFIG_ARCH_CHIP_SAM4E)
  #  define DMAC_WPMR_WPEN           (1 << 0)  /* Bit 0:  Write Protect Enable */
  #  define DMAC_WPMR_WPKEY_SHIFT    (8)       /* Bits 8-31: Write Protect KEY */
  #  define DMAC_WPMR_WPKEY_MASK     (0x00ffffff << DMAC_WPMR_WPKEY_SHIFT)
  #    define DMAC_WPMR_WPKEY        (0x00444d41 << DMAC_WPMR_WPKEY_SHIFT)
  #endif
  
  /* DMAC Write Protect Status Register DMAC_WPSR */
  
  #if defined(CONFIG_ARCH_CHIP_SAM4E)
  #  define DMAC_WPSR_WPVS           (1 << 0)  /* Bit 0:  Write Protect Violation Status */
  #  define DMAC_WPSR_WPVSRC_SHIFT   (8)       /* Bits 8-23: Write Protect Violation Source */
  #  define DMAC_WPSR_WPVSRC_MASK    (0xffff << DMAC_WPSR_WPVSRC_SHIFT)
  #endif
  
  /* DMA Hardware interface numbers *******************************************************/
  
  #if defined(CONFIG_ARCH_CHIP_SAM3U)
  
  #  define DMACHAN_INTF_HSMCI0          0
  #  define DMACHAN_INTF_SPI0TX          1         /* SPI0 Transmit */
  #  define DMACHAN_INTF_SPI0RX          2         /* SPI0 Receive */
  #  define DMACHAN_INTF_SSC0TX          3         /* SSC0 Transmit */
  #  define DMACHAN_INTF_SSC0RX          4         /* SSC0 Receive */
  #  define DMACHAN_INTF_PWM0EV0         5         /* PWM0 Event Line 0 */
  #  define DMACHAN_INTF_PWM0EV1         6         /* PWM0 Event Line 1 */
  #  define DMACHAN_INTF_TIO0            7         /* TIO Output of TC Ch. 0 */
  
  #elif defined(CONFIG_ARCH_CHIP_SAM3X) || defined(CONFIG_ARCH_CHIP_SAM3A)
  
  #  define DMACHAN_INTF_HSMCI0          0         /* HSMCI0 Transmit/Receive */
  #  define DMACHAN_INTF_SPI0TX          1         /* SPI0 Transmit */
  #  define DMACHAN_INTF_SPI0RX          2         /* SPI0 Receive */
  #  define DMACHAN_INTF_SSC0TX          3         /* SSC0 Transmit */
  #  define DMACHAN_INTF_SSC0RX          4         /* SSC0 Receive */
  #  define DMACHAN_INTF_SPI1TX          5         /* SPI1 Transmit */
  #  define DMACHAN_INTF_SPI1RX          6         /* SPI1 Receive */
  #  define DMACHAN_INTF_USART0TX        11        /* USART0 Transmit */
  #  define DMACHAN_INTF_USART0RX        12        /* USART0 Receive */
  #  define DMACHAN_INTF_USART1TX        13        /* USART1 Transmit */
  #  define DMACHAN_INTF_USART1RX        14        /* USART1 Receive */
  #  define DMACHAN_INTF_PWM0TX          15        /* PWM0 Transmit */
  
  #elif defined(CONFIG_ARCH_CHIP_SAM4E)
  
  #  define DMACHAN_INTF_HSMCI0          0         /* HSMCI Transmit/Receive */
  #  define DMACHAN_INTF_SPI0TX          1         /* SPI Transmit */
  #  define DMACHAN_INTF_SPI0RX          2         /* SPI Receive */
  #  define DMACHAN_INTF_USART0TX        3         /* USART0 Transmit */
  #  define DMACHAN_INTF_USART0RX        4         /* USART0 Receive */
  #  define DMACHAN_INTF_USART1TX        5         /* USART1 Transmit */
  #  define DMACHAN_INTF_USART1RX        6         /* USART1 Receive */
  #  define DMACHAN_INTF_AESTX           11        /* AES Transmit */
  #  define DMACHAN_INTF_AESRX           12        /* AES Receive */
  #  define DMACHAN_INTF_PWM0TX          13        /* PWM0 Transmit */
  
  #endif
  
  /****************************************************************************************
   * Public Types
   ****************************************************************************************/
  
  /* DMA multi buffer transfer link list entry structure */
  
  struct dma_linklist_s
  {
    uint32_t src;    /* Source address */
    uint32_t dest;   /* Destination address */
    uint32_t ctrla;  /* Control A value */
    uint32_t ctrlb;  /* Control B value */
    uint32_t next;   /* Next descriptor address */
  };
  
  /****************************************************************************************
   * Public Data
   ****************************************************************************************/
  
  /****************************************************************************************
   * Public Functions
   ****************************************************************************************/
  
  #endif /* __ARCH_ARM_SRC_SAM34_HARDWARE_SAM_DMAC_H */
  