#include <stdio.h>
#include <myuart.h>
#include <dmx.h>

void ShowStatus();

// Now the address and length of the built in MP3 songs
// note that I've combined songs 1 (door opening) and 2 (footsteps) into song 1
#define SONGONELEN					(0x0000bbc1>>2)+(0x00026e0a>>2)
#define SONGTWOLEN					(0x00026e0a>>2)
#define SONGTHREELEN				(0x0003a43f>>2)

// The following are port values
#define MP3DREQ						0x80
#define MP3DCLK						0x01
#define MP3SDAT						0x40
#define MP3BSYNC					0x20
#define MP3WAIT						{int mpdelay; for (mpdelay=0;mpdelay<10;mpdelay++); }

// MP3 related prototypes
void mp3sendword(unsigned int data);
void pollmp3(int command,int song);
void mp3flush(void);
unsigned long reorder(unsigned long source);

main()
{
	unsigned int i,p;
	unsigned int incommingstate=0;
	volatile char *mydmxdata=(volatile char*)&_dmxoutputdata;
	volatile char *mydmxin=(volatile char*)&_dmxinputdata;
	volatile unsigned int *mydmxchanged=(volatile unsigned int*)&_dmxchanged;
	volatile unsigned int *mydmxaddress=(volatile unsigned int*)&_dmxinadr;
	volatile unsigned int *mydmxcount=(volatile unsigned int*)&_dmxcount;
	volatile unsigned int *mydmxtemp=(volatile unsigned int*)&_dmxtemp;
	char channel=0;
	char newdata=0;

	int newsong=0;
	int oldsong=0;

	printf("\n\rDMX MP3 receiver.\n\r");
   	fflush(stdout);

	// Clear output
	for (i=0;i<512;i++) mydmxdata[i]=0;

   	printf("Monitoring DMX input and console...press num to play\n\r");
   	fflush(stdout);

	while (1) {
		// Check for input from the console
		if (_cwaiting()!=0) {
			newdata=_cget();
			switch (newdata) {
				case '1':
					// Play sample 1
					pollmp3(1,1);
					break;
				case '2':
					// Play sample 1
					pollmp3(1,2);
					break;
				case '3':
					// Play sample 3
					pollmp3(1,3);
					break;
				case 's':
					// Play sample 3
					pollmp3(2,0);
					break;
				case 'x':
					// print the DMX inputs
				   	printf("DMX IN: ");
				   	for(p=0;p<20;p++) printf("%i,",mydmxin[p]);
					printf("\n\r");
					// Now the changed status
					printf("Changed: %i, count: %i\n\r",*mydmxchanged,*mydmxcount);
				   	fflush(stdout);
					break;
			}
		}
		// Check if we need to do anything based on DMX data
		// Figure out what we should be playing
		newsong=0;
		for (i=16;i<19;i++) {
			if (mydmxin[i]>50) newsong=i-15;
		}
		if (newsong!=oldsong) {
			if (newsong==0)	pollmp3(2,0); else pollmp3(1,newsong);
			oldsong=newsong;
		}
		pollmp3(0,0);
	}
}

// ************************ The Mp3 stuff **********************
// Shifts out 8 bits with clock and byte-sync

void mp3sendword(unsigned int data)
{
	unsigned int dcopy,tout;
	int n;
	dcopy=data;

	for (n=0;n<32;n++)
	{
		// If in first 6 bits send bsync high, else low
		if (n&0x06) tout=0; else tout=MP3BSYNC;
		// Check if data line needs to be high or not
		if ((dcopy&0x80000000)>0) tout+=MP3SDAT;
		// Send with clock low
		*gpiodataout=tout;
		// Shift data here so clock cycles are of roughly even duty
		dcopy=(dcopy<<1);
		// Cause a delay
		MP3WAIT
		// Send with clock high
		*gpiodataout=tout|MP3DCLK;
		// Cause a delay
		MP3WAIT
		// Ready for next cycle!
	}
}

void pollmp3(int command,int song)
{
	// To play an MP3 file simple send the entire file to the device
	// Only send data when DREQ=1

	unsigned int *songastart=(unsigned int*)0x8e002400;
	unsigned int *songbstart=(unsigned int*)0x8e00dfd0;
	unsigned int *songcstart=(unsigned int*)0x8e034de0;

	static int songstatus=0; // 0=stopped, >0 = playing song #
	static unsigned int *dpos;
	static unsigned int *endpoint;

	switch (command) {
		case 0:
			// Check if any more info needs to be sent to the MP3 player
			if (((*gpiodatain)&MP3DREQ)>0) {
				// We can send more info to the player
				if (songstatus>0) {
					mp3sendword(*dpos++);
					// stop playing if reached end
					if (dpos>=endpoint) {
					   	printf("\n\r**** Stopping playback as at end **** \n\r");
					   	fflush(stdout);
						songstatus=0;
					}
				} else {
					mp3sendword(0);
				}
			}
			break;
		case 1:
			// Start playing song
		   	printf("\n\r**** Starting playback of %i **** \n\r",song);
		   	fflush(stdout);
			switch (song) {
				case 1: dpos=(unsigned int*)songastart; endpoint=(unsigned int*)(dpos+SONGONELEN); break;
				case 2: dpos=(unsigned int*)songbstart; endpoint=(unsigned int*)(dpos+SONGTWOLEN); break;
				case 3: dpos=(unsigned int*)songcstart; endpoint=(unsigned int*)(dpos+SONGTHREELEN); break;
			}
			songstatus=song;
			break;
		case 2:
			// Stop playing song
		   	printf("\n\r**** Stopping playback as requested **** \n\r");
		   	fflush(stdout);
			songstatus=0;
			break;
	}
}