//-------------------------------------------------------------------
// NSSP.CPP
//
// 16-Jun-2006 ADS/ak
//  Updated to work with PXA270 NSSP port
//-------------------------------------------------------------------

#include "stdafx.h"
#include <windows.h>
#include "gpio.h"
#include "ssp.h"
#include "clk.h"
#include "resource.h"
#include <stdlib.h>

#define LOOP_COUNTER	0x3ffff

extern volatile GPIO_REGS	*GpioRegPtr;
extern volatile SSP_REGS	*SspRegPtr;
extern volatile CLKMAN_REGS	*v_pClkRegs;

//ULONG SerialClockRate=0x16F;			// 367(0x16f):10 KBits/S
//ULONG SerialClockRate=0x24;			// 36(0x24):13e6 / 24 Mbits/s
ULONG SerialClockRate=0x6;			// 36(0x24):13e6 / 24 Mbits/s

void InitNSSP( VOID )
{
	ULONG sscr0=0;
	ULONG gafr;
	ULONG gpdr;
	ULONG pcon=0;
	ULONG cken;

	#if ADS_DEBUG
		RETAILMSG(1,(L" InitNSSP: + \r\n"));
	#endif

/* PXA255
		// Disable SSP Clock
	cken = READ_REGISTER_ULONG(&v_pClkRegs->cken);
	cken &= ~CLK_NSSP;
	WRITE_REGISTER_ULONG(&v_pClkRegs->cken,cken);

    // Set up for the NSSP.
	//----------------

	// Set GPIO 81 Alternate Functions : NSSP Clock (Output Mode)
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR1_3);
	gafr &= 0xfffffff3;								// Clear Function Bits
	gafr |= 0x00000004;								// Function Mode 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR1_3, gafr);


	// Set GPIO 82 Alternate Functions : NSSP Frame (Output Mode)
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR1_3);
	gafr &= 0xffffffcf;								// Clear Function Bits
	gafr |= 0x00000010;								// Function Mode 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR1_3, gafr);

	// Set GPIO 83 Alternate Functions : NSSP Trasmit (Output Mode)
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR1_3);
	gafr &= 0xffffff3f;								// Clear Function Bits
	gafr |= 0x00000040;								// Function Mode 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR1_3, gafr);

	// Set GPIO 84 Alternate Functions : NSSP Receive (Input Mode)
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR1_3);
	gafr &= 0xfffffcff;								// Clear Function Bits
	gafr |= 0x00000200;								// Function Mode 2
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR1_3, gafr);

	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR1_3);
	
	#if ADS_DEBUG
		RETAILMSG(1,(L" GpioRegPtr->GAFR1_3= 0x%x \r\n",gafr));
	#endif
	
	gpdr = READ_REGISTER_ULONG(&GpioRegPtr->GPDR_z);
	gpdr |= (GPIO_81 | GPIO_82 | GPIO_83);
	gpdr &= (~GPIO_84);
	WRITE_REGISTER_ULONG(&GpioRegPtr->GPDR_z, gpdr);

	gpdr = READ_REGISTER_ULONG(&GpioRegPtr->GPDR_z);

	#if ADS_DEBUG
		RETAILMSG(1,(L" GpioRegPtr->GPDR_z= 0x%x \r\n",gpdr));
	#endif

*/

/* PXA270 */

	// Disable SSP Clock
	cken = READ_REGISTER_ULONG(&v_pClkRegs->cken);
	cken &= ~CLK_NSSP;
	WRITE_REGISTER_ULONG(&v_pClkRegs->cken,cken);

    // Set up for the NSSP.
	//----------------

	ULONG altFcn1 = 0x01;  // use 0x01 to enable Alternate Fuction 1 of the pin

	// Set GPIO 81 Alternate Functions : NSSP Transmit (Output Mode)
	ULONG pin81mask = 0x03 << 2;
	ULONG pin81AltFcn1 = (0x03 & altFcn1) << 2;
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR2_U);
	gafr &= ~pin81mask;								// Clear bits
	gafr |= pin81AltFcn1;							// Enable pin Alternate Function 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR2_U, gafr);


	// Set GPIO 82 Alternate Functions : NSSP Receive (Input Mode)
	ULONG pin82mask = 0x03 << 4;
	ULONG pin82AltFcn1 = (0x03 & altFcn1) << 4;
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR2_U);
	gafr &= ~pin82mask;								// Clear bits
	gafr |= pin82AltFcn1;							// Enable pin Alternate Function 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR2_U, gafr);

	// Set GPIO 83 Alternate Functions : NSSP Frame (Output Mode)
	ULONG pin83mask = 0x03 << 6;
	ULONG pin83AltFcn1 = (0x03 & altFcn1) << 6;
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR2_U);
	gafr &= ~pin83mask;								// Clear bits
	gafr |= pin83AltFcn1;							// Enable pin Alternate Function 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR2_U, gafr);

	// Set GPIO 84 Alternate Functions : NSSP Clock (Output Mode)
	ULONG pin84mask = 0x03 << 8;
	ULONG pin84AltFcn1 = (0x03 & altFcn1) << 8;
	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR2_U);
	gafr &= ~pin84mask;								// Clear bits
	gafr |= pin84AltFcn1;							// Enable pin Alternate Function 1
	WRITE_REGISTER_ULONG(&GpioRegPtr->GAFR2_U, gafr);

	gafr = READ_REGISTER_ULONG(&GpioRegPtr->GAFR2_U);
	
	#if ADS_DEBUG
		RETAILMSG(1,(L" GpioRegPtr->GAFR2_U= 0x%x \r\n",gafr));
	#endif
	
	gpdr = READ_REGISTER_ULONG(&GpioRegPtr->GPDR_2);
	gpdr |= (GPIO_81 | GPIO_83 | GPIO_84);
	gpdr &= (~GPIO_82);
	WRITE_REGISTER_ULONG(&GpioRegPtr->GPDR_2, gpdr);

