#ifndef __CSPI_1_REGISTERS_H__
#define __CSPI_1_REGISTERS_H__

// MS Didn't even supply stdint.h! Ugh...
#include "stdint.h"  
#include "register_bitops.h"

PVOID MapPhysicalAddr(PVOID dwPhysicalAddress, DWORD dwSize);

namespace CSPI_1
{
	static volatile uint32_t virtualAddress = (uint32_t) MapPhysicalAddr((PVOID) 0x43FA4000, 0x100); 
	
	enum Registers
	{
		RXDATA		= 0x0000,		// 0x00	- Receive data (ro) 
		TXDATA		= 0x0004,		// 0x04	- Transmit data (wo)
		CONTROL		= 0x0008,		// 0x08	- Control Register
		INTERRUPT	= 0x000C,		// 0x0c	- Interrupt Register
		DMA			= 0x0010,		// 0x10	- DMA Register
		STATUS		= 0x0014,		// 0x14	- Status Register
		PERIOD		= 0x0018,		// 0x18	- Period Register
		TEST		= 0x001C		// 0x1c	- Test Register
	};

	// Bits 25 and 24 of the control register
	enum CONTROL_REGISTER_BIT_FIELDS
	{
		CHIPSELECT						= REGISTER_BIT_DEFINITION(25, 24),
		DRCTL							= REGISTER_BIT_DEFINITION(21, 20),
		DATARATE						= REGISTER_BIT_DEFINITION(18, 16),	
		BITCOUNT						= REGISTER_BIT_DEFINITION(12,  8),		
		SSPOL							= REGISTER_BIT_DEFINITION( 7,  7),
		SSCTL							= REGISTER_BIT_DEFINITION( 6,  6),
		PHA								= REGISTER_BIT_DEFINITION( 5,  5),
		POL								= REGISTER_BIT_DEFINITION( 4,  4),
		SMC								= REGISTER_BIT_DEFINITION( 3,  3),
		XCH								= REGISTER_BIT_DEFINITION( 2,  2),
		MODE							= REGISTER_BIT_DEFINITION( 1,  1),
		EN								= REGISTER_BIT_DEFINITION( 0,  0)
	};
	
	enum TEST_REGISTER_BIT_FIELDS
	{
		SWAP							= REGISTER_BIT_DEFINITION(15, 15),
		LBC								= REGISTER_BIT_DEFINITION(14, 14),
		SMSTATUS						= REGISTER_BIT_DEFINITION(11,  8),		
		RXCNT							= REGISTER_BIT_DEFINITION( 7,  4),
		TXCNT							= 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 // __CSPI_1_REGISTERS_H__
