/********************************************************************************
 * @file    IAP_Program.c
 * @author  SOC AE Team
 * @version V1.1
 * @date    2025-06-27
 * @brief   通过IAP向flash指定地址写入指定数据。
 *
 *******************************************************************************/

#include "sc32_conf.h"
#include "Function_Init.h"

#define FLASH_USER_ADDR  0x801FE00

static volatile uint8_t IAP_Flag = 0;

static boolType CheckSaveData(void)
{
	// 实现数据有效性检查逻辑
	// 假设数据合法返回SET，否则返回0
	return TRUE;  // 示例中假设数据总是合法
}

void IAP_Program_Function(void)
{

  uint32_t ReadWord = 0; 
  uint32_t Array_WriteWord[3]={0x11223344,0x22334455,0x33445566}, Array_ReadWord[3];
  uint8_t Flag_ReadWord = 0, Key_Press = 0, Iap_Enflag = 0, i;
#if defined(SC32f10xx)
	uint16_t ReadHalfWord = 0;
	uint8_t ReadByte = 0;
	uint16_t Array_WriteHalfWord[5]={0x1111,0x2222,0x3333,0x4444,0x5555}, Array_ReadHalfWord[5];
	uint8_t Array_WriteByte[5]={0x99,0x88,0x77,0x66,0x55}, Array_ReadByte[5];
  uint8_t  Flag_ReadHalfWord = 0, Flag_ReadByte = 0;	
#endif	
	GPIO_InitTypeDef GPIOInit_PC01_Struct;
	GPIOInit_PC01_Struct.GPIO_Pin = GPIO_Pin_1;
	GPIOInit_PC01_Struct.GPIO_Mode = GPIO_Mode_IN_PU;
	GPIOInit_PC01_Struct.GPIO_DriveLevel = 0;
	GPIO_Init(GPIOC,&GPIOInit_PC01_Struct);
	
	if(GPIO_ReadDataBit(GPIOC,GPIO_Pin_1) == 0)
	{
		if(Key_Press == 0)
		{
			Key_Press = 1;
			Iap_Enflag = 1;   //按下按键，允许IAP写入，作为解锁的第一个必要条件
		}
	}
	Key_Press = 0;
	
	if(Iap_Enflag == 1)
	{
		IapWriteFlag = IAP_SOFTKEY1;  //允许写入IAP，置第一重安全锁解锁
	}
	if(CheckSaveData() == SET)
	{
		IapWriteFlag |= IAP_SOFTKEY2;  //待写入数据合法性，作为解锁的第二个必要条件，置第二重安全锁解锁
	}
	
	if(Iap_Enflag == 1)
	{
		IAP_Unlock();	//解锁IAP操作

		IAP_EraseSector((FLASH_USER_ADDR - FLASH_BASE) / 512);	//擦除地址所在扇区，每个扇区大小为512Byte
		IAP_WriteCmd(ENABLE);	//开启写使能
		
		/* 单个数据依次写入(注意地址对齐) */
		IAP_ProgramWord(FLASH_USER_ADDR,0x12345678);	//字写入，目标地址FLASH_USER_ADDR
		/* 批量数据写入 */
		//写入地址请勿重合！写入数据请勿超出扇区范围！
		IAP_ProgramWordArray(FLASH_USER_ADDR+20,Array_WriteWord,3);//批量字写入
#if defined(SC32f10xx) 
		/* 单个数据依次写入(注意地址对齐) */
		IAP_ProgramHalfWord(FLASH_USER_ADDR+4,0x6666);  //半字写入，目标地址（FLASH_USER_ADDR+4）
		IAP_ProgramByte(FLASH_USER_ADDR+6,0x99); //字节写入，目标地址（(FLASH_USER_ADDR+4)+2）
		/* 批量数据写入 */
		//写入地址请勿重合！写入数据请勿超出扇区范围！
		IAP_ProgramHalfWordArray(FLASH_USER_ADDR+40,Array_WriteHalfWord,5);//批量半字写入
		IAP_ProgramByteArray(FLASH_USER_ADDR+60,Array_WriteByte,5);//批量字节写入
#endif  

		IAP_Lock();	//上锁IAP操作，并且复位IAP操作寄存器
		
		/* 单个数据依次读取 */
		ReadWord = IAP_ReadWord(FLASH_USER_ADDR); //字读，目标地址（0x803FE00）
		
		/* 批量数据读取 */
		Flag_ReadWord = IAP_ReadWordArray(FLASH_USER_ADDR+20,Array_ReadWord,3);//批量字读，返回值为读取成功数据大小
#if defined(SC32f10xx) 
		/* 单个数据依次读取 */
	 
		ReadHalfWord = IAP_ReadHalfWord(FLASH_USER_ADDR+4); //半字读，目标地址（0x803FE00+4=0x803FE04）
		ReadByte = IAP_ReadByte(FLASH_USER_ADDR+6); //字节读，目标地址（0x803FE04+2=0x803FE06）
		
		/* 批量数据读取 */
		Flag_ReadHalfWord = IAP_ReadHalfWordArray(FLASH_USER_ADDR+40,Array_ReadHalfWord,5);//批量半字读，返回值为读取成功数据大小
		Flag_ReadByte = IAP_ReadByteArray(FLASH_USER_ADDR+60,Array_ReadByte,5);//批量字节读，返回值为读取成功数据大小
#endif   
#if defined(SC32f12xx) 
		if(ReadWord == 0x12345678)//单个数据读写判断
		{
			if(Flag_ReadWord == 3)//批量写入成功个数判断
			{
				IAP_Flag = 1;	
			}
		}
#elif defined(SC32f10xx) 

		if(ReadWord == 0x12345678 && ReadHalfWord == 0x6666 && ReadByte == 0x99)//单个数据读写判断
		{
			if(Flag_ReadWord == 3 && Flag_ReadHalfWord == 5 && Flag_ReadByte == 5)//批量写入成功个数判断
			{
				IAP_Flag = 1;	
			}
		}
	}
#endif
  while(1)
  {
#if defined(SC32f12xx) 
    if(IAP_Flag == 1)
    {
      printf("IAP Program Success !!!\r\n");
      printf("Array_ReadWord = { ");
      for(i=0;i<3;i++)
      {
        printf("%x ", Array_ReadWord[i]);
      }
      printf("}\r\n");
    }
    else
    {
      printf("IAP Program Error !!!\r\n");
    }
#elif defined(SC32f10xx)
		if(IAP_Flag == 1)
		{
		  printf("IAP Program Success !!!\r\n");
			printf("Array_ReadWord = { ");
			for(i=0;i<3;i++)
	    {
				printf("%x ", Array_ReadWord[i]);
			}
			printf("}\r\n");
			printf("Array_ReadHalfWord = { ");
			for(i=0;i<5;i++)
	    {
				printf("%x ", Array_ReadHalfWord[i]);
			}
			printf("}\r\n");
			printf("Array_ReadByte = { ");
			for(i=0;i<5;i++)
	    {
				printf("%x ", Array_ReadByte[i]);
			}
			printf("}\r\n");
		}
	  else
	  {
		  printf("IAP Program Error !!!\r\n");
	  }		
#endif
  }

}
