# HG changeset patch # User František Kučera # Date 1496581153 -7200 # Node ID ea8642c174958df5e3f65221e2f06aafe8209f2d # Parent 896eca3d40d8a53cf5c1d130ae718a7d9e3f542c lpt-signal-generator: parametrizace, unicode diff -r 896eca3d40d8 -r ea8642c17495 c++/lpt-signal-generator/lpt.cpp --- a/c++/lpt-signal-generator/lpt.cpp Sun Jun 04 14:57:42 2017 +0200 +++ b/c++/lpt-signal-generator/lpt.cpp Sun Jun 04 14:59:13 2017 +0200 @@ -23,35 +23,75 @@ #include #include +/** + * can not mix printf and wprintf + * see https://stackoverflow.com/questions/8681623/printf-and-wprintf-in-single-c-code + * > This is to be expected; your code is invoking undefined behavior. + * > Per the C standard, each FILE stream has associated with it an "orientation" (either "byte" or "wide) + * > which is set by the first operation performed on it, and which can be inspected with the fwide function. + * > Calling any function whose orientation conflicts with the orientation of the stream results in undefined behavior. + */ +#include +#include + + using namespace std; -// g++ lpt.cpp && ./a.out +// run this program: g++ lpt.cpp && time chrt 1 ./a.out +// depending to frequency and machine performance the total time will be more than given duration +// despite the real-time priority, because some additional time is spent in outb() functions +// so "duration" means total sleep time int main() { - cout << "LPT!" << endl; + //cout << "LPT!" << endl; // same as using printf → breaks all folllowing wprintf() calls, see note above - //int addr = 0x378; // parport0 + /* + * if setlocale() is missing, unicode characters are replaced with ? or „→“ with „->“ because C/POSIX locale is used, + * see man setlocale: + * > On startup of the main program, the portable "C" locale is selected as default. + * > If locale is an empty string, "", each part of the locale that should be modified is set according to the environment variables. + */ + setlocale(LC_ALL,""); - int addr = 0xe400; // parport1 + int addr = 0xe400; // parallel port address; first number of given port in: cat /proc/ioports | grep parport + 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 + int outputPower = 10; // duty cycle; 100 = 100 % + int duration = 5; // in seconds; total sleep time, see note above - //int addr = 0x278; + int valueWidth = 10; // just for padding of printed values + int labelWidth = -15; // just for padding of printed labels - //int addr = 0xc800; + // ' = thousand separator + // * = padding + wprintf(L"%*ls %*x\n", labelWidth, L"Parallel port:", valueWidth, addr); // or %#*x – adds 0x prefix + wprintf(L"%*ls %'*d Hz\n", labelWidth, L"Base frequency:", valueWidth, baseFreq); + wprintf(L"%*ls %*d %%\n", labelWidth, L"Output power:", valueWidth, outputPower); + wprintf(L"%*ls %'*d s\n", labelWidth, L"Duration:", valueWidth, duration); + // in microseconds: + int oneSecond = 1000 * 1000; + int timeOn = oneSecond * outputPower / 100 / baseFreq; + int timeOff = oneSecond * (100 - outputPower) / 100 / baseFreq; - if (ioperm(addr,1,1)) { fprintf(stderr, "Access denied to %x\n", addr), exit(1); } + int cycleCount = duration * baseFreq; + wprintf(L"%*ls %'*d ×\n", labelWidth, L"Cycle count:", valueWidth, cycleCount); + wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time on:", valueWidth, timeOn); + wprintf(L"%*ls %'*d μs in each cycle\n", labelWidth, L"Time off:", valueWidth, timeOff); + wprintf(L"%*ls %*ls\n", labelWidth, L"unicode test:", valueWidth, L"čeština → …"); - for (int i = 0; i < 30; i++) { - cout << "cyklus" << endl; - usleep(100*1000); - outb(0b11111111, addr); - usleep(10*1000); + + if (ioperm(addr,1,1)) { fwprintf(stderr, L"Access denied to port %#x\n", addr), exit(1); } + + outb(0b00000000, addr); + + for (int i = 0; i < cycleCount; i++) { + outb(0b00000001, addr); + usleep(timeOn); outb(0b00000000, addr); + usleep(timeOff); } - - cout << "hotovo" << endl; - + wprintf(L"finished\n"); }