//****************************************************************************
//
// LED blink example
//
//****************************************************************************

#configure board        hu_arm_v4
#configure clcd_lines   2
#configure memory       rom
#configure baudrate     38400

class output_pin {
public:
   virtual void set( bool x ) = 0; 
};

class pin_lpc2: public output_pin {
private:
   unsigned int n;
public: 
   pin_lpc2( unsigned int n ): n( n ) { mkt_pin_configure( n, mkt_output ); }
   void set( bool x ) { mkt_pin_write( n, x ); }
};

class lpc2148 {
public:
   pin_lpc2 pio0_4;
   pin_lpc2 pio0_6;
   pin_lpc2 pio0_16;
   pin_lpc2 pio0_31;  
   
   lpc2148(): 
      pio0_4( 4 ), 
	  pio0_6( 6 ), 
	  pio0_16( 16 ), 
	  pio0_31( 31 ) 
   {}
};	

class hc595 : public output_pin {
private:

   output_pin &hclk, &sclk, &data;    
   
public:   
       
   hc595( output_pin &hclk, output_pin &sclk, output_pin &data ):
      hclk( hclk ), sclk( sclk ), data( data ){} 
   
   void set( bool x ){
      data.set( x );
      for( unsigned int i = 0; i < 8; i++ ){
         sclk.set( 0 );
         mkt_wait_us( 1 );
         sclk.set( 1 );
         mkt_wait_us( 1 );
      }   
      hclk.set( 0 );
      mkt_wait_us( 1 );
      hclk.set( 1 );
      mkt_wait_us( 1 );                             
   }
   
}; 

class tee : public output_pin {
private:

   output_pin & first, & second;
public:   

   tee( 
      output_pin & first, 
	  output_pin & second 
   ): 
      first( first ), second( second )
   {}
   
   void set( bool x ){ 
      first.set( x ); 
	  second.set( x ); 
   }
};
              
void blink( output_pin &led, unsigned int delay = 200 * 1000 ){
    for(;;){
       led.set( 1 );
       mkt_wait_us( delay );
       led.set( 0 );
       mkt_wait_us( delay );
   }      
};

int main( void ){ 
   lpc2148 target;
   hc595 shift_register( target.pio0_16, target.pio0_4, target.pio0_6 );
   tee both( shift_register, target.pio0_31 );
   blink( both, 1000 * 1000 );
}


