/******************************************************************************/
/* SOUND.C: Sound Player                                                      */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools.                    */
/* Copyright (c) 2005-2006 Keil Software. All rights reserved.                */
/* This software may only be used under the terms of a valid, current,        */
/* end user licence from KEIL for a compatible version of KEIL software       */
/* development tools. Nothing else gives you the right to use this software.  */
/******************************************************************************/
                  
#include <startup.h>
#include <LPC214X.h>
#include <armVIC.h>
#include <type.h>
#include <irq.h>
#include <TFT018.h>
#include <rprintf.h>

#define CPU_CLOCK   60000000                /* CPU Clock                      */
#define DATA_FREQ       8000                /* Sound Data Frequency           */

#define TIM_TICK    (CPU_CLOCK/DATA_FREQ)   /* Timer Tick                     */


extern const char SoundData[];              /* Sound Data (Signed 16-bit)     */
extern const int  SoundCount;               /* Sound Data Count               */

unsigned int  Index  = 0;                   /* Sound Data Index               */
unsigned char Volume = 0;                   /* Sound Volume Level             */

/* Timer Counter 0 Interrupt executes @ DATA_FREQ Rate                        */
#define	INT_VECT_NUM	0

static void tc0(void) __attribute__ ((interrupt("IRQ")));
void tc0 (void) {
  unsigned long val;
  
  if (Index < SoundCount) {                 /* Check if Data is available     */
    if ((Index & 0x3F) == 0) {              /* On every 64th Sample           */
      AD0CR |= 0x01000000;                  /* Start A/D Conversion           */
      do {
        val = AD0GDR;                        /* Read A/D Data Register         */
      } while ((val & 0x80000000) == 0);    /* Wait for end of A/D Conversion */
      AD0CR &= ~0x01000000;                 /* Stop A/D Conversion            */
      Volume = val >> 8;                    /* Extract Volume Level (0-255)   */
      IOCLR1 = 0x00FF0000;                  /* Turn Off all LEDs              */
    }
    val    = 0x8000;                        /* Sound Data: Middle Point       */
    val   += SoundData[Index];              /* Sound Data:  Lower 8-bits      */
    val   += SoundData[Index + 1] << 8;     /* Sound Data: Higher 8-bits      */
    val   &= 0xFFFF;
    val   *= Volume;                        /* Sound Volume Level             */
    val  >>= 8;
    DACR   = val;                           /* Set Speaker Output             */   
    Index += 2;                             /* Next Sample                    */
  } 
  T0IR        = 1;                          /* Clear interrupt flag           */
  VICVectAddr = 0;                          /* Acknowledge Interrupt          */
}


char s[20], *sp;
int input_str(int ch){
	*sp ++ = (char)ch;
	*sp = 0;
	return ch;
}

int main (void) {

	Initialize();
  PINSEL1 = 0x01080000;                     /* Select DAC (AOUT) & AIN1       */

	BacklightOn();
	LCD_Init();
	LCD_Clear_Screen(Blue);
  LCD_PutString(1,30,"Sound Test",0xF800,0xFFE0);
  LCD_PutString(1,60,"Push BP4",0xF800,0xFFE0);

  AD0CR   = 0x00200402;                     /* ADC1: 10-bit AIN1 @ 3MHz       */ 
  DACR    = 0x00008000;                     /* DAC Output set to Middle Point */

  /* Setup Timer 0: Periodic Interrupt @ DATA_FREQ Rate                       */
  T0MR0 = TIM_TICK - 1;                     /* Timer0 Match Value 0           */
  T0MCR = 3;                                /* Interrupt and Reset on MR0     */
  T0TCR = 1;                                /* Timer0 Enable                  */

	VICIntSelect &= ~(1<<TIMER0_INT);
	VICIntEnable |= (1<<TIMER0_INT);

	(*(&VICVectCntl0+INT_VECT_NUM)) = 0x20 | TIMER0_INT; // choose highest priority ISR slot 	
	(*(&VICVectAddr0+INT_VECT_NUM)) = (int)tc0;

	enableIRQ();

  while (1) {                               /* Loop forever                   */
  	char s[20];
	sp = s;
	rprintf_devopen( input_str );
	rprintf("Volume : %4d ", Volume);
	LCD_PutString(1,90,s,0xF800,0xFFE0);

    if (Index == SoundCount) {              /* Check if Sound is over         */
      if ((IOPIN0 & 0x00004000) == 0) {     /* Check if INT1 is pressed       */
        Index = 0;                          /* Play the Sound again           */
      }
    }
  }
}
