#include   "../config/mcal/peripheral/sercom/i2c_master/plib_sercom1_i2c_master.h"
#include "DrvRT905.h"
#include "rt903x_reg.h"
#include "OsekCom.h"
#include "RTT/SEGGER_RTT.h"
#include "RTT/SEGGER_RTT_Conf.h"

#define RT905ADDR   0x5F
#define I2C_INIT    0
#define I2C_WRITE   1
#define I2C_READ    2


#define PLAY_CTRL_GO    0x01


static uint8_t I2C_state = I2C_INIT;
uint8_t I2Ctx[5] = {0};
uint8_t I2Crx[5] = {0};
static uint16_t I2C_counter = 0;


#define ARR1LEN (WAVE1LEN1+WAVE1LEN2+1)
#define ARR2LEN (WAVE2LEN1+WAVE2LEN2+1)
#define ARR3LEN (WAVE3LEN1+WAVE3LEN2+1)

#define WAVE1LEN1  99
#define WAVE1LEN2  98
//150Hz 0.7/0.4
const signed char RAMPLAY_wave1_data[ARR1LEN]  = {
    REG_RAM_DATA,
    /* --------------wave1 0.7----------------------*/
    -2   ,-4   ,-5   ,-6   ,-6   ,-5   ,-2   ,4    , /*0-7*/
    11   ,21   ,32   ,44   ,56   ,68   ,79   ,87   , /*8-15*/
    94   ,97   ,97   ,95   ,90   ,82   ,72   ,61   , /*16-23*/
    48   ,34   ,20   ,6    ,-9   ,-23  ,-37  ,-50  , /*24-31*/
    -63  ,-74  ,-84  ,-92  ,-97  ,-99  ,-97  ,-93  , /*32-39*/
    -85  ,-76  ,-64  ,-52  ,-41  ,-31  ,-24  ,-20  , /*40-47*/
    -19  ,-21  ,-26  ,-33  ,-40  ,-48  ,-55  ,-61  , /*48-55*/
    -64  ,-66  ,-65  ,-63  ,-58  ,-53  ,-46  ,-39  , /*56-63*/
    -31  ,-23  ,-14  ,-6   ,3    ,11   ,20   ,27   , /*64-71*/
    34   ,40   ,45   ,48   ,50   ,50   ,48   ,46   , /*72-79*/
    42   ,38   ,33   ,28   ,23   ,18   ,13   ,9    , /*80-87*/
    5    ,2    ,0    ,-2   ,-3   ,-3   ,-3   ,-3   , /*88-95*/
    -2   ,-1   ,0    , /*96-98*/
    /* --------------wave1 0.4----------------------*/
    -2   ,-3   ,-4   ,-4   ,-3   ,-1   ,2    ,6    , /*0-7*/
    12   ,18   ,25   ,32   ,39   ,45   ,50   ,53   , /*8-15*/
    55   ,55   ,54   ,51   ,47   ,41   ,34   ,27   , /*16-23*/
    19   ,11   ,3    ,-5   ,-13  ,-21  ,-29  ,-36  , /*24-31*/
    -43  ,-48  ,-53  ,-55  ,-57  ,-56  ,-53  ,-49  , /*32-39*/
    -43  ,-37  ,-30  ,-24  ,-18  ,-14  ,-12  ,-11  , /*40-47*/
    -12  ,-15  ,-19  ,-23  ,-28  ,-32  ,-35  ,-37  , /*48-55*/
    -38  ,-37  ,-36  ,-33  ,-30  ,-27  ,-22  ,-18  , /*56-63*/
    -13  ,-8   ,-3   ,1    ,6    ,11   ,15   ,19   , /*64-71*/
    23   ,25   ,27   ,28   ,28   ,27   ,26   ,24   , /*72-79*/
    22   ,19   ,16   ,13   ,10   ,7    ,5    ,3    , /*80-87*/
    1    ,0    ,-1   ,-2   ,-2   ,-2   ,-2   ,-2   , /*88-95*/
    -1   ,0    , /*96-97*/
};

