/**
 * \file
 *
 * \brief DMACA Register Definitions
 *
 * - Compiler:           IAR EWAVR32 and GNU GCC for AVR32
 * - Supported devices:  All devices
 * - AppNote:
 *
 * \author               Atmel Corporation: http://www.atmel.com \n
 *                       Support and FAQ: http://support.atmel.no/
 *
 * \page License
 *
 * 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. The name of Atmel may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an
 * Atmel AVR product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL 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 DMACA_REGS_H_INCLUDED
#define DMACA_REGS_H_INCLUDED

/** \name DMACA Channel Registers */
//@{
#define DMACA_CHAN_SAR		0x0000	//!< Source Address
#define DMACA_CHAN_DAR		0x0008	//!< Destination Address
#define DMACA_CHAN_LLP		0x0010	//!< Linked List Pointer
# define DMACA_LLP_LMS(x)		((x) <<  0)	//!< List Master Select
#define DMACA_CHAN_CTLL		0x0018	//!< Control Register Low
# define DMACA_CTLL_INT_EN		(  1 <<  0)	//!< Interrupt Enable
# define DMACA_CTLL_DST_TR_WIDTH(x)	((x) <<  1)	//!< Dest Xfer Width
# define DMACA_CTLL_SRC_TR_WIDTH(x)	((x) <<  4)	//!< Src Xfer Width
# define DMACA_CTLL_DINC_INCREMENT	(  0 <<  7)	//!< Increment Dest
# define DMACA_CTLL_DINC_DECREMENT	(  1 <<  7)	//!< Decrement Dest
# define DMACA_CTLL_DINC_NO_CHANGE	(  2 <<  7)	//!< Dest Unchanged
# define DMACA_CTLL_SINC_INCREMENT	(  0 <<  9)	//!< Increment Src
# define DMACA_CTLL_SINC_DECREMENT	(  1 <<  9)	//!< Decrement Src
# define DMACA_CTLL_SINC_NO_CHANGE	(  2 <<  9)	//!< Src Unchanged
# define DMACA_CTLL_DST_MSIZE(x)	((x) << 11)	//!< Dest Burst Len
# define DMACA_CTLL_SRC_MSIZE(x)	((x) << 14)	//!< Src Burst Len
# define DMACA_CTLL_TT_M2M		(  0 << 20)	//!< Mem-to-Mem
# define DMACA_CTLL_TT_M2P		(  1 << 20)	//!< Mem-to-Periph
# define DMACA_CTLL_TT_P2M		(  2 << 20)	//!< Periph-to-Mem
# define DMACA_CTLL_TT_P2P		(  3 << 20)	//!< Periph-to-Periph
# define DMACA_CTLL_DMS(x)		((x) << 23)	//!< Dest Master
# define DMACA_CTLL_SMS(x)		((x) << 25)	//!< Src Master
# define DMACA_CTLL_LLP_D_EN		(  1 << 27)	//!< Dest Block Chain
# define DMACA_CTLL_LLP_S_EN		(  1 << 28)	//!< Src Block Chain
#define DMACA_CHAN_CTLH		0x001c	//!< Control Register High
# define DMACA_CTLH_BLOCK_TS(x)		((x) <<  0)	//!< Block Xfer Size
#define DMACA_CHAN_CFGL		0x0040	//!< Configuration Register Low
# define DMACA_CFGL_CH_PRIOR(x)		((x) <<  5)	//!< Chan Priority
# define DMACA_CH_SUSP			(  1 <<  8)	//!< Chan Suspend
# define DMACA_FIFO_EMPTY		(  1 <<  9)	//!< FIFO is empty
#define DMACA_CHAN_CFGH		0x0044	//!< Configuration Register High
# define DMACA_CFGH_FCMODE		(  1 <<  0)	//!< Flow Ctrl Mode
# define DMACA_CFGH_FIFO_MODE		(  1 <<  1)	//!< FIFO Mode
# define DMACA_CFGH_SRC_PER(x)		((x) <<  7)	//!< Src Peripheral
# define DMACA_CFGH_DST_PER(x)		((x) << 11)	//!< Dest Peripheral
//@}

/** Size of each channel register block in bytes */
#define DMACA_CHAN_REGS_SIZE	0x0058

