~ubuntu-branches/ubuntu/karmic/piklab/karmic

« back to all changes in this revision

Viewing changes to src/progs/pickit2/base/pickit.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Miriam Ruiz
  • Date: 2007-09-01 22:37:44 UTC
  • Revision ID: james.westby@ubuntu.com-20070901223744-2r8t5kiqdurs5j8g
Tags: upstream-0.14.5
ImportĀ upstreamĀ versionĀ 0.14.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org>                    *
 
3
 *                                                                         *
 
4
 *   This program is free software; you can redistribute it and/or modify  *
 
5
 *   it under the terms of the GNU General Public License as published by  *
 
6
 *   the Free Software Foundation; either version 2 of the License, or     *
 
7
 *   (at your option) any later version.                                   *
 
8
 ***************************************************************************/
 
9
#include "pickit.h"
 
10
 
 
11
#include "devices/base/device_group.h"
 
12
#include "progs/base/prog_group.h"
 
13
 
 
14
//-----------------------------------------------------------------------------
 
15
Pickit::Array::Array(uint length, uchar fillChar, PrintMode mode)
 
16
  : _fillChar(fillChar), _mode(mode), _data(length)
 
17
{
 
18
  _data.fill(fillChar);
 
19
}
 
20
 
 
21
QString Pickit::Array::pretty() const
 
22
{
 
23
  int end = _data.count() - 1;
 
24
  for (; end>=0; end--)
 
25
    if ( _data[end]!=_fillChar ) break;
 
26
  QString s;
 
27
  for (int i=0; i<=end; i++) s += toPrintable(_data[i], _mode);
 
28
  return s;
 
29
}
 
30
 
 
31
//-----------------------------------------------------------------------------
 
32
Pickit::USBPort::USBPort(uint deviceId, Log::Base &log)
 
33
  : Port::USB(log)
 
34
{
 
35
  init(Microchip::VENDOR_ID, deviceId, CONFIG_HID);
 
36
}
 
37
 
 
38
bool Pickit::USBPort::command(uchar c)
 
39
{
 
40
  Array a = array();
 
41
  a._data[0] = c;
 
42
  return command(a);
 
43
}
 
44
 
 
45
bool Pickit::USBPort::command(const char *s)
 
46
{
 
47
  Array a = array();
 
48
  if (s) {
 
49
    Q_ASSERT( strlen(s)<=a.length() );
 
50
    for (uint i=0; i<strlen(s); i++) a._data[i] = s[i];
 
51
  }
 
52
  return command(a);
 
53
}
 
54
 
 
55
bool Pickit::USBPort::command(const Array &cmd)
 
56
{
 
57
  log(Log::ExtraDebug, QString("send command: \"%1\"").arg(cmd.pretty()));
 
58
  return write(writeEndPoint(), (const char *)cmd._data.data(), cmd.length());
 
59
}
 
60
 
 
61
bool Pickit::USBPort::receive(Pickit::Array &array)
 
62
{
 
63
  if ( !read(readEndPoint(), (char *)array._data.data(), array.length()) ) return false;
 
64
  log(Log::MaxDebug, QString("received: \"%1\"").arg(array.pretty()));
 
65
  return true;
 
66
}
 
67
 
 
68
bool Pickit::USBPort::getMode(VersionData &version, ::Programmer::Mode &mode)
 
69
{
 
70
  if ( !command('v') ) return false;
 
71
  Array a = array();
 
72
  if ( !receive(a) ) return false;
 
73
  if ( a[5]=='B' ) {
 
74
    version = VersionData(a[6], a[7], 0);
 
75
    mode = ::Programmer::BootloadMode;
 
76
  } else {
 
77
    version = VersionData(a[0], a[1], a[2]);
 
78
    mode = ::Programmer::NormalMode;
 
79
  }
 
80
  return true;
 
81
}
 
82
 
 
83
bool Pickit::USBPort::receiveWords(uint nbBytesWord, uint nbRead, QValueVector<uint> &words, uint offset)
 
