#include "Flash.h"

/********************************
  * @brief  OTA参数初始化
  * @retval FLASH_COMPLETE初始成功
  ********************************/
uint8_t Flash_RangeErase(uint32_t FlashAddress, uint32_t Size)
{
	uint8_t flag = 1;
	uint32_t msize=0;
	FLASH_Status FlashStatus = FLASH_COMPLETE;
	
	while(Size > msize) {
		FLASH_Unlock();// Unlock the Flash to enable the flash control register access
		FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)
		FlashStatus = FLASH_ErasePage(FlashAddress+msize);
  		FLASH_Lock(); // Lock the Flash to disable the flash control register access

		/* If erase operation was failed, a Flash error code is returned */
		if (FlashStatus != FLASH_COMPLETE) {
			flag = 0;
			break;
		}
		msize += FLASH_PAGE_SIZE;
	}
	
	return flag;
}

#if 1
uint8_t Flash_PageErase(uint8_t _PageNumber)
{
	uint8_t flag = 0;

	if(_PageNumber > 127)
		return 0;

	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)

	if(	FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * _PageNumber)) == FLASH_COMPLETE	)
	{
		flag = 1;
	}
	FLASH_Lock(); // Lock the Flash to disable the flash control register access

	return flag;
}

uint8_t Flash_BufferWrite(uint32_t address, uint32_t *p_buffer, uint32_t len)
{
	uint8_t  flag = 1;
	uint32_t EndAddr = 0;
	//uint32_t *p_buffer = (uint32_t *)buffer;

	if(address%4||len%4) {
		return 0;
	}
	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)

	EndAddr = address + len;

	while (address < EndAddr) {
		if (FLASH_ProgramWord(address, *p_buffer) == FLASH_COMPLETE) {
			p_buffer++;
			address += 4;
		} else {
			flag = 0;// Error occurred while writing data in Flash memory.
		}
	}

	FLASH_Lock(); // Lock the Flash to disable the flash control register access	
	return flag;
}

void Flash_BufferRead(uint32_t address, uint8_t *buffer, uint32_t len)
{
	uint32_t EndAddr = 0;
	uint8_t *p_buffer = (uint8_t *)buffer;

	if(address%4||len%4) {
		return ;
	}
	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)

	EndAddr = address + len;

	while (address < EndAddr) {
		*p_buffer++ = *(__IO uint8_t *)address;
		address += 1;
	}

	FLASH_Lock(); // Lock the Flash to disable the flash control register access		
}

//读取flash中有效数据的长度
uint32_t Flash_DatalenRead(uint32_t address,uint32_t len)
{
	uint32_t BeginAddr = 0;
	uint32_t addrlen = 0;
	uint32_t data;
	if(address%4||len%4) {
		return addrlen;
	}
	
	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)
	
	BeginAddr = address + len - 4;
	while(address < BeginAddr)
	{
		data = *(__IO uint32_t *)BeginAddr;
		if(data != 0xFFFFFFFF)
			break;
		BeginAddr -= 4;
	}
	FLASH_Lock(); // Lock the Flash to disable the flash control register access
	
	if(address <= BeginAddr)
	{
		addrlen = (BeginAddr+4) - address;
	}
	return addrlen;
}
#else

uint8_t Flash_PageErase(uint8_t _PageNumber)
{
	uint8_t flag = 0;

	if(_PageNumber > 127)
		return 0;

	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)

	if(	FLASH_ErasePage(FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE * _PageNumber)) == FLASH_COMPLETE	)
	{
		flag = 1;
	}
	FLASH_Lock(); // Lock the Flash to disable the flash control register access

	return flag;
}

uint8_t Flash_BufferWrite(uint8_t _PageNumber,uint32_t *pBuffer,uint16_t Num)
{
	uint8_t  flag = 1;
	uint32_t Address = 0,EndAddr = 0;

	FLASH_Unlock();// Unlock the Flash to enable the flash control register access
	FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);	// Clear pending flags (if any)
	Address = FLASH_USER_START_ADDR + FLASH_PAGE_SIZE * _PageNumber;
	EndAddr = Address + Num;

	while (Address < EndAddr) {
		if (FLASH_ProgramWord(Address, *pBuffer++) == FLASH_COMPLETE) {
			Address += 4;
		} else {
			flag = 0;// Error occurred while writing data in Flash memory.
		}
	}

	FLASH_Lock(); // Lock the Flash to disable the flash control register access
	
	return flag;
}
/*
void Flash_BufferRead(uint8_t _PageNumber,uint32_t *pBuffer,uint16_t Num)
{

	uint8_t i;
	uint32_t Address = 0;
	
	Address = FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE *  _PageNumber		 );

	for( i=0; i<Num/4; i++ )
  {
    *pBuffer++ = *(__IO uint32_t *)Address;
     Address += 4;
  }
	for( i=0; i<Num%4; i++ )
	{
		*(uint8_t *)pBuffer = *(__IO uint8_t *)Address;
		 ( (uint8_t *)pBuffer )++;//地址加1
		 Address += 1;
	}

}*/
void Flash_BufferRead(uint8_t _PageNumber,uint8_t *pBuffer,uint16_t Num)
{
	uint8_t i;
	uint32_t Address = 0;
	
	Address = FLASH_USER_START_ADDR + (FLASH_PAGE_SIZE *  _PageNumber		 );

	for( i=0; i< Num; i++)
	{
		*pBuffer++ = *(__IO uint8_t *)Address++;
	}
}

#endif
