/*********************************************************************
 *
 *                  DMA  transfer example 
 *
 *********************************************************************
 * FileName:        led_txfer.c
 * Dependencies:    plib.h
 *
 * Processor:       PIC32
 *
 * Compiler:        MPLAB XC32 v1 or higher
 *                  MPLAB IDE v8 or higher
 *
 * Author:    Bruce Land           Date:   May 2014
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/*********************************************************************
 *
 * This example blinks LEDs on the MIcroStickII board using a pattern stored in flash or RAM memory.
 * It uses the DMA controller to transfer data from flash to the I/O port controlling the LEDs.
 * The DMA transfer is initiated by a timer interrupt (we use the Timer23 in this example).
 * Once the pattern is completely transferred, the process is repeated.
 *
 ********************************************************************/
#include <plib.h>        /* PIC32 peripheral library */

#ifndef _DMAC
    #error "This example needs a PIC32MX processor with DMA controller present. Aborting build!"
#endif  // _DMAC


//  Configuration Bit settings
//  System Clock = 40 MHz,  Peripherial Bus = 40 MHz
//  Internal Osc w/PLL FNOSC = FRCPLL
//  Input Divider    2x Divider FPLLIDIV
//  Multiplier      20x Multiplier FPLLMUL
//  Output divider   2x Divider FPLLODIV
//  peripherial bus divider FPBDIV = 1
//  WDT disabled
//  Other options are don't care
//
#pragma config FNOSC = FRCPLL, POSCMOD = HS, FPLLIDIV = DIV_2, FPLLMUL = MUL_20, FPBDIV = DIV_1, FPLLODIV = DIV_2
#pragma config FWDTEN = OFF

#define	SYS_FREQ	40000000		// frequency we're running at


// type in the bytes that define the pattern that will be output to the LED's
// no longer than DmaGetMaxTxferSize()
// Rate varies in bust mode from 10 MHz to 5.5 MHz within the burst

// In Flash
static const unsigned char	LED_pattern[]=
{
	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,
	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,
};

/*
// In RAM
unsigned char	LED_pattern[]=
{
	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,       
	0xff,	0x00,	0xff,	0x00,	0xff,	0x00,	0xff,	0x00
};
*/
int main(void)
{
	int	dmaChn=0;		// the DMA channel to use

	// first let us set the LED I/O ports as digital outputs
        // PIN 2 on 28 pin PDIP
        mPORTAClearBits(BIT_0 );		//Clear bits to ensure light is off.
        mPORTASetPinsDigitalOut(BIT_0 );    //Set port as output

        // PIN 4 on 28 pin PDIP
        mPORTBClearBits(BIT_0);		//Clear bits to ensure light is off.
        mPORTBSetPinsDigitalOut(BIT_0 );    //Set port as output

	// Open the desired DMA channel.
	// We enable the AUTO option, we'll keep repeating the sam transfer over and over.
	DmaChnOpen(dmaChn, 0, DMA_OPEN_AUTO);

	// set the transfer parameters: source & destination address, source & destination size, number of bytes per event
        // Setting the last parameter to one makes the DMA output one byte/interrupt
	DmaChnSetTxfer(dmaChn, LED_pattern, (void*)&LATA, sizeof(LED_pattern), 1, 1);
        //DmaChnSetTxfer(dmaChn, LED_pattern, (void*)&LATA, sizeof(LED_pattern), 1, sizeof(LED_pattern));

	// set the transfer event control: what event is to start the DMA transfer
        // In this case, timer3 
	DmaChnSetEventControl(dmaChn, DMA_EV_START_IRQ(_TIMER_3_IRQ));

	// once we configured the DMA channel we can enable it
	// now it's ready and waiting for an event to occur...
	DmaChnEnable(dmaChn);


	// now use the 32 bit timer to generate an interrupt to start the
        // DMA burst ever 125 ticks
        OpenTimer23(T2_ON | T2_SOURCE_INT | T2_PS_1_1, 10); //125

        // Toggle a pin on a separate port to see how DMA affects normal execution
	while(1)
	{
		mPORTBToggleBits(BIT_0);
	}


}





