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