84
{
 
85
  log(Log::MaxDebug, QString("receive words nbBytesWord=%1 nbRead=%2 offset=%3").arg(nbBytesWord).arg(nbRead).arg(offset));
 
86
  Array a = array();
 
87
  QMemArray<uchar> data(nbRead*a.length());
 
88
  uint l = 0;
 
89
  for (uint i=0; i<nbRead; i++) {
 
90
    if ( !receive(a) ) return false;
 
91
    for (uint k=offset; k<a.length(); k++) {
 
92
      data[l] = a[k];
 
93
      l++;
 
94
    }
 
95
  }
 
96
  words.resize(data.count()/nbBytesWord);
 
97
  for (uint i=0; i<uint(words.count()); i++) {
 
98
    words[i] = 0;
 
99
    for (uint k=0; k<nbBytesWord; k++) words[i] |= data[nbBytesWord*i + k] << (8*k);
 
100
  }
 
101
  return true;
 
102
}
 
103
 
 
104
//-----------------------------------------------------------------------------
 
105
Pickit::Hardware::Hardware(::Programmer::Base &base, USBPort *port)
 
106
  : ::Programmer::PicHardware(base, port)
 
107
{}
 
108
 
 
109
bool Pickit::Hardware::internalConnectHardware()
 
110
{
 
111
  return port().open();
 
112
}
 
113
 
 
114
bool Pickit::Hardware::setTargetPower(uint v)
 
115
{
 
116
  Array cmd = port().array();
 
117
  cmd[0] = 'V';
 
118
  cmd[1] = v;
 
119
  return port().command(cmd);
 
120
}
 
121
 
 
122
bool Pickit::Hardware::writeWords(uint max, char c, uint nbBytesWord,
 
123
                                  uint &i, const Device::Array &data)
 
124
{
 
125
  Q_ASSERT( i<data.count() );
 
126
  Q_ASSERT( nbBytesWord==1 || nbBytesWord==2 );
 
127
  Array cmd = port().array();
 
128
  uint n = (nbBytesWord==1 ? 2 : 3);
 
129
  Q_ASSERT( n*max<=cmd.length() );
 
130
  for (uint k=0; k<max; k++) {
 
131
    cmd[n*k] = c;
 
132
    cmd[n*k+1] = data[i] & 0xFF;
 
133
    if ( nbBytesWord==2 ) cmd[n*k+2] = (data[i] >> 8) & 0xFF;
 
134
    i++;
 
135
    if ( i>=data.count() ) break;
 
136
  }
 
137
  return port().command(cmd);
 
138
}
 
139
 
 
140
bool Pickit::Hardware::regenerateOsccal(uint &newValue)
 
141
{
 
142
  if ( !setTargetPower(Osc2_5kHz) ) return false;
 
143
  if ( !setTargetPower(PowerOn + Osc2_5kHz) ) return false;
 
144
  Port::usleep(400000); // 400 ms
 
145
  if ( !setTargetPower(PowerOff) ) return false;
 
146
  Pickit::Array cmd = port().array();
 
147
  cmd[0] = 'P';
 
148
  cmd[1] = 'I';
 
149
  cmd[2] = 120;
 
150
  cmd[3] = 0;
 
151
  cmd[4] = 'r';
 
152
  cmd[5] = 'p';
 
153
  if ( !port().command(cmd) ) return false;
 
154
  QValueVector<uint> words;
 
155
  if ( !port().receiveWords(1, 1, words) ) return false;
 
156
  newValue = words[7] | 0x3400;
 
157
  return true;
 
158
}
 
159
 
 
160
//----------------------------------------------------------------------------
 
161
bool Pickit::DeviceSpecific::setPowerOn()
 
162
{
 
163
  return hardware().port().command(entryMode());
 
164
}
 
165
 
 
166
bool Pickit::DeviceSpecific::setPowerOff()
 
167
{
 
168
  return hardware().port().command('p');
 
169
}
 
170
 
 
171
bool Pickit::DeviceSpecific::setTargetPowerOn(bool on)
 