/** \name DMACA Global Registers */
//@{
#define DMACA_RAW_TFR		0x02c0	//!< Raw Transfer Complete Status
#define DMACA_RAW_BLOCK		0x02c8	//!< Raw Block Complete Status
#define DMACA_RAW_SRC_TRAN	0x02d0	//!< Raw Src Transaction Status
#define DMACA_RAW_DST_TRAN	0x02d8	//!< Raw Dst Transaction Status
#define DMACA_RAW_ERR		0x02e0	//!< Raw Error Status
#define DMACA_STATUS_TFR	0x02e8	//!< Transfer Complete Status
#define DMACA_STATUS_BLOCK	0x02f0	//!< Block Complete Status
#define DMACA_STATUS_SRC_TRAN	0x02f8	//!< Src Transaction Status
#define DMACA_STATUS_DST_TRAN	0x0300	//!< Dst Transaction Status
#define DMACA_STATUS_ERR	0x0308	//!< Error Status
#define DMACA_MASK_TFR		0x0310	//!< Transfer Complete Mask
#define DMACA_MASK_BLOCK	0x0318	//!< Block Complete Mask
#define DMACA_MASK_SRC_TRAN	0x0320	//!< Src Transaction Mask
#define DMACA_MASK_DST_TRAN	0x0328	//!< Dst Transaction Mask
#define DMACA_MASK_ERR		0x0330	//!< Error Mask
#define DMACA_CLEAR_TFR		0x0338	//!< Transfer Complete Clear
#define DMACA_CLEAR_BLOCK	0x0340	//!< Block Complete Clear
#define DMACA_CLEAR_SRC_TRAN	0x0348	//!< Src Transaction Clear
#define DMACA_CLEAR_DST_TRAN	0x0350	//!< Dst Transaction Clear
#define DMACA_CLEAR_ERR		0x0358	//!< Error Clear
#define DMACA_STATUS_INT	0x0360	//!< Interrupt Status
#define DMACA_DMACFG		0x0398	//!< DMA Configuration
# define DMACA_DMACFG_DMA_EN		(  1 <<  0)	//!< Controller Enable
#define DMACA_CH_EN		0x03a0	//!< Channel Enable
//@}

/** \brief DMACA Hardware Descriptor */
struct dmaca_hw_desc {
	uint32_t	sar;	//!< Source Address
	uint32_t	dar;	//!< Destination Address
	uint32_t	llp;	//!< Linked List Pointer
	uint32_t	ctll;	//!< Control Low
	uint32_t	ctlh;	//!< Control High
};

/**
 * \brief Read the DMACA global register \a reg.
 */
#define dmaca_read_reg(reg)					\
	mmio_read32((void *)(DMACA_BASE + DMACA_##reg))
/**
 * \brief Write \a value to the DMACA global register \a reg.
 */
#define dmaca_write_reg(reg, value)				\
	mmio_write32((void *)(DMACA_BASE + DMACA_##reg), value)

/**
 * \brief Read the value of \a reg in the channel registers of \a chan.
 */
#define dmaca_chan_read_reg(chan, reg)				\
	mmio_read32(chan->regs + DMACA_CHAN_##reg)
/**
 * \brief Write \a value to \a reg in the channel registers of \a chan.
 */
#define dmaca_chan_write_reg(chan, reg, value)			\
	mmio_write32(chan->regs + DMACA_CHAN_##reg, value)

/**
 * \brief Set the bit corresponding to \a chan in the channel bitmap
 * register \a reg.
 */
#define dmaca_set_chan_bit(chan, reg)				\
	dmaca_write_reg(reg, (chan->mask << 8) | chan->mask)
/**
 * \brief Clear the bit corresponding to \a chan in the channel bitmap
 * register \a reg.
 */
#define dmaca_clear_chan_bit(chan, reg)				\
	dmaca_write_reg(reg, chan->mask << 8)
/**
 * \brief Return nonzero if the bit corresponding to \a chan is set in
 * the channel bitmap register \a reg.
 */
#define dmaca_test_chan_bit(chan, reg)				\
	(dmaca_read_reg(reg) & chan->mask)

#endif /* DMACA_REGS_H_INCLUDED */
