LCOV - code coverage report
Current view: top level - backend/devices/parallel - pdevice.cpp (source / functions) Hit Total Coverage
Test: "6f9243f" Lines: 307 438 70.1 %
Date: 2024-02-24 14:58:06 Functions: 20 24 83.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // ---------------------------------------------------------------------------
       2             : // USB EPROM/Flash Programmer
       3             : //
       4             : // Copyright (2024) Robson Martins
       5             : //
       6             : // This work is licensed under a Creative Commons Attribution-NonCommercial-
       7             : // ShareAlike 4.0 International License.
       8             : // ---------------------------------------------------------------------------
       9             : /**
      10             :  * @ingroup Software
      11             :  * @file backend/devices/parallel/pdevice.cpp
      12             :  * @brief Implementation of a Parallel Device.
      13             :  *
      14             :  * @author Robson Martins (https://www.robsonmartins.com)
      15             :  */
      16             : // ---------------------------------------------------------------------------
      17             : 
      18             : #include <QByteArray>
      19             : #include <QRandomGenerator>
      20             : #include <QLoggingCategory>
      21             : 
      22             : #include "backend/devices/parallel/pdevice.hpp"
      23             : 
      24             : // ---------------------------------------------------------------------------
      25             : // Logging
      26             : 
      27        7874 : Q_LOGGING_CATEGORY(devicePar, "device.parallel")
      28             : 
      29             : #define DEBUG qCDebug(devicePar)
      30             : #define INFO qCInfo(devicePar)
      31             : #define WARNING qCWarning(devicePar)
      32             : #define CRITICAL qCCritical(devicePar)
      33             : #define FATAL qCFatal(devicePar)
      34             : 
      35             : // ---------------------------------------------------------------------------
      36             : 
      37          13 : ParDevice::ParDevice(QObject *parent) : Device(parent) {
      38          13 :     info_.deviceType = kDeviceParallelMemory;
      39          13 :     info_.name = "Parallel Device";
      40          13 :     size_ = 2048;
      41          26 :     DEBUG << info_.toString();
      42          13 : }
      43             : 
      44          13 : ParDevice::~ParDevice() {}
      45             : 
      46          37 : bool ParDevice::read(QByteArray &buffer) {
      47          74 :     INFO << "Reading device...";
      48          37 :     uint32_t total = size_;
      49          37 :     if (flags_.is16bit) total /= 2;
      50          37 :     canceling_ = false;
      51             :     // Init pins/bus to Read operation
      52          37 :     if (!initDevice(kDeviceOpRead)) {
      53           0 :         WARNING << "Error reading device";
      54           0 :         return false;
      55             :     }
      56          37 :     bool error = false;
      57             :     // Read the device
      58          37 :     if (!readDevice(buffer)) error = true;
      59          37 :     if (!error) emit onProgress(total, total, true);
      60             :     // Close resources
      61          37 :     finalizeDevice();
      62          37 :     if (error) {
      63           0 :         WARNING << "Error reading device";
      64             :     } else {
      65          74 :         INFO << "Reading device OK";
      66             :     }
      67          37 :     return !error;
      68             : }
      69             : 
      70         114 : bool ParDevice::program(const QByteArray &buffer, bool verify) {
      71         228 :     INFO << "Programming device...";
      72         114 :     uint32_t total = qMin(size_, static_cast<uint32_t>(buffer.size()));
      73         114 :     if (flags_.is16bit) total /= 2;
      74         114 :     canceling_ = false;
      75             :     // Init pins/bus to Prog operation
      76         114 :     if (!initDevice(kDeviceOpProg)) {
      77           0 :         WARNING << "Error programming device";
      78           0 :         return false;
      79             :     }
      80         114 :     bool error = false;
      81             :     // Program the device
      82         114 :     if (!programDevice(buffer)) error = true;
      83             :     // Close resources
      84         114 :     finalizeDevice();
      85             :     // If error, returns
      86         114 :     if (error) {
      87           0 :         WARNING << "Error programming device";
      88           0 :         return false;
      89             :     }
      90             :     // If no error and verify flag is disabled, return
      91         114 :     if (!verify) {
      92          77 :         emit onProgress(total, total, true);
      93         154 :         INFO << "Programming device OK";
      94          77 :         return true;
      95             :     }
      96             :     // If verify flag is enabled, verify device
      97          37 :     return this->verify(buffer);
      98             : }
      99             : 
     100         138 : bool ParDevice::verify(const QByteArray &buffer) {
     101         276 :     INFO << "Verifying device...";
     102         138 :     uint32_t total = qMin(size_, static_cast<uint32_t>(buffer.size()));
     103         138 :     if (flags_.is16bit) total /= 2;
     104         138 :     canceling_ = false;
     105             :     // Init pins/bus to Read operation
     106         138 :     if (!initDevice(kDeviceOpRead)) {
     107           0 :         WARNING << "Error verifying device";
     108           0 :         return false;
     109             :     }
     110         138 :     bool error = false;
     111             :     // Read the device and verify (compare) buffer
     112         138 :     if (!verifyDevice(buffer)) error = true;
     113         138 :     if (!error) emit onProgress(total, total, true);
     114             :     // Close resources
     115         138 :     finalizeDevice();
     116         138 :     if (error) {
     117         128 :         WARNING << "Error verifying device";
     118             :     } else {
     119         148 :         INFO << "Verifying device OK";
     120             :     }
     121         138 :     return !error;
     122             : }
     123             : 
     124          59 : bool ParDevice::erase(bool check) {
     125         118 :     INFO << "Erasing device...";
     126          59 :     uint32_t total = size_;
     127          59 :     if (flags_.is16bit) total /= 2;
     128          59 :     canceling_ = false;
     129             :     // Init pins/bus to Erase operation
     130          59 :     if (!initDevice(kDeviceOpErase)) {
     131           0 :         WARNING << "Error erasing device";
     132           0 :         return false;
     133             :     }
     134          59 :     bool error = false;
     135             :     // Erase the device
     136          59 :     if (!eraseDevice()) error = true;
     137             :     // Close resources
     138          59 :     finalizeDevice();
     139             :     // If error, returns
     140          59 :     if (error) {
     141           0 :         WARNING << "Error erasing device";
     142           0 :         return false;
     143             :     }
     144             :     // If no error and check flag is disabled, return
     145          59 :     if (!check) {
     146          32 :         emit onProgress(total, total, true);
     147          64 :         INFO << "Erasing device OK";
     148          32 :         return true;
     149             :     }
     150             :     // If check flag is enabled, verify device
     151          27 :     return blankCheck();
     152             : }
     153             : 
     154         128 : bool ParDevice::blankCheck() {
     155         256 :     INFO << "Blank checking device...";
     156         128 :     uint32_t total = size_;
     157         128 :     if (flags_.is16bit) total /= 2;
     158         128 :     canceling_ = false;
     159             :     // Init pins/bus to Read operation
     160         128 :     if (!initDevice(kDeviceOpRead)) {
     161           0 :         WARNING << "Error blank checking device";
     162           0 :         return false;
     163             :     }
     164         128 :     bool error = false;
     165             :     // Blank check the device
     166         128 :     if (!blankCheckDevice()) error = true;
     167         128 :     if (!error) emit onProgress(total, total, true);
     168             :     // Close resources
     169         128 :     finalizeDevice();
     170         128 :     if (error) {
     171          74 :         WARNING << "Error blank checking device";
     172             :     } else {
     173         182 :         INFO << "Blank checking device OK";
     174             :     }
     175         128 :     return !error;
     176             : }
     177             : 
     178           0 : bool ParDevice::getId(TDeviceID &result) {
     179           0 :     INFO << "Getting device ID...";
     180           0 :     uint32_t total = size_;
     181           0 :     if (flags_.is16bit) total /= 2;
     182           0 :     canceling_ = false;
     183             :     // Init pins/bus to Get ID operation
     184           0 :     if (!initDevice(kDeviceOpGetId)) {
     185           0 :         WARNING << "Error getting device ID";
     186           0 :         return false;
     187             :     }
     188           0 :     bool error = false;
     189             :     // Getting the device ID
     190           0 :     if (!getIdDevice(result)) error = true;
     191           0 :     if (!error) emit onProgress(total, total, true);
     192             :     // Close resources
     193           0 :     finalizeDevice();
     194           0 :     if (error) {
     195           0 :         WARNING << "Error getting device ID";
     196             :     } else {
     197           0 :         INFO << "Getting device ID OK";
     198             :     }
     199           0 :     return !error;
     200             : }
     201             : 
     202           4 : bool ParDevice::unprotect() {
     203           8 :     INFO << "Unprotecting device...";
     204           4 :     uint32_t total = size_;
     205           4 :     if (flags_.is16bit) total /= 2;
     206           4 :     canceling_ = false;
     207             :     // Init pins/bus to Prog operation
     208           4 :     if (!initDevice(kDeviceOpProg)) {
     209           0 :         WARNING << "Error unprotecting device";
     210           0 :         return false;
     211             :     }
     212           4 :     bool error = false;
     213             :     // Unprotect the device
     214           4 :     if (!protectDevice(false)) error = true;
     215           4 :     if (!error) emit onProgress(total, total, true);
     216             :     // Close resources
     217           4 :     finalizeDevice();
     218           4 :     if (error) {
     219           0 :         WARNING << "Error unprotecting device";
     220             :     } else {
     221           8 :         INFO << "Unprotecting device OK";
     222             :     }
     223           4 :     return !error;
     224             : }
     225             : 
     226           4 : bool ParDevice::protect() {
     227           8 :     INFO << "Protecting device...";
     228           4 :     uint32_t total = size_;
     229           4 :     if (flags_.is16bit) total /= 2;
     230           4 :     canceling_ = false;
     231             :     // Init pins/bus to Prog operation
     232           4 :     if (!initDevice(kDeviceOpProg)) {
     233           0 :         WARNING << "Error protecting device";
     234           0 :         return false;
     235             :     }
     236           4 :     bool error = false;
     237             :     // Protect the device
     238           4 :     if (!protectDevice(true)) error = true;
     239           4 :     if (!error) emit onProgress(total, total, true);
     240             :     // Close resources
     241           4 :     finalizeDevice();
     242           4 :     if (error) {
     243           0 :         WARNING << "Error protecting device";
     244             :     } else {
     245           8 :         INFO << "Protecting device OK";
     246             :     }
     247           4 :     return !error;
     248             : }
     249             : 
     250         170 : bool ParDevice::programDevice(const QByteArray &buffer) {
     251         340 :     DEBUG << "Programming data...";
     252         170 :     uint32_t current = 0;
     253         170 :     uint32_t total = qMin(size_, static_cast<uint32_t>(buffer.size()));
     254         170 :     if (flags_.is16bit) total /= 2;
     255         170 :     uint16_t data = 0xFFFF;
     256         170 :     int increment = (flags_.is16bit ? 2 : 1);
     257         170 :     if (!runner_.deviceSetTwp(twp_) || !runner_.deviceSetTwc(twc_)) {
     258           0 :         emit onProgress(current, total, true, false);
     259           0 :         WARNING << "Program error: setting tWP or tWC";
     260           0 :         return false;
     261             :     }
     262         170 :     QByteArray block;
     263         170 :     int blockSize = (sectorSize_ ? sectorSize_ : getBufferSize());
     264         170 :     uint32_t count = blockSize;
     265         170 :     if (flags_.is16bit && count >= 2) count /= 2;
     266         170 :     int i = 0;
     267             :     bool success;
     268       99114 :     while (i < buffer.size()) {
     269             :         // Repeat for n max attempts
     270       98944 :         for (int attempt = 1; attempt <= maxAttemptsProg_; attempt++) {
     271       98944 :             if ((current % 0x100) == 0) emit onProgress(current, total);
     272       98944 :             runner_.processEvents();
     273       98944 :             if (canceling_) {
     274           0 :                 emit onProgress(current, total, true, false, true);
     275           0 :                 DEBUG << QString("Program canceled at 0x%1 of 0x%2")
     276           0 :                              .arg(current, 6, 16, QChar('0'))
     277           0 :                              .arg(total, 6, 16, QChar('0'));
     278           0 :                 return false;
     279             :             }
     280             : 
     281             :             // Repeat for each byte/word in block size
     282       98944 :             block.clear();
     283             :             do {
     284     4113408 :                 data = buffer[i] & 0xFF;
     285     4113408 :                 if (flags_.is16bit) {
     286     2219008 :                     data <<= 8;                      // MSB
     287     2219008 :                     data |= (buffer[i + 1] & 0xFF);  // LSB
     288             :                 }
     289             :                 // Insert data into block buffer
     290     4113408 :                 if (flags_.is16bit) block.append((data & 0xFF00) >> 8);
     291     4113408 :                 block.append(data & 0xFF);
     292     4113408 :                 i += increment;
     293     4113408 :             } while (block.size() < blockSize);  // one block
     294             : 
     295             :             // Write data
     296       98944 :             if (sectorSize_) {
     297             :                 // Write (and verify) sector
     298        1280 :                 success = runner_.deviceWriteSector(block, sectorSize_);
     299             :             } else {
     300             :                 // Write (and verify) block
     301       97664 :                 success = runner_.deviceWrite(block);
     302             :             }
     303             : 
     304             :             // increment address
     305       98944 :             if (success) {
     306       98944 :                 current += count;
     307       98944 :                 break;
     308             :             } else {
     309           0 :                 i -= blockSize;
     310             :             }
     311             : 
     312             :             // Error
     313           0 :             if (attempt == maxAttemptsProg_) {
     314           0 :                 emit onProgress(current, total, true, false);
     315           0 :                 data = buffer[i] & 0xFF;
     316           0 :                 if (flags_.is16bit) {
     317           0 :                     data <<= 8;                      // MSB
     318           0 :                     data |= (buffer[i + 1] & 0xFF);  // LSB
     319             :                 }
     320           0 :                 WARNING << QString(
     321             :                                "Program error at 0x%1 of 0x%2. Data to "
     322             :                                "write 0x%3")
     323           0 :                                .arg(current, 6, 16, QChar('0'))
     324           0 :                                .arg(total, 6, 16, QChar('0'))
     325           0 :                                .arg(data, flags_.is16bit ? 4 : 2, 16,
     326           0 :                                     QChar('0'));
     327           0 :                 return false;
     328             :             }
     329             :         }
     330             :     }
     331         340 :     DEBUG << "Program OK";
     332         170 :     return true;
     333         170 : }
     334             : 
     335         144 : bool ParDevice::verifyDevice(const QByteArray &buffer) {
     336         288 :     DEBUG << "Verifying data...";
     337         144 :     uint32_t current = 0;
     338         144 :     uint32_t total = qMin(size_, static_cast<uint32_t>(buffer.size()));
     339         144 :     if (flags_.is16bit) total /= 2;
     340         144 :     uint16_t data = 0xFFFF;
     341         144 :     int increment = (flags_.is16bit ? 2 : 1);
     342         144 :     QByteArray block;
     343         144 :     int blockSize = getBufferSize();
     344         144 :     uint32_t count = blockSize;
     345         144 :     if (flags_.is16bit && count >= 2) count /= 2;
     346             :     bool success;
     347         144 :     int i = 0;
     348      117675 :     for (current = 0; current < total; current += count) {
     349      117595 :         if ((current % 0x100) == 0) emit onProgress(current, total);
     350      117595 :         runner_.processEvents();
     351      117595 :         if (canceling_) {
     352           0 :             emit onProgress(current, total, true, false, true);
     353           0 :             DEBUG << QString("Verify canceled at 0x%1 of 0x%2")
     354           0 :                          .arg(current, 6, 16, QChar('0'))
     355           0 :                          .arg(total, 6, 16, QChar('0'));
     356           0 :             return false;
     357             :         }
     358             : 
     359             :         // Repeat for each byte/word in block size
     360      117595 :         block.clear();
     361             :         do {
     362     4294240 :             if (i >= buffer.size()) break;
     363     4294240 :             data = buffer[i] & 0xFF;
     364     4294240 :             if (flags_.is16bit) {
     365     3231840 :                 data <<= 8;                      // MSB
     366     3231840 :                 data |= (buffer[i + 1] & 0xFF);  // LSB
     367             :             }
     368             :             // Insert data into block buffer
     369     4294240 :             if (flags_.is16bit) block.append((data & 0xFF00) >> 8);
     370     4294240 :             block.append(data & 0xFF);
     371     4294240 :             i += increment;
     372     4294240 :         } while (block.size() < blockSize);  // one block
     373             : 
     374             :         // Verify block
     375      117595 :         success = runner_.deviceVerify(block);
     376             : 
     377             :         // Error
     378      117595 :         if (!success) {
     379          64 :             emit onProgress(current, total, true, false);
     380          64 :             i -= blockSize;
     381          64 :             data = buffer[i] & 0xFF;
     382          64 :             if (flags_.is16bit) {
     383          10 :                 data <<= 8;                      // MSB
     384          10 :                 data |= (buffer[i + 1] & 0xFF);  // LSB
     385             :             }
     386         128 :             WARNING << QString(
     387             :                            "Verify error at 0x%1 of 0x%2. Expected data 0x%3")
     388         128 :                            .arg(current, 6, 16, QChar('0'))
     389         128 :                            .arg(total, 6, 16, QChar('0'))
     390          64 :                            .arg(data, flags_.is16bit ? 4 : 2, 16, QChar('0'));
     391          64 :             return false;
     392             :         }
     393             :     }
     394         160 :     DEBUG << "Verify OK";
     395          80 :     return true;
     396         144 : }
     397             : 
     398          37 : bool ParDevice::readDevice(QByteArray &buffer) {
     399          74 :     DEBUG << "Reading data...";
     400          37 :     uint32_t current = 0;
     401          37 :     uint32_t total = size_;
     402          37 :     if (flags_.is16bit) total /= 2;
     403          37 :     int blockSize = getBufferSize();
     404          37 :     uint32_t count = blockSize;
     405          37 :     if (flags_.is16bit && count >= 2) count /= 2;
     406          37 :     QByteArray data;
     407          37 :     buffer.clear();
     408             :     bool success;
     409       39077 :     for (current = 0; current < total; current += count) {
     410       39040 :         if (current % 0x100 == 0) emit onProgress(current, total);
     411       39040 :         runner_.processEvents();
     412       39040 :         if (canceling_) {
     413           0 :             emit onProgress(current, total, true, false, true);
     414           0 :             DEBUG << QString("Read canceled at 0x%1 of 0x%2")
     415           0 :                          .arg(current, 6, 16, QChar('0'))
     416           0 :                          .arg(total, 6, 16, QChar('0'));
     417           0 :             return false;
     418             :         }
     419             :         // Read block
     420       39040 :         data = runner_.deviceRead();
     421       39040 :         success = (data.size() == blockSize);
     422             :         // Error
     423       39040 :         if (!success) {
     424           0 :             emit onProgress(current, total, true, false);
     425           0 :             WARNING << QString("Read error at 0x%1 of 0x%2")
     426           0 :                            .arg(current, 6, 16, QChar('0'))
     427           0 :                            .arg(total, 6, 16, QChar('0'));
     428           0 :             return false;
     429             :         }
     430             :         // Copy data
     431       39040 :         buffer.append(data);
     432             :     }
     433          74 :     DEBUG << "Read OK";
     434          37 :     return true;
     435          37 : }
     436             : 
     437          45 : bool ParDevice::eraseDevice() {
     438          90 :     DEBUG << "Erasing data...";
     439          45 :     uint32_t current = 0;
     440          45 :     uint32_t total = size_;
     441          45 :     if (flags_.is16bit) total /= 2;
     442          45 :     uint32_t count = getBufferSize();
     443          45 :     if (flags_.is16bit && count >= 2) count /= 2;
     444          45 :     if (!runner_.deviceSetTwp(twp_) || !runner_.deviceSetTwc(twc_)) {
     445           0 :         emit onProgress(current, total, true, false);
     446           0 :         WARNING << "Erase error: setting tWP or tWC";
     447           0 :         return false;
     448             :     }
     449             :     // VPP on
     450          45 :     runner_.vppCtrl(true);
     451             :     // Repeat for n max attempts
     452          67 :     for (int attempt = 1; attempt <= maxAttemptsProg_; attempt++) {
     453             :         // Erase entire chip
     454          67 :         bool success = true;
     455          67 :         if (!runner_.deviceErase()) success = false;
     456        8579 :         for (current = 0; current < total; current += count) {
     457        8537 :             if (current % 0x100 == 0) emit onProgress(current, total);
     458        8537 :             runner_.processEvents();
     459        8537 :             if (canceling_) {
     460           0 :                 emit onProgress(current, total, true, false, true);
     461           0 :                 DEBUG << QString("Erase canceled at 0x%1 of 0x%2")
     462           0 :                              .arg(current, 6, 16, QChar('0'))
     463           0 :                              .arg(total, 6, 16, QChar('0'));
     464           0 :                 return false;
     465             :             }
     466             :             // Verify data, if not in Fast Erase mode
     467        8537 :             if (!fastProg_) {
     468             :                 // Check block
     469        8534 :                 if (success && !runner_.deviceBlankCheck()) {
     470          22 :                     success = false;
     471             :                 }
     472             :             }
     473        8537 :             if (fastProg_ && success) break;
     474        8534 :             if (!success && attempt == maxAttemptsProg_) {
     475             :                 // Error
     476           0 :                 emit onProgress(current, total, true, false);
     477           0 :                 WARNING << QString(
     478             :                                "Erase error at 0x%1 of 0x%2. Expected data "
     479             :                                "0x%3")
     480           0 :                                .arg(current, 6, 16, QChar('0'))
     481           0 :                                .arg(total, 6, 16, QChar('0'))
     482           0 :                                .arg(flags_.is16bit ? "FFFF" : "FF");
     483           0 :                 return false;
     484             :             }
     485        8534 :             if (!success) break;
     486             :         }
     487          67 :         if (success) break;
     488             :     }
     489             :     // VPP off
     490          45 :     runner_.vppCtrl(false);
     491          90 :     DEBUG << "Erase OK";
     492          45 :     return true;
     493             : }
     494             : 
     495         128 : bool ParDevice::blankCheckDevice() {
     496         256 :     DEBUG << "Blank checking data...";
     497         128 :     uint32_t current = 0;
     498         128 :     uint32_t total = size_;
     499         128 :     if (flags_.is16bit) total /= 2;
     500         128 :     int increment = flags_.is16bit ? 2 : 1;
     501         128 :     uint32_t count = getBufferSize();
     502         128 :     if (flags_.is16bit && count >= 2) count /= 2;
     503             :     bool success;
     504       50368 :     for (current = 0; current < total; current += count) {
     505       50277 :         if ((current % 0x100) == 0) emit onProgress(current, total);
     506       50277 :         runner_.processEvents();
     507       50277 :         if (canceling_) {
     508           0 :             emit onProgress(current, total, true, false, true);
     509           0 :             DEBUG << QString("Blank Check canceled at 0x%1 of 0x%2")
     510           0 :                          .arg(current, 6, 16, QChar('0'))
     511           0 :                          .arg(total, 6, 16, QChar('0'));
     512           0 :             return false;
     513             :         }
     514             :         // Check block
     515       50277 :         success = runner_.deviceBlankCheck();
     516             :         // Error
     517       50277 :         if (!success) {
     518          37 :             emit onProgress(current, total, true, false);
     519          74 :             WARNING << QString("Blank Check error at 0x%1 of 0x%2")
     520          74 :                            .arg(current, 6, 16, QChar('0'))
     521          37 :                            .arg(total, 6, 16, QChar('0'));
     522          37 :             return false;
     523             :         }
     524             :     }
     525         182 :     DEBUG << "Blank Check OK";
     526          91 :     return true;
     527             : }
     528             : 
     529           0 : bool ParDevice::getIdDevice(TDeviceID &deviceId) {
     530           0 :     DEBUG << "Getting ID...";
     531           0 :     uint32_t current = 0;
     532           0 :     uint32_t total = size_;
     533           0 :     if (flags_.is16bit) total /= 2;
     534             :     // Getting ID
     535           0 :     deviceId = runner_.deviceGetId();
     536           0 :     if (!deviceId.manufacturer && !deviceId.device) {
     537           0 :         emit onProgress(current, total, true, false);
     538           0 :         WARNING << "Error getting ID";
     539           0 :         return false;
     540             :     }
     541           0 :     DEBUG << "Get ID OK";
     542           0 :     return true;
     543             : }
     544             : 
     545           8 : bool ParDevice::protectDevice(bool protect) {
     546          16 :     DEBUG << (protect ? "Protecting..." : "Unprotecting...");
     547           8 :     uint32_t current = 0;
     548           8 :     uint32_t total = size_;
     549           8 :     if (flags_.is16bit) total /= 2;
     550           8 :     if (!runner_.deviceSetTwp(twp_) || !runner_.deviceSetTwc(twc_)) {
     551           0 :         emit onProgress(current, total, true, false);
     552           0 :         WARNING << "Protect/Unprotect error: setting tWP or tWC";
     553           0 :         return false;
     554             :     }
     555             :     // Protect/Unprotect
     556             :     bool success;
     557           8 :     if (protect) {
     558           4 :         success = runner_.deviceProtect();
     559             :     } else {
     560           4 :         success = runner_.deviceUnprotect();
     561             :     }
     562           8 :     if (!success) {
     563           0 :         emit onProgress(current, total, true, false);
     564           0 :         WARNING << "Error protecting/unprotecting";
     565           0 :         return false;
     566             :     }
     567          16 :     DEBUG << (protect ? "Protect OK" : "Unprotect OK");
     568           8 :     return true;
     569             : }
     570             : 
     571         488 : bool ParDevice::initDevice(kDeviceOperation operation) {
     572         976 :     DEBUG << "Initializing...";
     573         488 :     if (!runner_.open(port_)) {
     574           1 :         emit onProgress(0, size_, true, false);
     575           2 :         WARNING << "Error opening serial port";
     576           1 :         return false;
     577             :     }
     578         487 :     if (!runner_.deviceConfigure(algo_, flags_)) {
     579           0 :         emit onProgress(0, size_, true, false);
     580           0 :         WARNING << "Error configuring device";
     581           0 :         return false;
     582             :     }
     583         487 :     bool success = true;
     584         487 :     switch (operation) {
     585         306 :         case kDeviceOpRead:
     586             :             // VDD Rd
     587         612 :             if (!runner_.vddSet(vddRd_) ||
     588         306 :                 !runner_.deviceSetupBus(kCmdDeviceOperationRead)) {
     589           0 :                 success = false;
     590             :             }
     591         306 :             break;
     592         122 :         case kDeviceOpProg:
     593             :             // VDD Wr / VPP
     594         244 :             if (!runner_.vddSet(vddWr_) || !runner_.vppSet(vpp_) ||
     595         122 :                 !runner_.deviceSetupBus(kCmdDeviceOperationProg)) {
     596           0 :                 success = false;
     597             :             }
     598         122 :             break;
     599          59 :         case kDeviceOpErase:
     600             :             // VDD Wr / VEE
     601         118 :             if (!runner_.vddSet(vddWr_) || !runner_.vppSet(vee_) ||
     602          59 :                 !runner_.deviceSetupBus(kCmdDeviceOperationProg)) {
     603           0 :                 success = false;
     604             :             }
     605          59 :             break;
     606           0 :         case kDeviceOpGetId:
     607             :             // VDD Rd / VEE
     608           0 :             if (!runner_.vddSet(vddRd_) || !runner_.vppSet(vee_) ||
     609           0 :                 !runner_.deviceResetBus()) {
     610           0 :                 success = false;
     611             :             }
     612           0 :             break;
     613           0 :         case kDeviceOpReset:
     614             :         default:
     615           0 :             if (!runner_.deviceResetBus()) success = false;
     616           0 :             break;
     617             :     }
     618         487 :     if (success) {
     619         974 :         DEBUG << "Initialize OK";
     620             :     } else {
     621           0 :         DEBUG << "Error initializing device";
     622             :     }
     623         487 :     return success;
     624             : }
     625             : 
     626         487 : void ParDevice::finalizeDevice() {
     627         974 :     DEBUG << "Finalizing...";
     628         487 :     runner_.deviceResetBus();
     629         487 :     runner_.close();
     630         974 :     DEBUG << "Finalize OK";
     631         487 : }
     632             : 
     633           0 : bool ParDevice::finalizeDevice(uint32_t current, uint32_t total, bool done,
     634             :                                bool success, bool canceled) {
     635           0 :     finalizeDevice();
     636           0 :     emit onProgress(current, total, done, success, canceled);
     637           0 :     return success;
     638             : }
     639             : 
     640           3 : QByteArray ParDevice::generateRandomData_() {
     641           6 :     DEBUG << "Generating Random Data...";
     642           3 :     QByteArray buffer(size_, 0);
     643       14339 :     for (int i = 0; i < size_; ++i) {
     644       14336 :         buffer[i] = static_cast<char>(QRandomGenerator::global()->generate());
     645             :     }
     646           3 :     return buffer;
     647           0 : }
     648             : 
     649           3 : QByteArray ParDevice::generatePatternData_() {
     650           6 :     DEBUG << "Generating Pattern Data...";
     651           3 :     QByteArray buffer(size_, 0);
     652           3 :     uint8_t data = 0x55;
     653       14339 :     for (int i = 0; i < size_; ++i) {
     654       14336 :         buffer[i] = static_cast<char>(data);
     655       14336 :         data = ~data;
     656             :     }
     657           3 :     return buffer;
     658           0 : }

Generated by: LCOV version 1.14