summaryrefslogtreecommitdiffstats
path: root/src/devices/pic/base/pic.h
blob: 7b0dfc49f4e603c1db022ab208e559ea8e23a512 (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/***************************************************************************
 *   Copyright (C) 2005-2007 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.                                   *
 ***************************************************************************/
#ifndef PIC_H
#define PIC_H

#include <qstringlist.h>
#include <qmap.h>

#include "common/global/global.h"
#include "common/common/bitvalue.h"
#include "devices/base/generic_device.h"

namespace Pic
{
class XmlToData;
class Group;
class Config;
class RegistersData;

//-----------------------------------------------------------------------------
struct VoltageData {
  double min, max, nominal;
};
inline bool operator ==(const Pic::VoltageData &v1, const Pic::VoltageData &v2) { return ( v1.min==v2.min && v1.max==v2.max && v1.nominal==v2.nominal ); }

BEGIN_DECLARE_ENUM(ProgVoltageType)
  Vpp = 0, VddBulkErase, VddWrite
END_DECLARE_ENUM_STD(ProgVoltageType)

struct CalibrationData {
  BitValue opcode, opcodeMask;
};

enum MemoryRangeTypeProperty { ReadOnly = 0, Writable = 1 };
Q_DECLARE_FLAGS(MemoryRangeTypeProperties, MemoryRangeTypeProperty)
Q_DECLARE_OPERATORS_FOR_FLAGS(MemoryRangeTypeProperties)
struct MemoryRangeTypeData {
  const char *key, *label;
  MemoryRangeTypeProperties properties;
};
BEGIN_DECLARE_ENUM(MemoryRangeType)
  Code = 0, Cal, UserId, DeviceId, Config, Eeprom, DebugVector, HardwareStack, CalBackup, ProgramExecutive
END_DECLARE_ENUM(MemoryRangeType, MemoryRangeTypeData)

BEGIN_DECLARE_ENUM(SelfWrite)
  Yes, No
END_DECLARE_ENUM_STD(SelfWrite)

BEGIN_DECLARE_ENUM(DeviceType)
  Normal, J, K
END_DECLARE_ENUM_STD(DeviceType)

struct ArchitectureData {
  const char *key, *label;
  uint nbBitsPC;                     // nb bits program counter
  uint nbBytesWord;                  // nb bytes per word (hex file and icd2)
  bool packed;                       // addressIncrement = (packed ? nbBytesWord : nbBytesWord/2)
  uint nbBitsRegister;
  uint registerBankLength;
  uint nbBits[MemoryRangeType::Nb_Types];  // nb bits per word
  bool hasAddressAccess;             // memory can be accessed randomly
  SelfWrite::Type selfWrite;
  DeviceType::Type deviceType;
};
BEGIN_DECLARE_ENUM(Architecture)
  P10X = 0, P16X, P17C, P18C, P18F, P18J, P24F, P24H, P30F, P33F
END_DECLARE_ENUM(Architecture, ArchitectureData)

enum MemoryRangeProperty { NotPresent = 0, Present = 1, Programmable = 2 };
Q_DECLARE_FLAGS(MemoryRangeProperties, MemoryRangeProperty)
Q_DECLARE_OPERATORS_FOR_FLAGS(MemoryRangeProperties)
struct MemoryRangeData {
  MemoryRangeProperties properties;
  Address start, end;
  uint hexFileOffset;
};

namespace Checksum
{
  BEGIN_DECLARE_ENUM(Algorithm)
    Normal = 0, XOR4, XNOR7, XNOR8
  END_DECLARE_ENUM_STD(Algorithm)
  class Data {
  public:
    BitValue constant;
    Algorithm algorithm;
    QStringList protectedMaskNames;
    QString bbsize;
    BitValue blankChecksum, checkChecksum;
  };
} // namespace

BEGIN_DECLARE_ENUM(Feature)
  CCP, ADC, SSP, LVD, USB, USART, CAN, ECAN, Ethernet, LCD, MotorControl,
  MotionFeedback, SelfWrite
END_DECLARE_ENUM_STD(Feature)

//-----------------------------------------------------------------------------
class Data : public Device::Data
{
public:
  Data();
  virtual ~Data();
  virtual QString fname(Device::Special special) const;
  virtual QString listViewGroup() const { return _architecture.label(); }
  bool isPresent(MemoryRangeType type) const { return (range(type).properties & Present); }
  bool isReadable(MemoryRangeType type) const;
  bool isWritable(MemoryRangeType type) const;
  uint nbAddresses(MemoryRangeType type) const;
  uint nbWords(MemoryRangeType type) const;
  uint addressIncrement(MemoryRangeType type) const;
  uint nbWordsWriteAlignment(MemoryRangeType type) const;
  MemoryRangeData range(MemoryRangeType type) const { return _ranges[type]; }
  virtual uint nbBitsAddress() const { return _nbBitsPC; }
  uint nbBitsWord(MemoryRangeType type) const { return _architecture.data().nbBits[type.type()]; }
  uint nbBytesWord(MemoryRangeType type) const { return nbBitsToNbBytes(nbBitsWord(type)); }
  uint nbCharsWord(MemoryRangeType type) const { return nbBitsToNbChars(nbBitsWord(type)); }
  BitValue mask(MemoryRangeType type) const { return uint(1 << nbBitsWord(type))-1; }
  BitValue userIdRecommendedMask() const { return _userIdRecommendedMask; }
  const Config &config() const { return *_config; }
  Architecture architecture() const { return _architecture; }
  bool is18Family() const { return ( _architecture==Architecture::P18C || _architecture==Architecture::P18F || _architecture==Architecture::P18J); }
  bool is16bitFamily() const { return ( _architecture.data().nbBitsRegister==16 ); }
  VoltageData voltage(ProgVoltageType type) const { return _voltages[type]; }
  virtual bool canWriteCalibration() const { return isWritable(MemoryRangeType::Cal); }
  bool checkCalibration(const Device::Array &data, QString *message = 0) const;
  const QMap<Device::Special, BitValue> ids() const { return _ids; }
  virtual bool matchId(BitValue rawId, Device::IdData &data) const;
  QStringList idNames(const QMap<QString, Device::IdData> &ids) const;
  const QMap<QString, Checksum::Data> checksums() const { return _checksums; }
  const RegistersData &registersData() const;
  const CalibrationData &calibrationData() const { return _calibration; }

  bool hasFeature(Feature feature, bool *unknown = 0) const;
  BitValue nopInstruction() const { return 0x0; }
  Device::Array gotoInstruction(Address address, bool withPageSelection) const;
  bool isGotoInstruction(BitValue instruction) const;

private:
  Architecture _architecture;
  QMap<Device::Special, BitValue> _ids;
  uint             _nbBitsPC;
  uint             _nbWordsCodeWrite;    // #### only for 18F/18J devices [0 for other devices]
  uint             _nbWordsCodeRowErase; // #### only for 18F/18J devices [0 for other devices or if not available]
  QMap<ProgVoltageType, VoltageData>     _voltages;
  QMap<MemoryRangeType, MemoryRangeData> _ranges;
  BitValue         _userIdRecommendedMask;
  Config          *_config;
  QMap<QString, Checksum::Data> _checksums;
  CalibrationData  _calibration;
  SelfWrite        _selfWrite;

  friend class XmlToData;
  friend class Group;
  friend QDataStream &operator <<(QDataStream &s, const Data &data);
  friend QDataStream &operator >>(QDataStream &s, Data &data);
};

QDataStream &operator <<(QDataStream &s, const Data &data);
QDataStream &operator >>(QDataStream &s, Data &data);

} // namespace

QDataStream &operator <<(QDataStream &s, const Pic::VoltageData &vd);
QDataStream &operator >>(QDataStream &s, Pic::VoltageData &vd);
QDataStream &operator <<(QDataStream &s, const Pic::MemoryRangeData &mrd);
QDataStream &operator >>(QDataStream &s, Pic::MemoryRangeData &mrd);
QDataStream &operator <<(QDataStream &s, const Pic::Checksum::Data &cd);
QDataStream &operator >>(QDataStream &s, Pic::Checksum::Data &cd);
QDataStream &operator <<(QDataStream &s, const Pic::CalibrationData &cd);
QDataStream &operator >>(QDataStream &s, Pic::CalibrationData &cd);

#endif