172
{
 
173
  return hardware().setTargetPower(on ? PowerOn : PowerOff);
 
174
}
 
175
 
 
176
//----------------------------------------------------------------------------
 
177
bool Pickit::BMDeviceSpecific::doRead(Pic::MemoryRangeType type, Device::Array &data, const ::Programmer::VerifyData *vdata)
 
178
{
 
179
  data.resize(device().nbWords(type));
 
180
  gotoMemory(type);
 
181
  QValueVector<uint> words;
 
182
  switch (type) {
 
183
    case Pic::MemoryConfig:
 
184
    case Pic::MemoryCode:
 
185
    case Pic::MemoryCal:
 
186
    case Pic::MemoryCalBackup:
 
187
    case Pic::MemoryUserId:
 
188
    case Pic::MemoryDeviceId:
 
189
      for (uint i=0; i<data.count();) {
 
190
        if ( !hardware().port().command('R') ) return false;
 
191
        if ( !hardware().port().receiveWords(2, 1, words) ) return false;
 
192
        for (uint k=0; k<uint(words.count()); k++) {
 
193
          data[i] = words[k];
 
194
          if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
 
195
          i++;
 
196
          if ( i>=data.count() ) break;
 
197
        }
 
198
      }
 
199
      break;
 
200
    case Pic::MemoryEeprom:
 
201
      for (uint i=0; i<data.count();) {
 
202
        if ( !hardware().port().command('r') ) return false; // #### not sure this is correct for Pickit1: "rrrrrrrr" used by usb_pickit
 
203
        if ( !hardware().port().receiveWords(1, 1, words) ) return false;
 
204
        for (uint k=0; k<uint(words.count()); k++) {
 
205
          data[i] = words[k];
 
206
          if ( vdata && !hardware().verifyWord(i, data[i], type, *vdata) ) return false;
 
207
          i++;
 
208
          if ( i>=data.count() ) break;
 
209
        }
 
210
      }
 
211
      break;
 
212
    case Pic::MemoryDebugVector:
 
213
    case Pic::MemoryHardwareStack:
 
214
    case Pic::MemoryProgramExecutive:
 
215
    case Pic::Nb_MemoryRangeTypes: Q_ASSERT(false); return false;
 
216
  }
 
217
  if ( type==Pic::MemoryCode || type==Pic::MemoryEeprom ) addProgress(data.count());
 
218
  return true;
 
219
}
 
220
 
 
221
bool Pickit::BMDeviceSpecific::incrementPC(uint nb)
 
222
{
 
223
  Pickit::Array cmd = hardware().port().array();
 
224
  cmd[0] = 'I';
 
225
  cmd[1] = nb & 0xFF;
 
226
  cmd[2] = (nb >> 8) & 0xFF;
 
227
  return hardware().port().command(cmd);
 
228
}
 
229
 
 
230
bool Pickit::BMDeviceSpecific::doEraseRange(Pic::MemoryRangeType type)
 
231
{
 
232
  Q_ASSERT( type==Pic::MemoryCode );
 
233
  return hardware().port().command('E');
 
234
}
 
235
 
 
236
bool Pickit::BMDeviceSpecific::doWrite(Pic::MemoryRangeType type, const Device::Array &data, bool force)
 
237
{
 
238
  // #### TODO: speed optimize...
 
239
  Q_UNUSED(force);
 
240
  gotoMemory(type);
 
241
  uint nb = nbWrites(type);
 
242
  switch (type) {
 
243
    case Pic::MemoryConfig:
 
244
    case Pic::MemoryCode:
 
245
    case Pic::MemoryCal:
 
246
    case Pic::MemoryUserId:
 
247
      for (uint i=0; i<data.count(); )
 
248
        hardware().writeWords(nb, writeCode(), 2, i, data);
 
249
      break;
 
250
    case Pic::MemoryEeprom:
 
251
      for (uint i=0; i<data.count(); )
 
252
        hardware().writeWords(nb, writeData(), 1, i, data);
 
253
      break;
 
254
    case Pic::MemoryCalBackup:
 
255
    case Pic::MemoryDeviceId:
 
256
    case Pic::MemoryDebugVector:
 
257
    case Pic::MemoryHardwareStack:
 
258
    case Pic::MemoryProgramExecutive:
 
259
    case Pic::Nb_MemoryRangeTypes: Q_ASSERT(false); return false;
 
260
  }
 
261
  if ( type==Pic::MemoryCode || type==Pic::MemoryEeprom ) addProgress(data.count());
 
262
  return true;
 
263
}
 
