
#include "basic_io.h"
#include "LCD.h"
#include "SD_Card.h"
#include "altera_avalon_pio_regs.h"
#include "includes.h"
#include <stdio.h>
#include "Test.h"
#include "Open_I2C.h"
#include <stdbool.h>
////#define WHO_AM_I   0x0D
//
//int main(void)
//{
//  UINT16 i=0,Tmp1=0,Tmp2=0;
//  UINT32 j=720;
//  BYTE Buffer[512]={0};
//
//  SD_card_init();
//  LCD_Test();
//  while(1)
//  {
//    //printf("%d\n",IORD(ACCEL_SDA_BASE,0));
//    SD_read_lba(Buffer,j,1);
//    while(i<512)
//    {
//      if(!IORD(AUDIO_0_BASE,0))
//      {
//        Tmp1=(Buffer[i+1]<<8)|Buffer[i];
//        IOWR(AUDIO_0_BASE,0,Tmp1);
//        i+=2;
//      }
//    }
//    IOWR(SEG7_DISPLAY_BASE,0,j);
//    j++;
//    i=0;
//  }
// 
//  return 0;
//}

//-------------------------------------------------------------------------


//* Definition of Task Stacks */
#define   TASK_STACKSIZE       2048
OS_STK    task_which_note_stk[TASK_STACKSIZE];
OS_STK    task_sd_play_stk[TASK_STACKSIZE];


/* Definition of Task Priorities */
#define TASK_WHICH_NOTE_PRIORITY    1
#define TASK_SD_PLAY_PRIORITY       2


//#define NONE_PRESSED 1//value read form button PIO when no buttons pressed
//#define DEBOUNCE 500000 //time in microseconds to wait for swithc debounce.
 // Time in microseconds to wait for switch debounce


