⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 programmer.cpp

📁 用于开发Atmel的AVR系列单片机的GCC集成开发环境
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**************************************************************************
Project: WinAVRIDE        Class: Programmer Dialog
Copyright (C) 2005  Philipp Schober

This program 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 of the License, or
(at your option) any later version.

This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

History
19.Feb 2005 - First Release (V1.0)
****************************************************************************/

#include <vcl.h>
#include <stdio.h>
#pragma hdrstop

#include "Programmer.h"
#include "HexEditor.h"
#include "PrgOptions.h"

#define PGM_PAR 0
#define PGM_STK500 1
#define USE_POLLING
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "BitBox"
#pragma link "PSSlider"
#pragma resource "*.dfm"
TPgmDlg *PgmDlg;
//---------------------------------------------------------------------------
__fastcall TPgmDlg::TPgmDlg(TComponent* Owner)
        : TForm(Owner)
{
 ParPgm = new TParPgm;
 memstream = new TMemoryStream;
 STK500 = new TSTK500 (this);
 OscillatorFreq = 3670016;
 ChangedManually = false;
}
//---------------------------------------------------------------------------
__fastcall TPgmDlg::~TPgmDlg(void)
{
 delete ParPgm;
 delete memstream;
 delete STK500;
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::ShowWindow (AnsiString mcu)
{
 int i;

 eeprombufsize = 0;
 flashbufsize = 0;
 if (!ChangedManually)
 {
  for (i = 0;i < ComboBox1->Items->Count;i++)
  {
   if (ComboBox1->Items->Strings[i] == mcu)
   {
    ComboBox1->ItemIndex = i;
   }
  }
 }
 ChangeProgrammer ();
 if (ProgrammerType == PGM_STK500) TabSheet4->TabVisible = true;
 else TabSheet4->TabVisible = false;
 Sleep (10);
 ChangeDevice ();
 Position = poScreenCenter;
 SetProgPort ();
 if (ProgrammerType == PGM_PAR) if (!ParPgm->Init()) return;
 flashbuffer = new unsigned char[MAX_FLASHBUF];
 eeprombuffer = new unsigned char[MAX_EEPROMBUF];
 TrackBar1Change (this);
 ShowModal ();
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::UpdSigClick(TObject *Sender)
{
 unsigned char sig[3], cal[4] = {0};
 AnsiString temp;

 if (ProgrammerType == PGM_PAR)
 {
  if (!StartPGM ())
  {
   ErrorMessage ("Can't start Communication");
   StopPGM ();
   return;
  }
  ParPgm->GetSignature (sig);
 }
 else
 {
  if (!STK500->CheckPresence ())
  {
   ErrorMessage ("STK500 not available");
   return;
  }
  if (!STK500->EnablePGM (&chip))
  {
   ErrorMessage ("Can't start Communication");
   STK500->DisablePGM ();
   return;
  }
  STK500->GetSignature (sig);
 }
 if (sig[0] != 0x1E) ErrorMessage ("Invalid Signature\nNo Atmel Device");
 temp.printf ("%2.2X : %2.2X : %2.2X", (int)sig[0], (int)sig[1], (int)sig[2]);
 Signature->Caption = temp;
 if (chip.calibbytes > 0)
 {
  if (ProgrammerType == PGM_PAR) ParPgm->ReadCalibrationByte (0, &cal[0]);
  else STK500->ReadCalibrationByte (0, &cal[0]);
  if (chip.calibbytes > 1)
  {
   if (ProgrammerType == PGM_PAR) ParPgm->ReadCalibrationByte (1, &cal[1]);
   else STK500->ReadCalibrationByte (1, &cal[1]);
  }
  if (chip.calibbytes > 2)
  {
   if (ProgrammerType == PGM_PAR) ParPgm->ReadCalibrationByte (2, &cal[2]);
   else STK500->ReadCalibrationByte (2, &cal[2]);
  }
  if (chip.calibbytes > 3)
  {
   if (ProgrammerType == PGM_PAR) ParPgm->ReadCalibrationByte (3, &cal[3]);
   else STK500->ReadCalibrationByte (3, &cal[3]);
  }
 }
 temp.printf ("%2.2X", (int)cal[0]);
 Calib1->Caption = temp;
 temp.printf ("%2.2X", (int)cal[1]);
 Calib2->Caption = temp;
 temp.printf ("%2.2X", (int)cal[2]);
 Calib3->Caption = temp;
 temp.printf ("%2.2X", (int)cal[3]);
 Calib4->Caption = temp;
 if (ProgrammerType == PGM_PAR) StopPGM ();
 else STK500->DisablePGM ();
}
//---------------------------------------------------------------------------
bool __fastcall TPgmDlg::WriteFlashPage (void)
{
 int i, p, page, polladr, pt;
 unsigned char *buf, *pollbuf, temp[2];

 StatusLabel->Caption = "Programming Flash ...";
 buf = flashbuffer;
 Progress->Max = flashbufsize;
 Progress->Position = 0;
 Application->ProcessMessages ();
 page = chip.pagesize;
 if (ProgrammerType == PGM_STK500)
 {
  if (flashbufsize > 512) page = 128;
  else page = 32;
  if (chip.paged) page = chip.pagesize;
  STK500->LoadAddress (0);
 }

 for (p = 0;p < flashbufsize;p += page)
 {
  if (ProgrammerType == PGM_PAR)
  {
   for (i = 0;i < chip.pagesize;i++)
   {
    if (*(buf + i) != 0xff) // Search for non empty pages
    {
     polladr = p + i;
     pollbuf = buf + i;
     break;
    }
   }
   if (i < chip.pagesize) // Don't write empty pages
   {
    for (i = 0;i < chip.pagesize;i += 2)
    {
     if (*buf != 0xff || *(buf + 1) != 0xff)
     {
      if (!ParPgm->LoadPage (buf, (p + i) / 2))
      {
       ErrorMessage ("Error during Load Page");
       return false;
      }
     }
     buf += 2;
     Progress->Position = p + i;
     Application->ProcessMessages ();
    }
    if (!ParPgm->WritePage (p / 2))
    {
     ErrorMessage ("Error during Write Page");
     return false;
    }
    #ifdef USE_POLLING
    // Data Polling Flash
    pt = chip.WD_Flash / 10;
    if (pt == 0) pt = 1;
    i = 10;
    while (i--)
    {
     DelayMS (pt);
     if (ParPgm->ReadFlash (polladr / 2, temp))
     {
      if (polladr % 2)
      {
       if (temp[1] == *pollbuf) i = 0;
      }
      else if (temp[0] == *pollbuf) i = 0;
     }
    }
    #else
    DelayMS (chip.WD_Flash);
    #endif
   }
   else buf += chip.pagesize;
  }
  else
  {
   if (!STK500->WritePage (buf, page, 'F'))
   {
    ErrorMessage ("Error during Write Page");
    return false;
   }
   buf += page;
   Progress->Position = p + page;
   Application->ProcessMessages ();
  }
 }
 return true;
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::ErrorMessage (AnsiString Error)
{
 Application->MessageBox (Error.c_str (), "Error", MB_OK | MB_ICONERROR);
}
//---------------------------------------------------------------------------
bool __fastcall TPgmDlg::StartPGM (void)
{
 ParPgm->EnableBuffer (true);
 ParPgm->SetReset (true);
 if (!ParPgm->EnablePgm ()) return false;
 return true;
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::StopPGM (void)
{
 ParPgm->SetReset (false);
 ParPgm->EnableBuffer (false);
}
//---------------------------------------------------------------------------

void __fastcall TPgmDlg::FormClose(TObject *Sender, TCloseAction &Action)
{
 delete [] flashbuffer;
 delete [] eeprombuffer;
}
//---------------------------------------------------------------------------

void __fastcall TPgmDlg::LoadFlButtonClick(TObject *Sender)
{
 AnsiString temp;

 OpenDialog1->Filter = "Binary (*.bin)|*.bin|Intel Hex(*.hex)|*.hex|"
                       "Motorola SRec (*.src,*.rom)|*.src;*.rom";
 OpenDialog1->FilterIndex = 2;
 if (OpenDialog1->Execute ())
 {
  memset (flashbuffer, 0xff, MAX_FLASHBUF * sizeof(unsigned char));
  flashbufsize = LoadFileToBuffer (OpenDialog1->FileName,
                                   flashbuffer, MAX_FLASHBUF);
 }
 temp.printf ("%X", BSizeToWSize (flashbufsize));
 FlashFileSize->Caption = temp;
}
//---------------------------------------------------------------------------

void __fastcall TPgmDlg::LoadEEButtonClick(TObject *Sender)
{
 AnsiString temp;

 OpenDialog1->Filter = "Binary (*.bin)|*.bin|Intel Hex(*.hex)|*.hex|"
                       "Motorola SRec (*.src,*.rom)|*.src;*.rom|"
                       "EEProm (*.eep)|*.eep";
 OpenDialog1->FilterIndex = 4;
 if (OpenDialog1->Execute ())
 {
  eeprombufsize = LoadFileToBuffer (OpenDialog1->FileName,
                                    eeprombuffer, MAX_EEPROMBUF);
 }
 temp.printf ("%X", eeprombufsize);
 EEFileSize->Caption = temp;
}
//---------------------------------------------------------------------------
int __fastcall TPgmDlg::LoadFileToBuffer (AnsiString filename, unsigned char *buf,
                                          int maxsize)
{
 TFileStream *stream;
 int size, type, c;
 AnsiString temp;
 FILE *filestream;

 temp = ExtractFileExt (filename);
 if (!temp.AnsiCompareIC (".eep"))
 {
  filestream = fopen (filename.c_str (), "r");
  if (filestream == NULL)
  {
   ErrorMessage ("Can't open File");
   return 0;
  }
  c = fgetc (filestream);
  fclose (filestream);
  // Try to discover Filetype by first char
  if (c == (int)':') type = 1;
  else if (c == (int)'S') type = 2;
  else type = 0;
 }
 else
 {
  if (!temp.AnsiCompareIC (".bin")) type = 0;
  else if (!temp.AnsiCompareIC (".hex")) type = 1;
  else type = 2;
 }

 switch (type)
 {
  case 0: stream = new TFileStream (filename, fmOpenRead);
          if (stream == NULL)
          {
           ErrorMessage ("Can't open File");
           return 0;
          }
          if (stream->Size > maxsize)
          {
           ErrorMessage ("File is too big for Buffer");
           delete stream;
           return 0;
          }
          size = stream->Read (buf, stream->Size);
          delete stream;
          break;
  case 1: ihex = new TIHex;
          size = ihex->ReadFile (filename, buf, maxsize);
          delete ihex;
          break;
  case 2: srec = new TSRecord;
          size = srec->ReadFile (filename, buf, maxsize);
          delete srec;
          break;
 }
 return size;
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::ComboBoxKeyPress(TObject *Sender, char &Key)
{
 Key = 0;        
}
//---------------------------------------------------------------------------
void __fastcall TPgmDlg::ReadFlButtonClick(TObject *Sender)
{
 int i;
 unsigned char *buf;
 AnsiString temp;

 if (ProgrammerType == PGM_PAR)
 {
  if (!StartPGM ())
  {
   ErrorMessage ("Can't start Communication");
   StopPGM ();
   return;
  }
 }
 else
 {
  if (!STK500->CheckPresence ())
  {
   ErrorMessage ("STK500 not available");
   return;
  }
  if (!STK500->EnablePGM (&chip))
  {
   ErrorMessage ("Can't start Communication");
   STK500->DisablePGM ();
   return;
  }
 }
 DisableUIF (true);
 buf = flashbuffer;
 StatusLabel->Caption = "Reading Flash ...";
 memset (flashbuffer, 0xff, MAX_FLASHBUF * sizeof(unsigned char));
 Progress->Max = BSizeToWSize(chip.flashsize);
 if (ProgrammerType == PGM_STK500) STK500->LoadAddress (0);
 for (i = 0;i < BSizeToWSize(chip.flashsize);i++)
 {
  if (ProgrammerType == PGM_PAR) ParPgm->ReadFlash (i, buf);
  else if (!STK500->ReadPage (buf, 128, 'F'))
  {
   ErrorMessage ("Error reading Flash");
   STK500->DisablePGM ();
   DisableUIF (false);
   StatusLabel->Caption = "Ready";
   Progress->Position = 0;
   return;
  }
  if (ProgrammerType == PGM_PAR) buf += 2;
  else
  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -