#include   "forceSnsr.h"
#include   "forceSnsr_Cfg.h"
#include   <string.h>
#include "RTT/SEGGER_RTT.h"
#include "RTT/SEGGER_RTT_Conf.h"


/***************************************************************
copyright from private LiuXiao
if you have any question,you can contact me by email 461445092@qq.com
2022-10-05 17:56:24.020233
***************************************************************/


/***************************************************************/

extern forcesnsr_RxReg_un_type forcesnsr_reg_state_un_bak;
extern forcesnsr_RxReg_un_type forcesnsr_reg_state_un;


forcesnsrMain_State_e forcesnsr_mainctrl_status[forcesnsrMax_CH ];
forcesnsrMain_State_e forcesnsr_lastmainctrl_status[forcesnsrMax_CH ];
STATE_UINT8         forcesnsr_data_tbl[32];
STATE_UINT8         forcesnsr_i2c_process_state_u8;
forcesnsr_RxReg_un_type forcesnsr_reg_state_grp;

 uint8_t force_button_state_u8 = 0;

/***************************************************************/


/***************************static function statement begin************************************/
static void forcesnsr_I2c_End_Callback(uintptr_t contextHandle);
static STATE_UINT8 forcesnsr_I2c_send(STATE_UINT8 regid,STATE_UINT8 len,STATE_UINT8 * data);
static STATE_UINT8 forcesnsr_I2c_recive(STATE_UINT8 regid,STATE_UINT8 len,STATE_UINT8 * data);
static void forcesnsr_I2c_init(void);
static STATE_UINT8 forcesnsr_id_I2c_send(STATE_UINT8 index);
static STATE_UINT8 forcesnsr_id_I2c_recive(STATE_UINT8 index);
static 	STATE_UINT8  Get_Reg_Ckc_is_Ok(void);


static forcesnsrMain_State_e forcesnsr_handle_entry_init(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_during_init(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_exit_init(STATE_UINT8 channel);


static forcesnsrMain_State_e forcesnsr_handle_entry_state1(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_during_state1(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_exit_state1(STATE_UINT8 channel);


static forcesnsrMain_State_e forcesnsr_handle_entry_state2(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_during_state2(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_exit_state2(STATE_UINT8 channel);


static forcesnsrMain_State_e forcesnsr_handle_entry_state3(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_during_state3(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_exit_state3(STATE_UINT8 channel);


static forcesnsrMain_State_e forcesnsr_handle_entry_state4(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_during_state4(STATE_UINT8 channel);
static forcesnsrMain_State_e forcesnsr_handle_exit_state4(STATE_UINT8 channel);


/***************************static function statement end  ************************************/




/***************************table begin************************************/
const forcesnsrState_Handle_Ptr forcesnsr_handle_func_tbl[5][3] = 
{
    {(forcesnsrState_Handle_Ptr) forcesnsr_handle_entry_init,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_during_init,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_exit_init},
    
    {(forcesnsrState_Handle_Ptr) forcesnsr_handle_entry_state1,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_during_state1,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_exit_state1},
    
    {(forcesnsrState_Handle_Ptr) forcesnsr_handle_entry_state2,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_during_state2,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_exit_state2},
    
    {(forcesnsrState_Handle_Ptr) forcesnsr_handle_entry_state3,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_during_state3,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_exit_state3},
    
    {(forcesnsrState_Handle_Ptr) forcesnsr_handle_entry_state4,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_during_state4,
    (forcesnsrState_Handle_Ptr) forcesnsr_handle_exit_state4}
};

/***************************table end  ************************************/




/***************************static function define begin************************************/



/***************************init_entry***********************************/
static forcesnsrMain_State_e forcesnsr_handle_entry_init(STATE_UINT8 channel)
{
/*please fill your code*/
    return init_STATE_E_0;
}


/***************************init_during***********************************/
static forcesnsrMain_State_e forcesnsr_handle_during_init(STATE_UINT8 channel)
{
/*please fill your code*/
	STATE_UINT8 ret = FALSE;
    
	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_NOT_PROCESS)
	{
		ret = forcesnsr_id_I2c_send(forcesnsr_REG_ID_MAIN_CFG_INDEX);
		if(ret == TRUE)
		{
			forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESSING;
		}
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_FAIL)
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_SUCESS)
	{
		return state1_STATE_E_1;
	}
	
    return init_STATE_E_0;
}


/***************************init_exit***********************************/
static forcesnsrMain_State_e forcesnsr_handle_exit_init(STATE_UINT8 channel)
{
/*please fill your code*/
	forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
    return init_STATE_E_0;
}


/***************************state1_entry***********************************/
static forcesnsrMain_State_e forcesnsr_handle_entry_state1(STATE_UINT8 channel)
{
/*please fill your code*/

    return init_STATE_E_0;
}


/***************************state1_during***********************************/
static forcesnsrMain_State_e forcesnsr_handle_during_state1(STATE_UINT8 channel)
{
/*please fill your code*/
	STATE_UINT8 ret = FALSE;

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_NOT_PROCESS)
	{
		ret = forcesnsr_id_I2c_send(forcesnsr_REG_ID_CAL_BASELINE_INT_CFG_INDEX);
		if(ret == TRUE)
		{
			forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESSING;
		}
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_FAIL)
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_SUCESS)
	{
		return state2_STATE_E_2;
	}

    return state1_STATE_E_1;
}


/***************************state1_exit***********************************/
static forcesnsrMain_State_e forcesnsr_handle_exit_state1(STATE_UINT8 channel)
{
/*please fill your code*/
	forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
    return init_STATE_E_0;
}


/***************************state2_entry***********************************/
static forcesnsrMain_State_e forcesnsr_handle_entry_state2(STATE_UINT8 channel)
{
/*please fill your code*/
    return init_STATE_E_0;
}


/***************************state2_during***********************************/
static forcesnsrMain_State_e forcesnsr_handle_during_state2(STATE_UINT8 channel)
{
/*please fill your code*/
	STATE_UINT8 ret = FALSE;
	
	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_NOT_PROCESS)
	{
		ret = forcesnsr_id_I2c_send(forcesnsr_REG_ID_FALLING_CFG_INDEX);
		if(ret == TRUE)
		{
			forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESSING;
		}
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_FAIL)
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_SUCESS)
	{		
		return state3_STATE_E_3;
	}

    return state2_STATE_E_2;
}


/***************************state2_exit***********************************/
static forcesnsrMain_State_e forcesnsr_handle_exit_state2(STATE_UINT8 channel)
{
/*please fill your code*/
	forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
    return init_STATE_E_0;
}


/***************************state3_entry***********************************/
static forcesnsrMain_State_e forcesnsr_handle_entry_state3(STATE_UINT8 channel)
{
/*please fill your code*/
    return init_STATE_E_0;
}


/***************************state3_during***********************************/
static forcesnsrMain_State_e forcesnsr_handle_during_state3(STATE_UINT8 channel)
{
/*please fill your code*/
	STATE_UINT8 ret = FALSE;

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_NOT_PROCESS)
	{
		ret = forcesnsr_id_I2c_recive(forcesnsr_REG_ID_AD_TEMP_INDEX);
		if(ret == TRUE)
		{
			forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESSING;
		}
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_FAIL)
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_SUCESS)
	{
		memcpy(&forcesnsr_reg_state_un_bak,&forcesnsr_reg_state_un,sizeof(forcesnsr_reg_state_un_bak));
		return state4_STATE_E_4;
	}
    return state3_STATE_E_3;
}


/***************************state3_exit***********************************/
static forcesnsrMain_State_e forcesnsr_handle_exit_state3(STATE_UINT8 channel)
{
/*please fill your code*/
	forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
    return init_STATE_E_0;
}


/***************************state4_entry***********************************/
static forcesnsrMain_State_e forcesnsr_handle_entry_state4(STATE_UINT8 channel)
{
/*please fill your code*/
    return init_STATE_E_0;
}


/***************************state4_during***********************************/
static forcesnsrMain_State_e forcesnsr_handle_during_state4(STATE_UINT8 channel)
{
/*please fill your code*/
	STATE_UINT8 ret = FALSE;

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_NOT_PROCESS)
	{
		ret = forcesnsr_id_I2c_recive(forcesnsr_REG_ID_BASELINE_INDEX);
		if(ret == TRUE)
		{
			forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESSING;
		}
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_FAIL)
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;
	}

	if(forcesnsr_i2c_process_state_u8 == forcesnsr_CALLBACK_PROCESS_SUCESS)
	{
		memcpy(&forcesnsr_reg_state_un_bak,&forcesnsr_reg_state_un,sizeof(forcesnsr_reg_state_un_bak));
		if(TRUE == Get_Reg_Ckc_is_Ok())
		{
			return state3_STATE_E_3;
		}
		else
		{
			return init_STATE_E_0;
		}
	}
	
    return state4_STATE_E_4;
}


