Mercurial > public > ostc_companion
comparison OSTCFrogOperations.cpp @ 8:21ce6187d32e
Minor changes done by automatic style checker
| author | Ideenmodellierer |
|---|---|
| date | Mon, 12 Jan 2026 13:51:17 +0000 |
| parents | 0b3630a29ad8 |
| children |
comparison
equal
deleted
inserted
replaced
| 7:0969ef86c42d | 8:21ce6187d32e |
|---|---|
| 34 // | 34 // |
| 35 ////////////////////////////////////////////////////////////////////////////// | 35 ////////////////////////////////////////////////////////////////////////////// |
| 36 | 36 |
| 37 #include "OSTCFrogOperations.h" | 37 #include "OSTCFrogOperations.h" |
| 38 | 38 |
| 39 #include "Utils/Exception.h" | |
| 39 #include "Utils/Log.h" | 40 #include "Utils/Log.h" |
| 40 #include "Utils/Exception.h" | |
| 41 | 41 |
| 42 #include "HexFile.h" | 42 #include "HexFile.h" |
| 43 #include "SettingsDialog.h" | 43 #include "SettingsDialog.h" |
| 44 | 44 |
| 45 #include <QApplication> | 45 #include <QApplication> |
| 46 #include <QDateTime> | 46 #include <QDateTime> |
| 47 #include <QProgressBar> | 47 #include <QProgressBar> |
| 48 #include <QStringList> | 48 #include <QStringList> |
| 49 | 49 |
| 50 // Byte extration, compatible littleendian or bigendian. | 50 // Byte extration, compatible littleendian or bigendian. |
| 51 #define LOW(x) ((unsigned char)((x) % 256)) | 51 #define LOW(x) ((unsigned char) ((x) % 256)) |
| 52 #define HIGH(x) ((unsigned char)((x / (1<<8)) % 256)) | 52 #define HIGH(x) ((unsigned char) ((x / (1 << 8)) % 256)) |
| 53 #define UPPER(x) ((unsigned char)((x / (1<<16)) % 256)) | 53 #define UPPER(x) ((unsigned char) ((x / (1 << 16)) % 256)) |
| 54 #define UP32(x) ((unsigned char)((x / (1<<24)) % 256)) | 54 #define UP32(x) ((unsigned char) ((x / (1 << 24)) % 256)) |
| 55 | 55 |
| 56 #define IMAGE_ROUNDING 1024 | 56 #define IMAGE_ROUNDING 1024 |
| 57 #define FIRMWARE_AREA 0x3E0000 | 57 #define FIRMWARE_AREA 0x3E0000 |
| 58 #define FIRMWARE_SIZE 0x01D000 | 58 #define FIRMWARE_SIZE 0x01D000 |
| 59 | 59 |
| 60 extern QProgressBar* progress; | 60 extern QProgressBar *progress; |
| 61 | 61 |
| 62 ////////////////////////////////////////////////////////////////////////////// | 62 ////////////////////////////////////////////////////////////////////////////// |
| 63 | 63 |
| 64 OSTCFrogOperations::OSTCFrogOperations() | 64 OSTCFrogOperations::OSTCFrogOperations() |
| 65 : _firmware(0), | 65 : _firmware(0) |
| 66 _serialNumber(0), | 66 , _serialNumber(0) |
| 67 _isOpen(false), | 67 , _isOpen(false) |
| 68 _commandMode(false) | 68 , _commandMode(false) |
| 69 { | 69 {} |
| 70 } | |
| 71 | 70 |
| 72 OSTCFrogOperations::~OSTCFrogOperations() | 71 OSTCFrogOperations::~OSTCFrogOperations() |
| 73 { | 72 { |
| 74 if( _isOpen ) | 73 if (_isOpen) |
| 75 disconnect(true); | 74 disconnect(true); |
| 76 } | 75 } |
| 77 | 76 |
| 78 ////////////////////////////////////////////////////////////////////////////// | 77 ////////////////////////////////////////////////////////////////////////////// |
| 79 /// /// | 78 /// /// |
| 80 /// PORT management /// | 79 /// PORT management /// |
| 81 /// /// | 80 /// /// |
| 82 ////////////////////////////////////////////////////////////////////////////// | 81 ////////////////////////////////////////////////////////////////////////////// |
| 83 | 82 |
| 84 //QRegExp OSTCFrogOperations::portTemplate() const | 83 //QRegExp OSTCFrogOperations::portTemplate() const |
| 84 #if 0 | |
| 85 QRegularExpression OSTCFrogOperations::portTemplate() const | 85 QRegularExpression OSTCFrogOperations::portTemplate() const |
| 86 { | 86 { |
| 87 #if defined(Q_OS_MAC) | 87 #if defined(Q_OS_MAC) |
| 88 return QRegExp("tty[.]frog.*", Qt::CaseInsensitive); | 88 return QRegExp("tty[.]frog.*", Qt::CaseInsensitive); |
| 89 #elif defined(Q_OS_LINUX) | 89 #elif defined(Q_OS_LINUX) |
| 90 // Seems ok for debian, ubuntu, and SUSE (google dixit). | 90 // Seems ok for debian, ubuntu, and SUSE (google dixit). |
| 91 // Obviously, needs the rfcomm package. "hcitool scan" or lsusb to have | 91 // Obviously, needs the rfcomm package. "hcitool scan" or lsusb to have |
| 92 // a list of connected stuff... | 92 // a list of connected stuff... |
| 93 return QRegExp("rfcomm.*", Qt::CaseInsensitive); | 93 return QRegExp("rfcomm.*", Qt::CaseInsensitive); |
| 94 #elif defined(Q_OS_WIN) | 94 #elif defined(Q_OS_WIN) |
| 95 // return QRegExp("COM.*", Qt::CaseSensitive); | 95 // return QRegExp("COM.*", Qt::CaseSensitive); |
| 96 return QRegularExpression( | 96 return QRegularExpression("COM([0-9]+)", QRegularExpression::CaseInsensitiveOption); |
| 97 "COM([0-9]+)", | |
| 98 QRegularExpression::CaseInsensitiveOption | |
| 99 ); | |
| 100 #endif | 97 #endif |
| 101 } | 98 } |
| 102 | 99 #endif |
| 100 QRegularExpression OSTCFrogOperations::portTemplate() const | |
| 101 { | |
| 102 #if defined(Q_OS_MAC) | |
| 103 // Mac-spezifischer regulärer Ausdruck | |
| 104 return QRegularExpression("tty[.]frog.*", QRegularExpression::CaseInsensitiveOption); | |
| 105 #elif defined(Q_OS_LINUX) | |
| 106 // Linux-spezifischer regulärer Ausdruck für rfcomm | |
| 107 // Funktioniert für Debian, Ubuntu, und SUSE (wie von Google beschrieben) | |
| 108 return QRegularExpression("rfcomm.*", QRegularExpression::CaseInsensitiveOption); | |
| 109 #elif defined(Q_OS_WIN) | |
| 110 // Windows-spezifischer regulärer Ausdruck für COM-Ports | |
| 111 return QRegularExpression("COM([0-9]+)", QRegularExpression::CaseInsensitiveOption); | |
| 112 #endif | |
| 113 } | |
| 103 QStringList OSTCFrogOperations::listPorts() const | 114 QStringList OSTCFrogOperations::listPorts() const |
| 104 { | 115 { |
| 105 return listBluetoothPorts(); | 116 return listBluetoothPorts(); |
| 106 } | 117 } |
| 107 | 118 |
| 127 } | 138 } |
| 128 | 139 |
| 129 HardwareOperations::CompanionFeatures OSTCFrogOperations::supported() const | 140 HardwareOperations::CompanionFeatures OSTCFrogOperations::supported() const |
| 130 { | 141 { |
| 131 // No ICON, no PARAMETER, no FIRMWARE, no DUMPSCREEN yet... | 142 // No ICON, no PARAMETER, no FIRMWARE, no DUMPSCREEN yet... |
| 132 return CompanionFeatures(NAME|DATE); | 143 return CompanionFeatures(NAME | DATE); |
| 133 } | 144 } |
| 134 | 145 |
| 135 bool OSTCFrogOperations::connect() | 146 bool OSTCFrogOperations::connect() |
| 136 { | 147 { |
| 137 try { | 148 try { |
| 138 //---- Open the serial port------------------------------------------- | 149 //---- Open the serial port------------------------------------------- |
| 139 LOG_TRACE( QString("Open port %1...").arg(Settings::port) ); | 150 LOG_TRACE(QString("Open port %1...").arg(Settings::port)); |
| 140 _isOpen = false; | 151 _isOpen = false; |
| 141 | 152 |
| 142 //---- Execute the start protocol ------------------------------------ | 153 //---- Execute the start protocol ------------------------------------ |
| 143 static char animation[] = "/-\\|"; | 154 static char animation[] = "/-\\|"; |
| 144 | 155 |
| 145 int reply = 0; | 156 int reply = 0; |
| 146 for(int retry=0; retry < 30; ++retry) { | 157 for (int retry = 0; retry < 30; ++retry) { |
| 147 _serial.open( Settings::port, "Frog"); | 158 _serial.open(Settings::port, "Frog"); |
| 148 _serial.sleep(100); | 159 _serial.sleep(100); |
| 149 _serial.purge(); | 160 _serial.purge(); |
| 150 _serial.writeByte(0xBB); | 161 _serial.writeByte(0xBB); |
| 151 try { | 162 try { |
| 152 reply = _serial.readByte(); | 163 reply = _serial.readByte(); |
| 153 if( reply == 0x4D ) | 164 if (reply == 0x4D) |
| 154 break; | 165 break; |
| 166 } catch (...) { | |
| 155 } | 167 } |
| 156 catch(...) {} | 168 LOG_TRACE(QString("Starting... %1").arg(animation[retry % sizeof animation])); |
| 157 LOG_TRACE( QString("Starting... %1").arg(animation[retry % sizeof animation])); | |
| 158 } | 169 } |
| 159 if( reply != 0x4D ) | 170 if (reply != 0x4D) |
| 160 LOG_THROW("Not started"); | 171 LOG_THROW("Not started"); |
| 161 | 172 |
| 162 //---- Enquire about Frog id ----------------------------------------- | 173 //---- Enquire about Frog id ----------------------------------------- |
| 163 getIdentity(); | 174 getIdentity(); |
| 164 | 175 |
| 165 //---- Everything is ok ---------------------------------------------- | 176 //---- Everything is ok ---------------------------------------------- |
| 166 _isOpen = true; | 177 _isOpen = true; |
| 167 return true; | 178 return true; |
| 168 } | 179 } catch (const Exception &e) { |
| 169 catch(const Exception& e) { | |
| 170 _serial.close(); | 180 _serial.close(); |
| 171 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); | 181 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); |
| 172 } | 182 } |
| 173 _isOpen = false; | 183 _isOpen = false; |
| 174 return false; | 184 return false; |
| 179 connect(); | 189 connect(); |
| 180 } | 190 } |
| 181 | 191 |
| 182 bool OSTCFrogOperations::disconnect(bool /*closing*/) | 192 bool OSTCFrogOperations::disconnect(bool /*closing*/) |
| 183 { | 193 { |
| 184 if( !_isOpen ) return false; | 194 if (!_isOpen) |
| 195 return false; | |
| 185 | 196 |
| 186 _serial.purge(); | 197 _serial.purge(); |
| 187 _serial.writeByte(0xFF); | 198 _serial.writeByte(0xFF); |
| 188 _serial.sleep(100); | 199 _serial.sleep(100); |
| 189 | 200 |
| 190 _serial.purge(); | 201 _serial.purge(); |
| 191 _serial.close(); | 202 _serial.close(); |
| 192 | 203 |
| 193 _description.clear(); // cleanup for interface updateStatus() | 204 _description.clear(); // cleanup for interface updateStatus() |
| 194 _isOpen = false; | 205 _isOpen = false; |
| 195 | 206 |
| 196 return true; | 207 return true; |
| 197 } | 208 } |
| 198 | 209 |
| 202 /// /// | 213 /// /// |
| 203 ////////////////////////////////////////////////////////////////////////////// | 214 ////////////////////////////////////////////////////////////////////////////// |
| 204 | 215 |
| 205 void OSTCFrogOperations::beginCommands() | 216 void OSTCFrogOperations::beginCommands() |
| 206 { | 217 { |
| 207 Q_ASSERT( !_commandMode ); | 218 Q_ASSERT(!_commandMode); |
| 208 static char animation[] = "/-\\|"; | 219 static char animation[] = "/-\\|"; |
| 209 for(int i=0;; ++i) | 220 for (int i = 0;; ++i) { |
| 210 { | 221 if (i == 100) // 20.0 sec loop ? |
| 211 if( i == 100 ) // 20.0 sec loop ? | |
| 212 LOG_THROW("Bad reply to open command"); | 222 LOG_THROW("Bad reply to open command"); |
| 213 | 223 |
| 214 _serial.sleep(100); | 224 _serial.sleep(100); |
| 215 _serial.purge(); | 225 _serial.purge(); |
| 216 _serial.writeByte(0xAA); // Start byte | 226 _serial.writeByte(0xAA); // Start byte |
| 217 | 227 |
| 218 int reply = 0; | 228 int reply = 0; |
| 219 try { | 229 try { |
| 220 reply = _serial.readByte(); | 230 reply = _serial.readByte(); |
| 221 } catch(...) {} | 231 } catch (...) { |
| 222 if( reply == 0x4B ) | 232 } |
| 233 if (reply == 0x4B) | |
| 223 goto Started; | 234 goto Started; |
| 224 | 235 |
| 225 LOG_TRACE(QString("Connecting %1") | 236 LOG_TRACE(QString("Connecting %1").arg(animation[i % 4])); |
| 226 .arg(animation[i%4])); | |
| 227 _serial.sleep(200); | 237 _serial.sleep(200); |
| 228 continue; | 238 continue; |
| 229 | 239 |
| 230 Started: | 240 Started: |
| 231 unsigned char buffer[] = "\xAA\xAB\xAC"; | 241 unsigned char buffer[] = "\xAA\xAB\xAC"; |
| 232 _serial.writeBlock(buffer, 3); | 242 _serial.writeBlock(buffer, 3); |
| 233 | 243 |
| 234 try { | 244 try { |
| 235 unsigned char reply = _serial.readByte(); | 245 unsigned char reply = _serial.readByte(); |
| 236 if( reply == 0x4C ) { | 246 if (reply == 0x4C) { |
| 237 _commandMode = true; | 247 _commandMode = true; |
| 238 return; | 248 return; |
| 239 } | 249 } |
| 240 } catch(...) {} | 250 } catch (...) { |
| 251 } | |
| 241 | 252 |
| 242 _serial.sleep(200); | 253 _serial.sleep(200); |
| 243 } | 254 } |
| 244 } | 255 } |
| 245 | 256 |
| 246 ////////////////////////////////////////////////////////////////////////////// | 257 ////////////////////////////////////////////////////////////////////////////// |
| 247 | 258 |
| 248 void OSTCFrogOperations::endCommands() | 259 void OSTCFrogOperations::endCommands() |
| 249 { | 260 { |
| 250 Q_ASSERT( _commandMode ); | 261 Q_ASSERT(_commandMode); |
| 251 | 262 |
| 252 _serial.sleep(100); | 263 _serial.sleep(100); |
| 253 _serial.purge(); | 264 _serial.purge(); |
| 254 _serial.writeByte(0xFF); // Exit service mode | 265 _serial.writeByte(0xFF); // Exit service mode |
| 255 _serial.sleep(10); | 266 _serial.sleep(10); |
| 256 | 267 |
| 257 unsigned char buffer = _serial.readByte(); | 268 unsigned char buffer = _serial.readByte(); |
| 258 if( buffer != 0xFF ) | 269 if (buffer != 0xFF) |
| 259 LOG_THROW("End failed"); | 270 LOG_THROW("End failed"); |
| 260 | 271 |
| 261 _commandMode = false; | 272 _commandMode = false; |
| 262 disconnect(); | 273 disconnect(); |
| 263 } | 274 } |
| 264 | 275 |
| 265 ////////////////////////////////////////////////////////////////////////////// | 276 ////////////////////////////////////////////////////////////////////////////// |
| 266 | 277 |
| 267 void OSTCFrogOperations::eraseRange(unsigned int addr, unsigned int size) | 278 void OSTCFrogOperations::eraseRange(unsigned int addr, unsigned int size) |
| 268 { | 279 { |
| 269 Q_ASSERT( _commandMode ); | 280 Q_ASSERT(_commandMode); |
| 270 | 281 |
| 271 // Convert size to number of pages, rounded up. | 282 // Convert size to number of pages, rounded up. |
| 272 size = ((size + 4095) / 4096); | 283 size = ((size + 4095) / 4096); |
| 273 if( size < 256 || addr != 0x300000 ) | 284 if (size < 256 || addr != 0x300000) { |
| 274 { | |
| 275 unsigned char buffer[4]; | 285 unsigned char buffer[4]; |
| 276 // Erase just the needed pages. | 286 // Erase just the needed pages. |
| 277 buffer[0] = UPPER(addr); | 287 buffer[0] = UPPER(addr); |
| 278 buffer[1] = HIGH(addr); | 288 buffer[1] = HIGH(addr); |
| 279 buffer[2] = LOW(addr); | 289 buffer[2] = LOW(addr); |
| 280 buffer[3] = LOW(size); | 290 buffer[3] = LOW(size); |
| 281 _serial.writeByte(0x42); // Command | 291 _serial.writeByte(0x42); // Command |
| 282 _serial.sleep(10); | 292 _serial.sleep(10); |
| 283 | 293 |
| 284 _serial.writeBlock(buffer, 4); | 294 _serial.writeBlock(buffer, 4); |
| 285 // Wait (120/4)ms by block of 4K, plus 3% VAT to be sure. | 295 // Wait (120/4)ms by block of 4K, plus 3% VAT to be sure. |
| 286 _serial.sleep(40 + size * 31); | 296 _serial.sleep(40 + size * 31); |
| 287 } | 297 } else { |
| 288 else | |
| 289 { | |
| 290 // Erase the whole 512KB of icon memory... | 298 // Erase the whole 512KB of icon memory... |
| 291 _serial.writeByte(0x41); | 299 _serial.writeByte(0x41); |
| 292 _serial.sleep(3000); | 300 _serial.sleep(3000); |
| 293 } | 301 } |
| 294 | 302 |
| 295 try { | 303 try { |
| 296 (void)_serial.readByte(); | 304 (void) _serial.readByte(); |
| 297 } catch(...) {} | 305 } catch (...) { |
| 306 } | |
| 298 } | 307 } |
| 299 | 308 |
| 300 ////////////////////////////////////////////////////////////////////////////// | 309 ////////////////////////////////////////////////////////////////////////////// |
| 301 | 310 |
| 302 void OSTCFrogOperations::startWrite(unsigned int addr) | 311 void OSTCFrogOperations::startWrite(unsigned int addr) |
| 303 { | 312 { |
| 304 Q_ASSERT( _commandMode ); | 313 Q_ASSERT(_commandMode); |
| 305 | 314 |
| 306 unsigned char buffer[3]; | 315 unsigned char buffer[3]; |
| 307 buffer[0] = UPPER(addr); | 316 buffer[0] = UPPER(addr); |
| 308 buffer[1] = HIGH(addr); | 317 buffer[1] = HIGH(addr); |
| 309 buffer[2] = LOW(addr); | 318 buffer[2] = LOW(addr); |
| 317 | 326 |
| 318 ////////////////////////////////////////////////////////////////////////////// | 327 ////////////////////////////////////////////////////////////////////////////// |
| 319 | 328 |
| 320 void OSTCFrogOperations::stopWrite() | 329 void OSTCFrogOperations::stopWrite() |
| 321 { | 330 { |
| 322 Q_ASSERT( _commandMode ); | 331 Q_ASSERT(_commandMode); |
| 323 | 332 |
| 324 _serial.flush(); | 333 _serial.flush(); |
| 325 _serial.sleep(200); // Should be > 100ms. | 334 _serial.sleep(200); // Should be > 100ms. |
| 326 | 335 |
| 327 unsigned char reply = _serial.readByte(); | 336 unsigned char reply = _serial.readByte(); |
| 328 if( reply != 0x4C ) | 337 if (reply != 0x4C) |
| 329 LOG_THROW("stopWrite"); | 338 LOG_THROW("stopWrite"); |
| 330 } | 339 } |
| 331 | 340 |
| 332 ////////////////////////////////////////////////////////////////////////////// | 341 ////////////////////////////////////////////////////////////////////////////// |
| 333 | 342 |
| 334 void OSTCFrogOperations::readBytes(unsigned int addr, | 343 void OSTCFrogOperations::readBytes(unsigned int addr, unsigned char *ptr, unsigned int size) |
| 335 unsigned char* ptr, | 344 { |
| 336 unsigned int size) | 345 Q_ASSERT(_commandMode); |
| 337 { | |
| 338 Q_ASSERT( _commandMode ); | |
| 339 | 346 |
| 340 unsigned char buffer[6]; | 347 unsigned char buffer[6]; |
| 341 buffer[0] = UPPER(addr); | 348 buffer[0] = UPPER(addr); |
| 342 buffer[1] = HIGH(addr); | 349 buffer[1] = HIGH(addr); |
| 343 buffer[2] = LOW(addr); | 350 buffer[2] = LOW(addr); |
| 350 | 357 |
| 351 _serial.writeBlock(buffer, 6); | 358 _serial.writeBlock(buffer, 6); |
| 352 _serial.sleep(10); | 359 _serial.sleep(10); |
| 353 | 360 |
| 354 unsigned int len = _serial.readBlock(ptr, size); | 361 unsigned int len = _serial.readBlock(ptr, size); |
| 355 if( len < size ) | 362 if (len < size) |
| 356 LOG_THROW("readBytes too short"); | 363 LOG_THROW("readBytes too short"); |
| 357 | 364 |
| 358 unsigned char reply = _serial.readByte(); | 365 unsigned char reply = _serial.readByte(); |
| 359 if( reply != 0x4C ) | 366 if (reply != 0x4C) |
| 360 LOG_THROW("readBytes"); | 367 LOG_THROW("readBytes"); |
| 361 } | 368 } |
| 362 | 369 |
| 363 ////////////////////////////////////////////////////////////////////////////// | 370 ////////////////////////////////////////////////////////////////////////////// |
| 364 /// /// | 371 /// /// |
| 368 | 375 |
| 369 void OSTCFrogOperations::getIdentity() | 376 void OSTCFrogOperations::getIdentity() |
| 370 { | 377 { |
| 371 //---- get model | 378 //---- get model |
| 372 HardwareDescriptor hw = hardwareDescriptor(); | 379 HardwareDescriptor hw = hardwareDescriptor(); |
| 373 if( hw != HW_UNKNOWN_OSTC && hw != HW_Frog ) | 380 if (hw != HW_UNKNOWN_OSTC && hw != HW_Frog) |
| 374 LOG_THROW("Not a Frog."); | 381 LOG_THROW("Not a Frog."); |
| 375 | 382 |
| 376 //---- get identity | 383 //---- get identity |
| 377 _serial.sleep(100); // Make sure last command is finished. | 384 _serial.sleep(100); // Make sure last command is finished. |
| 378 _serial.purge(); | 385 _serial.purge(); |
| 379 _serial.writeByte('i'); // 0x63 | 386 _serial.writeByte('i'); // 0x63 |
| 380 | 387 |
| 381 unsigned char buffer[1+2+2+13+1] = {0}; | 388 unsigned char buffer[1 + 2 + 2 + 13 + 1] = {0}; |
| 382 unsigned len = _serial.readBlock(buffer, sizeof buffer); | 389 unsigned len = _serial.readBlock(buffer, sizeof buffer); |
| 383 | 390 |
| 384 if( len != sizeof buffer || buffer[0] != 'i' || buffer[18] != 0x4D ) | 391 if (len != sizeof buffer || buffer[0] != 'i' || buffer[18] != 0x4D) |
| 385 LOG_THROW("get identity data"); | 392 LOG_THROW("get identity data"); |
| 386 | 393 |
| 387 _serialNumber = buffer[1] + buffer[2]*256; | 394 _serialNumber = buffer[1] + buffer[2] * 256; |
| 388 _firmware = buffer[3]*256 + buffer[4]; | 395 _firmware = buffer[3] * 256 + buffer[4]; |
| 389 | 396 |
| 390 _description = QString("%1 #%2, v%3.%4, %5") | 397 _description |
| 391 .arg(model()) | 398 = QString("%1 #%2, v%3.%4, %5") |
| 392 .arg(_serialNumber, 4, 10, QChar('0')) | 399 .arg(model()) |
| 393 .arg(_firmware / 256).arg(_firmware % 256) | 400 .arg(_serialNumber, 4, 10, QChar('0')) |
| 394 .arg( QString::fromLatin1((char*)buffer+5, 13) | 401 .arg(_firmware / 256) |
| 395 .replace(QChar('\0'), "") | 402 .arg(_firmware % 256) |
| 396 .trimmed() ); | 403 .arg(QString::fromLatin1((char *) buffer + 5, 13).replace(QChar('\0'), "").trimmed()); |
| 397 | 404 |
| 398 LOG_TRACE("Found " << _description); | 405 LOG_TRACE("Found " << _description); |
| 399 } | 406 } |
| 400 | 407 |
| 401 ////////////////////////////////////////////////////////////////////////////// | 408 ////////////////////////////////////////////////////////////////////////////// |
| 402 | 409 |
| 403 void OSTCFrogOperations::writeText(const QString& _msg) | 410 void OSTCFrogOperations::writeText(const QString &_msg) |
| 404 { | 411 { |
| 405 // Pad to 15 chars: | 412 // Pad to 15 chars: |
| 406 QByteArray ascii = (_msg + QString(15, QChar(' '))).left(15).toLatin1(); | 413 QByteArray ascii = (_msg + QString(15, QChar(' '))).left(15).toLatin1(); |
| 407 | 414 |
| 408 _serial.sleep(100); // Make sure last command is finished. | 415 _serial.sleep(100); // Make sure last command is finished. |
| 409 _serial.purge(); | 416 _serial.purge(); |
| 410 _serial.writeByte('n'); // 0x6E | 417 _serial.writeByte('n'); // 0x6E |
| 411 | 418 |
| 412 unsigned char reply = _serial.readByte(); | 419 unsigned char reply = _serial.readByte(); |
| 413 if( reply != 'n' ) | 420 if (reply != 'n') |
| 414 LOG_THROW("message start"); | 421 LOG_THROW("message start"); |
| 415 | 422 |
| 416 _serial.writeBlock((unsigned char *)ascii.constData(), 15); | 423 _serial.writeBlock((unsigned char *) ascii.constData(), 15); |
| 417 reply = _serial.readByte(); | 424 reply = _serial.readByte(); |
| 418 if( reply != 0x4D ) | 425 if (reply != 0x4D) |
| 419 LOG_THROW("message end"); | 426 LOG_THROW("message end"); |
| 420 } | 427 } |
| 421 | 428 |
| 422 ////////////////////////////////////////////////////////////////////////////// | 429 ////////////////////////////////////////////////////////////////////////////// |
| 423 | 430 |
| 429 buffer[2] = date.time().second(); | 436 buffer[2] = date.time().second(); |
| 430 buffer[3] = date.date().month(); | 437 buffer[3] = date.date().month(); |
| 431 buffer[4] = date.date().day(); | 438 buffer[4] = date.date().day(); |
| 432 buffer[5] = date.date().year() % 100; | 439 buffer[5] = date.date().year() % 100; |
| 433 | 440 |
| 434 _serial.sleep(100); // Make sure last command is finished. | 441 _serial.sleep(100); // Make sure last command is finished. |
| 435 _serial.purge(); | 442 _serial.purge(); |
| 436 _serial.writeByte('b'); // 0x62 | 443 _serial.writeByte('b'); // 0x62 |
| 437 | 444 |
| 438 unsigned char reply = _serial.readByte(); | 445 unsigned char reply = _serial.readByte(); |
| 439 if( reply != 'b' ) | 446 if (reply != 'b') |
| 440 LOG_THROW("sync time"); | 447 LOG_THROW("sync time"); |
| 441 | 448 |
| 442 _serial. writeBlock( buffer, sizeof buffer); | 449 _serial.writeBlock(buffer, sizeof buffer); |
| 443 reply = _serial.readByte(); | 450 reply = _serial.readByte(); |
| 444 if( reply != 0x4D ) | 451 if (reply != 0x4D) |
| 445 LOG_THROW("sync time end"); | 452 LOG_THROW("sync time end"); |
| 446 | 453 |
| 447 writeText("Set " + date.toString("MM/dd hh:mm")); | 454 writeText("Set " + date.toString("MM/dd hh:mm")); |
| 448 } | 455 } |
| 449 | 456 |
| 456 | 463 |
| 457 ////////////////////////////////////////////////////////////////////////////// | 464 ////////////////////////////////////////////////////////////////////////////// |
| 458 | 465 |
| 459 void OSTCFrogOperations::setName(const QString &newName) | 466 void OSTCFrogOperations::setName(const QString &newName) |
| 460 { | 467 { |
| 461 QByteArray padded = (newName+QString(13, QChar(' '))).left(13).toLatin1(); | 468 QByteArray padded = (newName + QString(13, QChar(' '))).left(13).toLatin1(); |
| 462 | 469 |
| 463 _serial.sleep(100); // Make sure last command is finished. | 470 _serial.sleep(100); // Make sure last command is finished. |
| 464 _serial.purge(); | 471 _serial.purge(); |
| 465 _serial.writeByte('c'); // 0x63 | 472 _serial.writeByte('c'); // 0x63 |
| 466 | 473 |
| 467 unsigned char reply = _serial.readByte(); | 474 unsigned char reply = _serial.readByte(); |
| 468 if( reply != 'c' ) | 475 if (reply != 'c') |
| 469 LOG_THROW("set custom text"); | 476 LOG_THROW("set custom text"); |
| 470 | 477 |
| 471 _serial.writeBlock((unsigned char*)padded.constData(), 13); | 478 _serial.writeBlock((unsigned char *) padded.constData(), 13); |
| 472 reply = _serial.readByte(); | 479 reply = _serial.readByte(); |
| 473 if( reply != 0x4D ) | 480 if (reply != 0x4D) |
| 474 LOG_THROW("custom text end"); | 481 LOG_THROW("custom text end"); |
| 475 | 482 |
| 476 // Re-read new name: | 483 // Re-read new name: |
| 477 getIdentity(); | 484 getIdentity(); |
| 478 writeText(customText()); | 485 writeText(customText()); |
| 479 } | 486 } |
| 480 | 487 |
| 481 ////////////////////////////////////////////////////////////////////////////// | 488 ////////////////////////////////////////////////////////////////////////////// |
| 482 | 489 |
| 483 void OSTCFrogOperations::setIcons(const QString &/*fileName*/) | 490 void OSTCFrogOperations::setIcons(const QString & /*fileName*/) |
| 484 { | 491 { |
| 485 // beginCommands(); | 492 // beginCommands(); |
| 486 // eraseRange(0x000000, 0x00000); | 493 // eraseRange(0x000000, 0x00000); |
| 487 // startWrite(0x000000); | 494 // startWrite(0x000000); |
| 488 // stopWrite(); | 495 // stopWrite(); |
| 489 // endCommands(); | 496 // endCommands(); |
| 490 | 497 |
| 491 LOG_THROW( "Set icons: Not yet implemented." ); | 498 LOG_THROW("Set icons: Not yet implemented."); |
| 492 } | 499 } |
| 493 | 500 |
| 494 int OSTCFrogOperations::firmware() const | 501 int OSTCFrogOperations::firmware() const |
| 495 { | 502 { |
| 496 return _firmware; | 503 return _firmware; |
| 506 return _description.section(',', 2).trimmed(); | 513 return _description.section(',', 2).trimmed(); |
| 507 } | 514 } |
| 508 | 515 |
| 509 /////////////////////////////////////////////////////////////////////////////// | 516 /////////////////////////////////////////////////////////////////////////////// |
| 510 | 517 |
| 511 static unsigned char frogSecretKey[16] = { | 518 static unsigned char frogSecretKey[16] |
| 512 111, 85, 190, 69, | 519 = {111, 85, 190, 69, 108, 254, 242, 19, 231, 49, 248, 255, 233, 48, 176, 241}; |
| 513 108,254, 242, 19, | |
| 514 231, 49, 248,255, | |
| 515 233, 48, 176,241 | |
| 516 }; | |
| 517 | 520 |
| 518 void OSTCFrogOperations::loadFirmware(HexFile &hex, const QString &fileName) const | 521 void OSTCFrogOperations::loadFirmware(HexFile &hex, const QString &fileName) const |
| 519 { | 522 { |
| 520 hex.allocate(FIRMWARE_SIZE); | 523 hex.allocate(FIRMWARE_SIZE); |
| 521 hex.loadEncrypted(fileName, frogSecretKey); | 524 hex.loadEncrypted(fileName, frogSecretKey); |
| 543 buffer[2] = UPPER(checksum); | 546 buffer[2] = UPPER(checksum); |
| 544 buffer[3] = UP32(checksum); | 547 buffer[3] = UP32(checksum); |
| 545 | 548 |
| 546 // Compute magic checksum's checksum. | 549 // Compute magic checksum's checksum. |
| 547 buffer[4] = 0x55; | 550 buffer[4] = 0x55; |
| 548 buffer[4] ^= buffer[0]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7); | 551 buffer[4] ^= buffer[0]; |
| 549 buffer[4] ^= buffer[1]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7); | 552 buffer[4] = (buffer[4] << 1 | buffer[4] >> 7); |
| 550 buffer[4] ^= buffer[2]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7); | 553 buffer[4] ^= buffer[1]; |
| 551 buffer[4] ^= buffer[3]; buffer[4] =(buffer[4]<<1 | buffer[4]>>7); | 554 buffer[4] = (buffer[4] << 1 | buffer[4] >> 7); |
| 552 | 555 buffer[4] ^= buffer[2]; |
| 553 _serial.sleep(100); // Make sure last command is finished. | 556 buffer[4] = (buffer[4] << 1 | buffer[4] >> 7); |
| 557 buffer[4] ^= buffer[3]; | |
| 558 buffer[4] = (buffer[4] << 1 | buffer[4] >> 7); | |
| 559 | |
| 560 _serial.sleep(100); // Make sure last command is finished. | |
| 554 _serial.purge(); | 561 _serial.purge(); |
| 555 _serial.writeByte('P'); // 0x50 | 562 _serial.writeByte('P'); // 0x50 |
| 556 | 563 |
| 557 unsigned char reply = _serial.readByte(); | 564 unsigned char reply = _serial.readByte(); |
| 558 if( reply != 'P' ) | 565 if (reply != 'P') |
| 559 LOG_THROW( "Programming start" ); | 566 LOG_THROW("Programming start"); |
| 560 | 567 |
| 561 _serial.writeBlock(buffer, sizeof buffer); | 568 _serial.writeBlock(buffer, sizeof buffer); |
| 562 _serial.sleep(4000); | 569 _serial.sleep(4000); |
| 563 | 570 |
| 564 // NOTE: the device never return, because it always to a reset, | 571 // NOTE: the device never return, because it always to a reset, |
| 565 // with ot without reprogramming... | 572 // with ot without reprogramming... |
| 566 _serial.close(); | 573 _serial.close(); |
| 567 _isOpen = false; | 574 _isOpen = false; |
| 568 } | 575 } catch (const Exception &e) { |
| 569 catch(const Exception& e) { | 576 LOG_TRACE(QString("Cannot upgrade: <font color='red'>%1</font>").arg(e.what())); |
| 570 LOG_TRACE(QString("Cannot upgrade: <font color='red'>%1</font>") | |
| 571 .arg(e.what())); | |
| 572 | 577 |
| 573 // Unknown state: so make a hard cleanup: | 578 // Unknown state: so make a hard cleanup: |
| 574 _commandMode = false; | 579 _commandMode = false; |
| 575 _isOpen = false; | 580 _isOpen = false; |
| 576 _serial.close(); | 581 _serial.close(); |