#define WAVE2LEN1  92
#define WAVE2LEN2  91
const signed char RAMPLAY_wave2_data[ARR2LEN] = {
    REG_RAM_DATA,
    /* --------------wave2 0.7----------------------*/
    -4   ,-6   ,-8   ,-9   ,-7   ,-2   ,6    ,17   , /*0-7*/
    30   ,45   ,61   ,75   ,86   ,94   ,97   ,96   , /*8-15*/
    90   ,79   ,65   ,48   ,29   ,9    ,-12  ,-32  , /*16-23*/
    -51  ,-68  ,-82  ,-92  ,-97  ,-98  ,-94  ,-86  , /*24-31*/
    -73  ,-59  ,-43  ,-27  ,-13  ,-3   ,3    ,5    , /*32-39*/
    3    ,-3   ,-12  ,-22  ,-33  ,-42  ,-51  ,-57  , /*40-47*/
    -61  ,-63  ,-64  ,-63  ,-61  ,-59  ,-55  ,-51  , /*48-55*/
    -45  ,-38  ,-31  ,-22  ,-12  ,-2   ,7    ,17   , /*56-63*/
    25   ,32   ,38   ,42   ,45   ,47   ,48   ,47   , /*64-71*/
    46   ,44   ,41   ,37   ,33   ,28   ,22   ,17   , /*72-79*/
    12   ,7    ,3    ,0    ,-3   ,-4   ,-4   ,-4   , /*80-87*/
    -3   ,-2   ,-1   ,0    , /*88-91*/
    /* --------------wave2 0.4----------------------*/
    -2   ,-4   ,-5   ,-5   ,-4   ,-2   ,3    ,9    , /*0-7*/
    17   ,26   ,34   ,42   ,49   ,53   ,55   ,54   , /*8-15*/
    51   ,45   ,37   ,27   ,16   ,5    ,-7   ,-18  , /*16-23*/
    -29  ,-39  ,-47  ,-53  ,-56  ,-56  ,-54  ,-49  , /*24-31*/
    -42  ,-34  ,-25  ,-16  ,-8   ,-2   ,2    ,3    , /*32-39*/
    1    ,-2   ,-7   ,-13  ,-19  ,-24  ,-29  ,-33  , /*40-47*/
    -35  ,-36  ,-37  ,-36  ,-35  ,-34  ,-32  ,-29  , /*48-55*/
    -26  ,-22  ,-18  ,-13  ,-7   ,-2   ,4    ,9    , /*56-63*/
    14   ,18   ,22   ,24   ,26   ,27   ,27   ,27   , /*64-71*/
    26   ,25   ,23   ,21   ,19   ,16   ,13   ,9    , /*72-79*/
    6    ,4    ,1    ,0    ,-2   ,-2   ,-3   ,-2   , /*80-87*/
    -2   ,-1   ,0    , /*88-90*/
};

#define WAVE3LEN1  81
#define WAVE3LEN2  79
const signed char RAMPLAY_wave3_data[ARR3LEN] = {
    REG_RAM_DATA,
    /* --------------wave3 0.7----------------------*/
    1    ,1    ,0    ,-3   ,-7   ,-9   ,-10  ,-7   , /*0-7*/
    1    ,14   ,30   ,48   ,66   ,81   ,90   ,92   , /*8-15*/
    84   ,67   ,43   ,14   ,-17  ,-46  ,-70  ,-86  , /*16-23*/
    -93  ,-91  ,-82  ,-66  ,-48  ,-29  ,-12  ,0    , /*24-31*/
    8    ,11   ,10   ,6    ,0    ,-6   ,-11  ,-15  , /*32-39*/
    -18  ,-20  ,-21  ,-23  ,-25  ,-27  ,-30  ,-32  , /*40-47*/
    -34  ,-34  ,-33  ,-31  ,-26  ,-21  ,-15  ,-10  , /*48-55*/
    -4   ,0    ,4    ,7    ,10   ,12   ,14   ,17   , /*56-63*/
    19   ,22   ,24   ,25   ,26   ,25   ,23   ,21   , /*64-71*/
    17   ,14   ,10   ,7    ,4    ,2    ,1    ,0    , /*72-79*/
    0    , /*80-80*/
    /* --------------wave3 0.4----------------------*/
    1    ,0    ,-2   ,-4   ,-6   ,-6   ,-4   ,0    , /*0-7*/
    8    ,17   ,27   ,38   ,46   ,51   ,52   ,48   , /*8-15*/
    38   ,24   ,8    ,-10  ,-26  ,-40  ,-49  ,-53  , /*16-23*/
    -52  ,-47  ,-38  ,-28  ,-17  ,-7   ,0    ,4    , /*24-31*/
    6    ,5    ,3    ,0    ,-3   ,-6   ,-9   ,-10  , /*32-39*/
    -11  ,-12  ,-13  ,-14  ,-16  ,-17  ,-19  ,-20  , /*40-47*/
    -20  ,-19  ,-18  ,-15  ,-12  ,-9   ,-6   ,-3   , /*48-55*/
    0    ,2    ,4    ,5    ,7    ,8    ,9    ,11   , /*56-63*/
    12   ,13   ,14   ,14   ,14   ,13   ,12   ,10   , /*64-71*/
    8    ,6    ,4    ,2    ,1    ,0    ,0    , /*72-78*/
};

