/*********************************************************************
 *
 *                  DMA API definitions
 *
 *********************************************************************
 * FileName:        Dma.h
 * Dependencies:	p32xxxx.h
 * 					int.h
 *
 * Processor:       PIC32
 *
 * Complier:        MPLAB C32
 *                  MPLAB IDE
 * Company:         Microchip Technology Inc.
 *
 * Software License Agreement
 *
 * The software supplied herewith by Microchip Technology Incorporated
 * (the Company) for its PIC32/PIC24F Microcontroller is intended
 * and supplied to you, the Companys customer, for use solely and
 * exclusively on Microchip PIC32/PIC24F Microcontroller products.
 * The software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN AS IS CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *
 * $Id: Dma.h,v 1.9 2007/01/17 21:35:46 C12878 Exp $
 * $Name:  $
 *
 ********************************************************************/

#ifndef _DMA_H_
#define _DMA_H_

#include <p32xxxx.h>
#include <peripheral/int.h>


// DMA definitions

#ifdef _DMAC0
	#define _DMA_CHANNELS		// DMA channels exist


// existent DMA channels
	enum
	{
		DMA_CHANNEL0,
	#ifdef _DMAC1
		DMA_CHANNEL1,
	#ifdef _DMAC2
		DMA_CHANNEL2,
	#ifdef _DMAC3
		DMA_CHANNEL3,
	#endif	// _DMAC3
	#endif	// _DMAC2
	#endif	// _DMAC1
		//	add/remove DMA channel as needed here

		DMA_CHANNELS	// number of current available channels
	};


	// Relative Dma channels priority, between each other
	typedef enum
	{
		DMA_CHN_PRI0,
		DMA_CHN_PRI1,
		DMA_CHN_PRI2,
		DMA_CHN_PRI3
	}DmaChannelPri;



	// high level definitions for the API functions

	typedef enum
	{
		DMA_OPEN_DEFAULT = 0,							// DAM default operation
		DMA_OPEN_AUTO	= _DCH0CON_CHAEN_MASK,					// DMA channel is auto enabled
		DMA_OPEN_CHAIN_LOW  = (_DCH0CON_CHCHN_MASK|_DCH0CON_CHCHNS_MASK),	// DMA channel is chained to lower channel
		DMA_OPEN_CHAIN_HI  = (_DCH0CON_CHCHN_MASK),				// DMA channel is chained to higher channel
		DMA_OPEN_DET_EN = _DCH0CON_CHAED_MASK,					// events detection enabled while channel off
		DMA_OPEN_ENABLE = _DCH0CON_CHEN_MASK,					// DMA channel is enabled after open
		DMA_OPEN_MATCH	= 0x80000000,						// DMA channel stops on match
	}DmaOpenFlags;	// flags for the channel configuration


	typedef enum
	{
		DMA_EV_ERR =			0x1,		// address error event
		DMA_EV_ABORT = 			0x2,		// transfer abort event
		DMA_EV_CELL_DONE =		0x4,		// cell transfer complete event
		DMA_EV_BLOCK_DONE =		0x8,		// block transfer complete event
		DMA_EV_DST_HALF =		0x10,		// destination half event
		DMA_EV_DST_FULL =		0x20,		// destination full event
		DMA_EV_SRC_HALF =		0x40,		// source half event
		DMA_EV_SRC_FULL =		0x80,		// source full event

		DMA_EV_ALL_EVNTS=		(DMA_EV_ERR|DMA_EV_ABORT|DMA_EV_CELL_DONE|DMA_EV_BLOCK_DONE|DMA_EV_DST_HALF|
									DMA_EV_DST_FULL|DMA_EV_SRC_HALF|DMA_EV_SRC_FULL)				// all available events
	}DmaEvFlags;	// flags for controlling the DMA channel events; Bit fields from the processor header file.


	typedef enum
	{
		DMA_TXFER_OK,			// the transfer was performed successfully
		DMA_TXFER_ADD_ERR,		// address error while performing the transfer
		DMA_TXFER_ABORT,		// the DMA transfer was aborted
		DMA_TXFER_BC_ERR,		// block complete not set after the DMA transfer performed
		DMA_TXFER_CC_ERR,		// cell complete not set after the DMA transfer performed
		DMA_TXFER_TMO			// DMA transfer timeout
	}DmaTxferRes;		// DMA transfer result

	typedef enum
	{
		DMA_WAIT_NOT,		// don't wait for the transfer to complete, return immediately
		DMA_WAIT_CELL,		// wait for the cell transfer to complete, than return
		DMA_WAIT_BLOCK		// wait for the block transfer to complete, than return
	}DmaWaitMode;		// DMA transfer wait mode


	/*********************************************************************
	 * Function:        void DmaChnOpen(int chn, DmaChannelPri chPri, DmaOpenFlags oFlags)
	 *
	 * PreCondition:    chPri	- valid channel priority, 0-3
	 *
	 * Input:			chn		- channel to be configured in the DMA controller
	 * 					chPri	- the priority given to the channel, 0-3
	 * 					oFlags	- orred flags specifying the open mode:
	 * 					                DMA_OPEN_DEFAULT: DMA default operation mode
	 * 							DMA_OPEN_AUTO:	DMA channel is auto enabled
	 * 							DMA_OPEN_CHAIN_LOW: DMA channel is chained to lower channel
	 * 							DMA_OPEN_CHAIN_HI: DMA channel is chained to higher channel
	 * 							DMA_OPEN_DET_EN: events detection enabled while channel off
	 * 							DMA_OPEN_ENABLE: DMA channel is enabled when opened
	 * 							DMA_OPEN_MATCH:	DMA channel stops on match
	 *
	 *
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function opens and configures the selected DMA channel using the supplied user flags and priority.
	 *
	 * Note:            - This is a high level access function that doesn't give access to all the settings possible for a DMA channel.
	 * 					Use the low level functions to address special settings.
	 * 					- After calling this function, the channel should be enabled using DmaChnEnable(chn) call
	 * 					if DMA_OPEN_ENABLE flag was not specified.
	 *					- If the CRC is attached to the submitted channel, the CRC append mode will be turned off.
	 * 						This way, the transfer will occur correctly together with CRC calculation.
	 * 					- The start and abort Irqs will be disabled and the channel event enable flags are disabled.
	* 						User has to call event channel functions to enable the event flags if needed.
	 *
	 * Example:			DmaChnOpen(3, DMA_CHN_PRI2, DMA_OPEN_AUTO|DMA_OPEN_MATCH|DMA_OPEN_ENABLE);
	 ********************************************************************/
	 void			DmaChnOpen(int chn, DmaChannelPri chPri, DmaOpenFlags oFlags);

	/*********************************************************************
	 * Function:        void DmaChnEnable(int chn)
	 *
	 * PreCondition:    None
	 *
	 * Input:			chn		- channel to be enabled
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function enables a previously configured DMA channel.
	 *
	 * Note:            DmaChnOpen() should have been called before.
	 *
	 * Example:			DmaChnEnable(3);
	 ********************************************************************/
	 void			DmaChnEnable(int chn);

	/*********************************************************************
	 * Function:        void DmaChnDisable(int chn)
	 *
	 * PreCondition:    None
	 *
	 * Input:			chn		- selected channel in the DMA controller
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function disables a DMA channel. The channel operation stops.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnDisable(3);
	 ********************************************************************/
	 void			DmaChnDisable(int chn);

	/*********************************************************************
	 * Function:        void DmaChnSetTxfer(int chn, const void* vSrcAdd, void* vDstAdd, int srcSize, int dstSize, int cellSize)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 								- vSrcAdd: source of the DMA transfer
	 * 								- vDstAdd: destination of the DMA transfer
	 * 								- srcSize: source buffer size, 1 to DmaGetMaxTxferSize() bytes, wrapped arround
	 * 								- dstSize: destination buffer size, 1 to DmaGetMaxTxferSize() bytes, wrapped around
	 * 								- cellSize: cell transfer size, 1 to DmaGetMaxTxferSize() bytes.
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the transfer characteristics for a DMA channel transfer:
	 * 					the source and the destination addresses.
	 * 					the source and destination lengths
	 * 					and the number of bytes	transferred per event.
	 *
	 * Note:			The function clears the existing DMA channel event flags.
	 *
	 * Example:			DmaChnSetTxfer(3, &U2RXREG, dstBuff, 1, 200, 1);
	 ********************************************************************/
	 void			DmaChnSetTxfer(int chn, const void* vSrcAdd, void* vDstAdd, int srcSize, int dstSize, int cellSize);


	/*********************************************************************
	 * Function:        void DmaChnSetSrcAdd(int chn, const void* vSrcAdd)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 *
	 * Input:           chn		- DMA channel number
	 * 				- vSrcAdd: source (virtual) of the DMA transfer
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        The function is a helper to set directly the transfer source address.
	 *
	 * Note:            None.
	 *
	 * Example:         DmaChnSetSrcAdd(2, srcBuff+sizeof(srcBuff));
	 ********************************************************************/
	 void			DmaChnSetSrcAdd(int chn, const void* vSrcAdd);

	/*********************************************************************
	 * Function:        void DmaChnSetDstAdd(int chn, void* vDstAdd)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 								- vDstAdd: destination (virtual) of the DMA transfer
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function is a helper to set directly the transfer destination address.
	 *
	 * Note:            None
	 *
	 * Example:         DmaChnSetDstAdd(2, dstBuff+sizeof(dstBuff));
	 ********************************************************************/
	 void			DmaChnSetDstAdd(int chn, void* vDstAdd);

	/*********************************************************************
	 * Function:        void DmaChnSetMatchPattern(int chn, int pattern)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					pattern	-  the match pattern
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the curent match pattern for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnSetMatchPattern(3, '\r');
	 ********************************************************************/
	 void			DmaChnSetMatchPattern(int chn, int pattern);

	/*********************************************************************
	 * Function:        int DmaChnGetMatchPattern(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          The channel match pattern.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the curent match pattern for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int pattern=DmaChnGetMatchPattern(3);
	 ********************************************************************/
	 int			DmaChnGetMatchPattern(int chn);

	/*********************************************************************
	 * Function:        DmaTxferRes DmaChnStartTxfer(int chn, DmaWaitMode wMode, unsigned long retries)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					wMode	- if DMA_WAIT_NOT, return immediately
	 * 							- if DMA_WAIT_CELL, return after the cell transfer complete
	 * 							- if DMA_WAIT_BLOCK, return after the whole transfer is done
	 * 					retries	- retry counter: if transfer not complete after so many retries, return with tmo.
	 * 								If 0, wait forever.
	 *
	 * Output:          DMA_TXFER_OK if not waiting for the transfer completion or if the transfer ended normally,
	 * 					an DmaTxferRes error code  otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function initiates (forces) a DMA transfer for the selected DMA channel.
	 * 					The DMA channel is enabled.
	 * 					If waiting for the transfer completion needed (user doesn't use an ISR to catch
	 * 					this event) the function will periodically query the DMA controller for the
	 * 					transfer completion status.
	 *
	 * Note:            None
	 *
	 * Example:         DmaChnStartTxfer(3, DMA_WAIT_BLOCK, 0);
	 ********************************************************************/
	 DmaTxferRes DmaChnStartTxfer(int chn, DmaWaitMode wMode, unsigned long retries);

	/*********************************************************************
	 * Function:        void DmaChnForceTxfer(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function forces a DMA transfer to occur for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnForceTxfer(3);
	 ********************************************************************/
	 void			DmaChnForceTxfer(int chn);

	/*********************************************************************
	 * Function:        void DmaChnAbortTxfer(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function aborts a current undergoing DMA transfer for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnAbortTxfer(3);
	 ********************************************************************/
	 void			DmaChnAbortTxfer(int chn);

	// High level channel event and interrupt control functions

	/*********************************************************************
	 * Function:        void DmaChnSetEvEnableFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the event enable flags for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					enabled for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnSetEvEnableFlags(3, DMA_EV_ERR|DMA_EV_ABORT|DMA_EV_BLOCK_DONE|DMA_EV_SRC_FULL);
	 ********************************************************************/
	 void			DmaChnSetEvEnableFlags(int chn, DmaEvFlags eFlags);

	/*********************************************************************
	 * Function:        void DmaChnClrEvEnableFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function clears the event enable flags for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					disabled for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnClrEvEnableFlags(3, DMA_EV_ERR|DMA_EV_ABORT|DMA_EV_BLOCK_DONE|DMA_EV_SRC_FULL);
	 ********************************************************************/
	 void			DmaChnClrEvEnableFlags(int chn, DmaEvFlags eFlags);

	/*********************************************************************
	 * Function:        void DmaChnWriteEvEnableFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the event enable flags for the selected DMA channel.
	 * 					The channel event flags are forced to the eFlags value.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnWriteEvEnableFlags(3, DMA_EV_ALL_EVNTS);
	 ********************************************************************/
	 void			DmaChnWriteEvEnableFlags(int chn, DmaEvFlags eFlags);

	/*********************************************************************
	 * Function:        DmaEvFlags DmaChnGetEvEnableFlags(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          - event flags with the following significance:
	 * 						- DMA_EV_ERR: address error event
	 * 						- DMA_EV_ABORT: transfer abort event
	 * 						- DMA_EV_CELL_DONE: cell transfer complete event
	 * 						- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 						- DMA_EV_DST_HALF: destination half event
	 * 						- DMA_EV_DST_FULL: destination full event
	 * 						- DMA_EV_SRC_HALF: source half event
	 * 						- DMA_EV_SRC_FULL: source full event
	 *						- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the event enabled flags for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaEvFlags enabledFlags=DmaChnGetEvEnableFlags(3);
	 ********************************************************************/
	 DmaEvFlags	DmaChnGetEvEnableFlags(int chn);

	/*********************************************************************
	 * Function:        void DmaChnClrEvFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function clears the event flags for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					cleared for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaChnClrEvFlags(3, DMA_EV_ALL_EVNTS);
	 ********************************************************************/
	 void			DmaChnClrEvFlags(int chn, DmaEvFlags eFlags);

	/*********************************************************************
	 * Function:        DmaEvFlags DmaChnGetEvFlags(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          event flags with the following significance:
	 * 						- DMA_EV_ERR: address error event
	 * 						- DMA_EV_ABORT: transfer abort event
	 * 						- DMA_EV_CELL_DONE: cell transfer complete event
	 * 						- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 						- DMA_EV_DST_HALF: destination half event
	 * 						- DMA_EV_DST_FULL: destination full event
	 * 						- DMA_EV_SRC_HALF: source half event
	 * 						- DMA_EV_SRC_FULL: source full event
	 * 						- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the event flags for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaEvFlags intSetFlags=DmaChnGetEvFlags(3);
	 ********************************************************************/
	 DmaEvFlags	DmaChnGetEvFlags(int chn);

	/*********************************************************************
	 * Function:        void DmaChnIntEnable(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function enables the interrupts in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=3; DmaChnIntEnable(chn);
	 * 					mDmaChnIntEnable(3);
	 ********************************************************************/
	#define			DmaChnIntEnable(chn)	INTEnable(INT_DMA0+(chn), 1)
	#define			mDmaChnIntEnable(c)		(mDMA##c##IntEnable(1))	// macro version


	/*********************************************************************
	 * Function:        void DmaChnIntDisable(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function disables the interrupts in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=3; DmaChnIntDisable(chn);
	 * 					mDmaChnIntDisable(3);
	 ********************************************************************/
	#define			DmaChnIntDisable(chn)		INTEnable(INT_DMA0+(chn), 0)
	#define			mDmaChnIntDisable(c)		(mDMA##c##IntEnable(0))	// macro version



	/*********************************************************************
	 * Function:        int DmaChnGetIntEnable(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          TRUE if the corresponding interrupt is enabled,
	 * 					FALSE otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the Interrupt Controller (EVIC) interrupt enabled status for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=3; int isEnabled=DmaChnGetIntEnable(chn);
	 * 					isEnabled=mDmaChnGetIntEnable(3);
	 ********************************************************************/
	#define			DmaChnGetIntEnable(chn)		INTGetEnable(INT_DMA0+(chn))
	#define			mDmaChnGetIntEnable(c)		(mDMA##c##GetIntEnable())		// macro version

	/*********************************************************************
	 * Function:        void DmaChnSetIntPriority(int chn, int iPri, int subPri)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					iPri	- the interrupt priority in the interrupt controller
	 * 					subPri	- the interrupt subpriority in the interrupt controller
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the interrupt priority and subpriority in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=0; DmaChnSetIntPriority(chn, INT_PRIORITY_LEVEL_5, INT_SUB_PRIORITY_LEVEL_3);
	 * 					mDmaChnSetIntPriority(0, 5, 3);
	 ********************************************************************/
	#define			DmaChnSetIntPriority(chn, iPri, subPri)		do{INTSetPriority(INT_DMA0+(chn), (iPri)); \
	 															INTSetSubPriority(INT_DMA0+(chn), (subPri));}while(0)
	#define			mDmaChnSetIntPriority(c, iPri, subPri)		(mDMA##c##SetIntPriority(iPri), mDMA##c##SetIntSubPriority(subPri))	// macro version

	/*********************************************************************
	 * Function:        int DmaChnGetIntPriority(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          the current channel interrupt priority in the INT controller
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function reads the current interrupt priority in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=2; int currPri=DmaChnGetIntPriority(chn);
	 * 					currPri=mDmaChnGetIntPriority(2);
	 ********************************************************************/
	#define			DmaChnGetIntPriority(chn)	INTGetPriority(INT_DMA0+(chn))
 	#define			mDmaChnGetIntPriority(c)	(mDMA##c##GetIntPriority())		// macro version

	/*********************************************************************
	 * Function:        int DmaChnGetIntSubPriority(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          the current channel interrupt subpriority in the INT controller
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function reads the current subinterrupt priority in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=2; int currSubPri=DmaChnGetIntSubPriority(chn);
	 * 					currSubPri=mDmaChnGetIntSubPriority(2);
	 ********************************************************************/
	#define			DmaChnGetIntSubPriority(chn)	INTGetSubPriority(INT_DMA0+(chn))
	#define			mDmaChnGetIntSubPriority(c)		(mDMA##c##GetIntSubPriority())		// macro version

	/*********************************************************************
	 * Function:        int DmaChnGetIntFlag(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          TRUE if the corresponding channel interrupt flag is set
	 * 					FALSE otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function reads the current interrupt flag status in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=1; int isFlagSet=DmaChnGetIntFlag(chn);
	 * 					isFlagSet=mDmaChnGetIntFlag(1);
	 ********************************************************************/
	#define			DmaChnGetIntFlag(chn)		INTGetFlag(INT_DMA0+(chn))
 	#define			mDmaChnGetIntFlag(c)		(mDMA##c##GetIntFlag())			// macro version

	/*********************************************************************
	 * Function:        void DmaChnClrIntFlag(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function clears the current interrupt flag status in the Interrupt Controller (EVIC) for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int chn=1; DmaChnClrIntFlag(chn);
	 * 					mDmaChnClrIntFlag(1);
	 ********************************************************************/
	#define			DmaChnClrIntFlag(chn)		INTClearFlag(INT_DMA0+(chn))
 	#define			mDmaChnClrIntFlag(c)		(mDMA##c##ClearIntFlag())		// macro version



	// high level helpers for fast strcpy/memcpy transfers

	/*********************************************************************
	 * Function:        DmaTxferRes DmaChnMemcpy(void* s1, const void* s2, int n, int chn, DmaChannelPri chPri)
	 *
	 * PreCondition:    chn		- a valid DMA channel
	 * 					s1, s2	- valid memory pointers
	 * 					n>0, n<=DmaGetMaxTxferSize()
	 *
	 * Input:			s1		- destination pointer
	 * 					s2		- source pointer
	 * 					n		- number of bytes to transfer
	 * 					chn		- the DMA channel to perform the transfer
	 * 					chPri	- the desired channel priority
	 *
	 * Output:          DMA_TXFER_OK if the transfer ended normally,
	 * 					an DmaTxferRes error code  otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function configures a DMA channel for a fast memory transfer.
	 * 			Then it copies one block of memory from source to destination.
	 *
	 *
	 * Note:            - If the CRC is attached to the submitted channel, the CRC append mode will be turned off.
	 * 						This way, the transfer will occur correctly together with CRC calculation.
	 * 					- The start and abort Irqs will be disabled and the channel event enable flags are disabled.
	 * 					- Multiple channels could be opened to perform fast memory transfers, if necessary.
	 * 					- The function clears the suspend state and resumes the operation of the DMA controller.
	 *
 	 * Example:		res=DmaChnMemcpy(pDst, pSrc, buffSz, 0, DMA_CHN_PRI3);
 	 ********************************************************************/
	 DmaTxferRes	DmaChnMemcpy(void* s1, const void* s2, int n, int chn, DmaChannelPri chPri);

	/*********************************************************************
	 * Function:        DmaTxferRes DmaChnStrcpy(char* s1, const char* s2, int chn, DmaChannelPri chPri)
	 *
	 * PreCondition:    chn		- a valid DMA channel
	 * 					s1, s2	- valid memory pointers
	 *
	 * Input:			s1		- destination pointer
	 * 					s2		- source pointer
	 * 					chn		- the DMA channel to perform the transfer
	 * 					chPri	- the desired channel priority
	 *
	 * Output:          DMA_TXFER_OK if the transfer ended normally,
	 * 					an DmaTxferRes error code  otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function configures a DMA channel for a fast memory transfer.
	 * 			Then it copies one zero terminated string from source to destination.
	 *
	 *
	 * Note:            - If the CRC is attached to the submitted channel, the CRC append mode will be turned off.
	 *				This way, the transfer will occur correctly together with CRC calculation.
	 *			- The start and abort Irqs will be disabled and the channel event enable flags are disabled.
	 *			- Multiple channels could be opened to perform fast memory transfers, if necessary.
	 * 			- The function clears the suspend state and resumes the operation of the DMA controller.
	 *
	 *
 	 * Example:		res=DmaChnStrcpy(str1, str2, 0, DMA_CHN_PRI3);
	 *********************************************************************/
	 DmaTxferRes	DmaChnStrcpy(char* s1, const char* s2, int chn, DmaChannelPri chPri);

	/*********************************************************************
	 * Function:        DmaTxferRes DmaChnStrncpy(char* s1, const char* s2, int n, int chn, DmaChannelPri chPri)
	 *
	 * PreCondition:    chn		- a valid DMA channel
	 * 					s1, s2	- valid memory pointers
	 *
	 * Input:			s1		- destination pointer
	 * 					s2		- source pointer
	 * 					chn		- the DMA channel to perform the transfer
	 * 					chPri	- the desired channel priority
	 *
	 * Output:          DMA_TXFER_OK if the transfer ended normally,
	 * 					an DmaTxferRes error code  otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function configures a DMA channel for a fast memory transfer.
	 * 			Then it copies one zero terminated string from source to destination.
	 * 			It copies no more than n characters from s2.
	 *
	 *
	 * Note:            - If the CRC is attached to the submitted channel, the CRC append mode will be turned off.
	 *				This way, the transfer will occur correctly together with CRC calculation.
	 *			- The start and abort Irqs will be disabled and the channel event enable flags are disabled.
	 *			- Multiple channels could be opened to perform fast memory transfers, if necessary.
	 * 			- The function clears the suspend state and resumes the operation of the DMA controller.
	 *
	 *
 	 * Example:		res=DmaChnStrncpy(str1, str2, MAX_STR_LEN, 0, DMA_CHN_PRI3);
	 ********************************************************************/
	 DmaTxferRes DmaChnStrncpy(char* s1, const char* s2, int n, int chn, DmaChannelPri chPri);

	/*********************************************************************
	 * Function:        DmaTxferRes DmaChnMemCrc(void* d, const void* s, int n, int chn, DmaChannelPri chPri)
	 *
	 * PreCondition:    chn		- a valid DMA channel
	 * 					d, s		- valid memory pointer
	 * 					n>0, n<=DmaGetMaxTxferSize()
	 *
	 * Input:			d		- address where to deposit the result
	 * 					s		- source buffer pointer
	 * 					n		- number of bytes in the pointer
	 * 					chn		- the DMA channel to use
	 * 					chPri	- the desired channel priority
	 *
	 * Output:          DMA_TXFER_OK if the transfer ended normally,
	 * 					an DmaTxferRes error code  otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function is a helper that calculates the CRC of a memory block.
	 * 			The function configures the DMA channel for a fast memory transfer and calculates the CRC.
	 *
	 *
	 * Note:            - The CRC generator must have been previously configured using mCrcConfigure()
	 * 					- No transfer is done, just the CRC is calculated.
	 *			- The start and abort Irqs will be disabled and the channel event enable flags are disabled.
	 * 			- The function clears the suspend state and resumes the operation of the DMA controller.
	 *
	 * Example:		int myCrc; DmaChnMemCrc(&myCrc, srcBuff, sizeof(srcBuff), 0, DMA_CHN_PRI3);
	 ********************************************************************/
	 DmaTxferRes	DmaChnMemCrc(void* d, const void* s, int n, int chn, DmaChannelPri chPri);


	// High level CRC functions

	/*********************************************************************
	 * Function:        void mCrcConfigure(int polynomial, int pLen, int seed)
	 *
	 * PreCondition:    pLen		- valid polynomial length within 1-16
	 *
	 * Input:			polynomial	- the layout of the CRC generator
	 * 					pLen		- the length of the CRC generator polynomial
	 * 					seed		- the initial seed of the CRC generator
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function configures the CRC module by setting the parameters that define the generator polynomial:
	 * 					- the length of the CRC generator polynomial, pLen;
	 * 					- the function sets the layout of the shift stages that take place in the CRC generation.
	 * 						Setting a bit to 1 enables the XOR input from the MSb (pLen bit) to the selected stage in the shift register.
	 * 						If bit is cleared, the selected shift stage gets data directly from the previous stage in the shift register.
	 * 						Note that in a proper CRC polynomial, both the most significant bit (MSb) and least significant bit(LSb)
	 * 						are always a '1'. Considering the generator polynomial: X^16+X^15+X^2+1, the value to be written as
	 * 						feedback should be 0x8005, or 0x8004, but not 0x018005;
	 *					- the function sets the seed of the CRC generator. This is the initial data present in the
	 * 						CRC shift register before the CRC calculation begins. A good initial value is usually 0xffffffff.
	 *
	 * Note:            - Bit 0 of the generator polynomial is always XOR'ed.
	 * 					- When the append mode is set, the attached DMA channel has to have destination size <=4.
	 * 						Upon the transfer completion the calculated CRC is stored at the destination address.
	 * 					- When append mode is cleared, the DMA transfer occurs normally, and the CRC value is available using
	 * 						the CrcResult() function.
	 * 					- The CRC module should be configured before enabled.
	 *
	 * Example:			mCrcConfigure(0x8005, 16, 0xffff);
	 ********************************************************************/
	#define mCrcConfigure(polynomial, pLen, seed)	(DCRCCONCLR=_DCRCCON_PLEN_MASK, DCRCCONSET=((pLen)-1)<<_DCRCCON_PLEN_POSITION, DCRCDATA=(seed), DCRCXOR=(polynomial))


	/*********************************************************************
	 * Function:        void CrcAttachChannel(int chn, int appendMode)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 *
	 * Input:			chn			- the DMA channel to be attached to the CRC generator module.
	 * 					appendMode	- if TRUE the data passed to the CRC generator is not transferred to destination
	 * 									but it's written to the destination address when the block transfer is complete.
	 * 								- if FALSE the data is transferred normally while the CRC is calculated. The CRC will
	 * 									be available using the CrcResult function.
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function attaches the CRC module to an DMA channel and enables the CRC generator.
	 * 					From now on, all the DMA traffic is directed to the CRC generator. Once the DMA block transfer
	 * 					is complete, the CRC result is available both at the DMA destination address and in the CRC data register.
	 *
	 * Note:            None
	 *
	 * Example:			CrcAttachChannel(0, TRUE);
	 ********************************************************************/
	 void			CrcAttachChannel(int chn, int appendMode);

	/*********************************************************************
	 * Function:        int CrcResult(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          the current value of the CRC generator.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the calculated CRC value.
	 *
	 * Note:            The function returns the valid CRC result by masking out the unused MSbits in the CRC register.
	 * 					Use CrcGetValue() to get the full CRC register value.
	 *
	 * Example:			int myCrc=CrcResult();
	 ********************************************************************/
	 int			CrcResult(void);


