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

📄 stk500.cpp

📁 用于开发Atmel的AVR系列单片机的GCC集成开发环境
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************
Project: WinAVRIDE        Class: STK500 Programmer
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>
#pragma hdrstop

#include "stk500.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)
//---------------------------------------------------------------------------
#define NO_RESPONSE       0
#define STK_OK            0x10
#define STK_FAILED        0x11
#define STK_UNKNOWN       0x12
#define STK_NODEVICE      0x13
#define STK_INSYNC        0x14
#define STK_NOSYNC        0x15

#define ADC_CHANNEL_ERROR 0x16
#define ADC_MEASURE_OK    0x17
#define PWM_CHANNEL_ERROR 0x18
#define PWM_ADJUST_OK     0x19

// STK500 Protocol V2
#define STK500V2_OFFSET          5
#define CMD_SIGN_ON              0x01
#define CMD_SET_PARAMETER        0x02
#define CMD_GET_PARAMETER        0x03
#define CMD_LOAD_ADDRESS         0x06
// SPI Commands
#define CMD_ENTER_PROGMODE_ISP   0x10
#define CMD_LEAVE_PROGMODE_ISP   0x11
#define CMD_CHIP_ERASE_ISP       0x12
#define CMD_PROGRAM_FLASH_ISP    0x13
#define CMD_READ_FLASH_ISP       0x14
#define CMD_PROGRAM_EEPROM_ISP   0x15
#define CMD_READ_EEPROM_ISP      0x16
#define CMD_READ_LOCK_ISP        0x1A
#define CMD_READ_SIGNATURE_ISP   0x1B
#define CMD_READ_OSCCAL_ISP      0x1C
#define CMD_SPI_MULTI            0x1D
// Parallel Commands
#define CMD_ENTER_PROGMODE_PP    0x20
#define CMD_LEAVE_PROGMODE_PP    0x21
#define CMD_CHIP_ERASE_PP        0x22
#define CMD_PROGRAM_FLASH_PP     0x23
#define CMD_READ_FLASH_PP        0x24
#define CMD_PROGRAM_EEPROM_PP    0x25
#define CMD_READ_EEPROM_PP       0x26
#define CMD_PROGRAM_FUSE_PP      0x27
#define CMD_READ_FUSE_PP         0x28
#define CMD_PROGRAM_LOCK_PP      0x29
#define CMD_READ_LOCK_PP         0x2A
#define CMD_READ_SIGNATURE_PP    0x2B
#define CMD_READ_OSCCAL_PP       0x2C

