/*******************************************************************************
 * Aleix Riera                                                                 *
 * www.fjarre.com/~aleix                                                       *
 * aleix@fjarre.com                                                            *
 *******************************************************************************/
///////////////////////////////////////////////////////////
//DEFINES
///////////////////////////////////////////////////////////
//******************* General&DSP *************************
//(DSP: MAKE SURE TO MAKE THE CHANGES IN BOTH SIDES)
#define		MIN_CUTOFF		.062500	//0x080000
#define		WAVE_TABLE_LEN		256
#define		BUFFER_SIZE		16
#define		DSP_DATA_LEN		79
//(Arithmetic)
#define		ONE			.9999999
#define		AHALF			.4999999
#define		TABLE_LEN		128
#define		INI_VOLUME		120
#define		FS			48000
//******************* Title&Config ************************
#define		WAIT_TITLE		1
#define		LEDS			1
#define		EGGS			1
#define		INIT_EVENTS		5
#define		WAIT_TITLE_TIME1	1000	//(in ms)
#define		WAIT_TITLE_TIME2	300	//(in ms)
#define		WAIT_TITLE_TIME3	100	//(in ms)
#define		WAIT_LOADSAVE		600	//(in ms)
#define		MAX_WAIT_LFO_LEDS	10	//LED active/inactive in seconds (led_tasks)
#define		LEDS_ALWAYS		PANEL01_LED_EDIT|PANEL01_LED_SHIFT
//****************** Table Values *************************
#define		TVALUE_AMPLITUDE_INI		0		//[0..1]
#define		TVALUE_AMPLITUDE_FINAL		AHALF
#define		TVALUE_AMPLITUDE_LOG		0
#define		TVALUE_FREQ_INI			0		//[0..FS/2]
#define		TVALUE_FREQ_FINAL		40
#define		TVALUE_FREQ_LOG			1		//1=logarithmic
#define		TVALUE_FREQ_DMA			0		//0=No DMA oscillators
#define		TVALUE_OFFSET_INI		0		//[0..1]
#define		TVALUE_OFFSET_FINAL		ONE
#define		TVALUE_OFFSET_LOG		0
#define		TVALUE_OFFSET_CUTOFF_INI	MIN_CUTOFF	//[0..1]
#define		TVALUE_OFFSET_CUTOFF_FINAL	ONE
#define		TVALUE_OFFSET_CUTOFF_LOG	0
#define		TVALUE_DELAYTIME_MIN		.00001		//[0..1)(NOTE:correct values depend of DELAY_BUFFER size)
			//Maximum delay time:
			//MAX=DELAY_BUFFER_SIZE/FS
			//MIN=TVALUE_DELAYTIME_MIN*MAX
			//This version: 0.11ms - 10,321s (logtable[127]=0.944061)
//********************* Menu ******************************
#define		MAX_OPTIONS_PER_SECTION		9
	#define		MENU_PART			4
	#define		MENU_GROUP			2
	#define		MENU_PAGE 			9
	#define		OPTIONS				MAX_OPTIONS_PER_SECTION*5
