#include "bsp.h"



void bsp_flash_init(void)
{
/**********************************Flash配置初始化*************************************/
	FREQ_CLK = 0x10;				  //指明当前系统时钟	
	/***********************************LVD配置初始化**************************************/
//	LVDC = 0xAA;						  //LVD设置3.0V,禁止中断
//	//	消抖时间 = 	(0xFF + 2) * 1/Fcpu
//	//			 =	(0xFF + 2) / 16000000	（当前的CPU时钟）
//	//			 =	16.0625us
//	LVDDBC = 0xFF;					  //设置消抖时间
//	LVDC &=~ 0x08;			      //清除LVD中断标志位 
}
/*	************************************************************************************
*									 模块性能介绍
*	1、Flash擦写次数10万次以上
*	2、扇区擦除时间约5ms，且擦除时不响应任何中断，但会置相关标志位，擦除完成后响应
*	3、可设置应用程序读保护，应用程序写保护（以4K字节为保护单位）
*	4、可以设置仿真器扇区读保护，扇区写保护（以4K字节为保护单位）
*	5、设置保护后无法擦写程序，读取的数据全为零
* 6、每一颗MCU在出厂时会固化一个CHIP_ID，一共8个字节，一颗芯片一个ID，不会重复
*	************************************************************************************/
/**
  * @说明  	扇区擦除，，约消耗5ms的时间，
  *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  * @参数  	fui_Address ：被擦除的扇区内的任意一个地址
  * @返回值 无
  * @注		  只要操作扇区里面的任意一个地址，就可以擦除此扇区
  */
void Flash_EraseBlock(unsigned int fui_Address)
{
//	while(1)
//	{
//		LVDC &=~ 0x08;			  //清除LVD中断标志位
//		if((LVDC&0x08)==0)		break;
//	}
	EA=0;
	IAP_CMD = 0xF00F;				//Flash解锁
	IAP_ADDR = fui_Address;	//写入擦除地址
	IAP_CMD = 0xD22D;				//选择操作方式， 扇区擦除
	IAP_CMD = 0xE11E; 			//触发后IAP_ADDRL&IAP_ADDRH指向0xFF，同时自动锁定
	EA=1;
}

/**
  * @说明  	写入一个字节数据到Flash里面
  *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  * @参数  	fui_Address ：FLASH地址
  *	@参数	  fucp_SaveData：写入的数据
  * @返回值 无
  * @注		  写之前必须先对操作的扇区进行擦除
  */
void FLASH_WriteData(unsigned char fuc_SaveData, unsigned int fui_Address)
{
//	while(1)
//	{
//		LVDC &=~ 0x08;			   //清除LVD中断标志位
//		if((LVDC&0x08)==0)		break;
//	}
	EA=0;
	IAP_DATA = fuc_SaveData;
	IAP_CMD=0xF00F;				   //Flash解锁
	IAP_ADDR = fui_Address;
	IAP_CMD=0xB44B;				   //字节编程
	IAP_CMD=0xE11E;				   //触发一次操作
	EA=1;
}

/**
  * @说明  	写入任意长度的数据到FLASH里面
  *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  * @参数  	fui_Address ：FLASH起始地址
  *	@参数	  fuc_Length ： 写入数据长度
  *			    取值范围：0x00-0xFF
  *	@参数  *fucp_SaveArr：写入的数据存放区域的首地址
  * @返回值 无
  * @注		  写之前必须先对操作的扇区进行擦除
  */
void Flash_WriteArr(unsigned int fui_Address,unsigned int fuc_Length,unsigned char *fucp_SaveArr)
{
	unsigned char fui_i = 0;
	EA=0;
	for(fui_i=0;fui_i<fuc_Length;fui_i++)
	{
		FLASH_WriteData(*(fucp_SaveArr++), fui_Address++); 
	}
	EA=1;
}


/**
  * @说明  	写入任意长度的数据到FLASH里面
  *         该函数需绝对地址编译，详情请查阅IAP操作应用手册
  * @参数  	fui_Address ：FLASH起始地址
  *	@参数	  fuc_Length ： 写入数据长度
  *			    取值范围：0x00-0xFF
  *	@参数  *fucp_SaveArr：写入的数据存放区域的首地址
  * @返回值 无
  * @注		  写之前必须先对操作的扇区进行擦除
  */
//void Flash_WriteWord(unsigned int fui_Address,unsigned char fuc_Length,unsigned int *fucp_SaveArr) //地址为偶数
//{
//	unsigned char fui_i = 0;
//	unsigned int  word;
//	EA=0;
//	for(fui_i=0;fui_i<fuc_Length;fui_i++)
//	{
//		word=*(fucp_SaveArr++);
//		FLASH_WriteData((word/256), fui_Address++); 
//		FLASH_WriteData((word%256), fui_Address++); 
//	}
//	EA=1;
//}
/**
  * @说明  	从FLASH里面读取任意长度的数据
  * @参数  	fui_Address ：FLASH起始地址
  *	@参数	  fuc_Length ：读取数据长度
  *			    取值范围：0x00-0xFFFF
  *	@参数	 *fucp_SaveArr：读取数据存放的区域首地址
  * @返回值 无
  * @注		  无
  */
//void Flash_ReadWord(unsigned int fui_Address,unsigned int fuc_Length,unsigned int *fucp_SaveArr) //地址为偶数
//{
//	unsigned char Hi,Lo;
//	while(fuc_Length--)
//	{
//	  Hi=*((unsigned char code *)(fui_Address++));//读取数据
//		Lo=*((unsigned char code *)(fui_Address++));//读取数据
//		*(fucp_SaveArr++)=Hi*256+Lo;
//	}
//}
/**
  * @说明  	从FLASH里面读取任意长度的数据
  * @参数  	fui_Address ：FLASH起始地址
  *	@参数	  fuc_Length ：读取数据长度
  *			    取值范围：0x00-0xFFFF
  *	@参数	 *fucp_SaveArr：读取数据存放的区域首地址
  * @返回值 无
  * @注		  无
  */
void Flash_ReadArr(unsigned int fui_Address,unsigned int fuc_Length,unsigned char *fucp_SaveArr)
{
	while(fuc_Length--)
	*(fucp_SaveArr++)=*((unsigned char code *)(fui_Address++));//读取数据
}

