

#include "r_cg_macrodriver.h"

#include "pfdl.h"
#include "pfdl_types.h"

/***********************************************************************************************************************
* Function Name: WriteDataflash
* Description  : 
* Arguments    : buffer: to be writed data; Addr:Target absolute address,must be check for different mcu;lenth:to be writed number,<=1024
* Return Value : PFDL_OK - 
                     Success
                 PFDL_IDLE -
				     Idling statement
			     PFDL_ERR_MARGIN - 
				     Blank check error
				     
				 other//if(Addr>=FLASH_START_ADDRESS&&Addr<FLASH_END_ADDRESS){				      
***********************************************************************************************************************/
uint8_t WriteDataflash(uint8_t* buffer,uint32_t Addr,uint16_t lenth)
{
	static unsigned char Wr_Status;
	pfdl_status_t  ret;   
	pfdl_descriptor_t descriptor;
	pfdl_request_t requester;

	if(Addr>=0x000F1000 && Addr<0x000F2000)
	{
		if(Wr_Status == 0)
		{		
		    	/* ---- Setting for PFDL_Open ---- */
		    	descriptor.fx_MHz_u08            = FDL_FRQ;
		    	descriptor.wide_voltage_mode_u08 = FDL_VOL;
		    	PFDL_Open(&descriptor);
		    	
		    	/* ---- Setting for blank check ---- */
		    	requester.command_enu   = PFDL_CMD_BLANKCHECK_BYTES;
		    	requester.index_u16     = (unsigned int)(Addr - 0x0F1000);//g_write_address;0x0F1000 according to MCU
		    	requester.bytecount_u16 = lenth;
		    	ret                     = PFDL_Execute(&requester);      /* Blank check */
			Wr_Status = 1;
		}
		
		if(Wr_Status == 1)
		{
			/* ---- Waiting for command finish ---- */
			while(ret == PFDL_BUSY)
			{
				ret = PFDL_Handler();     /* Status check process */
			}
			if(ret != PFDL_BUSY)
			{
				/* **** When blank check error **** */
			    	if(ret == PFDL_ERR_MARGIN)
			    	{
			    	
			    		/* ---- Setting for erase ---- */
			    		requester.command_enu = PFDL_CMD_ERASE_BLOCK;
			    		requester.index_u16   = (unsigned int)(Addr - 0x0F1000)/0x400;//TARGET_BLOCK;    
			    		ret                   = PFDL_Execute(&requester); /* Erase block data */				    	
					Wr_Status = 2;
			    		/* Erase data of target block */
			    	}
			    	/* **** When other than blank check error **** */
			    	else
			    	{
			    	    	/* Do nothing */
			    	}
				
				/******When blank no check error***/
				if(ret == PFDL_OK)
			    	{
			    	  	/* ---- Setting for write ---- */
		    			requester.command_enu   = PFDL_CMD_WRITE_BYTES;
		    			requester.index_u16     = (unsigned int)(Addr - 0x0F1000);//g_write_address;;
		    			requester.bytecount_u16 = lenth;
		    			requester.data_pu08     = buffer;//&g_write_value;    
		    			ret                     = PFDL_Execute(&requester);   /* Execute write */
					Wr_Status = 3;
				}
			}
		}

		if(Wr_Status == 2)
		{
			/* ---- Waiting for command finish ---- */
			while(ret == PFDL_BUSY)
			{
				ret = PFDL_Handler();     /* Status check process */
			}  
			if(ret != PFDL_BUSY)
			{
				if(ret == PFDL_OK)
			    	{
			    	  	/* ---- Setting for write ---- */
		    			requester.command_enu   = PFDL_CMD_WRITE_BYTES;
		    			requester.index_u16     = (unsigned int)(Addr - 0x0F1000);//g_write_address;;
		    			requester.bytecount_u16 = lenth;
		    			requester.data_pu08     = buffer;//&g_write_value;    
		    			ret                     = PFDL_Execute(&requester);   /* Execute write */
					Wr_Status = 3;
				}
				/* **** When blank check or data erase is failure **** */
				else
				{
					ret = PFDL_NG;
					//PFDL_Close(); /* Close FDL */
					//Wr_Status = 0;
					return ret;
				}
			}							
		}
		
		if(Wr_Status == 3)
		{
			/* ---- Waiting for command finish ---- */
			while(ret == PFDL_BUSY)
			{
				ret = PFDL_Handler();     /* Status check process */
			}
			if(ret != PFDL_BUSY)
			{
				/* ==== When write data is success ==== */	    	   
			    	if(ret == PFDL_OK)
			    	{
	    	        		/* ---- Setting for verify ---- */
		    			requester.command_enu   = PFDL_CMD_IVERIFY_BYTES;
						requester.index_u16     = (unsigned int)(Addr- 0x0F1000);//g_write_address;;
						requester.bytecount_u16 = lenth;    
		    			ret                     = PFDL_Execute(&requester);  /* Execute internal verify */
		    			Wr_Status = 4;	    	        
		    	    	}
			        /* ==== When writing data is failure ==== */
			    	else
			    	{
			    	        ret = PFDL_NG;
					//PFDL_Close(); /* Close FDL */
					//Wr_Status = 0;
					return ret;
			    	}
			}			
		}
		
		if(Wr_Status == 4)
		{
			/* ---- Waiting for command finish ---- */
			while(ret == PFDL_BUSY)
			{
				ret = PFDL_Handler();     /* Status check process */
			}  
			if(ret != PFDL_BUSY)
			{
				PFDL_Close(); /* Close FDL */
				Wr_Status = 0;
				return 0x11;//write data flash finished
			}			
		}
	}
	else
	{
		ret = PFDL_NG;
		Wr_Status = 0;
		return ret;
	}
} 


