/**********************************************************************/
/*                                                                    */
/* File name: DLL_interface.c                                         */
/*                                                                    */
/* Since:     2002/12/03                                              */
/*                                                                    */
/* Version:   1.02                                                    */
/*                                                                    */
/* Author:    MONTAGNE Xavier [XM] {link xavier.montagne@wanadoo.fr}  */
/*                                                                    */
/* Purpose: Offer high level interface for PIC programming operations:*/
/*          parsing or creat an HEX file, updating the PIC structures */
/*          after parsing, reading or programming the PIC,...         */
/*                                                                    */
/* Distribution: This file is part of PP18.                           */
/*               PP18 is free software; you can redistribute it       */
/*               and/or modify it under the terms of the GNU General  */
/*               Public License as published by the Free Software     */
/*               Foundation; either version 2, or (at your option)    */
/*               any later version.                                   */
/*                                                                    */
/*               PP18 is distributed in the hope that it will be      */
/*               useful, but WITHOUT ANY WARRANTY; without even the   */
/*               implied warranty of MERCHANTABILITY or FITNESS FOR A */
/*               PARTICULAR PURPOSE.  See the GNU General Public      */
/*               License for more details.                            */
/*                                                                    */
/*               You should have received a copy of the GNU General   */
/*               Public License along with PP18; see the file         */
/*               COPYING.txt. If not, write to the Free Software      */
/*               Foundation, 59 Temple Place - Suite 330,             */
/*               Boston, MA 02111-1307, USA.                          */
/*                                                                    */
/* History:                                                           */
/*      2002/12/03  [XM] Create this file                             */
/*                                                                    */
/**********************************************************************/

/***********************************************************************
 * INCLUDES
 **********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#include "DLL_interface.h"

/***********************************************************************
 * DEFINES.
 **********************************************************************/

/******* Defines dedicated to this PIC ********************************/ 
#define _DEFAULT_PATTERN_                0xFF
#define _MAX_PIC_SIZE                    0x4000


/***********************************************************************
 * Function prototypes.
 **********************************************************************/
void ProgressWindow_Show(pHexFile_t p_hfFile, unsigned int Read_Write);
void DLLAboutWindow_Show(void);
void SettingsWindow_Show(void);
void ConfigWindow_Show(unsigned int uiFrom);

/***********************************************************************
 * Global variables.
 **********************************************************************/
/******* Structures for data from/to PIC or file **********************/ 
HexFile_t HEX_from_file;
HexFile_t HEX_from_PIC;
unsigned short MemFile[_MAX_PIC_SIZE];
unsigned short MemPIC[_MAX_PIC_SIZE];
ConfigWord_t CFG_File;
ConfigWord_t CFG_PIC;

extern unsigned int IsLocked;

/******* Structure related to statistics if necessary *****************/ 
Statistic_t Stat;

/******* Checksum computation from file or PIC content ****************/ 
unsigned char Checksum;


/***********************************************************************
 * Only fill the SHexFile structure. Do not proceed to any programming 
 * sequences. This function fills the Hex_from_file structure, so it has
 * to be called first to initialyze. 
 *
 * @param  char *ucFilename   IN  HEX filename to parse
 * @return Status_t               FILE_ERROR if something wrong appends
 *                                (Hex larger than PIC memory size)
 *                                ALL_RIGHT otherwise
 **********************************************************************/
