www.pudn.com > armexamples.rar > spi.c


/* 
 
Module Name:	SPI.CPP 
 
Abstract:		SPI Interface Routines for Samsung SC2410 CPU 
   
Notes:			Presently, only the SPI Channel 0 is supported. 
 
Environment:	Samsung SC2410 CPU 
 
Date: 			2004/01/28 
 
By: 			Li zhongmin 
    
*/ 
 
#include 	"2410addr.h" 
#include 	"2410lib.h" 
#include 	"def.h" 
#include 	"spi.h" 
 
 
volatile DWORD g_dwWaitCounter = 0; 
//---------------------------------------------------------------------------------- 
 
 
// Used to wait the specified # of clock cycles 
#define WAIT(x)		{ for(g_dwWaitCounter=0; g_dwWaitCounter> 8; 
 
	//----- 4. Wait until the controller is ready to transfer ----- 
	waitCount = 1000; 
	while(!(rSPSTA0 & SPI_TRANSFER_READY)) 
	{ 
		if(--waitCount == 0) 
		{ 
			//RETAILMSG(1, (TEXT("WAVEDEV.DLL: SPI_SendWord() - timeout occurred while waiting to transfer byte\r\n"))); 
            bRet = FALSE; 
			goto SEND_ERROR; 
		} 
	} 
 
	//----- 5. Send second half of word ----- 
	rSPTDAT0 = (wData & 0x00FF); 
 
	//----- 6. Delay a little bit so the byte finishes clocking out before the chip select line is deasserted ----- 
	WAIT(10000); 
 
	//----- 7. Deselect the slave device (active low) ----- 
	rGPGDAT |= CHIP_DESELECT_nSS0; 
 
SEND_ERROR: 
 
    StopSPIClock(); 
 
	return bRet; 
} 
 
 
//------------------------------------ Helper Routines ------------------------------------ 
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Function:		StartSPIClock() 
 
Description:	Enables the SPI clock. 
 
Returns:		N/A 
-------------------------------------------------------------------*/ 
VOID StartSPIClock(VOID) 
{ 
	rCLKCON |= SPI_INTERNAL_CLOCK_ENABLE;		// Enable the CPU clock to the SPI controller 
 
	rSPCON0 |= (SPI_CLOCK_ENABLE|SPI_SELECT_MASTER);// Enable the SPI clock 
	 
	return; 
} 
 
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Function:		StopSPIClock() 
 
Description:	Disables the SPI clock. 
 
Returns:		N/A 
-------------------------------------------------------------------*/ 
VOID StopSPIClock(VOID) 
{ 
	rCLKCON &= ~SPI_INTERNAL_CLOCK_ENABLE;	// Disable the CPU clock to the SPI controller 
 
	rSPCON0 &= ~SPI_CLOCK_ENABLE;				// Disable the SPI clock 
	 
	return; 
} 
 
 
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
Function:		SetSPIClockRate() 
 
Description:	Sets the SPI clock (a.k.a. baud) rate: 
 
Params:			ClockRate       0x00 =      25Mhz 
								0x01 = 1/2  25Mhz 
								0x02 = 1/4  25Mhz 
								0x03 = 1/8  25Mhz 
								0x04 = 1/16 25Mhz 
								0x05 = 1/32 25Mhz 
								0x06 = 1/64 25Mhz 
								0x07 = 99.121Khz 
 
Returns:		N/A 
-------------------------------------------------------------------*/ 
VOID SetSPIClockRate(DWORD ClockRate) 
{ 
	UINT16 prescale; 
 
    //----- 1. Set the clock rate  ----- 
	//		   NOTE: Using the prescale value, the clock's baud rate is 
	//				 determined as follows: baud_rate = (PCLK / 2 / (prescale + 1)) 
	// 
	//				 Hence, the prescale value can be computed as follows: 
	//				 prescale = ((PCLK / 2) / baud_rate) - 1 
	switch(ClockRate) 
	{ 
		case CLK_RATE_FULL:						// 25 Mhz			 
		prescale = (PCLK / 40000000) - 1; 
		break; 
 
		case CLK_RATE_HALF:						// 1/2  25 Mhz						 
		prescale = (PCLK / 30000000) - 1; 
		break; 
 
		case CLK_RATE_FOUR:						// 1/4  25 Mhz						 
		prescale = (PCLK / 10000000) - 1; 
		break; 
 
		case CLK_RATE_EIGHT:					// 1/8  25 Mhz						 
		prescale = (PCLK / 500000) - 1; 
		break; 
 
		case CLK_RATE_SIXTEEN:					// 1/16 25 Mhz						 
		prescale = (PCLK / 2500000) - 1; 
		break; 
 
		case CLK_RATE_THIRTY2:					// 1/32 25 Mhz						 
		prescale = (PCLK / 1250000) - 1; 
		break; 
 
		case CLK_RATE_SIXTY4:					// 1/64 25 Mhz						 
		prescale = (PCLK / 625000) - 1; 
		break; 
 
		case CLK_RATE_SLOW:						// 99.121 kHz (i.e. ~1/256 25Mhz) 
		prescale = 255; 
		break; 
 
		default: 
		return; 
		break; 
	} 
 
	rSPPRE0 = prescale; 
 
 
    return; 
}