📄 programmer.cpp
字号:
/**************************************************************************
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 + -