264
 
 
265
//----------------------------------------------------------------------------
 
266
bool Pickit::Baseline::gotoMemory(Pic::MemoryRangeType type)
 
267
{
 
268
  switch (type) {
 
269
    case Pic::MemoryConfig:
 
270
    case Pic::MemoryEeprom: return true;
 
271
    case Pic::MemoryCode:
 
272
    case Pic::MemoryCal:
 
273
    case Pic::MemoryUserId:
 
274
    case Pic::MemoryCalBackup: return incrementPC(1+device().range(type).start);
 
275
    case Pic::MemoryDeviceId:
 
276
    case Pic::MemoryDebugVector:
 
277
    case Pic::MemoryHardwareStack:
 
278
    case Pic::MemoryProgramExecutive:
 
279
    case Pic::Nb_MemoryRangeTypes: break;
 
280
  }
 
281
  Q_ASSERT(false);
 
282
  return false;
 
283
}
 
284
 
 
285
//----------------------------------------------------------------------------
 
286
bool Pickit::P16F::gotoMemory(Pic::MemoryRangeType type)
 
287
{
 
288
  Pickit::Array cmd = hardware().port().array();
 
289
  cmd[0] = 'C';
 
290
  switch (type) {
 
291
    case Pic::MemoryCode: return true;
 
292
    case Pic::MemoryEeprom: return true;
 
293
    case Pic::MemoryUserId: return hardware().port().command(cmd);
 
294
    case Pic::MemoryDeviceId:
 
295
      cmd[1] = 'I';
 
296
      cmd[2] = 0x06;
 
297
      cmd[3] = 0x00;
 
298
      return hardware().port().command(cmd);
 
299
    case Pic::MemoryConfig:
 
300
      cmd[1] = 'I';
 
301
      cmd[2] = 0x07;
 
302
      cmd[3] = 0x00;
 
303
      return hardware().port().command(cmd);
 
304
    case Pic::MemoryCal:
 
305
      if ( device().range(type).start==device().range(Pic::MemoryCode).end+1 )
 
306
        return incrementPC(device().range(type).start);
 
307
      cmd[1] = 'I';
 
308
      cmd[2] = 0x08;
 
309
      cmd[3] = 0x00;
 
310
      return hardware().port().command(cmd);
 
311
    case Pic::MemoryCalBackup:
 
312
    case Pic::MemoryDebugVector:
 
313
    case Pic::MemoryHardwareStack:
 
314
    case Pic::MemoryProgramExecutive:
 
315
    case Pic::Nb_MemoryRangeTypes: break;
 
316
  }
 
317
  Q_ASSERT(false);
 
318
  return false;
 
319
}
 
320
 
 
321
bool Pickit::P16F::doErase(bool)
 
322
{
 
323
  Pickit::Array cmd = hardware().port().array();
 
324
  cmd[0] = 'C';
 
325
  cmd[1] = writeCode();
 
326
  cmd[2] = 0xFF;
 
327
  cmd[3] = 0x3F;
 
328
  cmd[4] = 'E';
 
329
  cmd[5] = 'e';
 
330
  return hardware().port().command(cmd);
 
331
}
 
332
 
 
333
bool Pickit::P16F::doEraseRange(Pic::MemoryRangeType type)
 
334
{
 
335
  if ( type==Pic::MemoryEeprom ) return hardware().port().command('e');
 
336
  return BMDeviceSpecific::doEraseRange(type);
 
337
}