/*****************************************************/
/* Examples Program For "ET-ARM7 BASE LPC2106" Board */
/* Target MCU  : Philips ARM7-LPC2106                */
/*       	   : X-TAL : 19.6608 MHz                 */
/*             : Run Speed 58.9824MHz (With PLL)     */
/* Keil Editor : uVision3 V3.03a                     */
/* Compiler    : Keil CARM V2.50a		             */
/* Create By   : Eakachai Makarn (WWW.ETT.CO.TH)     */
/* Last Update : 17/April/2006                       */
/* Function    : Example Use SPI Interface 74HC595   */
/*             : LED Moving on Output 74HC595(8 Bit) */	
/*****************************************************/
// LPC2106    <----->  74HC595
// MOSI(P0.6) ------>  DIN(14)
// SCK(P0.4)  ------>  Shift(11)
// MISO(P0.5) -------  NC
// GPIO0.2    ------>  Latch(12)
// LPC2106 SS(P0.7) = "1"(SPI Master Mode)
// 74HC595 OE(13)   = "0"(Output Enable)
// 74HC595 MCLR(10) = "1"(Not Reset) 

/* Warning Pull-Up 10K on SPI Pin
    -> Pin GPIO0.2 (Latch)
    -> Pin GPIO0.4 (SCK)
    -> Pin GPIO0.6 (MOSI)
	-> Pin GPIO0.7 (SS#)
   74HC595 Not Stable(Not Work) if Not Pull-Up
*/

#include <LPC210x.H> 	                               	// LPC2106 MPU Register

/* pototype  section */
void delay_led(unsigned long int);						// Delay Time Function

int main(void)
{
  unsigned char LED;  									// LED Output Status Buffer
  
  // Initial P0.2 = Output Latch SPI(74HC595)
  IODIR  |= 0x00000004;									// P0.2 = Output Port
  IOCLR  |= 0x00000004;									// P0.2 = Latch = "0"

  // Initial SPI0 Pin Connect on P0[4] to P0[7]
  PINSEL0 &= 0xFFFF00FF;                                // Reset GPIO Pin Control Status Bit[15:8] 
  PINSEL0 |= 0x00000100;								// Bit[09:08] = 01 = P0.4 is SCK(SPI0)  
  PINSEL0 |= 0x00000400;								// Bit[11:10] = 01 = P0.5 is MISO(SPI0)  
  PINSEL0 |= 0x00001000;								// Bit[13:12] = 01 = P0.6 is MOSI(SPI0)                                  
  PINSEL0 |= 0x00004000;								// Bit[15:14] = 01 = P0.7 is SS(SPI0)  

  // Initial SPI0 Function Interface to 74HC595
  // SPI0 Clock Counter Register
  S0SPCCR = 0x000000FF;	  								// SPI-0 Clock = PCLK / 256

  // SPI0 Control Register
  S0SPCR &= 0x000000F7;									// CPHA = 0 = Rising Clock Shift Data
  S0SPCR &= 0x000000EF;                                 // CPOL = 0 = Normal Clock "0",Active = "1"
  S0SPCR |= 0x00000020;									// MSTR = 1 = Master SPI
  S0SPCR |= 0x00000040;                                 // LSBF = 1 = LSB First
  S0SPCR &= 0x0000007F;									// SPIE = 0 = Disable SPI Interrupt

  // Start Test Output SPI(74HC595) //
  while(1)												// Loop Continue
  {    
    for (LED = 0x01; LED < 0x80; LED <<= 1)				// Shift Left GPIO-0 (Right <- Left)
    { 
      IOCLR |= 0x00000004;                           	// Falling Edge Latch(Start Chips Select)
	  S0SPDR = 0xFF-LED;								// Send SPI to 74HC595 Output(Toggle Logic Drive)
	  while((S0SPSR & 0x80)!= 0x80){;;}					// Wait SPIF = 1 (SPI Send Complete)	   	   
	  IOSET |= 0x00000004;                           	// Rising Edge Latch(Stop Chips Select)				
      delay_led(5000000);	    						// Display Delay	    			
    }								 

    for (LED = 0x80; LED > 0x01; LED >>= 1)				// Shift Right GPIO-0(Right -> Left)
    { 
	  IOCLR |= 0x00000004;                           	// Falling Edge Latch(Start Chips Select)
	  S0SPDR = 0xFF-LED;								// Send SPI to 74HC595 Output(Toggle Logic Drive)
	  while((S0SPSR & 0x80)!= 0x80){;;}					// Wait SPIF = 1 (SPI Send Complete)	   	   
	  IOSET |= 0x00000004;                           	// Rising Edge Latch(Stop Chips Select)				
      delay_led(5000000);	    						// Display Delay	
    }  	    
  }   
}	  

/***********************/
/* Delay Time Function */
/***********************/
void delay_led(unsigned long int count1)
{
  while(count1 > 0) {count1--;}							// Loop Decrease Counter	
}
