/*
 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/*******************************************************************************
 * Standard C Included Files
 ******************************************************************************/
#include <stdio.h>
#include <string.h>
/*******************************************************************************
 * SDK Included Files
 ******************************************************************************/
#include "fsl_sgtl5000_driver.h"
#include "fsl_clock_manager.h"
#include "fsl_device_registers.h"
#include "fsl_soundcard.h"
#include "board.h"
/*******************************************************************************
 * Application Included Files
 ******************************************************************************/
#include "modulator.h"
#include "pcm_data.h"
#include "terminal_menu.h" 
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define SAMPLE_SIZE 1024
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
void pin_setup(void);
void user_menu(void);
/*******************************************************************************
 * Global Variables
 ******************************************************************************/
extern sound_card_t g_soundCard;
float32_t fftStore[2 * SAMPLE_SIZE];
float32_t fftFreqBin[SAMPLE_SIZE];
const uint32_t *cMajorArpeggio[] = {(uint32_t *)sin261Hz, (uint32_t *)sin329Hz, (uint32_t *)sin392Hz, (uint32_t *)sin523Hz, (uint32_t *)sin392Hz, (uint32_t *)sin329Hz, (uint32_t *)sin261Hz};
/*******************************************************************************
 * Code
 ******************************************************************************/
void pin_setup(void)
{    
    clock_manager_set_gate(kClockModuleSAI, 0, 1);
    
    configure_i2s_pin_mux(0);
    configure_i2c_pin_mux(0);
}

/******************************************************************************/
int main (void)
{ 
    uint32_t size;
  
    hardware_init();
    
    /* Configure pins. */
    pin_setup();
    
    /* Initialize audio codec & i2s module. */
    modulator_init();
     
    /* Initialize UART terminal. */
    debug_uart_init(BOARD_DEBUG_UART_INSTANCE, BOARD_DEBUG_UART_BAUD);
    
    /* Print welcome message. */
    menu_start();
    
    /* Adjust volume to a reasonable level. */
    sgtl_write_reg(g_soundCard.codec.handler, CHIP_DAC_VOL, (180|180<<8));
    
    /* Get size of arpegio. */
    size = sizeof(cMajorArpeggio)/sizeof(uint32_t *);
    
    /* Play introduction arpeggio. */
    play_wav_arpeggio((uint32_t *)cMajorArpeggio, size, 2);
    
    while(1)
    {
        user_menu(); /* User menu, viewable through serial terminal. */  	
    } 
}
/******************************************************************************/
void user_menu(void)
{
    char menuMsg;
    uint32_t *wavData;
    uint16_t wavSize;
    uint8_t divider;
	
    menuMsg = menu_note_select();
	
    switch(menuMsg)
    {
        case '1':
            wavData = (uint32_t *)sin261Hz;
            wavSize = sizeof(sin261Hz);
            break;
        case '2':
            wavData = (uint32_t *)sin293Hz;
            wavSize = sizeof(sin293Hz);
            break;
        case '3':
            wavData = (uint32_t *)sin329Hz;
            wavSize = sizeof(sin329Hz);
            break;
        case '4':
            wavData = (uint32_t *)sin349Hz;
            wavSize = sizeof(sin349Hz);
            break;
        case '5':
            wavData = (uint32_t *)sin392Hz;
            wavSize = sizeof(sin392Hz);
            break;
        case '6':
            wavData = (uint32_t *)sin440Hz;
            wavSize = sizeof(sin440Hz);
            break;
        case '7':
            wavData = (uint32_t *)sin493Hz;
            wavSize = sizeof(sin493Hz);
            break;
        case '8':
            wavData = (uint32_t *)sin523Hz;
            wavSize = sizeof(sin523Hz);
            break;         
        default:
            break;
    }
	
    menuMsg = menu_duration_select();
	
    switch(menuMsg)
    {
        case '1':
            divider = 1;
            break;
        case '2':
            divider = 2;
            break;
        case '3':
            divider = 4;
            break;
        default:
            break;
    }
	
    menuMsg = menu_modulation_select();
	
    switch(menuMsg)
    {
        case '1':
            play_wav(wavData, divider);                
            break;
        case '2':
            play_mod_wav((uint16_t *)wavData, (uint16_t *)modBuffer, fftStore, fftFreqBin, divider, kSquareWave, wavSize, SAMPLE_SIZE);                
            break;
        case '3':
            play_mod_wav((uint16_t *)wavData, (uint16_t *)modBuffer, fftStore, fftFreqBin, divider, kSawWave, wavSize, SAMPLE_SIZE);               
            break;
        case '4':
            play_mod_wav((uint16_t *)wavData, (uint16_t *)modBuffer, fftStore, fftFreqBin, divider, kTriangleWave, wavSize, SAMPLE_SIZE);               
            break;            
        default:
            break;
    }  
}
/******************************************************************************
 * EOF
 ******************************************************************************/
