module; import sys; import io; export module morse; static unsigned slen (const char * str) { unsigned n = 0; while (*str++) n++; return n; } union morse_byte { struct { unsigned char bits : 5; unsigned char mlen : 3; }; unsigned char byte; explicit constexpr morse_byte () noexcept : byte (0u) {} }; /* Použijeme vygenerovanou tabulku, * je naprosto nečitelná, ale z čitelného kódu. * * Jsme v bare metal, tak ušetříme každý byte, * ať to stojí co chce (je to cca 500 bytů). */ #include "table.cpp" export class Morse { const unsigned unit; const io::GpioClass & led; public: explicit Morse (const io::GpioClass & pin, const unsigned ms = 100) noexcept : unit (ms), led (pin) { sys::init (); } const Morse & operator<< (const char * text) const; protected: void out (const morse_byte mb) const; }; const Morse & Morse::operator<< (const char * text) const { const unsigned len = slen (text); for (unsigned n=0; n 1 x unit * - => 3 x unit * mezera mezi značkami => 1 x unit * mezera mezi znaky => 3 x unit * mezera mezi slovy => 7 x unit * */ void Morse::out (const morse_byte mb) const { /* Finta je v tom, že i když se pole mlen a bits překrývají, * nevadí to - maximální délka je 6, takže v nejnižším bitu * mlen může být obsažen 1 bit 6.bitového znaku. * Takhle napsáno to běhá jen na malém indiánu, přepisovat * to do bitových posunů nebudu, i když by to bylo čistší. * */ const unsigned len = mb.mlen > 6u ? 6u : mb.mlen; if (!len) { sys::delay (4 * unit); return; } for (unsigned n=0; n