/*
 * File: DMA0 irq to DMA1 trigger
 * bit outputs on RA0 and RB0
 * Bruce Land
 * Target PIC:  PIC32MX250F128B
 */
// all peripheral library includes
#include <plib.h>

#pragma config FNOSC = FRCPLL, POSCMOD = OFF
//#pragma config FNOSC = PRIPLL, POSCMOD = EC, OSCIOFNC = OFF
#pragma config FPLLIDIV = DIV_2, FPLLMUL = MUL_20, FPLLODIV = DIV_2  //40 MHz
#pragma config FPBDIV = DIV_1 // PB 40 MHz
// turn off alternative functions for port pins B.4 and B.5
#pragma config JTAGEN = OFF, DEBUG = OFF
#pragma config FSOSCEN = OFF

// DMA tables
unsigned char LED_pattern0[]=
{
	0x01,	0x00,	0x01,	0x00,	0x01,	0x00,	0x01,	0x00,
	0x01,	0x00,	0x01,	0x00,	0x01,	0x00,	0x01,	0x00
};
// DMA tables
unsigned char	LED_pattern1[]=
{
	0x01,	0x01,	0x00,	0x00,	0x01,	0x01,	0x00,	0x00,
	0x01,	0x01,	0x00,	0x00,	0x01,	0x01,	0x00,	0x00
};

// to clear bits in DMA 0 flag register
// using DMA 1 transfer
unsigned short clear_flag = 0x0000 ;

//////////////////////////////////// 

 // handler for the DMA channel 0 interrupt
//void __ISR(_DMA0_VECTOR, IPL5SOFT) DmaHandler0(void)
//{
	//INTClearFlag(INT_SOURCE_DMA(DMA_CHANNEL0));	// clear int
    //DmaChnClrEvFlags(DMA_CHANNEL0, DMA_EV_CELL_DONE); // clear specific DMA event
//}

// === Main  ======================================================
void main(void) {
 
    SYSTEMConfig(40000000, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
  
  // === timer2 =================================
    // Set up timer2 on,  no interrupts, internal clock, prescalar 1, toggle rate
    OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_1, 40); // 30 works
	// !!!NO ISR TURNED ON!!!!!

  // === DMA setup  =====================
    // Open the desired DMA channels.
	// Enable the AUTO option 
	DmaChnOpen(0, 0, DMA_OPEN_AUTO);
    DmaChnOpen(1, 0, DMA_OPEN_AUTO);
    DmaChnOpen(2, 0, DMA_OPEN_AUTO);
    
	// set the transfer parameters: source & destination address, source & destination size, 
	// number of bytes per event
    DmaChnSetTxfer(0, LED_pattern0, (void*)&LATA, 16, 1, 1);
    DmaChnSetTxfer(1, &clear_flag, (void*)&DCH0INT, 2, 2, 2);
    DmaChnSetTxfer(2, LED_pattern1, (void*)&LATB, 16, 1, 1);

	// set the transfer event control: what event is to start the DMA transfers
        // In this case, timer2 for channel 0
        // and cell tranfer done on DMA0 for channel 1
        // and cell tranfer done on DMA0 for channel 2
	DmaChnSetEventControl(0, DMA_EV_START_IRQ(_TIMER_2_IRQ));
    DmaChnSetEventControl(1, DMA_EV_START_IRQ(_DMA0_IRQ)); 
    DmaChnSetEventControl(2, DMA_EV_START_IRQ(_DMA0_IRQ)); 
	
    // needed to set up cell done enable
    DmaChnSetEvEnableFlags(0, DMA_EV_CELL_DONE);
    
    // start the channels
    DmaChnEnable(0);
    DmaChnEnable(1);
    DmaChnEnable(2);
    
    /*	
	// enable system wide multi vectored interrupts
    INTConfigureSystem(INT_SYSTEM_CONFIG_MULT_VECTOR);
	INTEnableInterrupts();
	INTSetVectorPriority(INT_VECTOR_DMA(0), INT_PRIORITY_LEVEL_5);		// set INT controller priority
	INTSetVectorSubPriority(INT_VECTOR_DMA(0), INT_SUB_PRIORITY_LEVEL_3); // set INT controller sub-priority
    // enable DMA chn 0 cell done
    DmaChnSetEvEnableFlags(0, DMA_EV_CELL_DONE);
    // turn on dma 0 interrupt
	INTEnable(INT_SOURCE_DMA(0), INT_ENABLED);		// enable the chn interrupt in the INT controller
    */
    
    // set up i/o port pin
    ANSELA =0; // turn off analog on A
    ANSELB =0; // turn off analog on B
    mPORTAClearBits(BIT_0 );		//Clear A bits to ensure light is off.
    mPORTASetPinsDigitalOut(BIT_0 );    //Set A port as output
    mPORTBClearBits(BIT_0 );		//Clear B bits to ensure light is off.
    mPORTBSetPinsDigitalOut(BIT_0 );    //Set B port as output
    
	while(1){
        //if(DmaChnGetIntFlag(0)) {
           // mPORTAToggleBits(BIT_1);
            //DmaChnClrIntFlag(0);
        //}
        //DmaChnEnable(0);
    };   
  } // main

// === end  ======================================================

