/*

avr @ 16Mhz
9600 baud


on pro mini:

0   rxd   
1   txd   

2   pd2    
3   pd3    


4   pd4    
5   pd5   
6   pd6    
7   pd7    

8   pb0    
9   pb1    
10  pb2    


11  pb4
12  pb3
13  pb5


A0  pc0    
A1  pc1    
A2  pc2    
A3  pc3    

A4  pc4    
A5  pc5    


A6  adc6
A7  adc7



*/
#include <avr/io.h>
//#include <avr/interrupt.h>

#define NOP()                 asm volatile ("nop"::)
#define OUTPUT  1
#define INPUT   0

#define SetBit(BIT, PORT)     PORT |= (1<<BIT)
#define ClearBit(BIT, PORT)   PORT &= ~(1<<BIT)
#define IsHigh(BIT, PORT)    (PORT & (1<<BIT)) != 0
#define IsLow(BIT, PORT)     (PORT & (1<<BIT)) == 0
#define InBoundsI(v, l, h)        ((v) >= (h)) ? (0) : ((v) <= (l)) ? (0) : (1)

unsigned char pseudorandom32();
void          Delay(unsigned int delay);
void          Delay2(unsigned int delay) ;


int main( void ) {
 
   unsigned char twinkle[8] = {0, 32, 64, 96, 128, 160, 192, 224};
   
 
    // set up directions 
  DDRB = (OUTPUT << PB0 | OUTPUT << PB1 | INPUT << PB2 |INPUT << PB3 |INPUT << PB4 |INPUT << PB5 |INPUT << PB6 |INPUT << PB7);
  DDRD = (INPUT << PD0 | INPUT << PD1 | OUTPUT << PD2 |OUTPUT << PD3 |OUTPUT << PD4 |OUTPUT << PD5 |OUTPUT << PD6 |OUTPUT << PD7);        
  DDRC = (INPUT << PD0 | INPUT << PD1 | INPUT << PD2 |INPUT << PD3 |INPUT << PD4 |INPUT << PD5 |INPUT << PD6 |INPUT << PD7); 

  PORTB = 0x0C;

 // USART_Init( 103 ); // 9600 baud
//  USART_Init( 51 );  //19200 baud
  
    while(1) {
   
      if  ((twinkle[0] -= (pseudorandom32() & 0x01)) < 2) ClearBit(0, PORTB ); else SetBit(0, PORTB);
      if  ((twinkle[1] -= (pseudorandom32() & 0x01)) < 2) ClearBit(1, PORTB ); else SetBit(1, PORTB);
      if  ((twinkle[2] -= (pseudorandom32() & 0x01)) < 2) ClearBit(2, PORTD ); else SetBit(2, PORTD);
      if  ((twinkle[3] -= (pseudorandom32() & 0x01)) < 2) ClearBit(3, PORTD ); else SetBit(3, PORTD);
      if  ((twinkle[4] -= (pseudorandom32() & 0x01)) < 2) ClearBit(4, PORTD ); else SetBit(4, PORTD);
      if  ((twinkle[5] -= (pseudorandom32() & 0x01)) < 2) ClearBit(5, PORTD ); else SetBit(5, PORTD);
      if  ((twinkle[6] -= (pseudorandom32() & 0x01)) < 2) ClearBit(6, PORTD ); else SetBit(6, PORTD);
      if  ((twinkle[7] -= (pseudorandom32() & 0x01)) < 2) ClearBit(7, PORTD ); else SetBit(7, PORTD);
      
      // 1/16 second delay
                  
      Delay(10000);
     
     }
    
    
}

// I think this works...
unsigned char pseudorandom32() {

  // MSB on left
  static unsigned char R4 = 0x00, R3 = 0x00, R2 = 0x00, R1 = 0x01;
  unsigned char t;
  
  // xor'd bits are 31, 21, 1, 0 
  
  //R4   [31], 30,  29, 28, 27, 26,  25,   24
  //R3   23,  [22], 21, 20, 19, 18,  17,   16
  //R2   15,   14,  13, 12, 11, 10,  09,   08
  //R1   07,   06,  05, 04, 03, 02, [01], [00]
 
  // shift up
  
  R4 <<= 1;
  t = R4;  // bit 31
  
  if (R3 & 0x80) R4++;  
  R3 <<= 1;  
  t ^= R3 ; // bit 22
  
  if (R2 & 0x80) R3++;
  R2 <<= 1;  
  
  t >>= 6;  // move xor result over to bit 1
  t ^= R1;  // bit 1
  
  if (R1 & 0x80) R2++;  
  R1 <<= 1;  
  
  t^= R1;   // bit 0
  
  if (t & 0x02) R1++;
  
  return R1;

}



void Delay(unsigned int delay) {
  unsigned int x;
  for (x = delay; x != 0; x--) {
    asm volatile ("nop"::); 
  }
}

void Delay2(unsigned int delay) {
  unsigned int x;
  for (x = delay; x != 0; x--) {
    Delay(65000);
  }
}