//	printf("&GPDR_2 %0x8f  ",&GpioRegPtr->GPDR_2 );


//	gpdr = READ_REGISTER_ULONG(&GpioRegPtr->GPDR_3);

//	gpdr = READ_REGISTER_ULONG(&GpioRegPtr->GPDR_3);
//	gpdr |= (GPIO_106 | GPIO_107);
//	WRITE_REGISTER_ULONG(&GpioRegPtr->GPDR_3, gpdr);

/* END PXA270 */

	//Frame format FRF SPI, Serial Clock rate SCR 368, Data Size Select DSS 8 bit
	sscr0 = (SerialClockRate << 8) | SSCR0_DSS_8;
	WRITE_REGISTER_ULONG(&SspRegPtr->SSCR0, sscr0);

	#if ADS_DEBUG
		RETAILMSG(1,(L" SspRegPtr->sscr0= 0x%x \r\n",sscr0));
	#endif

	WRITE_REGISTER_ULONG(&SspRegPtr->SSSR,  SSPSR_ROR);
	WRITE_REGISTER_ULONG(&SspRegPtr->SSCR1, DEFAULT_SSPCR1);

	//Motorola, 
//	WRITE_REGISTER_ULONG(&SspRegPtr->SSCR0, SSPCR0_FRF_Motorola | SSPCR0_SCR | SSPCR0_DSS_8 | SSPCR0_SSE);

	#if ADS_DEBUG
		RETAILMSG(1,(L" InitNSSP: Enable Clock \r\n"));
	#endif

	sscr0 = READ_REGISTER_ULONG(&SspRegPtr->SSCR0);
	sscr0 |= SSPCR0_SSE;
	WRITE_REGISTER_ULONG(&SspRegPtr->SSCR0, sscr0);

	// Enable SSP Clock
	cken = READ_REGISTER_ULONG(&v_pClkRegs->cken);
	cken |= (CLK_NSSP);
	WRITE_REGISTER_ULONG(&v_pClkRegs->cken,cken);


	#if ADS_DEBUG
		RETAILMSG(1,(L" InitNSSP: - \r\n"));
	#endif

	return ;

}

//BYTE ReadSSPByteNoPush()
DWORD dwReadSSPNoPush()
{
	ULONG Count=LOOP_COUNTER;

	while((READ_REGISTER_ULONG(&SspRegPtr->SSSR) & SSSR_RNE) == 0)
	{
		if(Count-- == 0)
			break;
	}


	return (BYTE)READ_REGISTER_ULONG(&SspRegPtr->SSDR);
}

BOOL SendSSPWord (ULONG Wrd)
{
	WRITE_REGISTER_ULONG(&SspRegPtr->SSDR, Wrd);
	return TRUE;
}

BOOL SendSSPMessage(BYTE *pBuf, int num)
{
	int i;
	char letter[2];

	USHORT us;
	ULONG Count=LOOP_COUNTER;

	RETAILMSG(1,(L"Data sent:     0x"));
	for (i=0;i<num;i++)
	{
		Count=LOOP_COUNTER;

		while((READ_REGISTER_ULONG(&SspRegPtr->SSSR) & SSSR_TNF) == 0)
		{
			if(Count-- == 0 )
			{
				break;
			}			
		}

		if(Count == 0 )
		{
			break;
		}			

		us = pBuf[i];

	    WRITE_REGISTER_ULONG(&SspRegPtr->SSDR, us);
//		RETAILMSG(1,(L" %04x",us));
	}
	RETAILMSG(1,(L"\r\n"));

	if(Count == 0 )
	{
		goto error_return;
	}			

	// Show the bytes that were pushed out during the command sending

/*
	RETAILMSG(1,(L"Data received: 0x"));
	printf("Data received: ");
	for (i=0;i<num;i++)
	{
		RETAILMSG(1,(L" %04x",dwReadSSPNoPush()));
		//_itoa(dwReadSSPNoPush(), letter, 16);
		printf(" %04x",dwReadSSPNoPush());
	}
	RETAILMSG(1,(L"\r\n"));
	printf("\r\n");
*/
	return TRUE;

error_return:

	return FALSE;
}

