/*******************************************************************************
 *
 *  Module:         dataflash.c
 *  Description:    emulace EEPROM v interni dataflash procesoru
 *
 ******************************************************************************/

#include "includes.h"
#include "dataflash.h"
#include "Flash_API/Flash_API_R8C.h"

extern tsConfig	config;
extern tsTitle  cfgstitle;		
extern tsEDK  EDK;
extern tUChar ramBuffer[RAM_BUFFER_SIZE];	// globalni buffer
extern tUChar inputTable[MAX_SENSORS][INPUT_TABLE_RAM_SIZE];

/************************************************************************************/
// Write_page_EEPROM       																								 
//  argument1:write address(unsigned short)  																					 
//  argument2:write data address(unsigned char *)  																				 
//  argument3:write data number(unsigned short)  																				 
//  return: 0: NO ACK - ERROR
//			1: OK
/************************************************************************************/
tUInt Write_n_EEPROM( unsigned short adrs , unsigned char *wr_ptr , unsigned short no ) 
{ 
 unsigned char success; 

  BOOT.address = adrs;		// adresa zapisu
  BOOT.buffer = wr_ptr;		// pointer na zdrojovy buffer
  BOOT.length = no;			// delka zapisovanych dat
	
  FlashWrite();	
  
  success = BOOT.status;
  
  
  if (success != NO_ERROR)
   {
	  return(success); 
   }
	
  return(NO_ERROR); 
} 



/************************************************************************************/
// Read_n_EEPROM    																											*/ 
//  argument1:read address(unsigned short)  																					*/ 
//  argument2:read data address(unsigned char *)  																				*/ 
//  argument3:read data number(unsigned short)  																				*/ 
//  return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
unsigned int Read_n_EEPROM ( unsigned short adrs , unsigned char *rd_ptr , unsigned short no ) 
{ 
	char *pDF;
	int i;
	
	pDF = adrs;
	
	for (i=0; i<no; i++)
	 {
	   *rd_ptr++ = *pDF++;
	 }

 	return(NO_ERROR); 
} 



/************************************************************************************/
// ClearDF    																											*/ 
// smaze - inicializuje cely prostor dataflash 1024Bajtu
// return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
tUInt ClearDF(tUChar block)
{
  tUInt temp;
  tUInt success;
  
//  success = FlashErase( block );	// OK: success == 0 FAIL: success == 1 or 2 or 3
  BOOT.block = block;
  FlashErase();					// OK: success == 0 FAIL: success == 1 or 2 or 3
  success = BOOT.status;

  wait_ms(50);					// pockat na dokonceni mazani 

  if (success != NO_ERROR)  return(success); 

  return success;
}




/************************************************************************************/
// Write_InputConfig    																											*/ 
// ulozi konfiguraci zarizeni, v pripade ETS4 nastavene limity
// return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
unsigned char Write_InputConfig(void)
{
  tUInt status;
  tUInt loop;
  tUChar *src, *dest;
   	
  // operace zapisu musi byt READ-MODIFY-WRITE, proto bufferovat
  // nacitame cely alokovany prostor Bloku_B
  Read_n_EEPROM ( DF_BLOCK_B_START, (tUChar*)&ramBuffer, BLOCK_B_ALLOC_SIZE);	

  // pridat nove data do RamBufferu 
  // protoze mam rozsireny prostor inputTable o polozky ktere nechceme ukladat, musime ulozit jen 8 bajtu 
  dest = (tUChar*)&ramBuffer[0]+OFFSET_ADDRESS_INPUTCONFIG;
  src = (tUChar*)&inputTable[0];
  
  // nakopirovat 8 bajtu pro kazdy sensor
  for (loop=0; loop<MAX_SENSORS; loop++)		
  {
    my_memcpy(dest, src, INPUT_TABLE_DF_SIZE);	// nakopirovat obsah InputTable  
	src += INPUT_TABLE_RAM_SIZE;				// posunout ukazatel
	dest += INPUT_TABLE_DF_SIZE;
  }
  
  // smazat dataFlash
  ClearDF(BLOCK_B);

  // zapsat vse po modifikaci zpet
  status = Write_n_EEPROM( DF_BLOCK_B_START, (tUChar*)&ramBuffer, BLOCK_B_ALLOC_SIZE );
 
  return (status);
}





/************************************************************************************/
// Read_InputConfig    																											*/ 
// nacte po startu konfiguraci zarizeni, v pripade ETS4 nastavene limity
// return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
unsigned char Read_InputConfig(void)
{
  tUInt status;
  tUChar *dest;
  tUInt adr;
  tUInt loop;

  // nacitame jen 8 bajtu 
  dest = (tUChar*)&inputTable[0];
  adr =  CDATAADDRESS_INPUTTABLE;
  
  // nakopirovat ulozenych 8 bajtu pro kazdy sensor z dataFlash
  for (loop=0; loop<MAX_SENSORS; loop++)		
  {
    // naplnit jen obsah InputTable
    // nacitani jde pres ramBuffer
    Read_n_EEPROM ( adr, dest, 8);
	dest += INPUT_TABLE_RAM_SIZE;	// inkremetovat offset, ale o celou velikost pro jeden sensor
	adr += INPUT_TABLE_DF_SIZE;		// velikost v dataFlash
  }

}



