#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>
#include <taskmon.h>
#include <smarttrap.h>
#include <NetworkDebug.h>
#include <serial.h>
#include <pins.h>
#include <dspi.h>
#include <string.h>
#include <serial.h>
#include <utils.h>
#include <system.h>
#include <sim.h>
#include <i2cmaster.h>					// For I2C applications
#include <ucos.h>
#include <udp.h>
#include <stdlib.h>
#include <sim5441x.h>


void DSPI_setup(void);
void DAC_setup(void);


BYTE MUX_TX[38], MUX_RX[38];													// MUX TX Buffer. Not receiving data from the mux so MUX_RX might not be used...
BYTE DACTx_BUFF[3], DACRx_BUFF[10];											// DAC I2C Buffers
BYTE I2CStat;

extern "C" {
void UserMain(void * pd);
}

const char * AppName="SPI_DAC_Demo";

void UserMain(void * pd) {
    InitializeStack();
    if (EthernetIP == 0) GetDHCPAddress();
    OSChangePrio(MAIN_PRIO);
    EnableAutoUpdate();

    #ifdef _DEBUG
    InitializeNetworkGDB();
    #endif

    iprintf("Application started\n");

    J1[9].function(0);					// mux input
    J1[5].function(0);					// mux CS line
    J1[5] = 1;
    J1[6].function(0);					// mux WR line
    J1[6] = 1;
    J1[7].function(0);					// mux EN line
    J1[7] = 1;
    J2[16].function(0);					// DAC LDAC pin as GPIO
    J2[16] = 1;							// pulled high to prevent writing
    J2[44].function(0);					// DAC reset pin as GPIO
    J2[44] = 0;							// Pulled low for normal operation. Hardware inverted for reset.



    // DSPI_setup();
    DAC_setup();

    while (1)
    {
    	WORD data_counter;
    	data_counter = 0;
    	for (int i = 0; i < 100; i++)
    	{
    		data_counter = data_counter + 0x028F;
    		DACTx_BUFF[0] = 0x12;											// write to dac B command
    		DACTx_BUFF[1] = 0x00 | ((data_counter && 0xFF00) >> 8);			// DACs at half range
    		DACTx_BUFF[3] = 0x00 | (data_counter && 0x00FF);				// DACs at half range
    		J2[16] = 0;														// lower LDAC pin to latch command
    		I2CStat = I2CSendBuf(0x0C, DACTx_BUFF, 3, true);				// Load DAC data
    		J2[16] = 1;														// raise LDAC pin to latch command
    		for (int t = 0; t < 25000000; t++);								// delay before sending next output ~ 100ms
    	}

    	OSTimeDly(TICKS_PER_SECOND * 5);

    	for (int i = 0; i < 100; i++)
    	{
    		data_counter = data_counter - 0x028F;
    		DACTx_BUFF[0] = 0x12;											// write to dac B command
    		DACTx_BUFF[1] = 0x00 | ((data_counter && 0xFF00) >> 8);			// DACs at half range
    		DACTx_BUFF[3] = 0x00 | (data_counter && 0x00FF);				// DACs at half range
    		J2[16] = 0;														// lower LDAC pin to latch command
    		I2CStat = I2CSendBuf(0x0C, DACTx_BUFF, 3, true);				// Load DAC data
    		J2[16] = 1;														// raise LDAC pin to latch command
    		for (int t = 0; t < 25000000; t++);								// delay before sending next output ~ 100ms
    	}


    }

}