/*********************  end of high level functions ****************************************/

	// low level definitions for the API functions


	typedef struct
	{
		union
		{
			struct
			{
				unsigned int chn:	3;		// last active DMA channel
				unsigned int rdOp:	1;		// last DMA operation, read if 1, write if 0
			};
			unsigned int	w;						// word access
		}lastAccess;
		void*	lastAddress;		// most recent DMA address
	}DmaStatus;			// DMA controller status

	typedef enum
	{
		DMA_GFLG_SUSPEND =	_DMACON_SUSPEND_MASK,	// suspend DMA controller operation
		DMA_GFLG_SIDL =		_DMACON_SIDL_MASK,		// DMA controller sleep/active in idle mode
		DMA_GFLG_FRZ =		_DMACON_FRZ_MASK,		// DMA controller frozen/active in debug mode
		DMA_GFLG_ON =		_DMACON_ON_MASK,		// DMA module enabled/desabled
		//
		DMA_GFLG_ALL_FLAGS=	DMA_GFLG_SUSPEND|DMA_GFLG_SIDL|DMA_GFLG_FRZ|DMA_GFLG_ON		// all flags
	}DmaGlblFlags;	// flags for controlling global DMA controller behavior. From processor header file.




	typedef enum
	{
		DMA_EV_ABORT_IRQ_EN =		_DCH0ECON_AIRQEN_MASK,
		DMA_EV_START_IRQ_EN =		_DCH0ECON_SIRQEN_MASK,
		DMA_EV_MATCH_EN =			_DCH0ECON_PATEN_MASK,
	}DmaEvCtrlFlags;	// DMA channel event control fields accessibile as flags
	// also part of DmaEvCtrlFlags:
	#define	DMA_EV_START_IRQ(irq)	(DMA_EV_START_IRQ_EN | ((irq)<<_DCH0ECON_CHSIRQ_POSITION))	// NOTE: irq has to be a symbol from the processor header file
	#define	DMA_EV_ABORT_IRQ(irq)	(DMA_EV_ABORT_IRQ_EN | ((irq)<<_DCH0ECON_CHAIRQ_POSITION))	// NOTE: irq has to be a symbol from the processor header file

	// DMA channel event control as a structure:
	#define	DmaEvCtrl	__DCH0ECONbits_t




	typedef enum
	{
		DMA_CTL_AUTO_EN =		_DCH0CON_CHAEN_MASK,
		DMA_CTL_CHAIN_EN =		_DCH0CON_CHCHN_MASK,
		DMA_CTL_DET_EN =		_DCH0CON_CHAED_MASK,
		DMA_CTL_CHN_EN =		_DCH0CON_CHEN_MASK,
		DMA_CTL_CHAIN_DIR =		_DCH0CON_CHCHNS_MASK,
	}DmaChnCtrlFlags;	// controlling the DMA channel with flags
	// also part of DmaChnCtrlFlags:
	#define	DMA_CTL_PRI(pri)	((pri)&_DCH0CON_CHPRI_MASK) // DMA Control channel priority

	// DMA channel control as a structure:
	#define	DmaChnCtrl  	__DCH0CONbits_t

	typedef struct
	{
		void*	vSrcAdd;		// source of the DMA transfer, virtual
		void*	vDstAdd;		// destination of the DMA transfer, virtual
		int	srcSize;		// source buffer size, 1 to DmaGetMaxTxferSize() bytes. Wrapped around.
		int	dstSize;		// destination buffer size, 1 to DmaGetMaxTxferSize() bytes. Wrapped around.
		int	cellSize;		// no of bytes txferred per event, 1 to DmaGetMaxTxferSize().
	}DmaTxferCtrl;		// transfer setting: the transfer source, destination addresses and size, cell size


	/********************** low level DMA channel functions *******************************/



	// Global DMA controller functions


	/*********************************************************************
	 * Function:        void mDmaEnable(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:		None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function/macro enables the DMA controller.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaEnable();
	 ********************************************************************/
	#define		mDmaEnable()	(DMACONSET=_DMACON_ON_MASK)

	/*********************************************************************
	 * Function:        void mDmaDisable(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:		None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function/macro disables the DMA controller.
	 *
	 * Note:            None.
	 *
	 * Example:			mDmaDisable();
	 ********************************************************************/
	#define		mDmaDisable()	do{DMACONCLR=_DMACON_ON_MASK; while(DMACONbits.ON);}while(0)

	/*********************************************************************
	 * Function:        void mDmaReset(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:		None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function/macro resets the DMA controller.
	 *
	 * Note:            None.
	 *
	 * Example:			mDmaReset();
	 ********************************************************************/
	#define		mDmaReset()	mDmaDisable()

	/*********************************************************************
	 * Function:        int DmaSuspend(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:		None
	 *
	 * Output:          true if the DMA was previously suspended, false otherwise
	 *
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function suspends the DMA controller.
	 *
	 * Note:            None.
	 *
	 * Example:			int susp=DmaSuspend();
	 ********************************************************************/
    extern __inline__ int __attribute__((always_inline)) DmaSuspend(void)
	{
		int suspSt;
		if(!(suspSt=DMACONbits.SUSPEND))
		{
			DMACONSET=_DMACON_SUSPEND_MASK;		// suspend
			while(!(DMACONbits.SUSPEND));	// wait to be actually suspended
		}
		return suspSt;
	}



	/*********************************************************************
	 * Function:        void DmaResume(int susp)
	 *
	 * PreCondition:    None
	 *
	 * Input:		the desired DMA suspended state.
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function restores the DMA controller activity to the old suspended mode.
	 *
	 * Note:            None.
	 *
	 * Example:			int isSusp=DmaSuspend(); {....}; DmaResume(isSusp);
	 ********************************************************************/
    extern __inline__ void __attribute__((always_inline)) DmaResume(int susp)
	{
		if(susp)
		{
			DmaSuspend();
		}
		else
		{
			DMACONCLR=_DMACON_SUSPEND_MASK;		// resume DMA activity
		}
	}

	/*********************************************************************
	 * Function:        void DmaGetStatus(DmaStatus* pStat)
	 *
	 * PreCondition:    pStat	- valid pointer
	 *
	 * Input:			pStat	- pointer to a DmaStatus structure to store the current DMA controller
	 * 							status, carrying the following info:
	 * 								- chn:	the last active DMA channel
	 * 								- rdOp: the last DMA operation, read/write
	 * 								- lastAddress: the most recent DMA address
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function updates the info for the current DMA controller status.
	 * 					It updates the last DMA: operation, channel used and address.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaStatus stat; DmaGetStatus(&stat);
	 ********************************************************************/
	 void			DmaGetStatus(DmaStatus* pStat);

	/*********************************************************************
	 * Function:        void mDmaSetGlobalFlags(DmaGlblFlags gFlags)
	 *
	 * PreCondition:    None
	 *
	 * Input:			gFlags	- flags to be set, having the following fields:
	 * 								- DMA_GFLG_SUSPEND: DMA controller operation suspend
	 * 								- DMA_GFLG_SIDL: DMA controller sleep/active in idle mode
	 * 								- DMA_GFLG_FRZ: DMA controller frozen/active in debug mode
	 * 								- DMA_GFLG_ON: DMA controller enabled/desabled
	 * 								- DMA_GFLG_ALL_FLAGS: all flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function affects the global behavior of the DMA controller.
	 * 					It sets the specified flags. Any flag that is set in the gFlags will be
	 * 					enabled, the other flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			mDmaSetGlobalFlags(DMA_GFLG_SIDL|DMA_GFLG_ON);
	 ********************************************************************/
	#define				mDmaSetGlobalFlags(gFlags)	(DMACONSET=(gFlags))

	/*********************************************************************
	 * Function:        void mDmaClrGlobalFlags(DmaGlblFlags gFlags)
	 *
	 * PreCondition:    None
	 *
	 * Input:			gFlags	- flags to be cleared, having the following fields:
	 * 								- DMA_GFLG_SUSPEND: DMA controller operation suspend
	 * 								- DMA_GFLG_SIDL: DMA controller sleep/active in idle mode
	 * 								- DMA_GFLG_FRZ: DMA controller frozen/active in debug mode
	 * 								- DMA_GFLG_ON: DMA controller enabled/desabled
	 * 								- DMA_GFLG_ALL_FLAGS: all flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function affects the global behavior of the DMA controller.
	 * 					It clears the specified flags. Any flag that is set in the gFlags will be
	 * 					cleared, the other flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			mDmaClrGlobalFlags(DMA_GFLG_SUSPEND|DMA_GFLG_SIDL);
	 ********************************************************************/
	#define				mDmaClrGlobalFlags(gFlags)		(DMACONCLR=(gFlags))


	/*********************************************************************
	 * Function:        void mDmaWriteGlobalFlags(DmaGlblFlags gFlags)
	 *
	 * PreCondition:    None
	 *
	 * Input:			gFlags	- flags to be set, having the following fields:
	 * 								- DMA_GFLG_SUSPEND: DMA controller operation suspend
	 * 								- DMA_GFLG_SIDL: DMA controller sleep/active in idle mode
	 * 								- DMA_GFLG_FRZ: DMA controller frozen/active in debug mode
	 * 								- DMA_GFLG_ON: DMA controller enabled/desabled
	 * 								- DMA_GFLG_ALL_FLAGS: all flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function affects the global behavior of the DMA controller.
	 * 					It forces the flags to have the specified gFlags value.
	 *
	 * Note:            None.
	 *
	 * Example:			mDmaWriteGlobalFlags(DMA_GFLG_ALL_FLAGS);
	 ********************************************************************/
	#define				mDmaWriteGlobalFlags(gFlags)		(DMACON=(gFlags))

	/*********************************************************************
	 * Function:        DmaGlblFlags mDmaGetGlobalFlags(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          The current DMA controller flags settings.
	 * 						- DMA_GFLG_SUSPEND: DMA controller operation suspend
	 * 						- DMA_GFLG_SIDL: DMA controller sleep/active in idle mode
	 * 						- DMA_GFLG_FRZ: DMA controller frozen/active in debug mode
	 * 						- DMA_GFLG_ON: DMA controller enabled/desabled
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the global flags of the DMA controller.
	 *
	 * Note:            None.
	 *
	 * Example:			DmaGlblFlags dmaFlags=mDmaGetGlobalFlags();
	 ********************************************************************/
	#define 			mDmaGetGlobalFlags()		((DmaGlblFlags)DMACON)


	/*********************************************************************
	 * Function:        int DmaGetMaxTxferSize(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:           None
	 *
	 * Output:          The maximum transfer capacity for a DMA channel, in bytes.
	 *
	 * Side Effects:    None
	 *
	 * Overview:        The function returns the maximum number of bytes that can be transferred by a DMA channel.
	 *
	 * Note:            Revision dependant.
	 *
	 * Example:         int dmaMaxSz=DmaGetMaxTxferSize();
	 ********************************************************************/
	extern __inline__ int __attribute__((always_inline)) DmaGetMaxTxferSize(void)
	{
		return 256;
	}

	/*********************************************************************
	 * Function:        int DmaChnGetSrcPnt(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          Current channel source pointer.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the current source pointer for the selected DMA channel.
	 * 					It is the current offset, 0 to DmaGetMaxTxferSize()-1, in the source transfer buffer.
	 *
	 * Note:            None
	 *
	 * Example:         int srcPnt=DmaChnGetSrcPnt(3);
	 ********************************************************************/
	 int			DmaChnGetSrcPnt(int chn);

	/*********************************************************************
	 * Function:        int DmaChnGetDstPnt(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          Current channel destination pointer.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the current destination pointer for the selected DMA channel.
	 * 					It is the current offset, 0 to DmaGetMaxTxferSize()-1, in the destination transfer buffer.
	 *
	 * Note:            None
	 *
	 * Example:			int dstPnt=DmaChnGetDstPnt(3);
	 ********************************************************************/
	 int			DmaChnGetDstPnt(int chn);

	/*********************************************************************
	 * Function:        int DmaChnGetCellPnt(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          Current channel transfer pointer.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the current transfer progress pointer for the selected DMA channel.
	 * 					It ranges 0 to DmaGetMaxTxferSize()-1.
	 *
	 * Note:            None
	 *
	 * Example:			int cellPnt=DmaChnGetCellPnt(3);
	 ********************************************************************/
	 int			DmaChnGetCellPnt(int chn);

	// Channel control functions



	/*********************************************************************
	 * Function:        void DmaChnSetEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaEvCtrl	- 	either a DmaEvCtrl structure field, carrying the following info:
	 * 										- AIRQEN: enable/disable the abort IRQ action
	 * 										- SIRQEN: enable/disable the start IRQ action
	 * 										- PATEN: enable/disable the pattern match and abort
	 * 									or any of the DmaEvCtrlFlags:
	 * 										DMA_EV_ABORT_IRQ_EN|DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN
	 *
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the events that start and abort the transfer
	 * 					for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					enabled for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnSetEventControlFlags(3, DMA_EV_MATCH_EN|DMA_EV_START_IRQ_EN;
	 * 					or:
	 * 						DmaEvCtrl evCtrl; evCtrl.w=0; evCtrl.PATEN=1; evCtrl.SIRQEN=1;
	 * 						DmaChnSetEventControlFlags(3, evCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnSetEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl);


	/*********************************************************************
	 * Function:        void DmaChnClrEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaEvCtrl	- 	either a DmaEvCtrl structure field, carrying the following info:
	 * 										- AIRQEN: enable/disable the abort IRQ action
	 * 										- SIRQEN: enable/disable the start IRQ action
	 * 										- PATEN: enable/disable the pattern match and abort
	 * 									or any of the DmaEvCtrlFlags:
	 * 										DMA_EV_ABORT_IRQ_EN|DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN
	 *
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function clears the events that start and abort the transfer
	 * 					for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					disabled for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnClrEventControlFlags(3, DMA_EV_MATCH_EN|DMA_EV_START_IRQ_EN);
	 * 					or:
	 * 						DmaEvCtrl evCtrl; evCtrl.w=0; evCtrl.PATEN=1; evCtrl.AIRQEN=1;
	 * 						DmaChnClrEventControlFlags(3, evCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnClrEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl);



	/*********************************************************************
	 * Function:        void DmaChnWriteEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaEvCtrl	- 	either a DmaEvCtrl structure field, carrying the following info:
	 * 										- AIRQEN: enable/disable the abort IRQ action
	 * 										- SIRQEN: enable/disable the start IRQ action
	 * 										- PATEN: enable/disable the pattern match and abort
	 * 										- CHSIRQ: IRQ number to start the DMA channel transfer
	 * 										- CHAIRQ: IRQ number to abort the DMA channel transfer
	 * 									or any of the DmaEvCtrlFlags:
	 * 										DMA_EV_ABORT_IRQ_EN|DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN|DMA_EV_START_IRQ(irq)|DMA_EV_ABORT_IRQ(irq)
	 *
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function writes the events that start and abort the transfer
	 * 					for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnWriteEventControlFlags(3, DMA_EV_MATCH_EN|DMA_EV_START_IRQ(_UART2_RX_IRQ));
	 * 					or:
	 * 						DmaEvCtrl evCtrl; evCtrl.w=0; evCtrl.AIRQEN=1; evCtrl.PATEN=1; evCtrl.CHSIRQ=_UART2_RX_IRQ;
	 * 						DmaChnWriteEventControlFlags(3, evCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnWriteEventControlFlags(int chn, DmaEvCtrlFlags dmaEvCtrl);



	/*********************************************************************
	 * Function:        void DmaChnSetEventControl(int chn, DmaEvCtrlFlags dmaEvCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaEvCtrl	- 	either a DmaEvCtrl structure field, carrying the following info:
	 * 										- AIRQEN: enable/disable the abort IRQ action
	 * 										- SIRQEN: enable/disable the start IRQ action
	 * 										- PATEN: enable/disable the pattern match and abort
	 * 										- CHSIRQ: IRQ number to start the DMA channel transfer
	 * 										- CHAIRQ: IRQ number to abort the DMA channel transfer
	 * 									or any of the DmaEvCtrlFlags:
	 * 										DMA_EV_ABORT_IRQ_EN|DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN|DMA_EV_START_IRQ(irq)|DMA_EV_ABORT_IRQ(irq)
	 *
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the events that start and abort the transfer
	 * 					for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					enabled for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:           A shorter name for DmaChnWriteEventControlFlags();
	 *
	 * Example:			either:
	 * 						DmaChnSetEventControl(3, DMA_EV_MATCH_EN|DMA_EV_START_IRQ(_UART2_RX_IRQ));
	 * 					or:
	 * 						DmaEvCtrl evCtrl; evCtrl.w=0; evCtrl.AIRQEN=1; evCtrl.PATEN=1; evCtrl.CHSIRQ=_UART2_RX_IRQ;
	 * 						DmaChnSetEventControl(3, evCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnSetEventControl(int chn, DmaEvCtrlFlags dmaEvCtrl);


	/*********************************************************************
	 * Function:        DmaEvCtrlFlags DmaChnGetEventControl(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          - 	either a DmaEvCtrl structure field, carrying the following info:
	 * 							- AIRQEN: enable/disable the abort IRQ action
	 * 							- SIRQEN: enable/disable the start IRQ action
	 * 							- PATEN: enable/disable the pattern match and abort
	 * 							- CHSIRQ: IRQ number to start the DMA channel transfer
	 * 							- CHAIRQ: IRQ number to abort the DMA channel transfer
	 * 						or any of the DmaEvCtrlFlags:
	 * 							DMA_EV_ABORT_IRQ_EN|DMA_EV_START_IRQ_EN|DMA_EV_MATCH_EN|DMA_EV_START_IRQ(irq)|DMA_EV_ABORT_IRQ(irq)
	 *
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the events that start and abort the transfer
	 * 					for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaEvCtrlFlags evCtrlW=DmaChnGetEventControl(3); if(evCtrlW&DMA_EV_MATCH_EN) {...}
	 * 					or:
	 * 						DmaEvCtrl evCtrl; evCtrl.w=DmaChnGetEventControl(3); if(evCtrl.PATEN){...}
	 *
	 ********************************************************************/
	 DmaEvCtrlFlags	DmaChnGetEventControl(int chn);


	/*********************************************************************
	 * Function:        void DmaChnSetControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaChnCtrl	- 	either a DmaChnCtrl structure field, carrying the following info:
	 * 										- autoEn: enable/disable the automatic mode
	 * 										- chainEn: enable/disable channel chaining
	 * 										- detectEn: enable/disable events detection when channel disabled
	 * 										- chEn: enable/disable channel functionality
	 * 										- chainDir:	chain direction: chain to lower(1)/higher(0),pri channel
	 * 									or any of the DmaChnCtrlFlags flags:
	 * 										DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN|DMA_CTL_DET_EN|DMA_CTL_CHN_EN|DMA_CTL_CHAIN_DIR
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the selected DMA channel control flags:
	 * 					the chaining or auto mode, and events detection.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the dmaChnCtrl will be
	 * 					set for the selected channel, the other channel control flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnSetControlFlags(3, DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN);
	 * 					or:
	 * 						DmaChnCtrl chCtrl; chCtrl.w=0; chCtrl.autoEn=1; chCtrl.chainEn=1;
	 * 						DmaChnSetControlFlags(3, chCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnSetControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl);

	/*********************************************************************
	 * Function:        void DmaChnClrControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaChnCtrl	- 	either a DmaChnCtrl structure field, carrying the following info:
	 * 										- autoEn: enable/disable the automatic mode
	 * 										- chainEn: enable/disable channel chaining
	 * 										- detectEn: enable/disable events detection when channel disabled
	 * 										- chEn: enable/disable channel functionality
	 * 										- chainDir:	chain direction: chain to lower(1)/higher(0),pri channel
	 * 									or any of the DmaChnCtrlFlags flags:
	 * 										DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN|DMA_CTL_DET_EN|DMA_CTL_CHN_EN|DMA_CTL_CHAIN_DIR
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function clears the selected DMA channel control flags:
	 * 					the chaining or auto mode and events detection.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the dmaChnCtrl will be
	 * 					cleared for the selected channel, the other channel control flags won't be touched.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnClrControlFlags(3, DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN);
	 * 					or:
	 * 						DmaChnCtrl chCtrl; chCtrl.w=0; chCtrl.autoEn=1; chCtrl.chainEn=1;
	 * 						DmaChnClrControlFlags(3, chCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnClrControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl);

	/*********************************************************************
	 * Function:        void DmaChnWriteControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 * 					dmaChnCtrl	- 	either a DmaChnCtrl structure field, carrying the following info:
	 * 										- chPri: channel priority 0-3
	 * 										- autoEn: enable/disable the automatic mode
	 * 										- chainEn: enable/disable channel chaining
	 * 										- detectEn: enable/disable events detection when channel disabled
	 * 										- chEn: enable/disable channel functionality
	 * 										- chainDir:	chain direction: chain to lower(1)/higher(0),pri channel
	 * 									or any of the DmaChnCtrlFlags flags:
	 * 										DMA_CTL_PRI(pri)|DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN|DMA_CTL_DET_EN|DMA_CTL_CHN_EN|DMA_CTL_CHAIN_DIR
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function enables/disables the selected DMA channel and also sets
	 * 					the channel priority, chaining mode or auto and events detection.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnWriteControlFlags(3, DMA_CTL_PRI(DMA_CHN_PRI2)|DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN);
	 * 					or:
	 * 						DmaChnCtrl chCtrl; chCtrl.w=0; chCtrl.chPri=DMA_CHN_PRI2; chCtrl.autoEn=1; chCtrl.chainEn=1;
	 * 						DmaChnWriteControlFlags(3, chCtrl.w);
	 *
	 ********************************************************************/
	 void			DmaChnWriteControlFlags(int chn, DmaChnCtrlFlags dmaChnCtrl);

	/*********************************************************************
	 * Function:        void DmaChnSetControl(int chn, DmaChnCtrlFlags dmaChnCtrl)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:	    chn		- DMA channel number
	 *                  dmaChnCtrl	- 	either a DmaChnCtrl structure field, carrying the following info:
	 * 						- chPri: channel priority 0-3
	 * 						- autoEn: enable/disable the automatic mode
	 * 						- chainEn: enable/disable channel chaining
	 * 						- detectEn: enable/disable events detection when channel disabled
	 * 						- chEn: enable/disable channel functionality
	 * 						- chainDir:	chain direction: chain to lower(1)/higher(0),pri channel
	 * 					or any of the DmaChnCtrlFlags flags:
	 * 						DMA_CTL_PRI(pri)|DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN|DMA_CTL_DET_EN|DMA_CTL_CHN_EN|DMA_CTL_CHAIN_DIR
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:        The function enables/disables the selected DMA channel and also sets
	 * 					the channel priority, chaining mode or auto and events detection.
	 *
	 * Note:            Another name ( backward compatible) for DmaChnWriteControlFlags().
	 *
	 * Example:         either:
	 *                      DmaChnSetControl(3, DMA_CTL_PRI(DMA_CHN_PRI2)|DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN);
	 *                  or:
	 *                     	DmaChnCtrl chCtrl; chCtrl.w=0; chCtrl.chPri=DMA_CHN_PRI2; chCtrl.autoEn=1; chCtrl.chainEn=1;
	 * 			DmaChnSetControl(3, chCtrl.w);
	 *
	 ********************************************************************/
