#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <iostream>

#include "gpio.h"
#include "gpioRegisters.h"
#include "iomux.h"

using namespace std;

void GPIO::InitializeGPIO(void)
{
	unsigned int uiTemp;

	//GM Get the default values before we play with anything
	DEBUGMSG(1, (_T("Initial GPIO Register Values\n")));
	uiTemp = regRead(IOMUX::GPR);
	DEBUGMSG(1, (_T("Initial GPR		= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::DR);
	DEBUGMSG(1, (_T("Initial DR		= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::GDIR);
	DEBUGMSG(1, (_T("Initial GDIR	= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::PSR);
	DEBUGMSG(1, (_T("Initial PSR		= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::ICR1);
	DEBUGMSG(1, (_T("Initial ICR1	= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::ICR2);
	DEBUGMSG(1, (_T("Initial ICR2	= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::IMR);
	DEBUGMSG(1, (_T("Initial IMR		= 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::ISR);
	DEBUGMSG(1, (_T("Initial ISR		= 0x%8x\n"), uiTemp));
	uiTemp = regRead(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3);
	DEBUGMSG(1, (_T("\nInitial GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3	= 0x%8x\n"), uiTemp));

	//GM Setup the IOMUXC
	bitWrite(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3, IOMUX::SIGNAL_3_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3, IOMUX::SIGNAL_3_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3, IOMUX::SIGNAL_2_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3, IOMUX::SIGNAL_2_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO1Mux_capture_compare_watchdog_rst_pwmo, IOMUX::SIGNAL_2_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO1Mux_capture_compare_watchdog_rst_pwmo, IOMUX::SIGNAL_2_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO1Mux_usb_pwr_usb_oc_usb_byp_usbotg_clk, IOMUX::SIGNAL_1_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO1Mux_usb_pwr_usb_oc_usb_byp_usbotg_clk, IOMUX::SIGNAL_1_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO2Mux_key_row4_key_row5_key_row6_key_row7, IOMUX::SIGNAL_3_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO2Mux_key_row4_key_row5_key_row6_key_row7, IOMUX::SIGNAL_3_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO2Mux_key_row4_key_row5_key_row6_key_row7, IOMUX::SIGNAL_2_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO2Mux_key_row4_key_row5_key_row6_key_row7, IOMUX::SIGNAL_2_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO3Mux_sd1_data1_sd1_data2_sd1_data3_ata_cs0, IOMUX::SIGNAL_0_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO3Mux_sd1_data1_sd1_data2_sd1_data3_ata_cs0, IOMUX::SIGNAL_0_INPUT,  IOMUX::NO_INPUTS_SELECTED);
	bitWrite(IOMUX::GPIO3Mux_ata_cs1_ata_dior_ata_diow_ata_dmack, IOMUX::SIGNAL_3_OUTPUT, IOMUX::GPIO);
	bitWrite(IOMUX::GPIO3Mux_ata_cs1_ata_dior_ata_diow_ata_dmack, IOMUX::SIGNAL_3_INPUT,  IOMUX::NO_INPUTS_SELECTED);

	// Disable GPIO_0, _1 interrupts
	bitWrite(gpio1::IMR, gpio1::GPIO0, 0);
	bitWrite(gpio1::IMR, gpio1::GPIO1, 0);
	bitWrite(gpio1::IMR, gpio1::upGPIO3, 0);
	bitWrite(gpio2::IMR, gpio2::GPIO0, 0);
	bitWrite(gpio2::IMR, gpio2::GPIO1, 0);
	bitWrite(gpio3::IMR, gpio3::GPIO0, 0);
	bitWrite(gpio3::IMR, gpio3::GPIO1, 0);

	// Set GPIO_0, _1 as output
	bitWrite(gpio1::GDIR, gpio1::GPIO0, 1);
	bitWrite(gpio1::GDIR, gpio1::GPIO1, 1);
	bitWrite(gpio1::GDIR, gpio1::upGPIO3, 1);
	bitWrite(gpio2::GDIR, gpio2::GPIO0, 1);
	bitWrite(gpio2::GDIR, gpio2::GPIO1, 1);
	bitWrite(gpio3::GDIR, gpio3::GPIO0, 1);
	bitWrite(gpio3::GDIR, gpio3::GPIO1, 1);

	uiTemp = regRead(gpio1::IMR);
	DEBUGMSG(1, (_T("New IMR  = 0x%8x\n"), uiTemp));
	uiTemp = regRead(gpio1::GDIR);
	DEBUGMSG(1, (_T("New GDIR = 0x%8x\n"), uiTemp));

	uiTemp = regRead(IOMUX::GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3);
	DEBUGMSG(1, (_T("New GPIO1Mux_gpio1_0_gpio1_1_gpio1_2_gpio1_3   = 0x%8x\n"), uiTemp));
}

void GPIO::SetGPIO( unsigned int gpioBank, unsigned int bits )
{
	switch(gpioBank)
	{
	case 1:
		bitWrite(gpio1::DR, bits, 1);	
		break;
	case 2:
		bitWrite(gpio2::DR, bits, 1);	
		break;
	case 3:
		bitWrite(gpio3::DR, bits, 1);	
		break;
	}
}

void GPIO::ClearGPIO( unsigned int gpioBank, unsigned int bits )
{
	switch(gpioBank)
	{
	case 1:
		bitWrite(gpio1::DR, bits, 0);	
		break;
	case 2:
		bitWrite(gpio2::DR, bits, 0);	
		break;
	case 3:
		bitWrite(gpio3::DR, bits, 0);	
		break;
	}
}		

