1.1 --- a/c++/lpt-signal-generator/lpt.cpp Sun Jun 04 14:57:42 2017 +0200
1.2 +++ b/c++/lpt-signal-generator/lpt.cpp Sun Jun 04 14:59:13 2017 +0200
1.3 @@ -23,35 +23,75 @@
1.4 #include <sys/io.h>
1.5 #include <unistd.h>
1.6
1.7 +/**
1.8 + * can not mix printf and wprintf
1.9 + * see https://stackoverflow.com/questions/8681623/printf-and-wprintf-in-single-c-code
1.10 + * > This is to be expected; your code is invoking undefined behavior.
1.11 + * > Per the C standard, each FILE stream has associated with it an "orientation" (either "byte" or "wide)
1.12 + * > which is set by the first operation performed on it, and which can be inspected with the fwide function.
1.13 + * > Calling any function whose orientation conflicts with the orientation of the stream results in undefined behavior.
1.14 + */
1.15 +#include <wchar.h>
1.16 +#include <locale.h>
1.17 +
1.18 +
1.19 using namespace std;
1.20
1.21 -// g++ lpt.cpp && ./a.out
1.22 +// run this program: g++ lpt.cpp && time chrt 1 ./a.out
1.23 +// depending to frequency and machine performance the total time will be more than given duration
1.24 +// despite the real-time priority, because some additional time is spent in outb() functions
1.25 +// so "duration" means total sleep time
1.26
1.27 int main() {
1.28 - cout << "LPT!" << endl;
1.29 + //cout << "LPT!" << endl; // same as using printf → breaks all folllowing wprintf() calls, see note above
1.30
1.31 - //int addr = 0x378; // parport0
1.32 + /*
1.33 + * if setlocale() is missing, unicode characters are replaced with ? or „→“ with „->“ because C/POSIX locale is used,
1.34 + * see man setlocale:
1.35 + * > On startup of the main program, the portable "C" locale is selected as default.
1.36 + * > If locale is an empty string, "", each part of the locale that should be modified is set according to the environment variables.
1.37 + */
1.38 + setlocale(LC_ALL,"");
1.39
1.40 - int addr = 0xe400; // parport1
1.41 + int addr = 0xe400; // parallel port address; first number of given port in: cat /proc/ioports | grep parport
1.42 + 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.43 + int outputPower = 10; // duty cycle; 100 = 100 %
1.44 + int duration = 5; // in seconds; total sleep time, see note above
1.45
1.46 - //int addr = 0x278;
1.47 + int valueWidth = 10; // just for padding of printed values
1.48 + int labelWidth = -15; // just for padding of printed labels
1.49
1.50 - //int addr = 0xc800;
1.51 + // ' = thousand separator
1.52 + // * = padding
1.53 + wprintf(L"%*ls %*x\n", labelWidth, L"Parallel port:", valueWidth, addr); // or %#*x – adds 0x prefix
1.54 + wprintf(L"%*ls %'*d Hz\n", labelWidth, L"Base frequency:", valueWidth, baseFreq);
1.55 + wprintf(L"%*ls %*d %%\n", labelWidth, L"Output power:", valueWidth, outputPower);
1.56 + wprintf(L"%*ls %'*d s\n", labelWidth, L"Duration:", valueWidth, duration);
1.57
1.58 + // in microseconds:
1.59 + int oneSecond = 1000 * 1000;
1.60 + int timeOn = oneSecond * outputPower / 100 / baseFreq;
1.61 + int timeOff = oneSecond * (100 - outputPower) / 100 / baseFreq;
1.62
1.63 - if (ioperm(addr,1,1)) { fprintf(stderr, "Access denied to %x\n", addr), exit(1); }
1.64 + int cycleCount = duration * baseFreq;
1.65 + wprintf(L"%*ls %'*d ×\n", labelWidth, L"Cycle count:", valueWidth, cycleCount);
1.66 + wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time on:", valueWidth, timeOn);
1.67 + wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time off:", valueWidth, timeOff);
1.68
1.69 + wprintf(L"%*ls %*ls\n", labelWidth, L"unicode test:", valueWidth, L"čeština → …");
1.70
1.71 - for (int i = 0; i < 30; i++) {
1.72 - cout << "cyklus" << endl;
1.73 - usleep(100*1000);
1.74 - outb(0b11111111, addr);
1.75 - usleep(10*1000);
1.76 +
1.77 + if (ioperm(addr,1,1)) { fwprintf(stderr, L"Access denied to port %#x\n", addr), exit(1); }
1.78 +
1.79 + outb(0b00000000, addr);
1.80 +
1.81 + for (int i = 0; i < cycleCount; i++) {
1.82 + outb(0b00000001, addr);
1.83 + usleep(timeOn);
1.84 outb(0b00000000, addr);
1.85 + usleep(timeOff);
1.86 }
1.87
1.88 -
1.89 - cout << "hotovo" << endl;
1.90 -
1.91 + wprintf(L"finished\n");
1.92
1.93 }