#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
{
	static volatile uint32_t virtualAddress = (uint32_t) MapPhysicalAddr((PVOID) 0x43FAC000, 0x7FFF); 
	
	enum Registers
	{
		CSPI_1_SS2_SCLK_SDRY_CSPI_2_MOSI	= 0x0088, 
		CSPI_1_MOSI_MISO_SS_SS1				= 0x008C		 
	};

	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
	};


	// 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__
