/**
	******************************************************************************
	* @file
	* @author
	* @version
	* @date
	* @brief
	* @function List:
	******************************************************************************
	* @attention
	*
	*
	* <h2><center>&copy; COPYRIGHT 2021 </center></h2>
	******************************************************************************
	* @History:
	* @Author:
	* @Data:
	* @Version:
*/


//#include "includes.h"
//#include "error.h"
#include "boot_app.h"
#ifdef LIN_ENABLE
#include "lin_app.h"
#endif
#include "nvm.h"
//#include "lin_commontl_api.h"
//#include "lin_slave_diag.h"
#include "common_cfg.h"
#include "can_cfg.h"
#include "ComStack_Types.h"
#include "Dcm_Cfg.h"
#include "CanIf_Cfg.h"


#if 0 //最后的 app valid flag,应该在boot区成功时，要写入，記得debug時，要開啟
	#pragma CONST_SEG MEMORY_MAP_ROM_APP_FLAG_END
	const u8 AppValid[16] = {0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5};  //APP_VALID_FLAG_ADDR
	#pragma CONST_SEG DEFAULT
#else
MEMORY_MAP_FLAG_NO_OPTIME	const u8 AppValid[16]  = {0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5};
#endif


//片区开头的标志
MEMORY_MAP_FLAG_NO_OPTIME volatile const MEMORY_MAP_ROM_APP_VALID u8 AppValid1[16]  = {0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5,0xaa,0xaa,0x04,0xe5};  // APP_VALID_FLAG1_ADDR

MEMORY_MAP_FLAG_NO_OPTIME volatile const MEMORY_MAP_ROM_APP_RES u8 AppValid_in[4]  = {0x12,0x34,0x56,0x78};  //注意，為了校驗地址，範圍，必須開啟，該標志。  // APP_VALID_FLAG_IN_ADDR


u8 boot_app_check_flag_default(void);
void boot_app_response_default_success(void);

//static void Boot_SendEcuResetRespones(void);

//static u8 Boot_IsValidFlag(u8 flagId);
static void Boot_SetFlag(u8 flagId);

//static u8 Boot_MemCpy(u8 * des, const u8 *src, u32 size);

#ifndef RAM_OPTIMIZE_EN
__IO static u32 g_read_valid;
#endif

/* BEGIN_FUNCTION_HDR
************************************************************************************************
* Function Name : Boot_ReprogramCallBack
*
* Description   : Set the reprogramming flag and reset the ECU.
*
* Inputs        : none
*
* Outputs       : none
*
* Limitations   : Only for Bootloader
*
************************************************************************************************
END_FUNCTION_HDR */
void Boot_ReprogramCallBack(u8 flag_res)
{
	/*set reprogram flag*/
	Boot_SetFlag(flag_res);  //FLAG_REPROGRAM_ID
	/*reset ECU*/
	ResetMCUHandle();
}
//专门给lin用的
void Boot_Reprogram_only_writeram(void)
{
	/*set reprogram flag*/
	Boot_SetFlag(FLAG_REPROGRAM_ID);
	/*reset ECU*/
	//ResetMCUHandle();
}
/* BEGIN_FUNCTION_HDR
************************************************************************************************
* Function Name : Boot_ResetMCUCallBack
*
* Description   : Reset the ECU.
*
* Inputs        : none
*
* Outputs       : none
*
* Limitations   : Only for Bootloader
*
************************************************************************************************
END_FUNCTION_HDR */
void Boot_ResetMCUCallBack(void)
{
	/*set reprogram flag*/
	Boot_SetFlag(FLAG_RESET_ID);
	/*reset ECU*/
	ResetMCUHandle();
}