uint8_t list_data[] = {REG_RAM_DATA,1,0,1,0,0,0,0,0};

const signed char RAMPLAY_wavetable[25] =
{
    REG_RAM_DATA,
    0x03,0x00,0x00,WAVE1LEN1,0x03,WAVE1LEN1,0x00,WAVE1LEN2,
    0x04,0x00,0x00,WAVE2LEN1,0x04,WAVE2LEN1,0x00,WAVE2LEN2,
    0x05,0x00,0x00,WAVE3LEN1,0x05,WAVE3LEN1,0x00,WAVE3LEN2,
};



//延时等待部分
void I2C_counter_run(void)
{
    I2C_counter++;
}
uint8_t waitflag;
static uint8_t waitforflag(uint8_t timeout)
{
    I2C_counter = 0;
    waitflag = 0;
    while (I2C_counter < timeout)
    {

        if (SERCOM1_I2C_IsBusy() == false)
        {
            return ERR_OK;
        }
        
    }
    SEGGER_RTT_printf(0,"waitflag = %d \n",waitflag);
    return ERR_TIMEOUT;
}

void delayms(uint8_t time)
{
    I2C_counter = 0;
    while (I2C_counter < time)
    {
        ;
    }
}


//底层I2C部分
uint8_t RT905_WriteReg(uint8_t reg,uint8_t data)
{
    uint8_t ret = 0;
    I2Ctx[0] = reg;
    I2Ctx[1] = data;
    I2C_state = I2C_WRITE;
    ret = SERCOM1_I2C_Write(RT905ADDR,I2Ctx,2);
    if (ret)
    {
        return ERR_OK;
    }
    else
    {
        return ERR_I2CERR;
    }
} 
uint8_t RT905_ReadReg(uint8_t reg)
{
    uint8_t ret = 0;
    I2Ctx[0] = reg;
    I2C_state = I2C_READ;
    ret = SERCOM1_I2C_WriteRead(RT905ADDR,I2Ctx,1,I2Crx,1);
    if (ret)
    {
        return ERR_OK;
    }
    else
    {
        return ERR_I2CERR;
    }
}

uint8_t RT903_WriteReg_block(uint8_t reg,uint8_t data)
{
    uint8_t ret = 0;
    if (SERCOM1_I2C_IsBusy())
    {
        return ERR_BUSY;
    }
    
    ret = RT905_WriteReg(reg,data);
    if (ret == ERR_OK)
    {
        ret = waitforflag(3);//wait for 3ms
    }
    if (ret != ERR_OK)
    {
        SEGGER_RTT_printf(0,"WriteReg_ERR:ret = %d , reg = %02X\n",ret,reg);
    }
    return ret;
} 
uint8_t RT903_ReadReg_block(uint8_t reg,uint8_t *data)
{
    uint8_t ret = 0;
    ret = RT905_ReadReg(reg);
    if (ret == ERR_OK)
    {
        ret = waitforflag(3);//wait for 5ms
        if (ret == ERR_OK)
        {
            *data = I2Crx[0];
        }
    }
    if (ret != ERR_OK)
    {
        SEGGER_RTT_printf(0,"ReadReg_ERR:ret = %d , reg = %02X\n",ret,reg);
    }
    
    return ret;
}