//Eric's add-on.
OS_EVENT *SQ;
// globals! AHH
UINT32 j=0;
//UINT32 range_end=7900;
UINT32 range_end=0;
int tg = 0;
int ms = 0;//default 0 is note mode. 1 is chord mode.
int ms1 = 0;
/* Figures out which tap sensor is engaged and passes it to task_sd_play via a global */
void task_which_note(void* pdata)
{
    void *SM[10];
    SQ = OSQCreate(&SM[0], 10);
    INT8U err;
    void *Smsg;
    int swcnt = 0;
    while(1){
               
        printf("Before Pend.\n");
        Smsg = OSQPend(SQ, 0, &err);
        //printf("****************%d.\n", IORD_ALTERA_AVALON_PIO_DATA(MS_BASE));
        printf("After Pend ms=%d.\n", ms);
        if(err == OS_NO_ERR){
            tg = 1;
            printf("Before Reading from smsg;\n");
            INT8U switches = IORD_ALTERA_AVALON_PIO_DATA( Smsg );
            switches = switches % 254;
            swcnt = swcnt + switches;
            printf("Sw: %d\n",swcnt);
            if(ms%2 == 0){
                //Default: notes
                printf("Note Mode\n");
                if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEA_BASE)){   //tap sensors are active high
                    printf("Play note A\n");
                    j=1800;
                    range_end=2500; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEB_BASE)){  
                    printf("Play note B\n");
                    j=2900;
                    range_end=3400; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEC_BASE)){  
                    printf("Play note C\n");
                    j=3550;
                    range_end=4200; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTED_BASE)){  
                    printf("Play note D\n");j=4400;
                    range_end=5200; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEE_BASE)){  
                    printf("Play note E\n");j=5300;
                    range_end=5900; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEF_BASE)){  
                    printf("Play note F\n");j=6050;
                    range_end=6800; }
                else if(!IORD_ALTERA_AVALON_PIO_DATA(NOTEG_BASE)){  
                    printf("Play note G\n");j=6900;
                    range_end=7900; } 
                else {
                    tg = 0;
                }
            }
            if(ms%2 == 1){
                //Chord mode
                printf("Chord Mode\n");
            }
        }
        else{
            printf("Err.\n");
            }
        
    } //while(1)
}
//isr for switch
static void isr_SW (){
   OSQPost(SQ, IORD_ALTERA_AVALON_PIO_EDGE_CAP(SWITCH_PIO_BASE));
   IOWR_ALTERA_AVALON_PIO_EDGE_CAP(SWITCH_PIO_BASE,1);

}
//isr for RST
static void isr_ModeSwitch (){
   //OSQPost(SQ, IORD_ALTERA_AVALON_PIO_EDGE_CAP(SWITCH_PIO_BASE));
   //Mode switch signal interrupts, change the ms value to be 1;
   //OSQPost(SQ, IORD_ALTERA_AVALON_PIO_DATA(MS_BASE));
   //ms ++;
   ms = ms + IORD_ALTERA_AVALON_PIO_EDGE_CAP(MS_BASE);
   //ms = ms%2;
   IOWR_ALTERA_AVALON_PIO_EDGE_CAP(MS_BASE,1);

}
//void task_db (void* pdata)
//{
//    UINT32 buttons;
//    UINT32 button_val = 0xf;
//    int print_cnt;
//    printf("DDDDDDDDDDDDDDDBBBBBBBBBBBBBBBBBBBBB\n");
//    while(1){
//        printf("task db\n");
//        print_cnt = 0;
//        buttons = IORD_ALTERA_AVALON_PIO_DATA(MS_BASE);
//        if(buttons != NONE_PRESSED){ //if button pressed
//            usleep(DEBOUNCE);
//            ms++;
//            printf("button pressed ms = %d\n",ms);
//            
//            while(buttons != NONE_PRESSED) { //wait for button release
//                //printf("wait for it.\n");
//                button_val = buttons; //strobe state
//                buttons = IORD_ALTERA_AVALON_PIO_DATA(MS_BASE);
//            }
//            print_cnt = 1;
//        }
//
//    }
//    
//}
/* Plays .wav from SD card with switch up and glove button down */
void task_sd_play(void* pdata)
{
    UINT32 range_start=0;
    BYTE Buffer[512]={0};
    UINT16 i=0,Tmp1=0;
    printf("Please insert SD card.\n");  
    while(SD_card_init())    //will return 1 and continuously loop until SD card inserted
        usleep(500000);    
    LCD_Test();
    printf("SD card detected.\n");
    
//playing note

    while(1) {
        SD_read_lba(Buffer,j,1);  
        range_start=j;  //won't work, j++ rem? how to get it so it will play same note every switch flick?      
        if (tg == 1) {
               
            if(j<range_end) {   //restrict to only play 1 note/section
                while(i<512) { 
                    if(!IORD(AUDIO_0_BASE,0)) {  
                        Tmp1=(Buffer[i+1]<<8)|Buffer[i];
                        IOWR(AUDIO_0_BASE,0,Tmp1);
                        i+=2;
                    } //if(!IORD(AUDIO_0_BASE,0))
                } //while(i<512)
                IOWR(SEG7_DISPLAY_BASE,0,j);
                j++;
                i=0;
            } //if(j<range_end) 
        } //if play on switch
        else
            j=range_start; //reset j
    } //while(1)

} //end task_sd_play




// The main function creates task_sd_play 
int main(void)
{
    //isr_SW
    alt_irq_register (SWITCH_PIO_IRQ, NULL, isr_SW);
    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(SWITCH_PIO_BASE, 1);
    //isr_MS
    alt_irq_register (MS_IRQ, NULL, isr_ModeSwitch);
    IOWR_ALTERA_AVALON_PIO_IRQ_MASK(MS_BASE, 1);
    OSInit();

    
   OSTaskCreateExt(task_which_note,
                  NULL,
                  (void *)&task_which_note_stk[TASK_STACKSIZE-1],
                  TASK_WHICH_NOTE_PRIORITY,
                  TASK_WHICH_NOTE_PRIORITY,
                  task_which_note_stk,
                  TASK_STACKSIZE,
                  NULL,
                  0);
                  
  OSTaskCreateExt(task_sd_play,
                  NULL,
                  (void *)&task_sd_play_stk[TASK_STACKSIZE-1],
                  TASK_SD_PLAY_PRIORITY,
                  TASK_SD_PLAY_PRIORITY,
                  task_sd_play_stk,
                  TASK_STACKSIZE,
                  NULL,
                  0);
//  OSTaskCreateExt(task_db,
//                  NULL,
//                  (void *)&task_db_stk[TASK_STACKSIZE-1],
//                  TASK_DB_PRIORITY,
//                  TASK_DB_PRIORITY,
//                  task_db_stk,
//                  TASK_STACKSIZE,
//                  NULL,
//                  0);
  OSStart();
  return 0;
}
