c++/lpt-signal-generator/lpt.cpp
changeset 46 616e71c2d754
parent 45 ea8642c17495
child 47 9e2addbb9674
     1.1 --- a/c++/lpt-signal-generator/lpt.cpp	Sun Jun 04 14:59:13 2017 +0200
     1.2 +++ b/c++/lpt-signal-generator/lpt.cpp	Sun Jun 04 18:55:08 2017 +0200
     1.3 @@ -22,6 +22,7 @@
     1.4  #include <math.h>
     1.5  #include <sys/io.h>
     1.6  #include <unistd.h>
     1.7 +#include <chrono> // requires -std=c++11
     1.8  
     1.9  /**
    1.10   * can not mix printf and wprintf
    1.11 @@ -37,8 +38,8 @@
    1.12  
    1.13  using namespace std;
    1.14  
    1.15 -// run this program: g++ lpt.cpp && time chrt 1 ./a.out
    1.16 -// depending to frequency and machine performance the total time will be more than given duration
    1.17 +// run this program: g++ -std=c++11 lpt.cpp && time chrt 1 ./a.out
    1.18 +// depending on frequency and machine performance the total time will be more than given duration
    1.19  // despite the real-time priority, because some additional time is spent in outb() functions
    1.20  // so "duration" means total sleep time
    1.21  
    1.22 @@ -56,17 +57,17 @@
    1.23    int addr = 0xe400; // parallel port address; first number of given port in: cat /proc/ioports | grep parport
    1.24    int baseFreq = 10000; // base frequency in Hz, should be between 5 000 between 10 000 Hz; lower frequency leads to dashed/dotted lines instead of greyscale
    1.25    int outputPower = 10; // duty cycle; 100 = 100 %
    1.26 -  int duration = 5; // in seconds; total sleep time, see note above
    1.27 +  int duration = 1; // in seconds; total sleep time, see note above
    1.28  
    1.29    int valueWidth =  10; // just for padding of printed values
    1.30    int labelWidth = -15; // just for padding of printed labels
    1.31  
    1.32    // ' = thousand separator
    1.33    // * = padding
    1.34 -  wprintf(L"%*ls %*x\n",     labelWidth, L"Parallel port:", valueWidth, addr); // or %#*x – adds 0x prefix
    1.35 +  wprintf(L"%*ls %*x\n", labelWidth, L"Parallel port:", valueWidth, addr); // or %#*x – adds 0x prefix
    1.36    wprintf(L"%*ls %'*d Hz\n", labelWidth, L"Base frequency:", valueWidth, baseFreq);
    1.37 -  wprintf(L"%*ls %*d %%\n",  labelWidth, L"Output power:", valueWidth, outputPower);
    1.38 -  wprintf(L"%*ls %'*d s\n",  labelWidth, L"Duration:", valueWidth, duration);
    1.39 +  wprintf(L"%*ls %*d %% duty cycle\n",  labelWidth, L"Output power:", valueWidth, outputPower);
    1.40 +  wprintf(L"%*ls %'*d s\n", labelWidth, L"Duration:", valueWidth, duration);
    1.41  
    1.42    // in microseconds:
    1.43    int oneSecond = 1000 * 1000;
    1.44 @@ -75,23 +76,29 @@
    1.45  
    1.46    int cycleCount = duration * baseFreq;
    1.47    wprintf(L"%*ls %'*d ×\n", labelWidth, L"Cycle count:", valueWidth, cycleCount);
    1.48 -  wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time on:",  valueWidth, timeOn);
    1.49 -  wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time off:", valueWidth, timeOff);
    1.50 +  wprintf(L"%*ls %'*d μs 1× in each cycle\n", labelWidth, L"Time on:",  valueWidth, timeOn);
    1.51 +  wprintf(L"%*ls %'*d μs 1× in each cycle\n", labelWidth, L"Time off:", valueWidth, timeOff);
    1.52  
    1.53 -  wprintf(L"%*ls %*ls\n", labelWidth, L"unicode test:", valueWidth, L"čeština → …");
    1.54 +  //wprintf(L"%*ls %*ls\n", labelWidth, L"unicode test:", valueWidth, L"čeština → …");
    1.55  
    1.56  
    1.57    if (ioperm(addr,1,1)) { fwprintf(stderr, L"Access denied to port %#x\n", addr), exit(1); }
    1.58  
    1.59    outb(0b00000000, addr);
    1.60  
    1.61 +  auto startTimestamp = chrono::high_resolution_clock::now();
    1.62 +
    1.63    for (int i = 0; i < cycleCount; i++) {
    1.64 -    outb(0b00000001, addr);
    1.65 +    outb(0b00000001, addr); // first data out pin = data out 0 = pin 2 on DB-25 connector
    1.66      usleep(timeOn);
    1.67      outb(0b00000000, addr);
    1.68      usleep(timeOff);
    1.69    }
    1.70  
    1.71 -  wprintf(L"finished\n");
    1.72 +  auto finishTimestamp = chrono::high_resolution_clock::now();
    1.73 +  auto measuredDuration = chrono::duration_cast<chrono::nanoseconds>(finishTimestamp - startTimestamp).count();
    1.74 +
    1.75 +  wprintf(L"%*ls %'*d μs 2× in each cycle\n", labelWidth, L"single outb():", valueWidth, (measuredDuration-duration*oneSecond*1000)/cycleCount/2/1000);
    1.76 +  wprintf(L"%*ls %'*d ns 2× in each cycle\n", labelWidth, L"single outb():", valueWidth, (measuredDuration-duration*oneSecond*1000)/cycleCount/2);
    1.77  
    1.78  }