/****************************** TI 28004x *********************************\
 * @Module:       main.c
 * @Description:  Testing basic DMA transfer functionality
 ***************************************************************************/
#include "F28x_Project.h"
#include "f28004x_device.h"
#include "f28004x_globalprototypes.h"

#include "driverlib.h"  // header to TI2800

Uint32 RunCount = 0;
Uint32 dmaIntCount = 0;
Uint16 dmaXferTestSource[16]     ={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
Uint16 dmaXferTestDestination[16]={0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0};

__interrupt void adcDmaXferCompleteIsr(void);
void dmaConfig(void);

/*
 * @Function: main()
 */
void main(void)
{
    // Initialize device clock and peripherals
    InitSysCtrl();

    // Initialize GPIO
    InitGpio();

    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;

    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    InitPieVectTable();

    dmaConfig();

    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    EINT;
    ERTM;

    for (;;)
    {
        // Delay half a second
        DELAY_US(500000);

		// force DMA trigger so that the device will do a transfer
		DMA_forceTrigger(DMA_CH1_BASE);

        ++RunCount;
    }
}


// adcDmaXferCompleteIsr - this will be used to sync our control algorithm 
__interrupt void adcDmaXferCompleteIsr(void)
{
    dmaIntCount++;
	
	// if setup then signal control algorithm

    // Clear the interrupt flag and issue ACK
    DMA_clearTriggerFlag(DMA_CH1_BASE);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP7);
}


void dmaConfig(void)
{
    // Initialize DMA
    DMA_initController();

    // Configure DMA Ch1 to transfer data between two RAM buffers
    DMA_configAddresses(DMA_CH1_BASE, &dmaXferTestDestination[0], (const void *)&dmaXferTestSource[0]);
    DMA_configBurst(DMA_CH1_BASE, 15, 1, 1);   // burst of 16 words of 16 bits each therefore steps are set to 1
    DMA_configTransfer(DMA_CH1_BASE, 1, 0, 0); // transfer requires only 1 burst
    DMA_configWrap(DMA_CH1_BASE,1,-15,1,-15);  // wrap addresses back to start of buffers after a single transfer
    DMA_configMode(DMA_CH1_BASE,
                   DMA_TRIGGER_SOFTWARE,       // make this software trigger for now, should be triggered by last ADC channel interrupt
                   DMA_CFG_ONESHOT_ENABLE |    // allow the next burst to take place without additional triggers
                   DMA_CFG_CONTINUOUS_ENABLE | // leave channel enabled and ready for next trigger
                   DMA_CFG_SIZE_16BIT);        // transfer 16 bit words for now, preferably 32bit which will require adjusted steps and number of words above

    // Configure DMA Ch1 interrupt
    DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);  // Set device interrupt mode for end of each transfer
    DMA_enableInterrupt(DMA_CH1_BASE);                   // allow this device to generate the interrupt
    DMA_enableTrigger(DMA_CH1_BASE);                     // allow trigger to fire the device
    DMA_startChannel(DMA_CH1_BASE);                      // start the device

    Interrupt_register(INT_DMA_CH1, &adcDmaXferCompleteIsr);  // map DMA interrupt to my ISR
    Interrupt_enable(INT_DMA_CH1);                             // enable DMA interrupt
}
