using System;
using Microsoft.SPOT;

using Microsoft.SPOT.Hardware;
using System.Threading;
using System.Text;

namespace CPF
{
    class ADC2485
    {
        private static I2CDevice.Configuration config2485 = new I2CDevice.Configuration(0x26, 400);
        private static I2CDevice.I2CTransaction[] xActions2485 = new I2CDevice.I2CTransaction[2];

        private static byte[] sampleBytes = new byte[4];
        private static byte[] convertBytes = new byte[4];
        private static byte[] mode0 = new byte[1] { 0x00 };//External input, 50 and 60 Hz filter, 1X speed
        private static byte[] mode4 = new byte[1] { 0x04 };//External input, 60 Hz filter, 1X speed

        private static int xActionReturn;
        private static int value;

        private static double voltage;
        private static double position;
        private const double sensorLength = 250.1;
        private static float volts;

        public static double readBellowsPosition()
        {
            Program.g400I2C.Config = config2485;

            // create write buffer, send 2485 mode command
            xActions2485[0] = I2CDevice.CreateWriteTransaction(mode4);

            // create read buffer to read the returned data
            xActions2485[1] = I2CDevice.CreateReadTransaction(sampleBytes);

            //startTime = Utility.GetMachineTime();
            xActionReturn = Program.g400I2C.Execute(xActions2485, 1000);
            Thread.Sleep(200);
            xActionReturn = Program.g400I2C.Execute(xActions2485, 1000);
            //endTime = Utility.GetMachineTime();
            //diffTime = endTime - startTime;
            //Debug.Print("I2C Transaction Done, time diff = " + diffTime.ToString());

            if (xActionReturn == 0)
            {
                EngrLogger.writeToColumns("Error executing 2485 Transaction = " + xActionReturn.ToString());
                return double.NaN;
            }
            else
            {
                //Debug.Print(sampleBytes[0].ToString() + " " + sampleBytes[1].ToString() + " " +
                //            sampleBytes[2].ToString() + " " + sampleBytes[3].ToString());

                if ((sampleBytes[0] >= (byte)0xC0) || (sampleBytes[0] < (byte)0x40))
                {
                    EngrLogger.writeToColumns("2485 Sample out of range");
                    return (double.NaN);
                }
                else
                {
                    convertBytes[0] = sampleBytes[3];
                    convertBytes[1] = sampleBytes[2];
                    convertBytes[2] = sampleBytes[1];
                    convertBytes[3] = sampleBytes[0];
                    value = GHI.Utilities.Arrays.ExtractInt32(convertBytes, 0);

                    value = (int)(value ^ 0x80000000);  //Need to invert the msb per 2485 data sheet
                    //Debug.Print("ADC Value = " + value.ToString());
                    volts = (float)value;
                    voltage = 2.5 + (5.0 * (double)volts / 2147483648.0);
                    //Debug.Print("Voltage = " + voltage.ToString() + "\r\n");
                    position = (voltage - 0.1) * (sensorLength / 4.8);
                    //Debug.Print("Position = " + position.ToString());
                    return (position);
                }
            }
        }
    }
}
