#ifndef EDMA3_H
#define EDMA3_H

#include <xdc/std.h>  					// Mandatory - have to include first, for BIOS types
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>                          // Errors are our specialty.
#include <xdc/runtime/Log.h>				// Needed for any Log_info() call

#include <ti/sysbios/BIOS.h> 				// Mandatory - for BIOS_start() and friends.
#include <xdc/cfg/global.h> 				// Header file for statically defined objects/handles

#include <stdint.h>

#include <drv/edma3_drv.h> 	 // required for EDMA3_DRV_Handle declaration

// Table 2-6. EDMA3 Channel Synchronization Events
// EDMA3 Architecture SPRU966C–December 2005–Revised July 2011
typedef enum
{
  EDMA_HW_EVENT_DSP_EVT = 0,     // HPI/PCI-to-DSP Event
  EDMA_HW_EVENT_TEVTLO0 = 1,     // Timer 0 Lower Counter edma3_lld_rm.ae66Event
  EDMA_HW_EVENT_TEVTHI0 = 2,     // Timer 0 Higher Counter Event
  EDMA_HW_EVENT_NONE_3 = 3,
  EDMA_HW_EVENT_NONE_4 = 4,
  EDMA_HW_EVENT_NONE_5 = 5,
  EDMA_HW_EVENT_NONE_6 = 6,
  EDMA_HW_EVENT_NONE_7 = 7,
  EDMA_HW_EVENT_NONE_8 = 8,
  EDMA_HW_EVENT_ETBHFULLINT = 9, // Embedded Trace Buffer (ETB) is Half Full
  EDMA_HW_EVENT_ETBFULLINT = 10, // Embedded Trace Buffer (ETB) is Full
  EDMA_HW_EVENT_ETBACQINT = 11,  // Embedded Trace Buffer (ETB) Acquisition is Complete
  EDMA_HW_EVENT_XEVT0 = 12,      // MCBSP0 Transmit Event
  EDMA_HW_EVENT_REVT0 = 13,      // MCBSP0 Receive Event
  EDMA_HW_EVENT_XEVT1 = 14,      // MCBSP1 Transmit Event
  EDMA_HW_EVENT_REVT1 = 15,      // MCBSP1 Receive Event
  EDMA_HW_EVENT_TINT1L = 16,     // Timer1 Lower Counter Event
  EDMA_HW_EVENT_TINT1H = 17,     // Timer1 Higher Counter Event
  EDMA_HW_EVENT_NONE_18 = 18,
  EDMA_HW_EVENT_INTDST0 = 18,    // RapidIO Interrupt 0
  EDMA_HW_EVENT_INTDST1 = 20,    // RapidIO Interrupt 1
  EDMA_HW_EVENT_INTDST2 = 21,    // RapidIO Interrupt 2
  EDMA_HW_EVENT_INTDST3 = 22,    // RapidIO Interrupt 3
  EDMA_HW_EVENT_INTDST4 = 23,    // RapidIO Interrupt 4
  EDMA_HW_EVENT_INTDST5 = 24,    // RapidIO Interrupt 5
  EDMA_HW_EVENT_INTDST6 = 25,    // RapidIO Interrupt 6
  EDMA_HW_EVENT_NONE_26 = 26,
  EDMA_HW_EVENT_NONE_27 = 27,
  EDMA_HW_EVENT_VCP2REVT = 28,   // VCP2 Receive Event
  EDMA_HW_EVENT_VCP2XEVT = 29,   // VCP2 Transmit Event
  EDMA_HW_EVENT_TCP2AREVT = 30,  // TCP2_A Receive Event
  EDMA_HW_EVENT_TCP2AXEVT = 31,  // TCP2_A Transmit Event
  EDMA_HW_EVENT_UREVT = 32,      // UTOPIA Receive Event
  EDMA_HW_EVENT_TCP2BREVT = 33,  // TCP2_B Receive Event
  EDMA_HW_EVENT_TCP2BXEVT = 34,  // TCP2_B Transmit Event
  EDMA_HW_EVENT_NONE_35 = 35,
  EDMA_HW_EVENT_NONE_36 = 36,
  EDMA_HW_EVENT_NONE_37 = 37,
  EDMA_HW_EVENT_NONE_38 = 38,
  EDMA_HW_EVENT_NONE_39 = 39,
  EDMA_HW_EVENT_UXEVT = 40,      // UTOPIA Transmit Event
  EDMA_HW_EVENT_NONE_41 = 41,
  EDMA_HW_EVENT_NONE_42 = 42,
  EDMA_HW_EVENT_NONE_43 = 43,
  EDMA_HW_EVENT_ICREVT = 44,     // I2C Receive Event
  EDMA_HW_EVENT_ICXEVT = 45,     // I2C Transmit Event
  EDMA_HW_EVENT_NONE_46 = 46,
  EDMA_HW_EVENT_NONE_47 = 47,
  EDMA_HW_EVENT_GPINT0 = 48,     // GPIO Event 0
  EDMA_HW_EVENT_GPINT1 = 49,     // GPIO Event 1
  EDMA_HW_EVENT_GPINT2 = 50,     // GPIO Event 2
  EDMA_HW_EVENT_GPINT3 = 51,     // GPIO Event 3
  EDMA_HW_EVENT_GPINT4 = 52,     // GPIO Event 4
  EDMA_HW_EVENT_GPINT5 = 53,     // GPIO Event 5
  EDMA_HW_EVENT_GPINT6 = 54,     // GPIO Event 6
  EDMA_HW_EVENT_GPINT7 = 55,     // GPIO Event 7
  EDMA_HW_EVENT_GPINT8 = 56,     // GPIO Event 8
  EDMA_HW_EVENT_GPINT9 = 57,     // GPIO Event 9
  EDMA_HW_EVENT_GPINT10 = 58,    // GPIO Event 10
  EDMA_HW_EVENT_GPINT11 = 59,    // GPIO Event 11
  EDMA_HW_EVENT_GPINT12 = 60,    // GPIO Event 12
  EDMA_HW_EVENT_GPINT13 = 61,    // GPIO Event 13
  EDMA_HW_EVENT_GPINT14 = 62,    // GPIO Event 14
  EDMA_HW_EVENT_GPINT15 = 63     // GPIO Event 15
} EDMAChannelEvent_T;

