#ifndef __IOMUX_REGISTERS_H__
#define __IOMUX_REGISTERS_H__

// MS Didn't even supply stdint.h! Ugh...
#include "stdint.h"  
#include "register_bitops.h"

PVOID MapPhysicalAddr(PVOID dwPhysicalAddress, DWORD dwSize);

namespace IOMUX
{
	//GM static volatile uint32_t virtualAddress = (uint32_t) MapPhysicalAddr((PVOID) 0x43FAC000, 0x7FFF); 
	//GM change size to 0xCFFF to span entire IOMUXC address space
	static volatile uint32_t virtualAddress = (uint32_t) MapPhysicalAddr((PVOID) 0x43FAC000, 0xCFFF); 
	
	enum Registers
	{
		GPR												= 0x0008,	//GM add GPR register
		
		CSPI_1mux_SS2_SCLK_SRDY_CSPI_2_MOSI				= 0x0088,	//GM CSPI1_SCLK functional register
		CSPI_1mux_MOSI_MISO_SS_SS1						= 0x008C,	//GM CSPI1_MOSI functional register
		CSPI_1mux_RTS1_CTS1_DRT_DCE1_DSR_DCE1			= 0x007C,	//GM add CSPI1_SCLK alt1 register
		CSPI_1mux_RI_DCE1_DCD_DCE1_DTR_DTE1_DSR_DTE1	= 0x0078,	//GM add CSPI1_DRDY alt1 register
			
		CSPI_1pad_SCLK_SRDY_CSPI_2_MOSI					= 0x01FC,	//GM add CSPI1_SCLK functional pad config register
		CSPI_1pad_SFS6_MOSI_MISO						= 0x0204,	//GM add CSPI1_MOSI functional pad config register
		CSPI_1pad_CTS1_DTR_DCE1_DSR_DCE1				= 0X01EC,	//GM add CSPI1_SCLK alt 1 pad config register
		CSPI_1pad_RI_DCE1_DCD_DCE1_DTR_DTE1				= 0x01E8	//GM add CSPI1_DRDY alt 1 pad config register
	};

	enum MUX_OUTPUT_SELECT
	{
		GPIO							= 0, 
		FUNCTIONAL_OUTPUT				= 1,
		ALTERNATE_MODE_1_OUTPUT			= 2
	};

	enum MUX_INPUT_SELECT
	{
		NO_INPUTS_SELECTED				= 0,
		GPIO_PSR_ISR_INPUT				= 1,
		FUNCTIONAL_INPUT				= 2,
//		ALTERNATE_MODE_1_INPUT			= 3
		ALTERNATE_MODE_1_INPUT			= 4	//GM according to ref manual
	};


	// Bits 25 and 24 of the control register
	enum IOMUX_REGISTER_BIT_FIELDS
	{
		SIGNAL_3_OUTPUT					= REGISTER_BIT_DEFINITION(30, 28),
		SIGNAL_3_INPUT					= REGISTER_BIT_DEFINITION(27, 24),
		SIGNAL_2_OUTPUT					= REGISTER_BIT_DEFINITION(23, 20),
		SIGNAL_2_INPUT					= REGISTER_BIT_DEFINITION(19, 16),
		SIGNAL_1_OUTPUT					= REGISTER_BIT_DEFINITION(14, 12),
		SIGNAL_1_INPUT					= REGISTER_BIT_DEFINITION(11,  8),
		SIGNAL_0_OUTPUT					= REGISTER_BIT_DEFINITION( 6,  4),
		SIGNAL_0_INPUT					= REGISTER_BIT_DEFINITION( 3,  0)
	};
	
	inline volatile uint32_t *regAddress(Registers reg)
	{
		return reinterpret_cast<volatile uint32_t*>(virtualAddress + reg);
	}
	
	inline uint32_t regRead(Registers reg)
	{
		return *regAddress(reg);
	}
	
	inline void regWrite(Registers reg, uint32_t value)
	{
		*regAddress(reg) = value;
	}

}

#endif // __IOMUX_REGISTERS_H__