//设置播放波形，设置完之后调用RT903_PlayWave播放波形
uint8_t RT903_SetWaveNo(uint8_t id)
{
    if (id > 5)
    {
        return 0xff;
    }
    RT903_WriteReg_block(REG_RAM_CFG,0x02);//clear playlist
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x00);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x02);
    list_data[4] = id;
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)list_data,5);
    return waitforflag(5);
}
//播放波形
uint8_t RT903_PlayWave(void)
{
    return RT903_WriteReg_block(REG_PLAY_CTRL,PLAY_CTRL_GO);
}

//
static uint8_t rt903x_efuse_read(uint8_t index, uint8_t *data)
{
    uint8_t ret=ERR_OK;
    uint8_t reg_val;
    reg_val = index;
    ret = RT903_WriteReg_block(REG_EFS_ADDR_INDEX, reg_val);
    if (ret != ERR_OK)return ret;
    reg_val = BIT_EFS_READ;
    ret = RT903_WriteReg_block(REG_EFS_MODE_CTRL, reg_val);
    if (ret != ERR_OK)return ret;
    delayms(2);
    ret = RT903_ReadReg_block(REG_EFS_MODE_CTRL, &reg_val);
    if (ret != ERR_OK)return ret;
    if ((reg_val & BIT_EFS_READ) == 0)
    {
        ret = RT903_ReadReg_block(REG_EFS_RD_DATA, &reg_val);
        *data = (uint8_t)reg_val;
        SEGGER_RTT_printf(0,"%d.ret = %d , data = %d\n",index,ret,reg_val);
    }
    return ret;
}

