using System;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHI.Pins;


namespace CPF
{
    class CN0254
    {
        //private static SPI.Configuration CN2054Config = new SPI.Configuration((Cpu.Pin)GHI.Hardware.EMX.Pin.IO18, false, 100, 100, false, true, 1000, SPI.SPI_module.SPI1);
        private static SPI.Configuration CN0254Config = new SPI.Configuration(G400.PC29, false, 0, 0, false, true, 100, SPI.SPI_module.SPI2);
        private static SPI CN2054spi = new SPI(CN0254Config);

        private static ushort[] txData = new ushort[1];
        private static ushort[] rxData = new ushort[1];

        private static ushort[] configWord = new ushort[8];

        private static double[] voltage = new double[8];
        private static int[] rxShort = new int[8];

        private static double voltAccum = 0.0;
        private static int shortAccum = 0;

        //It take 2 samples before config word takes effect, see AD7689 data sheet timing diagrams
        private static int numBogusChannels = 2;
        private static int numAverages = 10;     //seems to be a problem with averaging on the Raptor
        private static int numChannels = 8;
        private static int startCh = 0;

        public static double[] scanAll()
        {
            double volts = 0.0;

            //txData[0] = 0x3FFF;     //Default
            configWord[0] = 0xF004;     //sequencer disabled, ch0 only. 1/4 BW filter
            configWord[1] = 0xF204;     //sequencer disabled, ch1 only. 1/4 BW filter
            configWord[2] = 0xF404;     //sequencer disabled, ch2 only. 1/4 BW filter
            configWord[3] = 0xF604;     //sequencer disabled, ch3 only. 1/4 BW filter
            configWord[4] = 0xF804;     //sequencer disabled, ch4 only. 1/4 BW filter
            configWord[5] = 0xFA04;     //sequencer disabled, ch5 only. 1/4 BW filter
            configWord[6] = 0xFC04;     //sequencer disabled, ch6 only. 1/4 BW filter
            configWord[7] = 0xFE04;     //sequencer disabled, ch7 only. 1/4 BW filter

            for (int chNum = startCh; chNum < (startCh + numChannels); chNum++)
            {
                volts = 0.0;
                voltAccum = 0.0;
                shortAccum = 0;
                txData[0] = configWord[chNum];
                for (int sampleNum = 0; sampleNum < numAverages + numBogusChannels; sampleNum++)
                {
                    CN2054spi.WriteRead(txData, rxData);

                    if (sampleNum > (numBogusChannels - 1))
                    {
                        //This converts the ADC output to voltage at the input to the ADC
                        volts = (3.81476E-05 * rxData[0]) + -6.35783E-06;
                        //This converts the voltage at the input to the ADC to the voltage at the input to the ADC buffer
                        volts = (volts - 1.251586) * -4.99;

                        voltAccum = voltAccum + volts;
                        shortAccum = shortAccum + rxData[0];
                    }
                }
                voltage[chNum] = voltAccum / numAverages;
                rxShort[chNum] = shortAccum / numAverages;

                //Debug.Print("CH " + chNum.ToString() + " " + rxShort[chNum].ToString() + "   " + voltage[chNum].ToString("F3"));
                //Debug.Print(" ");
            }
            return (voltage);
        }
    }
}

//Table 10. Configuration Register Description 
//Bit(s) Name Description 
//[13] CFG Configuration update. 
// 0 = keep current configuration settings. 
// 1 = overwrite contents of register. 
//[12:10] INCC Input channel configuration. Selection of pseudo bipolar, pseudo differential, pairs, single-ended, or temperature sensor. Refer 
//to the Input Configurations section. 
// Bit 12 Bit 11 Bit 10 Function 
// 0 0 X1 Bipolar differential pairs; INx− referenced to VREF/2 ± 0.1 V. 
// 0 1 0  Bipolar; INx referenced to COM = VREF/2 ± 0.1 V. 
// 0 1 1  Temperature sensor. 
// 1 0 X1 Unipolar differential pairs; INx− referenced to GND ± 0.1 V. 
// 1 1 0  Unipolar, INx referenced to COM = GND ± 0.1 V. 
// 1 1 1  Unipolar, INx referenced to GND. 
//[9:7] INx Input channel selection in binary fashion. 
// AD7689 
// Bit 9    Bit 8   Bit 7 Channel 
//  0       0       0 IN0 
//  0       0       1 IN1 
//  1       1       1 IN7 
//[6] BW Select bandwidth for low-pass filter. Refer to the Selectable Low-Pass Filter section. 
//0 = ¼ of BW, uses an additional series resistor to further bandwidth limit the noise. Maximum throughput must also be reduced to ¼. 
//1 = full BW. 
//[5:3] REF Reference/buffer selection. Selection of internal, external, external buffered, and enabling of the on-chip temperature sensor. 
//Refer to the Voltage Reference Output/Input section. 
// Bit 5    Bit 4   Bit 3 Function 
// 0        0       0 Internal reference, REF = 2.5 V output, temperature enabled. 
// 0        0       1 Internal reference, REF = 4.096 V output, temperature enabled. 
// 0        1       0 External reference, temperature enabled. 
// 0        1       1 External reference, internal buffer, temperature enabled. 
// 1        1       0 External reference, temperature disabled. 
// 1        1       1 External reference, internal buffer, temperature disabled. 
//[2:1] SEQ Channel sequencer. Allows for scanning channels in an IN0 to IN[7:0] fashion. Refer to the Channel Sequencer section. 
// Bit 2    Bit 1 Function 
//  0       0 Disable sequencer. 
//  0       1 Update configuration during sequence. 
//  1       0 Scan IN0 to IN[7:0] (set in CFG[9:7]), then temperature. 
//  1       1 Scan IN0 to IN[7:0] (set in CFG[9:7]). 
//[0] RB Read back the CFG register. 
// 0 = read back current configuration at end of data. 
// 1 = do not read back contents of configuration. 