Mercurial > public > ostc_companion
comparison OSTC2cOperations.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 |
|---|---|
| 46 #include "Utils/ProgressEvent.h" | 46 #include "Utils/ProgressEvent.h" |
| 47 | 47 |
| 48 #include <QDateTime> | 48 #include <QDateTime> |
| 49 #include <QRegularExpression> | 49 #include <QRegularExpression> |
| 50 | 50 |
| 51 #define FIRMWARE_SIZE 0x17F40 | 51 #define FIRMWARE_SIZE 0x17F40 |
| 52 | 52 |
| 53 // 64 bytes on Mk.2/2n/2c: | 53 // 64 bytes on Mk.2/2n/2c: |
| 54 #define FIRMWARE_BLOCK_SIZE 0x40 | 54 #define FIRMWARE_BLOCK_SIZE 0x40 |
| 55 | 55 |
| 56 ////////////////////////////////////////////////////////////////////////////// | 56 ////////////////////////////////////////////////////////////////////////////// |
| 57 | 57 |
| 58 OSTC2cOperations::OSTC2cOperations() | 58 OSTC2cOperations::OSTC2cOperations() |
| 59 : HardwareOperations(), | 59 : HardwareOperations() |
| 60 _computerFirmware(0), | 60 , _computerFirmware(0) |
| 61 _computerSerial(0) | 61 , _computerSerial(0) |
| 62 { | 62 {} |
| 63 } | |
| 64 | 63 |
| 65 ////////////////////////////////////////////////////////////////////////////// | 64 ////////////////////////////////////////////////////////////////////////////// |
| 66 | 65 |
| 67 void OSTC2cOperations::readBank0(byte bank0[]) | 66 void OSTC2cOperations::readBank0(byte bank0[]) |
| 68 { | 67 { |
| 76 { | 75 { |
| 77 _serial.sleep(100); | 76 _serial.sleep(100); |
| 78 _serial.purge(); | 77 _serial.purge(); |
| 79 _serial.writeByte('d'); | 78 _serial.writeByte('d'); |
| 80 int reply = _serial.readByte(); | 79 int reply = _serial.readByte(); |
| 81 if( reply != 'd' ) | 80 if (reply != 'd') |
| 82 LOG_THROW("Write start"); | 81 LOG_THROW("Write start"); |
| 83 | 82 |
| 84 for(int a=4; a<256; ++a) { | 83 for (int a = 4; a < 256; ++a) { |
| 85 _serial.writeByte(bank0[a]); | 84 _serial.writeByte(bank0[a]); |
| 86 reply = _serial.readByte(); | 85 reply = _serial.readByte(); |
| 87 if( reply != bank0[a] ) | 86 if (reply != bank0[a]) |
| 88 LOG_THROW("Write bank0 @ " << a); | 87 LOG_THROW("Write bank0 @ " << a); |
| 89 } | 88 } |
| 90 | 89 |
| 91 _serial.sleep(500); // Allow OSTC2c some time to reboot | 90 _serial.sleep(500); // Allow OSTC2c some time to reboot |
| 92 } | 91 } |
| 109 | 108 |
| 110 //---- Get a memory dump: | 109 //---- Get a memory dump: |
| 111 try { | 110 try { |
| 112 readBank0(bank0); | 111 readBank0(bank0); |
| 113 readBank1(bank1); | 112 readBank1(bank1); |
| 114 } catch(ReadTimeout) { | 113 } catch (ReadTimeout) { |
| 115 LOG_THROW("No reply from OSTC Mk.2, 2n or 2c..."); | 114 LOG_THROW("No reply from OSTC Mk.2, 2n or 2c..."); |
| 116 } | 115 } |
| 117 | 116 |
| 118 // Sanity check: | 117 // Sanity check: |
| 119 if( bank0[65] == 0xFF || bank1[1] > 99 || bank1[2] > 99 ) | 118 if (bank0[65] == 0xFF || bank1[1] > 99 || bank1[2] > 99) |
| 120 LOG_THROW("Not an OSTC Mk.2, 2n or 2c..."); | 119 LOG_THROW("Not an OSTC Mk.2, 2n or 2c..."); |
| 121 | 120 |
| 122 _computerSerial = bank0[0] + bank0[1]*256; | 121 _computerSerial = bank0[0] + bank0[1] * 256; |
| 123 _computerFirmware = bank1[1] * 100 + bank1[2]; | 122 _computerFirmware = bank1[1] * 100 + bank1[2]; |
| 124 _customText = QString::fromLatin1((char*)bank0+65, 25).section('}', 0,0); | 123 _customText = QString::fromLatin1((char *) bank0 + 65, 25).section('}', 0, 0); |
| 125 | 124 |
| 126 _description = QString("%1 #%2, v%3.%4, %5") | 125 _description = QString("%1 #%2, v%3.%4, %5") |
| 127 .arg(model()) | 126 .arg(model()) |
| 128 .arg(_computerSerial) | 127 .arg(_computerSerial) |
| 129 .arg(bank1[1]).arg(bank1[2], 2, 10, QChar('0')) | 128 .arg(bank1[1]) |
| 130 .arg( _customText ); | 129 .arg(bank1[2], 2, 10, QChar('0')) |
| 130 .arg(_customText); | |
| 131 } | 131 } |
| 132 | 132 |
| 133 int OSTC2cOperations::firmware() const | 133 int OSTC2cOperations::firmware() const |
| 134 { | 134 { |
| 135 return _computerFirmware; | 135 return _computerFirmware; |
| 160 } | 160 } |
| 161 #endif | 161 #endif |
| 162 QRegularExpression OSTC2cOperations::portTemplate() const | 162 QRegularExpression OSTC2cOperations::portTemplate() const |
| 163 { | 163 { |
| 164 #if defined(Q_OS_MAC) | 164 #if defined(Q_OS_MAC) |
| 165 return QRegularExpression("tty.usbserial-.*", | 165 return QRegularExpression("tty.usbserial-.*", QRegularExpression::CaseInsensitiveOption); |
| 166 QRegularExpression::CaseInsensitiveOption); | |
| 167 #elif defined(Q_OS_LINUX) | 166 #elif defined(Q_OS_LINUX) |
| 168 return QRegularExpression("ttyUSB.*"); // default: case-sensitive | 167 return QRegularExpression("ttyUSB.*"); // default: case-sensitive |
| 169 #elif defined(Q_OS_WIN) | 168 #elif defined(Q_OS_WIN) |
| 170 return QRegularExpression("COM.*"); // default: case-sensitive | 169 return QRegularExpression("COM.*"); // default: case-sensitive |
| 171 #endif | 170 #endif |
| 172 } | 171 } |
| 173 QStringList OSTC2cOperations::listPorts() const | 172 QStringList OSTC2cOperations::listPorts() const |
| 174 { | 173 { |
| 175 return listUSBPorts(); | 174 return listUSBPorts(); |
| 190 ////////////////////////////////////////////////////////////////////////////// | 189 ////////////////////////////////////////////////////////////////////////////// |
| 191 | 190 |
| 192 HardwareOperations::CompanionFeatures OSTC2cOperations::supported() const | 191 HardwareOperations::CompanionFeatures OSTC2cOperations::supported() const |
| 193 { | 192 { |
| 194 // No ICON. | 193 // No ICON. |
| 195 return CompanionFeatures(PARAMETERS|DATE|NAME|DUMPSCREEN|FIRMWARE | 194 return CompanionFeatures(PARAMETERS | DATE | NAME | DUMPSCREEN | FIRMWARE | HELIUM_DIVE |
| 196 |HELIUM_DIVE|CCR_DIVE); | 195 | CCR_DIVE); |
| 197 } | 196 } |
| 198 | 197 |
| 199 ////////////////////////////////////////////////////////////////////////////// | 198 ////////////////////////////////////////////////////////////////////////////// |
| 200 | 199 |
| 201 QString OSTC2cOperations::firmwareTemplate() const | 200 QString OSTC2cOperations::firmwareTemplate() const |
| 210 try { | 209 try { |
| 211 LOG_TRACE("Connecting " << Settings::port); | 210 LOG_TRACE("Connecting " << Settings::port); |
| 212 _serial.open(Settings::port, "OSTC2c"); | 211 _serial.open(Settings::port, "OSTC2c"); |
| 213 getIdentity(); | 212 getIdentity(); |
| 214 return true; | 213 return true; |
| 215 } | 214 } catch (const Exception &e) { |
| 216 catch(const Exception& e){ | |
| 217 _serial.close(); | 215 _serial.close(); |
| 218 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); | 216 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); |
| 219 } | 217 } |
| 220 return false; | 218 return false; |
| 221 } | 219 } |
| 225 QSize OSTC2cOperations::nameSize() const | 223 QSize OSTC2cOperations::nameSize() const |
| 226 { | 224 { |
| 227 return QSize(25, 1); | 225 return QSize(25, 1); |
| 228 } | 226 } |
| 229 | 227 |
| 230 void OSTC2cOperations::writeText(const QString& msg) | 228 void OSTC2cOperations::writeText(const QString &msg) |
| 231 { | 229 { |
| 232 // No hardware support for that. Just skip it, as it is done when | 230 // No hardware support for that. Just skip it, as it is done when |
| 233 // writting bank1... | 231 // writting bank1... |
| 234 LOG_TRACE(msg); | 232 LOG_TRACE(msg); |
| 235 } | 233 } |
| 240 { | 238 { |
| 241 try { | 239 try { |
| 242 _serial.open(Settings::port, "OSTC2c"); | 240 _serial.open(Settings::port, "OSTC2c"); |
| 243 | 241 |
| 244 _serial.writeByte(0xC1); | 242 _serial.writeByte(0xC1); |
| 245 _serial.sleep(500); // 0.50 sec for bootloader to start. | 243 _serial.sleep(500); // 0.50 sec for bootloader to start. |
| 246 | 244 |
| 247 //---- Send C1C1 to start upgrading firmware ----------------------------- | 245 //---- Send C1C1 to start upgrading firmware ----------------------------- |
| 248 unsigned char pic = 0; | 246 unsigned char pic = 0; |
| 249 unsigned char ok = '?'; | 247 unsigned char ok = '?'; |
| 250 for(int retry=0; retry < 10; ++retry) { | 248 for (int retry = 0; retry < 10; ++retry) { |
| 251 _serial.writeByte(0xC1); | 249 _serial.writeByte(0xC1); |
| 252 _serial.sleep(5); | 250 _serial.sleep(5); |
| 253 _serial.writeByte(0xC1); | 251 _serial.writeByte(0xC1); |
| 254 _serial.sleep(5); | 252 _serial.sleep(5); |
| 255 | 253 |
| 256 try { | 254 try { |
| 257 pic = _serial.readByte(); | 255 pic = _serial.readByte(); |
| 258 ok = _serial.readByte(); | 256 ok = _serial.readByte(); |
| 259 break; | 257 break; |
| 260 } | 258 } catch (const ReadTimeout &) { |
| 261 catch(const ReadTimeout&) { | 259 if (retry == 9) |
| 262 if( retry == 9 ) | |
| 263 LOG_THROW("Cannot start firmware upgrade: timeout."); | 260 LOG_THROW("Cannot start firmware upgrade: timeout."); |
| 264 | 261 |
| 265 LOG_INFO("Connecting OSTC2c (" << (retry+1) << "/10)..."); | 262 LOG_INFO("Connecting OSTC2c (" << (retry + 1) << "/10)..."); |
| 266 } | 263 } |
| 267 } | 264 } |
| 268 | 265 |
| 269 //---- Check PIC type ---------------------------------------------------- | 266 //---- Check PIC type ---------------------------------------------------- |
| 270 LOG_TRACE("Pic = " << int(pic)); | 267 LOG_TRACE("Pic = " << int(pic)); |
| 271 if( ! pic ) | 268 if (!pic) |
| 272 LOG_THROW("Cannot sync firmware upgrade. Cannot detect chip"); | 269 LOG_THROW("Cannot sync firmware upgrade. Cannot detect chip"); |
| 273 | 270 |
| 274 if( pic != 0x57 | 271 if (pic != 0x57 || ok != 'K') |
| 275 || ok != 'K' | 272 LOG_THROW("Cannot sync firmware upgrade. Bad chip " << int(pic) << " " << ok); |
| 276 ) | 273 |
| 277 LOG_THROW( "Cannot sync firmware upgrade. Bad chip " << int(pic) << " " << ok); | 274 _serial.sleep(50); // Wait 0.050 sec here. |
| 278 | |
| 279 _serial.sleep(50); // Wait 0.050 sec here. | |
| 280 return; | 275 return; |
| 281 } | 276 } catch (const Exception &e) { |
| 282 catch(const Exception& e) { | |
| 283 _serial.close(); | 277 _serial.close(); |
| 284 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); | 278 LOG_THROW("Cannot connect " << Settings::port << ": " << e.what()); |
| 285 } | 279 } |
| 286 return; | 280 return; |
| 287 } | 281 } |
| 288 | 282 |
| 289 ////////////////////////////////////////////////////////////////////////////// | 283 ////////////////////////////////////////////////////////////////////////////// |
| 290 | 284 |
| 291 bool OSTC2cOperations::disconnect(bool /*closing*/) | 285 bool OSTC2cOperations::disconnect(bool /*closing*/) |
| 292 { | 286 { |
| 293 if( ! _serial.isOpen() ) return false; | 287 if (!_serial.isOpen()) |
| 288 return false; | |
| 294 | 289 |
| 295 LOG_TRACE("Disconnecting."); | 290 LOG_TRACE("Disconnecting."); |
| 296 | 291 |
| 297 _serial.purge(); | 292 _serial.purge(); |
| 298 _serial.close(); | 293 _serial.close(); |
| 310 buffer[2] = date.time().second(); | 305 buffer[2] = date.time().second(); |
| 311 buffer[3] = date.date().month(); | 306 buffer[3] = date.date().month(); |
| 312 buffer[4] = date.date().day(); | 307 buffer[4] = date.date().day(); |
| 313 buffer[5] = date.date().year() % 100; | 308 buffer[5] = date.date().year() % 100; |
| 314 | 309 |
| 315 _serial.sleep(100); // Make sure last command is finished. | 310 _serial.sleep(100); // Make sure last command is finished. |
| 316 _serial.purge(); | 311 _serial.purge(); |
| 317 _serial.writeByte('b'); // 0x62 | 312 _serial.writeByte('b'); // 0x62 |
| 318 | 313 |
| 319 unsigned char reply = _serial.readByte(); | 314 unsigned char reply = _serial.readByte(); |
| 320 if( reply != 'b' ) | 315 if (reply != 'b') |
| 321 LOG_THROW( "sync time" ); | 316 LOG_THROW("sync time"); |
| 322 | 317 |
| 323 _serial.writeBlock( buffer, sizeof buffer); | 318 _serial.writeBlock(buffer, sizeof buffer); |
| 324 _serial.sleep(100); | 319 _serial.sleep(100); |
| 325 } | 320 } |
| 326 | 321 |
| 327 ////////////////////////////////////////////////////////////////////////////// | 322 ////////////////////////////////////////////////////////////////////////////// |
| 328 | 323 |
| 329 void OSTC2cOperations::setName(const QString &newName) | 324 void OSTC2cOperations::setName(const QString &newName) |
| 330 { | 325 { |
| 331 QByteArray padded = (newName + QString(25, '}')) | 326 QByteArray padded = (newName + QString(25, '}')).left(25).toLatin1(); |
| 332 .left(25) | |
| 333 .toLatin1(); | |
| 334 | 327 |
| 335 byte bank0[256] = {0}; | 328 byte bank0[256] = {0}; |
| 336 readBank0(bank0); | 329 readBank0(bank0); |
| 337 memcpy(bank0+65, padded.constData(), 25); | 330 memcpy(bank0 + 65, padded.constData(), 25); |
| 338 writeBank0(bank0); | 331 writeBank0(bank0); |
| 339 | 332 |
| 340 // Then get the new identity: | 333 // Then get the new identity: |
| 341 getIdentity(); | 334 getIdentity(); |
| 342 } | 335 } |
| 343 | 336 |
| 344 ////////////////////////////////////////////////////////////////////////////// | 337 ////////////////////////////////////////////////////////////////////////////// |
| 345 | 338 |
| 346 void OSTC2cOperations::setIcons(const QString &/*fileName*/) | 339 void OSTC2cOperations::setIcons(const QString & /*fileName*/) |
| 347 { | 340 { |
| 348 LOG_THROW("Not supported"); | 341 LOG_THROW("Not supported"); |
| 349 } | 342 } |
| 350 | 343 |
| 351 ////////////////////////////////////////////////////////////////////////////// | 344 ////////////////////////////////////////////////////////////////////////////// |
| 352 | 345 |
| 353 QImage OSTC2cOperations::dumpScreen() const | 346 QImage OSTC2cOperations::dumpScreen() const |
| 354 { | 347 { |
| 355 QImage image(320, 240, QImage::Format_RGB32); | 348 QImage image(320, 240, QImage::Format_RGB32); |
| 356 | 349 |
| 357 //---- Send dump screen command ------------------------------------- | 350 //---- Send dump screen command ------------------------------------- |
| 358 unsigned char reply; | 351 unsigned char reply; |
| 359 _serial.writeByte('l'); | 352 _serial.writeByte('l'); |
| 360 reply = _serial.readByte(); | 353 reply = _serial.readByte(); |
| 361 | 354 |
| 362 if( reply != 'l' ) | 355 if (reply != 'l') |
| 363 LOG_THROW( "Dumpscreen command failed: " << (int)reply ); | 356 LOG_THROW("Dumpscreen command failed: " << (int) reply); |
| 364 | 357 |
| 365 //---- Read image ---------------------------------------------------- | 358 //---- Read image ---------------------------------------------------- |
| 366 int percent = 0; | 359 int percent = 0; |
| 367 try { | 360 try { |
| 368 for(int x=0; x<320; ++x) | 361 for (int x = 0; x < 320; ++x) { |
| 369 { | 362 int p = x / 16; // 5% steps |
| 370 int p = x/16; // 5% steps | 363 if (p != percent) { |
| 371 if( p != percent ) | 364 PROGRESS(p, 320 / 16); |
| 372 { | |
| 373 PROGRESS(p, 320/16); | |
| 374 percent = p; | 365 percent = p; |
| 375 } | 366 } |
| 376 int pix = 0, count = 0; | 367 int pix = 0, count = 0; |
| 377 | 368 |
| 378 for(int y=0; y<240; ++y, --count) | 369 for (int y = 0; y < 240; ++y, --count) { |
| 379 { | 370 if (count <= 0) { |
| 380 if( count <= 0 ) | |
| 381 { | |
| 382 count = _serial.readByte(); | 371 count = _serial.readByte(); |
| 383 | 372 |
| 384 if( (count & 0x80) == 0 ) | 373 if ((count & 0x80) == 0) |
| 385 pix = 0; | 374 pix = 0; |
| 386 else if( (count & 0xC0) == 0xC0 ) | 375 else if ((count & 0xC0) == 0xC0) { |
| 387 { | |
| 388 pix = 0xFFFF; | 376 pix = 0xFFFF; |
| 389 count &= 0x3F; | 377 count &= 0x3F; |
| 390 } | 378 } else { |
| 391 else | |
| 392 { | |
| 393 unsigned char bpix[2]; | 379 unsigned char bpix[2]; |
| 394 _serial.readBlock(bpix, 2); | 380 _serial.readBlock(bpix, 2); |
| 395 pix = (bpix[0] << 8) + bpix[1]; | 381 pix = (bpix[0] << 8) + bpix[1]; |
| 396 count &= 0x3F; | 382 count &= 0x3F; |
| 397 } | 383 } |
| 398 count++; | 384 count++; |
| 399 } | 385 } |
| 400 // Bit extension 5bits --> 8bits: | 386 // Bit extension 5bits --> 8bits: |
| 401 // 12345123.45 = (12345 * 0b100001) / 4 | 387 // 12345123.45 = (12345 * 0b100001) / 4 |
| 402 // 12345612.3456 = (123456 * 0xb1000001) / 16 | 388 // 12345612.3456 = (123456 * 0xb1000001) / 16 |
| 403 int r = (31 & (pix >> 11)) * 255/31; | 389 int r = (31 & (pix >> 11)) * 255 / 31; |
| 404 int g = (63 & (pix >> 5)) * 255/63; | 390 int g = (63 & (pix >> 5)) * 255 / 63; |
| 405 int b = (31 & pix ) * 255/31; | 391 int b = (31 & pix) * 255 / 31; |
| 406 image.setPixel(x, y, qRgb( r, g, b)); | 392 image.setPixel(x, y, qRgb(r, g, b)); |
| 407 } | 393 } |
| 408 } | 394 } |
| 409 } | 395 } catch (ReadTimeout) { |
| 410 catch( ReadTimeout ) { | |
| 411 LOG_THROW("Missing image data..."); | 396 LOG_THROW("Missing image data..."); |
| 412 } | 397 } |
| 413 | 398 |
| 414 //---- Done ---------------------------------------------------------- | 399 //---- Done ---------------------------------------------------------- |
| 415 PROGRESS_RESET(); | 400 PROGRESS_RESET(); |
| 416 LOG_INFO( "Screen dumped." ); | 401 LOG_INFO("Screen dumped."); |
| 417 return image; | 402 return image; |
| 418 } | 403 } |
| 419 | 404 |
| 420 ////////////////////////////////////////////////////////////////////////////// | 405 ////////////////////////////////////////////////////////////////////////////// |
| 421 | 406 |
| 422 void OSTC2cOperations::loadFirmware(HexFile& hex, const QString& fileName) const | 407 void OSTC2cOperations::loadFirmware(HexFile &hex, const QString &fileName) const |
| 423 { | 408 { |
| 424 hex.allocate(FIRMWARE_SIZE); | 409 hex.allocate(FIRMWARE_SIZE); |
| 425 hex.load(fileName); | 410 hex.load(fileName); |
| 426 | 411 |
| 427 //---- Patch Firmware intialization GOTO --------------------------------- | 412 //---- Patch Firmware intialization GOTO --------------------------------- |
| 428 memcpy((void*)(hex.data() + 0x17F38), // To bootloader vector | 413 memcpy((void *) (hex.data() + 0x17F38), // To bootloader vector |
| 429 (void*)(hex.data() + 0x00000), // From fw reset code | 414 (void *) (hex.data() + 0x00000), // From fw reset code |
| 430 8); // Up to 8 bytes... | 415 8); // Up to 8 bytes... |
| 431 | 416 |
| 432 static unsigned char byteCode[8] = { | 417 static unsigned char byteCode[8] = { |
| 433 0xA0, 0xEF, 0xBF, 0xF0, // goto 0x1F740 (bootloader 19k) | 418 0xA0, |
| 434 0x00, 0x00, // nop | 419 0xEF, |
| 435 0x00, 0x00 // nop | 420 0xBF, |
| 421 0xF0, // goto 0x1F740 (bootloader 19k) | |
| 422 0x00, | |
| 423 0x00, // nop | |
| 424 0x00, | |
| 425 0x00 // nop | |
| 436 }; | 426 }; |
| 437 memcpy((void*)(hex.data() + 0x00000), // To OSTC reset vector | 427 memcpy((void *) (hex.data() + 0x00000), // To OSTC reset vector |
| 438 (void*)(byteCode), // From go back to bootloader. | 428 (void *) (byteCode), // From go back to bootloader. |
| 439 8); // Up to 8 bytes... | 429 8); // Up to 8 bytes... |
| 440 } | 430 } |
| 441 | 431 |
| 442 ////////////////////////////////////////////////////////////////////////////// | 432 ////////////////////////////////////////////////////////////////////////////// |
| 443 | 433 |
| 444 static void | 434 static void uploadBlock(Serial &serial, const HexFile &hex, size_t addr) |
| 445 uploadBlock(Serial& serial, const HexFile& hex, size_t addr) | |
| 446 { | 435 { |
| 447 const unsigned char count = FIRMWARE_BLOCK_SIZE; | 436 const unsigned char count = FIRMWARE_BLOCK_SIZE; |
| 448 assert( 0 < count && count < 255 ); | 437 assert(0 < count && count < 255); |
| 449 assert((addr+count) <= FIRMWARE_SIZE ); | 438 assert((addr + count) <= FIRMWARE_SIZE); |
| 450 unsigned char reply = 0; | 439 unsigned char reply = 0; |
| 451 | 440 |
| 452 unsigned char header[4]; | 441 unsigned char header[4]; |
| 453 header[0] = 0x1F & (addr >> 16); | 442 header[0] = 0x1F & (addr >> 16); |
| 454 header[1] = 0xFF & (addr >> 8); | 443 header[1] = 0xFF & (addr >> 8); |
| 455 header[2] = 0xFF & (addr); | 444 header[2] = 0xFF & (addr); |
| 456 header[3] = count; | 445 header[3] = count; |
| 457 | 446 |
| 458 unsigned char crc = header[0] + header[1] + header[2] + header[3]; | 447 unsigned char crc = header[0] + header[1] + header[2] + header[3]; |
| 459 for(int i=0; i<count; ++i) | 448 for (int i = 0; i < count; ++i) |
| 460 crc += hex.data()[addr+i]; | 449 crc += hex.data()[addr + i]; |
| 461 crc = -crc; // Sum should make zero. | 450 crc = -crc; // Sum should make zero. |
| 462 | 451 |
| 463 try { | 452 try { |
| 464 serial.writeBlock(header, sizeof header); | 453 serial.writeBlock(header, sizeof header); |
| 465 serial.writeBlock(hex.data()+addr, count); | 454 serial.writeBlock(hex.data() + addr, count); |
| 466 serial.writeByte(crc); | 455 serial.writeByte(crc); |
| 467 } catch(...) { | 456 } catch (...) { |
| 468 goto WriteFailed; | 457 goto WriteFailed; |
| 469 } | 458 } |
| 470 | 459 |
| 471 serial.sleep(20); // 18msec for a FLASH row write, plus VAT. | 460 serial.sleep(20); // 18msec for a FLASH row write, plus VAT. |
| 472 | 461 |
| 473 reply = serial.readByte(); | 462 reply = serial.readByte(); |
| 474 if( reply != 'K' ) | 463 if (reply != 'K') { |
| 475 { | |
| 476 serial.close(); | 464 serial.close(); |
| 477 LOG_THROW( QString("Bad checksum at 0x%1").arg((unsigned int)addr, 0, 16, QChar('0'))); | 465 LOG_THROW(QString("Bad checksum at 0x%1").arg((unsigned int) addr, 0, 16, QChar('0'))); |
| 478 } | 466 } |
| 479 return; | 467 return; |
| 480 | 468 |
| 481 WriteFailed: | 469 WriteFailed: |
| 482 serial.close(); | 470 serial.close(); |
| 483 | 471 |
| 484 LOG_THROW( QString("Write failed") ); | 472 LOG_THROW(QString("Write failed")); |
| 485 } | 473 } |
| 486 | 474 |
| 487 void OSTC2cOperations::upgradeFW(const QString& fileName) | 475 void OSTC2cOperations::upgradeFW(const QString &fileName) |
| 488 { | 476 { |
| 489 //---- Load and check firmware --------------------------------------- | 477 //---- Load and check firmware --------------------------------------- |
| 490 LOG_TRACE("Loading firmware '" << fileName << "'."); | 478 LOG_TRACE("Loading firmware '" << fileName << "'."); |
| 491 HexFile hex; | 479 HexFile hex; |
| 492 loadFirmware(hex, fileName); | 480 loadFirmware(hex, fileName); |
| 495 connectServiceMode(); | 483 connectServiceMode(); |
| 496 | 484 |
| 497 //---- Let's do it ------------------------------------------------------- | 485 //---- Let's do it ------------------------------------------------------- |
| 498 int percent = 0; | 486 int percent = 0; |
| 499 | 487 |
| 500 for(size_t addr = FIRMWARE_BLOCK_SIZE; addr < FIRMWARE_SIZE; addr += FIRMWARE_BLOCK_SIZE) | 488 for (size_t addr = FIRMWARE_BLOCK_SIZE; addr < FIRMWARE_SIZE; addr += FIRMWARE_BLOCK_SIZE) { |
| 501 { | 489 int p = int((addr * 200.0f) / float(FIRMWARE_SIZE) + 0.5f); |
| 502 int p = int((addr*200.0f) / float(FIRMWARE_SIZE) + 0.5f); | 490 if (p > percent) { |
| 503 if( p > percent ) | |
| 504 { | |
| 505 PROGRESS(percent, 200); | 491 PROGRESS(percent, 200); |
| 506 percent = p; | 492 percent = p; |
| 507 } | 493 } |
| 508 uploadBlock(_serial, hex, addr); | 494 uploadBlock(_serial, hex, addr); |
| 509 } | 495 } |
| 520 void OSTC2cOperations::getSignal() | 506 void OSTC2cOperations::getSignal() |
| 521 { | 507 { |
| 522 return; | 508 return; |
| 523 } | 509 } |
| 524 | 510 |
| 525 void OSTC2cOperations::getAllHeader(unsigned char* pBuffer) | 511 void OSTC2cOperations::getAllHeader(unsigned char *pBuffer) |
| 526 { | 512 { |
| 527 return; | 513 return; |
| 528 } | 514 } |
| 529 void OSTC2cOperations::writeAllHeader(unsigned char* pBuffer) | 515 void OSTC2cOperations::writeAllHeader(unsigned char *pBuffer) |
| 530 { | 516 { |
| 531 return; | 517 return; |
| 532 } | 518 } |
| 533 | 519 |
| 534 void OSTC2cOperations::getAllSamples(unsigned char* pBuffer) | 520 void OSTC2cOperations::getAllSamples(unsigned char *pBuffer) |
| 535 { | 521 { |
| 536 return; | 522 return; |
| 537 } | 523 } |
| 538 void OSTC2cOperations::writeAllSamples(unsigned char* pBuffer) | 524 void OSTC2cOperations::writeAllSamples(unsigned char *pBuffer) |
| 539 { | 525 { |
| 540 return; | 526 return; |
| 541 } | 527 } |
| 542 ////////////////////////////////////////////////////////////////////////////// | 528 ////////////////////////////////////////////////////////////////////////////// |