/************************************************************************************/
// Write_RomTitle
// vytvori a ulozi seriove cislo do DataFlash
// return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
unsigned int Write_RomTitle(tUChar *data)
{
  tUInt status;

  // operace zapisu musi byt READ-MODIFY-WRITE, proto bufferovat
  // nacitame cely alokovany prostor Bloku_A
  Read_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE);	

  // pridat nove data do RamBufferu 
  my_memcpy ((tUChar*)&ramBuffer+OFFSET_ADDRESS_TITLE, data, sizeof(cfgstitle.string));	// nakopirovat popisek

  // smazat obsah DF block_A
  ClearDF(BLOCK_A);
 
  // zapsat zpet do DF    
  status = Write_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE );

  // aktualizovat
  Read_RomTitle();

  return (status);
}



/************************************************************************************/
// Read_RomTitle
// nacte popisky
// return: 1:OK/0:ERR								 																			*/ 
/************************************************************************************/
unsigned int Read_RomTitle(void)
{
  Read_n_EEPROM ( CDATAADDRESS_TITLE, (tUChar*)&cfgstitle.string, sizeof (cfgstitle.string));
  
  return (NO_ERROR);
}





/************************************************************************************/
// WriteConfig
// zapis konfiguracnich parametru v rezimu RD3
/************************************************************************************/
tUInt WriteConfig(void)
{
  tUInt status;

  // operace zapisu musi byt READ-MODIFY-WRITE, proto bufferovat
  // nacitame cely alokovany prostor DATAFLASH BLOCK_A
  Read_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE);	

  // pridat nove data do RamBufferu 
  my_memcpy ((tUChar*)&ramBuffer+OFFSET_ADDRESS_CONFIG, (tUChar*)&EDK.config, sizeof(EDK.config));	

  // smazat obsah DF block_A
  ClearDF(BLOCK_A);
 
  // zapsat zpet do DF    
  status = Write_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE );

  // aktualizovat
  ReadConfig();
  
  return (status);					// navratovy kod
}
  


/************************************************************************************/
// ReadConfig
// nacteni globalnich konfiguracnich parametru
/************************************************************************************/
tUInt ReadConfig(void)
{
  tUInt status;
 
  // nacte zaznam  
  status = Read_n_EEPROM (CDATAADDRESS_CONFIG, (tUChar*)&EDK.config, sizeof(EDK.config));   // nacti celou strukturu cfgsystem

  return (status);			// navratovy kod
}



/************************************************************************************/
// SetDefaultConfig
// inicializuje konfiguracni parametry
/************************************************************************************/
tUInt SetDefaultConfig(void)
{
  tUInt status;

  // operace zapisu musi byt READ-MODIFY-WRITE, proto bufferovat
  // nacitame cely alokovany prostor DATAFLASH BLOCK_A
  Read_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE);	

  // default konfigurace, kopiruje konfiguracni stav zarizeni RD3  
  EDK.config.card_timeout 	   = DEFAULT_CARD_TIMEOUT;		
  EDK.config.emm_code_length   = DEFAULT_EMM_CODE_LENGTH;	
  EDK.config.card_code_flip    = DEFAULT_CARD_CODE_FLIP;
  EDK.config.card_code_reverse = DEFAULT_CARD_CODE_REVERSE;				
  EDK.config.wg_bit_length 	   = DEFAULT_WG_BIT_LENGTH;					
  EDK.config.card_code_dec 	   = DEFAULT_CARD_CODE_DEC;					
  EDK.config.card_code_hex 	   = DEFAULT_CARD_CODE_HEX;					
  EDK.config.card_code_dal 	   = DEFAULT_CARD_CODE_DAL;					
  EDK.config.card_code_mf7     = DEFAULT_CARD_CODE_MF7;					
  EDK.config.card_code_length  = DEFAULT_CARD_CODE_LENGTH;					
  EDK.config.card_send_loop    = DEFAULT_CARD_SEND_LOOP;				
  EDK.config.buzzer_active     = DEFAULT_BUZZER_ACTIVE;				
  EDK.config.buzzer_wait_card  = DEFAULT_BUZZER_WAIT_CARD;
  EDK.config.loopinp		   = DEFAULT_LOOPINP;  	
  EDK.config.check_offline	   = DEFAULT_CHECK_OFFLINE;
  EDK.config.check_byte		   = CFG_CHECK_BYTE;

  // pridat nove data do RamBufferu 
  my_memcpy ((tUChar*)&ramBuffer+OFFSET_ADDRESS_CONFIG, (tUChar*)&EDK.config, sizeof(EDK.config));

  // smazat obsah DF block_A
  ClearDF(BLOCK_A);
 
  // zapsat zpet do DF    
  status = Write_n_EEPROM ( DF_BLOCK_A_START, (tUChar*)&ramBuffer, BLOCK_A_ALLOC_SIZE );

  // aktualizovat
  ReadConfig();
  
  return (status);					// navratovy kod
}
  
  
