#include <hidef.h>      /* common defines and macros */
#include <mc9s12p128.h>     /* derivative information */
#include "flash.h"


/******************************************************************************
Function Name	:	FLASH_d_addr
Engineer		:	b19005
Date			:	30/11/08
Arguments	:	   
Return		: 0/success; others/fail 
Notes			:	This function programs all D-flash with the data from 0x4400 to 0x5400   
            (step = 2), that means the serial {0x4400, 0x4402, ... 0x53fe}
******************************************************************************/
tU16 FLASH_d_addr()
{
  tU16 sect;
  
  // Fill the range with its address 
  for (sect = 0; sect < FLASH_D_SECTNUM; sect++) {
    
      if (FLASH_OK != FLASH_d_addr_sector(0,sect))
        return FLASH_PROGRAM_ERROR;
  }
  
  return FLASH_OK;
}

/******************************************************************************
Function Name	:	FLASH_d_addr_sector
Engineer		:	b19005
Date			:	03/12/08
Arguments	: page: 0
            sector: 0...15	   
Return		: 0/success; others/fail 
Notes			:	This function programs a selected sector of D-flash with the data from 
            sector start global address to the sector end global address with step  
            2
******************************************************************************/
tU16 FLASH_d_addr_sector(tU08 page, tU08 sector)
{
  tU16 base, addr, j;
  tU32 i;
  
  // Fill the range with its address 
  base = FLASH_D_SADDRGL + page*FLASH_D_PAGESIZE + sector*FLASH_D_SECTSIZE ;

  if(LaunchFlashCommand(2, ERASE_D_FLASH_SECTOR, FLASH_D_ADDRGH, base, 0, 0, 0, 0) != CCIF_MASK) 
    return FLASH_PROGRAM_ERROR;      
  if(LaunchFlashCommand(3, ERASE_VERIFY_D_FLASH_SECTION, FLASH_D_ADDRGH, base, FLASH_D_SECTSIZE>>1, 0, 0, 0) != CCIF_MASK) 
    return FLASH_PROGRAM_ERROR;      
	
	addr = base;
	for (j = 0; j < FLASH_D_SECTSIZE; j+=8) {
	    
	  if(LaunchFlashCommand(6, PROGRAM_D_FLASH, FLASH_D_ADDRGH, addr, addr, addr+2, addr+4, addr+6) != CCIF_MASK) 
      return FLASH_PROGRAM_ERROR;
	    
	  addr += 8;
	}
  
  // Verify the data
  return FLASH_d_check_sector_data(page, sector, PATTERN_ADDRESS, 0);
    
}


/******************************************************************************
Function Name	:	FLASH_d_check_sector_data
Engineer		:	b19005
Date			:	03/12/08
Arguments	: page: 0
            sector: 0...15	
            mode: PATTERN_VALUE or PATTERN_ADDRESS 
            val: data for mode == PATTERN_VALUE  
Return		: 0/success; others/fail 
Notes			:	This function verify the data in a selected sector of D-flash
******************************************************************************/
tU16 FLASH_d_check_sector_data(tU08 page, tU08 sector, tU08 mode, tU16 val)
{
  tU16 base, addr, cval;
  tU32 i;
  
  // Verify the data
  data_ptr = (tU16 __far *) (FLASH_D_SADDRLOGIC+sector*FLASH_D_SECTSIZE);
  
  if (mode == PATTERN_VALUE) {
    
    for (i = 0; i < FLASH_D_SECTSIZE; i+=2) {
      
      if (*data_ptr++ != val) 
        return FLASH_PROGRAM_ERROR;
    }
  } 
  else {
    for (i = 0; i < FLASH_D_SECTSIZE; i+=2) {
      
      if (*data_ptr++ != FLASH_D_SADDRGL+FLASH_D_SECTSIZE*sector+i) 
        return FLASH_PROGRAM_ERROR;
    }
  }
    
  return FLASH_OK;
}

/******************************************************************************
Function Name	:	FLASH_d_check_block_data
Engineer		:	b19005
Date			:	03/12/08
Arguments	: mode: PATTERN_VALUE or PATTERN_ADDRESS 
            val: data for mode == PATTERN_VALUE  
Return		: 0/success; others/fail 
Notes			:	This function verify the data in a selected block of D-flash
******************************************************************************/
tU16 FLASH_d_check_block_data(tU08 mode, tU16 val)
{
  tU16 base, addr, cval;
  tU16 i;
  
  for (i = 0; i < FLASH_D_SECTNUM; i++) {
    
    if (FLASH_OK != FLASH_d_check_sector_data(0, i, mode, val))
      return FLASH_PROGRAM_ERROR;
  }
  
  return FLASH_OK;
}