//********************* Menu Prints ***********************
#define	PART_ROW	0
#define PART_COL	0
#define	GROUP_ROW	0
#define GROUP_COL	1
#define PAGE_ROW	0
#define	PAGE_COL	3
#define PARAM_ROW	1
#define	PARAM_COL	0
#define PARAM_VALUE_ROW	1
#define	PARAM_VALUE_COL	11
//********************* Loading/saving presets ************
#define	FLASH_FLAG		0x49	//hope this flag won't appear when flash initialization
#define	MAX_PRESETS_SIZE	128
#define	FLASH_DATA_LEN		70+1	//there's a flag
#define	PRINT_SAVE		"SAVE Preset"
#define	PRINT_LOAD		"LOAD Preset"
#define	KEY_SAVE		PANEL01_KEY_EDIT
#define	KEY_LOAD		PANEL01_KEY_SHIFT
//*********************** Easter eggs *********************
enum{NONE,RANDOM,EGG1,EGG2,EGG3};
//EGGRND: keys combination
#define	EGGRND_N	18
#define EGGRND_KEYS	PANEL01_KEY_VALUE_UP|PANEL01_KEY_VALUE_DOWN
#define	EGGRND00_PRINT0	"Vangelis,JMJarre"
#define	EGGRND00_PRINT1	"Kraftwerk,TDream"
#define	EGGRND01_PRINT0	"It's time to get" 
#define	EGGRND01_PRINT1	"the rhythm(Duke)"
#define	EGGRND02_PRINT0	"Pink Floyd, Enya"
#define	EGGRND02_PRINT1	"Alan Parsons Prj"
#define	EGGRND03_PRINT0	"Oldfield, Elfman"
#define	EGGRND03_PRINT1	"Glass,C.duSoleil"
#define	EGGRND04_PRINT0	"Dom F Scab,Lavid"
#define	EGGRND04_PRINT1	"Koval, Vitoulis "
#define	EGGRND05_PRINT0	"Chernob,Harrysb,"
#define	EGGRND05_PRINT1	"Sellaf,Hiroshima"
#define	EGGRND06_PRINT0	"ALLweSEEisBUTaDR"
#define	EGGRND06_PRINT1	"EAMwithinAdream."
#define	EGGRND07_PRINT0	"HighLevel energy"
#define	EGGRND07_PRINT1	"source detected."
#define	EGGRND08_PRINT0	"EXONIQE:Twilight"
#define	EGGRND08_PRINT1	"Zone:'Pink Rain'"
#define	EGGRND09_PRINT0	"ELECTRONIC TOUR:"
#define	EGGRND09_PRINT1	" 'Space Chords' "
#define	EGGRND10_PRINT0	"I love you,Marta"
#define	EGGRND10_PRINT1	"@_@PowerpuffGirl"
#define	EGGRND11_PRINT0	"Tales of Mystery"
#define	EGGRND11_PRINT1	"and Imagination."
#define	EGGRND12_PRINT0	"ItsTimeToKickAss"
#define	EGGRND12_PRINT1	"AndChewBubbleGum"
#define	EGGRND13_PRINT0	"THXuALL4URhelp&2"
#define	EGGRND13_PRINT1	"myPARENTS&friend"
#define	EGGRND14_PRINT0	"WHATareUwaiting4"
#define	EGGRND14_PRINT1	"XMAS?DamnedIFiDO"
#define	EGGRND15_PRINT0	"*Music Non-Stop*"
#define	EGGRND15_PRINT1	"PlanetOfVisions."
#define	EGGRND16_PRINT0	"AllThatYouNeedIs"
#define	EGGRND16_PRINT1	"Wine&GoodCompany"
#define	EGGRND17_PRINT0	"SPOLEconceivedBY"
#define	EGGRND17_PRINT1	" Jordi Trujillo "
//EGG1: lots of keys pressed
#define EGG1_NKEYS	500
#define	EGG1_PRINT0	"You make me feel"
#define	EGG1_PRINT1	"good! Nice work!"
//EGG2: secret combination of potentiometers value
#define	EGG2_VAL1	19
#define	EGG2_VAL2	4
#define	EGG2_VAL3	82
#define	EGG2_PRINT0	"Great! This' my "
#define	EGG2_PRINT1	"birth date.@^_^@"
//EGG3: another secret combination of potentiometers value
#define	EGG3_VAL1	29
#define	EGG3_VAL2	7
#define	EGG3_VAL3	88
#define	EGG3_PRINT0	"My love goes on "
#define	EGG3_PRINT1	"4ever.Je t'aime."
///////////////////////////////////////////////////////////
//STRUCTS
///////////////////////////////////////////////////////////
typedef struct{
	rtems_unsigned8	Amp[3];		//0:CUT;1:RES;2:PAN
	rtems_unsigned8	Freq[3];	//0:CUT;1:RES;2:PAN
	rtems_unsigned8	K[3];		//0:CUT;1:RES;2:PAN
	rtems_unsigned8	Filtlvl[3];	//0:LPF;1:BPF;2:HPF
	rtems_unsigned8	Sat;		//Overdrive
	rtems_unsigned8	Send;
	rtems_unsigned8 Vol;
	rtems_unsigned8	Active;
}TSouthPoleLine;

typedef struct{
	TSouthPoleLine	Line[4];
	rtems_unsigned8	D[3];	//0:Frac;1:Feedback;2:Random
	rtems_unsigned8	Mix[3];	//0:Thru;1:Lines;2:Delay
}TSouthPoleVariables;

