/*
* Copyright (C) 2021 ?2022 Texas Instruments Incorporated
*
* All rights reserved not granted herein.
* Limited License.
*
* Texas Instruments Incorporated grants a world-wide, royalty-free,
* non-exclusive license under copyrights and patents it now or
* hereafter owns or controls to make, have made, use, import, offer to
* sell and sell ("Utilize") this software subject to the terms herein.
* With respect to the foregoing patent license, such license is
* granted solely to the extent that any such patent is necessary to
* Utilize the software alone.  The patent license shall not apply to
* any combinations which include this software, other than
* combinations with devices manufactured by or for TI (?I Devices?.
* No hardware patent is licensed hereunder.
*
* Redistributions must preserve existing copyright notices and
* reproduce this license (including the above copyright notice and the
* disclaimer and (if applicable) source code license limitations
* below) in the documentation and/or other materials provided with the
* distribution
*
* Redistribution and use in binary form, without modification, are
* permitted provided that the following conditions are met:
*
*	* No reverse engineering, decompilation, or disassembly of this
*     software is permitted with respect to any software provided in
*     binary form.
*	* any redistribution and use are licensed by TI for use only with
*     TI Devices.
*	* Nothing shall obligate TI to provide you with source code for
*     the software licensed and provided to you in object code.
*
* If software source code is provided to you, modification and
* redistribution of the source code are permitted provided that the
* following conditions are met:
*
*   * any redistribution and use of the source code, including any
*     resulting derivative works, are licensed by TI for use only
*     with TI Devices.
*   * any redistribution and use of any object code compiled from the
*     source code and any resulting derivative works, are licensed by
*     TI for use only with TI Devices.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its suppliers may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* DISCLAIMER.
*
* THIS SOFTWARE IS PROVIDED BY TI AND TI? LICENSORS "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 TI AND TI? LICENSORS 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.
*/

#include "case.h"
#include "fatfs.h"
#include "i2s.h"
#include "sai.h"
#include "i2c.h"
#include "spi.h"
#include "init.h"
#include "tas2563_interface.h"

#define SAMPLE_LEN  2048
Interrupt_flag in_flag={0,0,0};

void testcase1()
{
 	if(exTas256x_speakeron(BYPASS))
     {
         printf("tas2563 power on failed\r\n");
         goto EXIT;

     };
    playback("selience-stero.pcm",0);
    // playback("Where Did U Go.pcm",0);
    exTas256x_speakeroff();

EXIT:
    return ;

}
void testcase2()
{
    uint16_t *buffer;
    uint32_t starttime;
    buffer=(uint16_t*)malloc(SAMPLE_LEN);
    memset(buffer,0,SAMPLE_LEN);
 	if(exTas256x_speakeron(CALIBRATION)) {
        printf("tas2563 power on failed\r\n");
        goto EXIT;
    }
    HAL_Delay(100);


    exTas256x_calib_start(NULL);
    starttime = HAL_GetTick();
    while(HAL_GetTick() > starttime +2000)
    {
        if(in_flag.audio_txflag==0){
            in_flag.audio_txflag=2;
            if(i2s_transmit(buffer,SAMPLE_LEN/2)) {
                printf("i2s transmit error\r\n");
                break;
                }
        }
    }
    free(buffer);
    exTas256x_calib_stop();
    exTas256x_speakeroff();
EXIT:
    return ;
}

void testcase3()
{
    int ret;
    uint32_t f0_array[2];
 	if(exTas256x_speakeron(CALIBRATION)) {
        printf("tas2563 power on failed\r\n");
        goto EXIT;
    }
    
    //playback("-15dB RMS stereo pink noise 60s.pcm",5000);
    // Playback in another thread
    HAL_Delay(8); //wait for 8s pink noise playback, then read the f0
    ret = exTas256x_get_f0(f0_array);
    if(ret!= -1) {
        printf("f0:%d,f0_array1:%d,f0_array1:%d \r\n",ret,f0_array[0],f0_array[1]);
    }
    exTas256x_speakeroff();
EXIT:
    return ;
}

int main_test()
{
    int nRet = 0;
    char cali[][10]={"4ohm","6ohm","8ohm","speaker"};
	nRet =exTas256x_init();
	if(nRet) {
		printf("%s:%u init error!\n",__func__, __LINE__);
		goto EXIT;
	}

    printf("Please push the key to start test 1\r\n");
    while(!in_flag.key_pushflag);
    in_flag.key_pushflag=0;
    printf("Test 1 start,music by dsp\r\n");
    testcase1();
    printf("Test 1 is completed\r\n");

    for(int i=0;i<4;i++){
        printf("Please connect %s first and push the key to start calibration\r\n",cali[i]);
        while(!in_flag.key_pushflag);
        in_flag.key_pushflag=0;
        printf("Calibration %s start\r\n",cali[i]);
        testcase2();
        printf("Calibration %s is completed\r\n",cali[i]);
    }
    printf("Please mask the speaker and push the key to start test 3\r\n");
    while(!in_flag.key_pushflag);
    in_flag.key_pushflag=0;
    printf("Test 3 start,get f0\r\n");
    testcase3();
    printf("Test 3 is completed\r\n");

	exTas256x_deinit();
EXIT:
	return nRet;

}

