acid-drop

- Hacking the planet from a LilyGo T-Deck using custom firmware
git clone git://git.acid.vegas/acid-drop.git
Log | Files | Refs | Archive | README | LICENSE

Hellschreiber.cpp (7109B)

      1 #include "Hellschreiber.h"
      2 #if !defined(RADIOLIB_EXCLUDE_HELLSCHREIBER)
      3 
      4 HellClient::HellClient(PhysicalLayer* phy) {
      5   _phy = phy;
      6 
      7   #if !defined(RADIOLIB_EXCLUDE_AFSK)
      8   _audio = nullptr;
      9   #endif
     10 }
     11 
     12 #if !defined(RADIOLIB_EXCLUDE_AFSK)
     13 HellClient::HellClient(AFSKClient* audio) {
     14   _phy = audio->_phy;
     15   _audio = audio;
     16 }
     17 #endif
     18 
     19 int16_t HellClient::begin(float base, float rate) {
     20   // calculate 24-bit frequency
     21   _baseHz = base;
     22   _base = (base * 1000000.0) / _phy->getFreqStep();
     23 
     24   // calculate "pixel" duration
     25   _pixelDuration = 1000000.0/rate;
     26 
     27   // configure for direct mode
     28   return(_phy->startDirect());
     29 }
     30 
     31 size_t HellClient::printGlyph(uint8_t* buff) {
     32   // print the character
     33   Module* mod = _phy->getMod();
     34   for(uint8_t mask = 0x40; mask >= 0x01; mask >>= 1) {
     35     for(int8_t i = RADIOLIB_HELL_FONT_HEIGHT - 1; i >= 0; i--) {
     36         uint32_t start = mod->micros();
     37         if(buff[i] & mask) {
     38           transmitDirect(_base, _baseHz);
     39         } else {
     40           standby();
     41         }
     42         while(mod->micros() - start < _pixelDuration);
     43     }
     44   }
     45 
     46   // make sure transmitter is off
     47   standby();
     48 
     49   return(1);
     50 }
     51 
     52 void HellClient::setInversion(bool invert) {
     53   _inv = invert;
     54 }
     55 
     56 size_t HellClient::write(const char* str) {
     57   if(str == NULL) {
     58     return(0);
     59   }
     60   return(HellClient::write((uint8_t *)str, strlen(str)));
     61 }
     62 
     63 size_t HellClient::write(uint8_t* buff, size_t len) {
     64   size_t n = 0;
     65   for(size_t i = 0; i < len; i++) {
     66     n += HellClient::write(buff[i]);
     67   }
     68   return(n);
     69 }
     70 
     71 size_t HellClient::write(uint8_t b) {
     72   // convert to position in font buffer
     73   uint8_t pos = b;
     74   if((pos >= ' ') && (pos <= '_')) {
     75     pos -= ' ';
     76   } else if((pos >= 'a') && (pos <= 'z')) {
     77     pos -= (2*' ');
     78   } else {
     79     return(0);
     80   }
     81 
     82   // fetch character from flash
     83   uint8_t buff[RADIOLIB_HELL_FONT_WIDTH];
     84   buff[0] = 0x00;
     85   for(uint8_t i = 0; i < RADIOLIB_HELL_FONT_WIDTH - 2; i++) {
     86     buff[i + 1] = RADIOLIB_NONVOLATILE_READ_BYTE(&HellFont[pos][i]);
     87   }
     88   buff[RADIOLIB_HELL_FONT_WIDTH - 1] = 0x00;
     89 
     90   // print the character
     91   return(printGlyph(buff));
     92 }
     93 
     94 size_t HellClient::print(__FlashStringHelper* fstr) {
     95   PGM_P p = reinterpret_cast<PGM_P>(fstr);
     96   size_t n = 0;
     97   while(true) {
     98     char c = RADIOLIB_NONVOLATILE_READ_BYTE(p++);
     99     if(c == '\0') {
    100       break;
    101     }
    102     n += HellClient::write(c);
    103   }
    104   return n;
    105 }
    106 
    107 size_t HellClient::print(const String& str) {
    108   return(HellClient::write((uint8_t*)str.c_str(), str.length()));
    109 }
    110 
    111 size_t HellClient::print(const char* str) {
    112   return(HellClient::write((uint8_t*)str, strlen(str)));
    113 }
    114 
    115 size_t HellClient::print(char c) {
    116   return(HellClient::write(c));
    117 }
    118 
    119 size_t HellClient::print(unsigned char b, int base) {
    120   return(HellClient::print((unsigned long)b, base));
    121 }
    122 
    123 size_t HellClient::print(int n, int base) {
    124   return(HellClient::print((long)n, base));
    125 }
    126 
    127 size_t HellClient::print(unsigned int n, int base) {
    128   return(HellClient::print((unsigned long)n, base));
    129 }
    130 
    131 size_t HellClient::print(long n, int base) {
    132   if(base == 0) {
    133     return(HellClient::write(n));
    134   } else if(base == DEC) {
    135     if (n < 0) {
    136       int t = HellClient::print('-');
    137       n = -n;
    138       return(HellClient::printNumber(n, DEC) + t);
    139     }
    140     return(HellClient::printNumber(n, DEC));
    141   } else {
    142     return(HellClient::printNumber(n, base));
    143   }
    144 }
    145 
    146 size_t HellClient::print(unsigned long n, int base) {
    147   if(base == 0) {
    148     return(HellClient::write(n));
    149   } else {
    150     return(HellClient::printNumber(n, base));
    151   }
    152 }
    153 
    154 size_t HellClient::print(double n, int digits) {
    155   return(HellClient::printFloat(n, digits));
    156 }
    157 
    158 size_t HellClient::println(void) {
    159   // Hellschreiber has no concept of "line ending", print one space instead
    160   return(HellClient::print(' '));
    161 }
    162 
    163 size_t HellClient::println(__FlashStringHelper* fstr) {
    164   size_t n = HellClient::print(fstr);
    165   n += HellClient::println();
    166   return(n);
    167 }
    168 
    169 size_t HellClient::println(const String& str) {
    170   size_t n = HellClient::print(str);
    171   n += HellClient::println();
    172   return(n);
    173 }
    174 
    175 size_t HellClient::println(const char* str) {
    176   size_t n = HellClient::print(str);
    177   n += HellClient::println();
    178   return(n);
    179 }
    180 
    181 size_t HellClient::println(char c) {
    182   size_t n = HellClient::print(c);
    183   n += HellClient::println();
    184   return(n);
    185 }
    186 
    187 size_t HellClient::println(unsigned char b, int base) {
    188   size_t n = HellClient::print(b, base);
    189   n += HellClient::println();
    190   return(n);
    191 }
    192 
    193 size_t HellClient::println(int num, int base) {
    194   size_t n = HellClient::print(num, base);
    195   n += HellClient::println();
    196   return(n);
    197 }
    198 
    199 size_t HellClient::println(unsigned int num, int base) {
    200   size_t n = HellClient::print(num, base);
    201   n += HellClient::println();
    202   return(n);
    203 }
    204 
    205 size_t HellClient::println(long num, int base) {
    206   size_t n = HellClient::print(num, base);
    207   n += HellClient::println();
    208   return(n);
    209 }
    210 
    211 size_t HellClient::println(unsigned long num, int base) {
    212   size_t n = HellClient::print(num, base);
    213   n += HellClient::println();
    214   return(n);
    215 }
    216 
    217 size_t HellClient::println(double d, int digits) {
    218   size_t n = HellClient::print(d, digits);
    219   n += HellClient::println();
    220   return(n);
    221 }
    222 
    223 size_t HellClient::printNumber(unsigned long n, uint8_t base) {
    224   char buf[8 * sizeof(long) + 1];
    225   char *str = &buf[sizeof(buf) - 1];
    226 
    227   *str = '\0';
    228 
    229   if(base < 2) {
    230     base = 10;
    231   }
    232 
    233   do {
    234     char c = n % base;
    235     n /= base;
    236 
    237     *--str = c < 10 ? c + '0' : c + 'A' - 10;
    238   } while(n);
    239 
    240   return(HellClient::write(str));
    241 }
    242 
    243 size_t HellClient::printFloat(double number, uint8_t digits)  {
    244   size_t n = 0;
    245 
    246   char code[] = {0x00, 0x00, 0x00, 0x00};
    247   if (isnan(number)) strcpy(code, "nan");
    248   if (isinf(number)) strcpy(code, "inf");
    249   if (number > 4294967040.0) strcpy(code, "ovf");  // constant determined empirically
    250   if (number <-4294967040.0) strcpy(code, "ovf");  // constant determined empirically
    251 
    252   if(code[0] != 0x00) {
    253     return(HellClient::write(code));
    254   }
    255 
    256   // Handle negative numbers
    257   if (number < 0.0) {
    258     n += HellClient::print('-');
    259     number = -number;
    260   }
    261 
    262   // Round correctly so that print(1.999, 2) prints as "2.00"
    263   double rounding = 0.5;
    264   for(uint8_t i = 0; i < digits; ++i) {
    265     rounding /= 10.0;
    266   }
    267   number += rounding;
    268 
    269   // Extract the integer part of the number and print it
    270   unsigned long int_part = (unsigned long)number;
    271   double remainder = number - (double)int_part;
    272   n += HellClient::print(int_part);
    273 
    274   // Print the decimal point, but only if there are digits beyond
    275   if(digits > 0) {
    276     n += HellClient::print('.');
    277   }
    278 
    279   // Extract digits from the remainder one at a time
    280   while(digits-- > 0) {
    281     remainder *= 10.0;
    282     unsigned int toPrint = (unsigned int)(remainder);
    283     n += HellClient::print(toPrint);
    284     remainder -= toPrint;
    285   }
    286 
    287   return n;
    288 }
    289 
    290 int16_t HellClient::transmitDirect(uint32_t freq, uint32_t freqHz) {
    291   #if !defined(RADIOLIB_EXCLUDE_AFSK)
    292   if(_audio != nullptr) {
    293     return(_audio->tone(freqHz));
    294   }
    295   #endif
    296   return(_phy->transmitDirect(freq));
    297 }
    298 
    299 int16_t HellClient::standby() {
    300   #if !defined(RADIOLIB_EXCLUDE_AFSK)
    301   if(_audio != nullptr) {
    302     return(_audio->noTone(_inv));
    303   }
    304   #endif
    305   return(_phy->standby());
    306 }
    307 
    308 #endif