uint8_t WriteDataflash1(uint8_t* buffer,uint32_t Addr,uint16_t lenth)
{
	pfdl_status_t  ret;   
    pfdl_descriptor_t descriptor;
    pfdl_request_t requester;
    
     if(Addr>=0x000F1000&&Addr<0x000F2000){
    	/* ---- Setting for PFDL_Open ---- */
    	descriptor.fx_MHz_u08            = FDL_FRQ;
    	descriptor.wide_voltage_mode_u08 = FDL_VOL;
    	PFDL_Open(&descriptor);
    	
    	/* ---- Setting for blank check ---- */
    	requester.command_enu   = PFDL_CMD_BLANKCHECK_BYTES;
    	requester.index_u16     = (unsigned int)(Addr - 0x0F1000);//g_write_address;0x0F1000 according to MCU
    	requester.bytecount_u16 = lenth;
    	ret                     = PFDL_Execute(&requester);      /* Blank check */
    	
    	/* ---- Waiting for command finish ---- */
    	while(ret == PFDL_BUSY)
    	{
    	    ret = PFDL_Handler();     /* Status check process */
    	}
    	
    	/* **** When blank check error **** */
    	if(ret == PFDL_ERR_MARGIN)
    	{
    	
    		/* ---- Setting for erase ---- */
    		requester.command_enu = PFDL_CMD_ERASE_BLOCK;
    		requester.index_u16   = (unsigned int)(Addr - 0x0F1000)/0x400;//TARGET_BLOCK;    
    		ret                   = PFDL_Execute(&requester); /* Erase block data */
    	
    		/* ---- Waiting for command finish ---- */
    		while(ret == PFDL_BUSY)
    		{
    	    	ret = PFDL_Handler();    /* Status check process */
    		}                           /* Erase data of target block */
    	}
    	/* **** When other than blank check error **** */
    	else
    	{
    	    /* Do nothing */
    	}
    	
    	if(ret == PFDL_OK)
    	{
    	    /* ---- Setting for write ---- */
    		requester.command_enu   = PFDL_CMD_WRITE_BYTES;
    		requester.index_u16     = (unsigned int)(Addr - 0x0F1000);//g_write_address;;
    		requester.bytecount_u16 = lenth;
    		requester.data_pu08     = buffer;//&g_write_value;    
    		ret                     = PFDL_Execute(&requester);   /* Execute write */
    	
    		/* ---- Waiting for command finish ---- */
    		while(ret == PFDL_BUSY)
    		{
    	    	ret = PFDL_Handler();       /* Status check process */
			}                              /* Write data process */
    	    /* ==== When write data is success ==== */
    	   
    	    if(ret == PFDL_OK)
    	    {
    	        /* ---- Setting for verify ---- */
    			requester.command_enu   = PFDL_CMD_IVERIFY_BYTES;
				requester.index_u16     = (unsigned int)(Addr- 0x0F1000);//g_write_address;;
				requester.bytecount_u16 = lenth;    
    			ret                     = PFDL_Execute(&requester);  /* Execute internal verify */
    	
    			/* ---- Waiting for command finish ---- */
    			while(ret == PFDL_BUSY)
    			{
    	    		ret = PFDL_Handler();/* Status check process */
    			} 
    	        
    	    }
    	    /* ==== When writing data is failure ==== */
    	    else
    	    {
    	        ret = PFDL_NG;
    	    }
    	}
    	/* **** When blank check or data erase is failure **** */
    	else
    	{
    	    ret = PFDL_NG;
    	}
    	
    	PFDL_Close(); /* Close FDL */
    	
    	return ret;
    }
    else{
    	ret = PFDL_NG;
    	return ret;
    }
} 


/***********************************************************************************************************************
* Function Name: ReadFlashData
* Description  : 
* Arguments    : buffer: to be read data; 
				 Addr:Target absolute address,must be check for different mcu; Both codeflash & dataflash can be used
				 lenth:to be read number
* Return Value : None
***********************************************************************************************************************/

void ReadFlashData(uint8_t* buffer,uint32_t Addr,uint16_t lenth)
{
	uint8_t temp;
	volatile uint32_t w_count;
	volatile uint8_t * snnumber;
	/**** Only dataflash needed start*****/
	if(0 == DFLEN)
	{
		DFLEN = 1U;  //允许存取数据闪存
    		for (w_count = 0U; w_count < 15U; w_count++)//3U
    		{
        		NOP(); //延时，给硬件反应的时间
    		}
	}
	/**** Only dataflash needed end******/
	snnumber = Addr;
	
	for(temp = 0; temp < lenth; temp ++)
	{
		*buffer = *snnumber;
		buffer ++;
		snnumber ++;
	}
	//memcpy(buffer,snnumber,lenth);
}

/* End user code. Do not edit comment generated here */