int i2c_print_reg_value(uint8_t devaddr)
{
    uint8_t regs[128];
    int ret=0;
    memset(regs,0,128);
    if( i2c_mem_read(devaddr,0x00, regs, 128)!=HAL_OK) {
            printf("mem read failed\r\n");
            ret=-1;
            goto EXIT;
        }
        for(uint8_t i=0;i<128;i++){
                printf(" 00---%x---%x   \r\n",i,regs[i]);
        }
    EXIT:
        return ret;
}
int spi_print_reg_value(uint8_t dev)
{
    uint8_t regs[128];
    int ret=0;
    memset(regs,0,128);
    if( spi_mem_read(dev,0x00, regs, 128)!=HAL_OK) {
            printf("mem read failed\r\n");
            ret=-1;
            goto EXIT;
        }
        for(uint8_t i=0;i<128;i++){

            printf(" 00---%x---%x   \r\n",i,regs[i]);

        }

    EXIT:
        return ret;
}


void i2s_dma_tx_callback(void)
{
    in_flag.audio_txflag--;
}
//wait to complete
void i2s_dma_rx_callback(void)
{

}
void  pushkey_callback(void)
{
    in_flag.key_pushflag=1;
}
void  interrupt_1_callback(void)
{

    printf("interrupt 1 event\r\n");

}
void  interrupt_2_callback(void)
{
    printf("interrupt 2 event\r\n");
}

//Input Parameter:
//1:file name
//2:time of playing music ,when its value is 0, then run to ending.
void playback(const char *file_name,uint32_t time_ms)
{
        uint8_t retSD;
        uint8_t index=0,i;
        uint32_t j;
        uint16_t *buffer[4];

        uint8_t *buf;
        uint32_t outlen[4],out;
        uint8_t Status = GPIO_PIN_RESET;
        uint32_t starttime;
        FIL File;
        retSD = f_open(&File,file_name,FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
        if(retSD){
        printf("Open pcm file failed,error:%d \r\n",retSD);
        return;
         }
        buf = (uint8_t*)malloc(SAMPLE_LEN*4);
        if(buffer[3] == NULL) {
            printf("Buffer apply failed\r\n");
            goto EXIT;
        }
        retSD = f_read(&File,buf,SAMPLE_LEN*3,(UINT*)&out);
        if(retSD)
        {
            printf("%s file read failed,error:%d \r\n",file_name, retSD);
            goto EXIT;
        }
        for(i=0;i<4;i++) {
            buffer[i] = buf + SAMPLE_LEN*i;
            outlen[i] = (out > SAMPLE_LEN)? SAMPLE_LEN:out;
            out -= outlen[i];
        }
        starttime = HAL_GetTick();
		while(1)
		{

    if(in_flag.audio_txflag==0)
    {
        in_flag.audio_txflag=2;
#ifdef SAI_ENABLE

        if(sai_transmit(buffer[index],outlen[index]/2))
        {
        printf("sai transmit error\r\n");
        break;
        }
#else
        if(i2s_transmit(buffer[index],outlen[index]/2))
        {
        printf("i2s transmit error\r\n");
        break;
        }
#endif

        if(outlen[index] != SAMPLE_LEN)
        {
            printf("read file over\r\n");
            break;
        }
        retSD = f_read(&File,buffer[(index+4-1)%4],SAMPLE_LEN,(UINT*)&outlen[(index+4-1)%4]);
        if(retSD)
        {
            printf("%s file read failed,error:%d \r\n",file_name, retSD);
            break;
        }
        index++;
        index %= 4;


        if(j%10==0)//Transform LED
    {
         Status ^= 0x1;
         switch_led0(Status);
    }
        j++;

   }


    if(in_flag.key_pushflag)//print register value
    {
        in_flag.key_pushflag=0;
#ifdef I2C_ENABLE
        i2c_print_reg_value(0x98);
#else
        spi_print_reg_value(0);
#endif
    }

    if(time_ms )
    {
        if(HAL_GetTick() >= (starttime + time_ms))
        {
            printf("time up\r\n");
            break;
        }
    }
}
EXIT:
    f_close(&File);
    free(buf);
}