/***************************state4_exit***********************************/
static forcesnsrMain_State_e forcesnsr_handle_exit_state4(STATE_UINT8 channel)
{
/*please fill your code*/

    return init_STATE_E_0;
}




/***************************static function define end  ************************************/




/***************************init function define begin************************************/
void  forcesnsr_Init(void)
{
    STATE_UINT32 fl_index_u32 = 0;  

    for(fl_index_u32 = 0 ; fl_index_u32 < forcesnsrMax_CH ; fl_index_u32++)
    {
        forcesnsr_mainctrl_status[fl_index_u32]=init_STATE_E_0;
        forcesnsr_lastmainctrl_status[fl_index_u32]=init_STATE_E_0;
    }

	forcesnsr_I2c_init();
}
/***************************init function define end  ************************************/




/***************************main function define begin************************************/
void  forcesnsr_MainTask(void)
{
    STATE_UINT32 fl_index_u32 = 0;  

    for(fl_index_u32 = 0 ; fl_index_u32 < forcesnsrMax_CH ; fl_index_u32++)
    {

        if(forcesnsr_mainctrl_status[fl_index_u32] <= state4_STATE_E_4)
        {
            forcesnsr_mainctrl_status[fl_index_u32]=forcesnsr_handle_func_tbl[forcesnsr_mainctrl_status[fl_index_u32]][1](fl_index_u32);
        }
        else
        {
            forcesnsr_mainctrl_status[fl_index_u32]=init_STATE_E_0;
        }
    

        if(forcesnsr_mainctrl_status[fl_index_u32] <= state4_STATE_E_4)
        {
            if(forcesnsr_lastmainctrl_status[fl_index_u32] != forcesnsr_mainctrl_status[fl_index_u32])
            {
                (void)forcesnsr_handle_func_tbl[forcesnsr_lastmainctrl_status[fl_index_u32]][2](fl_index_u32);
            }
        }
        else
        {
            forcesnsr_mainctrl_status[fl_index_u32]=init_STATE_E_0;
        }
    

        if(forcesnsr_mainctrl_status[fl_index_u32] <= state4_STATE_E_4)
        {
            if(forcesnsr_lastmainctrl_status[fl_index_u32] != forcesnsr_mainctrl_status[fl_index_u32])
            {
                (void)forcesnsr_handle_func_tbl[forcesnsr_mainctrl_status[fl_index_u32]][0](fl_index_u32);
            }
        }
        else
        {
            forcesnsr_mainctrl_status[fl_index_u32]=init_STATE_E_0;
        }
        forcesnsr_lastmainctrl_status[fl_index_u32]=forcesnsr_mainctrl_status[fl_index_u32];
    }
    

}
/***************************main function define end  ************************************/


/*
i2c initial 
*/

static void forcesnsr_I2c_init(void)
{
	PORT_PinPeripheralFunctionConfig(PORT_PIN_PA00,PERIPHERAL_FUNCTION_D);
	PORT_PinPeripheralFunctionConfig(PORT_PIN_PA01,PERIPHERAL_FUNCTION_D);
	
	forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_NOT_PROCESS;

	SERCOM1_I2C_Initialize();
	SERCOM1_I2C_CallbackRegister(forcesnsr_I2c_End_Callback,0);
    SEGGER_RTT_printf(0,"forcesnsr_I2c_init\n");
}


/*
i2c rx or tx process sucess callback
*/
extern uint8_t waitflag;
static void forcesnsr_I2c_End_Callback(uintptr_t contextHandle)
{
	if(SERCOM_I2C_ERROR_NONE == SERCOM1_I2C_ErrorGet())
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESS_SUCESS;
	}
	else if((SERCOM1_I2C_send_done())  && (SERCOM_I2C_ERROR_NAK == SERCOM1_I2C_ErrorGet()))
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESS_SUCESS;
	}
	else if((SERCOM1_I2C_rx_done())  && (SERCOM_I2C_ERROR_NAK == SERCOM1_I2C_ErrorGet()))
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESS_SUCESS;
	}
	else
	{
		forcesnsr_i2c_process_state_u8 = forcesnsr_CALLBACK_PROCESS_FAIL;
	}


	//SERCOM1_I2C_Initialize();
}


