using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace A103_SDK
{
    public partial class Form1 : Form
    {
        //*************************************
        //  A103 SDK Sample for C# 
        //  Ver:250108
        //  www.smartxbw.com
        //*************************************

        jClass_GPIO jc_GPIO = new jClass_GPIO();

        UInt16 iSlaveAdd_IOExt = 0x74;

        public Form1()
        {
            InitializeComponent();
        }

        private void button_OpenAdapter_Click(object sender, EventArgs e)
        {
            DeviceOpen();
        }

        private void DeviceOpen()
        {
            bool bA = jClass_FT4222.DeviceOpen("A");
            bool bB = jClass_FT4222.DeviceOpen("B");
            bool bC = jClass_FT4222.SetClockRate(60);

            if ((bA == true) && (bB == true) && (bC == true))
            {
                jc_GPIO.GPIO23_Init();
                label_AdapterStatus.Text = "Adapter status: Open success !";
            }
            else
            {
                label_AdapterStatus.Text = "Adapter status: Open failed !";

                bool bCloseA = jClass_FT4222.DeviceClose("A");
                bool bCloseB = jClass_FT4222.DeviceClose("B");
            }
        }

        private void DeviceClose()
        {
            bool bA = jClass_FT4222.DeviceClose("A");
            bool bB = jClass_FT4222.DeviceClose("B");

            label_AdapterStatus.Text = "Adapter status: Is closed !";
        }

        private void button_CloseAdapter_Click(object sender, EventArgs e)
        {
            DeviceClose();
        }

        private void Config_Init()
        {
            jc_GPIO.IOx_Index_SetOut(0x03);
            jc_GPIO.IOx_Index_SetValue(0x03, 1);

            jClass_FT4222.FT4222_I2CMaster_Init(jClass_FT4222.ftHandle, 100);
        }

        private bool Config_Set_VIO_2(UInt16 iValue)
        {
            UInt16 iSizeTransferred = 0;

            byte[] writeBuffer = new byte[3];
            writeBuffer[0] = 0x60;
            writeBuffer[1] = (byte)(iValue >> 8);
            writeBuffer[2] = (byte)(iValue & 0xFF);

            //jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)iWriteArrLen, ref iSizeTransferred);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, (UInt16)0x61, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
                return (true);

            return (false);
        }

        //VIO: 1.7~3.3
        private bool Config_Set_VIO(double VIO)
        {
            Config_Init();

            UInt16 iValue = (UInt16)(((2 * VIO - 3.3) / 3.3) * 65535);
            bool bValue = Config_Set_VIO_2(iValue);

            return (bValue);
        }

        private void button_Config_SetVIO_Click(object sender, EventArgs e)
        {
            //VIO From 1.7~3.3V
            Config_Set_VIO(3.0); //Set VIO=3.0V

            //Config_Set_VIO(1.7); //Set VIO=1.7V
            //Config_Set_VIO(3.3); //Set VIO=3.3V
        }

        private bool IOExp_I2C_PulUp_Set(byte PullUp)
        {
            Config_Init();

            UInt16 iSizeTransferred = 0;

            byte[] writeBuffer = new byte[2];

            writeBuffer[0] = 0x03;
            writeBuffer[1] = 0xFF;
            //jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)iWriteArrLen, ref iSizeTransferred);
            //if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, (UInt16)0x20, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, iSlaveAdd_IOExt, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
                return (false);

            writeBuffer[0] = 0x07;
            writeBuffer[1] = PullUp;
            //jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)iWriteArrLen, ref iSizeTransferred);
            //if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, (UInt16)0x20, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, iSlaveAdd_IOExt, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
                return (false);

            return (true);
        }

        private void button_Config_SetI2CPullup_Click(object sender, EventArgs e)
        {
            //IOExp_I2C_PulUp_Set(0xBB); //I2C Pull up resistance=5.1K            
            //IOExp_I2C_PulUp_Set(0xEE); //I2C Pull up resistance=1K
            //IOExp_I2C_PulUp_Set(0xFF); //I2C Pull up resistance=NC
            //IOExp_I2C_PulUp_Set(0x00); //I2C Pull up resistance=680R

            IOExp_I2C_PulUp_Set(0xDD); //I2C Pull up resistance=3.9K
        }

        private void I2C_Init()
        {
            jc_GPIO.IOx_Index_SetOut(0x03);
            jc_GPIO.IOx_Index_SetValue(0x03, 0);

            jClass_FT4222.FT4222_I2CMaster_Init(jClass_FT4222.ftHandle, 100); //100Kbps
            //jClass_FT4222.FT4222_I2CMaster_Init(jClass_FT4222.ftHandle, 400); //400Kbps
            //jClass_FT4222.FT4222_I2CMaster_Init(jClass_FT4222.ftHandle, 3400); //3.4Mbps
        }

        private void button_I2C_Read_Click(object sender, EventArgs e)
        {
            I2C_Init();

            //E2PROM is AT24C02

            //Set E2PROM's address=0x20
            UInt16 slaveAddress = 0x51;
            UInt16 iSizeTransferred = 0;
            byte[] writeBuffer = new byte[1];
            writeBuffer[0] = 0x20;

            bool bStatus; //True--Success; False--Failed

            //jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)iWriteArrLen, ref iSizeTransferred);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)(writeBuffer.Length), ref iSizeTransferred))
                bStatus = false;
            else
                bStatus = true;


            //Read two bytes from E2PROM.Current Address=0x20;            
            UInt16 bytesToRead = 2;
            byte[] buffer = new byte[bytesToRead];
            //FT4222_STATUS jClass_FT4222.FT4222_I2CMaster_Read((IntPtr ftHandle, UInt16 slaveAddress, ref byte buffer, UInt16 bytesToRead, ref UInt16 sizeTransferred);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Read(jClass_FT4222.ftHandle, slaveAddress, ref buffer[0], bytesToRead, ref iSizeTransferred))
                bStatus = false;
            else
                bStatus = true;
        }

        private void button_I2C_Write_Click(object sender, EventArgs e)
        {
            I2C_Init();

            //E2PROM is AT24C02

            //Write two bytes to E2PROM's address=0x20;
            UInt16 iSizeTransferred = 0;
            UInt16 slaveAddress = 0x51;
            byte[] writeBuffer = new byte[3];
            writeBuffer[0] = 0x20; //E2PROM's Address
            writeBuffer[1] = 0xA1; //Data1
            writeBuffer[2] = 0x92; //Data2
            bool bStatus; //True--Success; False--Failed

            //jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)iWriteArrLen, ref iSizeTransferred);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK != jClass_FT4222.FT4222_I2CMaster_Write(jClass_FT4222.ftHandle, slaveAddress, ref writeBuffer[0], (ushort)3, ref iSizeTransferred))
                bStatus = false;
            else
                bStatus = true;   
        }

        private void button_SPI_SingleReadWrite_Click(object sender, EventArgs e)
        {
            bool bStatus; //True--Success; False--Failed

            //Demo code.You need modify the code for your application.

            //SPI Clk=468K
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_Init(jClass_FT4222.ftHandle, jClass_FT4222.FT4222_SPIMode.SPI_IO_SINGLE, jClass_FT4222.FT4222_SPIClock.CLK_DIV_128, jClass_FT4222.FT4222_SPICPOL.CLK_IDLE_LOW, jClass_FT4222.FT4222_SPICPHA.CLK_LEADING, 0x01))
                bStatus = true;
            else
                bStatus = false;

            UInt16 iSizeTransferred = 0;
            bool isEndTransaction = true;
            byte[] readBuf = new byte[2];
            byte[] writeBuf = new byte[2];
            writeBuf[0] = 0x12;
            writeBuf[1] = 0x34;

            //jClass_FT4222.FT4222_STATUS FT4222_Status = jClass_FT4222.FT4222_SPIMaster_SingleReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf[0], (ushort)writeBuf_Length, ref iSizeTransferred, isEndTransaction);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_SingleReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf[0], (ushort)(writeBuf.Length), ref iSizeTransferred, isEndTransaction))
                bStatus = true;
            else
                bStatus = false;
        }

        private void button_QSPI_MultiReadWrite_Click(object sender, EventArgs e)
        {
            bool bStatus; //True--Success; False--Failed

            //Demo code.You need modify the code for your application.

            //Init Multi SPI
            //SPI Clk=468K
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_Init(jClass_FT4222.ftHandle, jClass_FT4222.FT4222_SPIMode.SPI_IO_QUAD, jClass_FT4222.FT4222_SPIClock.CLK_DIV_128, jClass_FT4222.FT4222_SPICPOL.CLK_IDLE_LOW, jClass_FT4222.FT4222_SPICPHA.CLK_LEADING, 0x01))
                bStatus = true;
            else
                bStatus = false;

            //Mulit ReadWrite
            byte[] readBuf = new byte[2];
            byte[] writeBuf_Combo = new byte[3];
            writeBuf_Combo[0] = 0x12; //Single Write
            writeBuf_Combo[1] = 0x34; //Multi Write
            writeBuf_Combo[2] = 0x56; //Multi Write
            UInt32 sizeOfRead = 0;
            //jClass_FT4222.FT4222_STATUS FT4222_Status = jClass_FT4222.FT4222_SPIMaster_MultiReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf_Combo[0], (byte)i_singleWriteBuf_Length, (UInt16)i_multiWriteBuf_Length, (UInt16)multiReadBytes, ref iSizeOfRead);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_MultiReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf_Combo[0], 1, 2, 3, ref sizeOfRead))
                bStatus = true;
            else
                bStatus = false;
        }

        private void button_DSPI_MultiReadWrite_Click(object sender, EventArgs e)
        {
            bool bStatus; //True--Success; False--Failed

            //Demo code.You need modify the code for your application.

            //Init Multi SPI
            //SPI Clk=468K
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_Init(jClass_FT4222.ftHandle, jClass_FT4222.FT4222_SPIMode.SPI_IO_DUAL, jClass_FT4222.FT4222_SPIClock.CLK_DIV_128, jClass_FT4222.FT4222_SPICPOL.CLK_IDLE_LOW, jClass_FT4222.FT4222_SPICPHA.CLK_LEADING, 0x01))
                bStatus = true;
            else
                bStatus = false;

            //Mulit ReadWrite
            byte[] readBuf = new byte[2];
            byte[] writeBuf_Combo = new byte[3];
            writeBuf_Combo[0] = 0x12; //Single Write
            writeBuf_Combo[1] = 0x34; //Multi Write
            writeBuf_Combo[2] = 0x56; //Multi Write
            UInt32 sizeOfRead = 0;
            //jClass_FT4222.FT4222_STATUS FT4222_Status = jClass_FT4222.FT4222_SPIMaster_MultiReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf_Combo[0], (byte)i_singleWriteBuf_Length, (UInt16)i_multiWriteBuf_Length, (UInt16)multiReadBytes, ref iSizeOfRead);
            if (jClass_FT4222.FT4222_STATUS.FT4222_OK == jClass_FT4222.FT4222_SPIMaster_MultiReadWrite(jClass_FT4222.ftHandle, ref readBuf[0], ref writeBuf_Combo[0], 1, 2, 3, ref sizeOfRead))
                bStatus = true;
            else
                bStatus = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void button_GPIO2_Output_Init_Click(object sender, EventArgs e)
        {
            jc_GPIO.IOx_Index_SetOut(0x02);
        }

        private void button_GPIO2_Output_0_Click(object sender, EventArgs e)
        {
            jc_GPIO.IOx_Index_SetValue(0x02, 0);
        }

        private void button_GPIO2_Output_1_Click(object sender, EventArgs e)
        {
            jc_GPIO.IOx_Index_SetValue(0x02, 1);
        }

        private void button_GPIO2_Input_Init_Click(object sender, EventArgs e)
        {
            jc_GPIO.IOx_Index_SetIn(0x02);   
        }

        private void button_GPIO2_Input_Read_Click(object sender, EventArgs e)
        {
            byte IO_Read_Value = jc_GPIO.IOx_Index_ReadBit(0x02);

            textBox_GPIO2_Input_Read.Text = IO_Read_Value.ToString();
        }
    }//============
}
