/******************************************************************************/
/*  Music Box demo ON Olimix LPC 2106-MT by senz                              */
/*  Modifed from :                                                            */
/*  LED Flasher - Timer Interrupt example for arm-elf-gcc                     */
/*  Lights LED on Startup and flashs LED when button is pressed.              */
/******************************************************************************/
/*  Inspired by a sample application from Keil Elektronik                     */
/*  A lot of information has been found in a sample from R O Software.        */
/******************************************************************************/
/*  Sample for WinARM by M.Thomas <eversmith@heizung-thomas.de>               */
/******************************************************************************/

#include "lpc210x_gnuarm.h"
#include "config.h"
#include "VIClowlevel.h"

#include "timer.h"

// olimex LPC-P2106: one led on P0.7 (active low)
#define LEDPIN 12
#define LEDMASK (1<<LEDPIN)

// 8 LEDS

#define LED1	(1<<23)
#define LED2	(1<<24)
#define LED3	(1<<22)
#define LED4	(1<<4)
#define LED5	(1<<5)
#define LED6	(1<<6)
#define LED7	(1<<7)
#define LED8	(1<<25)




#define BUZPIN 8
#define BUZMASK (1<<BUZPIN);
// olimex LPC-P2106: one switch on P0.31 (active low)
#define SWPIN 	31

#define WAIT100MS  10
#define WAIT1S     100

#define waitC	4

//BUTTONS

#define BUTTON1 0x08000000   //P0.27
#define BUTTON2 0x10000000   //P0.28
#define BUTTON3 0x20000000   //P0.29
#define BUTTON4 0x40000000   //P0.30
#define BUTTON5 0x80000000   //P0.31
int button_pressed(){
      unsigned long val;
      val = GPIO_IOPIN;
      
      if (!(val&BUTTON1)){
            return 1;
      }
       
      if (!(val&BUTTON2)){
            return 2;
      }
       
      if (!(val&BUTTON3)){
            return 3;
      }
       
      if (!(val&BUTTON4)){
            return 4;
      }
      
      if (!(val&BUTTON5)){
            return 5;
      }
      return 0;
}

void systemInit(void)
{
	// --- enable and connect the PLL (Phase Locked Loop) ---
	// a. set multiplier and divider
	SCB_PLLCFG = MSEL | (1<<PSEL1) | (0<<PSEL0);
	// b. enable PLL
	SCB_PLLCON = (1<<PLLE);
	// c. feed sequence
	SCB_PLLFEED = PLL_FEED1;
	SCB_PLLFEED = PLL_FEED2;
	// d. wait for PLL lock (PLOCK bit is set if locked)
	while (!(SCB_PLLSTAT & PLOCK));
	// e. connect (and enable) PLL
	SCB_PLLCON = (1<<PLLE) | (1<<PLLC);
	// f. feed sequence
	SCB_PLLFEED = PLL_FEED1;
	SCB_PLLFEED = PLL_FEED2;
	
	// --- setup and enable the MAM (Memory Accelerator Module) ---
	// a. start change by turning of the MAM (redundant)
	MAM_MAMCR = 0;	
	// b. set MAM-Fetch cycle to 3 cclk as recommended for >40MHz
	MAM_MAMTIM = MAM_FETCH;
	// c. enable MAM 
	MAM_MAMCR = MAM_MODE;

	// --- set VPB speed ---
	SCB_VPBDIV = VPBDIV_VAL;

    // --- map INT-vector ---
	#if defined(RAM_RUN)
	  SCB_MEMMAP = MEMMAP_USER_RAM_MODE;
	#elif defined(ROM_RUN)
	  SCB_MEMMAP = MEMMAP_USER_FLASH_MODE;
	#else
	#error RUN_MODE not defined!
	#endif
}

static void gpioInit(void)
{
	GPIO_IOSET  = (1<<LEDPIN);	// set Bit = LED off (active low)
	GPIO_IODIR |= (1<<LEDPIN);	// define LED-Pin as output
	
	GPIO_IODIR |= (LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8);//all led pins as output!
	
	GPIO_IOSET |= (LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8);//off all leds.
	
	GPIO_IOSET  = (1<<BUZPIN);	// set Bit = LED off (active low)
	GPIO_IODIR |= (1<<BUZPIN);	// define LED-Pin as output
		
	GPIO_IODIR &= ~(1<<SWPIN);	// define Switch-Pin as input
}


void wait (unsigned long delay)  
{
  unsigned long i;

  i = timeval + delay;
  while ( i != timeval);           
}

int return_ledmask(int value) {
	int mask = 0;
	int led_array[] = {LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8};
	int i;
	
	for (i=0; i<8; i++) {
		if (value&(1<<i)){
		//if (1){
			mask |= led_array[i];
		}
	}
	return mask;
}

int main(void) 
{
	int b;
	int cur_mask = 0;
	
	int wait_array[] = {383/2,383/2,340/2,303/2,286/2,255/2};
						/* C,C,D,E,F,G */
		
	int test_char[] = {	    
		0x00,0x00,0x82,0xFF,0x82,0x00,
		0x00,0x00,0x08,0x14,0x22,0x42,
		0x00,0x84,0x00,0x42,0x22,0x14,
		0x08,0x00,0x00,0x00,0x7E,0x82,
		0x80,0x80,0x80,0x72,0x7E,0x00,
		0x00,0x00,
		-1,-1,-1,-1,-1
	};
	
	/*
	
	{
	 01234567890123456789012345678901
	 ********************************
	 **111*****11***11*****11***11***
	 ***1*****1***1***1****1*****1***
	 ***1****1*********1***1*****1***
	 
	 ***1*****1*******1****1*****1***
	 ***1******1*****1*****1*****1***
	 ***1*******1***1******1*****1***
	 **111********1*********11111****
	}
	*/

	int led_array[] = {LED1,LED2,LED3,LED4,LED5,LED6,LED7,LED8};

	int wait_unit = 590000;//10s
    wait_unit = 5900;//.1s
	wait_unit = 590/8 ;//.01s
	
	
	gpioInit();  
	
	GPIO_IOCLR = LEDMASK; 	// enable LED - "life sign"

	systemInit();			// PLL, MAM etc.
	
	init_timer();
	
	enableIRQ(); 
	
	
	
	while(1) {
			
		for (b = 0; b < 26+5; b++) {
			
		  if (test_char[b] < 0) {
		       wait(wait_unit*100);
			   continue;
		  }
		  cur_mask = return_ledmask(test_char[b]);
		  //cur_mask = (LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8);
		  //cur_mask = (LED1);
		  
		  
		  if (cur_mask == 0) {
			GPIO_IOSET = (LED1|LED2|LED3|LED4|LED5|LED6|LED7|LED8);
			wait(wait_unit*2);
			
		  } else {
			GPIO_IOCLR = (cur_mask); //enable
		  
			wait(wait_unit);
		  
			GPIO_IOSET = (cur_mask); //disable		  
		  
			wait(wait_unit);
		 }
		}
		 
	}
}
