-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSRecord.cpp
148 lines (147 loc) · 3.58 KB
/
SRecord.cpp
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
#include "SRecord.h"
#include <QString>
#include <QTextStream>
namespace Fkgo
{
namespace Programmer
{
SRecord::SRecord()
{
}
SRecord::SRecord( const QByteArray& _source ) :
QByteArray(_source)
{
}
SRecord::Type SRecord::type() const
{
bool ok;
// get type from S-Record
Type _type = (Type)QString(mid(1,1)).toUInt(&ok,16);
// check for conversion error
if( !ok )
return Error;
// return S-Record type
return _type;
}
unsigned int SRecord::count() const
{
bool ok;
// get data count from S-Record
unsigned int _count = QString(mid(2,2)).toUInt(&ok,16);
// check for conversion error
if( !ok )
return 0;
// return S-Record data count
return _count;
}
unsigned int SRecord::addressCount() const
{
// check S-Record type and return corresponding address size
switch( type() )
{
case 1:
case 9:
return 2;
case 2:
case 8:
return 3;
case 3:
case 7:
return 4;
default:
return 0;
}
}
unsigned int SRecord::dataCount() const
{
return count() - addressCount() - 1;
}
unsigned long SRecord::address() const
{
bool ok;
// get address from S-Record
unsigned long _address = QString(mid(4,addressCount()*2)).toULong(&ok,16);
// check for conversion error
if( !ok )
return 0;
// return address
return _address;
}
QByteArray SRecord::data() const
{
// will be the result value
QByteArray _result;
// cache count and address length
unsigned int _dataCount = dataCount();
unsigned int _addressCount = addressCount();
// copy all data into result array
for( unsigned int i=0; i<_dataCount; ++i )
{
bool ok;
// read result byte, convert and add it to the result array
_result += QString(mid(4+(_addressCount+i)*2,2)).toUInt(&ok,16);
// check for conversion error
if( !ok )
// return empty result
return QByteArray();
}
// return result
return _result;
}
unsigned char SRecord::checksum() const
{
bool ok;
// get checksum from S-Record
unsigned char _checksum = QString(mid(4+count()*2-2,2)).toInt(&ok,16);
// check for conversion error
if( !ok )
// return empty checksum
return 0;
// return checksum
return _checksum;
}
bool SRecord::ok() const
{
// sum up all data
unsigned int _sum = 0;
{
// sum count, address and data bytes
for( int i=2; i<size()-2-2; ++i )
{
// read byte and convert and sum up
bool ok;
_sum += QString(mid(i*2,2)).toUInt(&ok,16);
// check for conversion error
if( !ok )
// checksum can not be validated
return false;
}
}
// validate checksum
return (_sum & 0xFF) == checksum();
}
QString SRecord::toString() const
{
QString _result;
QTextStream _ts(&_result);
_ts << "S" << QString::number(type(),16)
<< " " << QString::number(count(),16)
<< " " << QString::number(address(),16)
<< " " << data().toHex()
<< " " << QString::number(checksum(),16);
return *_ts.string();
}
bool SRecord::isData() const
{
switch( type() )
{
case Data16:
case Data24:
case Data32:
return true;
default:
return false;
}
}
}
}