typedef struct
{
  EDMA3_DRV_Handle edma;
  unsigned int channel;
  unsigned int tcc;
} EDMA_T;

// This function will:
// - create an instance (edma3InstanceId) for each EDMA3 hardware peripheral
// - provide a handle (hEdma) to the user instance of the EDMA mdoule
// DRV_create requires a globalConfig structure which contains the hardware resources
// available for this device (we used sampleEdma3GblCfgParams to accomplish this).
// DRV_open requires the initCfg structure to initialize the Driver Instance.
extern void edma_config(EDMA_T *EdmaObj);

// This function will:
// - allocate all the necessary channel resources and assign them to a channel Id
// - initialize the allocated PARAM registers (like ACNT, BCNT, etc.)
// - set the Options register to all default values
// - enable the IER register (inside EDMA3) to respond to allow an EDMA interrupt to be
//   generated
// The following are the default values that are used for the OPT register and LINK
// fields. If you desire to overide any of these defaults, copy this code and make the
// necessary modifications (as you can see we did below for the TCINTEN bit):
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_ITCCHEN, EDMA3_DRV_ITCCHEN_DIS);   //Intermediate Chaining DISABLED - default is DIS if not called
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_TCCHEN, EDMA3_DRV_TCCHEN_DIS);     //Chaining DISABLE - default is DIS if not called
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_ITCINTEN, EDMA3_DRV_ITCINTEN_DIS); //Intermediate interrupt enable DISABLED - default is DIS if not called
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_TCINTEN, EDMA3_DRV_TCINTEN_DIS);   //Interrupt enable DISABLED - default is DIS if not called
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_TCC, 0u);  //already set in EDMA3_DRV_requestChannel	 //TCC value - arbitrary
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_STATIC, EDMA3_DRV_STATIC_DIS);     //FIFO mode not used - so, we set it to zero - default is DIS if not called
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_SYNCDIM, EDMA3_DRV_SYNC_AB); 	    //Sync set to AB (we want an AB transfer after the manual start - not needed - already set to AB
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_SAM, EDMA3_DRV_ADDR_MODE_INCR); 		//Src Addr Mode = INCR - already set in EDMA3_DRV_setSrc/DstParams	//Address mode is INCR (not FIFO)
//	EDMA3_DRV_setOptField (hEdma,iChannel, EDMA3_DRV_OPT_FIELD_DAM, EDMA3_DRV_ADDR_MODE_INCR); 	    //Dst Addr Mode = INCR - already set in EDMA3_DRV_setSrc/DstParams
//  EDMA3_DRV_linkChannel (hEdma, iChannel, 0xFFFFu);	//Set link field to FFFF - no linking - this is the default if this API is not called
extern void edma_createChan(EDMA_T *EdmaObj, int16_t *Src, int16_t *Dst, int16_t buffer_size);

// This function will set the Event Enable Register (EER) bit corresponding to the
// channel we are using. To do this, we use EDMA3_DRV_TRIG_MODE_EVENT in the
// _enableTransfer call below.
// This function could be improved by returning the result.
extern void edma_start(EDMA_T EdmaObj);

// Check to see if the EDMA3 interrupt pending register (IPR) is set to one indicating
// that the transfer has completed. This is a blocking function - it will continue to
// poll the IPR bit and won't return until it becomes a 1.
// This function could be improved by returning the result. Also, adding a timeout
// feature would be an improvement.
extern void edma_wait(EDMA_T EdmaObj);;

// Check to see if the EDMA3 interrupt pending register (IPR) is set to one indicating
// that the transfer has completed. This is a one-time check - not a blocking
// function. The calling code can check the status and respond accordingly.
// tccStatus = TRUE or FALSE
extern unsigned short edma_check(EDMA_T EdmaObj);

// Delete (free) the current channel from the resource pool
extern void edma_deleteChan(EDMA_T EdmaObj);

// EDMA3_DRV_close is used to close an already opened EDMA3 Driver instance.
// EDMA3_DRV_delete deletes the driver instance and driver object.
extern void edma_release(EDMA_T EdmaObj);

/* ==========================    END OF FILE    =========================== */


#endif // EDMA3_H