typedef struct{
	TSouthPoleVariables	Factory;
	char			Name[PANEL_LCD_MAX_LINE_LEN+1];
}TSouthPoleFactoryPresets;
///////////////////////////////////////////////////////////
//CHARACTER REDEFINES
///////////////////////////////////////////////////////////
static rtems_unsigned8 char_active[8]={
	0x1F,	//11111
	0x1C,	//11100
	0x1D,	//11101
	0x0D,	//01101
	0x15,	//10101
	0x13,	//10011
	0x1B,	//11011
	0x1F	//11111
};
static rtems_unsigned8 char_noactive[8]={
	0x1F,	//11111
	0x1F,	//11111
	0x06,	//00110
	0x15,	//10101
	0x1B,	//11011
	0x15,	//10101
	0x0C,	//01100
	0x1F	//11111
};
static rtems_unsigned8 char_line0[8]={
	0x11,	//10001
	0x13,	//10011
	0x15,	//10101
	0x11,	//10001
	0x11,	//10001
	0x13,	//10011
	0x10,	//10000
	0x1F	//11111
};
static rtems_unsigned8 char_line1[8]={
	0x12,	//10010
	0x15,	//10101
	0x11,	//10001
	0x12,	//10010
	0x14,	//10100
	0x17,	//10111
	0x10,	//10000
	0x1F	//11111
};
static rtems_unsigned8 char_line2[8]={
	0x17,	//10111
	0x11,	//10001
	0x12,	//10011
	0x11,	//10001
	0x15,	//10101
	0x13,	//10011
	0x10,	//10000
	0x1F	//11111
};
static rtems_unsigned8 char_line3[8]={
	0x12,	//10010
	0x14,	//10100
	0x15,	//10101
	0x17,	//10111
	0x11,	//10001
	0x11,	//10001
	0x10,	//10000
	0x1F	//11111
};
static rtems_unsigned8 char_param1[8]={	//left
	0x1F,	//11111
	0x1E,	//11110
	0x1C,	//11100
	0x1C,	//11100
	0x18,	//11000
	0x18,	//11000
	0x10,	//10000
	0x10	//10000
};
static rtems_unsigned8 char_param2[8]={
	0x01,	//00001
	0x01,	//00001
	0x03,	//00011
	0x03,	//00011
	0x07,	//00111
	0x07,	//00111
	0x0F,	//01111
	0x1F	//11111
};
///////////////////////////////////////////////////////////
//FUNCTION DECLARATIONS
///////////////////////////////////////////////////////////
//init.c
void		init_flash(void);
void		init_panel_and_dsp(void);
void		init_panel_redefines(void);
void		init_menu(void);
void		init_variables(void);
void		init_southpole_presets(void);
void		fill_tables(void);
void		leds_and_wait(void);
void		fill_table(rtems_signed32 *table,float margin1, float margin2,rtems_boolean log);
void		fill_freq_tables(int wlength,int fs,int tablelen,rtems_signed32 *itable,rtems_signed32 *ftable,float f1,float f2,rtems_boolean log,rtems_boolean dma);
void		exit_flash(void);
//print.c
void		print_LCD(void);
void		print_LCD_part(void);
void		print_LCD_group(void);
void		print_LCD_page(void);
void		print_LCD_param(void);
void		print_preset(void);
void		print_preset_name(void);
void		print_title(int which);
void		trace_variables(void);	//ONLY FOR 0.96
void		print_egg(int egg);
//dsp.c
void		prepare_and_send_DSP(void);
//flash.c
void		access_flash(rtems_boolean saving);
void		write_flash(void);
rtems_boolean	read_flash(void);//TRUE if preset exists in flash
void		read_bank(rtems_boolean initializing);//Only TRUE when initializing
void		prepare_mem_to_flash(void);
void		prepare_flash_to_mem(void);
//leds.c
static rtems_task led_task1(rtems_task_argument argument);
rtems_id create_led_task1(rtems_task_argument argument);
static rtems_task led_task2(rtems_task_argument argument);
rtems_id create_led_task2(rtems_task_argument argument);
static rtems_task led_task3(rtems_task_argument argument);
rtems_id create_led_task3(rtems_task_argument argument);