//初始化
//uint32_t efs_data_debug=0;
uint16_t test1=0,test2=0;
uint8_t RT903_Init(void)
{
    uint8_t ret=ERR_OK;
    uint8_t reg_val;
    

    if(waitforflag(5) != ERR_OK)
    {
        return ERR_BUSY;
    }
    ret = RT903_WriteReg_block(REG_SOFT_RESET,0x01);//soft reset
    delayms(2);
    
    ret = RT903_ReadReg_block(REG_DEV_ID, &reg_val);
    SEGGER_RTT_printf(0,"ret = %d , REG_DEV_ID = %02X\n",ret,reg_val);
    delayms(1);
    ret = RT903_ReadReg_block(REG_REV_ID, &reg_val);
    SEGGER_RTT_printf(0,"ret = %d , REG_REV_ID = %02X\n",ret,reg_val);
    delayms(2);
    SEGGER_RTT_printf(0,"start read efuse:\n");
    uint32_t efs_data=0;
    uint8_t trim_val, *efs_data_p;
    //read out trim data from efuse
    efs_data_p = (uint8_t*)&efs_data;
    for(int32_t i = 0; i < 4; ++i)
    {
        ret = rt903x_efuse_read(i, efs_data_p + i);
    }
    SEGGER_RTT_printf(0,"ret = %d\n",ret);
    SEGGER_RTT_printf(0,"efuse:%08X\n",efs_data);
    SEGGER_RTT_printf(0,"start write efuse:\n");
    //apply trim data/
    trim_val = (efs_data & EFS_OSC_LDO_TRIM_MASK) >> EFS_OSC_LDO_TRIM_OFFSET;
    reg_val = trim_val << 6;
    trim_val = (efs_data & EFS_PMU_LDO_TRIM_MASK) >> EFS_PMU_LDO_TRIM_OFFSET;
    reg_val |= (trim_val << 4);
    ret = RT903_WriteReg_block(REG_PMU_CFG3, reg_val);
    if (ret != ERR_OK)return ret;

    
    trim_val = (efs_data & EFS_BIAS_1P2V_TRIM_MASK) >> EFS_BIAS_1P2V_TRIM_OFFSET;
    reg_val = trim_val << 4;
    trim_val = (efs_data & EFS_BIAS_I_TRIM_MASK) >> EFS_BIAS_I_TRIM_OFFSET;
    reg_val |= trim_val;
    ret = RT903_WriteReg_block(REG_PMU_CFG4, reg_val);
    if (ret != ERR_OK)return ret;

    trim_val = (efs_data & EFS_OSC_TRIM_MASK) >> EFS_OSC_TRIM_OFFSET;
    trim_val ^= 0x80;
    reg_val = trim_val;
    ret = RT903_WriteReg_block(REG_OSC_CFG1, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x0F;
    ret = RT903_WriteReg_block(0x2A, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x00;
    ret = RT903_WriteReg_block(REG_BEMF_CFG1, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x01;
    ret = RT903_WriteReg_block(REG_BEMF_CFG2, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x01;
    ret = RT903_WriteReg_block(REG_BOOST_CFG1, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x05;
    ret = RT903_WriteReg_block(REG_BOOST_CFG2, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x0A;
    ret = RT903_WriteReg_block(REG_BOOST_CFG3, reg_val);//8.5v
    if (ret != ERR_OK)return ret;

    reg_val = 0x50;
    ret = RT903_WriteReg_block(REG_BOOST_CFG4, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x1C;
    ret = RT903_WriteReg_block(REG_BOOST_CFG5, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x2C;
    ret = RT903_WriteReg_block(REG_PA_CFG1, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x03;
    ret = RT903_WriteReg_block(REG_PA_CFG2, reg_val);
    if (ret != ERR_OK)return ret;

    reg_val = 0x1C;
    ret = RT903_WriteReg_block(REG_PMU_CFG2, reg_val);
    if (ret != ERR_OK)return ret;

    ret = RT903_WriteReg_block(REG_GAIN_CFG, 0X7f); 
    if (ret != ERR_OK)return ret;

    ret=RT903_WriteReg_block(REG_PLAY_MODE,BIT_PLAY_MODE_RAM);//
    ret=RT903_WriteReg_block(REG_RAM_CFG,0x08);//Init SRAM
    SEGGER_RTT_printf(0,"success\n");
    return ret;
}


//写入波形，先调用RT903_Init，之后调用此函数写入波形数据
uint8_t RT903_WriteWave(void)
{
    uint8_t ret = 0;
    if(waitforflag(5) != ERR_OK)
    {
        return ERR_BUSY;
    }
    //write play list
    RT903_WriteReg_block(REG_RAM_CFG,0x06);//clear waveform and playlist
    delayms(2);
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x00);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x02);
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)list_data,5);
    ret = waitforflag(5); 
    if(ret != ERR_OK)
    {
        return ERR_TIMEOUT;
    }
    //write wave

    SEGGER_RTT_printf(0,"4\n");
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x20);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x02);
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)RAMPLAY_wavetable,sizeof(RAMPLAY_wavetable));
    ret = waitforflag(25);
    if(ret != ERR_OK)
    {
        return ERR_TIMEOUT;
    }
    SEGGER_RTT_printf(0,"%d write wave1\n",I2C_counter);
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x00);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x03);
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)RAMPLAY_wave1_data,sizeof(RAMPLAY_wave1_data));
    ret = waitforflag(25);
    if(ret != ERR_OK)
    {
        return ERR_TIMEOUT;
    }

    SEGGER_RTT_printf(0,"%d write wave2\n",I2C_counter);
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x00);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x04);
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)RAMPLAY_wave2_data,sizeof(RAMPLAY_wave2_data));
    ret = waitforflag(25);
    if(ret != ERR_OK)
    {
        return ERR_TIMEOUT;
    }

    SEGGER_RTT_printf(0,"%d write wave3\n",I2C_counter);
    RT903_WriteReg_block(REG_RAM_ADDR_L,0x00);
    RT903_WriteReg_block(REG_RAM_ADDR_H,0x05);
    SERCOM1_I2C_Write(RT905ADDR,(uint8_t *)RAMPLAY_wave3_data,sizeof(RAMPLAY_wave3_data));
    ret = waitforflag(25);
    if(ret != ERR_OK)
    {
        return ERR_TIMEOUT;
    }
    SEGGER_RTT_printf(0,"%d success\n",I2C_counter);
    return ret;
}