/* BEGIN_FUNCTION_HDR
************************************************************************************************
* Function Name : Boot_SetFlag
*
* Description   : Set the reprogramming flag.
*
* Inputs        : none
*
* Outputs       : none
*
* Limitations   : Only for Bootloader
*
************************************************************************************************
END_FUNCTION_HDR */
static void Boot_SetFlag(u8 flagId)
{
	u32 addr = 0xFFFFFFFFUL;
	//u32  data = 0xFFFFFFFFUL;
	const u8 l_data[FLAG_REPROGRAM_LEN] ={FLAG_REPROGRAM_u8_DATA0,FLAG_REPROGRAM_u8_DATA1,FLAG_REPROGRAM_u8_DATA2,FLAG_REPROGRAM_u8_DATA3};
	const u8 l_data1[FLAG_REPROGRAM_LEN] ={FLAG_REPROGRAM_u8_DATA0+1u,FLAG_REPROGRAM_u8_DATA1+1u,FLAG_REPROGRAM_u8_DATA2+1u,FLAG_REPROGRAM_u8_DATA3+1u};
	u8 l_buf[FLAG_REPROGRAM_LEN];
	switch (flagId)
	{
		case FLAG_REPROGRAM_ID:
			addr = FLAG_REPROGRAM_ADDR;
			//data = FLAG_REPROGRAM_DATA;
			l_buf[0]=l_data[0];
			l_buf[1]=l_data[1];
			l_buf[2]=l_data[2];
			l_buf[3]=l_data[3];
			break;
		case FLAG_RESET_ID:
			addr = FLAG_REPROGRAM_ADDR;
			l_buf[0]=0;
			l_buf[1]=0;
			l_buf[2]=0;
			l_buf[3]=0;
			break;
		case FLAG_REPROGRAM_NORES_ID:  //用于 1001跳到 1002 不用应答
			addr = FLAG_REPROGRAM_ADDR;
			l_buf[0]=l_data1[0];
			l_buf[1]=l_data1[1];
			l_buf[2]=l_data1[2];
			l_buf[3]=l_data1[3];
		break;
		default :
			/*code*/
			break;
	}

	if (addr != 0xFFFFFFFFUL)
	{
		#if 0
		(void)FlagWriteHandle(addr,4,(uc8*)&l_buf);
		#else
		(void)ram_write_bytes(addr,(u8*)&l_buf[0],FLAG_REPROGRAM_LEN);
		#endif
	}
}

#if 0
static u8 Boot_MemCpy(u8 * des, const u8 *src, u32 size)  /*PRQA S 3219*/
{
	u32 i;

	for (i = 0; i < size; i++)
	{
		des[i] = src[i];
	}

	return 0;

}
#endif

/**
* @brief  初始化
* @param  input:
* @param  output:
* @return   none:
* @calls
* @calls by
* @others
*/
void  boot_app_init(void)
{
	#ifdef LIN_ENABLE
	u8 i;  /*PRQA S 3205*/
	u8 l_buf[8];
	u32 tempP2Star;
	#endif
    u32 l_temp;
        
	#if 0
	boot_app_clear_flag();
	(void)in_flash_read_words(&g_boot_flag_info,in_flash_get_boot_log_s_addr() ,IN_FLASH_LOG_LEN_BOOT_WORKS);
	if(g_boot_flag_info == BOOT_APP_FLAG_IS_BOOT_SUCCESS)
	{
		boot_app_jump_to_app();
	}
	#endif
	#ifndef RAM_OPTIMIZE_EN
	g_read_valid = AppValid[0] ;
	#else
	l_temp = AppValid[0] ;
	#endif
	ram_read_bytes(FLAG_JUMP_TO_BOOT_RESPONSE_ADDR,(u8*)&l_temp,FLAG_JUMP_TO_BOOT_RESPONSE_LEN);
	#ifdef LIN_ENABLE
	switch(l_temp)
	{
		case FLAG_JUMP_TO_APP_RESPONSE_11_01:   /*PRQA S 0597*/
			//l_buf[0] = LIN_SALVE_DIAG_NAD;
			l_buf[0] = 0x02;
			l_buf[1] = 0x51;
			l_buf[2] = 0x01;
			//l_buf[4] = 0xff;
			//l_buf[5] = 0xff;
			//l_buf[6] = 0xff;
			//l_buf[7] = 0xff;
			//ld_put_raw(&l_buf[0]);
			ld_send_message((u16)l_buf[0],&l_buf[1]);  //TEMP_CLOSE
		break;
		case FLAG_JUMP_TO_APP_RESPONSE_11_03:   /*PRQA S 0597*/
			//l_buf[0] = LIN_SALVE_DIAG_NAD;
			l_buf[0] = 0x02;
			l_buf[1] = 0x51;
			l_buf[2] = 0x03;
			//l_buf[4] = 0xff;
			//l_buf[5] = 0xff;
			//l_buf[6] = 0xff;
			//l_buf[7] = 0xff;
			//ld_put_raw(&l_buf[0]);
			ld_send_message((u16)l_buf[0],&l_buf[1]);  //TEMP_CLOSE
		break;
		case FLAG_JUMP_TO_APP_RESPONSE_10_02:   /*PRQA S 0597*/
			#if 0
			l_buf[0] = LIN_SALVE_DIAG_NAD;
			for(i=0;i<7;i++)
			{
				l_buf[i+1] = gs_ReprogrammingResponse[i];
			}
			ld_put_raw(LI0,&l_buf[0]);
			#endif
		break;
		case FLAG_JUMP_TO_APP_RESPONSE_10_01:   /*PRQA S 0597*/
			//l_buf[0] = LIN_SALVE_DIAG_NAD;
			l_buf[0] = 0x06;
			l_buf[1] = 0x50;
			l_buf[2] = 0x01;
			l_buf[3] = (u8)(50>>8);
			l_buf[4] = (u8)(50);
			tempP2Star=5000/10;
			l_buf[5] = (u8)(tempP2Star>>8);  /*PRQA S 2984*/
			l_buf[6] = (u8)(tempP2Star);
			//ld_put_raw(&l_buf[0]);
			ld_send_message((u16)l_buf[0],&l_buf[1]);  //TEMP_CLOSE
		break;
		default:
		break;
	}
	#endif
	if(boot_app_check_flag_default()==TRUE)
	{
		//要发送信号，表示成功进入默认会话
		boot_app_response_default_success();
		//boot_app_check_flag_clear_default();
	}
	//flash_drv_ram_read();
	l_temp = FLAG_JUMP_TO_BOOT_RESPONSE_INIT;
	ram_write_bytes(FLAG_JUMP_TO_BOOT_RESPONSE_ADDR,(u8*)&l_temp,FLAG_JUMP_TO_BOOT_RESPONSE_LEN);
}