void DSPI_setup(void)
{
	// SPI initialization (see DSPItoSerial example):
	// SPI 1 for GPIO break-out
	J2[27].function(3);										//SPI 1 Input
	J2[28].function(3);										//SPI 1 Out
	J2[30].function(3);										//SPI 1 chip select 0
	J2[25].function(3);										//SPI 1 clock

	/*

	DSPIInit() function definition:

	void DSPI1Init( BYTE SPIModule = 1, DWORD Baudrate = 10000000,
	BYTE QueueBitSize = 0x8, BYTE CS = 0x0F,
	BYTE CSPol = 0x0F, BYTE ClkPolarity = 0x0,
	BYTE ClkPhase = 0x1, BOOL DoutHiz = TRUE,
	BYTE csToClockDelay = 0, BYTE delayAfterTransfer = 0 );

	 */

	/*
	 *		For DSPI1 (8 bit GPIO Breakout - see dspi.h for more details)
	 *
	 * 		SPIModule = 1
	 * 		Baudrate = 10MHz
	 * 		QueueBitSize = 8 bits
	 * 		CS = 0x0F (CS low active)
	 * 		CSPol = 0x0F (Follows CS)
	 * 		ClkPolarity = 0x0 (rising edge)
	 * 		ClkPhase = 0x1 (latches on falling edge)
	 * 		DoutHiz = true (high impedance output)
	 * 		csToClockDelay = 0 (delay between CS and Clk going high = close to half a clock cycle)
	 * 		DelayAfterTransfer = 0 (delay between transfers)
	 *
	 */


	// Load startup values into MUX
	// be sure to load MUX values into MYX_TX

	DSPIStart(1, MUX_TX, MUX_RX, 1, NULL, true);
	while(!DSPIdone(3));
}

void DAC_setup(void)
{

	/*
	 *					DAC setup - several modes.
	 *
	 *					Setting up the DAC functions (power and reference) requires sending the data, pulling LDAC low for 20ns
	 *
	 *					Sending data using command 0001 can be done by holding LDAC low, sending data, then pulling LDAC hi. This will
	 *					instantly set the data at the 24th clock pulse.
	 *
	 *					Sending the data, then pulsing LDAC low for 20ns asynchronously updated (slight delay - 10us?)
	 *
	 * 					Shutting off the external reference which is on by default at reset - send code 0x7F0000
	 *
	 * 					Shutting down DAC D (unused at this point) and powering up the rest - send code 0x7FC000 (D is floating - tristate)
	 *
	 * 																						- send code 0x7F8000 (D is connected to a 100k resistor to gnd internally)
	 *
	 *
	 */


	OSLock();
	// I2C DAC configured to initialize with 0 output
	J2[39].function(2);										// I2C 0 SDA line
	J2[42].function(2);										// I2C 0 SCL line
	I2CInit(0x34);											// 400kHz mode  (390.625 kHz) - default is 0x37 - 250kHz

	// DAC setup code #1 = 0x7F0000  - this sets up the DAC to shut off the 2.5V reference pin - which is connected to  the 5V external reference so we can use that instead.
	DACTx_BUFF[0] = 0x7F;											// write to all DACS
	DACTx_BUFF[1] = 0x00;											// DAC REF off  see page 25 of datasheet
	DACTx_BUFF[3] = 0x00;											// DAC ref off  see p 25 of datasheet
	I2CStat = I2CSendBuf(0x0, DACTx_BUFF, 3, true);					// load DAC data
	J2[16] = 0;														// lower LDAC pin to latch command
	for(int t=0; t<1; t++);											// may not need this delay - need a 20ns delay after loading the DAC
    J2[16] = 1;														// raise LDAC pin to set command

    for(int t = 0; t < 2500000; t++); 								// delay before next command is sent. Should provide ample time for DAC to set (~10us)

	// DAC setup code #1 = 0x7F0000  - this sets up the DAC to shut off the 2.5V reference pin - which is connected to  the 5V external reference so we can use that instead.
	DACTx_BUFF[0] = 0x7F;											// write to all DACS
	DACTx_BUFF[1] = 0xC0;											// DAC D off and tristate (floating)
	DACTx_BUFF[3] = 0x00;											// DAC A, B, C powered up fully
	I2CStat = I2CSendBuf(0x0, DACTx_BUFF, 3, true);					// load DAC data
	J2[16] = 0;														// lower LDAC pin to latch command
	for(int t=0; t<1; t++);											// may not need this delay - need a 20ns delay after loading the DAC
    J2[16] = 1;														// raise LDAC pin to set command

    for(int t = 0; t < 250000; t++); 								// delay before next command is sent. Should provide ample time for DAC to set (~10 us)

	OSUnlock();
	return;
}