#define CMD_SET_CONTROL_STACK    0x2D
// HV Serial Commands
#define CMD_ENTER_PROGMODE_HVSP  0x30
#define CMD_LEAVE_PROGMODE_HVSP  0x31
#define CMD_CHIP_ERASE_HVSP      0x32
#define CMD_PROGRAM_FLASH_HVSP   0x33
#define CMD_READ_FLASH_HVSP      0x34
#define CMD_PROGRAM_EEPROM_HVSP  0x35
#define CMD_READ_EEPROM_HVSP     0x36
#define CMD_PROGRAM_FUSE_HVSP    0x37
#define CMD_READ_FUSE_HVSP       0x38
#define CMD_PROGRAM_LOCK_HVSP    0x39
#define CMD_READ_LOCK_HVSP       0x3A
#define CMD_READ_SIGNATURE_HVSP  0x3B
#define CMD_READ_OSCCAL_HVSP     0x3C
// Status Responses
#define STATUS_CMD_OK            0x00
#define STATUS_CMD_TOUT          0x80
#define STATUS_RDY_BSY_TOUT      0x81
#define STATUS_SET_PARAM_MISSING 0x82
#define STATUS_CMD_FAILED        0xC0
#define STATUS_CKSUM_ERROR       0xC1
#define STATUS_CMD_UNKNOWN       0xC9
// Parameters
#define PARAM_VTARGET            0x94
#define PARAM_VADJUST            0x95
#define PARAM_OSC_PSCALE         0x96
#define PARAM_OSC_CMATCH         0x97
#define PARAM_SCK_DURATION       0x98
//---------------------------------------------------------------------------
__fastcall TSTK500::TSTK500 (TComponent* Owner)
        : TComponent(Owner)
{
 Comm = new TRS232Comm (this);
 Comm->OnRxChar = OnReceive;
 Comm->BaudRate = 115200;
 Comm->DataBits = 8;
 Comm->Parity = 'N';
 Comm->StopBits = 10;
 Comm->FlowControl = fcNone;
 Comm->NullStriping = false;
 Comm->InQSize = 1024;
 Comm->OutQSize = 1024;
}
//---------------------------------------------------------------------------
__fastcall TSTK500::~TSTK500 (void)
{
 delete Comm;
}
//---------------------------------------------------------------------------
void __fastcall TSTK500::OnReceive (DWORD Count)
{
 char buffer[1024];

 Comm->Read (rxdata + bytesrx, Count);
 if (response == NO_RESPONSE) response = buffer[0];
 //rxdata += buffer;
 bytesrx += Count;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::CheckPresence (void)
{
 char cmd[2];
 bool r = true;

 if (!Comm->Open ()) return false;
 cmd[0] = CMD_SIGN_ON;
 if (DoCommandV2 (cmd, 1, 11))
 {
  if (strstr ((char *)rxdata + 8, "STK500_2") ||
      strstr ((char *)rxdata + 8, "AVRISP_2"))
  {
   protocol = 2;
   Comm->Close ();
   Sleep (50);
   return true;
  }
 }
 else protocol = 1;
 if (!GetSync ())
 {
  Comm->Close ();
  return false;
 }
 cmd[0] = 0x31;
 cmd[1] = 0x20;
 if (!DoCommand (cmd, 2, 9))
 {
  ErrorMessage ("Can't Start Communication");
  r = false;
 }
 else
 {
  if (rxdata[0] != STK_INSYNC)
  {
   ErrorMessage ("Out of Sync on Presence Check");
   r = false;
  }
  else if (!strstr ((char *)rxdata, "AVR STK"))
  {
   ErrorMessage ("Invalid Sign on Message");
   r = false;
  }
  else if (rxdata[8] != STK_OK)
  {
   ErrorMessage ("Status Error on Presence Check");
   r = false;
  }
 }
 Comm->Close ();
 Sleep (50);
 return r;
}
//---------------------------------------------------------------------------
void __fastcall TSTK500::SetPort (AnsiString port)
{
 Comm->PortName = port;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::EnablePGM (TChipInfo *chip)
{
 char cmd[2];
 bool r = true;

 if (protocol == 2) return EnablePGMV2 (chip);
 if (!StartComm ()) return false;
 if (!SetDevParameters (chip)) return false;
 Sleep (10);
 if (!ChangeSCKLen ()) return false;
 Sleep (10);
 cmd[0] = 0x50;
 cmd[1] = 0x20;
 if (!DoCommand (cmd, 2, 2)) r = false;
 else
 {
  if (rxdata[0] != STK_INSYNC) r = false;
  else if (rxdata[1] != STK_OK) r = false;
 }
 return r;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::EnablePGMV2 (TChipInfo *chip)
{
 char cmd[16], ctrlstack[33] = {CMD_SET_CONTROL_STACK, 0x0e, 0x1e, 0x0f,  0x1e,
                              0x2e, 0x3e, 0x2f, 0x3f, 0x4e, 0x5e, 0x4f, 0x5f,
                              0x6e, 0x7e,  0x6f, 0x7f, 0x66, 0x76, 0x67, 0x77,
                              0x6a, 0x7a, 0x6b, 0x7b, 0xbe, 0xfd, 0, 1, 0, 0, 0, 0};

 if (!StartComm ()) return false;
 SetDevParameters (chip);
 if (!ChangeSCKLenV2 ()) return false;
 if (ChipInfoV2.progtype == CHIP_PROGSPI)
 {
  cmd[0] = CMD_ENTER_PROGMODE_ISP;
  cmd[1] = 200; // 200ms Command Timeout
  cmd[2] = 100; // 100ms Pin Stab Delay
  cmd[3] = 25; // Command Exe Delay
  cmd[4] = 32; // Sync Loops
  cmd[5] = 0; // Byte Delay
  cmd[6] = 0x53; // Poll Value
  cmd[7] = 3; // Poll Index
  cmd[8] = 0xAC; // Programming Enable
  cmd[9] = 0x53;
  cmd[10] = 0;
  cmd[11] = 0;
  if (!DoCommandV2 (cmd, 12, 2)) return false;
  if (rxdata[STK500V2_OFFSET] != CMD_ENTER_PROGMODE_ISP) return false;
  if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
 }
 else
 {
  if (!DoCommandV2 (ctrlstack, 33, 2)) return false;
  if (rxdata[STK500V2_OFFSET] != CMD_SET_CONTROL_STACK) return false;
  if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;

  if (ChipInfoV2.hvserial)
  {
   cmd[0] = CMD_ENTER_PROGMODE_HVSP;
   cmd[1] = 100; // Pin Stab Delay
   cmd[2] = 0; // Command Exe Delay
   cmd[3] = 10; // Sync Clock Cycles
   cmd[4] = 6; // Latch Cycles
   cmd[5] = 0; // Toggle Vtg
   cmd[6] = 0; // Power Off Delay
   cmd[7] = 0; // Reset Delay 1
   cmd[8] = 0; // Reset Delay 2
   if (!DoCommandV2 (cmd, 9, 2)) return false;
   if (rxdata[STK500V2_OFFSET] != CMD_ENTER_PROGMODE_HVSP) return false;
   if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
  }
  else
  {
   cmd[0] = CMD_ENTER_PROGMODE_PP;
   cmd[1] = 100; // Pin Stab Delay
   cmd[2] = 0; // Command Exe Delay
   cmd[3] = 6; // XTAL Cycles to Latch OSCCAL
   cmd[4] = 0; // Toggle Vtg
   cmd[5] = 0; // Power Off Delay
   cmd[6] = 0; // Reset Delay 1
   cmd[7] = 0; // Reset Delay 2
   if (!DoCommandV2 (cmd, 8, 2)) return false;
   if (rxdata[STK500V2_OFFSET] != CMD_ENTER_PROGMODE_PP) return false;
   if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
  }
 }
 return true;
}
//---------------------------------------------------------------------------
void __fastcall TSTK500::DisablePGM (void)
{
 char cmd[2];
 int i;
 bool r = true;

 if (protocol == 2)
 {
  DisablePGMV2 ();
  return;
 }
 cmd[0] = 0x51;
 cmd[1] = 0x20;
 for (i = 0;i < 10;i++)
 {
  if (!DoCommand (cmd, 2, 2)) r = false;
  else
  {
   if (rxdata[0] != STK_INSYNC) r = false;
   else if (rxdata[1] != STK_OK) r = false;
  }
  if (r) break;
  else r = true;
 }
 StopComm ();
}
//---------------------------------------------------------------------------
void __fastcall TSTK500::DisablePGMV2 (void)
{
 char cmd[3];

 if (ChipInfoV2.progtype == CHIP_PROGSPI) cmd[0] = CMD_LEAVE_PROGMODE_ISP;
 else if (ChipInfoV2.hvserial) cmd[0] = CMD_LEAVE_PROGMODE_HVSP;
 else cmd[0] = CMD_LEAVE_PROGMODE_PP;
 cmd[1] = 1; // Pre Delay (ms)
 cmd[2] = 1; // Post Delay (ms)

 DoCommandV2 (cmd, 3, 2);
 StopComm ();
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::DoCommand (unsigned char *com, int len, int num)
{
 int i;

 bytesrx = 0;

 Comm->Write (com, len);
 for (i = 0;i < 100;i++)
 {
  Application->ProcessMessages ();
  Sleep (5);
  if (bytesrx >= num)
  {
   return true;
  }
 }
 return false;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::DoCommandV2 (unsigned char *com, int len, int num)
{
 int i;
 unsigned char temp[400] = {0}, ChkSum;
 static unsigned char SeqNum = 0;

 // Prepare Message
 temp[0] = 0x1b;
 temp[1] = SeqNum++;
 temp[3] = (unsigned char)(len & 0xff);
 temp[2] = (unsigned char)((len >> 8) & 0xff);
 temp[4] = 0x0e;
 ChkSum = temp[0];
 for (i = 1;i < 5;i++) ChkSum ^= temp[i];
 for (i = 0;i < len;i++)
 {
  temp[5 + i] = *(com + i);
  ChkSum ^= temp[5 + i];
 }
 temp[5 + i] = ChkSum;
 bytesrx = 0;
 Comm->Write (temp, len + 6);
 for (i = 0;i < 100;i++)
 {
  Application->ProcessMessages ();
  Sleep (5);
  if (bytesrx >= num + 6)
  {
   rxdata[bytesrx] = 0;
   return true;
  }
 }
 return false;
}
//---------------------------------------------------------------------------
void __fastcall TSTK500::ErrorMessage (AnsiString msg)
{
 Application->MessageBox (msg.c_str(), "Error", MB_OK | MB_ICONERROR);
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::GetSignature (unsigned char *sig)
{
 char cmd[2];
 bool r = true;

 if (protocol == 2) return GetSignatureV2 (sig);
 cmd[0] = 0x75;
 cmd[1] = 0x20;
 if (!DoCommand (cmd, 2, 5))
 {
  ErrorMessage ("Can't Start Communication");
  r = false;
 }
 else
 {
  if (rxdata[0] != STK_INSYNC)
  {
   ErrorMessage ("Out of Sync on Get Signature");
   r = false;
  }
  else if (rxdata[4] != STK_OK)
  {
   ErrorMessage ("Status Error on Get Signature");
   r = false;
  }
 }
 //Comm->Close ();
 *(sig++) = rxdata[1];
 *(sig++) = rxdata[2];
 *sig = rxdata[3];
 return r;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::GetSignatureV2 (unsigned char *sig)
{
 char cmd[6];

 if (ChipInfoV2.progtype == CHIP_PROGSPI)
 { // SPI Mode
  cmd[0] = CMD_READ_SIGNATURE_ISP;
  cmd[1] = 4; // Return Address
  cmd[2] = 0x30; // Read Signature Byte
  cmd[3] = 0;
  cmd[5] = 0;
  for (cmd[4] = 0;cmd[4] < 3;cmd[4]++)
  {
   if (!DoCommandV2 (cmd, 6, 4)) return false;
   if (rxdata[STK500V2_OFFSET] != CMD_READ_SIGNATURE_ISP) return false;
   if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
   *(sig++) = rxdata[STK500V2_OFFSET + 2];
  }
 }
 else
 { // High Voltage Serial/Parallel Mode
  if (ChipInfoV2.hvserial) cmd[0] = CMD_READ_SIGNATURE_HVSP;
  else cmd[0] = CMD_READ_SIGNATURE_PP;
  for (cmd[1] = 0;cmd[1] < 3;cmd[1]++)
  {
   if (!DoCommandV2 (cmd, 2, 3)) return false;
   if (rxdata[STK500V2_OFFSET] != CMD_READ_SIGNATURE_PP &&
       rxdata[STK500V2_OFFSET] != CMD_READ_SIGNATURE_HVSP) return false;
   if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
   *(sig++) = rxdata[STK500V2_OFFSET + 2];
  }
 }
 return true;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::SetDevParameters (TChipInfo *chip)
{
 unsigned char cmd[22];
 bool r = true;
 union {int val; unsigned char byte[4];} conv;
 int i;

 if (protocol == 2)
 {
  for (i = 0;i < sizeof(TChipInfo);i++)
  {
   *((unsigned char *)&ChipInfoV2 + i) = *((unsigned char *)chip + i);
  }
  return true;
 }
 cmd[0] = 0x42;
 cmd[1] = chip->stk500_dev;
 cmd[2] = 0; // Revision
 cmd[3] = chip->progtype;
 cmd[4] = chip->parmode;
 cmd[5] = 0; //No Polling
 cmd[6] = chip->selftimed; 
 cmd[7] = chip->lockbytes;
 cmd[8] = chip->fusebytes;
 cmd[9] = 0xFF; //Flashpolval1
 cmd[10] = 0xFF; //Flashpolval2
 cmd[11] = 0; //EEPROMpolval1
 cmd[12] = 0xFF; //EEPROMpolval2;
 conv.val = chip->pagesize;
 cmd[13] = conv.byte[1];
 cmd[14] = conv.byte[0];
 conv.val = chip->eepromsize;
 cmd[15] = conv.byte[1];
 cmd[16] = conv.byte[0];
 conv.val = chip->flashsize;
 cmd[17] = conv.byte[3];
 cmd[18] = conv.byte[2];
 cmd[19] = conv.byte[1];
 cmd[20] = conv.byte[0];
 cmd[21] = 0x20;
 if (!DoCommand (cmd, 22, 2)) r = false;
 else
 {
  if (rxdata[0] != STK_INSYNC) r = false;
  else if (rxdata[1] != STK_OK) r = false;
 }
 return r;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::GetSync (void)
{
 unsigned char cmd[2];

 cmd[0] = 0x30;
 cmd[1] = 0x20;
 if (!DoCommand (cmd, 2, 2)) return false;
 else
 {
  if (rxdata[0] != STK_INSYNC) return false;
  else if (rxdata[1] != STK_OK) return false;
 }
 return true;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::LoadAddress (int adr)
{
 unsigned char cmd[4];

 if (protocol == 2) return LoadAddressV2 (adr);
 cmd[0] = 0x55;
 cmd[1] = adr & 0xff;
 cmd[2] = (adr >> 8) & 0xff;
 cmd[3] = 0x20;
 if (!DoCommand (cmd, 4, 2)) return false;
 else
 {
  if (rxdata[0] != STK_INSYNC) return false;
  else if (rxdata[1] != STK_OK) return false;
 }
 return true;
}
//---------------------------------------------------------------------------
bool __fastcall TSTK500::LoadAddressV2 (int adr)
{
 unsigned char cmd[5];

 cmd[0] = CMD_LOAD_ADDRESS;
 cmd[1] = (adr >> 24) & 0xff;
 cmd[2] = (adr >> 16) & 0xff;
 cmd[3] = (adr >> 8) & 0xff;
 cmd[4] = adr & 0xff;
 if (!DoCommandV2 (cmd, 5, 2)) return false;
 if (rxdata[STK500V2_OFFSET] != CMD_LOAD_ADDRESS) return false;
 if (rxdata[STK500V2_OFFSET + 1] != STATUS_CMD_OK) return false;
 return true;
}

⌨️ 快捷键说明

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