/*
i2c tx process ,ansync process
*/
static STATE_UINT8 forcesnsr_I2c_send(STATE_UINT8 regid,STATE_UINT8 len,STATE_UINT8 * data)
{
	STATE_UINT8 index = 0;
	STATE_UINT8 num = 0;
	STATE_UINT8 ret = 0;

	if(len > sizeof(forcesnsr_data_tbl))
	{
		return FALSE;
	}
	
	forcesnsr_data_tbl[index++] = 	regid;

	if(len < ((sizeof(forcesnsr_data_tbl))/(sizeof(forcesnsr_data_tbl[0])) - 3))
	{
		for(num = 0 ; num < len ; num ++)
		{
			forcesnsr_data_tbl[index++] = data[num];
		}

		/*i2c send interface*/
		ret = SERCOM1_I2C_Write(forcesnsr_BIT7_ADDR,forcesnsr_data_tbl,index);
	}

	return ret;
}

static STATE_UINT8 forcesnsr_id_I2c_send(STATE_UINT8 index)
{
	STATE_UINT8 ret = FALSE;
    
	ret = forcesnsr_I2c_send(forcesnsr_Main_Cfg_Tbl[index].cmd_id,\
		forcesnsr_Main_Cfg_Tbl[index].cmd_len,\
		(STATE_UINT8 *)forcesnsr_Main_Cfg_Tbl[index].default_state);

	return ret;
}


/*
i2c rx process ,ansync process
*/
static STATE_UINT8 forcesnsr_I2c_recive(STATE_UINT8 regid,STATE_UINT8 len,STATE_UINT8 * data)
{
	STATE_UINT8 ret = FALSE;
	forcesnsr_data_tbl[0] = regid;

	if((len + regid <= forcesnsr_Max_reg_num) && (data != 0))
	{
		/*i2c send and recive interface*/
		ret = SERCOM1_I2C_WriteRead(forcesnsr_BIT7_ADDR,forcesnsr_data_tbl,1,data,len);
	}
	
	return ret;
}

static STATE_UINT8 forcesnsr_id_I2c_recive(STATE_UINT8 index)
{
	STATE_UINT8 ret = FALSE;
    
	ret = forcesnsr_I2c_recive(forcesnsr_Main_Cfg_Tbl[index].cmd_id,\
		forcesnsr_Main_Cfg_Tbl[index].cmd_len,\
		(STATE_UINT8 *)forcesnsr_Main_Cfg_Tbl[index].cmd_data);

	return ret;
}

/*
return: ture is button pressed
*/
STATE_UINT8  Get_force_btn_is_press_state(void)
{
	if(FALSE == PORT_PinRead(PORT_PIN_PB31))
	{
		force_button_state_u8 = TRUE;
	}
	else
	{
		force_button_state_u8 = FALSE;
	}

	return force_button_state_u8;
}

/*
compare key register value
return true is force sensor chip register value match with expect
*/
STATE_UINT8  Get_Reg_Ckc_is_Ok(void)
{
	STATE_UINT8 ret = TRUE;
	
	if(forcesnsr_reg_state_un_bak.reg_grp[0] != forcesnsr_Main_Cfg_Tbl[0].default_state[0])
	{
		ret = FALSE;
	}
	if(forcesnsr_reg_state_un_bak.reg_grp[1] != forcesnsr_Main_Cfg_Tbl[0].default_state[1])
	{
		ret = FALSE;
	}
	if(forcesnsr_reg_state_un_bak.reg_grp[0xE] != forcesnsr_Main_Cfg_Tbl[1].default_state[7])
	{
		ret = FALSE;
	}
	if(forcesnsr_reg_state_un_bak.reg_grp[0x09] != forcesnsr_Main_Cfg_Tbl[1].default_state[2])
	{
		ret = FALSE;
	}
	if(forcesnsr_reg_state_un_bak.reg_grp[0x0A] != forcesnsr_Main_Cfg_Tbl[1].default_state[3])
	{
		ret = FALSE;
	}
	if(forcesnsr_reg_state_un_bak.reg_grp[0x0B] != forcesnsr_Main_Cfg_Tbl[1].default_state[4])
	{
		ret = FALSE;
	}
	return ret;
}



