// mapRegisters.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

#define CSPI1_BASE_PHYSICAL	(0x43FA4000)  //GM
#define CSPI2_BASE_PHYSICAL	(0x50010000)  //GM
#define CSPI3_BASE_PHYSICAL	(0x53FA4000)  //GM

#define READ_REGISTER_ULONG(reg) (*(volatile unsigned long * const)(reg))
#define WRITE_REGISTER_ULONG(reg, val) (*(volatile unsigned long * const)(reg)) = (val)
#define PAGE_SIZE 				0x1000 	// 1 page:4KB
#define PAGE_ALIGN(Vaddr) 		((PVOID)((ULONG)(Vaddr) & ~(PAGE_SIZE - 1)))
#define ROUND_TO_PAGES(Size)  	(((ULONG)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))


// Entire Structure GM
typedef struct
{
	unsigned long RXDATA;		//0x43FA_4000(CSPI1), 0x5001_0000(CSPI2), 0x53F8_4000(CSPI3)
	unsigned long TXDATA;		//0x43FA_4004(CSPI1), 0x5001_0004(CSPI2), 0x53F8_4004(CSPI3)
	unsigned long CONREG;		//0x43FA_4008(CSPI1), 0x5001_0008(CSPI2), 0x53F8_4008(CSPI3)
	unsigned long INTREG;		//0x43FA_400C(CSPI1), 0x5001_000C(CSPI2), 0x53F8_400C(CSPI3)
	unsigned long DMAREG;		//0x43FA_4010(CSPI1), 0x5001_0010(CSPI2), 0x53F8_4010(CSPI3)
	unsigned long STATREG;		//0x43FA_4014(CSPI1), 0x5001_0014(CSPI2), 0x53F8_4014(CSPI3)
	unsigned long PERIODREG;	//0x43FA_4018(CSPI1), 0x5001_0018(CSPI2), 0x53F8_4018(CSPI3)
}CSPI_REGS, *PSSP_REGS;

volatile CSPI_REGS		*CSPI1RegPtr = NULL;  //GM

extern "C"
{
   __declspec(dllimport) BOOL   VirtualCopy(LPVOID lpvDest, LPVOID lpvSrc, DWORD cbSize, DWORD fdwProtect);
}



PVOID MapPhysicalAddr(PVOID dwPhysicalAddress, DWORD dwSize)
{
	LPVOID pVirtualAddr;
	PVOID PageAlinedPhysicalAddress;
	ULONG Offset;
	DWORD PageAlignedSize;
	BOOL bCopyReturn;

	// Get Page Aligned Address
	PageAlinedPhysicalAddress = PAGE_ALIGN (dwPhysicalAddress);
	Offset = (ULONG)dwPhysicalAddress - (ULONG)PageAlinedPhysicalAddress;

	// Get page Aligned Size
	PageAlignedSize = ROUND_TO_PAGES(dwSize + Offset);

	// Create reserved block of virtual memory
	pVirtualAddr = VirtualAlloc(0, PageAlignedSize, MEM_RESERVE, PAGE_NOACCESS);

    if(pVirtualAddr == NULL) 
	{
		RETAILMSG(1,(L"	MapPhysicalAddr : Error Return. \r\n"));
        return NULL;
    }

	// Map physical memory to virtual memory
 	// then /256 and use the PAGE_PHYSICAL flag
	//----------------------------------------------
    bCopyReturn = VirtualCopy (	pVirtualAddr, 
								(LPVOID)((ULONG)PageAlinedPhysicalAddress >> 8),
								PageAlignedSize, 
								PAGE_READWRITE | PAGE_NOCACHE | PAGE_PHYSICAL);

    if(bCopyReturn == FALSE) 
	{
		RETAILMSG(1,(L"	MapPhysicalAddr : return false from VirtualCopy(). \r\n"));      
        VirtualFree( pVirtualAddr, 0, MEM_RELEASE  );
        return NULL;
    }

	pVirtualAddr = (PVOID)((PUCHAR)pVirtualAddr + Offset);

	return pVirtualAddr;

}


void MapRegisters( VOID )
{
	unsigned long	rxdata,
					txdata,
					conreg,
					intreg,
					dmareg,
					statreg,
					periodreg;


	CSPI1RegPtr = (CSPI_REGS *)MapPhysicalAddr((CSPI_REGS *)CSPI1_BASE_PHYSICAL,sizeof(CSPI_REGS));	// 1 Page
	if(CSPI1RegPtr == NULL)
		RETAILMSG(1,(L" Error 'cause CSPI1RegPtr == NULL \r\n"));

/*	GpioRegPtr = (GPIO_REGS *)MapPhysicalAddr((GPIO_REGS *)GPIO_BASE_PHYSICAL,sizeof(GPIO_REGS));	// 1 Page
	if(GpioRegPtr == NULL)
		RETAILMSG(1,(L" Error 'cause GpioRegPtr == NULL \r\n"));
*/

	DEBUGMSG(1,(TEXT("\nInitial CSPI Registers: ")));
	rxdata = READ_REGISTER_ULONG(&CSPI1RegPtr->RXDATA);
	DEBUGMSG(1,(TEXT("RXDATA = 0x%8x;  "),rxdata));
	txdata = READ_REGISTER_ULONG(&CSPI1RegPtr->TXDATA);
	DEBUGMSG(1,(TEXT("TXDATA = 0x%8x;  "),txdata));
	conreg = READ_REGISTER_ULONG(&CSPI1RegPtr->CONREG);
	DEBUGMSG(1,(TEXT("CONREG = 0x%8x;  "),conreg));
	intreg = READ_REGISTER_ULONG(&CSPI1RegPtr->INTREG);
	DEBUGMSG(1,(TEXT("INTREG = 0x%8x;  "),intreg));
	dmareg = READ_REGISTER_ULONG(&CSPI1RegPtr->DMAREG);
	DEBUGMSG(1,(TEXT("DMAREG = 0x%8x;  "),dmareg));
	statreg = READ_REGISTER_ULONG(&CSPI1RegPtr->STATREG);
	DEBUGMSG(1,(TEXT("STATREG = 0x%8x;  "),statreg));
	periodreg = READ_REGISTER_ULONG(&CSPI1RegPtr->PERIODREG);
	DEBUGMSG(1,(TEXT("PERIODREG= 0x%8x;  "),periodreg));
}

int WINAPI WinMain(	HINSTANCE hInstance,
					HINSTANCE hPrevInstance,
					LPTSTR    lpCmdLine,
					int       nCmdShow)
{
 	printf("Calling MapRegisters");
	MapRegisters();

	VirtualFree((PVOID)CSPI1RegPtr, 0, MEM_RELEASE);

	return 0;
}

