/**********************************************************************/
/*                                                                    */
/* File name: Progress.c                                              */
/*                                                                    */
/* Since:     2003/20/07                                              */
/*                                                                    */
/* 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:                                                           */
/*   2003/20/07  [XM] Create this file                                */
/*                                                                    */
/**********************************************************************/

/***********************************************************************
 * INCLUDES
 **********************************************************************/
#include <vcl.h>
#include "Progress.h"
#include "Com.h"
#include <vcl\Registry.hpp>

#pragma hdrstop

/***********************************************************************
 * DEFINES
 **********************************************************************/
#define NORMAL                 0
#define ABORT                  1

/***********************************************************************
 * Function prototypes.
 **********************************************************************/
extern "C" Status_t ProgressWindow_Show(pHexFile_t p_hfFile, unsigned int Read_Write);

/***********************************************************************
 * Global variables.
 **********************************************************************/
#pragma package(smart_init)
#pragma resource "*.dfm"
TProgressWindow *ProgressWindow;

static pHexFile_t local_p_hfFile;
static unsigned int index = 0;
static unsigned int ucRetry = 0;
static unsigned int action;
static unsigned int state;

extern TRegistry *regKey;
extern unsigned int delay_IO;

/***********************************************************************
 * Window constructor.
 *
 * @param  TComponent* Owner  IN  Parent object reference
 * @return none
 **********************************************************************/
__fastcall TProgressWindow::TProgressWindow(TComponent* Owner)
    : TForm(Owner)
{
  state = NORMAL;
}

/***********************************************************************
 * Function called by ReadMem & ProgramMem functions (DLL_interface.c).
 *
 * @param  u_int Read_Write    IN  To manage a READ or WRITE transfer
 * @param  pHexFile_t p_hfFile IN  HEX structure reference
 * @return none
 **********************************************************************/
Status_t ProgressWindow_Show(pHexFile_t p_hfFile, unsigned int Read_Write)
{
  regKey->OpenKey("\\Software\\PP18\\DLL\\Settings", false);

  if (ProgressWindow == NULL)
    ProgressWindow = new TProgressWindow(Application);

  state = NORMAL;

  if (Read_Write == DISPLAY_READ)
  {
    ProgressWindow->Image1->Visible = true;
    ProgressWindow->Image2->Visible = false;
  }
  if (Read_Write == DISPLAY_WRITE)
  {
    ProgressWindow->Image2->Visible = true;
    ProgressWindow->Image1->Visible = false;
  }

  action = Read_Write;

  local_p_hfFile = p_hfFile;
  ProgressWindow->Timer1->Enabled = true;
  ProgressWindow->ProgressBar1->Max = (local_p_hfFile->uiMemorySize) / BLOCK_SIZE;
  ProgressWindow->ProgressBar1->Position = 0;
  index = 0;
  ucRetry = 0;

  ProgressWindow->ShowModal();

  if (state == ABORT)
    p_hfFile->SChipStatus = ABORTED;

  return(ALL_RIGHT);
}

/***********************************************************************
 * Cancel the operation in progress.
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TProgressWindow::ButtonCancelClick(TObject *Sender)
{
  ProgressWindow->Timer1->Enabled = false;
  ProgressWindow->ProgressBar1->Position = 0;
  index = 0;
  ucRetry = 0;

  state = ABORT;

  ProgressWindow->Close();
}

/***********************************************************************
 * Transfer the data block by block.
 * This allows the user to cancel the transfer in progress...
 *
 * @param  TObject *Sender    IN  Caller object reference
 * @return none
 **********************************************************************/
void __fastcall TProgressWindow::Timer1Timer(TObject *Sender)
{
  Statistic_t Stat;
  unsigned int step;
  unsigned short MemFile[BLOCK_SIZE];
  Timer1->Enabled = false;

  if (index < local_p_hfFile->uiMemorySize)
  {
    _InitHardware();
    _PowerOn();

    /* For READ access only */
    if (action == DISPLAY_READ)
    {
      Label1->Caption = " ";
      ReadBlock(index*2, local_p_hfFile->pusMemory + index, BLOCK_SIZE);
      index = index + BLOCK_SIZE;
      ProgressBar1->Position++;
      Label2->Caption = "Number of bytes transfered :  " + IntToStr(index*2) +
                        " / " + IntToStr(local_p_hfFile->uiMemorySize * 2);
    }
    /* For WRITE access only */
    else
    {
      Label1->Caption = "Number of retries :  " + IntToStr(ucRetry);
      /* Check if the block to transfer is blank */
      for (step = 0; step < BLOCK_SIZE; step++)
      {
        if (*(local_p_hfFile->pusMemory + index + step) != 0xFFFF)
          break;
      }

      /* If block is not blank */
      if (step != BLOCK_SIZE)
      {
        /* Block transfer */
        ProgramBlock(index*2, local_p_hfFile->pusMemory + index, BLOCK_SIZE,
                     &Stat.uiTotalTry, &Stat.uiNbWordProgrammed);
        /* Init and read block from chip */
        _InitHardware();
        _PowerOn();
        ReadBlock(index*2, MemFile, BLOCK_SIZE);
        /* If failed then we try again */
        if (memcmp(MemFile, local_p_hfFile->pusMemory + index, BLOCK_SIZE*2) != 0)
        {
          ucRetry++;
          delay_IO = delay_IO + 10;
          /* 1000 retry max */
          if (ucRetry == 1000)
          {
            local_p_hfFile->SChipStatus = BAD_PROGRAMMED;
            Label1->Caption = " ";
            Label2->Caption = " ";
            ProgressWindow->Close();
          }
        }
        else
        {
          index = index + BLOCK_SIZE;
          ProgressBar1->Position++;
        }
      }
      /* Do not transfer the block 'cause is blank */
      else
      {
        index = index + BLOCK_SIZE;
        ProgressBar1->Position++;
      }
      Label2->Caption = "Number of bytes transfered :  " + IntToStr(index*2) +
                        " / " + IntToStr(local_p_hfFile->uiMemorySize * 2);
    }
  }
  /* No more data to transfer */
  else
  {
    local_p_hfFile->SChipStatus = PROGRAMMED;
    regKey->WriteInteger("DelayIO", delay_IO);
    Label1->Caption = " ";
    Label2->Caption = " ";
    ProgressWindow->Timer1->Enabled = false;
    ProgressWindow->Close();
    return;
  }

  _InitHardware();
  Timer1->Enabled = true;
}

/* End of File */