Status_t DLL_EXPORT ParseFile(char *ucFilename)
{
  FILE *fd;
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;
  unsigned short usChecksum;

  /******* Build the HEX_file_file structure ****************************/ 
  p_hfFile = &HEX_from_file;
  p_Stat = &Stat;
  p_hfFile->pusMemory = &MemFile[0];
  p_hfFile->pConfig = &CFG_File;
  p_hfFile->uiMemorySize = _MAX_PIC_SIZE;
  memset(p_hfFile->pusMemory, 0xFF, _MAX_PIC_SIZE * sizeof(unsigned short));
  /*memset(p_hfFile->pConfig, 0xFF, sizeof(ConfigWord_t));*/
  if (IsLocked == 0)
  {
    p_hfFile->pConfig->szFosc                = 0x07;
    p_hfFile->pConfig->szOscsen              = 0x00;
    p_hfFile->pConfig->szPwrten              = 0x00;
    p_hfFile->pConfig->szBoren               = 0x01;
    p_hfFile->pConfig->szBorv                = 0x03;
    p_hfFile->pConfig->szWdten               = 0x01;
    p_hfFile->pConfig->szWdtps               = 0x07;
    p_hfFile->pConfig->szCcp2mx              = 0x01;
    p_hfFile->pConfig->szStvren              = 0x01;
    p_hfFile->pConfig->szLVP                 = 0x01;
    p_hfFile->pConfig->szDebug               = 0x00;
    p_hfFile->pConfig->szCodeProtected       = 0xCF;
    p_hfFile->pConfig->szWriteProtected      = 0xEF;
    p_hfFile->pConfig->szTableReadProtected  = 0x4F;
  }
  /*memset(p_hfFile->pConfig, 0xFF, sizeof(ConfigWord_t));*/
  memset(p_hfFile->szIdValue, 0xFF, 8);
  p_hfFile->SChipStatus = 0;

  fd = fopen((const char*)ucFilename, "r");
  if (fd == NULL)
  {
  	p_hfFile->SChipStatus = 1;
    fclose(fd);
  	return(p_hfFile->SChipStatus);
  }
  else
	  p_hfFile->SChipStatus = 0;

  /******* Parse the HEX file and fill the memory field of the structure*/
  if ( !HexParserMemory(fd, p_hfFile->pusMemory, &(p_Stat->uiNbWord2BeProgrammed) ))
  {
	  p_hfFile->SChipStatus = 1;
      fclose(fd);
	  return(p_hfFile->SChipStatus);
  }
  if (p_hfFile->uiMemorySize < p_Stat->uiNbWord2BeProgrammed)
    p_hfFile->SChipStatus = 1;

  /******* Parse the HEX file and fill the config field of the structure*/
  if (IsLocked == 0)
  {
    fseek(fd, 0, SEEK_SET);
    if ( !HexParserConfig(fd, p_hfFile->pConfig) )
    {
	  p_hfFile->SChipStatus = 1;
      fclose(fd);
	  return(p_hfFile->SChipStatus);
    }
  }

  /******* Parse the HEX file and fill the ID field of the structure ****/
  fseek(fd, 0, SEEK_SET);
  if ( !HexParserID(fd, p_hfFile) )
  {
	  p_hfFile->SChipStatus = 1;
      fclose(fd);
	  return(p_hfFile->SChipStatus);
  }

  /******* Checksum computed from Memory + Config + ID ******************/
  ComputeGeneralChecksum(&usChecksum, FromFile);

  fclose(fd);
  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Give the memory size of the chip (and not the memory size of usefull
 * data inside the PIC), or the data size of the HEX file parsed.  
 *
 * @param  u_int *uiSize      OUT PIC memory size
 * @param  u_int uiFrom       IN  Flag (PIC or File) 
 * @return Status_t               Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT GetMemorySize(unsigned int *uiSize, unsigned int uiFrom)
{
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  *uiSize = p_hfFile->uiMemorySize;
  return(0);
}

/***********************************************************************
 * Copy the memory content from the PIC or FILE structure to the buffer
 * parameter.  
 *
 * @param  u_short *usMemory  OUT Memory buffer
 * @param  u_int uiFrom       IN  Flag (PIC or File) 
 * @return Status_t               Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT GetMemoryBuffer(unsigned short *usMemory, unsigned int uiFrom)
{
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  memcpy(usMemory, p_hfFile->pusMemory, p_hfFile->uiMemorySize * sizeof(unsigned short));
  return(0);
}

/***********************************************************************
 * Copy the memory content from the buffer to the PIC or FILE structure.  
 *
 * @param  u_short *usMemory  IN  Memory buffer
 * @param  u_int uiFrom       IN  Flag (PIC or File) 
 * @return Status_t               Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT SetMemoryBuffer(unsigned short *usMemory, unsigned int uiFrom)
{
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  memcpy(p_hfFile->pusMemory, usMemory, p_hfFile->uiMemorySize * sizeof(unsigned short));
  return(0);
}

/***********************************************************************
 * Rebuil a HEX File from memory, config and ID. Do not proceed to any 
 * programming sequences. This function creats a new HEX file a replace 
 * an existing one. 
 *
 * @param  char *ucFilename   IN  HEX filename to build
 * @param  u_int uiFrom       IN  Flag (PIC or File)  
 * @return Status_t               FILE_ERROR if something wrong appends
 *                                (cannot creat a new file)
 *                                ALL_RIGHT otherwise
 **********************************************************************/ 
Status_t DLL_EXPORT UnParseFile(char *ucFilename, unsigned int uiFrom)
{
  FILE *fd;
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;
  p_hfFile->SChipStatus = 0;

  fd = fopen((const char*)ucFilename, "w");
  if (fd == NULL)
  {
  	p_hfFile->SChipStatus = 1;
  	return(p_hfFile->SChipStatus);
  }

  /******* Build HEX file from Memory, config and ID ********************/ 
  HexUnParserMemory(fd, p_hfFile->pusMemory, p_hfFile->uiMemorySize * sizeof(unsigned short));
  HexUnParserConfig(fd, p_hfFile->pConfig);
  HexUnParserID(fd, p_hfFile);

  /******* END_OF_FILE_RECORD *******************************************/   
  SetNextChar (fd, ':');
  SetNextByte (fd, 0x00);
  SetNextShortUnSwap(fd, 0x00);
  SetNextByte (fd, END_OF_FILE_RECORD);
  SetNextByte(fd, 0xFF);
  SetCR(fd);

  fclose(fd);
  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Perform a programmation process to the hardware programmer and the 
 * chip on it concerning memory area only.
 *
 * @param  u_int uiFrom      IN  Flag (PIC or File)  
 * @return Status_t              BAD_PROGRAMMED if something wrong appends
 *                               PROGRAMMED if not
 *                               ALL_RIGHT otherwise
 **********************************************************************/  
Status_t DLL_EXPORT ProgramMem(unsigned int uiFrom)
{
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;
  p_hfFile->SChipStatus = 0;

  BulkErase();
  ProgressWindow_Show(p_hfFile, DISPLAY_WRITE);
	
  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Perform a programmation process to the hardware programmer and the 
 * chip on it concerning config area only.
 *
 * @param  u_int uiFrom      IN  Flag (PIC or File)  
 * @return Status_t              BAD_PROGRAMMED if something wrong appends
 *                               PROGRAMMED if not
 *                               ALL_RIGHT otherwise
 **********************************************************************/   
Status_t DLL_EXPORT ProgramConfig(unsigned int uiFrom)
{
  unsigned int total_try, word_programmed;
  unsigned short word;
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;
  p_Stat = &Stat;
  p_hfFile->SChipStatus = 0;

  p_Stat->uiNbWord2BeProgrammed = 4;
  
  word = 0x00;
  ProgramBlockCfg(0x300000, &word, 1, &total_try, &word_programmed); 

  word = ((p_hfFile->pConfig->szOscsen ? 0 : 1) << 13) + (p_hfFile->pConfig->szFosc << 8);
  ProgramBlockCfg(0x300001, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry = total_try;
  p_Stat->uiNbWordProgrammed = word_programmed;

  word = (p_hfFile->pConfig->szBorv << 2) + (p_hfFile->pConfig->szBoren << 1) +  \
		 ( (p_hfFile->pConfig->szPwrten) ? 0 : 1);
  ProgramBlockCfg(0x300002, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szWdtps << 9) + (p_hfFile->pConfig->szWdten << 8);
  ProgramBlockCfg(0x300003, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = 0x00;
  ProgramBlockCfg(0x300004, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = p_hfFile->pConfig->szCcp2mx << 8;
  ProgramBlockCfg(0x300005, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szStvren) + ((p_hfFile->pConfig->szDebug ? 0 : 1) << 7) + \
         (p_hfFile->pConfig->szLVP << 2);
  ProgramBlockCfg(0x300006, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = 0x00;
  ProgramBlockCfg(0x300007, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szCodeProtected & 0x0F);
  ProgramBlockCfg(0x300008, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szCodeProtected & 0xC0) << 8;
  ProgramBlockCfg(0x300009, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szWriteProtected & 0x0F);
  ProgramBlockCfg(0x30000A, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szWriteProtected & 0xE0) << 8;
  ProgramBlockCfg(0x30000B, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szTableReadProtected & 0x0F);
  ProgramBlockCfg(0x30000C, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  word = (p_hfFile->pConfig->szTableReadProtected & 0x40) << 8;
  ProgramBlockCfg(0x30000D, &word, 1, &total_try, &word_programmed);
  p_Stat->uiTotalTry += total_try;
  p_Stat->uiNbWordProgrammed += word_programmed;

  if (p_Stat->uiNbWordProgrammed != p_Stat->uiNbWord2BeProgrammed)
	p_hfFile->SChipStatus = 5;
  else
	p_hfFile->SChipStatus = 4;

  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Perform a programmation process to the hardware programmer and the 
 * chip on it concerning ID area only.
 *
 * @param  u_int uiFrom      IN  Flag (PIC or File)  
 * @return Status_t              BAD_PROGRAMMED if something wrong appends
 *                               PROGRAMMED if not
 *                               ALL_RIGHT otherwise
 **********************************************************************/   
Status_t DLL_EXPORT ProgramID(unsigned int uiFrom)
{
  unsigned int total_try, word_programmed, i;
  unsigned short word[4];
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;  

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;
  p_Stat = &Stat;
  p_hfFile->SChipStatus = 0;

  p_Stat->uiNbWord2BeProgrammed = 4;

  for (i = 0; i < p_Stat->uiNbWord2BeProgrammed; i++)
  {
	word[i] = (p_hfFile->szIdValue[i*2+1] << 8) + p_hfFile->szIdValue[i*2];
  }

  ProgramBlock(0x200000, word, 4, &total_try, &word_programmed); 
  p_Stat->uiTotalTry = total_try;
  p_Stat->uiNbWordProgrammed = word_programmed;
  
  if (p_Stat->uiNbWordProgrammed != p_Stat->uiNbWord2BeProgrammed)
	p_hfFile->SChipStatus = 5;
  else
	p_hfFile->SChipStatus = 4;
	
  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Download the code memory field from the PIC device, and update the 
 * PIC structure.
 *
 * @param  void
 * @return Status_t                BLANK if all memory set to 0xFFFF
 *                                 NOT_BLANK if not
 *                                 ALL_RIGHT otherwise
 **********************************************************************/   
Status_t DLL_EXPORT ReadMem(void)
{
  unsigned int i;
  pHexFile_t p_hfFile;

  p_hfFile = &HEX_from_PIC;
  p_hfFile->SChipStatus = 0;

  ProgressWindow_Show(p_hfFile, DISPLAY_READ);

  if (p_hfFile->SChipStatus == 10) /* ABORTED */
    return(p_hfFile->SChipStatus);

  p_hfFile->SChipStatus = 3; /* BLANK */
  for (i = 0; i < p_hfFile->uiMemorySize; i++)
  {
	if (p_hfFile->pusMemory[i] != 0xFFFF)
		p_hfFile->SChipStatus = 2; /* NOT BLANK */
  }

  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Download the config field from the PIC device, and update the PIC
 * structure.
 *
 * @param  void
 * @return Status_t                LOCKED if Code Prection ON
 *                                 ALL_RIGHT otherwise
 **********************************************************************/  
Status_t DLL_EXPORT ReadConfig(void)
{
  unsigned short word;
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;

  p_hfFile = &HEX_from_PIC;
  p_Stat = &Stat;
  p_hfFile->SChipStatus = 0;

  ReadBlock(0x300000, &word, 1);
  p_hfFile->pConfig->szFosc          = (word & 0x0700) >> 8;
  p_hfFile->pConfig->szOscsen        = (word & 0x2000) ? 0: 1;

  ReadBlock(0x300002, &word, 1);
  p_hfFile->pConfig->szPwrten        = (word & 0x0001) ? 0: 1;
  p_hfFile->pConfig->szBoren         = (word & 0x0002) ? 1: 0;
  p_hfFile->pConfig->szBorv          = (word & 0x000C) >> 2;
  p_hfFile->pConfig->szWdten         = (word & 0x0100) >> 8;
  p_hfFile->pConfig->szWdtps         = (word & 0x0E00) >> 9;

  ReadBlock(0x300004, &word, 1);
  p_hfFile->pConfig->szCcp2mx        = (word & 0x0100) >> 8;

  ReadBlock(0x300006, &word, 1);
  p_hfFile->pConfig->szDebug         = (word & 0x0080) ? 0 : 1;
  p_hfFile->pConfig->szLVP           = (word & 0x0004) >> 2;
  p_hfFile->pConfig->szStvren        =  word & 0x0001;

  ReadBlock(0x300008, &word, 1);
  p_hfFile->pConfig->szCodeProtected =  (word & 0x000F) + ((word & 0xC000) >> 8);

  ReadBlock(0x30000A, &word, 1);
  p_hfFile->pConfig->szWriteProtected = (word & 0x000F) + ((word & 0xE000) >> 8);

  ReadBlock(0x30000C, &word, 1);
  p_hfFile->pConfig->szTableReadProtected =  (word & 0x000F) + ((word & 0x4000) >> 8);

  if (p_hfFile->pConfig->szCodeProtected != 0xCF)
	  p_hfFile->SChipStatus = 6;

  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Download the ID field from the PIC device, and update the PIC 
 * structure.
 *
 * @param  void
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/  
Status_t DLL_EXPORT ReadID(void)
{
  unsigned short word;
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;

  p_hfFile = &HEX_from_PIC;
  p_Stat = &Stat;

  ReadBlock(0x200000, &word, 1);
  p_hfFile->szIdValue[0] =  word & 0x00FF;
  p_hfFile->szIdValue[1] = (word & 0xFF00) >> 8;

  ReadBlock(0x200002, &word, 1);
  p_hfFile->szIdValue[2] =  word & 0x00FF;
  p_hfFile->szIdValue[3] = (word & 0xFF00) >> 8;

  ReadBlock(0x200004, &word, 1);
  p_hfFile->szIdValue[4] =  word & 0x00FF;
  p_hfFile->szIdValue[5] = (word & 0xFF00) >> 8;

  ReadBlock(0x200006, &word, 1);
  p_hfFile->szIdValue[6] =  word & 0x00FF;
  p_hfFile->szIdValue[7] = (word & 0xFF00) >> 8;

  return(0);
}

/***********************************************************************
 * Download REV+DEV from the chip present in the device chip.
 * This function fills the Hex_from_file structure, so it has
 * to be called first to initialyze the PIC structure. 
 *
 * @param  char *PICname      IN  PIC name reference (name of DLL)
 * @return Status_t               PIC_DETECTED if right PIC detected
 *                                HARDWARE_ERROR if not detected            
 **********************************************************************/  
Status_t DLL_EXPORT ReadRevDev(char *PICname)
{
  pHexFile_t p_hfFile;
  pStatistic_t p_Stat;
  unsigned short usWord, usRev, usDev;
  static unsigned int uiDetected = 0;
  char thePICname[10] = "PIC18F452";

  p_hfFile = &HEX_from_PIC;
  p_Stat = &Stat;
  p_hfFile->SChipStatus = 0;

  PowerOn();
  ReadBlock(0x3FFFFE, &usWord, 1);
  PowerOff();
  usRev =   usWord & 0x1F;
  usDev = ((usWord & 0xE0) >> 5) + ((usWord & 0xFF00) >> 5);

  if (usRev == 0x1F)
	  p_hfFile->SChipStatus = 8;

  if ((usDev & 0x07FF) == 0x21)
  {
    p_hfFile->SChipStatus = 7;
    if (uiDetected == 0)
    {
      p_hfFile->pusMemory = &MemPIC[0];
      p_hfFile->pConfig = &CFG_PIC;
      p_hfFile->uiMemorySize = _MAX_PIC_SIZE;
      memset(p_hfFile->pusMemory, 0xFF, p_hfFile->uiMemorySize * sizeof(unsigned short));
      memset(p_hfFile->pConfig, 0xFF, sizeof(pConfigWord_t));
      memset(p_hfFile->szIdValue, 0xFF, 8);
      p_hfFile->pConfig->szRev = (unsigned char)(usRev);
      p_hfFile->pConfig->usDev = usDev;
      strcpy(PICname, thePICname);
      uiDetected = 1;
    }
  }
//  else
//    uiDetected = 0;

  return(p_hfFile->SChipStatus);
}

/***********************************************************************
 * Get the ID field of the structure specify by uiFrom with the ucValue.
 * The field is 8 bytes long, so just the byte specified by ucIndex is
 * modified.
 *
 * @param  u_char *ucValue     IN  Value of the ID to get at ucIndex pos
 * @param  u_char ucIndex      IN  Index of the ID to get
 * @param  u_int uiFrom        IN  Flag (PIC or File)
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT GetIDValue(unsigned char *ucValue, unsigned char ucIndex, unsigned int uiFrom)
{
  pHexFile_t p_hfFile;
  
  if (ucIndex > 7)
	return(9);  

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  *ucValue = p_hfFile->szIdValue[ucIndex];
  return(0);
}

/***********************************************************************
 * Fill the ID field of the structure specify by uiFrom with the ucValue.
 * The field is 8 bytes long, so just the byte specified by ucIndex is
 * modified.
 *
 * @param  u_char ucValue      IN  Value of the ID to set at ucIndex pos
 * @param  u_char ucIndex      IN  Index of the ID to set
 * @param  u_int uiFrom        IN  Flag (PIC or File)
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT SetIDValue(unsigned char ucValue, unsigned char ucIndex, unsigned int uiFrom)
{
  pHexFile_t p_hfFile;
  
  if (ucIndex > 7)
	return(9);

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  p_hfFile->szIdValue[ucIndex] = ucValue;
  return(0);
}

/***********************************************************************
 * Extract the checksum info from every line of an INTEL HEX file.
 * Compare it with the value computed by the HEX parser.
 *
 * @param  u_short *usChecksum IN  Reference to the checksum computed
 * @param  u_int uiFrom        IN  Flag (PIC or File)
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT ComputeGeneralChecksum(unsigned short *usChecksum, unsigned int uiFrom)
{
  unsigned short result;
  pHexFile_t p_hfFile;

  if (uiFrom == FromPIC)
    p_hfFile = &HEX_from_PIC;
  else
    p_hfFile = &HEX_from_file;

  result =  0;

/*  if (p_hfFile->pConfig->szCodeProtected == 0xCF)*/
  result += ComputeMemChecksum(p_hfFile);

  result += ComputeConfigChecksum(p_hfFile);

/*  if (p_hfFile->pConfig->szCodeProtected != 0xCF)*/
  result += ComputeIDChecksum(p_hfFile);

  p_hfFile->usChecksum = result;
  *usChecksum = result;
  return (0);
}

/***********************************************************************
 * Check the presence of a programmer on LPT port.
 * Hardware present if DATA_FROM_PIC == DATA_TO_PIC[0 or 1]
 *
 * @param  void
 * @return Status_t                ALL_RIGHT if hardware present
 *                                 HARDWARE_ERROR if not present
 **********************************************************************/
Status_t DLL_EXPORT IsHWPresent(void)
{
  unsigned char ucHWTestON, ucHWTestOFF;

  InitHardware();
  PowerOn();
  TestIO_ON(PL_DATA_TO_PIC);
  ReadDataFromPic(&ucHWTestON);
  TestIO_OFF(PL_DATA_TO_PIC);
  ReadDataFromPic(&ucHWTestOFF);
  PowerOff();

  if ((ucHWTestON != 0) && (ucHWTestOFF == 0))
    return(0);
  else
    return(8);
}

/***********************************************************************
 * Stuck at 0 all of the signals (logical 0, not necessarily physical 0).
 *
 * @param  void
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT InitHardware(void)
{
  _InitHardware();
  return(0);
}

/***********************************************************************
 * Stuck at 1 the VCC signal (logical 1, not necessarily physical 1).
 *
 * @param  void
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT PowerOn(void)
{
  _PowerOn();
  return(0);
}

/***********************************************************************
 * Stuck at 0 the VCC signal (logical 0, not necessarily physical 0).
 *
 * @param  void
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT PowerOff(void)
{
  _PowerOff();
  return(0);
}

/***********************************************************************
 * About window of the DLL.
 *
 * @param  HWND hWnd           IN  Handle of the main window
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT ShowDLL(HWND hWnd)
{
  DLLAboutWindow_Show();
  return(0);
}

/***********************************************************************
 * Show Settings window.
 *
 * @param  HWND hWnd           IN  Handle of the main window
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT ShowSettings(HWND hWnd)
{
  SettingsWindow_Show();
  return(0);
}

/***********************************************************************
 * Display the "Config" window of the DLL.
 *
 * @param  HWND hWnd           IN  Handle of the main window
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT ShowConfig(HWND hWnd, unsigned int uiFrom)
{
  ConfigWindow_Show(uiFrom);
  return(0);
}

/***********************************************************************
 * Erase all the programmable bits of the PIC18.
 *
 * @param  HWND hWnd           IN  Handle of the main window
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT DoBulkErase(HWND hWnd)
{
  BulkErase();
  return(0);
}

/***********************************************************************
 * Set /MCLR to VDD to start the target.
 *
 * @param  HWND hWnd           IN  Handle of the main window
 * @return Status_t                Always ALL_RIGHT
 **********************************************************************/
Status_t DLL_EXPORT RunTarget(void)
{
  TestIO_ON(PL_VPP);
  return(0);
}


/* End of File */