/**
* @brief
* @param  input:
* @param  output:
* @return   none:
* @calls
* @calls by
* @others
*/
void boot_app_task(void)
{
	#ifndef RAM_OPTIMIZE_EN
	g_read_valid += 1u;
	#endif
}




	/**
 * @brief  初始化
 * @param  input:
 * @param  output:
 * @return   none:
 * @calls
 * @calls by
 * @others
 */
void boot_app_jump_to_app(void)
{

}





u8 boot_app_check_flag_default(void)
{
	u8 i=0; /*PRQA S 2981*/
	u8 l_buf[FLAG_JUMP_TO_BOOT_RESPONSE_LEN];
	const u8 l_buf_init[FLAG_JUMP_TO_BOOT_RESPONSE_LEN]={FLAG_REPROGRAM_u8_DATA0,FLAG_REPROGRAM_u8_DATA1,FLAG_REPROGRAM_u8_DATA2,FLAG_REPROGRAM_u8_DATA3};
	u8 l_result=TRUE;

	(void)ram_read_bytes(FLAG_JUMP_TO_BOOT_RESPONSE_ADDR,(u8*)&l_buf[0],FLAG_JUMP_TO_BOOT_RESPONSE_LEN);

	for(i=0u;i<FLAG_JUMP_TO_BOOT_RESPONSE_LEN;i++)
	{
		if(l_buf[i]!=l_buf_init[i])
		{
			l_result=FALSE;
			break;
		}

	}

	return l_result;
}



void boot_app_response_default_success(void)
{
	PduInfoType l_tx_pdu;
	u8 l_buf[8] ;//={0x06,0x50,0x01,0x00,0x32,0x01,0xf4,0xaa};
	u16 l_temp;

	l_buf[0] = 0x06;
	l_buf[1] = 0x50;
	l_buf[2] = 0x01;
	l_buf[3] = (uint8)(gDcmDspSessionRow[0].DcmDspSessionP2ServerMax>>8);
	l_buf[4]=(uint8)(gDcmDspSessionRow[0].DcmDspSessionP2ServerMax);
	l_temp=(u16)(gDcmDspSessionRow[0].DcmDspSessionP2StarServerMax/10u);
	l_buf[5]=(uint8)(l_temp>>8);
	l_buf[6]=(uint8)(l_temp);
	l_buf[7]=0xaa;
	l_tx_pdu.SduLength =8;
	l_tx_pdu.SduDataPtr =l_buf;
	(void)CanIf_Transmit(ADPT_UDS_TX_HANDLE,&l_tx_pdu);  //注意，1是pduid fot diag
}


#if 0
void boot_app_check_flag_clear_default(void)
{
	const u8 l_buf[FLAG_JUMP_TO_BOOT_RESPONSE_LEN]={0};

	(void)ram_write_bytes(FLAG_JUMP_TO_BOOT_RESPONSE_ADDR,(u8*)&l_buf[0],FLAG_JUMP_TO_BOOT_RESPONSE_LEN);

}
#endif