-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.cpp
187 lines (184 loc) · 5.54 KB
/
main.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
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
180
181
182
183
184
185
186
187
#include "Connection.h"
#include "MotFile.h"
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>
#include <QString>
#include <QFileInfo>
#include <QDateTime>
#define HEX(x) QString::number(x,16)
QString progress( int _cur, int _max, int _len )
{
int _step = _max/_len;
return QString() + "[" + QString(_cur/_step+1,'#') + QString(_max/_step-_cur/_step-1,'.') + "] " + QString::number(100*_cur/_max+1) + "%";
}
/** @brief main routine
* @param _argc argument count
* @param _argv argument array
* @return exit value
*/
int main(int _argc, char *_argv[])
{
// make application instance
QCoreApplication _a(_argc, _argv);
{
_a.setApplicationName("flash-renesas");
_a.setApplicationVersion("0.4");
}
// initialize argument parser
QCommandLineParser _parser;
{
_parser.setApplicationDescription("M16C flash utility");
_parser.addHelpOption();
_parser.addVersionOption();
_parser.addPositionalArgument("mot", QCoreApplication::translate("main", "MOT file to flash."));
_parser.addPositionalArgument("port", QCoreApplication::translate("main", "Serial port to connect."));
_parser.addPositionalArgument("id", QCoreApplication::translate("main", "Flash ID (default: 00:00:00:00:00:00:00 or ff:ff:ff:ff:ff:ff:ff)"),"[id]");
}
// Process the actual command line arguments given by the user
_parser.process(_a);
QTextStream _out(stdout);
QTextStream _err(stderr);
// get positional arguments
QStringList _args = _parser.positionalArguments();
// check minimum argument count
if( _args.size() > 3 )
{
// to few parameters
_err << "ERROR: too many parameters" << endl;
// exit program
exit(-1);
}
QString _mot;
QString _port;
{
if( _args.size() >= 1 )
_mot = _args[0];
else
{
// to few parameters
_err << "ERROR: too few parameters" << endl;
exit(-1);
}
if( _args.size() >= 2 )
_port = _args[1];
}
QByteArray _id;
if( _args.size() > 2 )
{
// split argument into hopefully seven hexadecimal strings
QStringList _ids = _args[2].split(':');
// convert hexadecimal strings into a number array
bool ok = true;
for( int i=0; i<_ids.size() && ok; ++i )
_id += _ids[i].toInt(&ok,16);
// check if there wern't seven bytes
if( !ok || _id.size() != 7 )
{
// invalid ID
_err << "ERROR: invalid ID" << endl;
// exit program
exit(-1);
}
}
using namespace Fkgo::Programmer;
{
QFileInfo info(_mot);
_out << "Opening MOT file: '" << info.fileName() << "' " << info.lastModified().toString() << endl;
}
MotFile file(_mot);
if( !file.open(QIODevice::ReadOnly | QIODevice::Text) )
{
_err << "ERROR: MOT file not found" << endl;
exit(-1);
}
if( file.read().type() != SRecord::Header )
{
_err << "ERROR: unexpected file format" << endl;
exit(-1);
}
// create connection to the port given by parameter
Connection _c;
if( !_port.isEmpty() )
{
_out << "opening connection to port " << _port << endl;
// create connection to the port given by parameter
_c.open(_port,Connection::M16C);
// connect to the microcontroller
if( Connection::Ready != _c.autoBaud() )
{
_err << "ERROR: cannot connect" << endl;
exit(-1);
}
if( Connection::Ready != _c.baudRate() )
{
_err << "ERROR: cannot negotiate baud rate" << endl;
_out << "No response at 9600 baud. You may reset the controller and try again." << endl;
exit(-1);
}
_out << "negotiated baud rate: " << _c.baud() << endl;
// get version
QString _version;
if( Connection::Ready != _c.version(_version) )
{
_err << "ERROR: cannot get version" << endl;
exit(-1);
}
_out << "remote version: " << _version << endl;
// unlock the microcontroller with the ID given by argument
if( _id.isEmpty() )
{
_id = QByteArray(7,0);
if( Connection::Locked == _c.unlock(_id) )
{
_id = QByteArray(7,0xff);
if( Connection::Ready != _c.unlock(_id) )
{
_err << "ERROR: unlocking failed" << endl;
exit(-1);
}
}
}
else if( Connection::Ready != _c.unlock(_id) )
{
_err << "ERROR: unlocking failed" << endl;
exit(-1);
}
_out << "unlocked with: " << _id.toHex() << endl;
// eraseAll
_out << "erasing flash memory..." << endl;
if( Connection::Ready != _c.eraseAll() )
{
_err << "ERROR: erasing flash memory failed" << endl;
exit(-1);
}
}
QByteArray _image;
// blank page
const QByteArray _blank(0x100,0xff);
unsigned long _start = file.readImage(_image);
_out << "Writing image from " << HEX(_start) << " to " << HEX(_start+_image.size()-1) << " = " << _image.size()/1024 << "KB" << endl;
unsigned long _count=0;
for( int _cur = 0; _cur < _image.size(); _cur += 0x100 )
{
QByteArray _page = _image.mid(_cur, 0x100);
if( _page != _blank )
{
if( !_port.isEmpty() )
{
_out << "\rWriting page at address " << HEX(_start + _cur) << " " << progress(_cur,_image.size(),60) << " \b\b\b\b" << flush;
// program current page
if( Connection::Ready != _c.programPage( _start + _cur, _page ) )
{
_err << "ERROR: programming page failed" << endl;
exit(-1);
}
}
else
_out << HEX(_start + _cur) << ": " << _page.left(16).toHex() << "..." << _page.right(16).toHex() << endl;
_count++;
}
}
_out << "\n" << _count << " relevant pages = " << (_count*0x100)/1024 << "KB" << endl;
return 0;//_a.exec();
}