#define		DmaChnSetControl(chn, dmaChnCtrl)	DmaChnWriteControlFlags(chn, dmaChnCtrl)

	/*********************************************************************
	 * Function:        DmaChnCtrlFlags DmaChnGetControlFlags(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn			- DMA channel number
	 *
	 * Output:          - either a DmaChnCtrl structure field, carrying the following info:
	 * 							- chPri: channel priority 0-3
	 * 							- autoEn: enable/disable the automatic mode
	 * 							- chainEn: enable/disable channel chaining
	 * 							- detectEn: enable/disable events detection when channel disabled
	 * 							- chEn: enable/disable channel functionality
	 * 							- chainDir:	chain direction: chain to lower(1)/higher(0),pri channel
	 *						or any of the DmaChnCtrlFlags flags:
	 *							DMA_CTL_PRI(pri)|DMA_CTL_AUTO_EN|DMA_CTL_CHAIN_EN|DMA_CTL_DET_EN|DMA_CTL_CHN_EN|DMA_CTL_CHAIN_DIR
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the current control settings for the selected DMA channel,
	 * 					including the channel enable/disable status, the channel priority,
	 * 					chaining mode, auto mode and events detection.
	 *
	 * Note:            None.
	 *
	 * Example:			either:
	 * 						DmaChnCtrlFlags ctrl=DmaChnGetControlFlags(3); if(ctrl&DMA_CTL_AUTO_EN) {...}
	 * 					or:
	 * 						DmaChnCtrl chnCtrl; chnCtrl.w=DmaChnGetControlFlags(3); if(chnCtrl.autoEn) {...}
	 *
	 ********************************************************************/
	 DmaChnCtrlFlags	DmaChnGetControlFlags(int chn);


	/*********************************************************************
	 * Function:        int DmaChnGetEvDetect(int chn)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 *
	 * Output:          TRUE if an DMA event was detected, FALSE otherwise.
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the current event detection for the selected DMA channel.
	 *
	 * Note:            None.
	 *
	 * Example:			int evDetect=DmaChnGetEvDetect(3);
	 *
	 ********************************************************************/
	 int			DmaChnGetEvDetect(int chn);

	/*********************************************************************
	 * Function:        void DmaChnGetTxfer(int chn, DmaTxferCtrl* pTxCtrl, int mapToK0)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 * 					pTxCtrl	- valid pointer
	 *
	 * Input:			chn			- DMA channel number
	 * 					pTxCtrl		- pointer to a DmaTxferCtrl that will carry the following info:
	 * 								- vSrcAdd: source of the DMA transfer
	 * 								- vDstAdd: destination of the DMA transfer
	 * 								- srcSize: source buffer size, 1 to DmaGetMaxTxferSize() bytes, wrapped arround
	 * 								- dstSize: destination buffer size, 1 to DmaGetMaxTxferSize() bytes, wrapped around
	 * 								- cellSize: cell transfer size, 1 to DmaGetMaxTxferSize() bytes.
	 *					mapToK0		- if TRUE, a Kernel address is mapped to KSeg0, else KSeg1.
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the transfer characteristics for a DMA channel transfer:
	 * 					the source and the destination addresses.
	 * 					It also retrieves the source and destination lengths
	 * 					and the number of bytes	transferred per event.
	 *
	 * Note:            None
	 *
	 * Example:			DmaTxferCtrl txCtl; DmaChnGetTxfer(3, &txCtl, FALSE);
	 ********************************************************************/
	 void			DmaChnGetTxfer(int chn, DmaTxferCtrl* pTxCtrl, int mapToK0);

	// Low level CRC functions

	/*********************************************************************
	 * Function:        void mCrcEnable(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function enables the CRC module functionality and the attached DMA channel transfers are routed to the CRC module.
	 *
	 * Note:            The CRC module should be properly configured before enabled.
	 *
	 * Example:			mCrcEnable();
	 ********************************************************************/
	#define mCrcEnable()		(DCRCCONSET=_DCRCCON_CRCEN_MASK)

	/*********************************************************************
	 * Function:        void mCrcDisable(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function disables the CRC module functionality.
	 *
	 * Note:            None
	 *
	 * Example:			mCrcDisable();
	 ********************************************************************/
	#define mCrcDisable()	(DCRCCONCLR=_DCRCCON_CRCEN_MASK)


	/*********************************************************************
	 * Function:        int mCrcGetEnable(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          TRUE, if the CRC module is enabled
	 * 					FALSE otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the CRC module enabling status.
	 *
	 * Note:            None
	 *
	 * Example:			int isCrcEnabled=mCrcGetEnable();
	 ********************************************************************/
	#define				mCrcGetEnable()		(DCRCCONbits.CRCEN)


	/*********************************************************************
	 * Function:        void mCrcAppendModeEnable()
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function enables the CRC append mode. In this mode, the attached DMA channel reads
	 * 					the source data but does not write it to the destination address. The data it's just passed
	 * 					to the CRC generator for CRC calculation.
	 * 					When the block transfer is completed, the CRC result is written to the
	 * 					DMA channel destination address.
	 *
	 * Note:            The CRC module should be properly configured before enabled.
	 *
	 * Example:			mCrcAppendModeEnable();
	 ********************************************************************/
	#define	mCrcAppendModeEnable()	(DCRCCONSET=_DCRCCON_CRCAPP_MASK)


	/*********************************************************************
	 * Function:        void mCrcAppendModeDisable()
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function disables the CRC append mode. When the append mode is disabled,
	 * 					The attached DMA channel normally transfers data from source to destination.
	 * 					Data is also passed to the CRC controller for CRC calculation.
	 * 					When the DMA transfer is completed, the CRC value is available using the CrcGetValue function.
	 *
	 * Note:            None
	 *
	 * Example:			mCrcAppendModeDisable();
	 ********************************************************************/
	#define		mCrcAppendModeDisable()	(DCRCCONCLR=_DCRCCON_CRCAPP_MASK)

	/*********************************************************************
	 * Function:        int mCrcGetAppendMode(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          TRUE, if the CRC append mode is enabled
	 * 					FALSE otherwise
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the CRC module enabling status.
	 *
	 * Note:            None
	 *
	 * Example:			int isAppendEnabled=mCrcGetAppendMode();
	 ********************************************************************/
	#define				mCrcGetAppendMode()	(DCRCCONbits.CRCAPP==1)

	/*********************************************************************
	 * Function:        void mCrcSetDmaAttach(int chn)
	 *
	 * PreCondition:    chn		- valid DMA channel
	 *
	 * Input:			chn	- the DMA channel to be attached to the CRC module (the DMA channel transfers will be routed to the CRC module)
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function attaches a DMA channel to the CRC module.
	 *
	 * Note:            None
	 *
	 * Example:			mCrcSetDmaAttach(3);
	 ********************************************************************/
	#define				mCrcSetDmaAttach(chn)	(DCRCCONCLR=_DCRCCON_CRCCH_MASK, DCRCCONSET=(chn))

	/*********************************************************************
	 * Function:        int mCrcGetDmaAttach(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          the DMA channel that is currently attached to the CRC module
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the DMA channel number that is currently attached to the CRC module.
	 *
	 * Note:            None
	 *
	 * Example:			int chn=mCrcGetDmaAttach();
	 ********************************************************************/
	#define				mCrcGetDmaAttach()	((int)DCRCCONbits.CRCCH)


	/*********************************************************************
	 * Function:        void mCrcSetPLen(int pLen)
	 *
	 * PreCondition:    pLen	- valid polynomial length within 1-16
	 *
	 * Input:			pLen	- the length of the CRC generator polynomial
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The length of the CRC generator polynomial is set as being pLen;
	 *
	 * Note:            None
	 *
	 * Example:			mCrcSetPLen(16);
	 ********************************************************************/
	#define				mCrcSetPLen(pLen)		(DCRCCONCLR=_DCRCCON_PLEN_MASK, DCRCCONSET=(pLen)-1)

	/*********************************************************************
	 * Function:        int mCrcGetPLen(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          the length of the CRC generator polynomial
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the current length of the CRC generator polynomial.
	 * 					It's always a number between 1 and 16.
	 *
	 * Note:            None
	 *
	 * Example:			int polyLen=mCrcGetPLen();
	 ********************************************************************/
	#define				mCrcGetPLen()	(DCRCCONbits.PLEN+1)

	/*********************************************************************
	 * Function:        void mCrcSetShiftFeedback(int feedback)
	 *
	 * PreCondition:    None
	 *
	 * Input:			feedback	- the layout of the CRC generator
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the layout of the shift stages that take place in the CRC generation.
	 * 					Setting a bit to 1 enables the XOR input from the MSb (pLen bit) to the selected stage in the shift register.
	 * 					If bit is cleared, the selected shift stage gets data directly from the previous stage in the shift register.
	 *
	 * Note:            Bit 0 of the generator polynomial is always XOR'ed.
	 *
	 * Example:			mCrcSetShiftFeedback(0x8005);
	 ********************************************************************/
	#define				mCrcSetShiftFeedback(feedback)	(DCRCXOR=(feedback))


	/*********************************************************************
	 * Function:        int mCrcGetShiftFeedback(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          the current layout of the CRC generator
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the layout of the shift stages that take place in the CRC generation.
	 * 					A bit set to 1 enables the XOR input from the MSb (pLen bit) to the selected stage in the shift register.
	 * 					If a bit is cleared, the selected shift stage gets data directly from the previous stage in the shift register.
	 *
	 * Note:            Bit 0 of the generator polynomial is always XOR'ed.
	 *
	 * Example:			int feedback=mCrcGetShiftFeedback();
	 ********************************************************************/
	#define				mCrcGetShiftFeedback()	(DCRCXOR)

	/*********************************************************************
	 * Function:        void mCrcSetSeed(int seed)
	 *
	 * PreCondition:    None
	 *
	 * Input:			seed	- the initial seed of the CRC generator
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the seed of the CRC generator. This is the initial data present in the
	 * 					CRC shift register before the CRC calculation begins.
	 *
	 * Note:            None
	 *
	 * Example:			mCrcSetSeed(0xffff);
	 ********************************************************************/
	#define				mCrcSetSeed(seed)	(DCRCDATA=(seed))

	/*********************************************************************
	 * Function:        int mCrcGetValue(void)
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          the current value of the CRC generator
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function returns the current value of the CRC generator.
	 *
	 * Note:            Only the remainder bits (0 to pLen-1) are significant, the rest should be ignored.
	 *
	 * Example:			int calcCrc=mCrcGetValue();
	 ********************************************************************/
	#define				mCrcGetValue()		(DCRCDATA)


	// Channel test/debug and special functions

	/*********************************************************************
	 * Function:        void DmaChnSetEvFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the event flags for the selected DMA channel.
	 * 					Multiple flags can be orr-ed together. Any flag that is set in the eFlags will be
	 * 					set for the selected channel, the other channel event flags won't be touched.
	 *
	 * Note:            This is intended as a channel test function.
	 *
	 * Example:			DmaChnSetEvFlags(0, DMA_EV_ERR|DMA_EV_ABORT|DMA_EV_BLOCK_DONE|DMA_EV_SRC_FULL);
	 ********************************************************************/
	 void			DmaChnSetEvFlags(int chn, DmaEvFlags eFlags);

	/*********************************************************************
	 * Function:        void DmaChnWriteEvFlags(int chn, DmaEvFlags eFlags)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					eFlags	- event flags with the following significance:
	 * 								- DMA_EV_ERR: address error event
	 * 								- DMA_EV_ABORT: transfer abort event
	 * 								- DMA_EV_CELL_DONE: cell transfer complete event
	 * 								- DMA_EV_BLOCK_DONE: block transfer complete event
	 * 								- DMA_EV_DST_HALF: destination half event
	 * 								- DMA_EV_DST_FULL: destination full event
	 * 								- DMA_EV_SRC_HALF: source half event
	 * 								- DMA_EV_SRC_FULL: source full event
	 * 								- DMA_EV_ALL_EVNTS: all of the above flags
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function writes the event flags for the selected DMA channel.
	 * 					The channel event flags are forced to the eFlags value.
	 *
	 * Note:            This is intended as a channel test function.
	 *
	 * Example:			DmaChnWriteEvFlags(0, DMA_EV_ERR|DMA_EV_ABORT|DMA_EV_BLOCK_DONE|DMA_EV_SRC_FULL);
	 ********************************************************************/
	 void			DmaChnWriteEvFlags(int chn, DmaEvFlags eFlags);


	/*********************************************************************
	 * Function:        void mDmaFreezeEnable()
	 *
	 * PreCondition:    None
	 *
	 * Input:			None
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the DMA controller behavior in Debug mode.
	 * 					The DMA controller is frozen in Debug mode.
	 *
	 * Note:            This is intended as a channel test function.
	 *
	 * Example:			mDmaFreezeEnable();
	 ********************************************************************/
	#define		mDmaFreezeEnable()	(DMACONSET=_DMACON_FRZ_MASK)


	/*********************************************************************
	 * Function:        void mDmaFreezeDisable()
	 *
	 * PreCondition:    None
	 *
	 * Input:			frz	- if TRUE, the DMA controller is frozen in Debug mode.
	 * 						- if FALSE,
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets the DMA controller behavior in Debug mode.
	 * 					The DMA controller continues to run in Debug mode.
	 *
	 * Note:            This is intended as a channel test function.
	 *
	 * Example:			mDmaFreezeDisable();
	 ********************************************************************/
	#define	mDmaFreezeDisable()	(DMACONCLR=_DMACON_FRZ_MASK)


	// very low level access functions


	// indexes of all available channel registers
	typedef enum
	{
		// control register
		DMA_REG_IX_CON,
		DMA_REG_IX_CON_CLR,
		DMA_REG_IX_CON_SET,
		DMA_REG_IX_CON_INV,
		// event control register
		DMA_REG_IX_ECON,
		DMA_REG_IX_ECON_CLR,
		DMA_REG_IX_ECON_SET,
		DMA_REG_IX_ECON_INV,
		// interrupt control register
		DMA_REG_IX_INTR,
		DMA_REG_IX_INTR_CLR,
		DMA_REG_IX_INTR_SET,
		DMA_REG_IX_INTR_INV,
		// source address register
		DMA_REG_IX_SSA,
		DMA_REG_IX_SSA_CLR,
		DMA_REG_IX_SSA_SET,
		DMA_REG_IX_SSA_INV,
		// destination address register
		DMA_REG_IX_DSA,
		DMA_REG_IX_DSA_CLR,
		DMA_REG_IX_DSA_SET,
		DMA_REG_IX_DSA_INV,
		// source size register
		DMA_REG_IX_SSIZ,
		DMA_REG_IX_SSIZ_CLR,
		DMA_REG_IX_SSIZ_SET,
		DMA_REG_IX_SSIZ_INV,
		// destination size register
		DMA_REG_IX_DSIZ,
		DMA_REG_IX_DSIZ_CLR,
		DMA_REG_IX_DSIZ_SET,
		DMA_REG_IX_DSIZ_INV,
		// source pointer register
		DMA_REG_IX_SPTR,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		// destination pointer register
		DMA_REG_IX_DPTR,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		// cell size register
		DMA_REG_IX_CSIZ,
		DMA_REG_IX_CSIZ_CLR,
		DMA_REG_IX_CSIZ_SET,
		DMA_REG_IX_CSIZ_INV,
		// cell pointer register
		DMA_REG_IX_CPTR,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		DMA_REG_IX_RESERVED,
		// pattern data register
		DMA_REG_IX_DAT,
		DMA_REG_IX_DAT_CLR,
		DMA_REG_IX_DAT_SET,
		DMA_REG_IX_DAT_INV,
	}DmaChnRegIx;

	/*********************************************************************
	 * Function:        void DmaChnSetRegister(int chn, DmaChnRegIx regIx, int value)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					regIx	- register index
	 * 					value	- value to be set
	 *
	 * Output:          None
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function sets directly a value into a DMA channel register.
	 *
	 * Note:            This is intended as a low level access channel function.
	 *
	 * Example:			DmaChnSetRegister(3, DMA_REG_IX_SSIZ, myBuffSz);
	 ********************************************************************/
	 void			DmaChnSetRegister(int chn, DmaChnRegIx regIx, int value);

	/*********************************************************************
	 * Function:        int DmaChnGetRegister(int chn, DmaChnRegIx regIx)
	 *
	 * PreCondition:    chn	- valid DMA channel
	 *
	 * Input:			chn		- DMA channel number
	 * 					regIx	- register index
	 *
	 * Output:          the current register value
	 *
	 * Side Effects:    None
	 *
	 * Overview:		The function retrieves the current value of a DMA channel register.
	 *
	 * Note:            This is intended as a low level access channel function.
	 * 					Read from CLR/SET/INV registers yields undefined value.
	 *
	 * Example:			unsigned int mySrcSizeReg=DmaChnGetRegister(3, DMA_REG_IX_SSIZ);
	 ********************************************************************/
	 int			DmaChnGetRegister(int chn, DmaChnRegIx regIx);

#else
	#undef _DMA_CHANNELS		// no DMA channels
#endif	// _DMAC0

#endif /*_DMA_H_*/


