summaryrefslogtreecommitdiffstats
path: root/src/progs/icd2/base/icd2_prog.cpp
blob: dbea1d312afeadc5aafd6148846535bcfce350ab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/***************************************************************************
 *   Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org>             *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/
#include "icd2_prog.h"

#include "common/global/pfile.h"
#include "progs/base/prog_config.h"
#include "devices/list/device_list.h"
#include "icd2_serial.h"
#include "icd2_usb.h"
#include "icd2_data.h"

//-----------------------------------------------------------------------------
void Icd2::ProgrammerBase::clear()
{
  Icd::ProgrammerBase::clear();
  _firmwareId = 0;
  _testData = TestData();
}

bool Icd2::ProgrammerBase::readFirmwareVersion()
{
  if ( !hardware()->setup() ) return false;
  if ( !Icd::ProgrammerBase::readFirmwareVersion() ) return false;
  _firmwareId = hardware()->getFirmwareId();
  return !hasError();
}

bool Icd2::ProgrammerBase::internalSetupHardware()
{
  ::Programmer::Config config;
  if ( !_targetSelfPowered && device()->architecture()==Pic::Architecture::P30F
       && !askContinue(i18n("It is not recommended to power dsPICs from ICD. Continue anyway?")) ) {
    logUserAbort();
    return false;
  }
  return Icd::ProgrammerBase::internalSetupHardware();
}

bool Icd2::ProgrammerBase::selfTest(bool ask)
{
  log(Log::DebugLevel::Normal, "  Self-test");
  if ( !hardware()->selfTest(_testData) ) return false;
  if ( !_testData.pass() ) {
    TQString s;
    for (uint i=0; i<TestData::Nb_VoltageTypes; i++) {
      if ( i!=0 ) s += "; ";
      s += _testData.pretty(TestData::VoltageType(i));
    }
    log(Log::LineType::Warning, i18n("Self-test failed: %1").tqarg(s));
    if ( ask && !askContinue(i18n("Self-test failed (%1). Do you want to continue anyway?").tqarg(s)) ) {
      logUserAbort();
      return false;
    }
  }
  return !hasError();
}

VersionData Icd2::ProgrammerBase::firmwareVersion(::Programmer::FirmwareVersionType type) const
{
  const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA);
  const Version &v = vd->version[_firmwareId-1];
  return VersionData(v.major, v.minor, v.dot);
}

VersionData Icd2::ProgrammerBase::mplabVersion(::Programmer::FirmwareVersionType type) const
{
  const FirmwareVersionData *vd = (type==::Programmer::FirmwareVersionType::Min ? &MIN_VERSION_DATA : &MAX_VERSION_DATA);
  return VersionData(vd->mplabMajor, vd->mplabMinor, 0);
}

bool Icd2::ProgrammerBase::setupFirmware()
{
  const FamilyData &fdata = FAMILY_DATA[family(device()->name())];
  log(Log::DebugLevel::Normal, TQString("  Firmware id is %1 and we want %2").tqarg(_firmwareId).tqarg(fdata.efid));
  if ( fdata.efid==_firmwareId ) return true;
  log(Log::LineType::Information, i18n("  Incorrect firmware loaded."));

  // find firmware file
  PURL::Directory dir = firmwareDirectory();
  if ( dir.isEmpty() ) return false;
  TQString nameFilter = "ICD" + TQString::number(fdata.efid).rightJustify(2, '0') + "??????.hex";
  TQStringList files = dir.files(nameFilter);
  if ( files.isEmpty() ) {
    log(Log::LineType::Error, i18n("Could not find firmware file \"%1\" in directory \"%2\".").tqarg(nameFilter).tqarg(dir.path()));
    return false;
  }

  // upload hex file
  PURL::Url url(dir, files[files.count()-1]);
  log(Log::DebugLevel::Normal, TQString("  Firmware file: %1").tqarg(url.pretty()));
  Log::StringView sview;
  PURL::File file(url, sview);
  if ( !file.openForRead() ) {
    log(Log::LineType::Error, i18n("Could not open firmware file \"%1\".").tqarg(url.pretty()));
    return false;
  }
  if ( !doUploadFirmware(file) ) return false;

  // check firmware
  if ( !readFirmwareVersion() ) return false;
  if ( fdata.efid!=_firmwareId ) {
    log(Log::LineType::Error, i18n("Firmware still incorrect after uploading."));
    return false;
  }
  log(Log::LineType::Information, i18n("  Firmware succesfully uploaded."));
  return true;
}

//-----------------------------------------------------------------------------
Icd2::Programmer::Programmer(const ::Programmer::Group &group, const Pic::Data *data)
  : Icd2::ProgrammerBase(group, data, "icd2_programmer")
{}

//----------------------------------------------------------------------------
Programmer::Properties Icd2::Group::properties() const
{
   return ::Programmer::Programmer | ::Programmer::HasFirmware | ::Programmer::CanUploadFirmware
     | ::Programmer::NeedDeviceSpecificFirmware | ::Programmer::CanReleaseReset
     | ::Programmer::HasSelfTest | ::Programmer::CanReadMemory | ::Programmer::HasConnectedState;
}

bool Icd2::Group::canReadVoltage(Pic::VoltageType type) const
{
  return ( type==Pic::ProgrammerVpp || type==Pic::TargetVdd || type==Pic::TargetVpp );
}

Programmer::Hardware *Icd2::Group::createHardware(::Programmer::Base &base, const ::Programmer::HardwareDescription &hd) const
{
  if ( hd.port.type==PortType::Serial ) return new SerialHardware(base, hd.port.device);
  return new USBHardware(base);
}

Programmer::DeviceSpecific *Icd2::Group::createDeviceSpecific(::Programmer::Base &base) const
{
  return new Icd::DeviceSpecific(base);
}