first commit
This commit is contained in:
commit
e98d8e9b33
BIN
Display.pdf
Normal file
BIN
Display.pdf
Normal file
Binary file not shown.
296
README.md
Executable file
296
README.md
Executable file
|
@ -0,0 +1,296 @@
|
|||
RadioSonde Version 1.0.0
|
||||
============================
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO2.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO4.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO6.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO7.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO8.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web4.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web3.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web2.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web5.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web6.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web7.png" width="20%">
|
||||
|
||||
|
||||
Projet basé sur le travail de DL9RDZ
|
||||
====================================
|
||||
|
||||
Pour TTGO LORA 32 esp32 pico D4 <br>
|
||||
Décodage de RadioSonde RS41/92 and DFM06/09/17 et M10+/20 et MP3H
|
||||
|
||||
Attention à la version de votre TTGO! <br>
|
||||
vous devez modifier dans config.txt, le port de l'écran OLED <br>
|
||||
- TTGO v1: SDA=4 SCL=15, RST=16 <br>
|
||||
- TTGO v2: SDA=21 SCL=22, RST=16 <br>
|
||||
- puis pour le GPS:<br>
|
||||
Lilygo esp32 GPS pin 34 Rx, 12 Tx<br>
|
||||
- puis Buzzer<br>
|
||||
par defaut 4 si gps mettre 2 <br>
|
||||
- puis led<br>
|
||||
par defaut 25 <br>
|
||||
|
||||
## Version en production 1.0.0 devel 1.0.1
|
||||
|
||||
## 1.0.0
|
||||
refonte du system OS, et des pages Web<br>
|
||||
toujours avec la gestion:<br>
|
||||
- du buzzer<br>
|
||||
- du db ou smetre<br>
|
||||
- de la vbat nouvelle gestion(plus necessaire calibrage)<br>
|
||||
- suppression du mode telemetry export csv<br>
|
||||
- suppression de la bousole<br>
|
||||
- importation des RadioSonde Thank's DL9RDZ<br>
|
||||
- gestion update OTA<br>
|
||||
|
||||
## 0.9.2
|
||||
Correctif Dash SiteWeb config
|
||||
ADD API SondeHub Thank's DL9RDZ
|
||||
|
||||
## 0.9.1
|
||||
Corection RS41 <br>
|
||||
Correction DFM 06/09 <br>
|
||||
Add DFM17 <br>
|
||||
Correction for all trame recived for M10 and M20 1000ms to 1512ms,<br>
|
||||
Correction formulaire QRG, and end RS no save
|
||||
|
||||
## 0.9.0
|
||||
Add M20
|
||||
|
||||
## 0.8.8
|
||||
|
||||
Add M10+ <br>
|
||||
Add Temps restant avant impacte au sol si 99: 0. 0 soit le balon de la sonde n a pas encore éclaté, <br>
|
||||
ou les informations ne sont pas disponible actuellement <br>
|
||||
Add Test Buzzer au démarrage "Arche Perdu" Lol pour des chasseurs de sonde!<br>
|
||||
Compatible Lilygo esp32 GPS inboard pin 34 Rx, 12 Tx
|
||||
|
||||
## 0.8.7
|
||||
|
||||
correction bug Buzzer Off->On->Off <br>
|
||||
Add GainLNA RX SX1278FSK on Web config paramètre <br>
|
||||
Add update OTA Os + DataWeb <br>
|
||||
correction bugs sondmap.html <br>
|
||||
correction text upgrade Os et DataWeb <br>
|
||||
correction texte boussole S et N <br>
|
||||
correction bugs distance 4928Km si lat et lon =0 erroné <br>
|
||||
correction bugs fonction Vbat <br>
|
||||
Add Telemetry width export data.csv <br>
|
||||
Suppression µSD incompatible avec pin SX1278FSK et SPI <br>
|
||||
Add transfert Telemetry To µSD on put SD automatic
|
||||
|
||||
## 0.8.5
|
||||
|
||||
Evolution majeur du système <br>
|
||||
affichage du pourcentage de la batterie en mode scanning <br>
|
||||
création d'une fenetre Batterie, Boussole <br>
|
||||
suppresion lib et code TFT <br>
|
||||
création Azimute, elevation correction de Bugs majeur , mineur <br>
|
||||
Ajout fonction Smetre, Buzzer, QTH, Gps on off ... <br>
|
||||
mise à jour OTA <br>
|
||||
trop de modification pour toutes les expliciter!
|
||||
|
||||
## 0.8.1
|
||||
|
||||
modification de la partie Web
|
||||
|
||||
## 0.8.0
|
||||
|
||||
travail de refonte et réécriture du code
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## Les Boutons optionnel à ajouter(souder)
|
||||
sur les GPIO 1002 et 1004 <br>
|
||||
attention:
|
||||
|
||||
+3.3V--[ SW ]---GPIO----[ R1 ]---/ R1=10 ou 12KOhms
|
||||
|
||||
- appuie court <1.5 seconds <br>
|
||||
- appuie double court 0.5 seconds <br>
|
||||
- appuie moyen 2-4 seconds <br>
|
||||
- appuie long >5 seconds
|
||||
|
||||
## Buzzer optionnel à ajouter(souder)
|
||||
sur les GPIO 25 ou 12 suivant le modèl
|
||||
|
||||
GPIO --[ BUZZER ]---/
|
||||
|
||||
## Wifi configuration
|
||||
|
||||
Au démarrage, si aucune connexion possible au wifi paramètré, il monte un Wifi AP<br>
|
||||
le SSID et mot de passe par défaut est: <b>Radiosonde</b> <br>
|
||||
en mode AP, il doit être en 192.168.4.1, <br>
|
||||
mais vous avez aussi la possibilité de mettre http://radiosonde.local dans n'importe quel Wifi
|
||||
connecté.
|
||||
|
||||
|
||||
|
||||
## Mode Scanne
|
||||
|
||||
Le fichier qrg.txt contient la liste par défaut des cannaux.
|
||||
pour y configurer les noms, fréquences et mode [M=M10, 6=DFM06, 9=DFM09 et 4=RS41]
|
||||
|
||||
|
||||
## Mode Réception
|
||||
|
||||
En réception, une seul fréquence est décodé, les infos de la sonde (ID, GPS, RSSI, ...)
|
||||
seront affichées dans plusieur fenetre à choisir ( 0 à 6) à configurer dans la page Web
|
||||
rubrique config.
|
||||
In receiving mode, a single frequency will be decoded, and sonde info (ID, GPS
|
||||
coordinates, RSSI) will be displayed. The bar above the IP address indicates,
|
||||
for the last 18 frames, if reception was successfull (|) or failed (.)
|
||||
A DOUBLE press will switch to scanning mode.
|
||||
A SHORT press will switch to the next channel in channels.txt
|
||||
|
||||
## Mode Analyseur
|
||||
|
||||
Le mode analyseur de spectre (400..406 MHz) est affiché (chaque ligne == 50 kHz)
|
||||
Pour les cartes TTGO sans bouton configurable, il y a un nouveau paramètre dans config.txt:
|
||||
- spectrum=10 // 0=off / 1-99 nombre de seconds pour afficher l'analyseur
|
||||
- timer=1 // 0=off / 1= afficher le compte à rebours du spectre dans l'affichage du spectre
|
||||
- marker=1 // 0=off / 1= afficher la fréquence dans l'affichage du spectre
|
||||
|
||||
## Setup
|
||||
|
||||
voir Setup.md pour l'installation!
|
||||
|
||||
73
|
||||
Xavier
|
||||
|
||||
|
||||
|
||||
RadioSonde Version 0.9.1
|
||||
============================
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO2.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO3.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO4.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO5.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO6.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO7.jpg" width="50%"><img src="http://xavier.debert.free.fr/RS/TTGO8.jpg" width="50%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web4.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web3.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web2.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web5.png" width="20%"><img src="http://xavier.debert.free.fr/RS/Web6.png" width="20%">
|
||||
<img src="http://xavier.debert.free.fr/RS/Web7.png" width="20%">
|
||||
|
||||
|
||||
Projet basé sur le travail de DL9RDZ
|
||||
====================================
|
||||
|
||||
Pour TTGO LORA 32 esp32 pico D4 <br>
|
||||
Décodage de RadioSonde RS41/92 and DFM06/09/17 et M10+/20
|
||||
|
||||
Attention à la version de votre TTGO! <br>
|
||||
vous devez modifier dans config.txt, le port de l'écran OLED <br>
|
||||
- TTGO v1: SDA=4 SCL=15, RST=16 <br>
|
||||
- TTGO v2: SDA=21 SCL=22, RST=16
|
||||
|
||||
## Version en production 0.9.1 devel 0.9.2
|
||||
|
||||
## 0.9.1
|
||||
Corection RS41 <br>
|
||||
Correction DFM 06/09 <br>
|
||||
Add DFM17 <br>
|
||||
Correction for all trame recived for M10 and M20 1000ms to 1512ms,<br>
|
||||
Correction formulaire QRG, and end RS no save
|
||||
|
||||
## 0.9.0
|
||||
Add M20
|
||||
|
||||
## 0.8.8
|
||||
|
||||
Add M10+ <br>
|
||||
Add Temps restant avant impacte au sol si 99: 0. 0 soit le balon de la sonde n a pas encore éclaté, <br>
|
||||
ou les informations ne sont pas disponible actuellement <br>
|
||||
Add Test Buzzer au démarrage "Arche Perdu" Lol pour des chasseurs de sonde!<br>
|
||||
Compatible Lilygo esp32 GPS inboard pin 34 Rx, 12 Tx
|
||||
|
||||
## 0.8.7
|
||||
|
||||
correction bug Buzzer Off->On->Off <br>
|
||||
Add GainLNA RX SX1278FSK on Web config paramètre <br>
|
||||
Add update OTA Os + DataWeb <br>
|
||||
correction bugs sondmap.html <br>
|
||||
correction text upgrade Os et DataWeb <br>
|
||||
correction texte boussole S et N <br>
|
||||
correction bugs distance 4928Km si lat et lon =0 erroné <br>
|
||||
correction bugs fonction Vbat <br>
|
||||
Add Telemetry width export data.csv <br>
|
||||
Suppression µSD incompatible avec pin SX1278FSK et SPI <br>
|
||||
Add transfert Telemetry To µSD on put SD automatic
|
||||
|
||||
## 0.8.5
|
||||
|
||||
Evolution majeur du système <br>
|
||||
affichage du pourcentage de la batterie en mode scanning <br>
|
||||
création d'une fenetre Batterie, Boussole <br>
|
||||
suppresion lib et code TFT <br>
|
||||
création Azimute, elevation correction de Bugs majeur , mineur <br>
|
||||
Ajout fonction Smetre, Buzzer, QTH, Gps on off ... <br>
|
||||
mise à jour OTA <br>
|
||||
trop de modification pour toutes les expliciter!
|
||||
|
||||
## 0.8.1
|
||||
|
||||
modification de la partie Web
|
||||
|
||||
## 0.8.0
|
||||
|
||||
travail de refonte et réécriture du code
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## Les Boutons optionnel à ajouter(souder)
|
||||
sur les GPIO 1002 et 1004 <br>
|
||||
attention:
|
||||
|
||||
+3.3V--[ SW ]---GPIO----[ R1 ]---/ R1=10 ou 12KOhms
|
||||
|
||||
- appuie court <1.5 seconds <br>
|
||||
- appuie double court 0.5 seconds <br>
|
||||
- appuie moyen 2-4 seconds <br>
|
||||
- appuie long >5 seconds
|
||||
|
||||
## Buzzer optionnel à ajouter(souder)
|
||||
sur les GPIO 25 ou 12 suivant le modèl
|
||||
|
||||
GPIO --[ BUZZER ]---/
|
||||
|
||||
## Wifi configuration
|
||||
|
||||
Au démarrage, si aucune connexion possible au wifi paramètré, il monte un Wifi AP<br>
|
||||
le SSID et mot de passe par défaut est: <b>Radiosonde</b> <br>
|
||||
en mode AP, il doit être en 192.168.4.1, <br>
|
||||
mais vous avez aussi la possibilité de mettre http://radiosonde.local dans n'importe quel Wifi
|
||||
connecté.
|
||||
|
||||
|
||||
|
||||
## Mode Scanne
|
||||
|
||||
Le fichier qrg.txt contient la liste par défaut des cannaux.
|
||||
pour y configurer les noms, fréquences et mode [M=M10, 6=DFM06, 9=DFM09 et 4=RS41]
|
||||
|
||||
|
||||
## Mode Réception
|
||||
|
||||
En réception, une seul fréquence est décodé, les infos de la sonde (ID, GPS, RSSI, ...)
|
||||
seront affichées dans plusieur fenetre à choisir ( 0 à 6) à configurer dans la page Web
|
||||
rubrique config.
|
||||
In receiving mode, a single frequency will be decoded, and sonde info (ID, GPS
|
||||
coordinates, RSSI) will be displayed. The bar above the IP address indicates,
|
||||
for the last 18 frames, if reception was successfull (|) or failed (.)
|
||||
A DOUBLE press will switch to scanning mode.
|
||||
A SHORT press will switch to the next channel in channels.txt
|
||||
|
||||
## Mode Analyseur
|
||||
|
||||
Le mode analyseur de spectre (400..406 MHz) est affiché (chaque ligne == 50 kHz)
|
||||
Pour les cartes TTGO sans bouton configurable, il y a un nouveau paramètre dans config.txt:
|
||||
- spectrum=10 // 0=off / 1-99 nombre de seconds pour afficher l'analyseur
|
||||
- timer=1 // 0=off / 1= afficher le compte à rebours du spectre dans l'affichage du spectre
|
||||
- marker=1 // 0=off / 1= afficher la fréquence dans l'affichage du spectre
|
||||
|
||||
## Setup
|
||||
|
||||
voir Setup.md pour l'installation!
|
||||
|
||||
73
|
||||
Xavier
|
||||
|
||||
|
||||
|
||||
|
3874
RX_FSK/RX_FSK.ino
Normal file
3874
RX_FSK/RX_FSK.ino
Normal file
File diff suppressed because it is too large
Load Diff
BIN
RX_FSK/data.tar
Normal file
BIN
RX_FSK/data.tar
Normal file
Binary file not shown.
1
RX_FSK/data/GPSRESET
Normal file
1
RX_FSK/data/GPSRESET
Normal file
|
@ -0,0 +1 @@
|
|||
+
|
177
RX_FSK/data/cfg.js
Normal file
177
RX_FSK/data/cfg.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
var cfgs = [
|
||||
[ "", "General configuration", "" ],
|
||||
[ "wifi", "Wifi mode (0=off, 1=client, 2=AP, 3=client or AP autoselect on startup)" ],
|
||||
[ "mdnsname", "Network mDNS name"],
|
||||
[ "ephftp", "FTP server for ephemeris data (RS92 decoder)"],
|
||||
[ "debug", "Debug mode (0/1)" ],
|
||||
[ "maxsonde", "Maximum number of QRG entries (must be ≤ 50)" ],
|
||||
[ "rxlat", "Receiver fixed latitude"],
|
||||
[ "rxlon", "Receiver fixed longitude"],
|
||||
[ "rxalt", "Receiver fixed altitude"],
|
||||
[ "", "OLED display configuration", "" ],
|
||||
[ "screenfile", "Screen config (0=automatic; 1-2=OLED predefined; other=custom)" ],
|
||||
[ "display", "Display screens (scan, default, ...)" ],
|
||||
[ "dispsaver", "Display saver (0=never/1=always/2=ifnorx [+10*n: after n sec.])" ],
|
||||
[ "dispcontrast", "OLED contrast (-1=use default; 0..255=set contrast)" ],
|
||||
[ "norx_timeout", "No-RX-timeout in seconds (-1=disabled)"],
|
||||
[ "", "Spectrum display configuration", "" ],
|
||||
[ "spectrum", "Show spectrum on start (-1=no, 0=forever, >0=time [sec])" ],
|
||||
[ "startfreq", "Start frequency (MHz, default 400)" ],
|
||||
[ "channelbw", "Bandwidth (kHz)" ],
|
||||
[ "marker", "Spectrum MHz marker" ], // maybe remove, assume always ==1?
|
||||
[ "noisefloor", "Spectrum noisefloor" ],
|
||||
[ "", "Receiver configuration", "" ],
|
||||
[ "freqofs", "RX frequency offset (Hz)"],
|
||||
[ "rs41.agcbw", "RS41 AGC bandwidth"],
|
||||
[ "rs41.rxbw", "RS41 RX bandwidth"],
|
||||
[ "rs92.rxbw", "RS92 RX (and AGC) bandwidth"],
|
||||
[ "rs92.alt2d", "RS92 2D fix default altitude"],
|
||||
[ "dfm.agcbw", "DFM AGC bandwidth"],
|
||||
[ "dfm.rxbw", "DFM RX bandwidth"],
|
||||
[ "m10m20.agcbw", "M10/M20 AGC bandwidth"],
|
||||
[ "m10m20.rxbw", "M10/M20 RX bandwidth"],
|
||||
[ "mp3h.agcbw", "MP3H AGC bandwidth"],
|
||||
[ "mp3h.rxbw", "MP3H RX bandwidth"],
|
||||
[ "", "KISS TNC/AXUDP/AXTCP data feed configuration", ""],
|
||||
[ "call", "Call"],
|
||||
[ "passcode", "Passcode"],
|
||||
[ "kisstnc.active", "KISS TNC (port 14590) (needs reboot)"],
|
||||
[ "axudp.active", "AXUDP active"],
|
||||
[ "axudp.host", "AXUDP host"],
|
||||
[ "axudp.port", "AXUDP port"],
|
||||
[ "axudp.highrate", "Rate limit"],
|
||||
[ "tcp.active", "APRS TCP active"],
|
||||
[ "tcp.host", "APRS TCP host"],
|
||||
[ "tcp.port", "APRS TCP port"],
|
||||
[ "tcp.highrate", "Rate limit"],
|
||||
[ "tcp.objcall", "APRS object call"],
|
||||
[ "tcp.beaconsym", "APRS tracker symbol"],
|
||||
[ "tcp.chase", "APRS location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)"],
|
||||
[ "tcp.comment", "APRS location comment"],
|
||||
[ "", "MQTT data feed configuration", ""],
|
||||
[ "mqtt.active", "MQTT active (needs reboot)"],
|
||||
[ "mqtt.id", "MQTT client ID"],
|
||||
[ "mqtt.host", "MQTT server hostname"],
|
||||
[ "mqtt.port", "MQTT port"],
|
||||
[ "mqtt.username", "MQTT username"],
|
||||
[ "mqtt.password", "MQTT password"],
|
||||
[ "mqtt.prefix", "MQTT prefix"],
|
||||
[ "", "Chasemapper settings", ""],
|
||||
[ "cm.active", "Chasemapper active (0=disabled, 1=active)"],
|
||||
[ "cm.host", "Chasemapper UDP host"],
|
||||
[ "cm.port", "Chasemapper UDP port"],
|
||||
[ "", "SondeHub settings", ""],
|
||||
[ "sondehub.active", "SondeHub reporting (0=disabled, 1=active)"],
|
||||
[ "sondehub.chase", "SondeHub location reporting (0=off, 1=fixed, 2=chase/GPS, 3=auto)"],
|
||||
[ "sondehub.host", "SondeHub host (DO NOT CHANGE)"],
|
||||
[ "sondehub.callsign", "Callsign"],
|
||||
[ "sondehub.antenna", "Antenna (optional, visisble on SondeHub tracker)"],
|
||||
[ "sondehub.email", "SondeHub email (optional, only used to contact in case of upload errors)"],
|
||||
[ "", "SondeHub frequency import", "" ],
|
||||
[ "sondehub.fiactive", "SondeHub frequency import active (0=disabled, 1=active)" ],
|
||||
[ "sondehub.fiinterval", "Import frequency (minutes, ≥ 5)" ],
|
||||
[ "sondehub.fimaxdist", "Import maximum distance (km, ≤ 700)" ],
|
||||
[ "sondehub.fimaxage", "Import maximum age (hours, ≤ 48)" ],
|
||||
[ "", "Hardware configuration (requires reboot)", ""],
|
||||
[ "disptype", "Display type (0=OLED/SSD1306, 2=OLED/SH1106, 5=ST7789)"],
|
||||
[ "oled_sda", "OLED SDA/TFT SDA"],
|
||||
[ "oled_scl", "OLED SCL/TFT CLK"],
|
||||
[ "oled_rst", "OLED RST/TFT RST (needs reboot)"],
|
||||
[ "button_pin", "Button input port"],
|
||||
[ "button2_pin", "Button 2 input port"],
|
||||
[ "button2_axp", "Use AXP192 PWR as Button 2"],
|
||||
[ "touch_thresh", "Touch button threshold<br>(0 for calib mode)"],
|
||||
[ "power_pout", "Power control port"],
|
||||
[ "led_pout", "LED output port (25)"],
|
||||
|
||||
["buzzerOn", "Buzzer (0=Disabled, 1 Enable)"],
|
||||
["buzzerPort", "Buzzer Port (4)"],
|
||||
["buzzerFreq", "Buzzer Frequency (700)"],
|
||||
["dbsmetre", "dB = 0 / Smetre =1)"],
|
||||
["degdec", "Lat,Lon Decimal =0 ou Degres =1)"],
|
||||
|
||||
[ "gps_rxd", "GPS RXD pin (-1 to disable)"],
|
||||
[ "gps_txd", "GPS TXD pin (not really needed)"],
|
||||
[ "batt_adc", "Battery measurement pin"],
|
||||
[ "sx1278_ss", "SX1278 SS"],
|
||||
[ "sx1278_miso", "SX1278 MISO"],
|
||||
[ "sx1278_mosi", "SX1278 MOSI"],
|
||||
[ "sx1278_sck", "SX1278 SCK"],
|
||||
];
|
||||
|
||||
function mkcfg(id, key, label, value) {
|
||||
var s = "<tr style=\"visibility: collapse;\" class=\"cfgpanel\"><td>" + label + "</td><td><input name=\"" + key + "\" type=\"text\" value=\"" + value + "\"/></td></tr>\n";
|
||||
return s;
|
||||
}
|
||||
function mkcfgbtn(id, key, label, value) {
|
||||
var touch = "";
|
||||
var v = value;
|
||||
if(v != -1 && (v&128)) {
|
||||
touch = " checked";
|
||||
v = v & 127;
|
||||
}
|
||||
var s = "<tr style=\"visibility:collapse\" class=\"cfgpanel\"><td>" + label + "</td><td><input name=\"" + key + "\" type=\"text\" size=\"3\" value=\"" + v + "\"/>";
|
||||
s += "<input type=\"checkbox\" name=\"" + key + "#\" "+touch+"> Touch</td></tr>\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
function mksep(id,label,url) {
|
||||
return "<tr class=\"cfgheader\"><th class=\"cfg\" align=\"left\" colspan=\"2\">"+label+" <a href=\""+url+"\" target=\”_blank\">[wiki]</a></th></tr>\n";
|
||||
}
|
||||
function rowdisp(id,disp) {
|
||||
var matches = document.querySelectorAll("tr."+id);
|
||||
matches.forEach(function(e) { if(disp) e.hidden=true; else e.removeAttribute('hidden');});
|
||||
hid=id; nid="N"+id;
|
||||
if(!disp) { hid=nid; nid=id; }
|
||||
document.querySelector("span."+hid).hidden=true;
|
||||
document.querySelector("span."+nid).removeAttribute('hidden');
|
||||
}
|
||||
function configTable() {
|
||||
// iterate over cfgs
|
||||
var tab = "<table width=\"100%\"><tr><th>Option</th><th>Value</th></tr>\n";
|
||||
var id=0;
|
||||
for(i=0; i<cfgs.length; i++) {
|
||||
var key = cfgs[i][0];
|
||||
var lbl = cfgs[i][1];
|
||||
if(key) {
|
||||
if(key=="button_pin" || key=="button2_pin") {
|
||||
tab += mkcfgbtn("s"+id, key, lbl, cf.get(key));
|
||||
} else if (key=="display") {
|
||||
tab += mkcfg("s"+id, key, lbl, cf.get(key));
|
||||
tab += "<tr style=\"visibility:collapse\" class=\"cfgpanel\"><td>"+scr+"</td><td></td></tr>"
|
||||
} else {
|
||||
tab += mkcfg("s"+id, key, lbl, cf.get(key));
|
||||
}
|
||||
} else {
|
||||
id++;
|
||||
tab += mksep("s"+id, lbl, cfgs[i][2]);
|
||||
}
|
||||
}
|
||||
tab += "</table>";
|
||||
var cfgdiv = document.getElementById("cfgtab");
|
||||
cfgdiv.innerHTML = tab;
|
||||
// enable collapse / expand of items below a header
|
||||
var acc = document.getElementsByClassName("cfgheader");
|
||||
for(i=0; i<acc.length; i++) {
|
||||
acc[i].firstChild.innerHTML = "[+] " + acc[i].firstChild.innerHTML;
|
||||
acc[i].addEventListener("click", function(e) {
|
||||
if(e.target.nodeName=="A") return;
|
||||
achar = "[+]";
|
||||
if(this.classList.toggle("active")) achar = "[\u2212]";
|
||||
this.firstChild.innerHTML = achar + this.firstChild.innerHTML.substring(3);
|
||||
var panel = this;
|
||||
console.log(panel);
|
||||
while( panel = panel.nextElementSibling) {
|
||||
console.log(panel);
|
||||
if ( panel.className!="cfgpanel") { break; }
|
||||
if(panel.style.visibility==="collapse") {
|
||||
panel.style.visibility="visible";
|
||||
} else {
|
||||
console.log("none");
|
||||
panel.style.visibility="collapse";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
acc[0].click();
|
||||
}
|
150
RX_FSK/data/config.txt
Normal file
150
RX_FSK/data/config.txt
Normal file
|
@ -0,0 +1,150 @@
|
|||
#-------------------------------#
|
||||
# Hardware depending settings
|
||||
#-------------------------------#
|
||||
# pin: 255=disabled; x=button x+128=touch button
|
||||
#button_pin=130
|
||||
#button2_pin=142
|
||||
# No specification in config file: try autodetection (gpio4 pin level at startup)
|
||||
#button_pin=0
|
||||
#button2_pin=255
|
||||
#button2_axp=0
|
||||
# LED port
|
||||
#led_pout=-1
|
||||
# OLED Setup is depending on hardware of LoRa board
|
||||
# TTGO v1: SDA=4 SCL=15, RST=16
|
||||
# TTGO v2: SDA=21 SCL=22, RST=16
|
||||
# T-BEAM, OLED: SDA=21, SCL=22, RST=16
|
||||
# T-BEAM, ILI9225: SDA=4, CLK=21, RS=2, RST=22, CS=0
|
||||
# No specification in config file: try autodetection (gpio4 pin level at startup)
|
||||
#
|
||||
# disptype: 0=OLED, 1=ILI9225
|
||||
#disptype=0
|
||||
#oled_sda=21
|
||||
#oled_scl=22
|
||||
#oled_rst=16
|
||||
rxlat=
|
||||
rxlon=
|
||||
rxalt=
|
||||
oled_orient=1
|
||||
#gps_rxd=-1
|
||||
#gps_txd=-1
|
||||
# Frequency correction, in Hz
|
||||
# freqofs=0
|
||||
#-------------------------------#
|
||||
# General config settings
|
||||
#-------------------------------#
|
||||
maxsonde=20
|
||||
debug=0
|
||||
# wifi mode: 1=client in background; 2=AP in background; 3=client on startup, ap if failure
|
||||
wifi=3
|
||||
# TCP/IP KISS TNC in port 14590 for APRSdroid (0=disabled, 1=enabled)
|
||||
kisstnc.active = 1
|
||||
|
||||
# which screens file to use (0: automated selection based on display type and orientation, i>0: screens${i}.txt
|
||||
# predefined: 1: for OLED, 2: for ILI9225; 3: for ILI9225 (portrait mode); 4: for ILI9431; 5: for ILI9431 (portrait mode)
|
||||
# screenfile=2
|
||||
# display configuration. List of "displays"
|
||||
# first entry: "Scanner" display
|
||||
# second entry: default "Receiver" display
|
||||
# additional entries: alternative receiver display, activated by button
|
||||
display=0,1,2,3,4,5,6,7
|
||||
# turn off display: 0=never, 1=always, 2=if no RX; (+n*10: after n seconds)
|
||||
dispsaver=0
|
||||
# set OLED contrast (0..255) or leave at factory default (-1)
|
||||
dispcontrast=-1
|
||||
# set to -1 to disable (used for "N" values in timers in screens.txt). Value in seconds
|
||||
norx_timeout=20
|
||||
#Add F4IYT
|
||||
buzzerOn=1
|
||||
buzzerPort=25
|
||||
buzzerFreq=700
|
||||
dbsmetre=1
|
||||
#-------------------------------#
|
||||
# Spectrum display settings
|
||||
#-------------------------------#
|
||||
startfreq=400
|
||||
channelbw=10
|
||||
spectrum=-1 #10
|
||||
noisefloor=-125
|
||||
marker=1
|
||||
#-------------------------------#
|
||||
# APRS settings
|
||||
#-------------------------------#
|
||||
call=N0CALL
|
||||
passcode=12345
|
||||
#-------------------------------#
|
||||
# Sonde specific settings: bandwidth
|
||||
# valid values: 3100, 3900, 5200, 6300, 7800, 10400, 12500,
|
||||
# 15600, 20800, 25000, ...
|
||||
# other values will be rounded up to the next valid value
|
||||
# rs92.alt2d: default altitude used by RS92 decoder if only 3 sats available
|
||||
#-------------------------------#
|
||||
rs41.agcbw=12500
|
||||
rs41.rxbw=6300
|
||||
rs92.rxbw=12500
|
||||
rs92.alt2d=480
|
||||
dfm.agcbw=20800
|
||||
dfm.rxbw=10400
|
||||
#-------------------------------#
|
||||
# ftp server for RINEX data (for RS92)
|
||||
# YYYY/DDD/brdcDDD0.YYn.gz is appended
|
||||
# s1: igs.bkg.bund.de/IGS/BRDC/
|
||||
# s2: www.ngs.noaa.gov/cors/rinex/
|
||||
#-------------------------------#
|
||||
#ephftp=www.ngs.noaa.gov/cors/rinex/
|
||||
#ephftp=igs.bkg.bund.de/IGS/BRDC/
|
||||
ephftp=gssc.esa.int/gnss/data/daily/
|
||||
#-------------------------------#
|
||||
# axudp for sending to aprsmap
|
||||
#-------------------------------#
|
||||
# local use only, do not feed to public services
|
||||
# data not sanitized / quality checked, outliers not filtered out
|
||||
axudp.active=1
|
||||
axudp.host=192.168.42.20
|
||||
axudp.port=9002
|
||||
axudp.symbol=/O
|
||||
axudp.highrate=1
|
||||
#-------------------------------#
|
||||
# connect to some aprs server
|
||||
#-------------------------------#
|
||||
tcp.active=0
|
||||
tcp.host=radiosondy.info
|
||||
tcp.port=14590
|
||||
tcp.symbol=/O
|
||||
tcp.highrate=20
|
||||
# send beacon (possibly with different call or SSID)
|
||||
tcp.chase=0
|
||||
tcp.objcall=
|
||||
tcp.beaconsym=/`/(
|
||||
tcp.comment=
|
||||
#-------------------------------#
|
||||
# mqtt settings
|
||||
#-------------------------------#
|
||||
# data not sanitized / quality checked, outliers not filtered out
|
||||
mqtt.active=0
|
||||
mqtt.id=rdz_sonde_server
|
||||
mqtt.ip=192.168.1.5
|
||||
mqtt.port=1883
|
||||
mqtt.username=
|
||||
mqtt.password=
|
||||
mqtt.prefix=rdz_sonde_server/
|
||||
#-------------------------------#
|
||||
# Sondehub v2 settings
|
||||
#-------------------------------#
|
||||
# Sondehub v2 DB settings
|
||||
sondehub.active=0
|
||||
sondehub.chase=3
|
||||
sondehub.host=api.v2.sondehub.org
|
||||
sondehub.callsign=CHANGEME_RDZTTGO
|
||||
sondehub.antenna=
|
||||
sondehub.email=
|
||||
#-------------------------------#
|
||||
# Sondehub freq import settings
|
||||
#-------------------------------#
|
||||
shfimp.active=0
|
||||
shfimp.interval=60
|
||||
shfimp.maxdist=150
|
||||
shfimp.maxage=6
|
||||
#-------------------------------#
|
||||
# EOF
|
||||
#-------------------------------#
|
BIN
RX_FSK/data/fontawesome-webfont.eot
Executable file
BIN
RX_FSK/data/fontawesome-webfont.eot
Executable file
Binary file not shown.
BIN
RX_FSK/data/fontawesome-webfont.woff
Executable file
BIN
RX_FSK/data/fontawesome-webfont.woff
Executable file
Binary file not shown.
193
RX_FSK/data/index.html
Executable file
193
RX_FSK/data/index.html
Executable file
|
@ -0,0 +1,193 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>RadioSonde (version %VERSION_ID%)</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" href="data:,">
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body style="background-color: #008CBA;">
|
||||
<div style="background-color: #FFFFFF;">
|
||||
<h2><i onclick="w3_open()" class="fa fa-bars"></i> RadioSonde (version %VERSION_ID%)</h2>
|
||||
</div>
|
||||
<!--
|
||||
<p>GPIO state: <strong> %STATE%</strong></p>
|
||||
<p><a href="/on"><button class="button">ON</button></a></p>
|
||||
<p><a href="/off"><button class="button button2">OFF</button></a></p>
|
||||
-->
|
||||
|
||||
<!-- Side Navigation -->
|
||||
<nav style="text-align: left; background-color: #aaa; font-weight: bold; display:none" id="mySidebar">
|
||||
<h3>MENU</h3>
|
||||
<button class="tablinks fa fa-close" onclick="w3_close();"> Close</button><br>
|
||||
<button class="tablinks fa fa-dashboard" onclick="selTab(event,'QRG'); w3_close()" id="defaultTab"> QRG</button><br>
|
||||
<button class="tablinks fa fa-wifi" onclick="selTab(event,'WiFi'); w3_close()"> WiFi</button><br>
|
||||
<button class="tablinks fa fa-database" onclick="selTab(event,'Data'); w3_close()"> Data</button><br>
|
||||
<button class="tablinks fa fa-map-marker" onclick="selTab(event,'Map'); w3_close()"> Map</button><br>
|
||||
<button class="tablinks fa fa-map-marker" onclick="document.location.href='livemap.html'"> Livemap</button><br>
|
||||
<button class="tablinks fa fa-gears" onclick="selTab(event,'Config'); w3_close()"> Config</button><br>
|
||||
<button class="tablinks fa fa-sliders" onclick="selTab(event,'Control'); w3_close()"> Control</button><br>
|
||||
<button class="tablinks fa fa-download" onclick="selTab(event,'Update'); w3_close()"> Update</button><br>
|
||||
<button class="tablinks fa fa-support" onclick="selTab(event,'About'); w3_close()"> About</button><br><br><br><br>
|
||||
</nav>
|
||||
|
||||
<div id="QRG" class="tabcontent">
|
||||
<h3> QRG - Setup</h3>
|
||||
<iframe src="qrg.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="WiFi" class="tabcontent">
|
||||
<h3> WiFi - Settings</h3>
|
||||
<iframe src="wifi.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="Data" class="tabcontent" data-src="status.html">
|
||||
<h3>Data</h3>
|
||||
<iframe src="status.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="Map" class="tabcontent" data-src="map.html">
|
||||
<iframe src="map.html" style="border:none;" width="98%%" height="98%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="LiveMap" class="tabcontent" data-src="livemap.html">
|
||||
<iframe src="livemap.html" style="border:none;" width="98%%" height="98%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="Config" class="tabcontent">
|
||||
<h3>Configuration</h3>
|
||||
<iframe src="config.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="Control" class="tabcontent">
|
||||
<h3>Control</h3>
|
||||
<iframe src="control.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="Update" class="tabcontent">
|
||||
<h3>Update</h3>
|
||||
<iframe src="update.html" style="border:none;" width="100%%" height="100%%"></iframe>
|
||||
</div>
|
||||
<div id="Telemetry" class="tabcontent">
|
||||
<h3>Telemetry</h3>
|
||||
<button onclick="javascript:window.open('/download','_self');">Telemetry</button>
|
||||
</div>
|
||||
<div id="About" class="tabcontent">
|
||||
%VERSION_NAME%<br>
|
||||
CopyLeft 2020-2022 Modifier par <a href="http://openpmr.fr.nf/">Xav, FRS2013</a> & Vigor<br>
|
||||
<a href="#Update">Check for update (requires TTGO internet connection via WiFi)</a><br><br>
|
||||
<br>
|
||||
(version %VERSION_ID%)
|
||||
<br>
|
||||
Original project by Hansi<br>
|
||||
Copyright © 2019-2022 by Hansi Reiser, DL9RDZ<br>
|
||||
<br><br>
|
||||
Autodetect info: %AUTODETECT_INFO%<br>
|
||||
<br>
|
||||
RS92 RINEX eph state: %EPHSTATE%<br>
|
||||
<br>
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.<br>
|
||||
See <a href="https://www.gnu.org/licenses/gpl-2.0.txt">https://www.gnu.org/licenses/gpl-2.0.txt</a>
|
||||
for details.
|
||||
</div>
|
||||
|
||||
<div style="background-color: #008CBA;"><br>
|
||||
<div class="footer"><span></span><span class="ttgoinfo">RadioSonde %VERSION_ID%</span></div>
|
||||
</div>
|
||||
<script>
|
||||
function selTab(evt, id) {
|
||||
var i, tabcontent, tablinks;
|
||||
tabcontent=document.getElementsByClassName("tabcontent");
|
||||
for(i=0; i<tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = "none";
|
||||
var link = tabcontent[i].dataset.src;
|
||||
if(link) {
|
||||
var iframe = tabcontent[i].getElementsByTagName("iframe")[0];
|
||||
iframe.setAttribute("src", "");
|
||||
}
|
||||
}
|
||||
tablinks=document.getElementsByClassName("tablinks");
|
||||
for(i=0; i<tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||||
}
|
||||
var act = document.getElementById(id);
|
||||
act.style.display = "block";
|
||||
evt.currentTarget.className += " active";
|
||||
|
||||
var link = act.dataset.src;
|
||||
if(link) {
|
||||
var iframe = act.getElementsByTagName("iframe")[0];
|
||||
iframe.setAttribute("src", link);
|
||||
}
|
||||
}
|
||||
document.getElementById("defaultTab").click();
|
||||
</script>
|
||||
<!-- Script for Sidebar, Tabs, Accordions, Progress bars and slideshows -->
|
||||
<script>
|
||||
// Side navigation
|
||||
function w3_open() {
|
||||
var x = document.getElementById("mySidebar");
|
||||
x.style.width = "100%";
|
||||
x.style.height = "80%";
|
||||
x.style.fontSize = "40px";
|
||||
x.style.paddingTop = "0%";
|
||||
x.style.display = "block";
|
||||
}
|
||||
function w3_close() {
|
||||
document.getElementById("mySidebar").style.display = "none";
|
||||
}
|
||||
|
||||
// Tabs
|
||||
function openCity(evt, cityName) {
|
||||
var i;
|
||||
var x = document.getElementsByClassName("city");
|
||||
for (i = 0; i < x.length; i++) {
|
||||
x[i].style.display = "none";
|
||||
}
|
||||
var activebtn = document.getElementsByClassName("testbtn");
|
||||
for (i = 0; i < x.length; i++) {
|
||||
activebtn[i].className = activebtn[i].className.replace(" w3-dark-grey", "");
|
||||
}
|
||||
document.getElementById(cityName).style.display = "block";
|
||||
evt.currentTarget.className += " w3-dark-grey";
|
||||
}
|
||||
|
||||
var mybtn = document.getElementsByClassName("testbtn")[0];
|
||||
mybtn.click();
|
||||
|
||||
// Accordions
|
||||
function myAccFunc(id) {
|
||||
var x = document.getElementById(id);
|
||||
if (x.className.indexOf("w3-show") == -1) {
|
||||
x.className += " w3-show";
|
||||
} else {
|
||||
x.className = x.className.replace(" w3-show", "");
|
||||
}
|
||||
}
|
||||
|
||||
// Slideshows
|
||||
var slideIndex = 1;
|
||||
|
||||
function plusDivs(n) {
|
||||
slideIndex = slideIndex + n;
|
||||
showDivs(slideIndex);
|
||||
}
|
||||
|
||||
function showDivs(n) {
|
||||
var x = document.getElementsByClassName("mySlides");
|
||||
if (n > x.length) {slideIndex = 1}
|
||||
if (n < 1) {slideIndex = x.length} ;
|
||||
for (i = 0; i < x.length; i++) {
|
||||
x[i].style.display = "none";
|
||||
}
|
||||
x[slideIndex-1].style.display = "block";
|
||||
}
|
||||
|
||||
showDivs(1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
18
RX_FSK/data/livemap.html
Normal file
18
RX_FSK/data/livemap.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>RadioSonde LiveMap</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<link rel="stylesheet" type="text/css" href="style_map.css" />
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.8.0/dist/leaflet.css" />
|
||||
<script>var mapcenter=[%MAPCENTER%];</script>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://unpkg.com/leaflet@1.8.0/dist/leaflet.js"></script>
|
||||
<script src="https://unpkg.com/leaflet.marker.slideto@0.2.0/Leaflet.Marker.SlideTo.js"></script>
|
||||
<script src="livemap.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map"></div>
|
||||
</body>
|
||||
</html>
|
530
RX_FSK/data/livemap.js
Normal file
530
RX_FSK/data/livemap.js
Normal file
|
@ -0,0 +1,530 @@
|
|||
try {
|
||||
var check = $(document);
|
||||
} catch (e) {
|
||||
document.addEventListener("DOMContentLoaded", function(event) {
|
||||
document.getElementById('map').innerHTML = '<br /><br />In order to use this functionality, there must be an internet connection.<br /><br/><a href="livemap.html">retry</a><br /><br/><a href="index.html">go back</a>';
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
var map = L.map('map', { attributionControl: false, zoomControl: false });
|
||||
map.on('mousedown touchstart',function () { follow=false; });
|
||||
|
||||
L.control.scale().addTo(map);
|
||||
L.control.attribution({prefix:false}).addTo(map);
|
||||
|
||||
var osmlight = L.tileLayer('https://{s}.tile.openstreetmap.de/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
});
|
||||
|
||||
var osmdark = L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
maxZoom: 19
|
||||
});
|
||||
|
||||
var opentopo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 17,
|
||||
attribution: 'Map data: © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org">SRTM</a><br />Map style: © <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
|
||||
});
|
||||
|
||||
var esri = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
|
||||
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye,<br />Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community',
|
||||
maxZoom: 21
|
||||
});
|
||||
|
||||
var basemap;
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
map.addLayer(osmdark);
|
||||
basemap='osmdark';
|
||||
} else {
|
||||
map.addLayer(osmlight);
|
||||
basemap='osmlight';
|
||||
}
|
||||
|
||||
basemap_change = function () {
|
||||
if (basemap == 'osmlight') {
|
||||
map.removeLayer(osmlight);
|
||||
map.addLayer(opentopo);
|
||||
basemap = 'opentopo';
|
||||
} else if (basemap == 'opentopo') {
|
||||
map.removeLayer(opentopo);
|
||||
map.addLayer(esri);
|
||||
basemap = 'esri';
|
||||
} else if (basemap == 'esri') {
|
||||
map.removeLayer(esri);
|
||||
map.addLayer(osmdark);
|
||||
basemap = 'osmdark';
|
||||
} else {
|
||||
map.removeLayer(osmdark);
|
||||
map.addLayer(osmlight);
|
||||
basemap = 'osmlight';
|
||||
}
|
||||
};
|
||||
|
||||
if(mapcenter) map.setView(mapcenter, 5);
|
||||
else map.setView([51.163361,10.447683], 5); // Mitte DE
|
||||
|
||||
var reddot = '<span class="ldot rbg"></span>';
|
||||
var yellowdot = '<span class="ldot ybg"></span>';
|
||||
var greendot = '<span class="ldot gbg"></span>';
|
||||
var lastframe = 0;
|
||||
|
||||
$('#map .leaflet-control-container').append(L.DomUtil.create('div', 'leaflet-top leaflet-center leaflet-header'));
|
||||
var header = '';
|
||||
header += '<div id="sonde_main"><b>rdzTTGOSonde LiveMap</b><br />🎈 <b><span id="sonde_id"></span> - <span id="sonde_freq"></span> MHz - <span id="sonde_type"></span></b></div>';
|
||||
header += '<div id="sonde_detail"><span id="sonde_alt"></span>m | <span id="sonde_climb"></span>m/s | <span id="sonde_speed"></span>km/h | <span id="sonde_dir"></span>°<br /><span id="sonde_time"></span> | -<span id="sonde_rssi"></span>dBm</div>';
|
||||
header += '<div id="sonde_status"><span id="sonde_statbar"></span></div>';
|
||||
header += '<div id="settings"><br /><b>Prediction-Settings</b><br />';
|
||||
|
||||
header += '<label for="burst">Burst at:</label><input type="text" id="burst" maxlength="5" value="..." /> m<br />';
|
||||
header += '<label for="overwrite_descend">Descending:</label><input type="text" id="overwrite_descend" maxlength="2" value="..." /> m/s<br />';
|
||||
header += '<label for="overwrite_descend_till">Use this descending until:</label><input type="text" id="overwrite_descend_till" maxlength="5" value="..." /> m<br />';
|
||||
header += '<small>after the transmitted descend will be used</small>';
|
||||
header += '<div id="submit"><input type="button" value="save" onclick="settings_save();"/> <input type="button" id="submit" value="reset" onclick="settings_reset();"/></div>';
|
||||
header += '</div>';
|
||||
$('.leaflet-header').append(header);
|
||||
|
||||
|
||||
$('#map .leaflet-control-container').append(L.DomUtil.create('div', 'leaflet-bottom leaflet-center leaflet-footer'));
|
||||
var footer = '';
|
||||
footer += '<div id="gps_main"><b>Direction: </b><span class="gps_dir">...</span>°<br /><b>Distance: </b><span class="gps_dist">...</span>m</div>';
|
||||
$('.leaflet-footer').append(footer);
|
||||
|
||||
var statbar = '';
|
||||
headtxt = function(data,stat) {
|
||||
var staticon = (stat == '1')?greendot:yellowdot;
|
||||
statbar = staticon + statbar;
|
||||
if ((statbar.length) > 10*greendot.length) { statbar = statbar.substring(0,10*greendot.length); }
|
||||
if (data.id && data.vframe != lastframe ) {
|
||||
lastframe = data.vframe;
|
||||
$('#sonde_id').html(data.id);
|
||||
$('#sonde_alt').html(data.alt);
|
||||
$('#sonde_climb').html(data.climb);
|
||||
$('#sonde_speed').html( mr(data.speed * 3.6 * 10) / 10 );
|
||||
$('#sonde_dir').html(data.dir);
|
||||
$('#sonde_time').html(new Date(data.time * 1000).toISOString());
|
||||
$('#sonde_rssi').html(data.rssi / 2 );
|
||||
$('#sonde_detail').show();
|
||||
} else {
|
||||
if (!data.id) {
|
||||
$('#sonde_id').html(data.launchsite.trim());
|
||||
// $('#sonde_detail').hide();
|
||||
}
|
||||
}
|
||||
$('#sonde_freq').html(data.freq);
|
||||
$('#sonde_type').html(data.type);
|
||||
$('#sonde_statbar').html(' '+statbar);
|
||||
};
|
||||
|
||||
map.addControl(new L.Control.Button([ { position: 'topleft', text: '🔙', href: 'index.html' } ]));
|
||||
|
||||
L.control.zoom({ position:'topleft' }).addTo(map);
|
||||
|
||||
map.addControl(new L.Control.Button([ { position: 'topleft', text: '🗺️', href: 'javascript:basemap_change();' } ]));
|
||||
|
||||
map.addControl(new L.Control.Button([ { position: 'topright', id: "status", text: '', href: 'javascript:get_data();' } ]));
|
||||
|
||||
map.addControl(new L.Control.Button([
|
||||
{ position:'topright', text: '🎈', href: 'javascript:show(marker[last_id],\'marker\');' },
|
||||
{ text: '〰️', href: 'javascript:show_line();' },
|
||||
{ text: '💥', href: 'javascript:show(marker_burst[last_id],\'burst\');' },
|
||||
{ text: '🎯', href: 'javascript:show(marker_landing[last_id],\'landing\');' }
|
||||
]));
|
||||
|
||||
map.addControl(new L.Control.Button([ { position:'topright', text: '⚙️', href: 'javascript:show_settings();' } ]));
|
||||
|
||||
|
||||
|
||||
show = function(e,p) {
|
||||
if (p == 'landing') { get_predict(last_data); }
|
||||
if (e) {
|
||||
map.closePopup();
|
||||
map.setView(map._layers[e._leaflet_id].getLatLng());
|
||||
map._layers[e._leaflet_id].openPopup();
|
||||
follow = p;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
getTwoBounds = function (a,b) {
|
||||
var sW = new L.LatLng((a._southWest.lat > b._southWest.lat)?b._southWest.lat:a._southWest.lat, (a._southWest.lng > b._southWest.lng)?b._southWest.lng:a._southWest.lng);
|
||||
var nE = new L.LatLng((a._northEast.lat < b._northEast.lat)?b._northEast.lat:a._northEast.lat, (a._northEast.lng < b._northEast.lng)?b._northEast.lng:a._northEast.lng);
|
||||
|
||||
return new L.LatLngBounds(sW, nE);
|
||||
};
|
||||
|
||||
show_line = function() {
|
||||
$('.i_position, .i_landing').remove();
|
||||
map.closePopup();
|
||||
if (line[last_id]._latlngs.length != 0 && line_predict[last_id]._latlngs.length != 0) {
|
||||
map.fitBounds(getTwoBounds(line[last_id].getBounds(),line_predict[last_id].getBounds()));
|
||||
} else if (line[last_id]._latlngs.length != 0) {
|
||||
map.fitBounds(line[last_id].getBounds());
|
||||
} else if (line_predict[last_id]._latlngs.length != 0) {
|
||||
map.fitBounds(line_predict[last_id].getBounds());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
last_data = false;
|
||||
last_id = false;
|
||||
follow = 'marker';
|
||||
|
||||
marker_landing = [];
|
||||
icon_landing = L.divIcon({className: 'leaflet-landing'});
|
||||
dots_predict = [];
|
||||
line_predict = [];
|
||||
marker_burst = [];
|
||||
icon_burst = L.divIcon({className: 'leaflet-burst'});
|
||||
|
||||
marker = [];
|
||||
dots = [];
|
||||
line = [];
|
||||
|
||||
draw = function(data) {
|
||||
var stat;
|
||||
if (data.id) {
|
||||
last_id = data.id;
|
||||
// data.res: 0: ok 1: no rx (timeout), 2: crc err, >2 some other error
|
||||
if ((data.lat && data.lon && data.alt) && (lastframe != 0)) {
|
||||
var location = [data.lat,data.lon,data.alt];
|
||||
if (!marker[data.id]) {
|
||||
map.setView(location, 14);
|
||||
marker[data.id] = L.marker(location).addTo(map)
|
||||
.bindPopup(poptxt('position',data),{closeOnClick:false, autoPan:false}).openPopup();
|
||||
get_predict(data);
|
||||
} else {
|
||||
marker[data.id].slideTo(location, {
|
||||
duration: 500,
|
||||
keepAtCenter: (follow=='marker')?true:false
|
||||
})
|
||||
.setPopupContent(poptxt('position',data));
|
||||
}
|
||||
if (!dots[data.id]) { dots[data.id] = []; }
|
||||
dots[data.id].push(location);
|
||||
if (!line[data.id]) {
|
||||
line[data.id] = L.polyline(dots[data.id]).addTo(map);
|
||||
} else {
|
||||
line[data.id].setLatLngs(dots[data.id]);
|
||||
}
|
||||
|
||||
}
|
||||
if (data.res == 0) {
|
||||
storage_write(data);
|
||||
$('#status').html(greendot);
|
||||
stat = 1;
|
||||
} else {
|
||||
$('#status').html(yellowdot);
|
||||
stat = 0;
|
||||
}
|
||||
headtxt(data,stat);
|
||||
last_data = data;
|
||||
} else {
|
||||
$('#status').html(yellowdot);
|
||||
headtxt(data,0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
marker_gps = false;
|
||||
icon_gps = L.divIcon({className: 'leaflet-gps'});
|
||||
circ_gps = false;
|
||||
|
||||
gps = function(e) {
|
||||
gps_location = [e.lat,e.lon];
|
||||
gps_accuracy = e.hdop*2;
|
||||
|
||||
if (last_data && last_data.lat != '0.000000') {
|
||||
if ($('.leaflet-footer').css('display') == 'none') { $('.leaflet-footer').show(); }
|
||||
|
||||
var distance = Math.round(map.distance(gps_location,[last_data.lat, last_data.lon]));
|
||||
distance = (distance > 1000)?(distance / 1000) + 'k':distance;
|
||||
$('.leaflet-footer .gps_dist').html(distance);
|
||||
|
||||
$('.leaflet-footer .gps_dir').html( bearing(gps_location,[last_data.lat, last_data.lon]) );
|
||||
}
|
||||
|
||||
if (!marker_gps) {
|
||||
map.addControl(new L.Control.Button([{ position: 'topleft', text: '🛰️', href: 'javascript:show(marker_gps,\'gps\');' }]));
|
||||
|
||||
marker_gps = L.marker(gps_location,{icon:icon_gps}).addTo(map)
|
||||
.bindPopup(poptxt('gps',e),{closeOnClick:false, autoPan:false});
|
||||
circ_gps = L.circle(gps_location, gps_accuracy).addTo(map);
|
||||
} else {
|
||||
marker_gps.slideTo(gps_location, {
|
||||
duration: 500,
|
||||
keepAtCenter: (follow=='gps')?true:false
|
||||
})
|
||||
.setPopupContent(poptxt('gps',e));
|
||||
circ_gps.slideTo(gps_location, { duration: 500 });
|
||||
circ_gps.setRadius(gps_accuracy);
|
||||
}
|
||||
};
|
||||
|
||||
get_data = function() {
|
||||
$('#status').html(reddot);
|
||||
$.ajax({url: 'live.json', success: (function( data ) {
|
||||
if (typeof data != "object") { data = $.parseJSON(data); }
|
||||
if (data.sonde) {
|
||||
draw(data.sonde);
|
||||
} else {
|
||||
setTimeout(function() {$('#status').html(yellowdot);},100);
|
||||
}
|
||||
if (data.gps) {
|
||||
gps(data.gps);
|
||||
}
|
||||
}),
|
||||
timeout: 1000}
|
||||
);
|
||||
};
|
||||
|
||||
storage = (typeof(Storage) !== "undefined")?true:false;
|
||||
|
||||
settings_std = {
|
||||
burst: 32500,
|
||||
overwrite_descend: 6,
|
||||
overwrite_descend_till: 12000
|
||||
};
|
||||
|
||||
settings_read = function() {
|
||||
if (storage) {
|
||||
if (sessionStorage.settings) {
|
||||
return JSON.parse(sessionStorage.settings);
|
||||
} else {
|
||||
settings_write(settings_std);
|
||||
return settings_std;
|
||||
}
|
||||
} else {
|
||||
return settings_std;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
settings_write = function (data) {
|
||||
if (storage) {
|
||||
sessionStorage.settings = JSON.stringify(data);
|
||||
settings = data;
|
||||
}
|
||||
};
|
||||
|
||||
settings = settings_read();
|
||||
|
||||
settings_save = function() {
|
||||
settings.burst = parseInt($('#settings #burst').val());
|
||||
settings.overwrite_descend = parseInt($('#settings #overwrite_descend').val());
|
||||
settings.overwrite_descend_till = parseInt($('#settings #overwrite_descend_till').val());
|
||||
if (Number.isInteger(settings.burst) && Number.isInteger(settings.overwrite_descend) && Number.isInteger(settings.overwrite_descend_till)) {
|
||||
settings_write(settings);
|
||||
$("#settings").slideUp();
|
||||
get_predict(last_data);
|
||||
} else {
|
||||
alert('Error: only numeric values allowed!');
|
||||
}
|
||||
};
|
||||
|
||||
settings_reset = function() {
|
||||
if (confirm('Reset to default?')) {
|
||||
settings_write(settings_std);
|
||||
show_settings();
|
||||
}
|
||||
};
|
||||
|
||||
show_settings = function() {
|
||||
$('#settings #burst').val(settings.burst);
|
||||
$('#settings #overwrite_descend').val(settings.overwrite_descend);
|
||||
$('#settings #overwrite_descend_till').val(settings.overwrite_descend_till);
|
||||
$("#settings").slideToggle();
|
||||
};
|
||||
|
||||
predictor = false;
|
||||
get_predict = function(data) {
|
||||
if (!data) { return; }
|
||||
var ascent = (data.climb > 0)? data.climb : 15;
|
||||
var descent = (data.climb > 0)? settings.overwrite_descend : data.climb * -1;
|
||||
|
||||
var burst;
|
||||
if (data.climb > 0) {
|
||||
burst = (data.alt > settings.burst )?data.alt + 100 : settings.burst;
|
||||
} else {
|
||||
burst = parseInt(data.alt) + 7;
|
||||
if (data.alt > settings.overwrite_descend_till ) { descent = settings.overwrite_descend; }
|
||||
}
|
||||
|
||||
var m = new Date();
|
||||
var datetime = m.getUTCFullYear() + "-" + az(m.getUTCMonth()+1) + "-" + az(m.getUTCDate()) + "T" +
|
||||
az(m.getUTCHours()) + ":" + az(m.getUTCMinutes()) + ":" + az(m.getUTCSeconds()) + "Z";
|
||||
var url = 'https://api.v2.sondehub.org/tawhiri';
|
||||
url += '?launch_latitude='+data.lat + '&launch_longitude='+tawhiri_lon(data.lon);
|
||||
url += '&launch_altitude='+data.alt + '&launch_datetime='+datetime;
|
||||
url += '&ascent_rate='+ascent + '&burst_altitude=' + burst + '&descent_rate='+descent;
|
||||
|
||||
$.getJSON(url, function( prediction ) {
|
||||
draw_predict(prediction,data);
|
||||
});
|
||||
};
|
||||
|
||||
draw_predict = function(prediction,data) {
|
||||
var ascending = prediction.prediction[0].trajectory;
|
||||
var highest = ascending[ascending.length-1];
|
||||
var highest_location = [highest.latitude,sanitize_lon(highest.longitude)];
|
||||
|
||||
var descending = prediction.prediction[1].trajectory;
|
||||
var landing = descending[descending.length-1];
|
||||
var landing_location = [landing.latitude,sanitize_lon(landing.longitude)];
|
||||
|
||||
if (!marker_landing[data.id]) {
|
||||
marker_landing[data.id] = L.marker(landing_location,{icon: icon_landing}).addTo(map)
|
||||
.bindPopup(poptxt('landing',landing),{closeOnClick:false, autoPan:false});
|
||||
} else {
|
||||
marker_landing[data.id].slideTo(landing_location, {
|
||||
duration: 500,
|
||||
keepAtCenter: (follow=='landing')?true:false
|
||||
})
|
||||
.setPopupContent(poptxt('landing',landing));
|
||||
}
|
||||
|
||||
dots_predict[data.id]=[];
|
||||
|
||||
if (data.climb > 0) {
|
||||
ascending.forEach(p => dots_predict[data.id].push([p.latitude,sanitize_lon(p.longitude)]));
|
||||
|
||||
if (!marker_burst[data.id]) {
|
||||
marker_burst[data.id] = L.marker(highest_location,{icon:icon_burst}).addTo(map).bindPopup(poptxt('burst',highest),{closeOnClick:false, autoPan:false});
|
||||
} else {
|
||||
marker_burst[data.id].slideTo(highest_location, {
|
||||
duration: 500,
|
||||
keepAtCenter: (follow=='burst')?true:false
|
||||
}).setPopupContent(poptxt('burst',highest));
|
||||
}
|
||||
}
|
||||
|
||||
descending.forEach(p => dots_predict[data.id].push([p.latitude,sanitize_lon(p.longitude)]));
|
||||
|
||||
if (!line_predict[data.id]) {
|
||||
line_predict[data.id] = L.polyline(dots_predict[data.id],{color: 'yellow'}).addTo(map);
|
||||
} else {
|
||||
line_predict[data.id].setLatLngs(dots_predict[data.id]);
|
||||
}
|
||||
|
||||
if (data.climb > 0) {
|
||||
predictor_time = 5 * 60; // ascending, every 5 min
|
||||
} else if (data.climb < 0 && data.alt > 5000) {
|
||||
predictor_time = 2 * 60; // descending, above 5km, every 2 min
|
||||
} else {
|
||||
predictor_time = 30; // descending, below 5km, every 30 sec
|
||||
}
|
||||
clearTimeout(predictor);
|
||||
predictor = setTimeout(function() {get_predict(last_data);}, predictor_time*1000);
|
||||
};
|
||||
|
||||
sanitize_lon = function(lon) {
|
||||
if (lon > 180) { return lon - 360; }
|
||||
return lon;
|
||||
}
|
||||
tawhiri_lon = function(lon) {
|
||||
if (lon < 0) { return lon + 360; }
|
||||
return lon;
|
||||
}
|
||||
|
||||
poptxt = function(t,i) {
|
||||
var lat_input = (i.id)?i.lat:i.latitude;
|
||||
var lon_input = sanitize_lon((i.id)?i.lon:i.longitude);
|
||||
|
||||
var lat = Math.round(lat_input * 1000000) / 1000000;
|
||||
var lon = Math.round(lon_input * 1000000) / 1000000;
|
||||
|
||||
var add =
|
||||
'<br /><b>Position:</b> '+lat+', '+lon+'<br />'+
|
||||
'<b>Open:</b> <a href="https://www.google.de/maps/?q='+lat+', '+lon+'" target="_blank">GMaps</a> | <a href="https://www.openstreetmap.org/?mlat='+lat+'&mlon='+lon+'&zoom=15" target="_blank">OSM</a> | <a href="geo://'+lat+','+lon+'">GeoApp</a>';
|
||||
|
||||
if (t == 'position') { return '<div class="i_position"><b>🎈 '+i.id+'</b>'+add+'</div>'; }
|
||||
if (t == 'burst') { return '<div class="i_burst"><b>💥 Predicted Burst:</b><br />'+fd(i.datetime)+' in '+mr(i.altitude)+'m'+add+'</div>'; }
|
||||
if (t == 'highest') { return '<div class="i_burst"><b>💥 Burst:</b> '+mr(i.altitude)+'m'+add+'</div>';}
|
||||
if (t == 'landing') { return '<div class="i_landing"><b>🎯 Predicted Landing:</b><br />'+fd(i.datetime)+' at '+mr(i.altitude)+'m'+add+'</div>'; }
|
||||
if (t == 'gps') { return '<div class="i_gps">Position: '+(i.lat)+','+(i.lon)+'<br />Altitude: '+i.alt+'m<br />Speed: '+mr(i.speed * 3.6 * 10)/10+'km/h '+i.dir+'°<br />Sat: '+i.sat+' Hdop:'+(i.hdop/10)+'</div>'; }
|
||||
};
|
||||
|
||||
fd = function(date) {
|
||||
var d = new Date(Date.parse(date));
|
||||
return az(d.getUTCHours()) +':'+ az(d.getUTCMinutes())+' UTC';
|
||||
};
|
||||
az = function(n) { return (n<10)?'0'+n:n; };
|
||||
mr = function(n) { return Math.round(n); };
|
||||
|
||||
storage = (typeof(Storage) !== "undefined")?true:false;
|
||||
storage_write = function (data) {
|
||||
if (storage) {
|
||||
if (sessionStorage.sonde) {
|
||||
storage_data = JSON.parse(sessionStorage.sonde);
|
||||
} else {
|
||||
storage_data = [];
|
||||
}
|
||||
if (JSON.stringify(data) != JSON.stringify(storage_data[storage_data.length - 1])) {
|
||||
storage_data.push(data);
|
||||
sessionStorage.sonde = JSON.stringify(storage_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
storage_read = function() {
|
||||
if (storage) {
|
||||
if (sessionStorage.sonde) {
|
||||
storage_data = JSON.parse(sessionStorage.sonde);
|
||||
return storage_data;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
storage_remove = function() {
|
||||
sessionStorage.removeItem('sonde');
|
||||
};
|
||||
|
||||
session_storage = storage_read();
|
||||
if (session_storage) {
|
||||
session_storage.forEach(function(d) {
|
||||
dots.push([d.lat,d.lon,d.alt]);
|
||||
session_storage_last = d;
|
||||
});
|
||||
draw(session_storage_last);
|
||||
}
|
||||
|
||||
setInterval(get_data,1000);
|
||||
|
||||
});
|
||||
|
||||
L.Control.Button = L.Control.extend({
|
||||
onAdd: function (map) {
|
||||
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
|
||||
options = this.options;
|
||||
Object.keys(options).forEach(function(key) {
|
||||
this.link = L.DomUtil.create('a', '', container);
|
||||
this.link.text = options[key].text;
|
||||
this.link.href = options[key].href;
|
||||
this.link.id = options[key].id;
|
||||
});
|
||||
|
||||
this.options.position = this.options[0].position;
|
||||
return container;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// https://github.com/makinacorpus/Leaflet.GeometryUtil/blob/master/src/leaflet.geometryutil.js#L682
|
||||
// modified to fit
|
||||
function bearing(latlng1, latlng2) {
|
||||
var rad = Math.PI / 180,
|
||||
lat1 = latlng1[0] * rad,
|
||||
lat2 = latlng2[0] * rad,
|
||||
lon1 = latlng1[1] * rad,
|
||||
lon2 = latlng2[1] * rad,
|
||||
y = Math.sin(lon2 - lon1) * Math.cos(lat2),
|
||||
x = Math.cos(lat1) * Math.sin(lat2) -
|
||||
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
|
||||
var bearing = ((Math.atan2(y, x) * 180 / Math.PI) + 360) % 360;
|
||||
bearing = bearing < 0 ? bearing-360 : bearing;
|
||||
return Math.round(bearing);
|
||||
}
|
25
RX_FSK/data/map.html
Normal file
25
RX_FSK/data/map.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
maptype = "SH"; // TODO: Get from config
|
||||
|
||||
const maps = {
|
||||
"WS": ["https://www.wettersonde.net/map.php", (s)=>"?sonde="+s, (lat,lon)=>""],
|
||||
"SH": ["https://sondehub.org/#!mt=Mapnik", (lat,lon)=>'&mz=7&qm=12h&mc=' + lat + ',' + lon],
|
||||
"RS": ["https://radiosondy.info/", (s)=>"sonde.php?sondenumber="+s, (lat,lon)=>""],
|
||||
"OW": ["https://v2.openwx.de/start.php", (s)=>"?sonde="+s, (lat,lon)=>"?mode=mobile"],
|
||||
};
|
||||
|
||||
|
||||
const data = {"gps_lat":45.62172,"gps_lon":7.02026};
|
||||
|
||||
urlarg = + maps[maptype][1] + data['gps_lat']+","+data['gps_lon'];
|
||||
|
||||
iftxt='<iframe src="' + maps[maptype][0] + urlarg +'" style="border:1px solid #00A3D3;border-radius:20px;height:98vh;width:100%"></iframe>';
|
||||
document.write(iftxt);
|
||||
document.getElementsByTagName('body')[0].innerHTML = iftxt;
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
6
RX_FSK/data/networks.txt
Executable file
6
RX_FSK/data/networks.txt
Executable file
|
@ -0,0 +1,6 @@
|
|||
Radiosonde
|
||||
Radiosonde
|
||||
Terreandro
|
||||
terrexavier
|
||||
TERREWIFI
|
||||
terrexavier
|
26
RX_FSK/data/qrg.txt
Normal file
26
RX_FSK/data/qrg.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Frequency in Mhz (format nnn.nnn)
|
||||
# Type (4=RS41, R=RS92, D=DFM (automated normal/inverted), M=M10/M20, 3=MP3H)
|
||||
# (older versions: 6=DFM6, 9=DFM9, now both treated the same as D)
|
||||
# (older versions: M=M10, 2=M20, now both treaded the same: automated M10/M20 decoding)
|
||||
# +: active, -: not active
|
||||
#
|
||||
400.000 9 + Test(FR)
|
||||
402.000 2 + Nimes(FR)
|
||||
402.800 4 + Cuneo(IT)
|
||||
403.000 6 - Ajactio(FR)
|
||||
403.200 M - OHP(FR)
|
||||
403.010 6 - Canjuers(FR)
|
||||
404.200 4 - Rome(IT)
|
||||
404.789 9 - Frejus1(FR)
|
||||
404.800 4 - Milan(IT)
|
||||
405.000 R - Frejus2(FR)
|
||||
405.789 9 - Pegomas(FR)
|
||||
403.700 4 - Cuneo2(IT)
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
400.000 D -
|
||||
# end
|
54
RX_FSK/data/rdz.js
Normal file
54
RX_FSK/data/rdz.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
let stypes=new Map();
|
||||
stypes.set('4', 'RS41');
|
||||
stypes.set('R', 'RS92');
|
||||
stypes.set('D', 'DFM');
|
||||
stypes.set('M', 'M10/M20');
|
||||
stypes.set('3', 'MP3H');
|
||||
|
||||
function footer() {
|
||||
document.addEventListener("DOMContentLoaded", function(){
|
||||
var form = document.querySelector(".wrapper");
|
||||
form.addEventListener("input", function() {
|
||||
document.querySelector(".save").disabled = false;
|
||||
});
|
||||
document.querySelector(".save").disabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
/* Used by qrg.html in RX_FSK.ino */
|
||||
function prep() {
|
||||
var stlist=document.querySelectorAll("input.stype");
|
||||
for(txt of stlist){
|
||||
var val=txt.getAttribute('value'); var nam=txt.getAttribute('name');
|
||||
if(val=='2') { val='M'; }
|
||||
var sel=document.createElement('select');
|
||||
sel.setAttribute('name',nam);
|
||||
for(stype of stypes) {
|
||||
var opt=document.createElement('option');
|
||||
opt.value=stype[0];
|
||||
opt.innerHTML=stype[1];
|
||||
if(stype[0]==val) { opt.setAttribute('selected','selected'); }
|
||||
sel.appendChild(opt);
|
||||
}
|
||||
txt.replaceWith(sel);
|
||||
}
|
||||
}
|
||||
|
||||
function qrgTable() {
|
||||
var tab=document.getElementById("divTable");
|
||||
|
||||
var table = "<table><tr><th>Ch</th><th>Active</th><th>Frequency</th><th>Decoder</th><th>Launchsite</th></tr>";
|
||||
for(i=0; i<qrgs.length; i++) {
|
||||
var ck = "";
|
||||
if(qrgs[i][0]) ck="checked";
|
||||
table += "<tr><td class=\"ch\">" + (i+1) + "</td><td class=\"act\"><input name=\"A" + (i+1) + "\" type=\"checkbox\" " + ck + "/></td>";
|
||||
table += "<td><input name=\"F" + (i+1) + "\" type=\"text\" size=7 value=\"" + qrgs[i][1] + "\"></td>";
|
||||
table += "<td><input class=\"stype\" name=\"T" + (i+1) + "\" value=\"" + qrgs[i][3] + "\"></td>";
|
||||
table += "<td><input name=\"S" + (i+1) + "\" type=\"text\" value=\"" + qrgs[i][2] +"\"></td></tr>";
|
||||
}
|
||||
table += "</table>";
|
||||
tab.innerHTML = table;
|
||||
prep();
|
||||
footer();
|
||||
}
|
||||
|
460
RX_FSK/data/screens.txt
Normal file
460
RX_FSK/data/screens.txt
Normal file
|
@ -0,0 +1,460 @@
|
|||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg) [not yet implemented, maybe some day in future]
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
#
|
||||
# Default configuration for "Scanner" display:
|
||||
# - view timer disabled; rx timer=0; norx timer = 0
|
||||
# => after 1 second immediately an action is triggered
|
||||
# (norx: go to next sonde; rx: go to default receiver display)
|
||||
# - key1 actions: D,0,F,W
|
||||
# => Button press activates default receiver view, double press does nothing
|
||||
# Mid press activates Spectrum display, long press activates Wifi scan
|
||||
# - key2 has no function
|
||||
@Scanner
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=#,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0=S
|
||||
7,5=n
|
||||
|
||||
############
|
||||
# Default configuration for "Legacy" display:
|
||||
# - view timer=-1, rx timer=-1 (disabled); norx timer=20 (or -1 for "old" behaviour)
|
||||
# => norx timer fires after not receiving a singla for 20 seconds
|
||||
# - key1 actions: +,0,F,W
|
||||
# => Button1 press: next sonde; double press => @Scanner display
|
||||
# => Mid press activates Spectrum display, long press activates Wifi scan
|
||||
# - key2 actions: 2,#,#,#
|
||||
# => BUtton2 activates display 2 (@Field)
|
||||
# - timer actions: #,#,0
|
||||
# (norx timer: if no signal for >20 seconds: go back to scanner mode)
|
||||
#
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,5=f MHz
|
||||
1,8=c
|
||||
0,0=t
|
||||
1,0=is
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
6,0=R
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
# Configuratoon for "Field" display (display 2)
|
||||
# similar to @Legacy, but no norx timer, and Key2 goes to display 4
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
# Configuration for "Field2" display (display 3)
|
||||
# similar to @Field
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
#############
|
||||
# Configuration for "GPS" display
|
||||
# not yet the final version, just for testing
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@ScannerTFT
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=#,#,#,#
|
||||
timeaction=#,D,+
|
||||
fonts=5,6
|
||||
0,0=XScan
|
||||
0,8,-3=S#:
|
||||
0,9,5=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,5=n
|
||||
|
||||
############
|
||||
@MainTFT
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
color=FFD700
|
||||
0,0=Is
|
||||
color=0000FF
|
||||
0,11,-5.5=f
|
||||
1,1,6=c
|
||||
1,12.5,-4=t
|
||||
color=00ff00
|
||||
2,0=L
|
||||
4,0=O
|
||||
color=FFA500
|
||||
2,9.5,-7=A
|
||||
3,9.5,-7=vm/s
|
||||
color=AA5522
|
||||
4,9.5,-7=hkkm/h
|
||||
color=FFFFFF
|
||||
6,2=r
|
||||
7,0=xd=
|
||||
7,2,6=gD
|
||||
7,12=gI
|
||||
|
||||
############
|
||||
@PeilungTFT
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
color=ffff00,000033
|
||||
color=bbbbbb,000000
|
||||
0,2=xN Top:
|
||||
0,8=xCourse Top:
|
||||
color=ffff00,000033
|
||||
1,0=g0NCS,48,ffff00,000044,6,33ff33,5,eeaa00
|
||||
1,8=g0CCS,48,ffff00,000044,6,55ff55,5,eeaa00
|
||||
color=ffffff,000000
|
||||
6,0=xDirection:
|
||||
6,8,4=gI
|
||||
7,0=xCOG:
|
||||
7,4,4=gC
|
||||
7,8=xturn:
|
||||
7,12,4=gB
|
||||
|
||||
|
||||
############
|
||||
@GPSdataTFT
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=xOn-board GPS:
|
||||
1,0,8=gA
|
||||
2,0,8=gO
|
||||
3,0,8=gH
|
||||
4,0,8=gC
|
||||
5,0=xGPS vs Sonde:
|
||||
6,0,8=gD
|
||||
7,0,8=gI
|
||||
7,8,8=gB
|
||||
|
||||
############
|
||||
@BatteryTFT
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=xBattery status:
|
||||
0,14=bS
|
||||
1,0=xBatt:
|
||||
1,5,5=bVV
|
||||
2,0,16=bCmA(charging)
|
||||
3,0,16=bDmA(discharging)
|
||||
4.4,0=xUSB:
|
||||
4.4,5,5=bUV
|
||||
5.4,0,10=bImA
|
||||
6.4,0=xTemp:
|
||||
6.4,5,5=bT C
|
||||
|
||||
############
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
### Alternative display layouts based on https://gist.github.com/bazjo
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@Scan.TFT.Bazjo
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=#,#,#,#
|
||||
timeaction=#,D,+
|
||||
scale=11,10
|
||||
fonts=0,2
|
||||
color=e0e0e0
|
||||
#Row 1
|
||||
0.5,0=XScanning...
|
||||
#Row 2
|
||||
3,0=xIndex
|
||||
4,0=S/
|
||||
3,9=xSite
|
||||
4,9=S
|
||||
#Row 3
|
||||
6,0=xType
|
||||
7,0=T
|
||||
6,9=xFrequency
|
||||
7,9=F
|
||||
#Row 4
|
||||
9,0=xWeb UI IP
|
||||
10,0=N
|
||||
#Row 5
|
||||
#Footer
|
||||
color=6C757D
|
||||
15,0=xScan Mode
|
||||
15,18=bVV
|
||||
|
||||
############
|
||||
@Decode/General.TFT.Bazjo
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
scale=11,10
|
||||
fonts=0,2
|
||||
#Row 1
|
||||
color=996A06
|
||||
0,0=xSerial
|
||||
0,5=t
|
||||
color=FFB10B
|
||||
1,0=Is
|
||||
color=996A06
|
||||
0,11=xFreq.
|
||||
0,16=c
|
||||
color=FFB10B
|
||||
1,11=F
|
||||
#Row 2
|
||||
color=3C5C99
|
||||
3,0=xLatitude
|
||||
color=639AFF
|
||||
4,0=L
|
||||
color=3C5C99
|
||||
3,11=xLongitude
|
||||
color=639AFF
|
||||
4,11=O
|
||||
#Row 3
|
||||
color=3C5C99
|
||||
6,0=xHoriz. Speed
|
||||
color=639AFF
|
||||
7,0=Hkkm/h
|
||||
color=3C5C99
|
||||
6,11=xVert. Speed
|
||||
color=639AFF
|
||||
7,11=Vm/s
|
||||
#Row 4
|
||||
color=99004A
|
||||
9,0=xAltitude
|
||||
color=FF007B
|
||||
10,0=A
|
||||
color=99004A
|
||||
9,11=xBearing
|
||||
color=FF007B
|
||||
10,11=GB
|
||||
#Row 5
|
||||
color=06998E
|
||||
12,0=xRSSI
|
||||
color=0AFFEF
|
||||
13,0=R
|
||||
color=06998E
|
||||
12,11=xHistory
|
||||
color=0AFFEF
|
||||
13.5,11=Q4
|
||||
#Footer
|
||||
color=6C757D
|
||||
15,0=xDecode Mode / General View
|
||||
15,18=bVV
|
||||
|
||||
|
||||
############
|
||||
@Decode/Battery.TFT.Bazjo
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
scale=11,10
|
||||
fonts=0,2
|
||||
#Row 1
|
||||
color=99001F
|
||||
0,0=xBattery Status
|
||||
0,11=xBattery Voltage
|
||||
color=FF0035
|
||||
1,0=BS
|
||||
1,11=BVV
|
||||
#Row 2
|
||||
color=99001F
|
||||
3,0=xCharge Current
|
||||
3,11=xDischarge Current
|
||||
color=FF0035
|
||||
4,0=BCmA
|
||||
4,11=BDmA
|
||||
#Row 3
|
||||
color=99001F
|
||||
6,0=xUSB Voltage
|
||||
6,11=xUSB Current
|
||||
color=FF0035
|
||||
7,0=BUV
|
||||
7,11=BImA
|
||||
#Row 4
|
||||
color=99001F
|
||||
9,0=xIC Temperature
|
||||
#9,11=xKey
|
||||
color=FF0035
|
||||
10,0=BTC
|
||||
#10,11=XValue
|
||||
#Row 5
|
||||
#12,0=xKey
|
||||
#12,11=xKey
|
||||
#13,0=XValue
|
||||
#13,11=XValue
|
||||
#Footer
|
||||
color=99001F
|
||||
15,0=xDecode Mode/Battery View
|
||||
15,18=bVV
|
||||
|
267
RX_FSK/data/screens1.txt
Normal file
267
RX_FSK/data/screens1.txt
Normal file
|
@ -0,0 +1,267 @@
|
|||
### screens1.txt: OLED display
|
||||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg b battery)
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
#
|
||||
# Default configuration for "Scanner" display:
|
||||
# - view timer disabled; rx timer=0; norx timer = 0
|
||||
# => after 1 second immediately an action is triggered
|
||||
# (norx: go to next sonde; rx: go to default receiver display)
|
||||
# - key1 actions: D,0,F,W
|
||||
# => Button press activates default receiver view, double press does nothing
|
||||
# Mid press activates Spectrum display, long press activates Wifi scan
|
||||
# - key2 has no function
|
||||
@Scanner
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=D,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,0=bVV
|
||||
#7,0=gV
|
||||
7,5=n
|
||||
|
||||
############
|
||||
# Default configuration for "Legacy" display:
|
||||
# - view timer=-1, rx timer=-1 (disabled); norx timer=20 (or -1 for "old" behaviour)
|
||||
# => norx timer fires after not receiving a singla for 20 seconds
|
||||
# - key1 actions: +,0,F,W
|
||||
# => Button1 press: next sonde; double press => @Scanner display
|
||||
# => Mid press activates Spectrum display, long press activates Wifi scan
|
||||
# - key2 actions: 2,#,#,#
|
||||
# => BUtton2 activates display 2 (@Field)
|
||||
# - timer actions: #,#,0
|
||||
# (norx timer: if no signal for >20 seconds: go back to scanner mode)
|
||||
#
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,5=f MHz
|
||||
1,8=c
|
||||
0,0=t
|
||||
1,0=is
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
6,0=R
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
# Configuratoon for "Field" display (display 2)
|
||||
# similar to @Legacy, but no norx timer, and Key2 goes to display 4
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
# Configuration for "Field2" display (display 3)
|
||||
# similar to @Field
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
#############
|
||||
# Configuration for "GPS" display
|
||||
# not yet the final version, just for testing
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
#############
|
||||
@Meteo
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=xSonde
|
||||
3,0=xData
|
||||
2,10=A
|
||||
4,0=Mt°C
|
||||
4,9=Mh%rH
|
||||
6,0=MphPa
|
||||
6,11=MbV
|
||||
|
||||
#############
|
||||
@GPS-Data
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xGPS-Data
|
||||
1,0=xLAT :
|
||||
1,6=gA
|
||||
2,0=xLONG:
|
||||
2,6=gO
|
||||
3,0=xALT :
|
||||
3,9=gH
|
||||
4,0=xSonde
|
||||
5,0=xAlt :
|
||||
5,6=a
|
||||
6,0=xDist:
|
||||
6,6=gD
|
||||
|
||||
|
276
RX_FSK/data/screens2.txt
Normal file
276
RX_FSK/data/screens2.txt
Normal file
|
@ -0,0 +1,276 @@
|
|||
## screens2.txt: TFT display (landscape)
|
||||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg b batt)
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
|
||||
############
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@ScannerTFT
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=D,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,0=bVV
|
||||
7,5=n
|
||||
|
||||
############
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,0=t
|
||||
0,5=f MHz
|
||||
1,0=is
|
||||
#1,8=c
|
||||
1,8=z
|
||||
2,0=L
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,0=O
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,0=R
|
||||
6,7=Q
|
||||
7,6=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
### Alternative display layouts based on https://gist.github.com/bazjo
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
############
|
||||
@Meteo
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=xSonde
|
||||
3,0=xData
|
||||
2,10=A
|
||||
4,0=Mt°C
|
||||
4,9=Mh%rH
|
||||
6,0=MphPa
|
||||
6,11=MbV
|
||||
|
||||
##################
|
||||
@GPS-Data
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xGPS-Data
|
||||
1,0=xLAT :
|
||||
1,6=gA
|
||||
2,0=xLONG:
|
||||
2,6=gO
|
||||
3,0=xALT :
|
||||
3,9=gH
|
||||
4,0=xSonde
|
||||
5,0=xAlt :
|
||||
5,6=a
|
||||
6,0=xDist:
|
||||
6,6=gD
|
||||
|
||||
#################
|
||||
@TelemetryData
|
||||
scale=22,13
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
fonts=5,6
|
||||
color=FFD700
|
||||
0,0,10.5=Is
|
||||
color=0000FF
|
||||
0,11,-5.5=f
|
||||
1,0,4=t
|
||||
1,10.5,-6=c
|
||||
color=00ff00
|
||||
2,0,7=L
|
||||
3,0,7=O
|
||||
color=FFA500
|
||||
2,9.5,-7=a
|
||||
2.8,9.5,-7=vm/s
|
||||
color=AA5522
|
||||
3.6,9.5,-7=hkkm/h
|
||||
color=FFFFFF
|
||||
4.4,0=xTelemetry Data:
|
||||
5.3,0=Mt C
|
||||
5.3,9=Mh%rH
|
||||
6.5,0=MphPa
|
||||
6.5,11=MbV
|
276
RX_FSK/data/screens3.txt
Normal file
276
RX_FSK/data/screens3.txt
Normal file
|
@ -0,0 +1,276 @@
|
|||
## screens2.txt: TFT display (landscape)
|
||||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg b batt)
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
|
||||
############
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@ScannerTFT
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=D,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,0=bVV
|
||||
7,5=n
|
||||
|
||||
############
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,0=t
|
||||
0,5=f MHz
|
||||
1,0=is
|
||||
#1,8=c
|
||||
1,8=z
|
||||
2,0=L
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,0=O
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,0=R
|
||||
6,7=Q
|
||||
7,6=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
### Alternative display layouts based on https://gist.github.com/bazjo
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
############
|
||||
@Meteo
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=xSonde
|
||||
3,0=xData
|
||||
2,10=A
|
||||
4,0=Mt°C
|
||||
4,9=Mh%rH
|
||||
6,0=MphPa
|
||||
6,11=MbV
|
||||
|
||||
##################
|
||||
@GPS-Data
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xGPS-Data
|
||||
1,0=xLAT :
|
||||
1,6=gA
|
||||
2,0=xLONG:
|
||||
2,6=gO
|
||||
3,0=xALT :
|
||||
3,9=gH
|
||||
4,0=xSonde
|
||||
5,0=xAlt :
|
||||
5,6=a
|
||||
6,0=xDist:
|
||||
6,6=gD
|
||||
|
||||
#################
|
||||
@TelemetryData
|
||||
scale=22,13
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
fonts=5,6
|
||||
color=FFD700
|
||||
0,0,10.5=Is
|
||||
color=0000FF
|
||||
0,11,-5.5=f
|
||||
1,0,4=t
|
||||
1,10.5,-6=c
|
||||
color=00ff00
|
||||
2,0,7=L
|
||||
3,0,7=O
|
||||
color=FFA500
|
||||
2,9.5,-7=a
|
||||
2.8,9.5,-7=vm/s
|
||||
color=AA5522
|
||||
3.6,9.5,-7=hkkm/h
|
||||
color=FFFFFF
|
||||
4.4,0=xTelemetry Data:
|
||||
5.3,0=Mt C
|
||||
5.3,9=Mh%rH
|
||||
6.5,0=MphPa
|
||||
6.5,11=MbV
|
276
RX_FSK/data/screens4.txt
Normal file
276
RX_FSK/data/screens4.txt
Normal file
|
@ -0,0 +1,276 @@
|
|||
## screens2.txt: TFT display (landscape)
|
||||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg b batt)
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
|
||||
############
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@ScannerTFT
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=D,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,0=bVV
|
||||
7,5=n
|
||||
|
||||
############
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,0=t
|
||||
0,5=f MHz
|
||||
1,0=is
|
||||
#1,8=c
|
||||
1,8=z
|
||||
2,0=L
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,0=O
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,0=R
|
||||
6,7=Q
|
||||
7,6=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
### Alternative display layouts based on https://gist.github.com/bazjo
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
############
|
||||
@Meteo
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=xSonde
|
||||
3,0=xData
|
||||
2,10=A
|
||||
4,0=Mt°C
|
||||
4,9=Mh%rH
|
||||
6,0=MphPa
|
||||
6,11=MbV
|
||||
|
||||
##################
|
||||
@GPS-Data
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xGPS-Data
|
||||
1,0=xLAT :
|
||||
1,6=gA
|
||||
2,0=xLONG:
|
||||
2,6=gO
|
||||
3,0=xALT :
|
||||
3,9=gH
|
||||
4,0=xSonde
|
||||
5,0=xAlt :
|
||||
5,6=a
|
||||
6,0=xDist:
|
||||
6,6=gD
|
||||
|
||||
#################
|
||||
@TelemetryData
|
||||
scale=22,13
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
fonts=5,6
|
||||
color=FFD700
|
||||
0,0,10.5=Is
|
||||
color=0000FF
|
||||
0,11,-5.5=f
|
||||
1,0,4=t
|
||||
1,10.5,-6=c
|
||||
color=00ff00
|
||||
2,0,7=L
|
||||
3,0,7=O
|
||||
color=FFA500
|
||||
2,9.5,-7=a
|
||||
2.8,9.5,-7=vm/s
|
||||
color=AA5522
|
||||
3.6,9.5,-7=hkkm/h
|
||||
color=FFFFFF
|
||||
4.4,0=xTelemetry Data:
|
||||
5.3,0=Mt C
|
||||
5.3,9=Mh%rH
|
||||
6.5,0=MphPa
|
||||
6.5,11=MbV
|
276
RX_FSK/data/screens5.txt
Normal file
276
RX_FSK/data/screens5.txt
Normal file
|
@ -0,0 +1,276 @@
|
|||
## screens2.txt: TFT display (landscape)
|
||||
# Definition of display content and action behaviour
|
||||
#
|
||||
# Timer: (view timer, rx timer, norx timer)
|
||||
# - value -1: timer is disabled; value>=0: timer fires after (value) seconds
|
||||
# - view timer: time since current view (display mode and sonde) was started
|
||||
# - rx timer: time since when sonde data has been received continuously (trigger immediatly after RX)
|
||||
# - norx timer: time since when no sonde data has been received continuously
|
||||
# (rx and norx timer is started after tuning a new frequency and receiving a signal or not receiving
|
||||
# anything for a 1s period)
|
||||
#
|
||||
# Actions:
|
||||
# - W: activate WiFi scan
|
||||
# - F: activate frequency spectrum display
|
||||
# - 0: activate "Scan:" display (this is basically just display mode 0)
|
||||
# - x: (1..N): activate display mode x [deprecated]
|
||||
# - >: activate next display mode
|
||||
# - D: activate default receiver display (display mode specified in config)
|
||||
# - +: advance to next active sonde from QRG config
|
||||
# - #: no action
|
||||
#
|
||||
# Display content (lower/upper case: small/large font)
|
||||
# line,column=content
|
||||
# for ILI9225 its also possible to indicate
|
||||
# line,column,width=content for text within a box of width 'width'
|
||||
# line,column,-width=content for right-justified text
|
||||
#
|
||||
# XText : Text
|
||||
# F(suffix): frequency (with suffix, e.g., " MHz")
|
||||
# L latitade
|
||||
# O lOngitute
|
||||
# A altitude
|
||||
# Hm(suffix) hor. speed m/s (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Hk(suffix) hor. speed km/h (suffix: e.g. "km/h"; no suffix=>km/h as 16x8 bitmap for SSD1306 display only)
|
||||
# V(suffix) vert. speef (suffix: e.g. "m/s"; no suffix=>m/s as 16x8 bitmap for SSD1306 display only)
|
||||
# Ix sonde ID (default/d: dxlaprs; s: short id, n: real serial number)
|
||||
# RS41,RS92: all identical R1234567
|
||||
# DFMx: ID M12345678; short ID and serial 12345678
|
||||
# M10: ID ME95231F0; short ID: M95231F0; serial 9062104592
|
||||
# Q signal quality statistics bar
|
||||
# T type string (RS41/DFM9/DFM6/RS92)
|
||||
# C afC value
|
||||
# N ip address (only tiny font)
|
||||
# S scan list entry info: l/empty: launch site name, #=entry nr, t=total entries, a=active entries, /: #/t
|
||||
# K RS41 kill timer values: Kl launch timer, Kb burst timer, Kc kill countdown
|
||||
# format: K_4: h:mm k_6: h:mm:ss k_s: sssss, nothing shown for other sonde
|
||||
# Mx telemetry value x (t temp p preassure h hyg b batt)
|
||||
# Gx GPS-related data
|
||||
# raw data from GPS: GA, GO, GH, GC: LAtitude, lOngitude, Altutide(Height), Course over ground
|
||||
# relative to sonde: GD, GI, GB: Distance, dIrection (absolute), relative Bearing
|
||||
# G0 GPS circle diagram e.g. 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
# "N" (what is on top: N=north C=course)
|
||||
# "C" (where does the arrow point to: C=course, S=sonde)
|
||||
# "S" (what is shown by the bullet: C=course, S=sonde)
|
||||
# 50: circle radius, followed by fg and bg color
|
||||
# 5: bullet radius, followed by fg color
|
||||
# 4: arrow width, followed by fg color
|
||||
# R RSSI
|
||||
# B battery(T-Beam 1.0) S=status V=Batt.Volt C=charge current D=discharge current
|
||||
# U=USB volt I=USB current T=IC temp
|
||||
#
|
||||
# fonts=x,y can be used to select font (x=small, y=large) for all items below
|
||||
# for SSD1306, x and y can be used to select one of those fonts:
|
||||
# (y should be a 1x2 font (1,5,6,7), x a small font)
|
||||
# u8x8_font_chroma48medium8_r, // 0 ** default small
|
||||
# u8x8_font_7x14_1x2_f, // 1 ** default large
|
||||
# u8x8_font_amstrad_cpc_extended_f, // 2
|
||||
# u8x8_font_5x7_f, // 3
|
||||
# u8x8_font_5x8_f, // 4
|
||||
# u8x8_font_8x13_1x2_f, // 5
|
||||
# u8x8_font_8x13B_1x2_f, // 6
|
||||
# u8x8_font_7x14B_1x2_f, // 7
|
||||
# u8x8_font_artossans8_r, // 8
|
||||
# u8x8_font_artosserif8_r, // 9
|
||||
# u8x8_font_torussansbold8_r, // 10
|
||||
# u8x8_font_victoriabold8_r, // 11
|
||||
# u8x8_font_victoriamedium8_r, // 12
|
||||
# u8x8_font_pressstart2p_f, // 13
|
||||
# u8x8_font_pcsenior_f, // 14
|
||||
# u8x8_font_pxplusibmcgathin_f, // 15
|
||||
# u8x8_font_pxplusibmcga_f, // 16
|
||||
# u8x8_font_pxplustandynewtv_f, // 17
|
||||
#
|
||||
# for ILI9225, these fonts are available:
|
||||
# Terminal6x8 // 0
|
||||
# Terminal11x16 // 1
|
||||
# Terminal12x16 // 2
|
||||
# FreeMono9pt7b, // 3
|
||||
# FreeMono12pt7b, // 4
|
||||
# FreeSans9pt7b, // 5
|
||||
# FreeSans12pt7b, // 6
|
||||
# Picopixel, // 7
|
||||
#
|
||||
# color=rrggbb,rrggbb can be used to select color (foreground, background)
|
||||
# see https://github.com/Nkawu/TFT_22_ILI9225/wiki#color-reference for example (use without "#"-sign)
|
||||
#
|
||||
# for TFT display, coordinates and width are multiplied by xscale,yscale and later used in pixels
|
||||
# with scale=1,1 you can directly use pixel coordinates. (default: xscale=13,yscale=22 => 8 lines, 16 columns)
|
||||
###########
|
||||
|
||||
############
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@ScannerTFT
|
||||
timer=-1,0,0
|
||||
key1action=D,#,F,W
|
||||
key2action=D,#,#,#
|
||||
timeaction=#,D,+
|
||||
0,0=XScan
|
||||
0,5=S#:
|
||||
0,9=T
|
||||
3,0=F MHz
|
||||
5,0,16=S
|
||||
7,0=bVV
|
||||
7,5=n
|
||||
|
||||
############
|
||||
@Legacy
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
0,0=t
|
||||
0,5=f MHz
|
||||
1,0=is
|
||||
#1,8=c
|
||||
1,8=z
|
||||
2,0=L
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,0=O
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,0=R
|
||||
6,7=Q
|
||||
7,6=gD
|
||||
7,12=gI°
|
||||
|
||||
############
|
||||
@Field
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@Field2
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
2,0=L
|
||||
4,0=O
|
||||
1,12=t
|
||||
0,9=f
|
||||
3,10=h
|
||||
4,9=v
|
||||
0,0=Is
|
||||
6,0=A
|
||||
6,7=Q
|
||||
|
||||
############
|
||||
@GPSDIST
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=L
|
||||
4,0=O
|
||||
2,10=a
|
||||
3,10=h
|
||||
4,9=v
|
||||
5,9=gC
|
||||
5,13=gB
|
||||
6,7=Q
|
||||
7,0=gV
|
||||
7,2=xd=
|
||||
7,4=gD
|
||||
7,12=gI°
|
||||
|
||||
### Alternative display layouts based on https://gist.github.com/bazjo
|
||||
# Scan display for large 2" TFT dispaly
|
||||
@BatteryOLED
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xBat.Status:
|
||||
0,12=bS
|
||||
1,0=xBatt:
|
||||
1,6=bVV
|
||||
2,0=bCmA (charge)
|
||||
3,0=bDmA (disch.)
|
||||
4,0=xUSB:
|
||||
4,5=bUV
|
||||
5,5=bImA
|
||||
6,0=xTemp:
|
||||
6,5=bT C
|
||||
|
||||
############
|
||||
@Meteo
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=Is
|
||||
0,9=f
|
||||
1,12=t
|
||||
2,0=xSonde
|
||||
3,0=xData
|
||||
2,10=A
|
||||
4,0=Mt°C
|
||||
4,9=Mh%rH
|
||||
6,0=MphPa
|
||||
6,11=MbV
|
||||
|
||||
##################
|
||||
@GPS-Data
|
||||
timer=-1,-1,-1
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,#
|
||||
fonts=0,1
|
||||
0,0=xGPS-Data
|
||||
1,0=xLAT :
|
||||
1,6=gA
|
||||
2,0=xLONG:
|
||||
2,6=gO
|
||||
3,0=xALT :
|
||||
3,9=gH
|
||||
4,0=xSonde
|
||||
5,0=xAlt :
|
||||
5,6=a
|
||||
6,0=xDist:
|
||||
6,6=gD
|
||||
|
||||
#################
|
||||
@TelemetryData
|
||||
scale=22,13
|
||||
timer=-1,-1,N
|
||||
key1action=+,0,F,W
|
||||
key2action=>,#,#,#
|
||||
timeaction=#,#,0
|
||||
fonts=5,6
|
||||
color=FFD700
|
||||
0,0,10.5=Is
|
||||
color=0000FF
|
||||
0,11,-5.5=f
|
||||
1,0,4=t
|
||||
1,10.5,-6=c
|
||||
color=00ff00
|
||||
2,0,7=L
|
||||
3,0,7=O
|
||||
color=FFA500
|
||||
2,9.5,-7=a
|
||||
2.8,9.5,-7=vm/s
|
||||
color=AA5522
|
||||
3.6,9.5,-7=hkkm/h
|
||||
color=FFFFFF
|
||||
4.4,0=xTelemetry Data:
|
||||
5.3,0=Mt C
|
||||
5.3,9=Mh%rH
|
||||
6.5,0=MphPa
|
||||
6.5,11=MbV
|
659
RX_FSK/data/style.css
Executable file
659
RX_FSK/data/style.css
Executable file
|
@ -0,0 +1,659 @@
|
|||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
background-color: #ddd
|
||||
}
|
||||
|
||||
td#caption {
|
||||
text-align: center;
|
||||
background-color: #aaa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
td#sfreq {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.tab {
|
||||
overflow: hidden;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: inherit;
|
||||
float: left;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
padding: 14px 16px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
display: none;
|
||||
padding: 6px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-top: none;
|
||||
height: 100%;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: Helvetica;
|
||||
display: inline-block;
|
||||
margin: 0px auto;
|
||||
text-align: center;
|
||||
}
|
||||
h1{
|
||||
color: #0F3376;
|
||||
padding: 2vh;
|
||||
}
|
||||
p{
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
.button {
|
||||
display: inline-block;
|
||||
background-color: #008CBA;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
padding: 16px 40px;
|
||||
text-decoration: none;
|
||||
font-size: 30px;
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.button2 {
|
||||
background-color: #f44336;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
|
||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||
*/@font-face{font-family:'FontAwesome';
|
||||
src:url('fontawesome-webfont.eot?v=4.3.0');
|
||||
src:url('fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'),url('fontawesome-webfont.woff2?v=4.3.0') format('woff2'),url('fontawesome-webfont.woff?v=4.3.0') format('woff'),url('fontawesome-webfont.ttf?v=4.3.0') format('truetype'),url('fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');
|
||||
font-weight:normal;
|
||||
font-style:normal}.fa{display:inline-block;
|
||||
font:normal normal normal 14px/1 FontAwesome;
|
||||
font-size:inherit;
|
||||
text-rendering:auto;
|
||||
-webkit-font-smoothing:antialiased;
|
||||
-moz-osx-font-smoothing:grayscale;
|
||||
transform:translate(0, 0)}.fa-lg{font-size:1.33333333em;
|
||||
line-height:.75em;
|
||||
vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;
|
||||
text-align:center}.fa-ul{padding-left:0;
|
||||
margin-left:2.14285714em;
|
||||
list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;
|
||||
left:-2.14285714em;
|
||||
width:2.14285714em;
|
||||
top:.14285714em;
|
||||
text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;
|
||||
border:solid .08em #eee;
|
||||
border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;
|
||||
animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);
|
||||
animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);
|
||||
transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);
|
||||
transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);
|
||||
transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);
|
||||
transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
|
||||
-webkit-transform:rotate(90deg);
|
||||
-ms-transform:rotate(90deg);
|
||||
transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
|
||||
-webkit-transform:rotate(180deg);
|
||||
-ms-transform:rotate(180deg);
|
||||
transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
|
||||
-webkit-transform:rotate(270deg);
|
||||
-ms-transform:rotate(270deg);
|
||||
transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
|
||||
-webkit-transform:scale(-1, 1);
|
||||
-ms-transform:scale(-1, 1);
|
||||
transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
|
||||
-webkit-transform:scale(1, -1);
|
||||
-ms-transform:scale(1, -1);
|
||||
transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;
|
||||
display:inline-block;
|
||||
width:2em;
|
||||
height:2em;
|
||||
line-height:2em;
|
||||
vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;
|
||||
left:0;
|
||||
width:100%;
|
||||
text-align:center}
|
||||
.fa-stack-1x{line-height:inherit}
|
||||
.fa-stack-2x{font-size:2em}
|
||||
.fa-inverse{color:#fff}
|
||||
.fa-glass:before{content:"\f000"}
|
||||
.fa-music:before{content:"\f001"}
|
||||
.fa-search:before{content:"\f002"}
|
||||
.fa-envelope-o:before{content:"\f003"}
|
||||
.fa-heart:before{content:"\f004"}
|
||||
.fa-star:before{content:"\f005"}
|
||||
.fa-star-o:before{content:"\f006"}
|
||||
.fa-user:before{content:"\f007"}
|
||||
.fa-film:before{content:"\f008"}
|
||||
.fa-th-large:before{content:"\f009"}
|
||||
.fa-th:before{content:"\f00a"}
|
||||
.fa-th-list:before{content:"\f00b"}
|
||||
.fa-check:before{content:"\f00c"}
|
||||
.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}
|
||||
.fa-search-plus:before{content:"\f00e"}
|
||||
.fa-search-minus:before{content:"\f010"}
|
||||
.fa-power-off:before{content:"\f011"}
|
||||
.fa-signal:before{content:"\f012"}
|
||||
.fa-gear:before,.fa-cog:before{content:"\f013"}
|
||||
.fa-trash-o:before{content:"\f014"}
|
||||
.fa-home:before{content:"\f015"}
|
||||
.fa-file-o:before{content:"\f016"}
|
||||
.fa-clock-o:before{content:"\f017"}
|
||||
.fa-road:before{content:"\f018"}
|
||||
.fa-download:before{content:"\f019"}
|
||||
.fa-arrow-circle-o-down:before{content:"\f01a"}
|
||||
.fa-arrow-circle-o-up:before{content:"\f01b"}
|
||||
.fa-inbox:before{content:"\f01c"}
|
||||
.fa-play-circle-o:before{content:"\f01d"}
|
||||
.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}
|
||||
.fa-refresh:before{content:"\f021"}
|
||||
.fa-list-alt:before{content:"\f022"}
|
||||
.fa-lock:before{content:"\f023"}
|
||||
.fa-flag:before{content:"\f024"}
|
||||
.fa-headphones:before{content:"\f025"}
|
||||
.fa-volume-off:before{content:"\f026"}
|
||||
.fa-volume-down:before{content:"\f027"}
|
||||
.fa-volume-up:before{content:"\f028"}
|
||||
.fa-qrcode:before{content:"\f029"}
|
||||
.fa-barcode:before{content:"\f02a"}
|
||||
.fa-tag:before{content:"\f02b"}
|
||||
.fa-tags:before{content:"\f02c"}
|
||||
.fa-book:before{content:"\f02d"}
|
||||
.fa-bookmark:before{content:"\f02e"}
|
||||
.fa-print:before{content:"\f02f"}
|
||||
.fa-camera:before{content:"\f030"}
|
||||
.fa-font:before{content:"\f031"}
|
||||
.fa-bold:before{content:"\f032"}
|
||||
.fa-italic:before{content:"\f033"}
|
||||
.fa-text-height:before{content:"\f034"}
|
||||
.fa-text-width:before{content:"\f035"}
|
||||
.fa-align-left:before{content:"\f036"}
|
||||
.fa-align-center:before{content:"\f037"}
|
||||
.fa-align-right:before{content:"\f038"}
|
||||
.fa-align-justify:before{content:"\f039"}
|
||||
.fa-list:before{content:"\f03a"}
|
||||
.fa-dedent:before,.fa-outdent:before{content:"\f03b"}
|
||||
.fa-indent:before{content:"\f03c"}
|
||||
.fa-video-camera:before{content:"\f03d"}
|
||||
.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}
|
||||
.fa-pencil:before{content:"\f040"}
|
||||
.fa-map-marker:before{content:"\f041"}
|
||||
.fa-adjust:before{content:"\f042"}
|
||||
.fa-tint:before{content:"\f043"}
|
||||
.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}
|
||||
.fa-share-square-o:before{content:"\f045"}
|
||||
.fa-check-square-o:before{content:"\f046"}
|
||||
.fa-arrows:before{content:"\f047"}
|
||||
.fa-step-backward:before{content:"\f048"}
|
||||
.fa-fast-backward:before{content:"\f049"}
|
||||
.fa-backward:before{content:"\f04a"}
|
||||
.fa-play:before{content:"\f04b"}
|
||||
.fa-pause:before{content:"\f04c"}
|
||||
.fa-stop:before{content:"\f04d"}
|
||||
.fa-forward:before{content:"\f04e"}
|
||||
.fa-fast-forward:before{content:"\f050"}
|
||||
.fa-step-forward:before{content:"\f051"}
|
||||
.fa-eject:before{content:"\f052"}
|
||||
.fa-chevron-left:before{content:"\f053"}
|
||||
.fa-chevron-right:before{content:"\f054"}
|
||||
.fa-plus-circle:before{content:"\f055"}
|
||||
.fa-minus-circle:before{content:"\f056"}
|
||||
.fa-times-circle:before{content:"\f057"}
|
||||
.fa-check-circle:before{content:"\f058"}
|
||||
.fa-question-circle:before{content:"\f059"}
|
||||
.fa-info-circle:before{content:"\f05a"}
|
||||
.fa-crosshairs:before{content:"\f05b"}
|
||||
.fa-times-circle-o:before{content:"\f05c"}
|
||||
.fa-check-circle-o:before{content:"\f05d"}
|
||||
.fa-ban:before{content:"\f05e"}
|
||||
.fa-arrow-left:before{content:"\f060"}
|
||||
.fa-arrow-right:before{content:"\f061"}
|
||||
.fa-arrow-up:before{content:"\f062"}
|
||||
.fa-arrow-down:before{content:"\f063"}
|
||||
.fa-mail-forward:before,.fa-share:before{content:"\f064"}
|
||||
.fa-expand:before{content:"\f065"}
|
||||
.fa-compress:before{content:"\f066"}
|
||||
.fa-plus:before{content:"\f067"}
|
||||
.fa-minus:before{content:"\f068"}
|
||||
.fa-asterisk:before{content:"\f069"}
|
||||
.fa-exclamation-circle:before{content:"\f06a"}
|
||||
.fa-gift:before{content:"\f06b"}
|
||||
.fa-leaf:before{content:"\f06c"}
|
||||
.fa-fire:before{content:"\f06d"}
|
||||
.fa-eye:before{content:"\f06e"}
|
||||
.fa-eye-slash:before{content:"\f070"}
|
||||
.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}
|
||||
.fa-plane:before{content:"\f072"}
|
||||
.fa-calendar:before{content:"\f073"}
|
||||
.fa-random:before{content:"\f074"}
|
||||
.fa-comment:before{content:"\f075"}
|
||||
.fa-magnet:before{content:"\f076"}
|
||||
.fa-chevron-up:before{content:"\f077"}
|
||||
.fa-chevron-down:before{content:"\f078"}
|
||||
.fa-retweet:before{content:"\f079"}
|
||||
.fa-shopping-cart:before{content:"\f07a"}
|
||||
.fa-folder:before{content:"\f07b"}
|
||||
.fa-folder-open:before{content:"\f07c"}
|
||||
.fa-arrows-v:before{content:"\f07d"}
|
||||
.fa-arrows-h:before{content:"\f07e"}
|
||||
.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}
|
||||
.fa-twitter-square:before{content:"\f081"}
|
||||
.fa-facebook-square:before{content:"\f082"}
|
||||
.fa-camera-retro:before{content:"\f083"}
|
||||
.fa-key:before{content:"\f084"}
|
||||
.fa-gears:before,.fa-cogs:before{content:"\f085"}
|
||||
.fa-comments:before{content:"\f086"}
|
||||
.fa-thumbs-o-up:before{content:"\f087"}
|
||||
.fa-thumbs-o-down:before{content:"\f088"}
|
||||
.fa-star-half:before{content:"\f089"}
|
||||
.fa-heart-o:before{content:"\f08a"}
|
||||
.fa-sign-out:before{content:"\f08b"}
|
||||
.fa-linkedin-square:before{content:"\f08c"}
|
||||
.fa-thumb-tack:before{content:"\f08d"}
|
||||
.fa-external-link:before{content:"\f08e"}
|
||||
.fa-sign-in:before{content:"\f090"}
|
||||
.fa-trophy:before{content:"\f091"}
|
||||
.fa-github-square:before{content:"\f092"}
|
||||
.fa-upload:before{content:"\f093"}
|
||||
.fa-lemon-o:before{content:"\f094"}
|
||||
.fa-phone:before{content:"\f095"}
|
||||
.fa-square-o:before{content:"\f096"}
|
||||
.fa-bookmark-o:before{content:"\f097"}
|
||||
.fa-phone-square:before{content:"\f098"}
|
||||
.fa-twitter:before{content:"\f099"}
|
||||
.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}
|
||||
.fa-github:before{content:"\f09b"}
|
||||
.fa-unlock:before{content:"\f09c"}
|
||||
.fa-credit-card:before{content:"\f09d"}
|
||||
.fa-rss:before{content:"\f09e"}
|
||||
.fa-hdd-o:before{content:"\f0a0"}
|
||||
.fa-bullhorn:before{content:"\f0a1"}
|
||||
.fa-bell:before{content:"\f0f3"}
|
||||
.fa-certificate:before{content:"\f0a3"}
|
||||
.fa-hand-o-right:before{content:"\f0a4"}
|
||||
.fa-hand-o-left:before{content:"\f0a5"}
|
||||
.fa-hand-o-up:before{content:"\f0a6"}
|
||||
.fa-hand-o-down:before{content:"\f0a7"}
|
||||
.fa-arrow-circle-left:before{content:"\f0a8"}
|
||||
.fa-arrow-circle-right:before{content:"\f0a9"}
|
||||
.fa-arrow-circle-up:before{content:"\f0aa"}
|
||||
.fa-arrow-circle-down:before{content:"\f0ab"}
|
||||
.fa-globe:before{content:"\f0ac"}
|
||||
.fa-wrench:before{content:"\f0ad"}
|
||||
.fa-tasks:before{content:"\f0ae"}
|
||||
.fa-filter:before{content:"\f0b0"}
|
||||
.fa-briefcase:before{content:"\f0b1"}
|
||||
.fa-arrows-alt:before{content:"\f0b2"}
|
||||
.fa-group:before,.fa-users:before{content:"\f0c0"}
|
||||
.fa-chain:before,.fa-link:before{content:"\f0c1"}
|
||||
.fa-cloud:before{content:"\f0c2"}
|
||||
.fa-flask:before{content:"\f0c3"}
|
||||
.fa-cut:before,.fa-scissors:before{content:"\f0c4"}
|
||||
.fa-copy:before,.fa-files-o:before{content:"\f0c5"}
|
||||
.fa-paperclip:before{content:"\f0c6"}
|
||||
.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}
|
||||
.fa-square:before{content:"\f0c8"}
|
||||
.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}
|
||||
.fa-list-ul:before{content:"\f0ca"}
|
||||
.fa-list-ol:before{content:"\f0cb"}
|
||||
.fa-strikethrough:before{content:"\f0cc"}
|
||||
.fa-underline:before{content:"\f0cd"}
|
||||
.fa-table:before{content:"\f0ce"}
|
||||
.fa-magic:before{content:"\f0d0"}
|
||||
.fa-truck:before{content:"\f0d1"}
|
||||
.fa-pinterest:before{content:"\f0d2"}
|
||||
.fa-pinterest-square:before{content:"\f0d3"}
|
||||
.fa-google-plus-square:before{content:"\f0d4"}
|
||||
.fa-google-plus:before{content:"\f0d5"}
|
||||
.fa-money:before{content:"\f0d6"}
|
||||
.fa-caret-down:before{content:"\f0d7"}
|
||||
.fa-caret-up:before{content:"\f0d8"}
|
||||
.fa-caret-left:before{content:"\f0d9"}
|
||||
.fa-caret-right:before{content:"\f0da"}
|
||||
.fa-columns:before{content:"\f0db"}
|
||||
.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}
|
||||
.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}
|
||||
.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}
|
||||
.fa-envelope:before{content:"\f0e0"}
|
||||
.fa-linkedin:before{content:"\f0e1"}
|
||||
.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}
|
||||
.fa-legal:before,.fa-gavel:before{content:"\f0e3"}
|
||||
.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}
|
||||
.fa-comment-o:before{content:"\f0e5"}
|
||||
.fa-comments-o:before{content:"\f0e6"}
|
||||
.fa-flash:before,.fa-bolt:before{content:"\f0e7"}
|
||||
.fa-sitemap:before{content:"\f0e8"}
|
||||
.fa-umbrella:before{content:"\f0e9"}
|
||||
.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}
|
||||
.fa-lightbulb-o:before{content:"\f0eb"}
|
||||
.fa-exchange:before{content:"\f0ec"}
|
||||
.fa-cloud-download:before{content:"\f0ed"}
|
||||
.fa-cloud-upload:before{content:"\f0ee"}
|
||||
.fa-user-md:before{content:"\f0f0"}
|
||||
.fa-stethoscope:before{content:"\f0f1"}
|
||||
.fa-suitcase:before{content:"\f0f2"}
|
||||
.fa-bell-o:before{content:"\f0a2"}
|
||||
.fa-coffee:before{content:"\f0f4"}
|
||||
.fa-cutlery:before{content:"\f0f5"}
|
||||
.fa-file-text-o:before{content:"\f0f6"}
|
||||
.fa-building-o:before{content:"\f0f7"}
|
||||
.fa-hospital-o:before{content:"\f0f8"}
|
||||
.fa-ambulance:before{content:"\f0f9"}
|
||||
.fa-medkit:before{content:"\f0fa"}
|
||||
.fa-fighter-jet:before{content:"\f0fb"}
|
||||
.fa-beer:before{content:"\f0fc"}
|
||||
.fa-h-square:before{content:"\f0fd"}
|
||||
.fa-plus-square:before{content:"\f0fe"}
|
||||
.fa-angle-double-left:before{content:"\f100"}
|
||||
.fa-angle-double-right:before{content:"\f101"}
|
||||
.fa-angle-double-up:before{content:"\f102"}
|
||||
.fa-angle-double-down:before{content:"\f103"}
|
||||
.fa-angle-left:before{content:"\f104"}
|
||||
.fa-angle-right:before{content:"\f105"}
|
||||
.fa-angle-up:before{content:"\f106"}
|
||||
.fa-angle-down:before{content:"\f107"}
|
||||
.fa-desktop:before{content:"\f108"}
|
||||
.fa-laptop:before{content:"\f109"}
|
||||
.fa-tablet:before{content:"\f10a"}
|
||||
.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}
|
||||
.fa-circle-o:before{content:"\f10c"}
|
||||
.fa-quote-left:before{content:"\f10d"}
|
||||
.fa-quote-right:before{content:"\f10e"}
|
||||
.fa-spinner:before{content:"\f110"}
|
||||
.fa-circle:before{content:"\f111"}
|
||||
.fa-mail-reply:before,.fa-reply:before{content:"\f112"}
|
||||
.fa-github-alt:before{content:"\f113"}
|
||||
.fa-folder-o:before{content:"\f114"}
|
||||
.fa-folder-open-o:before{content:"\f115"}
|
||||
.fa-smile-o:before{content:"\f118"}
|
||||
.fa-frown-o:before{content:"\f119"}
|
||||
.fa-meh-o:before{content:"\f11a"}
|
||||
.fa-gamepad:before{content:"\f11b"}
|
||||
.fa-keyboard-o:before{content:"\f11c"}
|
||||
.fa-flag-o:before{content:"\f11d"}
|
||||
.fa-flag-checkered:before{content:"\f11e"}
|
||||
.fa-terminal:before{content:"\f120"}
|
||||
.fa-code:before{content:"\f121"}
|
||||
.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}
|
||||
.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}
|
||||
.fa-location-arrow:before{content:"\f124"}
|
||||
.fa-crop:before{content:"\f125"}
|
||||
.fa-code-fork:before{content:"\f126"}
|
||||
.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}
|
||||
.fa-question:before{content:"\f128"}
|
||||
.fa-info:before{content:"\f129"}
|
||||
.fa-exclamation:before{content:"\f12a"}
|
||||
.fa-superscript:before{content:"\f12b"}
|
||||
.fa-subscript:before{content:"\f12c"}
|
||||
.fa-eraser:before{content:"\f12d"}
|
||||
.fa-puzzle-piece:before{content:"\f12e"}
|
||||
.fa-microphone:before{content:"\f130"}
|
||||
.fa-microphone-slash:before{content:"\f131"}
|
||||
.fa-shield:before{content:"\f132"}
|
||||
.fa-calendar-o:before{content:"\f133"}
|
||||
.fa-fire-extinguisher:before{content:"\f134"}
|
||||
.fa-rocket:before{content:"\f135"}
|
||||
.fa-maxcdn:before{content:"\f136"}
|
||||
.fa-chevron-circle-left:before{content:"\f137"}
|
||||
.fa-chevron-circle-right:before{content:"\f138"}
|
||||
.fa-chevron-circle-up:before{content:"\f139"}
|
||||
.fa-chevron-circle-down:before{content:"\f13a"}
|
||||
.fa-html5:before{content:"\f13b"}
|
||||
.fa-css3:before{content:"\f13c"}
|
||||
.fa-anchor:before{content:"\f13d"}
|
||||
.fa-unlock-alt:before{content:"\f13e"}
|
||||
.fa-bullseye:before{content:"\f140"}
|
||||
.fa-ellipsis-h:before{content:"\f141"}
|
||||
.fa-ellipsis-v:before{content:"\f142"}
|
||||
.fa-rss-square:before{content:"\f143"}
|
||||
.fa-play-circle:before{content:"\f144"}
|
||||
.fa-ticket:before{content:"\f145"}
|
||||
.fa-minus-square:before{content:"\f146"}
|
||||
.fa-minus-square-o:before{content:"\f147"}
|
||||
.fa-level-up:before{content:"\f148"}
|
||||
.fa-level-down:before{content:"\f149"}
|
||||
.fa-check-square:before{content:"\f14a"}
|
||||
.fa-pencil-square:before{content:"\f14b"}
|
||||
.fa-external-link-square:before{content:"\f14c"}
|
||||
.fa-share-square:before{content:"\f14d"}
|
||||
.fa-compass:before{content:"\f14e"}
|
||||
.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}
|
||||
.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}
|
||||
.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}
|
||||
.fa-euro:before,.fa-eur:before{content:"\f153"}
|
||||
.fa-gbp:before{content:"\f154"}
|
||||
.fa-dollar:before,.fa-usd:before{content:"\f155"}
|
||||
.fa-rupee:before,.fa-inr:before{content:"\f156"}
|
||||
.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}
|
||||
.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}
|
||||
.fa-won:before,.fa-krw:before{content:"\f159"}
|
||||
.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}
|
||||
.fa-file:before{content:"\f15b"}
|
||||
.fa-file-text:before{content:"\f15c"}
|
||||
.fa-sort-alpha-asc:before{content:"\f15d"}
|
||||
.fa-sort-alpha-desc:before{content:"\f15e"}
|
||||
.fa-sort-amount-asc:before{content:"\f160"}
|
||||
.fa-sort-amount-desc:before{content:"\f161"}
|
||||
.fa-sort-numeric-asc:before{content:"\f162"}
|
||||
.fa-sort-numeric-desc:before{content:"\f163"}
|
||||
.fa-thumbs-up:before{content:"\f164"}
|
||||
.fa-thumbs-down:before{content:"\f165"}
|
||||
.fa-youtube-square:before{content:"\f166"}
|
||||
.fa-youtube:before{content:"\f167"}
|
||||
.fa-xing:before{content:"\f168"}
|
||||
.fa-xing-square:before{content:"\f169"}
|
||||
.fa-youtube-play:before{content:"\f16a"}
|
||||
.fa-dropbox:before{content:"\f16b"}
|
||||
.fa-stack-overflow:before{content:"\f16c"}
|
||||
.fa-instagram:before{content:"\f16d"}
|
||||
.fa-flickr:before{content:"\f16e"}
|
||||
.fa-adn:before{content:"\f170"}
|
||||
.fa-bitbucket:before{content:"\f171"}
|
||||
.fa-bitbucket-square:before{content:"\f172"}
|
||||
.fa-tumblr:before{content:"\f173"}
|
||||
.fa-tumblr-square:before{content:"\f174"}
|
||||
.fa-long-arrow-down:before{content:"\f175"}
|
||||
.fa-long-arrow-up:before{content:"\f176"}
|
||||
.fa-long-arrow-left:before{content:"\f177"}
|
||||
.fa-long-arrow-right:before{content:"\f178"}
|
||||
.fa-apple:before{content:"\f179"}
|
||||
.fa-windows:before{content:"\f17a"}
|
||||
.fa-android:before{content:"\f17b"}
|
||||
.fa-linux:before{content:"\f17c"}
|
||||
.fa-dribbble:before{content:"\f17d"}
|
||||
.fa-skype:before{content:"\f17e"}
|
||||
.fa-foursquare:before{content:"\f180"}
|
||||
.fa-trello:before{content:"\f181"}
|
||||
.fa-female:before{content:"\f182"}
|
||||
.fa-male:before{content:"\f183"}
|
||||
.fa-gittip:before,.fa-gratipay:before{content:"\f184"}
|
||||
.fa-sun-o:before{content:"\f185"}
|
||||
.fa-moon-o:before{content:"\f186"}
|
||||
.fa-archive:before{content:"\f187"}
|
||||
.fa-bug:before{content:"\f188"}
|
||||
.fa-vk:before{content:"\f189"}
|
||||
.fa-weibo:before{content:"\f18a"}
|
||||
.fa-renren:before{content:"\f18b"}
|
||||
.fa-pagelines:before{content:"\f18c"}
|
||||
.fa-stack-exchange:before{content:"\f18d"}
|
||||
.fa-arrow-circle-o-right:before{content:"\f18e"}
|
||||
.fa-arrow-circle-o-left:before{content:"\f190"}
|
||||
.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}
|
||||
.fa-dot-circle-o:before{content:"\f192"}
|
||||
.fa-wheelchair:before{content:"\f193"}
|
||||
.fa-vimeo-square:before{content:"\f194"}
|
||||
.fa-turkish-lira:before,.fa-try:before{content:"\f195"}
|
||||
.fa-plus-square-o:before{content:"\f196"}
|
||||
.fa-space-shuttle:before{content:"\f197"}
|
||||
.fa-slack:before{content:"\f198"}
|
||||
.fa-envelope-square:before{content:"\f199"}
|
||||
.fa-wordpress:before{content:"\f19a"}
|
||||
.fa-openid:before{content:"\f19b"}
|
||||
.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}
|
||||
.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}
|
||||
.fa-yahoo:before{content:"\f19e"}
|
||||
.fa-google:before{content:"\f1a0"}
|
||||
.fa-reddit:before{content:"\f1a1"}
|
||||
.fa-reddit-square:before{content:"\f1a2"}
|
||||
.fa-stumbleupon-circle:before{content:"\f1a3"}
|
||||
.fa-stumbleupon:before{content:"\f1a4"}
|
||||
.fa-delicious:before{content:"\f1a5"}
|
||||
.fa-digg:before{content:"\f1a6"}
|
||||
.fa-pied-piper:before{content:"\f1a7"}
|
||||
.fa-pied-piper-alt:before{content:"\f1a8"}
|
||||
.fa-drupal:before{content:"\f1a9"}
|
||||
.fa-joomla:before{content:"\f1aa"}
|
||||
.fa-language:before{content:"\f1ab"}
|
||||
.fa-fax:before{content:"\f1ac"}
|
||||
.fa-building:before{content:"\f1ad"}
|
||||
.fa-child:before{content:"\f1ae"}
|
||||
.fa-paw:before{content:"\f1b0"}
|
||||
.fa-spoon:before{content:"\f1b1"}
|
||||
.fa-cube:before{content:"\f1b2"}
|
||||
.fa-cubes:before{content:"\f1b3"}
|
||||
.fa-behance:before{content:"\f1b4"}
|
||||
.fa-behance-square:before{content:"\f1b5"}
|
||||
.fa-steam:before{content:"\f1b6"}
|
||||
.fa-steam-square:before{content:"\f1b7"}
|
||||
.fa-recycle:before{content:"\f1b8"}
|
||||
.fa-automobile:before,.fa-car:before{content:"\f1b9"}
|
||||
.fa-cab:before,.fa-taxi:before{content:"\f1ba"}
|
||||
.fa-tree:before{content:"\f1bb"}
|
||||
.fa-spotify:before{content:"\f1bc"}
|
||||
.fa-deviantart:before{content:"\f1bd"}
|
||||
.fa-soundcloud:before{content:"\f1be"}
|
||||
.fa-database:before{content:"\f1c0"}
|
||||
.fa-file-pdf-o:before{content:"\f1c1"}
|
||||
.fa-file-word-o:before{content:"\f1c2"}
|
||||
.fa-file-excel-o:before{content:"\f1c3"}
|
||||
.fa-file-powerpoint-o:before{content:"\f1c4"}
|
||||
.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}
|
||||
.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}
|
||||
.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}
|
||||
.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}
|
||||
.fa-file-code-o:before{content:"\f1c9"}
|
||||
.fa-vine:before{content:"\f1ca"}
|
||||
.fa-codepen:before{content:"\f1cb"}
|
||||
.fa-jsfiddle:before{content:"\f1cc"}
|
||||
.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}
|
||||
.fa-circle-o-notch:before{content:"\f1ce"}
|
||||
.fa-ra:before,.fa-rebel:before{content:"\f1d0"}
|
||||
.fa-ge:before,.fa-empire:before{content:"\f1d1"}
|
||||
.fa-git-square:before{content:"\f1d2"}
|
||||
.fa-git:before{content:"\f1d3"}
|
||||
.fa-hacker-news:before{content:"\f1d4"}
|
||||
.fa-tencent-weibo:before{content:"\f1d5"}
|
||||
.fa-qq:before{content:"\f1d6"}
|
||||
.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}
|
||||
.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}
|
||||
.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}
|
||||
.fa-history:before{content:"\f1da"}
|
||||
.fa-genderless:before,.fa-circle-thin:before{content:"\f1db"}
|
||||
.fa-header:before{content:"\f1dc"}
|
||||
.fa-paragraph:before{content:"\f1dd"}
|
||||
.fa-sliders:before{content:"\f1de"}
|
||||
.fa-share-alt:before{content:"\f1e0"}
|
||||
.fa-share-alt-square:before{content:"\f1e1"}
|
||||
.fa-bomb:before{content:"\f1e2"}
|
||||
.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}
|
||||
.fa-tty:before{content:"\f1e4"}
|
||||
.fa-binoculars:before{content:"\f1e5"}
|
||||
.fa-plug:before{content:"\f1e6"}
|
||||
.fa-slideshare:before{content:"\f1e7"}
|
||||
.fa-twitch:before{content:"\f1e8"}
|
||||
.fa-yelp:before{content:"\f1e9"}
|
||||
.fa-newspaper-o:before{content:"\f1ea"}
|
||||
.fa-wifi:before{content:"\f1eb"}
|
||||
.fa-calculator:before{content:"\f1ec"}
|
||||
.fa-paypal:before{content:"\f1ed"}
|
||||
.fa-google-wallet:before{content:"\f1ee"}
|
||||
.fa-cc-visa:before{content:"\f1f0"}
|
||||
.fa-cc-mastercard:before{content:"\f1f1"}
|
||||
.fa-cc-discover:before{content:"\f1f2"}
|
||||
.fa-cc-amex:before{content:"\f1f3"}
|
||||
.fa-cc-paypal:before{content:"\f1f4"}
|
||||
.fa-cc-stripe:before{content:"\f1f5"}
|
||||
.fa-bell-slash:before{content:"\f1f6"}
|
||||
.fa-bell-slash-o:before{content:"\f1f7"}
|
||||
.fa-trash:before{content:"\f1f8"}
|
||||
.fa-copyright:before{content:"\f1f9"}
|
||||
.fa-at:before{content:"\f1fa"}
|
||||
.fa-eyedropper:before{content:"\f1fb"}
|
||||
.fa-paint-brush:before{content:"\f1fc"}
|
||||
.fa-birthday-cake:before{content:"\f1fd"}
|
||||
.fa-area-chart:before{content:"\f1fe"}
|
||||
.fa-pie-chart:before{content:"\f200"}
|
||||
.fa-line-chart:before{content:"\f201"}
|
||||
.fa-lastfm:before{content:"\f202"}
|
||||
.fa-lastfm-square:before{content:"\f203"}
|
||||
.fa-toggle-off:before{content:"\f204"}
|
||||
.fa-toggle-on:before{content:"\f205"}
|
||||
.fa-bicycle:before{content:"\f206"}
|
||||
.fa-bus:before{content:"\f207"}
|
||||
.fa-ioxhost:before{content:"\f208"}
|
||||
.fa-angellist:before{content:"\f209"}
|
||||
.fa-cc:before{content:"\f20a"}
|
||||
.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}
|
||||
.fa-meanpath:before{content:"\f20c"}
|
||||
.fa-buysellads:before{content:"\f20d"}
|
||||
.fa-connectdevelop:before{content:"\f20e"}
|
||||
.fa-dashcube:before{content:"\f210"}
|
||||
.fa-forumbee:before{content:"\f211"}
|
||||
.fa-leanpub:before{content:"\f212"}
|
||||
.fa-sellsy:before{content:"\f213"}
|
||||
.fa-shirtsinbulk:before{content:"\f214"}
|
||||
.fa-simplybuilt:before{content:"\f215"}
|
||||
.fa-skyatlas:before{content:"\f216"}
|
||||
.fa-cart-plus:before{content:"\f217"}
|
||||
.fa-cart-arrow-down:before{content:"\f218"}
|
||||
.fa-diamond:before{content:"\f219"}
|
||||
.fa-ship:before{content:"\f21a"}
|
||||
.fa-user-secret:before{content:"\f21b"}
|
||||
.fa-motorcycle:before{content:"\f21c"}
|
||||
.fa-street-view:before{content:"\f21d"}
|
||||
.fa-heartbeat:before{content:"\f21e"}
|
||||
.fa-venus:before{content:"\f221"}
|
||||
.fa-mars:before{content:"\f222"}
|
||||
.fa-mercury:before{content:"\f223"}
|
||||
.fa-transgender:before{content:"\f224"}
|
||||
.fa-transgender-alt:before{content:"\f225"}
|
||||
.fa-venus-double:before{content:"\f226"}
|
||||
.fa-mars-double:before{content:"\f227"}
|
||||
.fa-venus-mars:before{content:"\f228"}
|
||||
.fa-mars-stroke:before{content:"\f229"}
|
||||
.fa-mars-stroke-v:before{content:"\f22a"}
|
||||
.fa-mars-stroke-h:before{content:"\f22b"}
|
||||
.fa-neuter:before{content:"\f22c"}
|
||||
.fa-facebook-official:before{content:"\f230"}
|
||||
.fa-pinterest-p:before{content:"\f231"}
|
||||
.fa-whatsapp:before{content:"\f232"}
|
||||
.fa-server:before{content:"\f233"}
|
||||
.fa-user-plus:before{content:"\f234"}
|
||||
.fa-user-times:before{content:"\f235"}
|
||||
.fa-hotel:before,.fa-bed:before{content:"\f236"}
|
||||
.fa-viacoin:before{content:"\f237"}
|
||||
.fa-train:before{content:"\f238"}
|
||||
.fa-subway:before{content:"\f239"}
|
||||
.fa-medium:before{content:"\f23a"}
|
392
RX_FSK/data/style_map.css
Executable file
392
RX_FSK/data/style_map.css
Executable file
|
@ -0,0 +1,392 @@
|
|||
body, html {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.active, .cfgheader:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
.cfgpanel {
|
||||
}
|
||||
|
||||
th.cfg {
|
||||
padding:5pt
|
||||
}
|
||||
table.stat {
|
||||
margin:0px 0px 5px 0px;
|
||||
}
|
||||
|
||||
.hamburger {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
height: 0.8em;
|
||||
margin-right: 0.3em;
|
||||
border-top: 0.2em solid #fff;
|
||||
border-bottom: 0.2em solid #fff;
|
||||
}
|
||||
|
||||
.hamburger:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0.3em;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
border-top: 0.2em solid #fff;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
}
|
||||
.tci {
|
||||
flex-grow: 1; border: none; margin: 0; padding: 0;
|
||||
}
|
||||
.footer {
|
||||
background-color: #333;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
td.ch {
|
||||
text-align: right;
|
||||
padding: 0px 8px;
|
||||
}
|
||||
td.act {
|
||||
text-align: center;
|
||||
}
|
||||
table, th, td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
background-color: #ddd
|
||||
}
|
||||
|
||||
td#caption {
|
||||
text-align: center;
|
||||
background-color: #aaa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
td#sfreq {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
.tabcontent {
|
||||
display: none;
|
||||
flex: 1;
|
||||
border-top: none;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: Helvetica;
|
||||
display: inline-block;
|
||||
margin: 0px auto;
|
||||
text-align: center;
|
||||
}
|
||||
h1{
|
||||
color: #0F3376;
|
||||
font-size: 24px
|
||||
}
|
||||
p{
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.button2 {
|
||||
background-color: #f44336;
|
||||
}
|
||||
:disabled.save {
|
||||
opacity: 0.5;
|
||||
}
|
||||
.save {
|
||||
background-color: #CC1111; /* 0F33C6; */
|
||||
border: white;
|
||||
border-width: 1;
|
||||
color: white;
|
||||
padding: 8px 30px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.ttgoinfo {
|
||||
color: white;
|
||||
padding: 8px 10px;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
margin: 0
|
||||
}
|
||||
.ctlbtn {
|
||||
background-color: #ccc;
|
||||
border: black;
|
||||
border-width: 1;
|
||||
color: black;
|
||||
padding: 4px 30px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
margin: 2;
|
||||
font-size: 4vh;
|
||||
}
|
||||
.update {
|
||||
margin: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.leaflet-popup-content table, .leaflet-popup-content table td {
|
||||
border:0;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.leaflet-popup-content table td:nth-child(2),.leaflet-popup-content table td:nth-child(5) {
|
||||
text-align: right;
|
||||
padding-left: 3px;
|
||||
}
|
||||
|
||||
.leaflet-popup-content table td:nth-child(3),.leaflet-popup-content table td:nth-child(6) {
|
||||
text-align: left;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.leaflet-gps{animation:fading 1s infinite}@keyframes fading{0%{opacity:0.7}50%{opacity:1}100%{opacity:0.7}}
|
||||
|
||||
.leaflet-gps::after {
|
||||
content: '🔵';
|
||||
}
|
||||
.leaflet-gps {
|
||||
margin-left: -7px !important;
|
||||
margin-top: -9px !important;
|
||||
}
|
||||
|
||||
.leaflet-burst::after {
|
||||
content: '💥';
|
||||
}
|
||||
.leaflet-burst {
|
||||
margin-left: -20px !important;
|
||||
margin-top: -22px !important;
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.leaflet-landing::after {
|
||||
content: '×';
|
||||
}
|
||||
|
||||
.leaflet-landing {
|
||||
margin-left: -13px !important;
|
||||
margin-top: -30px !important;
|
||||
font-weight: bold;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
|
||||
.leaflet-header {
|
||||
text-align: center;
|
||||
width: 250px;
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.leaflet-header #settings {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.leaflet-header label {
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.leaflet-header input {
|
||||
width: 80px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.leaflet-header #submit {
|
||||
margin: 3px auto;
|
||||
}
|
||||
|
||||
.leaflet-footer {
|
||||
display:none;
|
||||
text-align: center;
|
||||
width: 180px;
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
||||
.leaflet-center {
|
||||
left:0;
|
||||
right:0;
|
||||
margin: 0 auto;
|
||||
padding: 5px;
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.leaflet-header #sonde_detail {
|
||||
display:none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.leaflet-control-attribution {
|
||||
-moz-transform: rotate(-90deg) translateX(100%);
|
||||
-ms-transform: rotate(-90deg) translateX(100%);
|
||||
-o-transform: rotate(-90deg) translateX(100%);;
|
||||
-webkit-transform: rotate(-90deg) translateX(100%);
|
||||
transform: rotate(-90deg) translateX(100%);
|
||||
-webkit-transform-origin: 100% 100%;
|
||||
-moz-transform-origin: 100% 100%;
|
||||
-ms-transform-origin: 100% 100%;
|
||||
-o-transform-origin: 100% 100%;
|
||||
transform-origin: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.ldot {
|
||||
height: 15px;
|
||||
width: 15px;
|
||||
margin-top: 8px;
|
||||
margin-left: -1px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.ybg {
|
||||
background-color: orange;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(yellow), to(orange));
|
||||
background-image: linear-gradient(top, yellow, orange);
|
||||
}
|
||||
.gbg {
|
||||
background-color: green;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(lime), to(green));
|
||||
background-image: linear-gradient(top, lime, green);
|
||||
}
|
||||
.rbg {
|
||||
background-color: red;
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(orange), to(red));
|
||||
background-image: linear-gradient(top, orange, red);
|
||||
}
|
||||
|
||||
#sonde_statbar .ldot {
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
/* Add a black background color to the top navigation */
|
||||
.topnav {
|
||||
background-color: #333;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Style the links inside the navigation bar */
|
||||
.topnav a {
|
||||
float: left;
|
||||
display: block;
|
||||
color: #f2f2f2;
|
||||
text-align: center;
|
||||
padding: 14px 16px;
|
||||
text-decoration: none;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
/* Change the color of links on hover */
|
||||
.topnav a:hover {
|
||||
background-color: #ddd;
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* Add an active class to highlight the current page */
|
||||
.topnav a.active {
|
||||
background-color: #04AA6D;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Hide the link that should open and close the topnav on small screens */
|
||||
.topnav .icon {
|
||||
display: none;
|
||||
padding-bottom: 12px;
|
||||
padding-top: 11px;
|
||||
}
|
||||
|
||||
/* When the screen is less than 600 pixels wide, hide all links, except for the first one ("Home"). Show the link that contains should open and close the topnav (.icon) */
|
||||
@media screen and (max-width: 600px) {
|
||||
.topnav a:not(.active) {display: none;}
|
||||
.topnav a.icon {
|
||||
float: right;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* The "responsive" class is added to the topnav with JavaScript when the user clicks on the icon. This class makes the topnav look good on small screens (display the links vertically instead of horizontally) */
|
||||
@media screen and (max-width: 600px) {
|
||||
.topnav.responsive {position: relative;}
|
||||
.topnav.responsive a.icon {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
}
|
||||
.topnav.responsive a {
|
||||
float: none;
|
||||
display: block;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: #333;
|
||||
}
|
||||
h2{
|
||||
color: white;
|
||||
}
|
||||
table, th, td, .save, a.active {
|
||||
color: white;
|
||||
border: 1px solid grey;
|
||||
border-collapse: collapse;
|
||||
background-color: #333;
|
||||
}
|
||||
input, select, .tci, .warning {
|
||||
color: white;
|
||||
background-color: #333;
|
||||
}
|
||||
a:link, a:visited {
|
||||
color: #D3D3D3;
|
||||
}
|
||||
.topnav, td#sfreq {
|
||||
background-color: grey;
|
||||
}
|
||||
.topnav a:visited {
|
||||
color: white;
|
||||
}
|
||||
.ctlbtn {
|
||||
color: white;
|
||||
background-color: grey;
|
||||
}
|
||||
.leaflet-center {
|
||||
color: white;
|
||||
background-color: grey;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: grey !important;
|
||||
}
|
||||
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
|
||||
color: white !important;
|
||||
background: grey !important;
|
||||
}
|
||||
}
|
24
RX_FSK/features.h
Normal file
24
RX_FSK/features.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
// Configuration flags for including/excluding fuctionality from the compiled binary
|
||||
// set flag to 0 for exclude/1 for include
|
||||
|
||||
/* data feed to sondehubv2 */
|
||||
/* needs about 4k4 code, 200b data, 200b stack, 200b heap */
|
||||
#define FEATURE_SONDEHUB 1
|
||||
#define FEATURE_CHASEMAPPER 1
|
||||
#define FEATURE_MQTT 0
|
||||
|
||||
#define FEATURE_RS92 1
|
||||
|
||||
/* Most recent version support fonts in a dedicated flash parition "fonts".
|
||||
* This is incomabtible (in terms of code and flash layout) to previous versions.
|
||||
* If LEGACY_FONTS_IN_CODEBIN is sets, fonts are also included in the bin image.
|
||||
* This maintains compatibility for OTA with previous versions (in which case the
|
||||
* bin image fonts will be used as before).
|
||||
* The code automatically uses fonts in flash partition if that exists, otherwise
|
||||
* fonts in code.
|
||||
* The flash partition fonts support latin15 codeset (instead of 7bit ascii).
|
||||
* Also, it is easier to use different fonts :) just flash the font partition w/ something else...
|
||||
* This option will likely be removed post-master1.0
|
||||
*/
|
||||
#define LEGACY_FONTS_IN_CODEBIN 1
|
43
RX_FSK/src/Chasemapper.cpp
Normal file
43
RX_FSK/src/Chasemapper.cpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "Chasemapper.h"
|
||||
|
||||
extern const char *sondeTypeStrSH[];
|
||||
|
||||
int Chasemapper::send(WiFiUDP &udp, SondeInfo *si) {
|
||||
char buf[1024];
|
||||
struct tm tim;
|
||||
time_t t = si->d.time;
|
||||
gmtime_r(&t, &tim);
|
||||
uint8_t realtype = si->type;
|
||||
if (TYPE_IS_METEO(realtype)) {
|
||||
realtype = si->d.subtype == 1 ? STYPE_M10 : STYPE_M20;
|
||||
}
|
||||
sprintf(buf, "{ \"type\": \"PAYLOAD_SUMMARY\","
|
||||
"\"callsign\": \"%s\","
|
||||
"\"latitude\": %.5f,"
|
||||
"\"longitude\": %.5f,"
|
||||
"\"altitude\": %d,"
|
||||
"\"speed\": %d,"
|
||||
"\"heading\": %d,"
|
||||
"\"time\": \"%02d:%02d:%02d\","
|
||||
"\"model\": \"%s\","
|
||||
"\"freq\": \"%.3f MHz\"",
|
||||
si->d.ser,
|
||||
si->d.lat,
|
||||
si->d.lon,
|
||||
(int)si->d.alt,
|
||||
(int)(si->d.hs * 1.9438445), // m/s into knots
|
||||
(int)si->d.dir,
|
||||
tim.tm_hour, tim.tm_min, tim.tm_sec,
|
||||
sondeTypeStrSH[realtype],
|
||||
si->freq);
|
||||
if( !isnan(si->d.temperature) ) {
|
||||
sprintf(buf + strlen(buf), ", \"temp\": %.1f", si->d.temperature);
|
||||
}
|
||||
strcat(buf, "}");
|
||||
Serial.printf("Sending chasemapper json: %s\n", buf);
|
||||
udp.beginPacket(sonde.config.cm.host, sonde.config.cm.port);
|
||||
udp.write((const uint8_t *)buf, strlen(buf));
|
||||
udp.endPacket();
|
||||
return 0;
|
||||
}
|
||||
|
13
RX_FSK/src/Chasemapper.h
Normal file
13
RX_FSK/src/Chasemapper.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef _CHASEMAPPER_H
|
||||
#define _CHASEMAPPER_H
|
||||
|
||||
#include "Sonde.h"
|
||||
//#include <WiFi.h>
|
||||
#include <WiFiUdp.h>
|
||||
#include <time.h>
|
||||
class Chasemapper {
|
||||
public:
|
||||
static int send(WiFiUDP &udb, SondeInfo *si);
|
||||
};
|
||||
|
||||
#endif
|
693
RX_FSK/src/DFM.cpp
Normal file
693
RX_FSK/src/DFM.cpp
Normal file
|
@ -0,0 +1,693 @@
|
|||
|
||||
/* DFM decoder functions */
|
||||
#include "DFM.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "Sonde.h"
|
||||
|
||||
#define DFM_DEBUG 0
|
||||
|
||||
#if DFM_DEBUG
|
||||
#define DFM_DBG(x) x
|
||||
#else
|
||||
#define DFM_DBG(x)
|
||||
#endif
|
||||
|
||||
#define DFM_FRAMELEN 33
|
||||
|
||||
#define MAXIDAGE 1800
|
||||
|
||||
/*
|
||||
* observed DAT patterns for DFM-9:
|
||||
* A: 0+1; 2+3; 4+5; 6+7; 8+0 => keep frame in shadowFrame
|
||||
* B: 1+2; 3+4; 5+6; 7+8 => all good => keep date in shadowDate
|
||||
* C: 0+1; 2+3; 4+5; 6+7; 8+15 => all good => keep date in shadowDate
|
||||
* D: 0+1; 2+3; 4+5; 6+7; 0+1 => use shadowDate
|
||||
* not seen:5+6; 7+1
|
||||
* values:
|
||||
* 0:packet counter; 1:utc-msec; 2:lat,vh; 3:lon,dir, 4:alt,vv, 8=utc-date(day-hh-mm)
|
||||
*/
|
||||
|
||||
// single data structure, search restarts after decoder change
|
||||
static struct st_dfmstat {
|
||||
int idcnt0;
|
||||
int idcnt1;
|
||||
int lastfrid;
|
||||
int lastfrcnt;
|
||||
uint8_t start[50];
|
||||
uint16_t dat[50*2];
|
||||
uint8_t cnt[50*2];
|
||||
uint16_t good;
|
||||
uint32_t datesec;
|
||||
uint8_t frame;
|
||||
uint16_t msec;
|
||||
uint8_t nameregok;
|
||||
uint8_t nameregtop;
|
||||
uint8_t lastdat;
|
||||
uint8_t cycledone; // 0=no; 1=OK, 2=partially/with errors
|
||||
float meas[5+2];
|
||||
} dfmstate;
|
||||
|
||||
decoderSetupCfg DFMSetupCfg {
|
||||
.bitrate = 2500,
|
||||
// continuous mode
|
||||
// Enable auto-AFC, auto-AGC, RX Trigger by preamble ????
|
||||
.rx_cfg = 0x1E,
|
||||
.sync_cfg = 0x70,
|
||||
.sync_len = 2,
|
||||
.sync_data = (const uint8_t *)"\xAA\xAA",
|
||||
.preamble_cfg = 0xA8,
|
||||
};
|
||||
|
||||
int DFM::setup(float frequency, int type)
|
||||
{
|
||||
stype = type;
|
||||
#if DFM_DEBUG
|
||||
Serial.printf("Setup sx1278 for DFM sonde (type=%d)\n", stype);
|
||||
#endif
|
||||
if(sx1278.ON()!=0) {
|
||||
DFM_DBG(Serial.println("Setting SX1278 power on FAILED"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(DecoderBase::setup(DFMSetupCfg, sonde.config.dfm.agcbw, sonde.config.dfm.rxbw) != 0) {
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
// This is now all done by the generic setup method in base class
|
||||
if(sx1278.setFSK()!=0) {
|
||||
DFM_DBG(Serial.println("Setting FSM mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setBitrate(2500)!=0) {
|
||||
DFM_DBG(Serial.println("Setting bitrate 2500bit/s FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setAFCBandwidth(sonde.config.dfm.agcbw)!=0) {
|
||||
DFM_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.dfm.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.dfm.rxbw)!=0) {
|
||||
DFM_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.dfm.rxbw));
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if(sx1278.setRxConf(0x1E)!=0) {
|
||||
DFM_DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// working with continuous RX
|
||||
const char *SYNC="\xAA\xAA";
|
||||
if(sx1278.setSyncConf(0x70, 2, (const uint8_t *)SYNC)!=0) {
|
||||
DFM_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setPreambleDetect(0xA8)!=0) {
|
||||
//if(sx1278.setPreambleDetect(0x9F)!=0) {
|
||||
DFM_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
DFM_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
sx1278.setPayloadLength(0); // infinite for now...
|
||||
Serial.print("DFM: setting RX frequency to ");
|
||||
Serial.println(frequency);
|
||||
|
||||
int retval = sx1278.setFrequency(frequency);
|
||||
sx1278.clearIRQFlags();
|
||||
|
||||
// Do this only once in setup in continous mode
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
|
||||
memset((void *)&dfmstate, 0, sizeof(dfmstate));
|
||||
DFM_DBG(Serial.println("Setting SX1278 config for DFM finished\n"); Serial.println());
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#define bitpick(value,bitpos) (((value)>>(7-(bitpos)))&0x01)
|
||||
// Input: str: packed data, MSB first
|
||||
void DFM::deinterleave(uint8_t *str, int L, uint8_t *block) {
|
||||
int i, j;
|
||||
for (j = 0; j < B; j++) { // L = 7 (CFG), 13 (DAT1, DAT2)
|
||||
for (i = 0; i < L; i++) {
|
||||
block[B*i+j] = bitpick( str[(L*j+i)/8], (L*j+i)&7 )?0:1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t DFM::bits2val(const uint8_t *bits, int len) {
|
||||
uint32_t val = 0;
|
||||
for (int j = 0; j < len; j++) {
|
||||
val |= (bits[j] << (len-1-j));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
// Error correction for hamming code
|
||||
// returns 0: ok >0: 1 error was corrected -1: uncorrectable error
|
||||
int DFM::check(uint8_t code[8]) {
|
||||
int i, j;
|
||||
uint32_t synval = 0;
|
||||
uint8_t syndrom[4];
|
||||
int ret=0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
syndrom[i] = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
syndrom[i] ^= H[i][j] & code[j];
|
||||
}
|
||||
}
|
||||
synval = bits2val(syndrom, 4);
|
||||
if (synval) {
|
||||
ret = -1;
|
||||
for (j = 0; j < 8; j++) { // 1-bit-error
|
||||
if (synval == He[j]) { // reicht auf databits zu pruefen, d.h.
|
||||
ret = j+1; // (systematischer Code) He[0..3]
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else ret = 0;
|
||||
if (ret > 0) code[ret-1] ^= 0x1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Extended (8,4) Hamming code
|
||||
// Return number of corrected bits, -1 if uncorrectable error
|
||||
int DFM::hamming(uint8_t *ham, int L, uint8_t *sym) {
|
||||
int i, j;
|
||||
int ret = 0; // DFM: length L = 7 or 13
|
||||
for (i = 0; i < L; i++) { // L bytes (4bit data, 4bit parity)
|
||||
if (use_ecc) {
|
||||
int res = check(ham+8*i);
|
||||
if( res<0 ) ret = -1;
|
||||
else if ( ret >= 0 && res > 0 ) ret++;
|
||||
}
|
||||
// systematic Hamming code: copy bits 0..3
|
||||
for (j = 0; j < 4; j++) {
|
||||
sym[4*i+j] = ham[8*i+j];
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DFM::DFM() {
|
||||
}
|
||||
|
||||
void DFM::printRaw(const char *label, int len, int ret, const uint8_t *data)
|
||||
{
|
||||
Serial.print(label); Serial.print("(");
|
||||
Serial.print(ret);
|
||||
Serial.print("):");
|
||||
int i;
|
||||
for(i=0; i<len/2; i++) {
|
||||
char str[10];
|
||||
snprintf(str, 10, "%02X", data[i]);
|
||||
Serial.print(str);
|
||||
}
|
||||
Serial.print(data[i]&0x0F, HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
|
||||
const char* typestr[16]={
|
||||
"", "", "", "", "", "", // 00..05
|
||||
"DFM6", // 06 => DFM6
|
||||
"PS15", // 07 => PS15 (untested)
|
||||
"", "",
|
||||
"DFM9", // 0A => DFM9
|
||||
"DF17", // 0B => DFM17?
|
||||
"DF9P", // 0C => DFM9P or DFM17 test
|
||||
"DF17", // 0D => DFM17
|
||||
"", ""
|
||||
};
|
||||
|
||||
void DFM::killid() {
|
||||
SondeData *sd = &(sonde.si()->d);
|
||||
sd->validID = false;
|
||||
*(sd->id) = 0;
|
||||
*(sd->ser) = 0;
|
||||
memset((void *)&dfmstate, 0, sizeof(dfmstate));
|
||||
}
|
||||
|
||||
#define DFMIDTHRESHOLD 2
|
||||
/* inspired by oe5dxl's finddnmae in sondeudp.c of dxlaprs */
|
||||
void DFM::finddfname(uint8_t *b)
|
||||
{
|
||||
uint8_t st;
|
||||
uint32_t thres;
|
||||
uint32_t i;
|
||||
uint8_t ix;
|
||||
uint16_t d;
|
||||
SondeData *sd = &(sonde.si()->d);
|
||||
|
||||
st = b[0]; /* frame start byte */
|
||||
ix = b[3]; /* hi/lo part of ser; (LSB due to our bitsToBytes...) */
|
||||
d = (b[1]<<8) + b[2]; /* data byte */
|
||||
/* find highest channel number single frame serial,
|
||||
(2 frame serial will make a single serial too) */
|
||||
if(dfmstate.idcnt0 < DFMIDTHRESHOLD && dfmstate.idcnt1 < DFMIDTHRESHOLD) {
|
||||
uint32_t v = (st<<20) | (d<<4) | ix;
|
||||
if ( st > (dfmstate.lastfrid>>20) ) {
|
||||
dfmstate.lastfrid = v;
|
||||
Serial.print(" MAXCH:"); Serial.print(st);
|
||||
dfmstate.lastfrcnt = 0;
|
||||
} else if ( st == (dfmstate.lastfrid>>20) ) {
|
||||
/* same id found */
|
||||
if (v == dfmstate.lastfrid) {
|
||||
++dfmstate.lastfrcnt;
|
||||
thres = DFMIDTHRESHOLD * 2;
|
||||
/* may be a 2 frame serial so increase safety level */
|
||||
if (ix <= 1) thres *= 2;
|
||||
/* may be not a dfm6 so increase safety level */
|
||||
if ( (st>>4) != 6) thres *= 2;
|
||||
if (dfmstate.lastfrcnt >= thres) {
|
||||
/* id found */
|
||||
if (dfmstate.lastfrcnt == thres) {
|
||||
uint32_t id = ((st&0x0F)<<20) | (d<<4) | ix;
|
||||
uint32_t chkid = id;
|
||||
int i;
|
||||
/* check validity */
|
||||
for(i=0; i<6; i++) {
|
||||
if((chkid&0x0f)>9) { break; /* not ok */ }
|
||||
chkid >>= 4;
|
||||
}
|
||||
if(i==6) {
|
||||
snprintf(sd->id, 10, "D%x ", id);
|
||||
memcpy(sd->ser, sd->id+1, 9);
|
||||
sd->validID = true;
|
||||
sd->subtype = (st>>4)&0x0F;
|
||||
strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
return;
|
||||
}
|
||||
dfmstate.lastfrcnt = 0;
|
||||
Serial.print(" NOT NUMERIC SERIAL");
|
||||
}
|
||||
//anonym->idtime = osic_time();
|
||||
} else {
|
||||
Serial.print(" MAXCHCNT/SECLVL:");
|
||||
Serial.print(dfmstate.lastfrcnt);
|
||||
Serial.print("/");
|
||||
Serial.print(thres);
|
||||
}
|
||||
} else {
|
||||
dfmstate.lastfrid = v; /* not stable ser */
|
||||
dfmstate.lastfrcnt = 0UL;
|
||||
}
|
||||
}
|
||||
} /*find highest channel number single frame serial */
|
||||
|
||||
i = 0;
|
||||
while (i<dfmstate.nameregtop && dfmstate.start[i]!=st) i++;
|
||||
Serial.printf(" %02x:i=%d,top=%d", st, i, dfmstate.nameregtop);
|
||||
if (i<dfmstate.nameregtop) {
|
||||
if (ix<=1UL && (dfmstate.cnt[2*i+ix]==0 || dfmstate.dat[2*i+ix]==d)) {
|
||||
dfmstate.dat[2*i+ix] = d;
|
||||
if(dfmstate.cnt[2*i+ix] < 255) dfmstate.cnt[2*i+ix]++;
|
||||
Serial.print(" ID:");
|
||||
Serial.print(st, HEX);
|
||||
Serial.print("[");
|
||||
Serial.print(ix);
|
||||
Serial.print("] CNT:");
|
||||
Serial.print(dfmstate.cnt[2*i]);
|
||||
Serial.print(",");
|
||||
Serial.print(dfmstate.cnt[2*i+1]);
|
||||
Serial.print(",st=");
|
||||
Serial.print(st);
|
||||
Serial.print(",lastfrid=");
|
||||
Serial.print(dfmstate.lastfrid>>20);
|
||||
if( (dfmstate.cnt[2*i]>DFMIDTHRESHOLD && dfmstate.cnt[2*i+1]>DFMIDTHRESHOLD) ||
|
||||
(dfmstate.cnt[2*i]>0 && dfmstate.cnt[2*i+1]>0 && st == (dfmstate.lastfrid>>20) && (st>>4)>6) ) {
|
||||
if(dfmstate.idcnt0 <= 1) {
|
||||
dfmstate.idcnt0 = dfmstate.cnt[2*i];
|
||||
dfmstate.idcnt1 = dfmstate.cnt[2*i+1];
|
||||
dfmstate.nameregok = i;
|
||||
// generate id.....
|
||||
snprintf(sd->id, 10, "D%d", ((dfmstate.dat[2*i]<<16)|dfmstate.dat[2*i+1])%100000000);
|
||||
Serial.print("\nNEW AUTOID:");
|
||||
Serial.println(sd->id);
|
||||
memcpy(sd->ser, sd->id+1, 9);
|
||||
sd->validID = true;
|
||||
sd->subtype = (st>>4)&0x0F;
|
||||
strncpy(sd->typestr, typestr[ (st>>4)&0x0F ], 5);
|
||||
}
|
||||
if(dfmstate.nameregok==i) {
|
||||
Serial.print(" ID OK");
|
||||
// idtime = .... /* TODO */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* data changed so not ser */
|
||||
dfmstate.cnt[2*i] = 0;
|
||||
dfmstate.cnt[2*i+1] = 0;
|
||||
if(dfmstate.nameregok == i) { /* found id wrong */
|
||||
dfmstate.idcnt0 = 0;
|
||||
dfmstate.idcnt1 = 0;
|
||||
}
|
||||
}
|
||||
} else if (ix<=1) { /* add new entry for possible ID */
|
||||
dfmstate.start[dfmstate.nameregtop] = st;
|
||||
dfmstate.cnt[2*dfmstate.nameregtop] = 0;
|
||||
dfmstate.cnt[2*dfmstate.nameregtop+1] = 0;
|
||||
dfmstate.cnt[2*dfmstate.nameregtop+ix] = 1;
|
||||
dfmstate.dat[2*dfmstate.nameregtop+ix] = d;
|
||||
if(dfmstate.nameregtop<49) dfmstate.nameregtop++;
|
||||
}
|
||||
}
|
||||
|
||||
static float get_Temp() {
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
if(!si->validID) { // type not yet known, so don't try to decode
|
||||
return NAN;
|
||||
}
|
||||
float f = dfmstate.meas[0],
|
||||
f1 = dfmstate.meas[3],
|
||||
f2 = dfmstate.meas[4];
|
||||
if(si->subtype >= 0x0C) {
|
||||
f = dfmstate.meas[1];
|
||||
f1 = dfmstate.meas[5];
|
||||
f2 = dfmstate.meas[6];
|
||||
}
|
||||
Serial.printf("Meas: %f %f %f\n", f, f1, f2);
|
||||
// as in autorx / dfm
|
||||
float BB0 = 3260.0; // B/Kelvin, fit -55C..+40C
|
||||
float T0 = 25 + 273.15; // t0=25C
|
||||
float R0 = 5.0e3; // R0=R25=5k
|
||||
float Rf = 220e3; // Rf = 220k
|
||||
float g = f2/Rf;
|
||||
float R = (f-f1) / g; // meas[0,3,4] > 0 ?
|
||||
float T = 0; // T/Kelvin
|
||||
if (f*f1*f2 == 0) R = 0;
|
||||
if (R > 0) T = 1/(1/T0 + 1/BB0 * log(R/R0));
|
||||
T = T - 273.15; // Celsius
|
||||
if(T<-100 || T>50) {
|
||||
Serial.printf("Temperature invalid: %f\n", T);
|
||||
return NAN;
|
||||
}
|
||||
return T;
|
||||
}
|
||||
|
||||
void DFM::decodeCFG(uint8_t *cfg)
|
||||
{
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
// new ID
|
||||
finddfname(cfg);
|
||||
// get meas
|
||||
uint8_t conf_id = (*cfg)>>4;
|
||||
if(conf_id<=6) {
|
||||
uint32_t val = (cfg[1]<<12) | (cfg[2]<<4) | cfg[3];
|
||||
uint8_t exp = cfg[0] & 0xF;
|
||||
dfmstate.meas[conf_id] = val / (float)(1<<exp);
|
||||
Serial.printf("meas %d is %f (%d,%d)\n", conf_id, dfmstate.meas[conf_id], val, exp);
|
||||
}
|
||||
// get batt
|
||||
if(si->validID && si->subtype>=0x0A) {
|
||||
// otherwise don't try, as we might not have the right type yet...
|
||||
int cid = (si->subtype >= 0x0C) ? 0x7 : 0x5;
|
||||
if(conf_id == cid) {
|
||||
uint16_t val = cfg[1]<<8 | cfg[2];
|
||||
si->batteryVoltage = val / 1000.0;
|
||||
Serial.printf("battery: %f\n", si->batteryVoltage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// not used any more
|
||||
static int bitCount(int x) {
|
||||
int m4 = 0x1 | (0x1<<8) | (0x1<<16) | (0x1<<24);
|
||||
int m1 = 0xFF;
|
||||
int s4 = (x&m4) + ((x>>1)&m4) + ((x>>2)&m4) + ((x>>3)&m4) + ((x>>4)&m4) + ((x>>5)&m4) + ((x>>6)&m4) + ((x>>7)&m4);
|
||||
int s1 = (s4&m1) + ((s4>>8)&m1) + ((s4>>16)&m1) + ((s4>>24)&m1);
|
||||
return s1;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint16_t MON[]={0,0,31,59,90,120,151,181,212,243,273,304,334};
|
||||
|
||||
void DFM::decodeDAT(uint8_t *dat)
|
||||
{
|
||||
// TODO: Here we need to work on a shadow copy of SondeData in order to prevent concurrent changes while using data in main loop
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
Serial.print(" DAT["); Serial.print(dat[6]); Serial.print("]: ");
|
||||
|
||||
// We handle this case already here, because we need to update dfmstate.datesec before the cycle complete handling
|
||||
if( dat[6]==8 ) {
|
||||
int y = (dat[0]<<4) + (dat[1]>>4);
|
||||
int m = dat[1]&0x0F;
|
||||
int d = dat[2]>>3;
|
||||
int h = ((dat[2]&0x07)<<2) + (dat[3]>>6);
|
||||
int mi = (dat[3]&0x3F);
|
||||
Serial.printf("Date: %04d-%02d-%02d %02d:%02dz ", y, m, d, h, mi);
|
||||
si->sats = dat[4];
|
||||
si->validPos |= 0x40;
|
||||
// convert to unix time
|
||||
int tt = (y-1970)*365 + (y-1969)/4; // days since 1970
|
||||
if(m<=12) { tt += MON[m]; if((y%4)==0 && m>2) tt++; }
|
||||
tt = (tt+d-1)*(60*60*24) + h*3600 + mi*60;
|
||||
// If we get a time stamp much different to the previously received one, kill the ID.
|
||||
// most likely, we have a new sonde now, so wait for the new ID.
|
||||
if(tt-dfmstate.datesec > MAXIDAGE) killid();
|
||||
dfmstate.datesec = tt;
|
||||
dfmstate.good |= 0x100;
|
||||
}
|
||||
else if( dat[6]>8 ) return; // we ignore those...
|
||||
|
||||
/* Here we update data that should be updated only after receiving a "complete" frame (mainly for consistent SondeHub exports)
|
||||
* We do this (a) when there is a DAT8 block and (b) when there is wrap from DAT7 to DAT0, for these fields:
|
||||
* => frame
|
||||
* => vframe (only used for SondeHub as virtual frame number)
|
||||
* => time (calculated with using date and msec)
|
||||
* [assuming that if there is no DAT8, then the date value did not change.]
|
||||
*/
|
||||
|
||||
if( dat[6]==8 || dat[6] < dfmstate.lastdat) { // After DAT8, or after a "warp around"
|
||||
if( dfmstate.good&1 ) si->frame = dfmstate.frame;
|
||||
if( (dfmstate.good&0x102)==0x102 ) {
|
||||
si->time = dfmstate.datesec + dfmstate.msec/1000;
|
||||
// Lets be consistent with autorx: the timestamp uses the msec value truncated to seconds,
|
||||
// whereas the virtual frame number for DFM uses the msec value rounded to full seconds.
|
||||
// Actually, tt is real UTC, and the transformation to GPS seconds lacks adjusting for leap seconds
|
||||
si->vframe = dfmstate.datesec + (dfmstate.msec+500)/1000 - 315964800;
|
||||
}
|
||||
// All fields updated? 1=OK, 2=with errors
|
||||
Serial.printf("Cycle done: good is %x\n", dfmstate.good);
|
||||
si->temperature = get_Temp();
|
||||
Serial.printf("Temp: %f\n", si->temperature);
|
||||
dfmstate.cycledone = ((dfmstate.good&0x11F)==0x11F) ? 1 : 2;
|
||||
dfmstate.good = 0;
|
||||
dfmstate.lastdat = 0;
|
||||
} else {
|
||||
dfmstate.lastdat = dat[6];
|
||||
}
|
||||
dfmstate.good |= (1<<dat[6]);
|
||||
switch(dat[6]) {
|
||||
case 0:
|
||||
Serial.print("Packet counter: "); Serial.print(dat[3]);
|
||||
dfmstate.frame = dat[3];
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
int val = (((uint16_t)dat[4])<<8) + (uint16_t)dat[5];
|
||||
Serial.print("UTC-msec: "); Serial.print(val);
|
||||
dfmstate.msec = val;
|
||||
//uint32_t tmp = ((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + ((uint32_t)dat[3]);
|
||||
//si->sats = bitCount(tmp);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
float lat, vh;
|
||||
lat = (int32_t)(((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + ((uint32_t)dat[3]));
|
||||
vh = ((uint16_t)dat[4]<<8) + dat[5];
|
||||
Serial.print("GPS-lat: "); Serial.print(lat*0.0000001);
|
||||
Serial.print(", hor-V: "); Serial.print(vh*0.01);
|
||||
lat = lat*0.0000001;
|
||||
if( lat!=0 && si->lat!=0 && abs(lat-si->lat)>.25 ) killid();
|
||||
si->lat = lat;
|
||||
si->hs = vh*0.01;
|
||||
if(lat!=0 || vh!=0) si->validPos |= 0x11; else si->validPos &= ~0x11;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
float lon, dir;
|
||||
lon = (int32_t)(((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + (uint32_t)dat[3]);
|
||||
dir = ((uint16_t)dat[4]<<8) + dat[5];
|
||||
lon = lon*0.0000001;
|
||||
if( lon!=0 && si->lon!=0 && abs(lon-si->lon)>.25 ) killid();
|
||||
si->lon = lon;
|
||||
si->dir = dir*0.01;
|
||||
Serial.print("GPS-lon: "); Serial.print(si->lon);
|
||||
Serial.print(", dir: "); Serial.print(si->dir);
|
||||
if(lon != 0 || dir != 0) si->validPos |= 0x22; else si->validPos &= ~0x22;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
float alt, vv;
|
||||
alt = ((uint32_t)dat[0]<<24) + ((uint32_t)dat[1]<<16) + ((uint32_t)dat[2]<<8) + dat[3];
|
||||
vv = (int16_t)( ((int16_t)dat[4]<<8) | dat[5] );
|
||||
Serial.print("GPS-height: "); Serial.print(alt*0.01);
|
||||
Serial.print(", vv: "); Serial.print(vv*0.01);
|
||||
si->alt = alt*0.01;
|
||||
si->vs = vv*0.01;
|
||||
if(alt!=0 || vv != 0) si->validPos |= 0x0C; else si->validPos &= ~0x0C;
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
// handled above
|
||||
break;
|
||||
default:
|
||||
Serial.print("(?)");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DFM::bitsToBytes(uint8_t *bits, uint8_t *bytes, int len)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<len*4; i++) {
|
||||
//Serial.print(bits[i]?"1":"0");
|
||||
bytes[i/8] = (bytes[i/8]<<1) | (bits[i]?1:0);
|
||||
}
|
||||
bytes[(i-1)/8] &= 0x0F;
|
||||
}
|
||||
|
||||
static int haveNewFrame = 0;
|
||||
|
||||
int DFM::processDFMdata(uint8_t dt) {
|
||||
static uint8_t data[1024];
|
||||
static uint32_t rxdata = 0;
|
||||
static uint8_t rxbitc = 0;
|
||||
static uint8_t rxbyte = 0;
|
||||
static uint8_t rxsearching = 1;
|
||||
static uint8_t rxp;
|
||||
static int rssi=0, fei=0, afc=0;
|
||||
static uint8_t invers = 0;
|
||||
|
||||
for(int i=0; i<8; i++) {
|
||||
uint8_t d = (dt&0x80)?1:0;
|
||||
dt <<= 1;
|
||||
rxdata = (rxdata<<1) | d;
|
||||
if( (rxbitc&1)==0 ) {
|
||||
// "bit1"
|
||||
rxbyte = (rxbyte<<1) | d;
|
||||
} else {
|
||||
// "bit2" ==> 01 or 10 => 1, otherweise => 0
|
||||
// not here: (10=>1, 01=>0)!!! rxbyte = rxbyte ^ d;
|
||||
}
|
||||
//
|
||||
if(rxsearching) {
|
||||
if( rxdata == 0x6566A5AA || rxdata == 0x9A995A55 ) {
|
||||
rxsearching = false;
|
||||
rxbitc = 0;
|
||||
rxp = 0;
|
||||
rxbyte = 0;
|
||||
rssi=sx1278.getRSSI();
|
||||
fei=sx1278.getFEI();
|
||||
afc=sx1278.getAFC();
|
||||
sonde.si()->rssi = rssi;
|
||||
sonde.si()->afc = afc;
|
||||
invers = (rxdata == 0x6566A5AA)?1:0;
|
||||
}
|
||||
} else {
|
||||
rxbitc = (rxbitc+1)%16; // 16;
|
||||
if(rxbitc == 0) { // got 8 data bit
|
||||
if(invers) rxbyte=~rxbyte;
|
||||
data[rxp++] = rxbyte&0xff; // (rxbyte>>1)&0xff;
|
||||
if(rxp>=DFM_FRAMELEN) {
|
||||
rxsearching = true;
|
||||
//Serial.println("Got a DFM frame!");
|
||||
Serial.print("[RSSI="); Serial.print(rssi);
|
||||
Serial.print(" FEI="); Serial.print(fei);
|
||||
Serial.print(" AFC="); Serial.print(afc); Serial.print("] ");
|
||||
decodeFrameDFM(data);
|
||||
haveNewFrame = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DFM::receive() {
|
||||
int rxframes = 5; // UP TO 5 frames, stop at type 8 frame
|
||||
|
||||
// tentative continuous RX version...
|
||||
unsigned long t0 = millis();
|
||||
dfmstate.cycledone = 0;
|
||||
while( ( millis() - t0 ) < 1300 ) {
|
||||
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
if ( bitRead(value, 7) ) {
|
||||
Serial.println("FIFO full");
|
||||
}
|
||||
if ( bitRead(value, 4) ) {
|
||||
Serial.println("FIFO overflow");
|
||||
// new: (maybe clear only overflow??) TODO
|
||||
sx1278.clearIRQFlags();
|
||||
}
|
||||
if ( bitRead(value, 2) == 1 ) {
|
||||
Serial.println("FIFO: payload ready()");
|
||||
// does not make much sence? (from m10): TODO
|
||||
// ??????? sx1278.clearIRQFlags();
|
||||
}
|
||||
if(bitRead(value, 6) == 0) { // while FIFO not empty
|
||||
byte data = sx1278.readRegister(REG_FIFO);
|
||||
processDFMdata(data);
|
||||
value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
} else {
|
||||
if(haveNewFrame) {
|
||||
//Serial.printf("DFM::receive(): new frame complete after %ldms\n", millis()-t0);
|
||||
haveNewFrame = 0;
|
||||
rxframes--;
|
||||
// OK: All DAT frames (0/1/2/3/4/8) have been received in the last cycle
|
||||
if(dfmstate.cycledone==1) return RX_OK;
|
||||
if(dfmstate.cycledone>1 || rxframes==0) return RX_ERROR;
|
||||
}
|
||||
delay(2);
|
||||
}
|
||||
}
|
||||
return rxframes == 5 ? RX_TIMEOUT : RX_ERROR;
|
||||
}
|
||||
|
||||
int DFM::decodeFrameDFM(uint8_t *data) {
|
||||
deinterleave(data, 7, hamming_conf);
|
||||
deinterleave(data+7, 13, hamming_dat1);
|
||||
deinterleave(data+20, 13, hamming_dat2);
|
||||
|
||||
int ret0 = hamming(hamming_conf, 7, block_conf);
|
||||
int ret1 = hamming(hamming_dat1, 13, block_dat1);
|
||||
int ret2 = hamming(hamming_dat2, 13, block_dat2);
|
||||
//Serial.printf("Hamming returns %d %d %d -- %d\n", ret0, ret1, ret2, ret0|ret1|ret2);
|
||||
|
||||
byte byte_conf[4], byte_dat1[7], byte_dat2[7];
|
||||
bitsToBytes(block_conf, byte_conf, 7);
|
||||
bitsToBytes(block_dat1, byte_dat1, 13);
|
||||
bitsToBytes(block_dat2, byte_dat2, 13);
|
||||
|
||||
printRaw("CFG", 7, ret0, byte_conf);
|
||||
printRaw("DAT", 13, ret1, byte_dat1);
|
||||
printRaw("DAT", 13, ret2, byte_dat2);
|
||||
if (ret0>=0) decodeCFG(byte_conf);
|
||||
if (ret1>=0 && ret1<=4) decodeDAT(byte_dat1);
|
||||
if (ret2>=0 && ret2<=4) decodeDAT(byte_dat2);
|
||||
Serial.println("");
|
||||
// Consistent with autorx: If more than 4 corrected bit errors in DAT block, assume it is possibly corrupt and
|
||||
// don't treat it as a correct frame (ttgo display shows data anyway, but it is not sent to external sites)
|
||||
if(ret1>4 || ret2>4) return RX_ERROR;
|
||||
return (ret0|ret1|ret2)>=0 ? RX_OK : RX_ERROR;
|
||||
}
|
||||
|
||||
// moved to a single function in Sonde(). This function can be used for additional
|
||||
// processing here, that takes too long for doing in the RX task loop
|
||||
int DFM::waitRXcomplete() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DFM dfm = DFM();
|
74
RX_FSK/src/DFM.h
Normal file
74
RX_FSK/src/DFM.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* DFM.h
|
||||
* Functions for decoding DFM sondes with SX127x chips
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef DFM_h
|
||||
#define DFM_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "DecoderBase.h"
|
||||
|
||||
#define DFM_NORMAL 0
|
||||
#define DFM_INVERSE 1
|
||||
|
||||
/* Main class */
|
||||
class DFM : public DecoderBase
|
||||
{
|
||||
private:
|
||||
int stype;
|
||||
char *stypename=NULL;
|
||||
|
||||
void deinterleave(uint8_t *str, int L, uint8_t *block);
|
||||
uint32_t bits2val(const uint8_t *bits, int len);
|
||||
int check(uint8_t code[8]);
|
||||
int hamming(uint8_t *ham, int L, uint8_t *sym);
|
||||
void printRaw(const char *prefix, int len, int ret, const uint8_t* data);
|
||||
void finddfname(uint8_t *cfg);
|
||||
void decodeCFG(uint8_t *cfg);
|
||||
void decodeDAT(uint8_t *dat);
|
||||
void bitsToBytes(uint8_t *bits, uint8_t *bytes, int len);
|
||||
int processDFMdata(uint8_t dt);
|
||||
int decodeFrameDFM(uint8_t *data);
|
||||
void killid();
|
||||
|
||||
|
||||
#define B 8
|
||||
#define S 4
|
||||
uint8_t hamming_conf[ 7*B]; // 7*8=56
|
||||
uint8_t hamming_dat1[13*B]; // 13*8=104
|
||||
uint8_t hamming_dat2[13*B];
|
||||
|
||||
uint8_t block_conf[ 7*S]; // 7*4=28
|
||||
uint8_t block_dat1[13*S]; // 13*4=52
|
||||
uint8_t block_dat2[13*S];
|
||||
|
||||
uint8_t H[4][8] = // extended Hamming(8,4) particy check matrix
|
||||
{{ 0, 1, 1, 1, 1, 0, 0, 0},
|
||||
{ 1, 0, 1, 1, 0, 1, 0, 0},
|
||||
{ 1, 1, 0, 1, 0, 0, 1, 0},
|
||||
{ 1, 1, 1, 0, 0, 0, 0, 1}};
|
||||
uint8_t He[8] = { 0x7, 0xB, 0xD, 0xE, 0x8, 0x4, 0x2, 0x1}; // Spalten von H:
|
||||
// 1-bit-error-Syndrome
|
||||
|
||||
public:
|
||||
DFM();
|
||||
// main decoder API
|
||||
int setup(float frequency, int type);
|
||||
int receive();
|
||||
int waitRXcomplete();
|
||||
|
||||
int use_ecc = 1;
|
||||
};
|
||||
|
||||
extern DFM dfm;
|
||||
|
||||
#endif
|
51
RX_FSK/src/DecoderBase.cpp
Normal file
51
RX_FSK/src/DecoderBase.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
|
||||
#include "DecoderBase.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "Sonde.h"
|
||||
|
||||
#define DECODERBASE_DEBUG 1
|
||||
|
||||
#if DECODERBASE_DEBUG
|
||||
#define DBG(x) x
|
||||
#else
|
||||
#define DBG(x)
|
||||
#endif
|
||||
|
||||
|
||||
int DecoderBase::setup(decoderSetupCfg &setupcfg, uint16_t agcbw, uint16_t rxbw) {
|
||||
if(sx1278.setFSK()!=0) {
|
||||
DBG(Serial.println("Setting FSK mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setBitrate(setupcfg.bitrate)!=0) {
|
||||
DBG(Serial.println("Setting bitrate FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#if DECODERBASE_DEBUG
|
||||
float br = sx1278.getBitrate();
|
||||
Serial.print("Exact bitrate is ");
|
||||
Serial.println(br);
|
||||
#endif
|
||||
if(sx1278.setAFCBandwidth(agcbw)!=0) {
|
||||
DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(rxbw)!=0) {
|
||||
DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(sx1278.setRxConf(setupcfg.rx_cfg)!=0) {
|
||||
DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setSyncConf(setupcfg.sync_cfg, setupcfg.sync_len, setupcfg.sync_data)!=0) {
|
||||
DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setPreambleDetect(setupcfg.preamble_cfg)!=0) {
|
||||
DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
38
RX_FSK/src/DecoderBase.h
Normal file
38
RX_FSK/src/DecoderBase.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
#ifndef DECODER_BASE_H
|
||||
#define DECODER_BASE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "Sonde.h"
|
||||
|
||||
typedef struct _decoderSetupCfg {
|
||||
uint16_t bitrate;
|
||||
//uint16_t agcbw;
|
||||
//uint16_t rxbw;
|
||||
uint8_t rx_cfg;
|
||||
uint8_t sync_cfg;
|
||||
uint8_t sync_len;
|
||||
const uint8_t *sync_data;
|
||||
uint8_t preamble_cfg;
|
||||
} decoderSetupCfg;
|
||||
|
||||
/* Generic base class for all sonde decoders */
|
||||
class DecoderBase
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
int setup(decoderSetupCfg &setupcfg, uint16_t agcbw, uint16_t rxbw);
|
||||
virtual int setup(float frequency, int type=0) = 0;
|
||||
|
||||
virtual int receive() = 0;
|
||||
virtual int waitRXcomplete() = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
367
RX_FSK/src/DefaultFonts.c
Normal file
367
RX_FSK/src/DefaultFonts.c
Normal file
|
@ -0,0 +1,367 @@
|
|||
// SPDX-License-Identifier: GPL-3.0
|
||||
// original source: https://github.com/Nkawu/TFT_22_ILI9225
|
||||
|
||||
|
||||
#ifdef __AVR__
|
||||
#include <avr/pgmspace.h>
|
||||
#elif defined(ESP8266) || defined(ESP32)
|
||||
#include <pgmspace.h>
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAM) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) || defined(STM32F1) || defined(ESP32)
|
||||
#define PROGMEM
|
||||
#define fontdatatype const char
|
||||
#else
|
||||
#define fontdatatype const uint8_t
|
||||
#endif
|
||||
|
||||
//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
|
||||
//MikroElektronika 2011
|
||||
//http://www.mikroe.com
|
||||
|
||||
//GLCD FontName : Terminal6x8
|
||||
//GLCD FontSize : 6 x 8
|
||||
|
||||
fontdatatype Terminal6x8[] PROGMEM = {
|
||||
0x06, 0x08, 0x20, 0x60,
|
||||
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char
|
||||
0x05, 0x00, 0x00, 0x06, 0x5F, 0x06, 0x00, // Code for char !
|
||||
0x06, 0x00, 0x07, 0x03, 0x00, 0x07, 0x03, // Code for char "
|
||||
0x06, 0x00, 0x24, 0x7E, 0x24, 0x7E, 0x24, // Code for char #
|
||||
0x05, 0x00, 0x24, 0x2B, 0x6A, 0x12, 0x00, // Code for char $
|
||||
0x06, 0x00, 0x63, 0x13, 0x08, 0x64, 0x63, // Code for char %
|
||||
0x06, 0x00, 0x36, 0x49, 0x56, 0x20, 0x50, // Code for char &
|
||||
0x04, 0x00, 0x00, 0x07, 0x03, 0x00, 0x00, // Code for char '
|
||||
0x04, 0x00, 0x00, 0x3E, 0x41, 0x00, 0x00, // Code for char (
|
||||
0x04, 0x00, 0x00, 0x41, 0x3E, 0x00, 0x00, // Code for char )
|
||||
0x06, 0x00, 0x08, 0x3E, 0x1C, 0x3E, 0x08, // Code for char *
|
||||
0x06, 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // Code for char +
|
||||
0x04, 0x00, 0x00, 0xE0, 0x60, 0x00, 0x00, // Code for char ,
|
||||
0x06, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // Code for char -
|
||||
0x04, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // Code for char .
|
||||
0x06, 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // Code for char /
|
||||
0x06, 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // Code for char 0
|
||||
0x05, 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // Code for char 1
|
||||
0x06, 0x00, 0x62, 0x51, 0x49, 0x49, 0x46, // Code for char 2
|
||||
0x06, 0x00, 0x22, 0x49, 0x49, 0x49, 0x36, // Code for char 3
|
||||
0x06, 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // Code for char 4
|
||||
0x06, 0x00, 0x2F, 0x49, 0x49, 0x49, 0x31, // Code for char 5
|
||||
0x06, 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // Code for char 6
|
||||
0x06, 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // Code for char 7
|
||||
0x06, 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // Code for char 8
|
||||
0x06, 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // Code for char 9
|
||||
0x04, 0x00, 0x00, 0x6C, 0x6C, 0x00, 0x00, // Code for char :
|
||||
0x04, 0x00, 0x00, 0xEC, 0x6C, 0x00, 0x00, // Code for char ;
|
||||
0x05, 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // Code for char <
|
||||
0x06, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, // Code for char =
|
||||
0x06, 0x00, 0x00, 0x41, 0x22, 0x14, 0x08, // Code for char >
|
||||
0x06, 0x00, 0x02, 0x01, 0x59, 0x09, 0x06, // Code for char ?
|
||||
0x06, 0x00, 0x3E, 0x41, 0x5D, 0x55, 0x1E, // Code for char @
|
||||
0x06, 0x00, 0x7E, 0x11, 0x11, 0x11, 0x7E, // Code for char A
|
||||
0x06, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // Code for char B
|
||||
0x06, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // Code for char C
|
||||
0x06, 0x00, 0x7F, 0x41, 0x41, 0x41, 0x3E, // Code for char D
|
||||
0x06, 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // Code for char E
|
||||
0x06, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // Code for char F
|
||||
0x06, 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // Code for char G
|
||||
0x06, 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // Code for char H
|
||||
0x05, 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // Code for char I
|
||||
0x06, 0x00, 0x30, 0x40, 0x40, 0x40, 0x3F, // Code for char J
|
||||
0x06, 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // Code for char K
|
||||
0x06, 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // Code for char L
|
||||
0x06, 0x00, 0x7F, 0x02, 0x04, 0x02, 0x7F, // Code for char M
|
||||
0x06, 0x00, 0x7F, 0x02, 0x04, 0x08, 0x7F, // Code for char N
|
||||
0x06, 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // Code for char O
|
||||
0x06, 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // Code for char P
|
||||
0x06, 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Code for char Q
|
||||
0x06, 0x00, 0x7F, 0x09, 0x09, 0x19, 0x66, // Code for char R
|
||||
0x06, 0x00, 0x26, 0x49, 0x49, 0x49, 0x32, // Code for char S
|
||||
0x06, 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // Code for char T
|
||||
0x06, 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // Code for char U
|
||||
0x06, 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // Code for char V
|
||||
0x06, 0x00, 0x3F, 0x40, 0x3C, 0x40, 0x3F, // Code for char W
|
||||
0x06, 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // Code for char X
|
||||
0x06, 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Code for char Y
|
||||
0x05, 0x00, 0x71, 0x49, 0x45, 0x43, 0x00, // Code for char Z
|
||||
0x05, 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // Code for char [
|
||||
0x06, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // Code for char BackSlash
|
||||
0x05, 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // Code for char ]
|
||||
0x06, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // Code for char ^
|
||||
0x06, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // Code for char _
|
||||
0x04, 0x00, 0x00, 0x03, 0x07, 0x00, 0x00, // Code for char `
|
||||
0x06, 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // Code for char a
|
||||
0x06, 0x00, 0x7F, 0x44, 0x44, 0x44, 0x38, // Code for char b
|
||||
0x06, 0x00, 0x38, 0x44, 0x44, 0x44, 0x28, // Code for char c
|
||||
0x06, 0x00, 0x38, 0x44, 0x44, 0x44, 0x7F, // Code for char d
|
||||
0x06, 0x00, 0x38, 0x54, 0x54, 0x54, 0x08, // Code for char e
|
||||
0x05, 0x00, 0x08, 0x7E, 0x09, 0x09, 0x00, // Code for char f
|
||||
0x06, 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // Code for char g
|
||||
0x05, 0x00, 0x7F, 0x04, 0x04, 0x78, 0x00, // Code for char h
|
||||
0x05, 0x00, 0x00, 0x00, 0x7D, 0x40, 0x00, // Code for char i
|
||||
0x05, 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // Code for char j
|
||||
0x05, 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // Code for char k
|
||||
0x05, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x00, // Code for char l
|
||||
0x06, 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // Code for char m
|
||||
0x05, 0x00, 0x7C, 0x04, 0x04, 0x78, 0x00, // Code for char n
|
||||
0x06, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // Code for char o
|
||||
0x06, 0x00, 0xFC, 0x44, 0x44, 0x44, 0x38, // Code for char p
|
||||
0x06, 0x00, 0x38, 0x44, 0x44, 0x44, 0xFC, // Code for char q
|
||||
0x06, 0x00, 0x44, 0x78, 0x44, 0x04, 0x08, // Code for char r
|
||||
0x06, 0x00, 0x08, 0x54, 0x54, 0x54, 0x20, // Code for char s
|
||||
0x05, 0x00, 0x04, 0x3E, 0x44, 0x24, 0x00, // Code for char t
|
||||
0x05, 0x00, 0x3C, 0x40, 0x20, 0x7C, 0x00, // Code for char u
|
||||
0x06, 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // Code for char v
|
||||
0x06, 0x00, 0x3C, 0x60, 0x30, 0x60, 0x3C, // Code for char w
|
||||
0x05, 0x00, 0x6C, 0x10, 0x10, 0x6C, 0x00, // Code for char x
|
||||
0x05, 0x00, 0x9C, 0xA0, 0x60, 0x3C, 0x00, // Code for char y
|
||||
0x05, 0x00, 0x64, 0x54, 0x54, 0x4C, 0x00, // Code for char z
|
||||
0x05, 0x00, 0x08, 0x3E, 0x41, 0x41, 0x00, // Code for char {
|
||||
0x04, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, // Code for char |
|
||||
0x06, 0x00, 0x00, 0x41, 0x41, 0x3E, 0x08, // Code for char }
|
||||
0x05, 0x00, 0x02, 0x01, 0x02, 0x01, 0x00, // Code for char ~
|
||||
0x06, 0x00, 0x3C, 0x26, 0x23, 0x26, 0x3C // Code for char
|
||||
};
|
||||
|
||||
|
||||
//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
|
||||
//MikroElektronika 2011
|
||||
//http://www.mikroe.com
|
||||
|
||||
//GLCD FontName : Terminal11x16
|
||||
//GLCD FontSize : 11 x 16
|
||||
|
||||
fontdatatype Terminal11x16[] PROGMEM = {
|
||||
0x0B, 0x10, 0x20, 0x60,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x33, 0xFF, 0x33, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char !
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char "
|
||||
0x0B, 0x00, 0x02, 0x10, 0x1E, 0x90, 0x1F, 0xF0, 0x03, 0x7E, 0x02, 0x1E, 0x1E, 0x90, 0x1F, 0xF0, 0x03, 0x7E, 0x02, 0x1E, 0x00, 0x10, 0x00, // Code for char #
|
||||
0x09, 0x00, 0x00, 0x78, 0x04, 0xFC, 0x0C, 0xCC, 0x0C, 0xFF, 0x3F, 0xFF, 0x3F, 0xCC, 0x0C, 0xCC, 0x0F, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char $
|
||||
0x0B, 0x00, 0x30, 0x38, 0x38, 0x38, 0x1C, 0x38, 0x0E, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x38, 0x70, 0x38, 0x38, 0x38, 0x1C, 0x00, // Code for char %
|
||||
0x0A, 0x00, 0x00, 0x00, 0x1F, 0xB8, 0x3F, 0xFC, 0x31, 0xC6, 0x21, 0xE2, 0x37, 0x3E, 0x1E, 0x1C, 0x1C, 0x00, 0x36, 0x00, 0x22, 0x00, 0x00, // Code for char &
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x3F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char '
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0x07, 0x38, 0x01, 0x20, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char (
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x20, 0x07, 0x38, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char )
|
||||
0x09, 0x00, 0x00, 0x98, 0x0C, 0xB8, 0x0E, 0xE0, 0x03, 0xF8, 0x0F, 0xF8, 0x0F, 0xE0, 0x03, 0xB8, 0x0E, 0x98, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char *
|
||||
0x09, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xF0, 0x0F, 0xF0, 0x0F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char +
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ,
|
||||
0x09, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char -
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char .
|
||||
0x0B, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, // Code for char /
|
||||
0x0B, 0xF8, 0x07, 0xFE, 0x1F, 0x06, 0x1E, 0x03, 0x33, 0x83, 0x31, 0xC3, 0x30, 0x63, 0x30, 0x33, 0x30, 0x1E, 0x18, 0xFE, 0x1F, 0xF8, 0x07, // Code for char 0
|
||||
0x0A, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x30, 0x0C, 0x30, 0x0E, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, // Code for char 1
|
||||
0x0B, 0x1C, 0x30, 0x1E, 0x38, 0x07, 0x3C, 0x03, 0x3E, 0x03, 0x37, 0x83, 0x33, 0xC3, 0x31, 0xE3, 0x30, 0x77, 0x30, 0x3E, 0x30, 0x1C, 0x30, // Code for char 2
|
||||
0x0B, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x39, 0x7E, 0x1F, 0x3C, 0x0E, // Code for char 3
|
||||
0x0B, 0xC0, 0x03, 0xE0, 0x03, 0x70, 0x03, 0x38, 0x03, 0x1C, 0x03, 0x0E, 0x03, 0x07, 0x03, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x03, 0x00, 0x03, // Code for char 4
|
||||
0x0B, 0x3F, 0x0C, 0x7F, 0x1C, 0x63, 0x38, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0xE3, 0x38, 0xC3, 0x1F, 0x83, 0x0F, // Code for char 5
|
||||
0x0B, 0xC0, 0x0F, 0xF0, 0x1F, 0xF8, 0x39, 0xDC, 0x30, 0xCE, 0x30, 0xC7, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x39, 0x80, 0x1F, 0x00, 0x0F, // Code for char 6
|
||||
0x0B, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x30, 0x03, 0x3C, 0x03, 0x0F, 0xC3, 0x03, 0xF3, 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x03, 0x00, // Code for char 7
|
||||
0x0B, 0x00, 0x0F, 0xBC, 0x1F, 0xFE, 0x39, 0xE7, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x30, 0xFE, 0x39, 0xBC, 0x1F, 0x00, 0x0F, // Code for char 8
|
||||
0x0B, 0x3C, 0x00, 0x7E, 0x00, 0xE7, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x38, 0xC3, 0x1C, 0xC3, 0x0E, 0xE7, 0x07, 0xFE, 0x03, 0xFC, 0x00, // Code for char 9
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char :
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x9C, 0x70, 0xFC, 0x70, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ;
|
||||
0x09, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x01, 0xF0, 0x03, 0x38, 0x07, 0x1C, 0x0E, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char <
|
||||
0x0A, 0x00, 0x00, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x00, 0x00, // Code for char =
|
||||
0x09, 0x00, 0x00, 0x03, 0x30, 0x07, 0x38, 0x0E, 0x1C, 0x1C, 0x0E, 0x38, 0x07, 0xF0, 0x03, 0xE0, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char >
|
||||
0x0A, 0x1C, 0x00, 0x1E, 0x00, 0x07, 0x00, 0x03, 0x00, 0x83, 0x37, 0xC3, 0x37, 0xE3, 0x00, 0x77, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00, // Code for char ?
|
||||
0x0B, 0xF8, 0x0F, 0xFE, 0x1F, 0x07, 0x18, 0xF3, 0x33, 0xFB, 0x37, 0x1B, 0x36, 0xFB, 0x37, 0xFB, 0x37, 0x07, 0x36, 0xFE, 0x03, 0xF8, 0x01, // Code for char @
|
||||
0x0A, 0x00, 0x38, 0x00, 0x3F, 0xE0, 0x07, 0xFC, 0x06, 0x1F, 0x06, 0x1F, 0x06, 0xFC, 0x06, 0xE0, 0x07, 0x00, 0x3F, 0x00, 0x38, 0x00, 0x00, // Code for char A
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x30, 0xFE, 0x39, 0xBC, 0x1F, 0x00, 0x0F, 0x00, 0x00, // Code for char B
|
||||
0x0A, 0xF0, 0x03, 0xFC, 0x0F, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00, // Code for char C
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x07, 0x38, 0x0E, 0x1C, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, // Code for char D
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, // Code for char E
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char F
|
||||
0x0A, 0xF0, 0x03, 0xFC, 0x0F, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC7, 0x3F, 0xC6, 0x3F, 0x00, 0x00, // Code for char G
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char H
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I
|
||||
0x0A, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0xFF, 0x1F, 0xFF, 0x07, 0x00, 0x00, // Code for char J
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC0, 0x00, 0xE0, 0x01, 0xF0, 0x03, 0x38, 0x07, 0x1C, 0x0E, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0x00, 0x00, // Code for char K
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, // Code for char L
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x1E, 0x00, 0x78, 0x00, 0xE0, 0x01, 0xE0, 0x01, 0x78, 0x00, 0x1E, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char M
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x0E, 0x00, 0x38, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x07, 0x00, 0x1C, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char N
|
||||
0x0A, 0xF0, 0x03, 0xFC, 0x0F, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0x03, 0x30, 0x07, 0x38, 0x0E, 0x1C, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, // Code for char O
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0xC7, 0x01, 0xFE, 0x00, 0x7C, 0x00, 0x00, 0x00, // Code for char P
|
||||
0x0A, 0xF0, 0x03, 0xFC, 0x0F, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30, 0x03, 0x36, 0x07, 0x3E, 0x0E, 0x1C, 0xFC, 0x3F, 0xF0, 0x33, 0x00, 0x00, // Code for char Q
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x83, 0x01, 0x83, 0x01, 0x83, 0x03, 0x83, 0x07, 0x83, 0x0F, 0xC7, 0x1D, 0xFE, 0x38, 0x7C, 0x30, 0x00, 0x00, // Code for char R
|
||||
0x0A, 0x3C, 0x0C, 0x7E, 0x1C, 0xE7, 0x38, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC7, 0x39, 0x8E, 0x1F, 0x0C, 0x0F, 0x00, 0x00, // Code for char S
|
||||
0x09, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T
|
||||
0x0A, 0xFF, 0x07, 0xFF, 0x1F, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0xFF, 0x1F, 0xFF, 0x07, 0x00, 0x00, // Code for char U
|
||||
0x0A, 0x07, 0x00, 0x3F, 0x00, 0xF8, 0x01, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0x3E, 0xC0, 0x0F, 0xF8, 0x01, 0x3F, 0x00, 0x07, 0x00, 0x00, 0x00, // Code for char V
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x1C, 0x00, 0x06, 0x80, 0x03, 0x80, 0x03, 0x00, 0x06, 0x00, 0x1C, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char W
|
||||
0x0A, 0x03, 0x30, 0x0F, 0x3C, 0x1C, 0x0E, 0x30, 0x03, 0xE0, 0x01, 0xE0, 0x01, 0x30, 0x03, 0x1C, 0x0E, 0x0F, 0x3C, 0x03, 0x30, 0x00, 0x00, // Code for char X
|
||||
0x0A, 0x03, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x3F, 0xC0, 0x3F, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char Y
|
||||
0x0A, 0x03, 0x30, 0x03, 0x3C, 0x03, 0x3E, 0x03, 0x33, 0xC3, 0x31, 0xE3, 0x30, 0x33, 0x30, 0x1F, 0x30, 0x0F, 0x30, 0x03, 0x30, 0x00, 0x00, // Code for char Z
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [
|
||||
0x0B, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x18, // Code for char BackSlash
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ]
|
||||
0x0B, 0x60, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x00, // Code for char ^
|
||||
0x0B, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, // Code for char _
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x7E, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char `
|
||||
0x0A, 0x00, 0x1C, 0x40, 0x3E, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0xE0, 0x3F, 0xC0, 0x3F, 0x00, 0x00, // Code for char a
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xC0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x38, 0xC0, 0x1F, 0x80, 0x0F, 0x00, 0x00, // Code for char b
|
||||
0x0A, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xC0, 0x18, 0x80, 0x08, 0x00, 0x00, // Code for char c
|
||||
0x0A, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x30, 0xC0, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char d
|
||||
0x0A, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3B, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0xC0, 0x13, 0x80, 0x01, 0x00, 0x00, // Code for char e
|
||||
0x08, 0xC0, 0x00, 0xC0, 0x00, 0xFC, 0x3F, 0xFE, 0x3F, 0xC7, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f
|
||||
0x0A, 0x80, 0x03, 0xC0, 0xC7, 0xE0, 0xCE, 0x60, 0xCC, 0x60, 0xCC, 0x60, 0xCC, 0x60, 0xCC, 0x60, 0xE6, 0xE0, 0x7F, 0xE0, 0x3F, 0x00, 0x00, // Code for char g
|
||||
0x09, 0xFF, 0x3F, 0xFF, 0x3F, 0xC0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, // Code for char h
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x30, 0xEC, 0x3F, 0xEC, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x60, 0xC0, 0xEC, 0xFF, 0xEC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j
|
||||
0x09, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x03, 0x80, 0x07, 0xC0, 0x0F, 0xE0, 0x1C, 0x60, 0x38, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char k
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l
|
||||
0x0A, 0xE0, 0x3F, 0xC0, 0x3F, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x3F, 0xC0, 0x3F, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, // Code for char m
|
||||
0x0A, 0x00, 0x00, 0xE0, 0x3F, 0xE0, 0x3F, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, // Code for char n
|
||||
0x0A, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x38, 0xC0, 0x1F, 0x80, 0x0F, 0x00, 0x00, // Code for char o
|
||||
0x0A, 0xE0, 0xFF, 0xE0, 0xFF, 0x60, 0x0C, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0xE0, 0x1C, 0xC0, 0x0F, 0x80, 0x07, 0x00, 0x00, // Code for char p
|
||||
0x0A, 0x80, 0x07, 0xC0, 0x0F, 0xE0, 0x1C, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x0C, 0xE0, 0xFF, 0xE0, 0xFF, 0x00, 0x00, // Code for char q
|
||||
0x0A, 0x00, 0x00, 0xE0, 0x3F, 0xE0, 0x3F, 0xC0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0x00, 0x00, // Code for char r
|
||||
0x08, 0xC0, 0x11, 0xE0, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x3F, 0x40, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s
|
||||
0x08, 0x60, 0x00, 0x60, 0x00, 0xFE, 0x1F, 0xFE, 0x3F, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t
|
||||
0x0A, 0xE0, 0x0F, 0xE0, 0x1F, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x18, 0xE0, 0x3F, 0xE0, 0x3F, 0x00, 0x00, // Code for char u
|
||||
0x0A, 0x60, 0x00, 0xE0, 0x01, 0x80, 0x07, 0x00, 0x1E, 0x00, 0x38, 0x00, 0x38, 0x00, 0x1E, 0x80, 0x07, 0xE0, 0x01, 0x60, 0x00, 0x00, 0x00, // Code for char v
|
||||
0x0A, 0xE0, 0x07, 0xE0, 0x1F, 0x00, 0x38, 0x00, 0x1C, 0xE0, 0x0F, 0xE0, 0x0F, 0x00, 0x1C, 0x00, 0x38, 0xE0, 0x1F, 0xE0, 0x07, 0x00, 0x00, // Code for char w
|
||||
0x09, 0x60, 0x30, 0xE0, 0x38, 0xC0, 0x1D, 0x80, 0x0F, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x1D, 0xE0, 0x38, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char x
|
||||
0x09, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x81, 0x80, 0xE7, 0x00, 0x7E, 0x00, 0x1E, 0x80, 0x07, 0xE0, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y
|
||||
0x09, 0x60, 0x30, 0x60, 0x38, 0x60, 0x3C, 0x60, 0x36, 0x60, 0x33, 0xE0, 0x31, 0xE0, 0x30, 0x60, 0x30, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char z
|
||||
0x09, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x01, 0xFC, 0x1F, 0x7E, 0x3F, 0x07, 0x70, 0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, // Code for char {
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char |
|
||||
0x09, 0x00, 0x00, 0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x07, 0x70, 0x7E, 0x3F, 0xFC, 0x1F, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char }
|
||||
0x0A, 0x10, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x0C, 0x00, 0x18, 0x00, 0x10, 0x00, 0x18, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char ~
|
||||
0x0A, 0x00, 0x0F, 0x80, 0x0F, 0xC0, 0x0C, 0x60, 0x0C, 0x30, 0x0C, 0x30, 0x0C, 0x60, 0x0C, 0xC0, 0x0C, 0x80, 0x0F, 0x00, 0x0F, 0x00, 0x00 // Code for char
|
||||
};
|
||||
|
||||
|
||||
//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
|
||||
//MikroElektronika 2011
|
||||
//http://www.mikroe.com
|
||||
|
||||
//GLCD FontName : Terminal12x16
|
||||
//GLCD FontSize : 12 x 16
|
||||
|
||||
fontdatatype Terminal12x16[] PROGMEM = {
|
||||
0x0C, 0x10, 0x20, 0x60,
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char !
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char "
|
||||
0x0C, 0x00, 0x02, 0x10, 0x1E, 0x90, 0x1F, 0xF0, 0x1F, 0xFE, 0x03, 0x7E, 0x1E, 0x9E, 0x1F, 0xF0, 0x1F, 0xFE, 0x03, 0x7E, 0x02, 0x1E, 0x00, 0x10, 0x00, // Code for char #
|
||||
0x0A, 0x00, 0x00, 0x78, 0x04, 0xFC, 0x0C, 0xFC, 0x0C, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xCC, 0x0F, 0xCC, 0x0F, 0x88, 0x07, 0x00, 0x00, 0x00, 0x00, // Code for char $
|
||||
0x0C, 0x00, 0x30, 0x38, 0x38, 0x38, 0x3C, 0x38, 0x1E, 0x38, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x39, 0xF0, 0x38, 0x78, 0x38, 0x3C, 0x38, 0x1C, 0x00, // Code for char %
|
||||
0x0B, 0x00, 0x00, 0x00, 0x1F, 0xB8, 0x3F, 0xFC, 0x3F, 0xFE, 0x31, 0xE6, 0x37, 0xFE, 0x3F, 0x3E, 0x1E, 0x1C, 0x3E, 0x00, 0x36, 0x00, 0x22, 0x00, 0x00, // Code for char &
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x3F, 0x00, 0x3F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char '
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0xFF, 0x3F, 0x07, 0x38, 0x01, 0x20, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char (
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x20, 0x07, 0x38, 0xFF, 0x3F, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char )
|
||||
0x0A, 0x00, 0x00, 0x98, 0x0C, 0xB8, 0x0E, 0xF8, 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xF8, 0x0F, 0xB8, 0x0E, 0x98, 0x0C, 0x00, 0x00, 0x00, 0x00, // Code for char *
|
||||
0x0A, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char +
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ,
|
||||
0x0A, 0x00, 0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, // Code for char -
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char .
|
||||
0x0C, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x1E, 0x00, 0x0F, 0x80, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0E, 0x00, // Code for char /
|
||||
0x0C, 0xF8, 0x07, 0xFE, 0x1F, 0xFE, 0x1F, 0x07, 0x3F, 0x83, 0x33, 0xC3, 0x31, 0xE3, 0x30, 0x73, 0x30, 0x3F, 0x38, 0xFE, 0x1F, 0xFE, 0x1F, 0xF8, 0x07, // Code for char 0
|
||||
0x0B, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x30, 0x0C, 0x30, 0x0E, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, // Code for char 1
|
||||
0x0C, 0x1C, 0x30, 0x1E, 0x38, 0x1F, 0x3C, 0x07, 0x3E, 0x03, 0x3F, 0x83, 0x37, 0xC3, 0x33, 0xE3, 0x31, 0xF7, 0x30, 0x7F, 0x30, 0x3E, 0x30, 0x1C, 0x30, // Code for char 2
|
||||
0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x0F, 0x3C, 0xC7, 0x38, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x39, 0xFF, 0x3F, 0x7E, 0x1F, 0x3C, 0x0E, // Code for char 3
|
||||
0x0C, 0xC0, 0x03, 0xE0, 0x03, 0xF0, 0x03, 0x78, 0x03, 0x3C, 0x03, 0x1E, 0x03, 0x0F, 0x03, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x03, 0x00, 0x03, // Code for char 4
|
||||
0x0C, 0x3F, 0x0C, 0x7F, 0x1C, 0x7F, 0x3C, 0x63, 0x38, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0xE3, 0x38, 0xE3, 0x3F, 0xC3, 0x1F, 0x83, 0x0F, // Code for char 5
|
||||
0x0C, 0xC0, 0x0F, 0xF0, 0x1F, 0xF8, 0x3F, 0xFC, 0x39, 0xDE, 0x30, 0xCF, 0x30, 0xC7, 0x30, 0xC3, 0x30, 0xC3, 0x39, 0xC3, 0x3F, 0x80, 0x1F, 0x00, 0x0F, // Code for char 6
|
||||
0x0C, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x30, 0x03, 0x3C, 0x03, 0x3F, 0xC3, 0x0F, 0xF3, 0x03, 0xFF, 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x03, 0x00, // Code for char 7
|
||||
0x0C, 0x00, 0x0F, 0xBC, 0x1F, 0xFE, 0x3F, 0xFF, 0x39, 0xE7, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x30, 0xFF, 0x39, 0xFE, 0x3F, 0xBC, 0x1F, 0x00, 0x0F, // Code for char 8
|
||||
0x0C, 0x3C, 0x00, 0x7E, 0x00, 0xFF, 0x30, 0xE7, 0x30, 0xC3, 0x30, 0xC3, 0x38, 0xC3, 0x3C, 0xC3, 0x1E, 0xE7, 0x0F, 0xFF, 0x07, 0xFE, 0x03, 0xFC, 0x00, // Code for char 9
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x70, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char :
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x9C, 0x70, 0xFC, 0x70, 0xFC, 0x70, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ;
|
||||
0x0A, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x01, 0xF0, 0x03, 0xF8, 0x07, 0x3C, 0x0F, 0x1E, 0x1E, 0x0F, 0x3C, 0x07, 0x38, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char <
|
||||
0x0B, 0x00, 0x00, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x60, 0x06, 0x00, 0x00, // Code for char =
|
||||
0x0A, 0x00, 0x00, 0x03, 0x30, 0x07, 0x38, 0x0F, 0x3C, 0x1E, 0x1E, 0x3C, 0x0F, 0xF8, 0x07, 0xF0, 0x03, 0xE0, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char >
|
||||
0x0B, 0x1C, 0x00, 0x1E, 0x00, 0x1F, 0x00, 0x07, 0x00, 0x83, 0x37, 0xC3, 0x37, 0xE3, 0x37, 0xF7, 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x00, 0x00, // Code for char ?
|
||||
0x0C, 0xF8, 0x0F, 0xFE, 0x1F, 0xFF, 0x1F, 0xF7, 0x3B, 0xFB, 0x37, 0xFB, 0x37, 0xFB, 0x37, 0xFB, 0x37, 0xFF, 0x37, 0xFF, 0x37, 0xFE, 0x03, 0xF8, 0x01, // Code for char @
|
||||
0x0B, 0x00, 0x38, 0x00, 0x3F, 0xE0, 0x3F, 0xFC, 0x07, 0xFF, 0x06, 0x1F, 0x06, 0xFF, 0x06, 0xFC, 0x07, 0xE0, 0x3F, 0x00, 0x3F, 0x00, 0x38, 0x00, 0x00, // Code for char A
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xE7, 0x30, 0xFF, 0x39, 0xFE, 0x3F, 0xBC, 0x1F, 0x00, 0x0F, 0x00, 0x00, // Code for char B
|
||||
0x0B, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0x0F, 0x3C, 0x07, 0x38, 0x03, 0x30, 0x03, 0x30, 0x07, 0x38, 0x0F, 0x3C, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00, // Code for char C
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x07, 0x38, 0x0F, 0x3C, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, // Code for char D
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, // Code for char E
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char F
|
||||
0x0B, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0x0F, 0x3C, 0x07, 0x38, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC7, 0x3F, 0xC7, 0x3F, 0xC6, 0x3F, 0x00, 0x00, // Code for char G
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char H
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char I
|
||||
0x0B, 0x00, 0x0E, 0x00, 0x1E, 0x00, 0x3E, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0xFF, 0x3F, 0xFF, 0x1F, 0xFF, 0x07, 0x00, 0x00, // Code for char J
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xE0, 0x01, 0xF0, 0x03, 0xF8, 0x07, 0x3C, 0x0F, 0x1E, 0x1E, 0x0F, 0x3C, 0x07, 0x38, 0x03, 0x30, 0x00, 0x00, // Code for char K
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, // Code for char L
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x7E, 0x00, 0xF8, 0x01, 0xE0, 0x01, 0xF8, 0x01, 0x7E, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char M
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x3E, 0x00, 0xF8, 0x00, 0xF0, 0x03, 0xC0, 0x07, 0x00, 0x1F, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char N
|
||||
0x0B, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0x0F, 0x3C, 0x07, 0x38, 0x03, 0x30, 0x07, 0x38, 0x0F, 0x3C, 0xFE, 0x1F, 0xFC, 0x0F, 0xF0, 0x03, 0x00, 0x00, // Code for char O
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0xC7, 0x01, 0xFF, 0x01, 0xFE, 0x00, 0x7C, 0x00, 0x00, 0x00, // Code for char P
|
||||
0x0B, 0xF0, 0x03, 0xFC, 0x0F, 0xFE, 0x1F, 0x0F, 0x3C, 0x07, 0x38, 0x03, 0x36, 0x07, 0x3E, 0x0F, 0x3E, 0xFE, 0x3F, 0xFC, 0x3F, 0xF0, 0x33, 0x00, 0x00, // Code for char Q
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x83, 0x01, 0x83, 0x03, 0x83, 0x07, 0x83, 0x0F, 0xC7, 0x1F, 0xFF, 0x3D, 0xFE, 0x38, 0x7C, 0x30, 0x00, 0x00, // Code for char R
|
||||
0x0B, 0x3C, 0x0C, 0x7E, 0x1C, 0xFF, 0x3C, 0xE7, 0x38, 0xC3, 0x30, 0xC3, 0x30, 0xC3, 0x30, 0xC7, 0x39, 0xCF, 0x3F, 0x8E, 0x1F, 0x0C, 0x0F, 0x00, 0x00, // Code for char S
|
||||
0x0A, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char T
|
||||
0x0B, 0xFF, 0x07, 0xFF, 0x1F, 0xFF, 0x3F, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0xFF, 0x3F, 0xFF, 0x1F, 0xFF, 0x07, 0x00, 0x00, // Code for char U
|
||||
0x0B, 0x07, 0x00, 0x3F, 0x00, 0xFF, 0x01, 0xF8, 0x0F, 0xC0, 0x3F, 0x00, 0x3E, 0xC0, 0x3F, 0xF8, 0x0F, 0xFF, 0x01, 0x3F, 0x00, 0x07, 0x00, 0x00, 0x00, // Code for char V
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x1E, 0x80, 0x07, 0x80, 0x03, 0x80, 0x07, 0x00, 0x1E, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char W
|
||||
0x0B, 0x03, 0x30, 0x0F, 0x3C, 0x1F, 0x3E, 0x3C, 0x0F, 0xF0, 0x03, 0xE0, 0x01, 0xF0, 0x03, 0x3C, 0x0F, 0x1F, 0x3E, 0x0F, 0x3C, 0x03, 0x30, 0x00, 0x00, // Code for char X
|
||||
0x0B, 0x03, 0x00, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x3F, 0xC0, 0x3F, 0xF0, 0x3F, 0xFC, 0x00, 0x3F, 0x00, 0x0F, 0x00, 0x03, 0x00, 0x00, 0x00, // Code for char Y
|
||||
0x0B, 0x03, 0x30, 0x03, 0x3C, 0x03, 0x3E, 0x03, 0x3F, 0xC3, 0x33, 0xE3, 0x31, 0xF3, 0x30, 0x3F, 0x30, 0x1F, 0x30, 0x0F, 0x30, 0x03, 0x30, 0x00, 0x00, // Code for char Z
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char [
|
||||
0x0C, 0x0E, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0xF0, 0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0F, 0x00, 0x1E, 0x00, 0x1C, 0x00, 0x18, // Code for char BackSlash
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char ]
|
||||
0x0C, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0x78, 0x00, 0x70, 0x00, 0x60, 0x00, // Code for char ^
|
||||
0x0C, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, // Code for char _
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char `
|
||||
0x0B, 0x00, 0x1C, 0x40, 0x3E, 0x60, 0x3F, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0xE0, 0x3F, 0xE0, 0x3F, 0xC0, 0x3F, 0x00, 0x00, // Code for char a
|
||||
0x0B, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xE0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x38, 0xE0, 0x3F, 0xC0, 0x1F, 0x80, 0x0F, 0x00, 0x00, // Code for char b
|
||||
0x0B, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x38, 0xC0, 0x18, 0x80, 0x08, 0x00, 0x00, // Code for char c
|
||||
0x0B, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x30, 0xE0, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, // Code for char d
|
||||
0x0B, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3F, 0xE0, 0x3B, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0xE0, 0x33, 0xC0, 0x13, 0x80, 0x01, 0x00, 0x00, // Code for char e
|
||||
0x09, 0xC0, 0x00, 0xC0, 0x00, 0xFC, 0x3F, 0xFE, 0x3F, 0xFF, 0x3F, 0xC7, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char f
|
||||
0x0B, 0x80, 0x03, 0xC0, 0xC7, 0xE0, 0xCF, 0xE0, 0xCE, 0x60, 0xCC, 0x60, 0xCC, 0x60, 0xCC, 0x60, 0xEE, 0xE0, 0xFF, 0xE0, 0x7F, 0xE0, 0x3F, 0x00, 0x00, // Code for char g
|
||||
0x0A, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0xE0, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x3F, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, // Code for char h
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x30, 0xEC, 0x3F, 0xEC, 0x3F, 0xEC, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char i
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x60, 0xC0, 0xEC, 0xFF, 0xEC, 0xFF, 0xEC, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char j
|
||||
0x0A, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x80, 0x07, 0xC0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3C, 0x60, 0x38, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char k
|
||||
0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x30, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char l
|
||||
0x0B, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x00, 0xE0, 0x3F, 0xC0, 0x3F, 0xE0, 0x3F, 0xE0, 0x00, 0xE0, 0x3F, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, // Code for char m
|
||||
0x0B, 0x00, 0x00, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x3F, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x3F, 0xC0, 0x3F, 0x80, 0x3F, 0x00, 0x00, // Code for char n
|
||||
0x0B, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3F, 0xE0, 0x38, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0xE0, 0x38, 0xE0, 0x3F, 0xC0, 0x1F, 0x80, 0x0F, 0x00, 0x00, // Code for char o
|
||||
0x0B, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0x60, 0x1C, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0xE0, 0x1C, 0xE0, 0x1F, 0xC0, 0x0F, 0x80, 0x07, 0x00, 0x00, // Code for char p
|
||||
0x0B, 0x80, 0x07, 0xC0, 0x0F, 0xE0, 0x1F, 0xE0, 0x1C, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x1C, 0xE0, 0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0x00, 0x00, // Code for char q
|
||||
0x0B, 0x00, 0x00, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0x00, 0x00, // Code for char r
|
||||
0x09, 0xC0, 0x11, 0xE0, 0x33, 0xE0, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x33, 0x60, 0x3F, 0x60, 0x3F, 0x40, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char s
|
||||
0x09, 0x60, 0x00, 0x60, 0x00, 0xFE, 0x1F, 0xFE, 0x3F, 0xFE, 0x3F, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char t
|
||||
0x0B, 0xE0, 0x0F, 0xE0, 0x1F, 0xE0, 0x3F, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0xE0, 0x3F, 0xE0, 0x3F, 0xE0, 0x3F, 0x00, 0x00, // Code for char u
|
||||
0x0B, 0x60, 0x00, 0xE0, 0x01, 0xE0, 0x07, 0x80, 0x1F, 0x00, 0x3E, 0x00, 0x38, 0x00, 0x3E, 0x80, 0x1F, 0xE0, 0x07, 0xE0, 0x01, 0x60, 0x00, 0x00, 0x00, // Code for char v
|
||||
0x0B, 0xE0, 0x07, 0xE0, 0x1F, 0xE0, 0x3F, 0x00, 0x3C, 0xE0, 0x1F, 0xE0, 0x0F, 0xE0, 0x1F, 0x00, 0x3C, 0xE0, 0x3F, 0xE0, 0x1F, 0xE0, 0x07, 0x00, 0x00, // Code for char w
|
||||
0x0A, 0x60, 0x30, 0xE0, 0x38, 0xE0, 0x3D, 0xC0, 0x1F, 0x80, 0x0F, 0x80, 0x0F, 0xC0, 0x1F, 0xE0, 0x3D, 0xE0, 0x38, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char x
|
||||
0x0A, 0x00, 0x00, 0x60, 0x00, 0xE0, 0x81, 0xE0, 0xE7, 0x80, 0xFF, 0x00, 0x7E, 0x80, 0x1F, 0xE0, 0x07, 0xE0, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char y
|
||||
0x0A, 0x60, 0x30, 0x60, 0x38, 0x60, 0x3C, 0x60, 0x3E, 0x60, 0x37, 0xE0, 0x33, 0xE0, 0x31, 0xE0, 0x30, 0x60, 0x30, 0x20, 0x30, 0x00, 0x00, 0x00, 0x00, // Code for char z
|
||||
0x0A, 0x00, 0x00, 0x80, 0x00, 0xC0, 0x01, 0xFC, 0x1F, 0xFE, 0x3F, 0x7F, 0x7F, 0x07, 0x70, 0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x00, 0x00, 0x00, 0x00, // Code for char {
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x3F, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char |
|
||||
0x0A, 0x00, 0x00, 0x03, 0x60, 0x03, 0x60, 0x03, 0x60, 0x07, 0x70, 0x7F, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char }
|
||||
0x0B, 0x10, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, // Code for char ~
|
||||
0x0B, 0x00, 0x0F, 0x80, 0x0F, 0xC0, 0x0F, 0xE0, 0x0C, 0x70, 0x0C, 0x30, 0x0C, 0x70, 0x0C, 0xE0, 0x0C, 0xC0, 0x0F, 0x80, 0x0F, 0x00, 0x0F, 0x00, 0x00 // Code for char
|
||||
};
|
||||
|
||||
|
||||
//Font Generated by MikroElektronika GLCD Font Creator 1.2.0.0
|
||||
//MikroElektronika 2011
|
||||
//http://www.mikroe.com
|
||||
|
||||
//GLCD FontName : Trebuchet_MS16x21
|
||||
//GLCD FontSize : 16 x 21
|
||||
|
||||
fontdatatype Trebuchet_MS16x21[] PROGMEM = {
|
||||
0x10, 0x15, 0x2E, 0x0D,
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char .
|
||||
0x0C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x1E, 0x00, 0xC0, 0x1F, 0x00, 0xF0, 0x1F, 0x00, 0xFE, 0x0F, 0x80, 0xFF, 0x03, 0xF0, 0x7F, 0x00, 0xFE, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0x7F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char /
|
||||
0x10, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0x00, 0xF0, 0xFF, 0x03, 0xFC, 0xFF, 0x07, 0xFE, 0xFF, 0x0F, 0x3E, 0x80, 0x0F, 0x0F, 0x00, 0x1E, 0x07, 0x00, 0x1C, 0x07, 0x00, 0x1C, 0x07, 0x00, 0x1C, 0x0F, 0x00, 0x1E, 0x1F, 0x80, 0x0F, 0xFE, 0xFF, 0x0F, 0xFC, 0xFF, 0x07, 0xF8, 0xFF, 0x01, 0xC0, 0x7F, 0x00, // Code for char 0
|
||||
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x78, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3C, 0x00, 0x00, 0xFE, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char 1
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x18, 0x1E, 0x00, 0x1C, 0x0E, 0x00, 0x1F, 0x0F, 0x80, 0x1F, 0x07, 0xC0, 0x1F, 0x07, 0xF0, 0x1F, 0x07, 0xF8, 0x1D, 0x07, 0xFE, 0x1C, 0x0F, 0x3F, 0x1C, 0xFE, 0x1F, 0x1C, 0xFE, 0x0F, 0x1C, 0xFC, 0x03, 0x1C, 0xF8, 0x00, 0x1C, 0x00, 0x00, 0x1C, // Code for char 2
|
||||
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x0E, 0x0E, 0x00, 0x0F, 0x0F, 0x00, 0x1E, 0x07, 0x00, 0x1C, 0x07, 0x07, 0x1C, 0x07, 0x07, 0x1C, 0x07, 0x07, 0x1C, 0x8F, 0x0F, 0x1E, 0xFF, 0x1F, 0x1E, 0xFE, 0xFD, 0x0F, 0xFC, 0xFD, 0x0F, 0x78, 0xF8, 0x07, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, // Code for char 3
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xF0, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xFE, 0x00, 0x00, 0xEF, 0x00, 0x80, 0xE7, 0x00, 0xC0, 0xE3, 0x00, 0xF0, 0xE0, 0x00, 0x78, 0xE0, 0x00, 0xFC, 0xFF, 0x1F, 0xFE, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0x1F, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, // Code for char 4
|
||||
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0x03, 0x0F, 0xFF, 0x07, 0x0E, 0xFF, 0x03, 0x1C, 0xFF, 0x01, 0x1C, 0xC7, 0x01, 0x1C, 0xC7, 0x01, 0x1C, 0xC7, 0x01, 0x1E, 0xC7, 0x03, 0x1F, 0xC7, 0xFF, 0x0F, 0x87, 0xFF, 0x0F, 0x07, 0xFF, 0x07, 0x00, 0xFC, 0x01, 0x00, 0x00, 0x00, // Code for char 5
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x80, 0xFF, 0x03, 0xE0, 0xFF, 0x07, 0xF0, 0xFF, 0x0F, 0xF8, 0x0F, 0x1E, 0x7C, 0x07, 0x1C, 0x3E, 0x07, 0x1C, 0x1E, 0x07, 0x1C, 0x0F, 0x07, 0x1C, 0x07, 0x0F, 0x1E, 0x02, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x00, 0xFC, 0x07, 0x00, 0xF0, 0x01, // Code for char 6
|
||||
0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x00, 0x07, 0x00, 0x18, 0x07, 0x00, 0x1E, 0x07, 0xC0, 0x1F, 0x07, 0xF0, 0x1F, 0x07, 0xFC, 0x0F, 0x07, 0xFF, 0x01, 0xC7, 0x7F, 0x00, 0xF7, 0x0F, 0x00, 0xFF, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x03, 0x00, 0x00, // Code for char 7
|
||||
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x03, 0x78, 0xF8, 0x07, 0xFC, 0xFD, 0x0F, 0xFE, 0xFF, 0x0F, 0xFF, 0x1F, 0x1E, 0x8F, 0x0F, 0x1C, 0x07, 0x07, 0x1C, 0x07, 0x0F, 0x1C, 0x8F, 0x0F, 0x1C, 0xFF, 0x3F, 0x1E, 0xFE, 0xFD, 0x0F, 0xFE, 0xFD, 0x0F, 0x78, 0xF0, 0x07, 0x00, 0xE0, 0x03, // Code for char 8
|
||||
0x0F, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0xFC, 0x07, 0x00, 0xFE, 0x0F, 0x00, 0xFE, 0x0F, 0x08, 0x0F, 0x1E, 0x1C, 0x07, 0x1C, 0x1E, 0x07, 0x1C, 0x0F, 0x07, 0x9C, 0x0F, 0x07, 0xDC, 0x07, 0x0F, 0xFE, 0x03, 0xFE, 0xFF, 0x01, 0xFC, 0xFF, 0x00, 0xF8, 0x3F, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, // Code for char 9
|
||||
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x0C, 0xC0, 0x03, 0x1E, 0xC0, 0x03, 0x1E, 0x80, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Code for char :
|
||||
};
|
||||
|
||||
|
||||
|
1616
RX_FSK/src/Display.cpp
Normal file
1616
RX_FSK/src/Display.cpp
Normal file
File diff suppressed because it is too large
Load Diff
185
RX_FSK/src/Display.h
Normal file
185
RX_FSK/src/Display.h
Normal file
|
@ -0,0 +1,185 @@
|
|||
#ifndef Display_h
|
||||
#define Display_h
|
||||
|
||||
#define FONT_LARGE 1
|
||||
#define FONT_SMALL 0
|
||||
|
||||
#include <SPI.h>
|
||||
#include <Arduino_GFX_Library.h>
|
||||
#include <U8x8lib.h>
|
||||
#include <SPIFFS.h>
|
||||
|
||||
struct GpsPos {
|
||||
double lat;
|
||||
double lon;
|
||||
int alt;
|
||||
int course;
|
||||
float speed;
|
||||
int sat;
|
||||
int accuracy;
|
||||
int hdop;
|
||||
int valid;
|
||||
};
|
||||
extern struct GpsPos gpsPos;
|
||||
|
||||
#define WIDTH_AUTO 9999
|
||||
struct DispEntry {
|
||||
int16_t y;
|
||||
int16_t x;
|
||||
int16_t fmt, width;
|
||||
uint16_t fg,bg;
|
||||
void (*func)(DispEntry *de);
|
||||
const char *extra;
|
||||
};
|
||||
|
||||
#define GPSUSE_BASE 1
|
||||
#define GPSUSE_DIST 2
|
||||
#define GPSUSE_BEARING 4
|
||||
struct DispInfo {
|
||||
DispEntry *de;
|
||||
uint8_t *actions;
|
||||
int16_t *timeouts;
|
||||
const char *label;
|
||||
uint8_t usegps;
|
||||
};
|
||||
|
||||
struct StatInfo {
|
||||
uint8_t len;
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
struct CircleInfo { // 3,5=g0NCS,50,ff0000,000033,5,ffff00,4,ffffff
|
||||
char type;
|
||||
char top,bul,arr; // what to point to with top, bullet, array
|
||||
uint16_t fgcol, bgcol;
|
||||
uint8_t radius;
|
||||
uint8_t brad;
|
||||
uint16_t bcol;
|
||||
uint8_t awidth;
|
||||
uint16_t acol;
|
||||
};
|
||||
|
||||
// Now starting towards supporting different Display types / libraries
|
||||
class RawDisplay {
|
||||
public:
|
||||
virtual void begin() = 0;
|
||||
virtual void clear() = 0;
|
||||
virtual void setContrast(uint8_t contrast) = 0;
|
||||
virtual void setFont(uint8_t fontindex) = 0;
|
||||
virtual void getDispSize(uint8_t *height, uint8_t *width, uint8_t *lineskip, uint8_t *colskip) = 0;
|
||||
virtual void drawString(uint16_t x, uint16_t y, const char *s, int16_t width=WIDTH_AUTO, uint16_t fg=0xffff, uint16_t bg=0 ) = 0;
|
||||
virtual void drawTile(uint16_t x, uint16_t y, uint8_t cnt, uint8_t *tile_ptr) = 0;
|
||||
virtual void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color, bool fill) = 0;
|
||||
virtual void drawBitmap(uint16_t x1, uint16_t y1, const uint16_t* bitmap, int16_t w, int16_t h) = 0;
|
||||
virtual void welcome() = 0;
|
||||
virtual void drawIP(uint16_t x, uint16_t y, int16_t width=WIDTH_AUTO, uint16_t fg=0xffff, uint16_t bg=0 ) = 0;
|
||||
virtual void drawQS(uint16_t x, uint16_t y, uint8_t len, uint8_t size, uint8_t *stat, uint16_t fg=0xffff, uint16_t bg=0) = 0;
|
||||
};
|
||||
|
||||
class U8x8Display : public RawDisplay {
|
||||
private:
|
||||
U8X8 *u8x8 = NULL; // initialize later after reading config file
|
||||
uint8_t _type;
|
||||
const uint8_t **fontlist;
|
||||
int nfonts;
|
||||
|
||||
public:
|
||||
U8x8Display(uint8_t type = 0) { _type = type; }
|
||||
void begin();
|
||||
void clear();
|
||||
void setContrast(uint8_t contrast);
|
||||
void setFont(uint8_t fontindex);
|
||||
void getDispSize(uint8_t *height, uint8_t *width, uint8_t *lineskip, uint8_t *colskip);
|
||||
void drawString(uint16_t x, uint16_t y, const char *s, int16_t width=WIDTH_AUTO, uint16_t fg=0xffff, uint16_t bg=0);
|
||||
void drawTile(uint16_t x, uint16_t y, uint8_t cnt, uint8_t *tile_ptr);
|
||||
void drawTriangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t x3, uint16_t y3, uint16_t color, bool fill);
|
||||
void drawBitmap(uint16_t x1, uint16_t y1, const uint16_t* bitmap, int16_t w, int16_t h);
|
||||
void welcome();
|
||||
void drawIP(uint16_t x, uint16_t y, int16_t width=WIDTH_AUTO, uint16_t fg=0xffff, uint16_t bg=0);
|
||||
void drawQS(uint16_t x, uint16_t y, uint8_t len, uint8_t size, uint8_t *stat, uint16_t fg=0xffff, uint16_t bg=0);
|
||||
};
|
||||
|
||||
typedef Arduino_GFX MY_ILI9225;
|
||||
|
||||
class Display {
|
||||
private:
|
||||
void replaceLayouts(DispInfo *newlayout, int nnew);
|
||||
int allocDispInfo(int entries, DispInfo *d, char *label);
|
||||
void parseDispElement(char *text, DispEntry *de);
|
||||
int xscale=13, yscale=22;
|
||||
int fontsma=0, fontlar=1;
|
||||
uint16_t colfg, colbg;
|
||||
static void circ(uint16_t *bm, int16_t w, int16_t x0, int16_t y0, int16_t r, uint16_t fg, boolean fill, uint16_t bg);
|
||||
static int countEntries(File f);
|
||||
void calcGPS();
|
||||
int gpsDist; // -1: invalid
|
||||
int gpsDir, gpsBear; // 0..360; -1: invalid
|
||||
boolean gpsCourseOld;
|
||||
static const int LINEBUFLEN{ 255 };
|
||||
static char lineBuf[LINEBUFLEN];
|
||||
static const char *trim(char *s) {
|
||||
char *ret = s;
|
||||
while(*ret && isspace(*ret)) { ret++; }
|
||||
while(1) {
|
||||
int lastidx;
|
||||
lastidx = strlen(ret)-1;
|
||||
if(lastidx>=0 && isspace(ret[lastidx]))
|
||||
ret[lastidx] = 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public:
|
||||
static int getScreenIndex(int index);
|
||||
void initFromFile(int index);
|
||||
|
||||
int layoutIdx;
|
||||
DispInfo *layout;
|
||||
|
||||
DispInfo *layouts;
|
||||
int nLayouts;
|
||||
static RawDisplay *rdis;
|
||||
uint16_t dispstate;
|
||||
|
||||
Display();
|
||||
void init();
|
||||
static char buf[17];
|
||||
static void drawLat(DispEntry *de);
|
||||
static void drawLon(DispEntry *de);
|
||||
static void drawAlt(DispEntry *de);
|
||||
static void drawHS(DispEntry *de);
|
||||
static void drawVS(DispEntry *de);
|
||||
static void drawID(DispEntry *de);
|
||||
static void drawRSSI(DispEntry *de);
|
||||
static void drawQS(DispEntry *de);
|
||||
static void drawType(DispEntry *de);
|
||||
static void drawFreq(DispEntry *de);
|
||||
static void drawAFC(DispEntry *de);
|
||||
static void drawIP(DispEntry *de);
|
||||
static void drawSite(DispEntry *de);
|
||||
static void drawTelemetry(DispEntry *de);
|
||||
static void drawKilltimer(DispEntry *de);
|
||||
static void drawGPS(DispEntry *de);
|
||||
static void drawText(DispEntry *de);
|
||||
static void drawBatt(DispEntry *de);
|
||||
static void drawString(DispEntry *de, const char *str);
|
||||
void clearIP();
|
||||
void setIP(const char *ip, bool AP);
|
||||
void updateDisplayPos();
|
||||
void updateDisplayPos2();
|
||||
void updateDisplayID();
|
||||
void updateDisplayRSSI();
|
||||
void updateStat();
|
||||
void updateDisplayRXConfig();
|
||||
void updateDisplayIP();
|
||||
void updateDisplay();
|
||||
void dispsavectlON();
|
||||
void dispsavectlOFF(int rxactive);
|
||||
void setLayout(int layout);
|
||||
void setContrast();
|
||||
};
|
||||
|
||||
extern Display disp;
|
||||
|
||||
#endif
|
652
RX_FSK/src/M10M20.cpp
Normal file
652
RX_FSK/src/M10M20.cpp
Normal file
|
@ -0,0 +1,652 @@
|
|||
|
||||
/* M10 and M20 decoder functions */
|
||||
|
||||
#include "M10M20.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "rsc.h"
|
||||
#include "Sonde.h"
|
||||
#include <SPIFFS.h>
|
||||
|
||||
#define M10M20_DEBUG 1
|
||||
|
||||
#if M10M20_DEBUG
|
||||
#define M10M20_DBG(x) x
|
||||
#else
|
||||
#define M10M20_DBG(x)
|
||||
#endif
|
||||
|
||||
|
||||
static byte data1[512];
|
||||
static byte *dataptr=data1;
|
||||
|
||||
static uint8_t rxbitc;
|
||||
static uint16_t rxbyte;
|
||||
static int rxp=0;
|
||||
static int haveNewFrame = 0;
|
||||
//static int lastFrame = 0;
|
||||
static int headerDetected = 0;
|
||||
|
||||
|
||||
decoderSetupCfg m10m20SetupCfg = {
|
||||
.bitrate = 9600,
|
||||
//// Disable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
.rx_cfg = 0x00,
|
||||
.sync_cfg = 0x70,
|
||||
.sync_len = 1,
|
||||
.sync_data = (const uint8_t *)"\x66\x66",
|
||||
// Preamble detection off (+ size 1 byte, maximum tolerance; should not matter for "off"?)
|
||||
.preamble_cfg = 0x00 | 0x00 | 0x1F,
|
||||
};
|
||||
|
||||
int M10M20::setup(float frequency, int /*type*/)
|
||||
{
|
||||
M10M20_DBG(Serial.println("Setup sx1278 for M10/M20 sonde"));;
|
||||
if(sx1278.ON()!=0) {
|
||||
M10M20_DBG(Serial.println("Setting SX1278 power on FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// setFSK: switches to FSK standby mode
|
||||
if(sx1278.setFSK()!=0) {
|
||||
M10M20_DBG(Serial.println("Setting FSK mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
Serial.print("M10/M20: setting RX frequency to ");
|
||||
Serial.println(frequency);
|
||||
int res = sx1278.setFrequency(frequency);
|
||||
// Test: maybe fix issue after spectrum display?
|
||||
sx1278.writeRegister(REG_PLL_HOP, 0);
|
||||
|
||||
if(sx1278.setAFCBandwidth(sonde.config.m10m20.agcbw)!=0) {
|
||||
M10M20_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.m10m20.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.m10m20.rxbw)!=0) {
|
||||
M10M20_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.m10m20.rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// TODO: Maybe do this conditionally? -- maybe skip if afc if agcbw set to 0 or -1?
|
||||
//// Step 1: Tentative AFC mode
|
||||
sx1278.clearIRQFlags();
|
||||
// preamble detector + AFC + AGC on
|
||||
// wait for preamble interrupt within 2sec
|
||||
sx1278.setBitrate(4800);
|
||||
// DetectorOn=1, Preamble detector size 01, preamble tol 0x0A (10)
|
||||
sx1278.setPreambleDetect(0x80 | 0x20 | 0x0A);
|
||||
// Manual start RX, Enable Auto-AFC, Auto-AGC, RX Trigger (AGC+AFC)by preamble
|
||||
sx1278.setRxConf(0x20 | 0x10 | 0x08 | 0x06);
|
||||
// Packet config 1: fixed len, no mancecer, no crc, no address filter
|
||||
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// enable RX
|
||||
sx1278.setPayloadLength(0);
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
unsigned long t0 = millis();
|
||||
M10M20_DBG(Serial.printf("M10M20::setup() AFC preamble search start at %ld\n",t0));
|
||||
while( millis() - t0 < 1000 ) {
|
||||
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS1);
|
||||
if(value & 2) {
|
||||
int32_t afc = sx1278.getAFC();
|
||||
int16_t rssi = sx1278.getRSSI();
|
||||
Serial.printf("M10M20::setup: preamble: AFC is %d, RSSI is %.1f\n", afc, rssi/2.0);
|
||||
sonde.sondeList[rxtask.currentSonde].rssi = rssi;
|
||||
sonde.sondeList[rxtask.currentSonde].afc = afc;
|
||||
break;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
if( millis() - t0 >= 1000) {
|
||||
Serial.println("Preamble scan for AFC: TIMEOUT\n");
|
||||
return 1; // no preamble, so we may fail fast....
|
||||
}
|
||||
|
||||
//// Step 2: Real reception
|
||||
if( DecoderBase::setup(m10m20SetupCfg, sonde.config.m10m20.agcbw, sonde.config.m10m20.rxbw)!=0 ) {
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
// Now all done in DecoderBase::setup
|
||||
// FSK standby mode, seems like otherweise baudrate cannot be changed?
|
||||
sx1278.setFSK();
|
||||
if(sx1278.setBitrate(9600)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting bitrate 9600bit/s FAILED"));
|
||||
return 1;
|
||||
}
|
||||
M10M20_DBG(Serial.printf("Exact bitrate is %f\n", sx1278.getBitrate()));
|
||||
// Probably not necessary, as this was set before
|
||||
if(sx1278.setAFCBandwidth(sonde.config.m10m20.agcbw)!=0) {
|
||||
M10M20_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.m10m20.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.m10m20.rxbw)!=0) {
|
||||
M10M20_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.m10m20.rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
///// Enable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
//if(sx1278.setRxConf(0x1E)!=0) {
|
||||
// Disable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
if(sx1278.setRxConf(0x00)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// version 1, working with continuous RX
|
||||
const char *SYNC="\x66\x66";
|
||||
if(sx1278.setSyncConf(0x70, 1, (const uint8_t *)SYNC)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// Preamble detection off (+ size 1 byte, maximum tolerance; should not matter for "off"?)
|
||||
if(sx1278.setPreambleDetect(0x00 | 0x00 | 0x1F)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Packet config 1: fixed len, no mancecer, no crc, no address filter
|
||||
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
M10M20_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// enable RX
|
||||
sx1278.setPayloadLength(0); // infinite for now...
|
||||
sx1278.setRxConf(0x20);
|
||||
uint16_t afc = sx1278.getRawAFC();
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
delay(50);
|
||||
sx1278.setRawAFC(afc);
|
||||
delay(50);
|
||||
Serial.printf("after RX_MODE: AFC is %d\n", sx1278.getAFC());
|
||||
|
||||
#if M10M20_DEBUG
|
||||
M10M20_DBG(Serial.println("Setting SX1278 config for M10 finished\n"); Serial.println());
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
M10M20::M10M20() {
|
||||
}
|
||||
|
||||
#define M10_FRAMELEN 101
|
||||
#define M10_CRCPOS 99
|
||||
|
||||
#define M20_FRAMELEN 88
|
||||
#define M20_CRCPOSB 22
|
||||
|
||||
void M10M20::printRaw(uint8_t *data, int len)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
for(i=0; i<len; i++) {
|
||||
snprintf(buf, 3, "%02X ", data[i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
static uint16_t update_checkM10M20(int c, uint8_t b) {
|
||||
int c0, c1, t, t6, t7, s;
|
||||
c1 = c & 0xFF;
|
||||
// B
|
||||
b = (b >> 1) | ((b & 1) << 7);
|
||||
b ^= (b >> 2) & 0xFF;
|
||||
// A1
|
||||
t6 = ( c & 1) ^ ((c >> 2) & 1) ^ ((c >> 4) & 1);
|
||||
t7 = ((c >> 1) & 1) ^ ((c >> 3) & 1) ^ ((c >> 5) & 1);
|
||||
t = (c & 0x3F) | (t6 << 6) | (t7 << 7);
|
||||
// A2
|
||||
s = (c >> 7) & 0xFF;
|
||||
s ^= (s >> 2) & 0xFF;
|
||||
c0 = b ^ t ^ s;
|
||||
return ((c1 << 8) | c0) & 0xFFFF;
|
||||
}
|
||||
static uint16_t crc_M10M20(int len, uint8_t *msg) {
|
||||
uint16_t cs = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
cs = update_checkM10M20(cs, msg[i]);
|
||||
}
|
||||
return cs;
|
||||
}
|
||||
static bool checkM10M20crc(int crcpos, uint8_t *msg) {
|
||||
uint16_t cs, cs1;
|
||||
cs = crc_M10M20(crcpos, msg);
|
||||
cs1 = (msg[crcpos] << 8) | msg[crcpos+1];
|
||||
return (cs1 == cs);
|
||||
}
|
||||
|
||||
typedef uint32_t SET256[8];
|
||||
static SET256 sondeudp_VARSET = {0x03BBBBF0UL,0x80600000UL,0x06A001A0UL,
|
||||
0x0000001CUL,0x00000000UL,0x00000000UL,0x00000000UL,
|
||||
0x00000000UL};
|
||||
// VARSET=SET256{4..9,11..13,15..17,19..21,23..25,53..54,63,69,71,72,85,87,89,90,98..100};
|
||||
static SET256 sondeudp_VARSETM20 = {0xF3E27F54UL,0x0000000FUL,0x00000030UL,
|
||||
0x00000000UL, 0x00444C39UL, 0x53445A00UL, 0x00000000UL,
|
||||
0x00000000UL};
|
||||
// VARSET=SET256{2,4,6,8..10,11..14,17,21..25,28..35,68,69}; (* known as variable *)
|
||||
|
||||
static uint8_t fixcnt[M10_FRAMELEN];
|
||||
static uint8_t fixbytes[M10_FRAMELEN];
|
||||
|
||||
static int32_t getint32(uint8_t *data) {
|
||||
return (int32_t)( data[3]|(data[2]<<8)|(data[1]<<16)|(data[0]<<24) );
|
||||
}
|
||||
|
||||
static int32_t getint24(uint8_t *data) {
|
||||
return (int32_t)(data[2]|(data[1]<<8)|(data[0]<<16) );
|
||||
}
|
||||
|
||||
static int32_t getint24_r(uint8_t *data) {
|
||||
return (int32_t)(data[0]|(data[1]<<8)|(data[2]<<16) );
|
||||
}
|
||||
|
||||
static int16_t getint16(uint8_t *data) {
|
||||
return (int16_t)(data[1]|((uint16_t)data[0]<<8));
|
||||
}
|
||||
|
||||
static int16_t getint16_r(uint8_t *data) {
|
||||
return (int16_t)(((uint16_t)data[1]<<8) |data[0]);
|
||||
}
|
||||
|
||||
static char dez(uint8_t nr) {
|
||||
nr = nr%10;
|
||||
return '0'+nr;
|
||||
}
|
||||
static char hex(uint8_t nr) {
|
||||
nr = nr&0x0f;
|
||||
if(nr<10) return '0'+nr;
|
||||
else return 'A'+nr-10;
|
||||
}
|
||||
const static float DEGMUL = 1.0/0xB60B60;
|
||||
|
||||
#define VMUL 0.005
|
||||
#define VMUL_M20 0.01
|
||||
#ifndef PI
|
||||
#define PI (3.1415926535897932384626433832795)
|
||||
#endif
|
||||
#define RAD (PI/180)
|
||||
|
||||
|
||||
// ret: 1=frame ok; 2=frame with errors; 0=ignored frame (m10dop-alternativ)
|
||||
int M10M20::decodeframeM10(uint8_t *data) {
|
||||
int repairstep = 16;
|
||||
int repl = 0;
|
||||
bool crcok;
|
||||
// error correction, inspired by oe5dxl's sondeudp
|
||||
do {
|
||||
crcok = checkM10M20crc(M10_CRCPOS, data);
|
||||
if(crcok || repairstep==0) break;
|
||||
repl = 0;
|
||||
for(int i=0; i<M10_CRCPOS; i++) {
|
||||
if( ((sondeudp_VARSET[i/32]&(1<<(i%32))) == 0) && (fixcnt[i]>=repairstep) ) {
|
||||
repl++;
|
||||
data[i] = fixbytes[i];
|
||||
}
|
||||
}
|
||||
repairstep >>= 1;
|
||||
} while(true);
|
||||
if(crcok) {
|
||||
for(int i=0; i<M10_CRCPOS; i++) {
|
||||
if(fixbytes[i]==data[i] &&fixcnt[i]<255) fixcnt[i]++;
|
||||
else { fixcnt[i]=0; fixbytes[i]=data[i]; }
|
||||
}
|
||||
}
|
||||
Serial.println(crcok?"CRC OK":"CRC NOT OK");
|
||||
Serial.printf(" repair: %d/%d\n", repl, repairstep);
|
||||
if(!crcok) return 2;
|
||||
|
||||
if(data[1]==0x9F && data[2]==0x20) {
|
||||
Serial.println("Decoding...");
|
||||
//SondeInfo *si = sonde.si();
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
|
||||
// Its a M10
|
||||
// getid...
|
||||
char ids[12];
|
||||
ids[0] = 'M';
|
||||
ids[1] = 'E';
|
||||
ids[2] = hex(data[95]/16);
|
||||
ids[3] = hex(data[95]);
|
||||
ids[4] = hex(data[93]);
|
||||
uint32_t id = data[96] + data[97]*256;
|
||||
ids[5] = hex(id/4096);
|
||||
ids[6] = hex(id/256);
|
||||
ids[7] = hex(id/16);
|
||||
ids[8] = hex(id);
|
||||
ids[9] = 0;
|
||||
strncpy(si->id, ids, 10);
|
||||
ids[0] = hex(data[95]/16);
|
||||
ids[1] = dez((data[95]&0x0f)/10);
|
||||
ids[2] = dez((data[95]&0x0f));
|
||||
ids[3] = '-';
|
||||
ids[4] = dez(data[93]);
|
||||
ids[5] = '-';
|
||||
ids[6] = dez(id>>13);
|
||||
id &= 0x1fff;
|
||||
ids[7] = dez(id/1000);
|
||||
ids[8] = dez((id/100)%10);
|
||||
ids[9] = dez((id/10)%10);
|
||||
ids[10] = dez(id%10);
|
||||
ids[11] = 0;
|
||||
strncpy(si->ser, ids, 12);
|
||||
si->validID = true;
|
||||
Serial.printf("ID is %s [%02x %02x %d]\n", ids, data[95], data[93], id);
|
||||
// ID printed on sonde is ...-.-abbbb, with a=id>>13, bbbb=id&0x1fff in decimal
|
||||
// position data
|
||||
si->lat = getint32(data+14) * DEGMUL;
|
||||
si->lon = getint32(data+18) * DEGMUL;
|
||||
si->alt = getint32(data+22) * 0.001;
|
||||
float ve = getint16(data+4)*VMUL;
|
||||
float vn = getint16(data+6)*VMUL;
|
||||
si->vs = getint16(data+8) * VMUL;
|
||||
si->hs = sqrt(ve*ve+vn*vn);
|
||||
si->sats = data[30];
|
||||
float dir = atan2(ve, vn)*(1.0/RAD);
|
||||
if(dir<0) dir+=360;
|
||||
si->dir = dir;
|
||||
si->validPos = 0x3f;
|
||||
// m10 temp
|
||||
float T = NAN;
|
||||
{
|
||||
const float p0 = 1.07303516e-03, p1 = 2.41296733e-04, p2 = 2.26744154e-06, p3 = 6.52855181e-08;
|
||||
const float Rs[3] = { 12.1e3 , 36.5e3 , 475.0e3 };
|
||||
const float Rp[3] = { 1e20 , 330.0e3 , 2000.0e3 };
|
||||
uint8_t sct = data[62];
|
||||
float rt = getint16_r(data+63) & (0xFFF);
|
||||
if(rt!=0 && sct<3) {
|
||||
rt = (4095-rt)/rt - (Rs[sct]/Rp[sct]);
|
||||
if(rt>0) {
|
||||
rt = Rs[sct] / rt;
|
||||
if(rt>0) {
|
||||
rt = log(rt);
|
||||
rt = 1/( p0 + p1*rt + p2*rt*rt + p3*rt*rt*rt ) - 273.15;
|
||||
if(rt>-99 && rt<50) { T = rt; }
|
||||
}
|
||||
}
|
||||
}
|
||||
si->temperature = T;
|
||||
}
|
||||
|
||||
// m10 battery
|
||||
uint16_t batADC = (uint16_t)getint16_r(data+0x45);
|
||||
si->batteryVoltage = 2.709 * batADC * 2.5/1023.0;
|
||||
|
||||
// m10 humidity
|
||||
{
|
||||
float cRHc55 = ((float)(uint32_t)getint24_r(data+0x35)) / (uint32_t)getint24_r(data+0x32);
|
||||
float TH = -273.15;
|
||||
const float huRs = 22.1e3;
|
||||
const float p0 = 4.42606809e-03, p1 = -6.58184309e-04, p2 = 8.95735557e-05, p3 = -2.84347503e-06;
|
||||
float R = huRs / ( (4095.0/getint16_r(data+0x59)) - 1 );
|
||||
if(R>0) TH += 1/( p0 + p1*log(R) + p2*log(R)*log(R) + p3*log(R)*log(R)*log(R) );
|
||||
//float Tc = T;
|
||||
float rh = (cRHc55-0.8955)/0.002;
|
||||
const float T0=0.0, T1=-30.0;
|
||||
//float T = Tc;
|
||||
if(T<T0) rh += T0 - T/5.5;
|
||||
if(T<T1) rh *= 1.0 + (T1-T)/75.0;
|
||||
if(rh<0.0) rh=0.0;
|
||||
if(rh>100.0) rh=100.0;
|
||||
si->relativeHumidity = rh;
|
||||
}
|
||||
Serial.printf("hum: %.2f batt: %.2f\n", si->relativeHumidity, si->batteryVoltage);
|
||||
|
||||
uint32_t gpstime = getint32(data+10);
|
||||
uint16_t gpsweek = getint16(data+32);
|
||||
// UTC is GPSTIME - 18s (24*60*60-18 = 86382)
|
||||
// one week = 7*24*60*60 = 604800 seconds
|
||||
// unix epoch starts jan 1st 1970 0:00
|
||||
// gps time starts jan 6, 1980 0:00. thats 315964800 epoch seconds.
|
||||
// subtracting 86400 yields 315878400UL
|
||||
si->time = (gpstime/1000) + 86382 + gpsweek*604800 + 315878400UL;
|
||||
// consistent with autorx, vframe is based on GPS time without the -18 seconds adjustment
|
||||
// for the GPS time / UTC time difference (included in 86382 above)
|
||||
si->vframe = si->time - 315964800 + 18;
|
||||
si->validTime = true;
|
||||
} else {
|
||||
Serial.printf("data is %02x %02x %02x\n", data[0], data[1], data[2]);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static uint32_t rxdata;
|
||||
static bool rxsearching=true;
|
||||
static bool isM20=false;
|
||||
|
||||
// search for
|
||||
// //101001100110011010011010011001100110100110101010100110101001
|
||||
// //1010011001100110100110100110 0110.0110 1001.1010 1010.1001 1010.1001 => 0x669AA9A9
|
||||
void M10M20::processM10data(uint8_t dt)
|
||||
{
|
||||
for(int i=0; i<8; i++) {
|
||||
uint8_t d = (dt&0x80)?1:0;
|
||||
dt <<= 1;
|
||||
rxdata = (rxdata<<1) | d;
|
||||
if( (rxbitc&1)==0 ) {
|
||||
// "bit1"
|
||||
rxbyte = (rxbyte<<1) | d;
|
||||
} else {
|
||||
// "bit2" ==> 01 or 10 => 1, otherweise => 0
|
||||
rxbyte = rxbyte ^ d;
|
||||
}
|
||||
//
|
||||
if(rxsearching) {
|
||||
if( rxdata == 0xcccca64c || rxdata == 0x333359b3 ) {
|
||||
rxsearching = false;
|
||||
rxbitc = 0;
|
||||
rxp = 0;
|
||||
isM20 = false;
|
||||
headerDetected = 1;
|
||||
#if 1
|
||||
int rssi=sx1278.getRSSI();
|
||||
int fei=sx1278.getFEI();
|
||||
int afc=sx1278.getAFC();
|
||||
Serial.print("SYNC!!! Test: RSSI="); Serial.print(rssi);
|
||||
Serial.print(" FEI="); Serial.print(fei);
|
||||
Serial.print(" AFC="); Serial.println(afc);
|
||||
sonde.si()->rssi = rssi;
|
||||
sonde.si()->afc = afc;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
rxbitc = (rxbitc+1)%16; // 16;
|
||||
if(rxbitc == 0) { // got 8 data bit
|
||||
//Serial.printf("%03x ",rxbyte);
|
||||
dataptr[rxp++] = rxbyte&0xff; // (rxbyte>>1)&0xff;
|
||||
// detect type of sonde:
|
||||
// 64 9F 20 => M10
|
||||
// 64 49 0x => M10 (?) -- not used here
|
||||
// 45 20 7x => M20
|
||||
if(rxp==2 && dataptr[0]==0x45 && dataptr[1]==0x20) { isM20 = true; }
|
||||
if(isM20) {
|
||||
memcpy(sonde.si()->d.typestr, "M20 ", 5);
|
||||
sonde.si()->d.subtype = 2;
|
||||
if(rxp>=M20_FRAMELEN) {
|
||||
rxsearching = true;
|
||||
haveNewFrame = decodeframeM20(dataptr);
|
||||
}
|
||||
} else {
|
||||
memcpy(sonde.si()->d.typestr, "M10 ", 5);
|
||||
sonde.si()->d.subtype = 1;
|
||||
if(rxp>=M10_FRAMELEN) {
|
||||
rxsearching = true;
|
||||
haveNewFrame = decodeframeM10(dataptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int M10M20::receive() {
|
||||
unsigned long t0 = millis();
|
||||
Serial.printf("M10M20::receive() start at %ld\n",t0);
|
||||
while( millis() - t0 < 1100 ) {
|
||||
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
if ( bitRead(value, 7) ) {
|
||||
Serial.println("FIFO full");
|
||||
}
|
||||
if ( bitRead(value, 4) ) {
|
||||
Serial.println("FIFO overflow");
|
||||
}
|
||||
if ( bitRead(value, 2) == 1 ) {
|
||||
Serial.println("FIFO: ready()");
|
||||
sx1278.clearIRQFlags();
|
||||
}
|
||||
if(bitRead(value, 6) == 0) { // while FIFO not empty
|
||||
byte data = sx1278.readRegister(REG_FIFO);
|
||||
//Serial.printf("%02x:",data);
|
||||
processM10data(data);
|
||||
value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
} else {
|
||||
if(headerDetected) {
|
||||
t0 = millis(); // restart timer... don't time out if header detected...
|
||||
headerDetected = 0;
|
||||
}
|
||||
if(haveNewFrame) {
|
||||
Serial.printf("M10M20::receive(): new frame complete after %ldms\n", millis()-t0);
|
||||
printRaw(dataptr, M10_FRAMELEN);
|
||||
int retval = haveNewFrame==1 ? RX_OK: RX_ERROR;
|
||||
haveNewFrame = 0;
|
||||
return retval;
|
||||
}
|
||||
delay(2);
|
||||
}
|
||||
}
|
||||
int32_t afc = sx1278.getAFC();
|
||||
int16_t rssi = sx1278.getRSSI();
|
||||
Serial.printf("receive: AFC is %d, RSSI is %.1f\n", afc, rssi/2.0);
|
||||
Serial.printf("M10M20::receive() timed out\n");
|
||||
return RX_TIMEOUT; // TODO RX_OK;
|
||||
}
|
||||
|
||||
#define M10MAXLEN (240)
|
||||
|
||||
int M10M20::waitRXcomplete() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ret: 1=frame ok; 2=frame with errors; 0=ignored frame (m20dop-alternativ)
|
||||
int M10M20::decodeframeM20(uint8_t *data) {
|
||||
int repairstep = 16;
|
||||
int frl;
|
||||
int repl = 0;
|
||||
bool crcok = false;
|
||||
bool crcbok = false;
|
||||
//SondeInfo *si = sonde.si();
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
// error correction, inspired by oe5dxl's sondeudp
|
||||
// check first block
|
||||
uint8_t s[200];
|
||||
s[0] = 0x16;
|
||||
for(int i=1; i<=M20_CRCPOSB-1; i++) { s[i] = data[i+1]; }
|
||||
crcbok = (crc_M10M20(M20_CRCPOSB-1, s) ==
|
||||
((data[M20_CRCPOSB] << 8) | data[M20_CRCPOSB+1]));
|
||||
|
||||
frl = data[0] + 1; // frame len? (0x45+1 => 70)
|
||||
if(frl>M20_FRAMELEN) { frl = M20_FRAMELEN; }
|
||||
do {
|
||||
crcok = checkM10M20crc(frl-2, data);
|
||||
if(crcok || repairstep == 0) break;
|
||||
repl = 0;
|
||||
for(int i=crcbok?M20_CRCPOSB+2:0; i<frl-2; i++) {
|
||||
if( ((sondeudp_VARSETM20[i/32]&(1<<(i%32))) == 0) && (fixcnt[i]>=repairstep) ) {
|
||||
repl++;
|
||||
data[i] = fixbytes[i];
|
||||
}
|
||||
}
|
||||
repairstep >>= 1;
|
||||
} while(true);
|
||||
if(crcbok) {
|
||||
int oklen = crcok ? frl-2 : 21;
|
||||
for(int i=0; i<oklen; i++) {
|
||||
if(fixbytes[i]==data[i]) { if(fixcnt[i]<255) fixcnt[i]++; }
|
||||
else { fixcnt[i]=0; fixbytes[i]=data[i]; }
|
||||
}
|
||||
}
|
||||
Serial.println(crcok?"CRC OK":"CRC NOT OK");
|
||||
Serial.printf(" repair: %d/%d\n", repl, repairstep);
|
||||
if(!crcok) return 2;
|
||||
|
||||
Serial.println("Decoding...");
|
||||
// Its a M20
|
||||
// getid...
|
||||
// TODO: Adjust ID calculation and serial number reconstruction
|
||||
char ids[11]={'M','E','0','0','0','0','0','0','0','0','0'};
|
||||
|
||||
ids[0] = 'M';
|
||||
ids[1] = 'E';
|
||||
uint32_t id = data[18]; // getint16(data+18);
|
||||
ids[2] = hex(id/16);
|
||||
ids[3] = hex(id);
|
||||
//
|
||||
id = getint16_r(data+19)/4;
|
||||
ids[4] = (char)((id/10000)%10+48);
|
||||
ids[5] = (char)((id/1000)%10+48);
|
||||
ids[6] = (char)((id/100)%10+48);
|
||||
ids[7] = (char)((id/10)%10+48);
|
||||
ids[8] = (char)(id%10+48);
|
||||
ids[9] = 0;
|
||||
strncpy(si->id, ids, 10);
|
||||
// Serial: AAB-C-DDEEE
|
||||
char *ser = si->ser;
|
||||
uint8_t tmp = data[18] & 0x7F;
|
||||
ser[0] = (tmp/12) + '0';
|
||||
ser[1] = ((tmp%12 + 1) / 10 ) + '0';
|
||||
ser[2] = ((tmp%12 + 1) % 10 ) + '0';
|
||||
ser[3] = '-';
|
||||
ser[4] = ((data[19]&0x03)<<1) + (data[18]/128) + 1 + '0';
|
||||
ser[5] = '-';
|
||||
ser[6] = ids[4];
|
||||
ser[7] = ids[5];
|
||||
ser[8] = ids[6];
|
||||
ser[9] = ids[7];
|
||||
ser[10] = ids[8];
|
||||
ser[11] = 0;
|
||||
|
||||
// TODO
|
||||
if(crcok) {
|
||||
si->validID = true;
|
||||
//Serial.printf("ID is %s [%02x %02x %d]\n", ids, data[95], data[93], id);
|
||||
// ID printed on sonde is ...-.-abbbb, with a=id>>13, bbbb=id&0x1fff in decimal
|
||||
// position data
|
||||
// 0x1C 4 byte
|
||||
si->lat = getint32(data+28) * 1e-6;
|
||||
//0x20 4 byte
|
||||
si->lon = getint32(data+32) * 1e-6;
|
||||
//0x08 3 byte
|
||||
si->alt = getint24(data+8) * VMUL_M20;
|
||||
//0x0B 2 byte
|
||||
//VMUL_M20 specific
|
||||
float ve = getint16(data+11)*VMUL_M20;
|
||||
//0x0D 2 byte
|
||||
float vn = getint16(data+13)*VMUL_M20;
|
||||
//0x18 2 byte
|
||||
si->vs = getint16(data+24) * VMUL_M20;
|
||||
si->hs = sqrt(ve*ve+vn*vn);
|
||||
float dir = atan2(ve, vn)*(1.0/RAD);
|
||||
if(dir<0) dir+=360;
|
||||
si->dir = dir;
|
||||
si->validPos = 0x3f;
|
||||
|
||||
//0x0F 3 byte
|
||||
uint32_t tow = getint24(data+15);
|
||||
uint16_t week = getint16(data+26);
|
||||
si->time = (tow+week*604800+315964800)-18;
|
||||
si->vframe =si->time - 315964800;
|
||||
|
||||
si->validTime = true;
|
||||
}
|
||||
return crcok?1:2;
|
||||
}
|
||||
|
||||
|
||||
M10M20 m10m20 = M10M20();
|
66
RX_FSK/src/M10M20.h
Normal file
66
RX_FSK/src/M10M20.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* M10M20.h
|
||||
* Functions for decoding Meteomodem M10M20 sondes with SX127x chips
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef M10M20_h
|
||||
#define M10M20_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "DecoderBase.h"
|
||||
|
||||
/* Main class */
|
||||
class M10M20 : public DecoderBase
|
||||
{
|
||||
private:
|
||||
void printRaw(uint8_t *data, int len);
|
||||
void processM10data(uint8_t data);
|
||||
int decodeframeM10(uint8_t *data);
|
||||
int decodeframeM20(uint8_t *data);
|
||||
#if 0
|
||||
void stobyte92(uint8_t byte);
|
||||
void dogps(const uint8_t *sf, int sf_len,
|
||||
struct CONTEXTR9 * cont, uint32_t * timems,
|
||||
uint32_t * gpstime);
|
||||
uint32_t bits2val(const uint8_t *bits, int len);
|
||||
int bitsToBytes(uint8_t *bits, uint8_t *bytes, int len);
|
||||
int decode92(byte *data, int maxlen);
|
||||
|
||||
uint8_t hamming_conf[ 7*8]; // 7*8=56
|
||||
uint8_t hamming_dat1[13*8]; // 13*8=104
|
||||
uint8_t hamming_dat2[13*8];
|
||||
|
||||
uint8_t block_conf[ 7*4]; // 7*4=28
|
||||
uint8_t block_dat1[13*4]; // 13*4=52
|
||||
uint8_t block_dat2[13*4];
|
||||
|
||||
uint8_t H[4][8] = // extended Hamming(8,4) particy check matrix
|
||||
{{ 0, 1, 1, 1, 1, 0, 0, 0},
|
||||
{ 1, 0, 1, 1, 0, 1, 0, 0},
|
||||
{ 1, 1, 0, 1, 0, 0, 1, 0},
|
||||
{ 1, 1, 1, 0, 0, 0, 0, 1}};
|
||||
uint8_t He[8] = { 0x7, 0xB, 0xD, 0xE, 0x8, 0x4, 0x2, 0x1}; // Spalten von H:
|
||||
// 1-bit-error-Syndrome
|
||||
boolean initialized = false;
|
||||
#endif
|
||||
|
||||
public:
|
||||
M10M20();
|
||||
int setup(float frequency, int type = 0);
|
||||
int receive();
|
||||
int waitRXcomplete();
|
||||
|
||||
//int use_ecc = 1;
|
||||
};
|
||||
|
||||
extern M10M20 m10m20;
|
||||
|
||||
#endif
|
559
RX_FSK/src/MP3H.cpp
Normal file
559
RX_FSK/src/MP3H.cpp
Normal file
|
@ -0,0 +1,559 @@
|
|||
|
||||
/* MP3H decoder functions */
|
||||
|
||||
#include "MP3H.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "rsc.h"
|
||||
#include "Sonde.h"
|
||||
#include <SPIFFS.h>
|
||||
|
||||
#define MP3H_DEBUG 1
|
||||
|
||||
#if MP3H_DEBUG
|
||||
#define MP3H_DBG(x) x
|
||||
#else
|
||||
#define MP3H_DBG(x)
|
||||
#endif
|
||||
|
||||
static struct st_mp3hstate {
|
||||
uint32_t id1, id2;
|
||||
uint8_t idok;
|
||||
uint32_t gpsdate;
|
||||
uint32_t gpsdatetime;
|
||||
bool dateok;
|
||||
} mp3hstate;
|
||||
|
||||
static byte data1[512];
|
||||
static byte *dataptr=data1;
|
||||
|
||||
static uint8_t rxbitc;
|
||||
static uint16_t rxbyte;
|
||||
static int rxp=0;
|
||||
static int haveNewFrame = 0;
|
||||
//static int lastFrame = 0;
|
||||
static int headerDetected = 0;
|
||||
|
||||
extern uint16_t MON[];
|
||||
|
||||
decoderSetupCfg mp3hSetupCfg = {
|
||||
.bitrate = 2400,
|
||||
.rx_cfg = 0x00,
|
||||
.sync_cfg = 0x70,
|
||||
.sync_len = 1,
|
||||
.sync_data = (const uint8_t *)"\x66\x66",
|
||||
.preamble_cfg = 0x00 | 0x00 | 0x1F
|
||||
};
|
||||
|
||||
int MP3H::setup(float frequency, int /*type*/)
|
||||
{
|
||||
MP3H_DBG(Serial.println("Setup sx1278 for MP3H sonde"));;
|
||||
if(sx1278.ON()!=0) {
|
||||
MP3H_DBG(Serial.println("Setting SX1278 power on FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// setFSK: switches to FSK standby mode
|
||||
if(sx1278.setFSK()!=0) {
|
||||
MP3H_DBG(Serial.println("Setting FSK mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
Serial.print("MP3H: setting RX frequency to ");
|
||||
Serial.println(frequency);
|
||||
int res = sx1278.setFrequency(frequency);
|
||||
// Test: maybe fix issue after spectrum display?
|
||||
sx1278.writeRegister(REG_PLL_HOP, 0);
|
||||
|
||||
if(sx1278.setAFCBandwidth(sonde.config.mp3h.agcbw)!=0) {
|
||||
MP3H_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.mp3h.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.mp3h.rxbw)!=0) {
|
||||
MP3H_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.mp3h.rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
//// Step 2: Real reception
|
||||
if(DecoderBase::setup(mp3hSetupCfg, sonde.config.mp3h.agcbw, sonde.config.mp3h.rxbw)!=0) {
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
// Now all done in Decoderbase
|
||||
// FSK standby mode, seems like otherweise baudrate cannot be changed?
|
||||
sx1278.setFSK();
|
||||
if(sx1278.setBitrate(2400)!=0) {
|
||||
MP3H_DBG(Serial.println("Setting bitrate 2400bit/s FAILED"));
|
||||
return 1;
|
||||
}
|
||||
MP3H_DBG(Serial.printf("Exact bitrate is %f\n", sx1278.getBitrate()));
|
||||
// Probably not necessary, as this was set before
|
||||
if(sx1278.setAFCBandwidth(sonde.config.mp3h.agcbw)!=0) {
|
||||
MP3H_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.mp3h.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.mp3h.rxbw)!=0) {
|
||||
MP3H_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.mp3h.rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
///// Enable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
//if(sx1278.setRxConf(0x1E)!=0) {
|
||||
// Disable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
if(sx1278.setRxConf(0x00)!=0) {
|
||||
MP3H_DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// version 1, working with continuous RX
|
||||
const char *SYNC="\x66\x66";
|
||||
if(sx1278.setSyncConf(0x70, 1, (const uint8_t *)SYNC)!=0) {
|
||||
MP3H_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// Preamble detection off (+ size 1 byte, maximum tolerance; should not matter for "off"?)
|
||||
if(sx1278.setPreambleDetect(0x00 | 0x00 | 0x1F)!=0) {
|
||||
MP3H_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Packet config 1: fixed len, no mancecer, no crc, no address filter
|
||||
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
MP3H_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// enable RX
|
||||
sx1278.setPayloadLength(0); // infinite for now...
|
||||
//sx1278.setRxConf(0x20);
|
||||
uint16_t afc = sx1278.getRawAFC();
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
delay(50);
|
||||
sx1278.setRawAFC(afc);
|
||||
delay(50);
|
||||
Serial.printf("after RX_MODE: AFC is %d\n", sx1278.getAFC());
|
||||
|
||||
memset((void *)&mp3hstate, 0, sizeof(mp3hstate));
|
||||
#if MP3H_DEBUG
|
||||
MP3H_DBG(Serial.println("Setting SX1278 config for MP3H finished\n"); Serial.println());
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
MP3H::MP3H() {
|
||||
}
|
||||
|
||||
#define MP3H_FRAMELEN 49
|
||||
|
||||
// offsets from zilog
|
||||
// https://github.com/rs1729/RS/blob/master/demod/mod/mp3h1mod.c
|
||||
#define OFS -3
|
||||
#define pos_CNT1 (OFS+ 3) // 1 nibble (0x80..0x8F ?)
|
||||
#define pos_TIME (OFS+ 4) // 3*1 byte
|
||||
#define pos_GPSecefX (OFS+ 8) // 4 byte
|
||||
#define pos_GPSecefY (OFS+12) // 4 byte
|
||||
#define pos_GPSecefZ (OFS+16) // 4 byte
|
||||
#define pos_GPSecefV (OFS+20) // 3*2 byte
|
||||
#define pos_GPSnSats (OFS+26) // 1 byte (num Sats ?)
|
||||
#define pos_PTU1 (OFS+35) // 4 byte
|
||||
#define pos_PTU2 (OFS+39) // 4 byte
|
||||
#define pos_CNT2 (OFS+43) // 1 byte (0x01..0x10 ?)
|
||||
#define pos_CFG (OFS+44) // 2/4 byte
|
||||
#define pos_CRC (OFS+48) // 2 byte
|
||||
|
||||
|
||||
#define crc16poly 0xA001
|
||||
static bool checkMP3CRC(uint8_t *data)
|
||||
{
|
||||
int start = pos_CNT1;
|
||||
int len = 45;
|
||||
uint16_t rem = 0xffff;
|
||||
for(int i=0; i<len; i++) {
|
||||
rem ^= data[start+i];
|
||||
for(int j=0; j<8; j++) {
|
||||
if(rem&0x1) rem = (rem>>1) ^ crc16poly;
|
||||
else rem = rem>>1;
|
||||
}
|
||||
}
|
||||
uint16_t crcdat = data[pos_CRC] | (data[pos_CRC+1]<<8);
|
||||
return rem == crcdat ? true : false;
|
||||
}
|
||||
|
||||
void MP3H::printRaw(uint8_t *data, int len)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
for(i=0; i<len; i++) {
|
||||
snprintf(buf, 3, "%02X ", data[i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
#ifndef PI
|
||||
#define PI (3.1415926535897932384626433832795)
|
||||
#endif
|
||||
#define RAD (PI/180)
|
||||
#define DEG (180/PI)
|
||||
|
||||
static uint32_t u4(uint8_t *d)
|
||||
{
|
||||
return d[0] | (d[1]<<8) | (d[2]<<16) | (d[3]<<24);
|
||||
}
|
||||
#define i4(d) ((int32_t)u4(d))
|
||||
|
||||
static uint16_t u2(uint8_t *d)
|
||||
{
|
||||
return d[0] | (d[1]<<8);
|
||||
}
|
||||
#define i2(d) ((int16_t)u2(d))
|
||||
|
||||
|
||||
// defined in RS41.cpp
|
||||
extern void wgs84r(double x, double y, double z, double * lat, double * long0, double * heig);
|
||||
extern double atang2(double x, double y);
|
||||
|
||||
|
||||
void calcgps(uint8_t *buf) {
|
||||
//SondeInfo *si = sonde.si();
|
||||
SondeData *si =&(sonde.si()->d);
|
||||
double wx = i4(buf+pos_GPSecefX) * 0.01;
|
||||
double wy = i4(buf+pos_GPSecefY) * 0.01;
|
||||
double wz = i4(buf+pos_GPSecefZ) * 0.01;
|
||||
double vx = i2(buf+pos_GPSecefV) * 0.01;
|
||||
double vy = i2(buf+pos_GPSecefV+2) * 0.01;
|
||||
double vz = i2(buf+pos_GPSecefV+4) * 0.01;
|
||||
if(wx==0 && wy==0 && wz==0) { if(si->validPos&0x7f) { si->validPos |= 0x80; } return; }
|
||||
// wgs84r
|
||||
double lat, lng, alt;
|
||||
wgs84r(wx, wy, wz, &lat, &lng, &alt);
|
||||
if(alt<-1000 || alt>80000) { if(si->validPos&0x7f) { si->validPos |= 0x80; } return; }
|
||||
si->lat = (float)(lat*DEG);
|
||||
si->lon = (float)(lng*DEG);
|
||||
si->alt = alt;
|
||||
// speeddir
|
||||
double sinlat = sin(lat);
|
||||
double coslat = cos(lat);
|
||||
double sinlng = sin(lng);
|
||||
double coslng = cos(lng);
|
||||
double vn = -vx*sinlat*coslng - vy*sinlat*sinlng + vz*coslat;
|
||||
double ve = -vx*sinlng + vy*coslng;
|
||||
double clb = vx*coslat*coslng + vy*coslat*sinlng + vz*sinlat;
|
||||
double dir = atang2(vn, ve)/RAD;
|
||||
if(dir<0.0) dir+=360.0;
|
||||
si->dir = dir;
|
||||
si->vs = clb;
|
||||
si->hs = sqrt(vn*vn + ve*ve);
|
||||
si->sats = buf[pos_GPSnSats];
|
||||
|
||||
Serial.printf("Pos: %f %f alt %f dir %f vs %f hs %f sats %d\n", si->lat, si->lon, si->alt, si->dir, si->vs, si->hs, si->sats);
|
||||
si->validPos = 0x7f;
|
||||
}
|
||||
static uint32_t getgpstime(uint8_t *buf) {
|
||||
return buf[pos_TIME] * 60*60 + buf[pos_TIME+1] * 60 + buf[pos_TIME+2];
|
||||
}
|
||||
// unix time stamp from date and time info in frame.
|
||||
static void getmp3htime(uint8_t *buf) {
|
||||
//SondeInfo *si = sonde.si();
|
||||
SondeData *si =&(sonde.si()->d);
|
||||
|
||||
// gpsdate from CFG frame 15 (0 if not yet received)
|
||||
uint32_t gpsdate = mp3hstate.gpsdate;
|
||||
uint32_t gpstime = getgpstime(buf);
|
||||
int tt = 0;
|
||||
if(gpsdate) {
|
||||
uint16_t year = (gpsdate%100)+2000;
|
||||
gpsdate /= 100;
|
||||
uint8_t month = gpsdate%100;
|
||||
gpsdate /= 100;
|
||||
uint8_t day = gpsdate % 100;
|
||||
// year-month-day to unix time
|
||||
tt = (year-1970)*365 + (year-1969)/4; // days since 1970
|
||||
if(month<=12) { tt += MON[month]; if((year%4)==0 && month>2) tt++; }
|
||||
tt = (tt+day-1)*(60*60*24);
|
||||
if(gpstime < mp3hstate.gpsdatetime) tt += 60*60*24; // time wrapped since last date tx
|
||||
Serial.printf("date: %04d-%02d-%02d t%d ", year, month, day, gpstime);
|
||||
}
|
||||
tt += gpstime;
|
||||
si->time = tt;
|
||||
si->vframe = tt - 315964800;
|
||||
Serial.printf(" mp3h TIMESTAMP: %d\n", tt);
|
||||
}
|
||||
|
||||
static uint8_t hex(uint32_t n) {
|
||||
n = n % 16;
|
||||
return (n<10) ? (n+'0') : (n-10+'A');
|
||||
}
|
||||
|
||||
static void resetmp3h() {
|
||||
mp3hstate.id1 = mp3hstate.id2 = 0;
|
||||
mp3hstate.idok = 0;
|
||||
mp3hstate.gpsdate = 0;
|
||||
mp3hstate.dateok = 0;
|
||||
}
|
||||
|
||||
// ret: 1=frame ok; 2=frame with errors; 0=ignored frame (m10dop-alternativ)
|
||||
int MP3H::decodeframeMP3H(uint8_t *data) {
|
||||
printRaw(data, MP3H_FRAMELEN);
|
||||
|
||||
//
|
||||
if(!checkMP3CRC(data)) {
|
||||
// maybe add repairing frames later...
|
||||
return 2;
|
||||
}
|
||||
|
||||
// data is a frame with correct CRC
|
||||
//SondeInfo *si = sonde.si();
|
||||
SondeData *si =&(sonde.si()->d);
|
||||
uint8_t cnt = data[pos_CNT1] & 0x0F;
|
||||
uint32_t cfg = u4(data+pos_CFG);
|
||||
if(cnt==15) {
|
||||
// date
|
||||
mp3hstate.gpsdate = cfg;
|
||||
mp3hstate.gpsdatetime = getgpstime(data);
|
||||
mp3hstate.dateok = true;
|
||||
} else if(cnt==13) {
|
||||
// id2
|
||||
if(mp3hstate.id2 > 0 && mp3hstate.id2 != cfg) { resetmp3h(); }
|
||||
mp3hstate.id2 = cfg;
|
||||
mp3hstate.idok |= 2;
|
||||
} else if(cnt==12) {
|
||||
// id1
|
||||
if(mp3hstate.id1 > 0 && mp3hstate.id1 != cfg) { resetmp3h(); }
|
||||
mp3hstate.id1 = cfg;
|
||||
mp3hstate.idok |= 1;
|
||||
}
|
||||
// get id
|
||||
if((mp3hstate.idok&3) == 3) {
|
||||
//...
|
||||
//si->type = STYPE_MP3H;
|
||||
uint32_t n = mp3hstate.id1*100000 + mp3hstate.id2;
|
||||
si->id[0] = 'M';
|
||||
si->id[1] = 'R';
|
||||
si->id[2] = 'Z';
|
||||
si->id[3] = hex(n/0x100000);
|
||||
si->id[4] = hex(n/0x10000);
|
||||
si->id[5] = hex(n/0x1000);
|
||||
si->id[6] = hex(n/0x100);
|
||||
si->id[7] = hex(n/0x10);
|
||||
si->id[8] = hex(n);
|
||||
si->id[9] = 0;
|
||||
snprintf(si->ser, 12, "%u-%u", mp3hstate.id1, mp3hstate.id2);
|
||||
si->validID = true;
|
||||
}
|
||||
|
||||
// position
|
||||
calcgps(data);
|
||||
// time
|
||||
getmp3htime(data);
|
||||
return 1;
|
||||
#if 0
|
||||
int repairstep = 16;
|
||||
int repl = 0;
|
||||
bool crcok;
|
||||
// error correction, inspired by oe5dxl's sondeudp
|
||||
do {
|
||||
crcok = checkMP3Hcrc(M10_CRCPOS, data);
|
||||
if(crcok || repairstep==0) break;
|
||||
repl = 0;
|
||||
for(int i=0; i<M10_CRCPOS; i++) {
|
||||
if( ((sondeudp_VARSET[i/32]&(1<<(i%32))) == 0) && (fixcnt[i]>=repairstep) ) {
|
||||
repl++;
|
||||
data[i] = fixbytes[i];
|
||||
}
|
||||
}
|
||||
repairstep >>= 1;
|
||||
} while(true);
|
||||
if(crcok) {
|
||||
for(int i=0; i<M10_CRCPOS; i++) {
|
||||
if(fixbytes[i]==data[i] &&fixcnt[i]<255) fixcnt[i]++;
|
||||
else { fixcnt[i]=0; fixbytes[i]=data[i]; }
|
||||
}
|
||||
}
|
||||
Serial.println(crcok?"CRC OK":"CRC NOT OK");
|
||||
Serial.printf(" repair: %d/%d\n", repl, repairstep);
|
||||
|
||||
if(data[1]==0x9F && data[2]==0x20) {
|
||||
Serial.println("Decoding...");
|
||||
// Its a M10
|
||||
// getid...
|
||||
char ids[11];
|
||||
ids[0] = 'M';
|
||||
ids[1] = 'E';
|
||||
ids[2] = hex(data[95]/16);
|
||||
ids[3] = hex(data[95]);
|
||||
ids[4] = hex(data[93]);
|
||||
uint32_t id = data[96] + data[97]*256;
|
||||
ids[5] = hex(id/4096);
|
||||
ids[6] = hex(id/256);
|
||||
ids[7] = hex(id/16);
|
||||
ids[8] = hex(id);
|
||||
ids[9] = 0;
|
||||
strncpy(sonde.si()->id, ids, 10);
|
||||
ids[0] = hex(data[95]/16);
|
||||
ids[1] = dez((data[95]&0x0f)/10);
|
||||
ids[2] = dez((data[95]&0x0f));
|
||||
ids[3] = dez(data[93]);
|
||||
ids[4] = dez(id>>13);
|
||||
id &= 0x1fff;
|
||||
ids[5] = dez(id/1000);
|
||||
ids[6] = dez((id/100)%10);
|
||||
ids[7] = dez((id/10)%10);
|
||||
ids[8] = dez(id%10);
|
||||
strncpy(sonde.si()->ser, ids, 10);
|
||||
sonde.si()->validID = true;
|
||||
Serial.printf("ID is %s [%02x %02x %d]\n", ids, data[95], data[93], id);
|
||||
// ID printed on sonde is ...-.-abbbb, with a=id>>13, bbbb=id&0x1fff in decimal
|
||||
// position data
|
||||
sonde.si()->lat = getint32(data+14) * DEGMUL;
|
||||
sonde.si()->lon = getint32(data+18) * DEGMUL;
|
||||
sonde.si()->alt = getint32(data+22) * 0.001;
|
||||
float ve = getint16(data+4)*VMUL;
|
||||
float vn = getint16(data+6)*VMUL;
|
||||
sonde.si()->vs = getint16(data+8) * VMUL;
|
||||
sonde.si()->hs = sqrt(ve*ve+vn*vn);
|
||||
float dir = atan2(vn, ve)*(1.0/RAD);
|
||||
if(dir<0) dir+=360;
|
||||
sonde.si()->dir = dir;
|
||||
sonde.si()->validPos = 0x3f;
|
||||
|
||||
uint32_t gpstime = getint32(data+10);
|
||||
uint16_t gpsweek = getint16(data+32);
|
||||
// UTC is GPSTIME - 18s (24*60*60-18 = 86382)
|
||||
// one week = 7*24*60*60 = 604800 seconds
|
||||
// unix epoch starts jan 1st 1970 0:00
|
||||
// gps time starts jan 6, 1980 0:00. thats 315964800 epoch seconds.
|
||||
// subtracting 86400 yields 315878400UL
|
||||
sonde.si()->time = (gpstime/1000) + 86382 + gpsweek*604800 + 315878400UL;
|
||||
sonde.si()->validTime = true;
|
||||
} else {
|
||||
Serial.printf("data is %02x %02x %02x\n", data[0], data[1], data[2]);
|
||||
return 0;
|
||||
}
|
||||
return crcok?1:2;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t rxdata;
|
||||
static bool rxsearching=true;
|
||||
|
||||
// search for
|
||||
// 0xBF3H (or inverse)
|
||||
void MP3H::processMP3Hdata(uint8_t dt)
|
||||
{
|
||||
for(int i=0; i<8; i++) {
|
||||
uint8_t d = (dt&0x80)?1:0;
|
||||
dt <<= 1;
|
||||
rxdata = (rxdata<<1) | d;
|
||||
if( (rxbitc&1)==0 ) {
|
||||
// "bit1"
|
||||
rxbyte = (rxbyte<<1) | d;
|
||||
} else {
|
||||
// "bit2" ==> 01 or 10 => 1, otherweise => 0
|
||||
// rxbyte = rxbyte ^ d;
|
||||
}
|
||||
// BF3H => 1011 1111 0011 0101 => 10011010 10101010 01011010 01100110 => 9AAA5A66 // 6555a599
|
||||
if(rxsearching) {
|
||||
if( rxdata == 0x9AAA5A66 || rxdata == 0x6555a599 ) {
|
||||
rxsearching = false;
|
||||
rxbitc = 0;
|
||||
rxp = 0;
|
||||
headerDetected = 1;
|
||||
Serial.print("SYNC\n");
|
||||
int rssi=sx1278.getRSSI();
|
||||
int fei=sx1278.getFEI();
|
||||
int afc=sx1278.getAFC();
|
||||
Serial.print("SYNC!!! Test: RSSI="); Serial.print(rssi);
|
||||
Serial.print(" FEI="); Serial.print(fei);
|
||||
Serial.print(" AFC="); Serial.println(afc);
|
||||
sonde.si()->rssi = rssi;
|
||||
sonde.si()->afc = afc;
|
||||
}
|
||||
} else {
|
||||
rxbitc = (rxbitc+1)%16; // 16;
|
||||
if(rxbitc == 0) { // got 8 data bit
|
||||
dataptr[rxp++] = rxbyte&0xff; // (rxbyte>>1)&0xff;
|
||||
//if(rxp==2 && dataptr[0]==0x45 && dataptr[1]==0x20) { isM20 = true; }
|
||||
if(rxp>=MP3H_FRAMELEN) {
|
||||
rxsearching = true;
|
||||
haveNewFrame = decodeframeMP3H(dataptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXFRAMES 6
|
||||
int MP3H::receive() {
|
||||
// we wait for at most 6 frames or until a new seq nr.
|
||||
uint8_t nFrames = MAXFRAMES; // MP3H sends every frame 6x
|
||||
static uint32_t lastFrame = 0;
|
||||
uint8_t retval = RX_TIMEOUT;
|
||||
|
||||
unsigned long t0 = millis();
|
||||
Serial.printf("MP3H::receive() start at %ld\n",t0);
|
||||
while( millis() - t0 < 1100 + (retval!=RX_TIMEOUT)?1000:0 ) {
|
||||
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
if ( bitRead(value, 7) ) {
|
||||
Serial.println("FIFO full");
|
||||
}
|
||||
if ( bitRead(value, 4) ) {
|
||||
Serial.println("FIFO overflow");
|
||||
}
|
||||
if ( bitRead(value, 2) == 1 ) {
|
||||
Serial.println("FIFO: ready()");
|
||||
sx1278.clearIRQFlags();
|
||||
}
|
||||
if(bitRead(value, 6) == 0) { // while FIFO not empty
|
||||
byte data = sx1278.readRegister(REG_FIFO);
|
||||
Serial.printf("%02x:",data);
|
||||
processMP3Hdata(data);
|
||||
value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
} else {
|
||||
if(headerDetected) {
|
||||
t0 = millis(); // restart timer... don't time out if header detected...
|
||||
headerDetected = 0;
|
||||
}
|
||||
if(haveNewFrame) {
|
||||
Serial.printf("MP3H::receive(): new frame complete after %ldms\n", millis()-t0);
|
||||
printRaw(dataptr, MP3H_FRAMELEN);
|
||||
nFrames--;
|
||||
// frame with CRC error: just skip and retry (unless we have waited for 6 frames alred)
|
||||
if(haveNewFrame != 1) {
|
||||
Serial.printf("hNF: %d (ERROR)\n", haveNewFrame);
|
||||
retval = RX_ERROR;
|
||||
} else if (sonde.si()->d.time == lastFrame) { // same frame number as seen before => skip
|
||||
Serial.printf("Skipping frame with frame# %d\n", lastFrame);
|
||||
// nothing, wait for next, "new" frame
|
||||
} else { // good and new frame, return it.
|
||||
Serial.println("Good frame");
|
||||
haveNewFrame = 0;
|
||||
lastFrame = sonde.si()->d.time;
|
||||
return RX_OK;
|
||||
}
|
||||
haveNewFrame = 0;
|
||||
#if 0
|
||||
if(nFrames <= 0) {
|
||||
// up to 6 old or erronous frames received => break out
|
||||
Serial.printf("nFrames is %di, giving up\n", nFrames);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
delay(2);
|
||||
}
|
||||
}
|
||||
int32_t afc = sx1278.getAFC();
|
||||
int16_t rssi = sx1278.getRSSI();
|
||||
Serial.printf("receive: AFC is %d, RSSI is %.1f\n", afc, rssi/2.0);
|
||||
Serial.printf("MP3H::receive() timed out\n");
|
||||
return retval;
|
||||
}
|
||||
|
||||
int MP3H::waitRXcomplete() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MP3H mp3h = MP3H();
|
||||
|
36
RX_FSK/src/MP3H.h
Normal file
36
RX_FSK/src/MP3H.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* MP3H.h
|
||||
* Functions for decoding MP3H radiosonde
|
||||
* Copyright (C) 2021 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef MP3H_h
|
||||
#define MP3H_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "DecoderBase.h"
|
||||
|
||||
/* Main class */
|
||||
class MP3H : public DecoderBase
|
||||
{
|
||||
private:
|
||||
void printRaw(uint8_t *data, int len);
|
||||
void processMP3Hdata(uint8_t data);
|
||||
int decodeframeMP3H(uint8_t *data);
|
||||
public:
|
||||
MP3H();
|
||||
int setup(float frequency, int type = 0);
|
||||
int receive();
|
||||
int waitRXcomplete();
|
||||
};
|
||||
|
||||
extern MP3H mp3h;
|
||||
|
||||
#endif
|
934
RX_FSK/src/RS41.cpp
Normal file
934
RX_FSK/src/RS41.cpp
Normal file
|
@ -0,0 +1,934 @@
|
|||
|
||||
/* RS41 decoder functions */
|
||||
#include "RS41.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "rsc.h"
|
||||
#include "Sonde.h"
|
||||
|
||||
#define RS41_DEBUG 1
|
||||
|
||||
#if RS41_DEBUG
|
||||
#define RS41_DBG(x) x
|
||||
#else
|
||||
#define RS41_DBG(x)
|
||||
#endif
|
||||
|
||||
#define RS41MAXLEN (320)
|
||||
static byte data[800];
|
||||
static int dpos = 0;
|
||||
|
||||
|
||||
// whole 51 row frame as C structure
|
||||
// taken from https://github.com/einergehtnochrein/ra-firmware
|
||||
struct subframeBuffer {
|
||||
uint64_t valid; // bitmask for subframe valid; lsb=frame 0, etc.
|
||||
union {
|
||||
byte rawData[51*16];
|
||||
struct __attribute__((__packed__)) {
|
||||
uint16_t crc16; /* CRC16 CCITT Checksum over range 0x002...0x31F */
|
||||
uint16_t frequency; /* 0x002: TX is on 400 MHz + (frequency / 64) * 10 kHz */
|
||||
uint8_t startupTxPower; /* 0x004: TX power level at startup (1...7) */
|
||||
uint8_t reserved005;
|
||||
uint8_t reserved006;
|
||||
uint16_t reserved007; /* 0x007: ?? (some bitfield) [0],[1],[2],[3]. Init value = 0xE */
|
||||
uint16_t reserved009; /* 0x009: ? */
|
||||
uint8_t reserved00B;
|
||||
uint8_t reserved00C;
|
||||
uint8_t serial[8]; /* 0x00D: Sonde ID, 8 char, not terminated */
|
||||
uint16_t firmwareVersion; /* 0x015: 10000*major + 100*minor + patch*/
|
||||
uint16_t reserved017;
|
||||
uint16_t minHeight4Flight; /* 0x019: Height (meter above ground) where flight mode begins */
|
||||
uint8_t lowBatteryThreshold100mV; /* 0x01B: (Default=18) Shutdown if battery voltage below this
|
||||
threshold for some time (10s ?)
|
||||
*/
|
||||
uint8_t nfcDetectorThreshold; /* 0x01C: NFC detector threshold [25mV] (Default: 0x05 = 125mV) */
|
||||
uint8_t reserved01D; /* 0x01D: ?? (Init value = 0xB4) */
|
||||
uint8_t reserved01E; /* 0x01E: ?? (Init value = 0x3C) */
|
||||
uint16_t reserved01F;
|
||||
int8_t refTemperatureThreshold; /* 0x021: Reference temperature threshold [°C] */
|
||||
uint8_t reserved022;
|
||||
uint16_t reserved023;
|
||||
uint16_t reserved025;
|
||||
int16_t flightKillFrames; /* 0x027: Number of frames in flight until kill (-1 = disabled) */
|
||||
uint16_t reserved029; /* 0x029: ? (Init value = 0) */
|
||||
uint8_t burstKill; /* 0x02B: Burst kill (0=disabled, 1=enabled) */
|
||||
uint8_t reserved02C;
|
||||
uint8_t reserved02D;
|
||||
uint16_t reserved02E;
|
||||
uint16_t reserved030;
|
||||
uint8_t reserved032;
|
||||
uint16_t reserved033;
|
||||
uint16_t reserved035;
|
||||
uint16_t reserved037;
|
||||
uint16_t reserved039; /* 0x039: */
|
||||
uint8_t reserved03B; /* 0x03B: */
|
||||
uint8_t reserved03C; /* 0x03C: */
|
||||
float refResistorLow; /* 0x03D: Reference resistor low (750 Ohms) */
|
||||
float refResistorHigh; /* 0x041: Reference resistor high (1100 Ohms) */
|
||||
float refCapLow; /* 0x045: Reference capacitance low (0) */
|
||||
float refCapHigh; /* 0x049: Reference capacitance high (47 pF) */
|
||||
float taylorT[3]; /* 0x04D: Tayor coefficients for main temperature calculation */
|
||||
float calT; /* 0x059: Calibration factor for main sensor */
|
||||
float polyT[6]; /* 0x05D: */
|
||||
float calibU[2]; /* 0x075: Calibration coefficients for humidity sensor */
|
||||
|
||||
float matrixU[7][6]; /* 0x07D: Matrix for humidity sensor RH calculation */
|
||||
float taylorTU[3]; /* 0x125: Coefficients for U sensor temperature calculation */
|
||||
float calTU; /* 0x131: Calibration factor for U temperature sensor */
|
||||
float polyTrh[6]; /* 0x135: */
|
||||
|
||||
uint8_t reserved14D; /* 0x14D: */
|
||||
uint32_t reserved14E; /* 0x14E: */
|
||||
|
||||
float f152;
|
||||
uint8_t u156;
|
||||
float f157; /* 0x157: ?? (Initialized by same value as calibU[0]) */
|
||||
uint8_t reserved15B; /* 0x15B: */
|
||||
uint32_t reserved15C; /* 0x15C: */
|
||||
float f160[35];
|
||||
uint8_t startIWDG; /* 0x1EC: If ==1 or ==2: Watchdog IWDG will not be started */
|
||||
uint8_t parameterSetupDone; /* 0x1ED: Set (!=0) if parameter setup was done */
|
||||
uint8_t enableTestMode; /* 0x1EE: Test mode (service menu) (0=disabled, 1=enabled) */
|
||||
uint8_t enableTX; /* 0x1EF: 0=TX disabled, 1=TX enabled (maybe this is autostart?) */
|
||||
float f1F0[8];
|
||||
float pressureLaunchSite[2]; /* 0x210: Pressure [hPa] at launch site */
|
||||
struct __attribute__((__packed__)){
|
||||
char variant[10]; /* 0x218: Sonde variant (e.g. "RS41-SG") */
|
||||
uint8_t mainboard[10]; /* 0x222: Name of mainboard (e.g. "RSM412") */
|
||||
} names;
|
||||
struct __attribute__((__packed__)){
|
||||
uint8_t mainboard[9]; /* 0x22C: Serial number of mainboard (e.g. "L1123553") */
|
||||
uint8_t text235[12]; /* 0x235: "0000000000" */
|
||||
uint16_t reserved241; /* 0x241: */
|
||||
uint8_t pressureSensor[8]; /* 0x243: Serial number of pressure sensor (e.g. "N1310487") */
|
||||
uint16_t reserved24B; /* 0x24B: */
|
||||
} serials;
|
||||
uint16_t reserved24D; /* 0x24D: */
|
||||
uint16_t reserved24F; /* 0x24F: */
|
||||
uint16_t reserved251; /* 0x251: (Init value = 0x21A = 538) */
|
||||
uint8_t xdataUartBaud; /* 0x253: 1=9k6, 2=19k2, 3=38k4, 4=57k6, 5=115k2 */
|
||||
uint8_t reserved254;
|
||||
float cpuTempSensorVoltageAt25deg; /* 0x255: CPU temperature sensor voltage at 25°C */
|
||||
uint8_t reserved259;
|
||||
uint8_t reserved25A[0x25E -0x25A];
|
||||
float matrixP[18]; /* 0x25E: Coefficients for pressure sensor polynomial */
|
||||
float vectorBp[3]; /* 0x2A6: */
|
||||
uint8_t reserved2B2[8]; /* 0x2B2: */
|
||||
float matrixBt[12]; /* 0x2BA: */
|
||||
uint8_t reserved2EA[0x2FA-0x2EA];
|
||||
uint16_t halfword2FA[9];
|
||||
float reserved30C;
|
||||
float reserved310; /* 0x310: */
|
||||
uint8_t reserved314; /* 0x314: */
|
||||
uint8_t reserved315; /* 0x315: */
|
||||
int16_t burstKillFrames; /* 0x316: Number of active frames after burst kill */
|
||||
uint8_t reserved318[0x320-0x318];
|
||||
|
||||
/* This is fragment 50. It only uses 14 valid bytes! */
|
||||
int16_t killCountdown; /* 0x320: Counts frames remaining until kill (-1 = inactive) */
|
||||
uint8_t reserved322[6];
|
||||
int8_t intTemperatureCpu; /* 0x328: Temperature [°C] of CPU */
|
||||
int8_t intTemperatureRadio; /* 0x329: Temperature [°C] of radio chip */
|
||||
int8_t reserved32A; /* 0x32A: */
|
||||
uint8_t reserved32B; /* 0x32B: */
|
||||
uint8_t reserved32C; /* 0x32C: ? (the sum of two slow 8-bit counters) */
|
||||
uint8_t reserved32D; /* 0x32D: ? (the sum of two slow 8-bit counters) */
|
||||
} value;
|
||||
};
|
||||
};
|
||||
// moved global variable "calibration" to sondeInfo->extra
|
||||
|
||||
static uint16_t CRCTAB[256];
|
||||
|
||||
#define X2C_DIVR(a, b) ((b) != 0.0f ? (a)/(b) : (a))
|
||||
#define X2C_DIVL(a, b) ((a)/(b))
|
||||
static uint32_t X2C_LSH(uint32_t a, int32_t length, int32_t n)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
m = 0;
|
||||
m = (length == 32) ? 0xFFFFFFFFl : (1 << length) - 1;
|
||||
if (n > 0) {
|
||||
if (n >= (int32_t)length)
|
||||
return 0;
|
||||
return (a << n) & m;
|
||||
}
|
||||
|
||||
if (n <= (int32_t)-length)
|
||||
return 0;
|
||||
return (a >> -n) & m;
|
||||
}
|
||||
|
||||
double atang2(double x, double y)
|
||||
{
|
||||
double w;
|
||||
if (fabs(x)>fabs(y)) {
|
||||
w = (double)atan(X2C_DIVL(y,x));
|
||||
if (x<0.0) {
|
||||
if (y>0.0) w = 3.1415926535898+w;
|
||||
else w = w-3.1415926535898;
|
||||
}
|
||||
}
|
||||
else if (y!=0.0) {
|
||||
w = (double)(1.5707963267949f-atan(X2C_DIVL(x, y)));
|
||||
if (y<0.0) w = w-3.1415926535898;
|
||||
}
|
||||
else w = 0.0;
|
||||
return w;
|
||||
} /* end atang2() */
|
||||
|
||||
|
||||
static void Gencrctab(void)
|
||||
{
|
||||
uint16_t j;
|
||||
uint16_t i;
|
||||
uint16_t crc;
|
||||
for (i = 0U; i<=255U; i++) {
|
||||
crc = (uint16_t)(i*256U);
|
||||
for (j = 0U; j<=7U; j++) {
|
||||
if ((0x8000U & crc)) crc = X2C_LSH(crc,16,1)^0x1021U;
|
||||
else crc = X2C_LSH(crc,16,1);
|
||||
} /* end for */
|
||||
CRCTAB[i] = X2C_LSH(crc,16,-8)|X2C_LSH(crc,16,8);
|
||||
} /* end for */
|
||||
} /* end Gencrctab() */
|
||||
|
||||
decoderSetupCfg rs41SetupCfg = {
|
||||
.bitrate = 4800,
|
||||
.rx_cfg = 0x1E, // Enable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
.sync_cfg = 0x57, // Set autostart_RX to 01, preamble 0, SYNC detect==on, syncsize=3 (==4 byte
|
||||
.sync_len = 8,
|
||||
.sync_data = (const uint8_t *)"\x08\x6D\x53\x88\x44\x69\x48\x1F",
|
||||
.preamble_cfg = 0xA8,
|
||||
};
|
||||
|
||||
|
||||
int RS41::setup(float frequency, int /*type*/)
|
||||
{
|
||||
if(!initialized) {
|
||||
Gencrctab();
|
||||
initrsc();
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if(sx1278.ON()!=0) {
|
||||
RS41_DBG(Serial.println("Setting SX1278 power on FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(DecoderBase::setup(rs41SetupCfg, sonde.config.rs41.agcbw, sonde.config.rs41.rxbw)!=0 ) {
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
// all moved to DecoderBase now
|
||||
if(sx1278.setFSK()!=0) {
|
||||
RS41_DBG(Serial.println("Setting FSK mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setBitrate(4800)!=0) {
|
||||
RS41_DBG(Serial.println("Setting bitrate 4800bit/s FAILED"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(sx1278.setAFCBandwidth(sonde.config.rs41.agcbw)!=0) {
|
||||
RS41_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.rs41.agcbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.rs41.rxbw)!=0) {
|
||||
RS41_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.rs41.rxbw));
|
||||
return 1;
|
||||
}
|
||||
// Enable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
if(sx1278.setRxConf(0x1E)!=0) {
|
||||
RS41_DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// Set autostart_RX to 01, preamble 0, SYNC detect==on, syncsize=3 (==4 byte
|
||||
//char header[] = "0110.0101 0110.0110 1010.0101 1010.1010";
|
||||
|
||||
//const char *SYNC="\x10\xB6\xCA\x11\x22\x96\x12\xF8";
|
||||
const char *SYNC="\x08\x6D\x53\x88\x44\x69\x48\x1F";
|
||||
if(sx1278.setSyncConf(0x57, 8, (const uint8_t *)SYNC)!=0) {
|
||||
RS41_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setPreambleDetect(0xA8)!=0) {
|
||||
RS41_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Packet config 1: fixed len, no mancecer, no crc, no address filter
|
||||
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
RS41_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
int retval = sx1278.setFrequency(frequency);
|
||||
dpos = 0;
|
||||
|
||||
sx1278.clearIRQFlags();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
uint32_t RS41::bits2val(const uint8_t *bits, int len) {
|
||||
uint32_t val = 0;
|
||||
for (int j = 0; j < len; j++) {
|
||||
val |= (bits[j] << (len-1-j));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
RS41::RS41() {
|
||||
}
|
||||
|
||||
/* RS41 reed solomon decoder, from dxlAPRS
|
||||
*/
|
||||
static int32_t reedsolomon41(byte buf[], uint32_t buf_len, uint32_t len2)
|
||||
{
|
||||
uint32_t i;
|
||||
int32_t res1;
|
||||
/*tb1, */
|
||||
int32_t res;
|
||||
char b1[256];
|
||||
char b[256];
|
||||
uint32_t eraspos[24];
|
||||
uint32_t tmp;
|
||||
for (i = 0UL; i<=255UL; i++) {
|
||||
b[i] = 0;
|
||||
b1[i] = 0;
|
||||
} /* end for */
|
||||
tmp = len2;
|
||||
i = 0UL;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
b[230UL-i] = buf[i*2UL+56UL];
|
||||
b1[230UL-i] = buf[i*2UL+57UL];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=23UL; i++) {
|
||||
b[254UL-i] = buf[i+8UL];
|
||||
b1[254UL-i] = buf[i+32UL];
|
||||
} /* end for */
|
||||
res = decodersc(b, eraspos, 0);
|
||||
res1 = decodersc(b1, eraspos, 0);
|
||||
if (res>0L && res<=12L) {
|
||||
tmp = len2;
|
||||
i = 0UL;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
buf[i*2UL+56UL] = b[230UL-i];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=23UL; i++) {
|
||||
buf[i+8UL] = b[254UL-i];
|
||||
} /* end for */
|
||||
}
|
||||
if (res1>0L && res1<=12L) {
|
||||
tmp = len2;
|
||||
i = 0UL;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
buf[i*2UL+57UL] = b1[230UL-i];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=23UL; i++) {
|
||||
buf[i+32UL] = b1[254UL-i];
|
||||
} /* end for */
|
||||
}
|
||||
if (res<0L || res1<0L) return -1L;
|
||||
else return res+res1;
|
||||
return 0;
|
||||
} /* end reedsolomon41() */
|
||||
|
||||
|
||||
|
||||
|
||||
static char crcrs(const byte frame[], uint32_t frame_len,
|
||||
int32_t from, int32_t to)
|
||||
{
|
||||
uint16_t crc;
|
||||
int32_t i;
|
||||
int32_t tmp;
|
||||
crc = 0xFFFFU;
|
||||
tmp = to-3L;
|
||||
i = from;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
crc = X2C_LSH(crc,16,-8)^CRCTAB[(uint32_t)((crc^(uint16_t)(uint8_t)frame[i])&0xFFU)];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
return frame[to-1L]==(char)crc && frame[to-2L]==(char)X2C_LSH(crc,
|
||||
16,-8);
|
||||
} /* end crcrs() */
|
||||
|
||||
static int32_t getint32(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t i;
|
||||
n = 0UL;
|
||||
for (i = 3UL;; i--) {
|
||||
n = n*256UL+(uint32_t)(uint8_t)frame[p+i];
|
||||
if (i==0UL) break;
|
||||
} /* end for */
|
||||
return (int32_t)n;
|
||||
} /* end getint32() */
|
||||
|
||||
static uint32_t getint24(const byte frame[], uint32_t frame_len, uint32_t p) { // 24bit unsigned int
|
||||
uint32_t val24 = 0;
|
||||
val24 = frame[p] | (frame[p+1]<<8) | (frame[p+2]<<16);
|
||||
return val24;
|
||||
}
|
||||
|
||||
static uint32_t getcard16(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
return (uint32_t)(uint8_t)frame[p]+256UL*(uint32_t)(uint8_t)
|
||||
frame[p+1UL];
|
||||
} /* end getcard16() */
|
||||
|
||||
|
||||
static int32_t getint16(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
uint32_t n;
|
||||
n = (uint32_t)(uint8_t)frame[p]+256UL*(uint32_t)(uint8_t)
|
||||
frame[p+1UL];
|
||||
if (n>=32768UL) return (int32_t)(n-65536UL);
|
||||
return (int32_t)n;
|
||||
} /* end getint16() */
|
||||
|
||||
// also used by MP3H.cpp
|
||||
void wgs84r(double x, double y, double z,
|
||||
double * lat, double * long0,
|
||||
double * heig)
|
||||
{
|
||||
double sl;
|
||||
double ct;
|
||||
double st;
|
||||
double t;
|
||||
double rh;
|
||||
double xh;
|
||||
double h;
|
||||
h = x*x+y*y;
|
||||
if (h>0.0) {
|
||||
rh = sqrt(h);
|
||||
xh = x+rh;
|
||||
*long0 = atang2(xh, y)*2.0;
|
||||
if (*long0>3.1415926535898) *long0 = *long0-6.2831853071796;
|
||||
t = atan(X2C_DIVL(z*1.003364089821, rh));
|
||||
st = sin(t);
|
||||
ct = cos(t);
|
||||
*lat = atan((X2C_DIVL(z+4.2841311513312E+4*st*st*st,
|
||||
rh-4.269767270718E+4*ct*ct*ct)));
|
||||
sl = sin(*lat);
|
||||
*heig = X2C_DIVL(rh,cos(*lat))-(X2C_DIVR(6.378137E+6f,
|
||||
sqrt((1.0-6.6943799901413E-3*sl*sl))));
|
||||
}
|
||||
else {
|
||||
*lat = 0.0;
|
||||
*long0 = 0.0;
|
||||
*heig = 0.0;
|
||||
}
|
||||
/* lat:=atan(z/(rh*(1.0 - E2))); */
|
||||
/* heig:=sqrt(h + z*z) - EARTHA; */
|
||||
} /* end wgs84r() */
|
||||
|
||||
// returns: 0=ok, -1=error
|
||||
static void posrs41(const byte b[], uint32_t b_len, uint32_t p)
|
||||
{
|
||||
double dir;
|
||||
double vu;
|
||||
double ve;
|
||||
double vn;
|
||||
double vz;
|
||||
double vy;
|
||||
double vx;
|
||||
double heig;
|
||||
double long0;
|
||||
double lat;
|
||||
double z;
|
||||
double y;
|
||||
double x;
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
x = (double)getint32(b, b_len, p)*0.01;
|
||||
y = (double)getint32(b, b_len, p+4UL)*0.01;
|
||||
z = (double)getint32(b, b_len, p+8UL)*0.01;
|
||||
uint8_t sats = getcard16(b, b_len, p+18UL)&255UL;
|
||||
Serial.printf("x:%g, y:%g, z:%g sats:%d\n", x, y, z, sats);
|
||||
if( sats<4 || (x==0 && y==0 && z==0) ) {
|
||||
// RS41 sometimes sends frame with all 0
|
||||
// or, if sats<4, data is simply garbage. do not use.
|
||||
if(si->validPos) si->validPos |= 0x80; // flag as old
|
||||
return;
|
||||
}
|
||||
si->sats = sats;
|
||||
wgs84r(x, y, z, &lat, &long0, &heig);
|
||||
Serial.print(" ");
|
||||
si->lat = (float)(X2C_DIVL(lat,1.7453292519943E-2));
|
||||
Serial.print(si->lat);
|
||||
Serial.print(" ");
|
||||
si->lon = (float)(X2C_DIVL(long0,1.7453292519943E-2));
|
||||
Serial.print(si->lon);
|
||||
if (heig<1.E+5 && heig>(-1.E+5)) {
|
||||
Serial.print(" ");
|
||||
Serial.print((uint32_t)heig);
|
||||
Serial.print("m");
|
||||
}
|
||||
/*speed */
|
||||
vx = (double)getint16(b, b_len, p+12UL)*0.01;
|
||||
vy = (double)getint16(b, b_len, p+14UL)*0.01;
|
||||
vz = (double)getint16(b, b_len, p+16UL)*0.01;
|
||||
vn = (-(vx*sin(lat)*cos(long0))-vy*sin(lat)*sin(long0))+vz*cos(lat);
|
||||
ve = -(vx*sin(long0))+vy*cos(long0);
|
||||
vu = vx*cos(lat)*cos(long0)+vy*cos(lat)*sin(long0)+vz*sin(lat);
|
||||
dir = X2C_DIVL(atang2(vn, ve),1.7453292519943E-2);
|
||||
if (dir<0.0) dir = 360.0+dir;
|
||||
si->dir = dir;
|
||||
Serial.print(" ");
|
||||
si->hs = sqrt(vn*vn+ve*ve);
|
||||
Serial.print(si->hs*3.6);
|
||||
Serial.print("km/h ");
|
||||
Serial.print(dir);
|
||||
Serial.print("deg ");
|
||||
Serial.print((float)vu);
|
||||
si->vs = vu;
|
||||
Serial.print("m/s ");
|
||||
si->alt = heig;
|
||||
if( 0==(int)(lat*10000) && 0==(int)(long0*10000) ) {
|
||||
if(si->validPos) {
|
||||
// we have an old position, so keep previous position and mark it as old
|
||||
si->validPos |= 0x80;
|
||||
}
|
||||
}
|
||||
else
|
||||
si->validPos = 0x7f;
|
||||
} /* end posrs41() */
|
||||
|
||||
void ProcessSubframe( byte *subframeBytes, int subframeNumber ) {
|
||||
// the total subframe consists of 51 rows, each row 16 bytes
|
||||
// based on https://github.com/bazjo/RS41_Decoding/tree/master/RS41-SGP#Subframe
|
||||
struct subframeBuffer *s = (struct subframeBuffer *)sonde.si()->extra;
|
||||
// Allocate on demand
|
||||
if(!s) {
|
||||
s = (struct subframeBuffer *)malloc( sizeof(struct subframeBuffer) );
|
||||
if(!s) { Serial.println("ProcessSubframe: out of memory"); return; }
|
||||
sonde.si()->extra = s;
|
||||
s->valid = 0;
|
||||
}
|
||||
memcpy( s->rawData+16*subframeNumber, subframeBytes, 16);
|
||||
s->valid |= (1ULL << subframeNumber);
|
||||
Serial.printf("subframe %d; valid: %x%08x\n", subframeNumber, (uint32_t)(s->valid>>32), (uint32_t)s->valid);
|
||||
for(int i=0; i<16; i++) { Serial.printf("%02x[%c]", subframeBytes[i],( subframeBytes[i]>20 && subframeBytes[i]<127)? subframeBytes[i] : '.'); }
|
||||
Serial.println("");
|
||||
// subframeReceived[subframeNumber] = true; // mark this row of the total subframe as complete
|
||||
|
||||
#if 0
|
||||
Serial.printf("subframe number: 0x%02X\n", subframeNumber );
|
||||
Serial.print("subframe values: ");
|
||||
for ( int i = 0; i < 16; i++ ) {
|
||||
Serial.printf( "%02X ", subframeBytes[i] );
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
Serial.println("Full subframe");
|
||||
for ( int j = 0; j<51; j++ ) {
|
||||
Serial.printf("%03X ", j*16);
|
||||
for ( int i = 0; i < 16; i++ ) {
|
||||
Serial.printf( "%02X ", s.rawData[j*16+i] );
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Find the water vapor saturation pressure for a given temperature.
|
||||
* Uses the Hyland and Wexler equation with coefficients for T < 0°C.
|
||||
*/
|
||||
// taken from https://github.com/einergehtnochrein/ra-firmware
|
||||
static float _RS41_waterVaporSaturationPressure (float Tcelsius)
|
||||
{
|
||||
/* Convert to Kelvin */
|
||||
float T = Tcelsius + 273.15f;
|
||||
|
||||
/* Apply some correction magic */
|
||||
T = 0
|
||||
- 0.4931358f
|
||||
+ (1.0f + 4.61e-3f) * T
|
||||
- 1.3746454e-5f * T * T
|
||||
+ 1.2743214e-8f * T * T * T
|
||||
;
|
||||
|
||||
/* Plug into H+W equation */
|
||||
float p = expf(-5800.2206f / T
|
||||
+ 1.3914993f
|
||||
+ 6.5459673f * logf(T)
|
||||
- 4.8640239e-2f * T
|
||||
+ 4.1764768e-5f * T * T
|
||||
- 1.4452093e-8f * T * T * T
|
||||
);
|
||||
|
||||
/* Scale result to hPa */
|
||||
return p / 100.0f;
|
||||
}
|
||||
|
||||
#define PM(x) calibration->value.matrixP[x]
|
||||
// CALIB_P: matrixP (frames 0x25..0x2A) and type (frame 0x21)
|
||||
#define CALIB_P ((0x3Fll<<0x25)|(1ll<<0x21))
|
||||
float GetRAP( uint32_t m, uint32_t m1, uint32_t m2, int16_t ptraw) {
|
||||
struct subframeBuffer *calibration = (struct subframeBuffer *)sonde.si()->extra;
|
||||
float pt = (float)ptraw*0.01;
|
||||
float pw[6];
|
||||
pw[0] = PM(0) + pt*PM(7) + pt*pt*PM(11) + pt*pt*pt*PM(15);
|
||||
pw[1] = PM(1) + pt*PM(8) + pt*pt*PM(12) + pt*pt*pt*PM(16);
|
||||
pw[2] = PM(2) + pt*PM(9) + pt*pt*PM(13) + pt*pt*pt*PM(17);
|
||||
pw[3] = PM(3) + pt*PM(10)+ pt*pt*PM(14);
|
||||
pw[4] = PM(4);
|
||||
pw[5] = PM(5);
|
||||
float f = (float)m; //meas[9];
|
||||
float f1 = (float)m1; //meas[10];
|
||||
float f2 = (float)m2; //meas[11];
|
||||
float r = f-f1;
|
||||
if(r!=0.0) {
|
||||
r = (f2-f1) * PM(6) / r;
|
||||
float xx = 1.0;
|
||||
float p = 0.0;
|
||||
for(int i=0; i<=5; i++) {
|
||||
p += pw[i] * xx;
|
||||
xx = xx * r;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
// taken from https://github.com/einergehtnochrein/ra-firmware
|
||||
float GetRATemp( uint32_t measuredCurrent, uint32_t refMin, uint32_t refMax, float calT, float taylorT[3], float polyT[6] ) {
|
||||
struct subframeBuffer *calibration = (struct subframeBuffer *)sonde.si()->extra;
|
||||
/* Reference values for temperature are two known resistors.
|
||||
* From that we can derive the resistance of the sensor.
|
||||
*/
|
||||
float current = ( float(measuredCurrent) - float(refMin) ) / float(refMax - refMin);
|
||||
float res = calibration->value.refResistorLow
|
||||
+ (calibration->value.refResistorHigh - calibration->value.refResistorLow) * current;
|
||||
float x = res * calT;
|
||||
|
||||
float Tuncal = 0
|
||||
+ taylorT[0]
|
||||
+ taylorT[1] * x
|
||||
+ taylorT[2] * x * x;
|
||||
|
||||
/* Apply calibration polynomial */
|
||||
float temperature =
|
||||
Tuncal + polyT[0]
|
||||
+ polyT[1] * Tuncal
|
||||
+ polyT[2] * Tuncal * Tuncal
|
||||
+ polyT[3] * Tuncal * Tuncal * Tuncal
|
||||
+ polyT[4] * Tuncal * Tuncal * Tuncal * Tuncal
|
||||
+ polyT[5] * Tuncal * Tuncal * Tuncal * Tuncal * Tuncal;
|
||||
|
||||
return temperature;
|
||||
}
|
||||
|
||||
// taken from https://github.com/einergehtnochrein/ra-firmware
|
||||
float GetRAHumidity( uint32_t humCurrent, uint32_t humMin, uint32_t humMax, float sensorTemp, float externalTemp, float pressure ) {
|
||||
struct subframeBuffer *calibration = (struct subframeBuffer *)sonde.si()->extra;
|
||||
float current = float( humCurrent - humMin) / float( humMax - humMin );
|
||||
/* Compute absolute capacitance from the known references */
|
||||
float C = calibration->value.refCapLow
|
||||
+ (calibration->value.refCapHigh - calibration->value.refCapLow) * current;
|
||||
|
||||
/* Apply calibration */
|
||||
float Cp = ( C / calibration->value.calibU[0] - 1.0f) * calibration->value.calibU[1];
|
||||
|
||||
/* Compensation for low temperature and pressure at altitude */
|
||||
if(isnan(pressure)) {
|
||||
// if no pressure is available (non-SGP), estimate based on altitude
|
||||
pressure = 1013.25f * expf(-1.18575919e-4f * sonde.si()->d.alt );
|
||||
}
|
||||
|
||||
float Tp = (sensorTemp - 20.0f) / 180.0f;
|
||||
float sum = 0;
|
||||
float powc = 1.0f;
|
||||
float p = pressure / 1000.0f;
|
||||
for ( int i = 0; i < 3; i++) {
|
||||
float l = 0;
|
||||
float powt = 1.0f;
|
||||
for ( int j = 0; j < 4; j++) {
|
||||
l += calibration->value.matrixBt[4*i+j] * powt;
|
||||
powt *= Tp;
|
||||
}
|
||||
float x = calibration->value.vectorBp[i];
|
||||
sum += l * (x * p / (1.0f + x * p) - x * powc / (1.0f + x));
|
||||
powc *= Cp;
|
||||
}
|
||||
Cp -= sum;
|
||||
|
||||
float xj = 1.0f;
|
||||
for ( int j = 0; j < 7; j++) {
|
||||
float yk = 1.0f;
|
||||
for ( int k = 0; k < 6; k++) {
|
||||
sum += xj * yk * calibration->value.matrixU[j][k];
|
||||
yk *= Tp;
|
||||
}
|
||||
xj *= Cp;
|
||||
}
|
||||
|
||||
/* Since there is always a small difference between the temperature readings for
|
||||
* the atmospheric (main) tempoerature sensor and the temperature sensor inside
|
||||
* the humidity sensor device, transform the humidity value to the atmospheric conditions
|
||||
* with its different water vapor saturation pressure.
|
||||
*/
|
||||
float RH = sum
|
||||
* _RS41_waterVaporSaturationPressure(sensorTemp)
|
||||
/ _RS41_waterVaporSaturationPressure(externalTemp);
|
||||
|
||||
return RH;
|
||||
}
|
||||
|
||||
// returns: 0: ok, -1: rs or crc error
|
||||
int RS41::decode41(byte *data, int maxlen)
|
||||
{
|
||||
char buf[128];
|
||||
int crcok = 1;
|
||||
SondeData *si = &(sonde.si()->d);
|
||||
|
||||
int32_t corr = reedsolomon41(data, 560, 131); // try short frame first
|
||||
if(corr<0) {
|
||||
corr = reedsolomon41(data, 560, 230); // try long frame
|
||||
}
|
||||
#if 0
|
||||
Serial.print("RS result:");
|
||||
Serial.print(corr);
|
||||
Serial.println();
|
||||
#endif
|
||||
int p = 57; // 8 byte header, 48 byte RS
|
||||
while(p<maxlen) { /* why 555? */
|
||||
uint8_t typ = data[p++];
|
||||
uint32_t len = data[p++]+2UL;
|
||||
if(p+len>maxlen) break;
|
||||
|
||||
#if 0
|
||||
// DEBUG OUTPUT
|
||||
Serial.print("@");
|
||||
Serial.print(p-2);
|
||||
Serial.print(": ID:");
|
||||
Serial.print(typ, HEX);
|
||||
Serial.print(", len=");
|
||||
Serial.print(len);
|
||||
Serial.print(": ");
|
||||
for(int i=0; i<len-1; i++) {
|
||||
char buf[3];
|
||||
snprintf(buf, 4, "%02X|", data[p+i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
#endif
|
||||
// check CRC
|
||||
if(!crcrs(data, 560, p, p+len)) {
|
||||
Serial.println("###CRC ERROR###");
|
||||
crcok = 0;
|
||||
} else {
|
||||
switch(typ) {
|
||||
case 'y': // name
|
||||
{
|
||||
if(strncmp(si->id, (const char *)(data+p+2), 8)) {
|
||||
// ID changed, i.e. new sonde on same frequency. clear calibration and all other data
|
||||
sonde.clearAllData(sonde.si());
|
||||
struct subframeBuffer *sub = (struct subframeBuffer *)sonde.si()->extra;
|
||||
if(sub) { sub->valid = 0; }
|
||||
}
|
||||
Serial.print("#");
|
||||
uint16_t fnr = data[p]+(data[p+1]<<8);
|
||||
Serial.print(fnr);
|
||||
si->vframe = si->frame = fnr;
|
||||
Serial.print("; RS41 ID ");
|
||||
snprintf(buf, 10, "%.8s ", data+p+2);
|
||||
Serial.print(buf);
|
||||
si->batteryVoltage = data[p+10] / 10.0f;
|
||||
// not needed, if we end up here, the type has to be RS41.... si->type=STYPE_RS41;
|
||||
strncpy(si->id, (const char *)(data+p+2), 8);
|
||||
si->id[8]=0;
|
||||
strncpy(si->ser, (const char *)(data+p+2), 8);
|
||||
si->ser[8]=0;
|
||||
si->validID=true;
|
||||
int calnr = data[p+23];
|
||||
// not sure about this
|
||||
if(calnr==0x31) {
|
||||
uint16_t bt = data[p+30] + 256*data[p+31];
|
||||
si->burstKT = bt;
|
||||
}
|
||||
// this should be right...
|
||||
if(calnr==0x02) {
|
||||
uint16_t kt = data[p+31] + 256*data[p+32];
|
||||
si->launchKT = kt;
|
||||
}
|
||||
// and this seems fine as well...
|
||||
if(calnr==0x32) {
|
||||
uint16_t cntdown = data[p+24] + (data[p+25]<<8);
|
||||
uint16_t min = cntdown - (cntdown/3600)*3600;
|
||||
Serial.printf("Countdown value: %d\n [%2d:%02d:%02d]", cntdown, cntdown/3600, min/60, min-(min/60)*60);
|
||||
si->countKT = cntdown;
|
||||
si->crefKT = fnr;
|
||||
}
|
||||
ProcessSubframe( data+p+24, calnr );
|
||||
|
||||
}
|
||||
// TODO: some more data
|
||||
break;
|
||||
case '|': // date
|
||||
{
|
||||
uint32_t gpstime = getint32(data, 560, p+2);
|
||||
uint16_t gpsweek = getint16(data, 560, p);
|
||||
// UTC is GPSTIME - 18s (24*60*60-18 = 86382)
|
||||
// one week = 7*24*60*60 = 604800 seconds
|
||||
// unix epoch starts jan 1st 1970 0:00
|
||||
// gps time starts jan 6, 1980 0:00. thats 315964800 epoch seconds.
|
||||
// subtracting 86400 yields 315878400UL
|
||||
si->time = (gpstime/1000) + 86382 + gpsweek*604800 + 315878400UL;
|
||||
si->validTime = true;
|
||||
}
|
||||
break;
|
||||
case '{': // pos
|
||||
posrs41(data+p, len, 0);
|
||||
break;
|
||||
case 'z': // 0x7a is character z - 7A-MEAS temperature and humidity frame
|
||||
{
|
||||
uint32_t tempMeasMain = getint24(data, 560, p+0);
|
||||
uint32_t tempMeasRef1 = getint24(data, 560, p+3);
|
||||
uint32_t tempMeasRef2 = getint24(data, 560, p+6);
|
||||
uint32_t humidityMain = getint24(data, 560, p+9);
|
||||
uint32_t humidityRef1 = getint24(data, 560, p+12);
|
||||
uint32_t humidityRef2 = getint24(data, 560, p+15);
|
||||
uint32_t tempHumiMain = getint24(data, 560, p+18);
|
||||
uint32_t tempHumiRef1 = getint24(data, 560, p+21);
|
||||
uint32_t tempHumiRef2 = getint24(data, 560, p+24);
|
||||
uint32_t pressureMain = getint24(data, 560, p+27);
|
||||
uint32_t pressureRef1 = getint24(data, 560, p+30);
|
||||
uint32_t pressureRef2 = getint24(data, 560, p+33);
|
||||
int16_t ptraw = getint16(data, 560, p+38);
|
||||
#if 0
|
||||
Serial.printf( "External temp: tempMeasMain = %ld, tempMeasRef1 = %ld, tempMeasRef2 = %ld\n", tempMeasMain, tempMeasRef1, tempMeasRef2 );
|
||||
Serial.printf( "Rel Humidity: humidityMain = %ld, humidityRef1 = %ld, humidityRef2 = %ld\n", humidityMain, humidityRef1, humidityRef2 );
|
||||
Serial.printf( "Humid sensor: tempHumiMain = %ld, tempHumiRef1 = %ld, tempHumiRef2 = %ld\n", tempHumiMain, tempHumiRef1, tempHumiRef2 );
|
||||
Serial.printf( "Pressure sens: pressureMain = %ld, pressureRef1 = %ld, pressureRef2 = %ld\n", pressureMain, pressureRef1, pressureRef2 );
|
||||
#endif
|
||||
struct subframeBuffer *calibration = (struct subframeBuffer *)(sonde.si()->extra);
|
||||
// temp: 0xF8==bits 3..7 : we need refResistorlow/high, taylorT, polyT
|
||||
bool validExternalTemperature = calibration!=NULL && (calibration->valid & 0xF8) == 0xF8;
|
||||
|
||||
// humidity: bits 3..20 and 37..46. and bit 33 (variant)
|
||||
bool validHumidity = calibration!=NULL && (calibration->valid & 0x7FE2001FFFF8) == 0x7FE2001FFFF8;
|
||||
|
||||
// pressure: bits 33 and 37..42 (variant; x25..x2a: matrixP) /// CALIB_P is 0x7E200000000)
|
||||
bool validPressure = calibration!=NULL && (calibration->valid & CALIB_P)==CALIB_P && calibration->value.names.variant[7]=='P';
|
||||
|
||||
if ( validPressure ) {
|
||||
si->pressure = GetRAP( pressureMain, pressureRef1, pressureRef2, ptraw );
|
||||
Serial.printf("Pressure sensor = %f\n", si->pressure);
|
||||
}
|
||||
|
||||
if ( validExternalTemperature ) {
|
||||
si->temperature = GetRATemp( tempMeasMain, tempMeasRef1, tempMeasRef2,
|
||||
calibration->value.calT, calibration->value.taylorT, calibration->value.polyT );
|
||||
Serial.printf("External temperature = %f\n", si->temperature );
|
||||
}
|
||||
|
||||
if ( validHumidity && validExternalTemperature ) {
|
||||
si->tempRHSensor = GetRATemp( tempHumiMain, tempHumiRef1, tempHumiRef2,
|
||||
calibration->value.calTU, calibration->value.taylorTU, calibration->value.polyTrh );
|
||||
Serial.printf("Humidity Sensor temperature = %f\n", si->tempRHSensor );
|
||||
si->relativeHumidity = GetRAHumidity( humidityMain, humidityRef1, humidityRef2, si->tempRHSensor, si->temperature, si->pressure );
|
||||
Serial.printf("Relative humidity = %f\n", si->relativeHumidity );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}}
|
||||
p += len;
|
||||
Serial.println();
|
||||
}
|
||||
return crcok ? 0 : RX_ERROR;
|
||||
}
|
||||
void RS41::printRaw(uint8_t *data, int len)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
for(i=0; i<len; i++) {
|
||||
snprintf(buf, 3, "%02X", data[i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void RS41::bitsToBytes(uint8_t *bits, uint8_t *bytes, int len)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<len*4; i++) {
|
||||
bytes[i/8] = (bytes[i/8]<<1) | (bits[i]?1:0);
|
||||
}
|
||||
bytes[(i-1)/8] &= 0x0F;
|
||||
}
|
||||
|
||||
static unsigned char lookup[16] = {
|
||||
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
|
||||
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
|
||||
|
||||
static uint8_t reverse(uint8_t n) {
|
||||
return (lookup[n&0x0f] << 4) | lookup[n>>4];
|
||||
}
|
||||
|
||||
|
||||
static uint8_t scramble[64] = {150U,131U,62U,81U,177U,73U,8U,152U,50U,5U,89U,
|
||||
14U,249U,68U,198U,38U,33U,96U,194U,234U,121U,93U,109U,161U,
|
||||
84U,105U,71U,12U,220U,232U,92U,241U,247U,118U,130U,127U,7U,
|
||||
153U,162U,44U,147U,124U,48U,99U,245U,16U,46U,97U,208U,188U,
|
||||
180U,182U,6U,170U,244U,35U,120U,110U,59U,174U,191U,123U,76U,
|
||||
193U};
|
||||
|
||||
|
||||
int RS41::receive() {
|
||||
sx1278.setPayloadLength(RS41MAXLEN-8);
|
||||
int e = sx1278.receivePacketTimeout(1000, data+8);
|
||||
#if 1
|
||||
if(e) { /*Serial.println("TIMEOUT");*/ return RX_TIMEOUT; }
|
||||
|
||||
for(int i=0; i<RS41MAXLEN; i++) { data[i] = reverse(data[i]); }
|
||||
for(int i=0; i<RS41MAXLEN; i++) { data[i] = data[i] ^ scramble[i&0x3F]; }
|
||||
return decode41(data, RS41MAXLEN);
|
||||
#else
|
||||
// FAKE testing data
|
||||
SondeInfo *si = sonde.si();
|
||||
si->lat = 48;
|
||||
si->lon = -100;
|
||||
si->alt = 30000;
|
||||
si->vs = 3.4;
|
||||
si->validPos = 0x7f;
|
||||
si->validID = 1;
|
||||
strcpy(si->id, "A1234");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int RS41::waitRXcomplete() {
|
||||
// Currently not used. can be used for additinoal post-processing
|
||||
// (required for RS92 to avoid FIFO overrun in rx task)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// copy variant string to buf (max buflen chars; buflen should be 11
|
||||
// return 0 if subtype is available, -1 if not
|
||||
int RS41::getSubtype(char *buf, int buflen, SondeInfo *si) {
|
||||
struct subframeBuffer *sf = (struct subframeBuffer *)si->extra;
|
||||
if(!sf) return -1;
|
||||
if( ( (sf->valid>>0x21) &3) != 3 ) return -1; // or 1 instead of 3 for the first 8 chars only, as in autorx?
|
||||
if(buflen>11) buflen=11; // then buflen should be capped at 9 (8+trailing \0)
|
||||
strncpy(buf, sf->value.names.variant, buflen);
|
||||
buf[buflen-1]=0;
|
||||
if(*buf==0) return -1;
|
||||
Serial.printf("subframe valid: %x%08x; subtype=%s\n", (uint32_t)(sf->valid>>32), (uint32_t)sf->valid, buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RS41 rs41 = RS41();
|
73
RX_FSK/src/RS41.h
Normal file
73
RX_FSK/src/RS41.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* RS41.h
|
||||
* Functions for decoding RS41 sondes with SX127x chips
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef RS41_h
|
||||
#define RS41_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "Sonde.h"
|
||||
#include "DecoderBase.h"
|
||||
|
||||
/* Main class */
|
||||
class RS41 : public DecoderBase
|
||||
{
|
||||
private:
|
||||
uint32_t bits2val(const uint8_t *bits, int len);
|
||||
void printRaw(uint8_t *data, int len);
|
||||
void bitsToBytes(uint8_t *bits, uint8_t *bytes, int len);
|
||||
int decode41(byte *data, int maxlen);
|
||||
|
||||
#if 0
|
||||
#define B 8
|
||||
#define S 4
|
||||
uint8_t hamming_conf[ 7*B]; // 7*8=56
|
||||
uint8_t hamming_dat1[13*B]; // 13*8=104
|
||||
uint8_t hamming_dat2[13*B];
|
||||
|
||||
uint8_t block_conf[ 7*S]; // 7*4=28
|
||||
uint8_t block_dat1[13*S]; // 13*4=52
|
||||
uint8_t block_dat2[13*S];
|
||||
|
||||
uint8_t H[4][8] = // extended Hamming(8,4) particy check matrix
|
||||
{{ 0, 1, 1, 1, 1, 0, 0, 0},
|
||||
{ 1, 0, 1, 1, 0, 1, 0, 0},
|
||||
{ 1, 1, 0, 1, 0, 0, 1, 0},
|
||||
{ 1, 1, 1, 0, 0, 0, 0, 1}};
|
||||
uint8_t He[8] = { 0x7, 0xB, 0xD, 0xE, 0x8, 0x4, 0x2, 0x1}; // Spalten von H:
|
||||
#endif
|
||||
// 1-bit-error-Syndrome
|
||||
boolean initialized = false;
|
||||
|
||||
public:
|
||||
RS41();
|
||||
// New interface:
|
||||
// setup() is called when channel is activated (sets mode and frequency and activates receiver)
|
||||
int setup(float frequency, int type = 0);
|
||||
// processRXbyte is called by background task for each received byte
|
||||
// should be fast enough to not cause sx127x fifo buffer overflow
|
||||
// void processRXbyte(uint8_t data);
|
||||
// is called approx. 1x per second, may do some post-processing of received data
|
||||
// and update information in sonde data structure
|
||||
// returns infomration about sucess/error (for timers and for quality bar in display)
|
||||
int receive();
|
||||
int waitRXcomplete();
|
||||
//int receiveFrame();
|
||||
|
||||
static int getSubtype(char *buf, int buflen, SondeInfo *si);
|
||||
|
||||
int use_ecc = 1;
|
||||
};
|
||||
|
||||
extern RS41 rs41;
|
||||
|
||||
#endif
|
589
RX_FSK/src/RS92.cpp
Normal file
589
RX_FSK/src/RS92.cpp
Normal file
|
@ -0,0 +1,589 @@
|
|||
|
||||
/* RS92 decoder functions */
|
||||
#include "RS92.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "rsc.h"
|
||||
#include "Sonde.h"
|
||||
#include <SPIFFS.h>
|
||||
|
||||
// well...
|
||||
#include "rs92gps.h"
|
||||
|
||||
#define RS92_DEBUG 1
|
||||
|
||||
#if RS92_DEBUG
|
||||
#define RS92_DBG(x) x
|
||||
#else
|
||||
#define RS92_DBG(x)
|
||||
#endif
|
||||
|
||||
uint16_t *CRCTAB = NULL;
|
||||
|
||||
#define X2C_DIVR(a, b) ((b) != 0.0f ? (a)/(b) : (a))
|
||||
#define X2C_DIVL(a, b) ((a)/(b))
|
||||
static uint32_t X2C_LSH(uint32_t a, int32_t length, int32_t n)
|
||||
{
|
||||
uint32_t m;
|
||||
|
||||
m = 0;
|
||||
m = (length == 32) ? 0xFFFFFFFFl : (1 << length) - 1;
|
||||
if (n > 0) {
|
||||
if (n >= (int32_t)length)
|
||||
return 0;
|
||||
return (a << n) & m;
|
||||
}
|
||||
|
||||
if (n <= (int32_t)-length)
|
||||
return 0;
|
||||
return (a >> -n) & m;
|
||||
}
|
||||
|
||||
static void Gencrctab(void)
|
||||
{
|
||||
uint16_t j;
|
||||
uint16_t i;
|
||||
uint16_t crc;
|
||||
if(!CRCTAB) { CRCTAB=(uint16_t *)malloc(256*sizeof(uint16_t)); }
|
||||
for (i = 0U; i<=255U; i++) {
|
||||
crc = (uint16_t)(i*256U);
|
||||
for (j = 0U; j<=7U; j++) {
|
||||
if ((0x8000U & crc)) crc = X2C_LSH(crc,16,1)^0x1021U;
|
||||
else crc = X2C_LSH(crc,16,1);
|
||||
} /* end for */
|
||||
CRCTAB[i] = X2C_LSH(crc,16,-8)|X2C_LSH(crc,16,8);
|
||||
} /* end for */
|
||||
} /* end Gencrctab() */
|
||||
|
||||
|
||||
static byte data1[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
|
||||
static byte data2[512]={0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x10};
|
||||
static byte *dataptr=data1;
|
||||
|
||||
static uint8_t rxbitc;
|
||||
static int32_t asynst[10]={0};
|
||||
static uint16_t rxbyte;
|
||||
int rxp=0;
|
||||
|
||||
static int haveNewFrame = 0;
|
||||
static int lastFrame = 0;
|
||||
static int headerDetected = 0;
|
||||
|
||||
decoderSetupCfg rs92SetupCfg = {
|
||||
.bitrate = 4800,
|
||||
.rx_cfg = 0x1E,
|
||||
.sync_cfg = 0x70,
|
||||
.sync_len = 2,
|
||||
.sync_data = (const uint8_t *)"\x66\x65",
|
||||
.preamble_cfg = 0xA8,
|
||||
};
|
||||
|
||||
int RS92::setup(float frequency, int /*type*/)
|
||||
{
|
||||
#if RS92_DEBUG
|
||||
Serial.println("Setup sx1278 for RS92 sonde");
|
||||
#endif
|
||||
if(!initialized) {
|
||||
Gencrctab();
|
||||
initrsc();
|
||||
// not here for now.... get_eph("/brdc.19n");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
if(sx1278.ON()!=0) {
|
||||
RS92_DBG(Serial.println("Setting SX1278 power on FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(DecoderBase::setup(rs92SetupCfg, sonde.config.rs92.rxbw, sonde.config.rs92.rxbw)!=0) {
|
||||
return 1;
|
||||
}
|
||||
#if 0
|
||||
if(sx1278.setFSK()!=0) {
|
||||
RS92_DBG(Serial.println("Setting FSJ mode FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setBitrate(4800)!=0) {
|
||||
RS92_DBG(Serial.println("Setting bitrate 4800bit/s FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#if RS92_DEBUG
|
||||
float br = sx1278.getBitrate();
|
||||
Serial.print("Exact bitrate is ");
|
||||
Serial.println(br);
|
||||
#endif
|
||||
if(sx1278.setAFCBandwidth(sonde.config.rs92.rxbw)!=0) {
|
||||
RS92_DBG(Serial.printf("Setting AFC bandwidth %d Hz FAILED", sonde.config.rs92.rxbw));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setRxBandwidth(sonde.config.rs92.rxbw)!=0) {
|
||||
RS92_DBG(Serial.printf("Setting RX bandwidth to %d Hz FAILED", sonde.config.rs92.rxbw));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Enable auto-AFC, auto-AGC, RX Trigger by preamble
|
||||
if(sx1278.setRxConf(0x1E)!=0) {
|
||||
RS92_DBG(Serial.println("Setting RX Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// Set autostart_RX to 01, preamble 0, SYNC detect==on, syncsize=3 (==4 byte
|
||||
//char header[] = "0110.0101 0110.0110 1010.0101 1010.1010";
|
||||
|
||||
//const char *SYNC="\x10\xB6\xCA\x11\x22\x96\x12\xF8";
|
||||
//const char *SYNC="\x08\x6D\x53\x88\x44\x69\x48\x1F";
|
||||
// was 0x57
|
||||
//const char *SYNC="\x99\x9A";
|
||||
// version 1, working with continuous RX
|
||||
const char *SYNC="\x66\x65";
|
||||
if(sx1278.setSyncConf(0x70, 2, (const uint8_t *)SYNC)!=0) {
|
||||
RS92_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
if(sx1278.setPreambleDetect(0xA8)!=0) {
|
||||
RS92_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// version 2, with per-packet rx start, untested
|
||||
// header is 2a 10 65, i.e. with lsb first
|
||||
// 0 0101 0100 1 0 0000 1000 1 0 1010 0110 1
|
||||
// 10 10011001 10011010 01 10 10101010 01101010 01 10 01100110 10010110 01
|
||||
// preamble 0x6A 0x66 0x6A
|
||||
// i.e. preamble detector on (0x80), preamble detector size 1 (0x00), preample chip errors??? (0x0A)
|
||||
// after 2a2a2a2a2a1065
|
||||
if(sx1278.setPreambleDetect(0xA8)!=0) {
|
||||
RS92_DBG(Serial.println("Setting PreambleDetect FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// sync config: ato restart (01), preamble polarity AA (0), sync on (1), resevered (0), syncsize 2+1 (010) => 0x52
|
||||
const char *SYNC="\x6A\x66\x69";
|
||||
if(sx1278.setSyncConf(0x52, 3, (const uint8_t *)SYNC)!=0) {
|
||||
RS92_DBG(Serial.println("Setting SYNC Config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
// payload length is ((240 - 7)*10 +6)/8 = 292
|
||||
#endif
|
||||
|
||||
// Packet config 1: fixed len, no mancecer, no crc, no address filter
|
||||
// Packet config 2: packet mode, no home ctrl, no beackn, msb(packetlen)=0)
|
||||
if(sx1278.setPacketConfig(0x08, 0x40)!=0) {
|
||||
RS92_DBG(Serial.println("Setting Packet config FAILED"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
Serial.print("RS92: setting RX frequency to ");
|
||||
Serial.println(frequency);
|
||||
int res = sx1278.setFrequency(frequency);
|
||||
sx1278.clearIRQFlags();
|
||||
|
||||
// enable RX
|
||||
sx1278.setPayloadLength(0); // infinite for now...
|
||||
//sx1278.setPayloadLength(292);
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
|
||||
#if RS92_DEBUG
|
||||
RS92_DBG(Serial.println("Setting SX1278 config for RS92 finished\n"); Serial.println());
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t RS92::bits2val(const uint8_t *bits, int len) {
|
||||
uint32_t val = 0;
|
||||
for (int j = 0; j < len; j++) {
|
||||
val |= (bits[j] << (len-1-j));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
RS92::RS92() {
|
||||
}
|
||||
|
||||
/* RS92 reed solomon decoder, from dxlAPRS
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
static char crcrs(const byte frame[], uint32_t frame_len,
|
||||
int32_t from, int32_t to)
|
||||
{
|
||||
uint16_t crc;
|
||||
int32_t i;
|
||||
int32_t tmp;
|
||||
crc = 0xFFFFU;
|
||||
tmp = to-3L;
|
||||
i = from;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
crc = X2C_LSH(crc,16,-8)^CRCTAB[(uint32_t)((crc^(uint16_t)(uint8_t)frame[i])&0xFFU)];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
return frame[to-1L]==(char)crc && frame[to-2L]==(char)X2C_LSH(crc,
|
||||
16,-8);
|
||||
} /* end crcrs() */
|
||||
|
||||
static int32_t getint32(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
uint32_t n;
|
||||
uint32_t i;
|
||||
n = 0UL;
|
||||
for (i = 3UL;; i--) {
|
||||
n = n*256UL+(uint32_t)(uint8_t)frame[p+i];
|
||||
if (i==0UL) break;
|
||||
} /* end for */
|
||||
return (int32_t)n;
|
||||
} /* end getint32() */
|
||||
|
||||
|
||||
static uint32_t getcard16(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
return (uint32_t)(uint8_t)frame[p]+256UL*(uint32_t)(uint8_t)
|
||||
frame[p+1UL];
|
||||
} /* end getcard16() */
|
||||
|
||||
|
||||
static int32_t getint16(const byte frame[], uint32_t frame_len,
|
||||
uint32_t p)
|
||||
{
|
||||
uint32_t n;
|
||||
n = (uint32_t)(uint8_t)frame[p]+256UL*(uint32_t)(uint8_t)
|
||||
frame[p+1UL];
|
||||
if (n>=32768UL) return (int32_t)(n-65536UL);
|
||||
return (int32_t)n;
|
||||
} /* end getint16() */
|
||||
|
||||
static void wgs84r(double x, double y, double z,
|
||||
double * lat, double * long0,
|
||||
double * heig)
|
||||
{
|
||||
double sl;
|
||||
double ct;
|
||||
double st;
|
||||
double t;
|
||||
double rh;
|
||||
double xh;
|
||||
double h;
|
||||
h = x*x+y*y;
|
||||
if (h>0.0) {
|
||||
rh = (double)sqrt((float)h);
|
||||
xh = x+rh;
|
||||
*long0 = atang2(xh, y)*2.0;
|
||||
if (*long0>3.1415926535898) *long0 = *long0-6.2831853071796;
|
||||
t = (double)atan((float)(X2C_DIVL(z*1.003364089821,
|
||||
rh)));
|
||||
st = (double)sin((float)t);
|
||||
ct = (double)cos((float)t);
|
||||
*lat = (double)atan((float)
|
||||
(X2C_DIVL(z+4.2841311513312E+4*st*st*st,
|
||||
rh-4.269767270718E+4*ct*ct*ct)));
|
||||
sl = (double)sin((float)*lat);
|
||||
*heig = X2C_DIVL(rh,(double)cos((float)*lat))-(double)(X2C_DIVR(6.378137E+6f,
|
||||
sqrt((float)(1.0-6.6943799901413E-3*sl*sl))));
|
||||
}
|
||||
else {
|
||||
*lat = 0.0;
|
||||
*long0 = 0.0;
|
||||
*heig = 0.0;
|
||||
}
|
||||
/* lat:=atan(z/(rh*(1.0 - E2))); */
|
||||
/* heig:=sqrt(h + z*z) - EARTHA; */
|
||||
} /* end wgs84r() */
|
||||
#endif
|
||||
|
||||
|
||||
static int32_t reedsolomon92(uint8_t *buf, uint32_t buf_len)
|
||||
{
|
||||
uint32_t i;
|
||||
int32_t res;
|
||||
uint8_t b[256];
|
||||
uint32_t eraspos[24];
|
||||
for (i = 0UL; i<=255UL; i++) {
|
||||
b[i] = 0;
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=209UL; i++) {
|
||||
b[230UL-i] = buf[i+6UL];
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=23UL; i++) {
|
||||
b[254UL-i] = buf[i+216UL];
|
||||
} /* end for */
|
||||
res = decodersc((char *)b, eraspos, 0L);
|
||||
if (res>0L && res<=12L) {
|
||||
for (i = 0UL; i<=209UL; i++) {
|
||||
buf[i+6UL] = b[230UL-i];
|
||||
} /* end for */
|
||||
for (i = 0UL; i<=23UL; i++) {
|
||||
buf[i+216UL] = b[254UL-i];
|
||||
} /* end for */
|
||||
}
|
||||
return res;
|
||||
} /* end reedsolomon92() */
|
||||
|
||||
void printRaw(uint8_t *data, int len)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
for(i=0; i<len; i++) {
|
||||
snprintf(buf, 3, "%02X", data[i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void RS92::decodeframe92(uint8_t *data)
|
||||
{
|
||||
//uint32_t gpstime;
|
||||
//uint32_t flen;
|
||||
//uint32_t j;
|
||||
int32_t corr;
|
||||
corr = reedsolomon92(data, 301ul);
|
||||
//int calok;
|
||||
//int mesok;
|
||||
//uint32_t calibok;
|
||||
lastFrame = (dataptr==data1)?1:2;
|
||||
Serial.printf("rs corr is %d --- data:%p data1:%p data2:%p lastframe=%d\n", corr, data, data1, data2, lastFrame);
|
||||
dataptr = (dataptr==data1)?data2:data1;
|
||||
//print_frame(data, 240);
|
||||
#if 0
|
||||
/* from sondemod*/
|
||||
int p=6;
|
||||
while(1) {
|
||||
uint8_t typ = data[p];
|
||||
if(typ==0xff) break;
|
||||
++p;
|
||||
int len = ((uint32_t)data[p])*2 + 2;
|
||||
Serial.printf("type %c: len=%d\n", typ, len);
|
||||
//printRaw(data+p, len+2);
|
||||
if(len>240) {
|
||||
Serial.print("RS92 frame too long: ");
|
||||
Serial.println(len);
|
||||
break;
|
||||
}
|
||||
++p;
|
||||
j=0;
|
||||
uint16_t crc = 0xFFFF;
|
||||
while(j<len) {
|
||||
if(j < len-2) {
|
||||
for(int ic = 0; ic<=7; ic++) {
|
||||
if (((0x8000&crc)!=0) != ( ((1<<(7-ic))&data[p])!=0 )) {
|
||||
crc <<= 1;
|
||||
crc ^= 0x1021;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
++p;
|
||||
++j;
|
||||
if(p>240) {
|
||||
Serial.println("eof");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ( (((uint8_t)(crc&0xff)) != data[p-2]) || (((uint8_t)(crc>>8)) != data[p-1])) {
|
||||
Serial.printf("************ crc error: expected %04x\n",crc);
|
||||
continue;
|
||||
}
|
||||
switch(typ) {
|
||||
case 'e':
|
||||
Serial.println("cal ");
|
||||
//docalib(sf, 256, objname, 9, &contextr9, &mhz, &frameno);
|
||||
// ...
|
||||
break;
|
||||
case 'i':
|
||||
if(calok && calibok==0xffffffff) {
|
||||
//domes(sf, 256, &hp, &hyg, &temp)
|
||||
mesok = 1;
|
||||
}
|
||||
break;
|
||||
case 'g':
|
||||
Serial.println("gps ");
|
||||
if(1||calok) {
|
||||
//dogps(data+p-len, 256, &contextr9, &contextr9.timems, &gpstime);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
Serial.println("data "); break;
|
||||
if(data[p+2]!=3) Serial.println("aux ");
|
||||
// ..
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} /* end decodeframe92() */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void RS92::printRaw(uint8_t *data, int len)
|
||||
{
|
||||
char buf[3];
|
||||
int i;
|
||||
for(i=0; i<len; i++) {
|
||||
snprintf(buf, 3, "%02X", data[i]);
|
||||
Serial.print(buf);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
void RS92::stobyte92(uint8_t b)
|
||||
{
|
||||
dataptr[rxp] = b;
|
||||
if(rxp>=5 || b=='*') rxp++; else rxp=0;
|
||||
if(rxp==6) { // header detected
|
||||
headerDetected = 1;
|
||||
}
|
||||
if(rxp>=240) { // frame complete... (240 byte)
|
||||
rxp=0;
|
||||
//printRaw(data, 240);
|
||||
decodeframe92(dataptr);
|
||||
haveNewFrame = 1;
|
||||
}
|
||||
} /* end stobyte92() */
|
||||
|
||||
|
||||
uint32_t rxdata;
|
||||
bool rxsearching=true;
|
||||
|
||||
// search for
|
||||
// 101001100110011010011010011001100110100110101010100110101001
|
||||
// 1010011001100110100110100110 0110.0110 1001.1010 1010.1001 1010.1001 => 0x669AA9A9
|
||||
void RS92::process8N1data(uint8_t dt)
|
||||
{
|
||||
for(int i=0; i<8; i++) {
|
||||
uint8_t d = (dt&0x80)?1:0;
|
||||
rxdata = (rxdata<<1) | d;
|
||||
if((rxbitc&1)==1) { rxbyte = (rxbyte>>1) + (d<<9); } // mancester decoded data
|
||||
dt <<= 1;
|
||||
//
|
||||
if(rxsearching) {
|
||||
if(rxdata == 0x669AA9A9) {
|
||||
rxsearching = false;
|
||||
rxbitc = 0;
|
||||
rxp = 6;
|
||||
int rssi=sx1278.getRSSI();
|
||||
int fei=sx1278.getFEI();
|
||||
int afc=sx1278.getAFC();
|
||||
Serial.print("Test: RSSI="); Serial.print(rssi);
|
||||
Serial.print(" FEI="); Serial.print(fei);
|
||||
Serial.print(" AFC="); Serial.println(afc);
|
||||
sonde.si()->rssi = rssi;
|
||||
sonde.si()->afc = afc;
|
||||
}
|
||||
} else {
|
||||
rxbitc = (rxbitc+1)%20;
|
||||
if(rxbitc == 0) { // got startbit, 8 data bit, stop bit
|
||||
//Serial.printf("%03x ",rxbyte);
|
||||
dataptr[rxp++] = (rxbyte>>1)&0xff;
|
||||
if(rxp==7 && dataptr[6] != 0x65) {
|
||||
Serial.printf("wrong start: %02x\n",dataptr[6]);
|
||||
rxsearching = true;
|
||||
}
|
||||
if(rxp>=240) {
|
||||
rxsearching = true;
|
||||
decodeframe92(dataptr);
|
||||
haveNewFrame = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process8N1dataOrig(uint8_t data)
|
||||
{
|
||||
// data contains 8 bits (after mancester encoding; 4 real bit), big endian
|
||||
for(int i=0; i<4; i++) {
|
||||
uint8_t d = (data&0x80)?1:0;
|
||||
data = data << 2;
|
||||
rxbyte = (rxbyte>>1) + (d<<8);
|
||||
int maxk = 0;
|
||||
int max0 = 0;
|
||||
for(int k = 0; k< 10; k++) {
|
||||
int n = asynst[k] - asynst[(k+1)%10];
|
||||
if(abs(n)>abs(max0)) {
|
||||
max0 = n;
|
||||
maxk = k;
|
||||
}
|
||||
}
|
||||
//Serial.printf("<%d,%d,%d>",max0,maxk,rxbitc);
|
||||
if(rxbitc == maxk) {
|
||||
if(max0<0) { rxbyte = rxbyte ^ 0xFF; }
|
||||
/////TODO stobyte92( rxbyte&0xff );
|
||||
}
|
||||
//Serial.printf("%d:",asynst[rxbitc]);
|
||||
if(d) {
|
||||
asynst[rxbitc] += (32767-asynst[rxbitc])/16;
|
||||
} else {
|
||||
asynst[rxbitc] -= (32767+asynst[rxbitc])/16;
|
||||
}
|
||||
//Serial.printf("%d ",asynst[rxbitc]);
|
||||
rxbitc = (rxbitc+1) % 10;
|
||||
}
|
||||
}
|
||||
|
||||
int RS92::receive() {
|
||||
unsigned long t0 = millis();
|
||||
Serial.printf("RS92::receive() start at %ld\n",t0);
|
||||
while( millis() - t0 < 1000 ) {
|
||||
uint8_t value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
if ( bitRead(value, 7) ) {
|
||||
Serial.println("FIFO full");
|
||||
}
|
||||
if ( bitRead(value, 4) ) {
|
||||
Serial.println("FIFO overflow");
|
||||
}
|
||||
if ( bitRead(value, 2) == 1 ) {
|
||||
Serial.println("FIFO: ready()");
|
||||
sx1278.clearIRQFlags();
|
||||
}
|
||||
if(bitRead(value, 6) == 0) { // while FIFO not empty
|
||||
byte data = sx1278.readRegister(REG_FIFO);
|
||||
//Serial.printf("%02x",data);
|
||||
process8N1data(data);
|
||||
value = sx1278.readRegister(REG_IRQ_FLAGS2);
|
||||
} else {
|
||||
if(headerDetected) {
|
||||
t0 = millis(); // restart timer... don't time out if header detected...
|
||||
headerDetected = 0;
|
||||
}
|
||||
if(haveNewFrame) {
|
||||
Serial.printf("RS92::receive(): new frame complete after %ldms\n", millis()-t0);
|
||||
haveNewFrame = 0;
|
||||
return RX_OK;
|
||||
}
|
||||
delay(2);
|
||||
}
|
||||
}
|
||||
Serial.printf("RS92::receive() timed out\n");
|
||||
return RX_TIMEOUT; // TODO RX_OK;
|
||||
}
|
||||
|
||||
#define RS92MAXLEN (240)
|
||||
int RS92::waitRXcomplete() {
|
||||
// called after complete...
|
||||
Serial.printf("decoding frame %d\n", lastFrame);
|
||||
print_frame(lastFrame==1?data1:data2, 240);
|
||||
|
||||
SondeData *si = &( (sonde.sondeList+rxtask.receiveSonde)->d );
|
||||
si->lat = gpx.lat;
|
||||
si->lon = gpx.lon;
|
||||
si->alt = gpx.alt;
|
||||
si->vs = gpx.vU;
|
||||
si->hs = gpx.vH;
|
||||
si->dir = gpx.vD;
|
||||
si->validPos = 0x3f;
|
||||
memcpy(si->id, gpx.id, 9);
|
||||
memcpy(si->ser, gpx.id, 9);
|
||||
si->validID = true;
|
||||
si->vframe = si->frame = gpx.frnr;
|
||||
si->sats = gpx.k;
|
||||
si->time = (gpx.gpssec/1000) + 86382 + gpx.week*604800 + 315878400UL;
|
||||
si->validTime = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RS92 rs92 = RS92();
|
92
RX_FSK/src/RS92.h
Normal file
92
RX_FSK/src/RS92.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* RS92.h
|
||||
* Functions for decoding RS92 sondes with SX127x chips
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef RS92_h
|
||||
#define RS92_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#include "DecoderBase.h"
|
||||
|
||||
|
||||
struct CONTEXTR9 {
|
||||
char calibdata[512];
|
||||
uint32_t calibok;
|
||||
char mesok;
|
||||
char posok;
|
||||
char framesent;
|
||||
double lat;
|
||||
double lon;
|
||||
double heig;
|
||||
double speed;
|
||||
double dir;
|
||||
double climb;
|
||||
double lastlat;
|
||||
double laslong;
|
||||
double lastalt;
|
||||
double lastspeed;
|
||||
double lastdir;
|
||||
double lastclb;
|
||||
float hrmsc;
|
||||
float vrmsc;
|
||||
double hp;
|
||||
double hyg;
|
||||
double temp;
|
||||
double ozontemp;
|
||||
double ozon;
|
||||
uint32_t goodsats;
|
||||
uint32_t timems;
|
||||
uint32_t framenum;
|
||||
};
|
||||
|
||||
|
||||
/* Main class */
|
||||
class RS92 : public DecoderBase
|
||||
{
|
||||
private:
|
||||
void process8N1data(uint8_t data);
|
||||
void stobyte92(uint8_t byte);
|
||||
void decodeframe92(uint8_t *data);
|
||||
uint32_t bits2val(const uint8_t *bits, int len);
|
||||
void printRaw(uint8_t *data, int len);
|
||||
int bitsToBytes(uint8_t *bits, uint8_t *bytes, int len);
|
||||
int decode92(byte *data, int maxlen);
|
||||
|
||||
uint8_t hamming_conf[ 7*8]; // 7*8=56
|
||||
uint8_t hamming_dat1[13*8]; // 13*8=104
|
||||
uint8_t hamming_dat2[13*8];
|
||||
|
||||
uint8_t block_conf[ 7*4]; // 7*4=28
|
||||
uint8_t block_dat1[13*4]; // 13*4=52
|
||||
uint8_t block_dat2[13*4];
|
||||
|
||||
uint8_t H[4][8] = // extended Hamming(8,4) particy check matrix
|
||||
{{ 0, 1, 1, 1, 1, 0, 0, 0},
|
||||
{ 1, 0, 1, 1, 0, 1, 0, 0},
|
||||
{ 1, 1, 0, 1, 0, 0, 1, 0},
|
||||
{ 1, 1, 1, 0, 0, 0, 0, 1}};
|
||||
uint8_t He[8] = { 0x7, 0xB, 0xD, 0xE, 0x8, 0x4, 0x2, 0x1}; // Spalten von H:
|
||||
// 1-bit-error-Syndrome
|
||||
boolean initialized = false;
|
||||
|
||||
public:
|
||||
RS92();
|
||||
int setup(float frequency, int type = 0);
|
||||
int receive();
|
||||
int waitRXcomplete();
|
||||
|
||||
int use_ecc = 1;
|
||||
};
|
||||
|
||||
extern RS92 rs92;
|
||||
|
||||
#endif
|
886
RX_FSK/src/SX1278FSK.cpp
Normal file
886
RX_FSK/src/SX1278FSK.cpp
Normal file
|
@ -0,0 +1,886 @@
|
|||
/*
|
||||
* Functions for using SX127x in FSK mode (mainly receive)
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* Partially based on the SX1278 libraray for managing Semtech modules
|
||||
* Copyright (C) 2015 Wireless Open Source
|
||||
* http://wirelessopensource.com
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#include "SX1278FSK.h"
|
||||
#include "SPI.h"
|
||||
#include "Sonde.h"
|
||||
#include "Display.h"
|
||||
|
||||
|
||||
#define SPI_MUTEX_LOCK() \
|
||||
do \
|
||||
{ \
|
||||
} while (xSemaphoreTake(_lock, portMAX_DELAY) != pdPASS)
|
||||
#define SPI_MUTEX_UNLOCK() xSemaphoreGive(_lock)
|
||||
|
||||
SX1278FSK::SX1278FSK() {}
|
||||
|
||||
void SX1278FSK::setup(xSemaphoreHandle lock)
|
||||
{
|
||||
_lock = lock;
|
||||
Serial.println("Setup sx1278");
|
||||
if(_lock) SPI_MUTEX_LOCK();
|
||||
digitalWrite(sonde.config.sx1278_ss, HIGH);
|
||||
pinMode(sonde.config.sx1278_ss, OUTPUT);
|
||||
Serial.printf("Configuing SX1278FSK SPI with miso=%d, mosi=%d, sck=%d, ss=%d\n", sonde.config.sx1278_miso,
|
||||
sonde.config.sx1278_mosi, sonde.config.sx1278_sck, sonde.config.sx1278_ss);
|
||||
SPI.begin(sonde.config.sx1278_sck, sonde.config.sx1278_miso, sonde.config.sx1278_mosi, -1); // no hardware CS
|
||||
// was: SPI.begin();
|
||||
|
||||
//Set most significant bit first
|
||||
SPI.setBitOrder(MSBFIRST);
|
||||
//Divide the clock frequency
|
||||
SPI.setClockDivider(SPI_CLOCK_DIV2);
|
||||
//Set data mode
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
if(_lock) SPI_MUTEX_UNLOCK();
|
||||
};
|
||||
|
||||
|
||||
static SPISettings spiset = SPISettings(10000000L, MSBFIRST, SPI_MODE0);
|
||||
|
||||
/*
|
||||
Function: Turns the module ON.
|
||||
Returns: 0 on success, 1 otherwise
|
||||
*/
|
||||
uint8_t SX1278FSK::ON()
|
||||
{
|
||||
uint8_t state = 2;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'ON'"));
|
||||
#endif
|
||||
|
||||
// Set Maximum Over Current Protection
|
||||
state = setMaxCurrent(0x1B);
|
||||
if( state == 0 )
|
||||
{
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("## Setting ON with maximum current supply ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// set FSK mode
|
||||
state = setFSK();
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Turn the module OFF.
|
||||
Returns: Nothing
|
||||
*/
|
||||
void SX1278FSK::OFF()
|
||||
{
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'OFF'"));
|
||||
#endif
|
||||
|
||||
//SPI.end();
|
||||
#if 0
|
||||
// Powering the module
|
||||
pinMode(SX1278_SS,OUTPUT);
|
||||
digitalWrite(SX1278_SS,LOW);
|
||||
#endif
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("## Setting OFF ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Reads the indicated register.
|
||||
Returns: The content of the register
|
||||
Parameters:
|
||||
address: address register to read from
|
||||
*/
|
||||
byte SX1278FSK::readRegister(byte address)
|
||||
{
|
||||
byte value = 0x00;
|
||||
|
||||
if(_lock) SPI_MUTEX_LOCK();
|
||||
digitalWrite(sonde.config.sx1278_ss,LOW);
|
||||
SPI.beginTransaction(spiset);
|
||||
|
||||
//delay(1);
|
||||
bitClear(address, 7); // Bit 7 cleared to write in registers
|
||||
SPI.transfer(address);
|
||||
value = SPI.transfer(0x00);
|
||||
SPI.endTransaction();
|
||||
digitalWrite(sonde.config.sx1278_ss,HIGH);
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
if(address!=0x3F) {
|
||||
Serial.print(F("## Reading: ##\t"));
|
||||
Serial.print(F("Register "));
|
||||
Serial.print(address, HEX);
|
||||
Serial.print(F(": "));
|
||||
Serial.print(value, HEX);
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
if(_lock) SPI_MUTEX_UNLOCK();
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Writes on the indicated register.
|
||||
Returns: Nothing
|
||||
Parameters:
|
||||
address: address register to write in
|
||||
data: value to write in the register
|
||||
*/
|
||||
void SX1278FSK::writeRegister(byte address, byte data)
|
||||
{
|
||||
if(_lock) SPI_MUTEX_LOCK();
|
||||
digitalWrite(sonde.config.sx1278_ss,LOW);
|
||||
SPI.beginTransaction(spiset);
|
||||
|
||||
//delay(1);
|
||||
bitSet(address, 7); // Bit 7 set to read from registers
|
||||
SPI.transfer(address);
|
||||
SPI.transfer(data);
|
||||
SPI.endTransaction();
|
||||
digitalWrite(sonde.config.sx1278_ss,HIGH);
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Writing: ##\t"));
|
||||
Serial.print(F("Register "));
|
||||
bitClear(address, 7);
|
||||
Serial.print(address, HEX);
|
||||
Serial.print(F(": "));
|
||||
Serial.print(data, HEX);
|
||||
Serial.println();
|
||||
#endif
|
||||
if(_lock) SPI_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: Clears the IRQ flags
|
||||
*
|
||||
* Configuration registers are accessed through the SPI interface.
|
||||
* Registers are readable in all device mode including Sleep. However, they
|
||||
* should be written only in Sleep and Stand-by modes.
|
||||
*
|
||||
* Returns: Nothing
|
||||
*/
|
||||
void SX1278FSK::clearIRQFlags()
|
||||
{
|
||||
#if 0
|
||||
byte st0;
|
||||
// Save the previous status
|
||||
st0 = readRegister(REG_OP_MODE);
|
||||
// Stdby mode to write in registers
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
|
||||
#endif
|
||||
// FSK mode flags1 register
|
||||
writeRegister(REG_IRQ_FLAGS1, 0xFF);
|
||||
// FSK mode flags2 register
|
||||
writeRegister(REG_IRQ_FLAGS2, 0xFF);
|
||||
#if 0
|
||||
// Getting back to previous status
|
||||
if(st0 != FSK_STANDBY_MODE) {
|
||||
writeRegister(REG_OP_MODE, st0);
|
||||
}
|
||||
#endif
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("## FSK flags cleared ##"));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Sets the module in FSK mode.
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
*/
|
||||
uint8_t SX1278FSK::setFSK()
|
||||
{
|
||||
uint8_t state = 2;
|
||||
byte st0;
|
||||
//byte config1;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'setFSK'"));
|
||||
#endif
|
||||
|
||||
writeRegister(REG_OP_MODE, FSK_SLEEP_MODE); // Sleep mode (mandatory to change mode)
|
||||
// If we are in LORA mode, above line activate Sleep mode, but does not change mode to FSK
|
||||
// as mode change is only allowed in sleep mode. Next line changes to FSK
|
||||
writeRegister(REG_OP_MODE, FSK_SLEEP_MODE);
|
||||
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); // FSK standby mode
|
||||
|
||||
//writeRegister(REG_FIFO_THRESH, 0x80); // condition to start packet tx
|
||||
//config1 = readRegister(REG_SYNC_CONFIG);
|
||||
//config1 = config1 & B00111111;
|
||||
//writeRegister(REG_SYNC_CONFIG,config1);
|
||||
|
||||
delay(100);
|
||||
|
||||
st0 = readRegister(REG_OP_MODE); // Reading config mode
|
||||
if( st0 == FSK_STANDBY_MODE )
|
||||
{ // FSK mode
|
||||
state = 0;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("## FSK set with success ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
} else { // LoRa mode
|
||||
state = 1;
|
||||
Serial.println( st0 );
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("** There has been an error while setting FSK **"));
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/* Function: Sets FSK bitrate
|
||||
* Returns: 0 for success, >0 in case of error
|
||||
* Parameters: bps: requested bitrate
|
||||
* (raw data rate, for Mancester encoding, the effective bitrate is bps/2)
|
||||
*/
|
||||
|
||||
uint8_t SX1278FSK::setBitrate(float bps)
|
||||
{
|
||||
// TODO: Check if FSK mode is active
|
||||
|
||||
// check if bitrate is allowed allowed bitrate
|
||||
if((bps < 1200) || (bps > 300000)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// set mode to FSK STANDBY
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
|
||||
|
||||
// set bit rate
|
||||
uint16_t bitRate = (SX127X_CRYSTAL_FREQ * 1.0) / bps;
|
||||
writeRegister(REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8);
|
||||
writeRegister(REG_BITRATE_LSB, (bitRate & 0x00FF));
|
||||
|
||||
// also set fractional part
|
||||
uint16_t fracRate = (SX127X_CRYSTAL_FREQ * 16.0) / bps - bitRate * 16 + 0.5;
|
||||
writeRegister(REG_BIT_RATE_FRAC, fracRate&0x0F);
|
||||
return 0;
|
||||
}
|
||||
/* Function: Gets configured bitrate
|
||||
* Returns bitrate in bit/second
|
||||
*/
|
||||
float SX1278FSK::getBitrate()
|
||||
{
|
||||
uint8_t fmsb = readRegister(REG_BITRATE_MSB);
|
||||
uint8_t flsb = readRegister(REG_BITRATE_LSB);
|
||||
uint8_t ffrac = readRegister(REG_BIT_RATE_FRAC) & 0x0F;
|
||||
return SX127X_CRYSTAL_FREQ / ( (fmsb<<8) + flsb + ffrac / 16.0 );
|
||||
}
|
||||
|
||||
//typedef struct rxbwset { float bw; uint8_t mant; uint8_t rxp; } st_rxbwsettings;
|
||||
|
||||
uint8_t SX1278FSK::setRxBandwidth(float bw)
|
||||
{
|
||||
// TODO: Check if in FSK mode
|
||||
//
|
||||
if(bw<2600 || bw>250000) { return 1; /* invalid */ }
|
||||
|
||||
uint8_t rxbwexp = 1;
|
||||
bw = SX127X_CRYSTAL_FREQ / bw / 8;
|
||||
while(bw>31) { rxbwexp++; bw/=2.0; }
|
||||
uint8_t rxbwmant = bw<17?0 : bw<21? 1:2;
|
||||
|
||||
// set mode to FSK STANDBY
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
|
||||
|
||||
writeRegister(REG_RX_BW, rxbwexp | (rxbwmant<<3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
float SX1278FSK::getRxBandwidth()
|
||||
{
|
||||
uint8_t rxbw = readRegister(REG_RX_BW);
|
||||
uint8_t rxbwexp = rxbw&0x07;
|
||||
uint8_t rxbwmant = (rxbw>>3)&0x03;
|
||||
rxbwmant = 16 + 4*rxbwmant;
|
||||
return SX127X_CRYSTAL_FREQ / ( rxbwmant << (rxbwexp+2));
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::setAFCBandwidth(float bw)
|
||||
{
|
||||
// TODO: Check if in FSK mode
|
||||
//
|
||||
if(bw<2600 || bw>250000) { return 1; /* invalid */ }
|
||||
|
||||
uint8_t rxbwexp = 1;
|
||||
bw = SX127X_CRYSTAL_FREQ / bw / 8;
|
||||
while(bw>31) { rxbwexp++; bw/=2.0; }
|
||||
uint8_t rxbwmant = bw<17?0 : bw<21? 1:2;
|
||||
|
||||
// set mode to FSK STANDBY
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
|
||||
|
||||
writeRegister(REG_AFC_BW, rxbwexp | (rxbwmant<<3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
float SX1278FSK::getAFCBandwidth()
|
||||
{
|
||||
uint8_t rxbw = readRegister(REG_AFC_BW);
|
||||
uint8_t rxbwexp = rxbw&0x07;
|
||||
uint8_t rxbwmant = (rxbw>>3)&0x03;
|
||||
rxbwmant = 16 + 4*rxbwmant;
|
||||
return SX127X_CRYSTAL_FREQ / ( rxbwmant << (rxbwexp+2));
|
||||
}
|
||||
|
||||
|
||||
uint8_t SX1278FSK::setFrequency(float freq) {
|
||||
|
||||
// set mode to FSK STANDBY
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE);
|
||||
freq += sonde.config.freqofs; // manual frequency correction
|
||||
|
||||
uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ;
|
||||
writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16);
|
||||
writeRegister(REG_FRF_MID, (frf&0x00ff00)>>8);
|
||||
writeRegister(REG_FRF_LSB, (frf&0x0000ff));
|
||||
return 0;
|
||||
}
|
||||
|
||||
float SX1278FSK::getFrequency() {
|
||||
uint8_t fmsb = readRegister(REG_FRF_MSB);
|
||||
uint8_t fmid = readRegister(REG_FRF_MID);
|
||||
uint8_t flsb = readRegister(REG_FRF_LSB);
|
||||
return ((fmsb<<16)|(fmid<<8)|flsb) * 1.0 / (1<<19) * SX127X_CRYSTAL_FREQ;
|
||||
}
|
||||
|
||||
|
||||
static int gaintab[]={-999,0,-6,-12,-24,-36,-48,-999};
|
||||
int SX1278FSK::getLNAGain() {
|
||||
int gain = (readRegister(REG_LNA)>>5)&0x07;
|
||||
return gaintab[gain];
|
||||
}
|
||||
uint8_t SX1278FSK::setLNAGain(int gain) {
|
||||
uint8_t g=1;
|
||||
while(gain<gaintab[g] && g<6) {g++; }
|
||||
writeRegister(REG_LNA, g<<5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::getRxConf() {
|
||||
return readRegister(REG_RX_CONFIG);
|
||||
}
|
||||
uint8_t SX1278FSK::setRxConf(uint8_t conf) {
|
||||
writeRegister(REG_RX_CONFIG, conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::setSyncConf(uint8_t conf, int len, const uint8_t *syncpattern) {
|
||||
int res=0;
|
||||
writeRegister(REG_SYNC_CONFIG, conf);
|
||||
if(len>8) return 1;
|
||||
for(int i=0; i<len; i++) {
|
||||
writeRegister(REG_SYNC_VALUE1+i, syncpattern[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::getSyncConf() {
|
||||
return sx1278.readRegister(REG_SYNC_CONFIG);
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::setPreambleDetect(uint8_t conf) {
|
||||
sx1278.writeRegister(REG_PREAMBLE_DETECT, conf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::getPreambleDetect() {
|
||||
return sx1278.readRegister(REG_PREAMBLE_DETECT);
|
||||
}
|
||||
|
||||
uint8_t SX1278FSK::setPacketConfig(uint8_t conf1, uint8_t conf2)
|
||||
{
|
||||
uint8_t ret=0;
|
||||
sx1278.writeRegister(REG_PACKET_CONFIG1, conf1);
|
||||
sx1278.writeRegister(REG_PACKET_CONFIG2, conf2);
|
||||
return ret;
|
||||
};
|
||||
uint16_t SX1278FSK::getPacketConfig() {
|
||||
uint8_t c1 = sx1278.readRegister(REG_PACKET_CONFIG1);
|
||||
uint8_t c2 = sx1278.readRegister(REG_PACKET_CONFIG2);
|
||||
return (c2<<8)|c1;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Gets the preamble length from the module.
|
||||
Returns: preamble length
|
||||
*/
|
||||
uint16_t SX1278FSK::getPreambleLength()
|
||||
{
|
||||
uint16_t p_length;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'getPreambleLength'"));
|
||||
#endif
|
||||
|
||||
p_length = readRegister(REG_PREAMBLE_MSB_FSK);
|
||||
p_length = (p_length<<8) | readRegister(REG_PREAMBLE_LSB_FSK);
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Preamble length configured is "));
|
||||
Serial.print(p_length, HEX);
|
||||
Serial.print(F(" ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
return p_length;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Sets the preamble length in the module
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
Parameters:
|
||||
l: length value to set as preamble length.
|
||||
*/
|
||||
uint8_t SX1278FSK::setPreambleLength(uint16_t l)
|
||||
{
|
||||
byte st0;
|
||||
int8_t state = 2;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'setPreambleLength'"));
|
||||
#endif
|
||||
|
||||
st0 = readRegister(REG_OP_MODE); // Save the previous status
|
||||
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); // Set Standby mode to write in registers
|
||||
// Storing MSB preamble length in FSK mode
|
||||
writeRegister(REG_PREAMBLE_MSB_FSK, l>>8);
|
||||
writeRegister(REG_PREAMBLE_LSB_FSK, l&0xFF);
|
||||
|
||||
state = 0;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Preamble length "));
|
||||
Serial.print(l, HEX);
|
||||
Serial.println(F(" has been successfully set ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
if(st0 != FSK_STANDBY_MODE) {
|
||||
writeRegister(REG_OP_MODE, st0); // Getting back to previous status
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Gets the payload length from the module.
|
||||
Returns: configured length; -1 on error
|
||||
*/
|
||||
int SX1278FSK::getPayloadLength()
|
||||
{
|
||||
int length;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'getPayloadLength'"));
|
||||
#endif
|
||||
length = readRegister(REG_PAYLOAD_LENGTH_FSK);
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Payload length configured is "));
|
||||
Serial.print(length);
|
||||
Serial.println(F(" ##"));
|
||||
#endif
|
||||
return length;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Sets the payload length from the module.
|
||||
Returns: 0 for ok, otherwise error
|
||||
// TODO: Larger than 255 bytes?
|
||||
*/
|
||||
uint8_t SX1278FSK::setPayloadLength(int len)
|
||||
{
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("Starting 'setPayloadLength'"));
|
||||
Serial.println(len);
|
||||
#endif
|
||||
uint8_t conf2 = readRegister(REG_PACKET_CONFIG2);
|
||||
conf2 = (conf2 & 0xF8) | ( (len>>8)&0x7 );
|
||||
writeRegister(REG_PACKET_CONFIG2, conf2);
|
||||
writeRegister(REG_PAYLOAD_LENGTH_FSK, len&0xFF);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Gets the current value of RSSI.
|
||||
Returns: RSSI value
|
||||
*/
|
||||
int16_t SX1278FSK::getRSSI()
|
||||
{
|
||||
int16_t RSSI;
|
||||
//int rssi_mean = 0;
|
||||
int total = 1;
|
||||
|
||||
/// FSK mode
|
||||
// get mean value of RSSI
|
||||
for(int i = 0; i < total; i++)
|
||||
{
|
||||
RSSI = readRegister(REG_RSSI_VALUE_FSK);
|
||||
//rssi_mean += _RSSI;
|
||||
}
|
||||
//rssi_mean = rssi_mean / total;
|
||||
//RSSI = rssi_mean;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 0)
|
||||
Serial.print(F("## RSSI value is "));
|
||||
Serial.print(RSSI);
|
||||
Serial.println(F(" ##"));
|
||||
#endif
|
||||
return RSSI;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Gets the current value of FEI (frequency error indication)
|
||||
Returns: FEI value in Hz
|
||||
*/
|
||||
int32_t SX1278FSK::getFEI()
|
||||
{
|
||||
int32_t FEI;
|
||||
int16_t regval = (readRegister(REG_FEI_MSB)<<8) | readRegister(REG_FEI_LSB);
|
||||
//Serial.printf("feireg: %04x\n", regval);
|
||||
FEI = (int32_t)(regval * SX127X_FSTEP);
|
||||
return FEI;
|
||||
}
|
||||
/*
|
||||
Function: Gets the current value of AFC (automated frequency correction)
|
||||
Returns: AFC value in Hz
|
||||
*/
|
||||
int32_t SX1278FSK::getAFC()
|
||||
{
|
||||
int32_t AFC;
|
||||
int16_t regval = (readRegister(REG_AFC_MSB)<<8) | readRegister(REG_AFC_LSB);
|
||||
//Serial.printf("afcreg: %04x\n", regval);
|
||||
AFC = (int32_t)(regval * SX127X_FSTEP);
|
||||
return AFC;
|
||||
}
|
||||
uint16_t SX1278FSK::getRawAFC() {
|
||||
return (readRegister(REG_AFC_MSB)<<8) | readRegister(REG_AFC_LSB);
|
||||
}
|
||||
void SX1278FSK::setRawAFC(uint16_t afc) {
|
||||
writeRegister(REG_AFC_MSB, afc>>8);
|
||||
writeRegister(REG_AFC_LSB, afc&0xFF);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Gets the current supply limit of the power amplifier, protecting battery chemistries.
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
Parameters:
|
||||
rate: value to compute the maximum current supply. Maximum current is 45+5*'rate' [mA]
|
||||
*/
|
||||
int SX1278FSK::getMaxCurrent()
|
||||
{
|
||||
int value;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'getMaxCurrent'"));
|
||||
#endif
|
||||
|
||||
value = readRegister(REG_OCP);
|
||||
|
||||
// extract only the OcpTrim value from the OCP register
|
||||
value &= B00011111;
|
||||
|
||||
if( value <= 15 ) {
|
||||
value = (45 + (5 * value));
|
||||
} else if( value <= 27 ) {
|
||||
value = (-30 + (10 * value));
|
||||
} else {
|
||||
value = 240;
|
||||
}
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Maximum current supply configured is "));
|
||||
Serial.print(value, DEC);
|
||||
Serial.println(F(" mA ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Limits the current supply of the power amplifier, protecting battery chemistries.
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
state = -1 --> Forbidden parameter value for this function
|
||||
Parameters:
|
||||
rate: value to compute the maximum current supply. Range: 0x00 to 0x1B. The
|
||||
Maximum current is:
|
||||
Imax = 45+5*OcpTrim [mA] if OcpTrim <= 15 (120 mA) /
|
||||
Imax = -30+10*OcpTrim [mA] if 15 < OcpTrim <= 27 (130 to 240 mA)
|
||||
Imax = 240mA for higher settings
|
||||
*/
|
||||
int8_t SX1278FSK::setMaxCurrent(uint8_t rate)
|
||||
{
|
||||
int8_t state = 2;
|
||||
byte st0;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'setMaxCurrent'"));
|
||||
#endif
|
||||
|
||||
// Maximum rate value = 0x1B, because maximum current supply = 240 mA
|
||||
if (rate > 0x1B)
|
||||
{
|
||||
state = -1;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("** Maximum current supply is 240 mA, "));
|
||||
Serial.println(F("so maximum parameter value must be 27 (DEC) or 0x1B (HEX) **"));
|
||||
Serial.println();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// Enable Over Current Protection
|
||||
rate |= B00100000;
|
||||
|
||||
//state = 1;
|
||||
st0 = readRegister(REG_OP_MODE); // Save the previous status
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); // Set FSK Standby mode to write in registers
|
||||
writeRegister(REG_OCP, rate); // Modifying maximum current supply
|
||||
if(st0 != FSK_STANDBY_MODE) {
|
||||
writeRegister(REG_OP_MODE, st0); // Getting back to previous status
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Function: Configures the module to receive information.
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
*/
|
||||
uint8_t SX1278FSK::receive()
|
||||
{
|
||||
uint8_t state = 1;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'receive'"));
|
||||
#endif
|
||||
// TODO: Is there anything else to be done?
|
||||
//
|
||||
writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
state = 0;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println(F("## Receiving FSK mode activated with success ##"));
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Configures the module to receive a packet
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
Parameters:
|
||||
wait: timeout in ms
|
||||
data: memory where to place received data
|
||||
*/
|
||||
uint8_t SX1278FSK::receivePacketTimeout(uint32_t wait, byte *data)
|
||||
{
|
||||
int di=0;
|
||||
uint8_t state = 2;
|
||||
unsigned long previous;
|
||||
byte value = 0x00;
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'receivePacketTimeout'"));
|
||||
#endif
|
||||
// set RX mode
|
||||
state = receive();
|
||||
if(state != 0) { return state; }
|
||||
|
||||
#if (SX1278FSK_debug_mode > 0)
|
||||
Serial.println(F("RX mode sucessfully activated"));
|
||||
#endif
|
||||
previous = millis();
|
||||
/// FSK mode
|
||||
value = readRegister(REG_IRQ_FLAGS2);
|
||||
byte ready=0;
|
||||
// while not yet done or FIFO not yet empty
|
||||
while( (!ready || bitRead(value,6)==0) && (millis() - previous < wait) )
|
||||
{
|
||||
if( bitRead(value,2)==1 ) ready=1;
|
||||
if( bitRead(value, 6) == 0 ) { // FIFO not empty
|
||||
data[di++] = readRegister(REG_FIFO);
|
||||
// It's a bit of a hack.... get RSSI and AFC (a) at beginning of packet and
|
||||
// for RS41 after about 0.5 sec. It might be more logical to put this decoder-specific
|
||||
// code into RS41.cpp instead of this file... (maybe TODO?)
|
||||
if(di==1 || di==290 ) {
|
||||
int rssi=getRSSI();
|
||||
int afc=getAFC();
|
||||
#if 0
|
||||
Serial.printf("Test(%d): RSSI=%d", rxtask.currentSonde, rssi/2);
|
||||
Serial.print("Test: AFC="); Serial.println(afc);
|
||||
#endif
|
||||
sonde.sondeList[rxtask.currentSonde].rssi = rssi;
|
||||
sonde.sondeList[rxtask.currentSonde].afc = afc;
|
||||
if(rxtask.receiveResult==0xFFFF)
|
||||
rxtask.receiveResult = RX_UPDATERSSI;
|
||||
//sonde.si()->rssi = rssi;
|
||||
//sonde.si()->afc = afc;
|
||||
}
|
||||
if(di>520) {
|
||||
// TODO
|
||||
Serial.println("TOO MUCH DATA");
|
||||
break;
|
||||
}
|
||||
previous = millis(); // reset timeout after receiving data
|
||||
} else {
|
||||
delay(10);
|
||||
}
|
||||
value = readRegister(REG_IRQ_FLAGS2);
|
||||
}
|
||||
if( !ready || bitRead(value, 6)==0) {
|
||||
#if 1&&(SX1278FSK_debug_mode > 0)
|
||||
Serial.println(F("** The timeout has expired **"));
|
||||
Serial.println();
|
||||
#endif
|
||||
sonde.si()->rssi = getRSSI();
|
||||
writeRegister(REG_OP_MODE, FSK_STANDBY_MODE); // Setting standby FSK mode
|
||||
return 1; // TIMEOUT
|
||||
}
|
||||
|
||||
#if (SX1278FSK_debug_mode > 0)
|
||||
Serial.println(F("## Packet received:"));
|
||||
for(unsigned int i = 0; i < di; i++)
|
||||
{
|
||||
Serial.print(data[i], HEX); // Printing payload
|
||||
Serial.print("|");
|
||||
}
|
||||
Serial.println(F(" ##"));
|
||||
#endif
|
||||
state = 0;
|
||||
// Initializing flags
|
||||
clearIRQFlags();
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
Function: It gets the temperature from the measurement block module.
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
*/
|
||||
uint8_t SX1278FSK::getTemp()
|
||||
{
|
||||
byte st0;
|
||||
uint8_t state = 2;
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.println();
|
||||
Serial.println(F("Starting 'getTemp'"));
|
||||
#endif
|
||||
|
||||
st0 = readRegister(REG_OP_MODE); // Save the previous status
|
||||
|
||||
if( _modem == LORA )
|
||||
{ // Allowing access to FSK registers while in LoRa standby mode
|
||||
writeRegister(REG_OP_MODE, LORA_STANDBY_FSK_REGS_MODE);
|
||||
}
|
||||
|
||||
state = 1;
|
||||
// Saving temperature value
|
||||
_temp = readRegister(REG_TEMP);
|
||||
if( _temp & 0x80 ) // The SNR sign bit is 1
|
||||
{
|
||||
// Invert and divide by 4
|
||||
_temp = ( ( ~_temp + 1 ) & 0xFF );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Divide by 4
|
||||
_temp = ( _temp & 0xFF );
|
||||
}
|
||||
|
||||
|
||||
#if (SX1278FSK_debug_mode > 1)
|
||||
Serial.print(F("## Temperature is: "));
|
||||
Serial.print(_temp);
|
||||
Serial.println(F(" ##"));
|
||||
Serial.println();
|
||||
#endif
|
||||
|
||||
if( _modem == LORA )
|
||||
{
|
||||
writeRegister(REG_OP_MODE, st0); // Getting back to previous status
|
||||
}
|
||||
|
||||
state = 0;
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: It prints the registers related to RX
|
||||
Returns: Integer that determines if there has been any error
|
||||
state = 2 --> The command has not been executed
|
||||
state = 1 --> There has been an error while executing the command
|
||||
state = 0 --> The command has been executed with no errors
|
||||
*/
|
||||
void SX1278FSK::showRxRegisters()
|
||||
{
|
||||
Serial.println(F("\n--- Show RX register ---"));
|
||||
|
||||
// variable
|
||||
byte reg;
|
||||
|
||||
for(int i = 0x00; i < 0x80; i++)
|
||||
{
|
||||
reg = readRegister(i);
|
||||
Serial.print(F("Reg 0x"));
|
||||
Serial.print(i, HEX);
|
||||
Serial.print(F(":"));
|
||||
Serial.print(reg, HEX);
|
||||
Serial.println();
|
||||
delay(100);
|
||||
}
|
||||
|
||||
Serial.println(F("------------------------"));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
xSemaphoreHandle globalLock =xSemaphoreCreateMutex();
|
||||
SX1278FSK sx1278 = SX1278FSK();
|
280
RX_FSK/src/SX1278FSK.h
Normal file
280
RX_FSK/src/SX1278FSK.h
Normal file
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
* Functions for using SX127x in FSK mode (mainly receive)
|
||||
* Copyright (C) 2019 Hansi Reiser, dl9rdz
|
||||
*
|
||||
* Partially based on the SX1278 libraray for managing Semtech modules
|
||||
* Copyright (C) 2015 Wireless Open Source
|
||||
* http://wirelessopensource.com
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1+
|
||||
*/
|
||||
|
||||
#ifndef SX1278FSK_h
|
||||
#define SX1278FSK_h
|
||||
|
||||
/******************************************************************************
|
||||
* Includes
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Definitions & Declarations
|
||||
*****************************************************************************/
|
||||
|
||||
#define SX127X_CRYSTAL_FREQ 32000000
|
||||
#define SX127X_FSTEP (SX127X_CRYSTAL_FREQ*1.0/(1<<19))
|
||||
|
||||
#define SX1278FSK_debug_mode 0
|
||||
|
||||
//! MACROS //
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01) // read a bit
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit))) // set bit to '1'
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit))) // set bit to '0'
|
||||
|
||||
|
||||
//! REGISTERS //
|
||||
// FSK Commun LORA
|
||||
#define REG_FIFO 0x00
|
||||
#define REG_OP_MODE 0x01
|
||||
#define REG_BITRATE_MSB 0x02
|
||||
#define REG_BITRATE_LSB 0x03
|
||||
#define REG_FDEV_MSB 0x04
|
||||
#define REG_FDEV_LSB 0x05
|
||||
#define REG_FRF_MSB 0x06
|
||||
#define REG_FRF_MID 0x07
|
||||
#define REG_FRF_LSB 0x08
|
||||
#define REG_PA_CONFIG 0x09
|
||||
#define REG_PA_RAMP 0x0A
|
||||
#define REG_OCP 0x0B
|
||||
#define REG_LNA 0x0C
|
||||
#define REG_RX_CONFIG 0x0D
|
||||
#define REG_FIFO_ADDR_PTR 0x0D
|
||||
#define REG_RSSI_CONFIG 0x0E
|
||||
#define REG_FIFO_TX_BASE_ADDR 0x0E
|
||||
#define REG_RSSI_COLLISION 0x0F
|
||||
#define REG_FIFO_RX_BASE_ADDR 0x0F
|
||||
#define REG_RSSI_THRESH 0x10
|
||||
#define REG_FIFO_RX_CURRENT_ADDR 0x10
|
||||
#define REG_RSSI_VALUE_FSK 0x11
|
||||
#define REG_IRQ_FLAGS_MASK 0x11
|
||||
#define REG_RX_BW 0x12
|
||||
#define REG_IRQ_FLAGS 0x12
|
||||
#define REG_AFC_BW 0x13
|
||||
#define REG_RX_NB_BYTES 0x13
|
||||
#define REG_OOK_PEAK 0x14
|
||||
#define REG_RX_HEADER_CNT_VALUE_MSB 0x14
|
||||
#define REG_OOK_FIX 0x15
|
||||
#define REG_RX_HEADER_CNT_VALUE_LSB 0x15
|
||||
#define REG_OOK_AVG 0x16
|
||||
#define REG_RX_PACKET_CNT_VALUE_MSB 0x16
|
||||
#define REG_RX_PACKET_CNT_VALUE_LSB 0x17
|
||||
#define REG_MODEM_STAT 0x18
|
||||
#define REG_PKT_SNR_VALUE 0x19
|
||||
#define REG_AFC_FEI 0x1A
|
||||
#define REG_PKT_RSSI_VALUE 0x1A
|
||||
#define REG_AFC_MSB 0x1B
|
||||
#define REG_RSSI_VALUE_LORA 0x1B
|
||||
#define REG_AFC_LSB 0x1C
|
||||
#define REG_HOP_CHANNEL 0x1C
|
||||
#define REG_FEI_MSB 0x1D
|
||||
#define REG_MODEM_CONFIG1 0x1D
|
||||
#define REG_FEI_LSB 0x1E
|
||||
#define REG_MODEM_CONFIG2 0x1E
|
||||
#define REG_PREAMBLE_DETECT 0x1F
|
||||
#define REG_SYMB_TIMEOUT_LSB 0x1F
|
||||
#define REG_RX_TIMEOUT1 0x20
|
||||
#define REG_PREAMBLE_MSB_LORA 0x20
|
||||
#define REG_RX_TIMEOUT2 0x21
|
||||
#define REG_PREAMBLE_LSB_LORA 0x21
|
||||
#define REG_RX_TIMEOUT3 0x22
|
||||
#define REG_PAYLOAD_LENGTH_LORA 0x22
|
||||
#define REG_RX_DELAY 0x23
|
||||
#define REG_MAX_PAYLOAD_LENGTH 0x23
|
||||
#define REG_OSC 0x24
|
||||
#define REG_HOP_PERIOD 0x24
|
||||
#define REG_PREAMBLE_MSB_FSK 0x25
|
||||
#define REG_FIFO_RX_BYTE_ADDR 0x25
|
||||
#define REG_PREAMBLE_LSB_FSK 0x26
|
||||
#define REG_MODEM_CONFIG3 0x26
|
||||
#define REG_SYNC_CONFIG 0x27
|
||||
#define REG_SYNC_VALUE1 0x28
|
||||
#define REG_LORA_FEI_MSB 0x28
|
||||
#define REG_SYNC_VALUE2 0x29
|
||||
#define REG_LORA_FEI_MID 0x29
|
||||
#define REG_SYNC_VALUE3 0x2A
|
||||
#define REG_LORA_FEI_LSB 0x2A
|
||||
#define REG_SYNC_VALUE4 0x2B
|
||||
#define REG_SYNC_VALUE5 0x2C
|
||||
#define REG_RSSI_WIDEBAND 0x2C
|
||||
#define REG_SYNC_VALUE6 0x2D
|
||||
#define REG_SYNC_VALUE7 0x2E
|
||||
#define REG_SYNC_VALUE8 0x2F
|
||||
#define REG_PACKET_CONFIG1 0x30
|
||||
#define REG_PACKET_CONFIG2 0x31
|
||||
#define REG_DETECT_OPTIMIZE 0x31
|
||||
#define REG_PAYLOAD_LENGTH_FSK 0x32
|
||||
#define REG_NODE_ADRS 0x33
|
||||
#define REG_INVERT_IQ 0x33
|
||||
#define REG_BROADCAST_ADRS 0x34
|
||||
#define REG_FIFO_THRESH 0x35
|
||||
#define REG_SEQ_CONFIG1 0x36
|
||||
#define REG_SEQ_CONFIG2 0x37
|
||||
#define REG_DETECTION_THRESHOLD 0x37
|
||||
#define REG_TIMER_RESOL 0x38
|
||||
#define REG_TIMER1_COEF 0x39
|
||||
#define REG_SYNC_WORD 0x39
|
||||
#define REG_TIMER2_COEF 0x3A
|
||||
#define REG_IMAGE_CAL 0x3B
|
||||
#define REG_TEMP 0x3C
|
||||
#define REG_LOW_BAT 0x3D
|
||||
#define REG_IRQ_FLAGS1 0x3E
|
||||
#define REG_IRQ_FLAGS2 0x3F
|
||||
#define REG_DIO_MAPPING1 0x40
|
||||
#define REG_DIO_MAPPING2 0x41
|
||||
#define REG_VERSION 0x42
|
||||
#define REG_PLL_HOP 0x44
|
||||
#define REG_TCXO 0x4B
|
||||
#define REG_PA_DAC 0x4D
|
||||
#define REG_FORMER_TEMP 0x5B
|
||||
#define REG_BIT_RATE_FRAC 0x5D
|
||||
#define REG_AGC_REF 0x61
|
||||
#define REG_AGC_THRESH1 0x62
|
||||
#define REG_AGC_THRESH2 0x63
|
||||
#define REG_AGC_THRESH3 0x64
|
||||
#define REG_PLL 0x70
|
||||
|
||||
|
||||
//FSK MODES:
|
||||
const uint8_t FSK_SLEEP_MODE = 0x00;
|
||||
const uint8_t FSK_STANDBY_MODE = 0x01;
|
||||
const uint8_t FSK_TX_MODE = 0x03;
|
||||
const uint8_t FSK_RX_MODE = 0x05;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* SX1278FSK Class
|
||||
* Functions and variables for managing SX127x transceiver chips in FSK mode,
|
||||
* mainly for receiving radiosonde transmissions
|
||||
******************************************************************************/
|
||||
class SX1278FSK
|
||||
{
|
||||
public:
|
||||
// class constructor
|
||||
SX1278FSK();
|
||||
|
||||
void setup(xSemaphoreHandle lock);
|
||||
|
||||
// Turn on SX1278 module (return 0 on sucess, 1 otherwise)
|
||||
uint8_t ON();
|
||||
|
||||
// Turn off SX1278 module
|
||||
void OFF();
|
||||
|
||||
// Read internal register
|
||||
byte readRegister(byte address);
|
||||
|
||||
// Write internal register
|
||||
void writeRegister(byte address, byte data);
|
||||
|
||||
// Clear IRQ flags
|
||||
void clearIRQFlags();
|
||||
|
||||
// Activate FSK mode (return 0 on success, 1 otherwise)
|
||||
uint8_t setFSK();
|
||||
|
||||
// Configures bitrate register (closest approximation to requested bitrate)
|
||||
uint8_t setBitrate(float bps);
|
||||
float getBitrate();
|
||||
|
||||
// Configures RX bandwidth (next largest supported bandwith if exact value not possible)
|
||||
uint8_t setRxBandwidth(float bps);
|
||||
float getRxBandwidth();
|
||||
|
||||
// Configures AFC bandwidth (next largest supported bandwith if exact value not possible)
|
||||
uint8_t setAFCBandwidth(float bps);
|
||||
float getAFCBandwidth();
|
||||
|
||||
// Configures RX frequency (closest approximation to requested frequency)
|
||||
uint8_t setFrequency(float freq);
|
||||
float getFrequency();
|
||||
|
||||
int getLNAGain();
|
||||
uint8_t setLNAGain(int gain);
|
||||
|
||||
uint8_t getRxConf();
|
||||
uint8_t setRxConf(uint8_t conf);
|
||||
|
||||
uint8_t setSyncConf(uint8_t conf, int len, const uint8_t *syncpattern);
|
||||
uint8_t getSyncConf();
|
||||
|
||||
uint8_t setPreambleDetect(uint8_t conf);
|
||||
uint8_t getPreambleDetect();
|
||||
|
||||
uint8_t setPacketConfig(uint8_t conf1, uint8_t conf2);
|
||||
uint16_t getPacketConfig();
|
||||
|
||||
// Get configured preamble length (used for TX only?)
|
||||
uint16_t getPreambleLength();
|
||||
|
||||
// Sets the preamble length.
|
||||
uint8_t setPreambleLength(uint16_t l);
|
||||
|
||||
// Gets the payload length (expected length for receive)
|
||||
int getPayloadLength();
|
||||
uint8_t setPayloadLength(int len);
|
||||
|
||||
// Get current RSSI value
|
||||
int16_t getRSSI();
|
||||
|
||||
// Get current FEI (frequency error indication) value
|
||||
int32_t getFEI();
|
||||
|
||||
// Get current AFC value
|
||||
int32_t getAFC();
|
||||
uint16_t getRawAFC();
|
||||
void setRawAFC(uint16_t afc);
|
||||
|
||||
// Get the maximum current supply by the module.
|
||||
int getMaxCurrent();
|
||||
|
||||
// Set the maximum current supply by the module.
|
||||
int8_t setMaxCurrent(uint8_t rate);
|
||||
|
||||
// Put the module in reception mode.
|
||||
//return '0' on success, '1' otherwise
|
||||
uint8_t receive();
|
||||
|
||||
// Receive a packet
|
||||
uint8_t receivePacketTimeout(uint32_t wait, byte *data);
|
||||
|
||||
xSemaphoreHandle _lock = NULL;
|
||||
|
||||
#if 0
|
||||
//! It gets the internal temperature of the module.
|
||||
/*!
|
||||
It stores in global '_temp' variable the module temperature.
|
||||
\return '0' on success, '1' otherwise
|
||||
*/
|
||||
uint8_t getTemp();
|
||||
|
||||
//! It prints the registers related to RX via USB
|
||||
/*!
|
||||
* \return void
|
||||
*/
|
||||
void showRxRegisters();
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
extern SX1278FSK sx1278;
|
||||
|
||||
#endif
|
207
RX_FSK/src/Scanner.cpp
Normal file
207
RX_FSK/src/Scanner.cpp
Normal file
|
@ -0,0 +1,207 @@
|
|||
#include "Scanner.h"
|
||||
|
||||
#include <U8x8lib.h>
|
||||
|
||||
#include "SX1278FSK.h"
|
||||
#include "Sonde.h"
|
||||
#include "Display.h"
|
||||
|
||||
|
||||
double STARTF;
|
||||
|
||||
|
||||
struct scancfg {
|
||||
int PLOT_W; // Width of plot, in pixel
|
||||
int PLOT_H8; // Height of plot, in 8 pixel units
|
||||
int TICK1; // Pixel per MHz marker
|
||||
int TICK2; // Pixel per sub-Mhz marker (250k or 200k)
|
||||
double CHANSTEP; // Scanner frequenz steps
|
||||
int SMPL_PIX; // Frequency steps per pixel
|
||||
int NCHAN; // number of channels to scan, PLOT_W * SMPL_PIX
|
||||
int SMOOTH;
|
||||
int ADDWAIT;
|
||||
int VSCALE;
|
||||
};
|
||||
|
||||
//struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/20.0, 20, 120*20, 1 };
|
||||
struct scancfg scanLCD={ 121, 7, 120/6, 120/6/4, 6000.0/120.0/10.0, 10, 120*10, 2, 40, 1 };
|
||||
struct scancfg scanTFT={ 210, 16, 210/6, 210/6/5, 6000.0/210.0/10.0, 10, 210*10, 1, 0, 1 };
|
||||
struct scancfg scan934x={ 300, 22, 300/6, 300/6/5, 6000.0/300.0/7.0, 7, 300*5, 1, 10, 2 };
|
||||
|
||||
struct scancfg &scanconfig = scanTFT;
|
||||
|
||||
#define CHANBW 12500
|
||||
//#define PIXSAMPL (50/CHANBW)
|
||||
//#define STARTF 401000000
|
||||
|
||||
// max of 120*5 and 210*3
|
||||
//#define MAXN 210*10
|
||||
//#define MAXN 120*20
|
||||
#define MAXN 300*10
|
||||
|
||||
// max of 120 and 210 (ceil(210/8)*8)) -- now ceil(300/8)*8
|
||||
//#define MAXDISP 216
|
||||
#define MAXDISP 304
|
||||
|
||||
int scanresult[MAXN];
|
||||
int scandisp[MAXDISP];
|
||||
double peakf=0;
|
||||
|
||||
//#define PLOT_MIN -250
|
||||
#define PLOT_MIN (sonde.config.noisefloor*2)
|
||||
#define PLOT_SCALE(x) (x<PLOT_MIN?0:(x-PLOT_MIN)/2)
|
||||
|
||||
const byte tilepatterns[9]={0,0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF};
|
||||
void Scanner::fillTiles(uint8_t *row, int value) {
|
||||
for(int y=0; y<scanconfig.PLOT_H8; y++) {
|
||||
int nbits = scanconfig.VSCALE*value - 8*(scanconfig.PLOT_H8-1-y);
|
||||
if(nbits<0) { row[8*y]=0; continue; }
|
||||
if(nbits>=8) { row[8*y]=255; continue; }
|
||||
row[8*y] = tilepatterns[nbits];
|
||||
}
|
||||
}
|
||||
/* LCD:
|
||||
* There are 16*8 columns to plot, NPLOT must be lower than that
|
||||
* currently, we use 128 * 50kHz channels
|
||||
* There are 8*8 values to plot; MIN is bottom end,
|
||||
* TFT:
|
||||
* There are 210 columns to plot
|
||||
* Currently we use 210 * (6000/120)kHz channels, i.e. 28.5714kHz
|
||||
*/
|
||||
///// unused???? uint8_t tiles[16] = { 0x0f,0x0f,0x0f,0x0f,0xf0,0xf0,0xf0,0xf0, 1, 3, 7, 15, 31, 63, 127, 255};
|
||||
|
||||
// type 0: lcd, 1: tft(ILI9225), 2: lcd(sh1106) 3:TFT(ili9341), 4: TFT(ili9342)
|
||||
#define ISTFT (sonde.config.disptype!=0 && sonde.config.disptype!=2)
|
||||
void Scanner::plotResult()
|
||||
{
|
||||
int yofs = 0;
|
||||
char buf[30];
|
||||
if(ISTFT) {
|
||||
yofs = 2;
|
||||
if (sonde.config.marker != 0) {
|
||||
itoa((sonde.config.startfreq), buf, 10);
|
||||
disp.rdis->drawString(0, 1, buf);
|
||||
disp.rdis->drawString(scanconfig.PLOT_W/2-10, 1, "MHz");
|
||||
itoa((sonde.config.startfreq + 6), buf, 10);
|
||||
disp.rdis->drawString(scanconfig.PLOT_W-15, 1, buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (sonde.config.marker != 0) {
|
||||
itoa((sonde.config.startfreq), buf, 10);
|
||||
disp.rdis->drawString(0, 1, buf);
|
||||
disp.rdis->drawString(7, 1, "MHz");
|
||||
itoa((sonde.config.startfreq + 6), buf, 10);
|
||||
disp.rdis->drawString(13, 1, buf);
|
||||
}
|
||||
}
|
||||
uint8_t row[scanconfig.PLOT_H8*8];
|
||||
for(int i=0; i<scanconfig.PLOT_W; i+=8) {
|
||||
for(int j=0; j<8; j++) {
|
||||
fillTiles(row+j, PLOT_SCALE(scandisp[i+j]));
|
||||
if( (i+j)>=scanconfig.PLOT_W ) { for(int y=0; y<scanconfig.PLOT_H8; y++) row[j+8*y]=0; }
|
||||
if( ((i+j)%scanconfig.TICK1)==0) { row[j] |= 0x07; }
|
||||
if( ((i+j)%scanconfig.TICK2)==0) { row[j] |= 0x01; }
|
||||
}
|
||||
for(int y=0; y<scanconfig.PLOT_H8; y++) {
|
||||
if(sonde.config.marker && y==1 && !ISTFT ) {
|
||||
// don't overwrite MHz marker text
|
||||
if(i<3*8 || (i>=7*8&&i<10*8) || i>=13*8) continue;
|
||||
}
|
||||
disp.rdis->drawTile(i/8, y+yofs, 1, row+8*y);
|
||||
}
|
||||
}
|
||||
if(ISTFT) { // large TFT
|
||||
sprintf(buf, "Peak: %03.3f MHz", peakf*0.000001);
|
||||
disp.rdis->drawString(0, (yofs+scanconfig.PLOT_H8+1)*8, buf);
|
||||
} else {
|
||||
sprintf(buf, "Peak: %03.3fMHz", peakf*0.000001);
|
||||
disp.rdis->drawString(0, 7, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void Scanner::scan()
|
||||
{
|
||||
if(!ISTFT) { // LCD small
|
||||
scanconfig = scanLCD;
|
||||
} else if (sonde.config.disptype==1) {
|
||||
scanconfig = scanTFT;
|
||||
} else {
|
||||
scanconfig = scan934x;
|
||||
}
|
||||
// Configure
|
||||
STARTF = (sonde.config.startfreq * 1000000);
|
||||
sx1278.writeRegister(REG_PLL_HOP, 0x80); // FastHopOn
|
||||
sx1278.setRxBandwidth((int)(scanconfig.CHANSTEP*1000));
|
||||
double bw = sx1278.getRxBandwidth();
|
||||
Serial.print("RX Bandwith for scan: "); Serial.println(bw);
|
||||
sx1278.writeRegister(REG_RSSI_CONFIG, scanconfig.SMOOTH&0x07);
|
||||
sx1278.setFrequency(STARTF);
|
||||
Serial.print("Start freq = "); Serial.println(STARTF);
|
||||
sx1278.writeRegister(REG_OP_MODE, FSK_RX_MODE);
|
||||
|
||||
unsigned long start = millis();
|
||||
uint32_t lastfrf= STARTF * (1<<19) / SX127X_CRYSTAL_FREQ;
|
||||
float freq = STARTF;
|
||||
int wait = scanconfig.ADDWAIT + 20 + 1000*(1<<(scanconfig.SMOOTH+1))/4/(0.001*CHANBW);
|
||||
Serial.print("wait time (us) is: "); Serial.println(wait);
|
||||
for(int iter=0; iter<3; iter++) { // three interations, to catch all RS41 transmissions
|
||||
delayMicroseconds(20000); yield();
|
||||
for(int i=0; i<scanconfig.PLOT_W*scanconfig.SMPL_PIX; i++) {
|
||||
freq = STARTF + 1000.0*i*scanconfig.CHANSTEP;
|
||||
//freq = 404000000 + 100*i*scanconfig.CHANSTEP;
|
||||
uint32_t frf = freq * 1.0 * (1<<19) / SX127X_CRYSTAL_FREQ;
|
||||
if( (lastfrf>>16)!=(frf>>16) ) {
|
||||
sx1278.writeRegister(REG_FRF_MSB, (frf&0xff0000)>>16);
|
||||
}
|
||||
if( ((lastfrf&0x00ff00)>>8) != ((frf&0x00ff00)>>8) ) {
|
||||
sx1278.writeRegister(REG_FRF_MID, (frf&0x00ff00)>>8);
|
||||
}
|
||||
sx1278.writeRegister(REG_FRF_LSB, (frf&0x0000ff));
|
||||
lastfrf = frf;
|
||||
// Wait TS_HOP (20us) + TS_RSSI ( 2^(scacconfig.SMOOTH+1) / 4 / CHANBW us)
|
||||
delayMicroseconds(wait);
|
||||
int rssi = -(int)sx1278.readRegister(REG_RSSI_VALUE_FSK);
|
||||
if(iter==0) { scanresult[i] = rssi; } else {
|
||||
if(rssi>scanresult[i]) scanresult[i]=rssi;
|
||||
}
|
||||
}
|
||||
}
|
||||
yield();
|
||||
unsigned long duration = millis()-start;
|
||||
Serial.print("wait: ");
|
||||
Serial.println(wait);
|
||||
Serial.print("Scan time: ");
|
||||
Serial.println(duration);
|
||||
Serial.print("Final freq: ");
|
||||
Serial.println(freq);
|
||||
int peakidx=-1;
|
||||
int peakres=-9999;
|
||||
for(int i=0; i<scanconfig.PLOT_W; i+=1) {
|
||||
int r=scanresult[i*scanconfig.SMPL_PIX];
|
||||
if(r>peakres+1) { peakres=r; peakidx=i*scanconfig.SMPL_PIX; }
|
||||
scandisp[i] = r;
|
||||
for(int j=1; j<scanconfig.SMPL_PIX; j++) {
|
||||
r = scanresult[i*scanconfig.SMPL_PIX+j];
|
||||
scandisp[i]+=r;
|
||||
if(r>peakres+1) { peakres=r; peakidx=i*scanconfig.SMPL_PIX+j; }
|
||||
}
|
||||
//for(int j=1; j<PIXSAMPL; j++) { if(scanresult[i+j]>scandisp[i/PIXSAMPL]) scandisp[i/PIXSAMPL] = scanresult[i+j]; }
|
||||
Serial.print(scanresult[i]); Serial.print(", ");
|
||||
}
|
||||
peakidx--;
|
||||
double newpeakf = STARTF + scanconfig.CHANSTEP*1000.0*peakidx;
|
||||
if(newpeakf<peakf-20000 || newpeakf>peakf+20000) peakf=newpeakf; // different frequency
|
||||
else if (newpeakf < peakf) peakf = 0.75*newpeakf + 0.25*peakf; // averaging on frequency, some bias towards lower...
|
||||
else peakf = 0.25*newpeakf + 0.75*peakf;
|
||||
Serial.println("\n");
|
||||
for(int i=0; i<scanconfig.PLOT_W; i++) {
|
||||
scandisp[i]/=scanconfig.SMPL_PIX;
|
||||
Serial.print(scandisp[i]); Serial.print(", ");
|
||||
}
|
||||
Serial.println("\n");
|
||||
Serial.print("Peak: ");
|
||||
Serial.print(peakf);
|
||||
}
|
||||
|
||||
Scanner scanner = Scanner();
|
23
RX_FSK/src/Scanner.h
Normal file
23
RX_FSK/src/Scanner.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
#ifndef _SCANNER_H
|
||||
#define _SCANNER_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <Arduino.h>
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
class Scanner
|
||||
{
|
||||
private:
|
||||
void fillTiles(uint8_t *row, int value);
|
||||
|
||||
public:
|
||||
void plotResult();
|
||||
void scan(void);
|
||||
};
|
||||
|
||||
extern Scanner scanner;
|
||||
#endif
|
247
RX_FSK/src/ShFreqImport.cpp
Normal file
247
RX_FSK/src/ShFreqImport.cpp
Normal file
|
@ -0,0 +1,247 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "ShFreqImport.h"
|
||||
#include "Sonde.h"
|
||||
|
||||
static int ppos;
|
||||
static int quotes;
|
||||
static char id[20];
|
||||
static int idpos;
|
||||
static float lat, lon, freq;
|
||||
static char type[20];
|
||||
|
||||
static uint8_t inuse[1+99/8]; // MAXSONDE is 99
|
||||
|
||||
static char keyword[40];
|
||||
static int keywordpos;
|
||||
static char value[40];
|
||||
static int valuepos;
|
||||
|
||||
static int importState;
|
||||
static float homelat, homelon;
|
||||
|
||||
|
||||
// Map SondeHub type string to Stype. -1 for not supported types.
|
||||
int ShFreqImport::stringToStype(const char *type) {
|
||||
if(type[2]=='4') return STYPE_RS41;
|
||||
if(type[2]=='9') return STYPE_RS92;
|
||||
if(type[1]=='1') return STYPE_M10M20;
|
||||
if(type[1]=='2') return STYPE_M10M20;
|
||||
if(type[0]=='D') return STYPE_DFM;
|
||||
if(type[2]=='3') return STYPE_MP3H; // TODO: check if '3' is correct
|
||||
return -1; // iMet is not supported
|
||||
}
|
||||
|
||||
// in Display.cpp
|
||||
extern float calcLatLonDist(float lat1, float lon1, float lat2, float lon2);
|
||||
|
||||
void ShFreqImport::setLabel(int idx, char *id, float lat, float lon) {
|
||||
snprintf(sonde.sondeList[idx].launchsite, 18, "@%s/%d", id, (int)(calcLatLonDist(homelat, homelon, lat, lon)/1000));
|
||||
sonde.sondeList[idx].launchsite[17] = 0;
|
||||
}
|
||||
|
||||
void ShFreqImport::usekeyvalue() {
|
||||
if(strcmp(keyword,"lat")==0) lat = atof(value);
|
||||
if(strcmp(keyword,"lon")==0) lon = atof(value);
|
||||
if(strcmp(keyword,"frequency")==0) { if(isnan(freq)) freq = atof(value); } // prefer tx_frequency if available
|
||||
if(strcmp(keyword,"tx_frequency")==0) freq = atof(value);
|
||||
if(strcmp(keyword,"type")==0) strcpy(type, value);
|
||||
}
|
||||
|
||||
/* populate qrg.txt with frequency of near sonde */
|
||||
void ShFreqImport::populate(char *id, float lat, float lon, float freq, const char *type)
|
||||
{
|
||||
//printf(" ID %s: %.5f, %.5f f=%.3f, type=%s \n", id, lat, lon, freq, type);
|
||||
// Skip if freq already exists
|
||||
int stype = stringToStype(type);
|
||||
if(stype<0) return; // unsupported type
|
||||
|
||||
// check if frequency exists already
|
||||
// don't do anything if its a static entry
|
||||
// update label if its a dynamic SH entry
|
||||
int i;
|
||||
for(i=0; i<sonde.config.maxsonde; i++) {
|
||||
if( abs(sonde.sondeList[i].freq-freq)<0.003 ) { // exists already, max error 3000 Hz
|
||||
Serial.printf("id %s close to %d\n", id, i);
|
||||
if( sonde.sondeList[i].type == stype) {
|
||||
char *l = sonde.sondeList[i].launchsite;
|
||||
if( *l=='@' || *l==' ' || *l==0 ) {
|
||||
setLabel(i, id, lat, lon);
|
||||
inuse[i/8] |= (1<<(i&7));
|
||||
}
|
||||
sonde.sondeList[i].active = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// find slot
|
||||
// slots with empty launchsite are considered available for automated entries
|
||||
while(ppos < sonde.config.maxsonde) {
|
||||
if( *sonde.sondeList[ppos].launchsite==' ' || *sonde.sondeList[ppos].launchsite== 0 ) break;
|
||||
ppos++;
|
||||
}
|
||||
if(ppos >= sonde.config.maxsonde) {
|
||||
Serial.println("populate: out of free slots");
|
||||
return;
|
||||
} // no more free slots
|
||||
|
||||
sonde.clearAllData(&sonde.sondeList[ppos]);
|
||||
sonde.sondeList[ppos].active = 1;
|
||||
sonde.sondeList[ppos].freq = freq;
|
||||
sonde.sondeList[ppos].type = (SondeType)stype;
|
||||
setLabel(ppos, id, lat, lon);
|
||||
inuse[ppos/8] |= (1<<(ppos&7));
|
||||
ppos++;
|
||||
}
|
||||
|
||||
// clears all remaining automatically filled slots (no longer in SH data)
|
||||
void ShFreqImport::cleanup() {
|
||||
//Serial.println("Cleanup called ********");
|
||||
for(int i=0; i<sonde.config.maxsonde; i++) {
|
||||
if( (((inuse[i/8]>>(i&7))&1) == 0) && *sonde.sondeList[i].launchsite=='@' ) {
|
||||
// Don't remove the currently active entry
|
||||
if(i==sonde.currentSonde) continue;
|
||||
Serial.printf("removing #%d\n", i);
|
||||
sonde.sondeList[i].launchsite[0] = 0;
|
||||
sonde.sondeList[i].active = 0;
|
||||
sonde.sondeList[i].freq = 400;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BUFLEN 128
|
||||
#define VALLEN 20
|
||||
int ShFreqImport::handleChar(char c) {
|
||||
Serial.print(c);
|
||||
switch(importState) {
|
||||
case START:
|
||||
// wait for initial '{'
|
||||
if(c=='{') {
|
||||
Serial.println("{ found");
|
||||
importState++;
|
||||
}
|
||||
break;
|
||||
case BEFOREID:
|
||||
// what for first '"' in { "A1234567" : { ... } }; or detect end
|
||||
if(c=='"') { idpos = 0; lat = NAN; lon = NAN; freq = NAN; *type = 0; importState++; }
|
||||
if(c=='}') {
|
||||
importState = ENDREACHED;
|
||||
cleanup();
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case COPYID:
|
||||
// copy ID "A1234567" until second '"' is earched
|
||||
if(c=='"') { id[idpos] = 0; importState++; }
|
||||
else id[idpos++] = c;
|
||||
break;
|
||||
case AFTERID:
|
||||
// wait for '{' in '"A1234567": { ...'
|
||||
if(c=='{') importState++;
|
||||
break;
|
||||
case BEFOREKEY:
|
||||
if(c=='"') { keywordpos = 0; importState++; }
|
||||
break;
|
||||
case COPYKEY:
|
||||
if(c=='"') { importState++; keyword[keywordpos] = 0; /* printf("Key: >%s<\n", keyword);*/ }
|
||||
else keyword[keywordpos++] = c;
|
||||
break;
|
||||
case AFTERKEY:
|
||||
if(c==':') {
|
||||
valuepos = 0;
|
||||
quotes = 0;
|
||||
if(strcmp(keyword,"lat")==0 || strcmp(keyword, "lon")==0 || strcmp(keyword, "frequency")==0 || strcmp(keyword, "tx_frequency")==0)
|
||||
importState = BEFORENUMVAL;
|
||||
else {
|
||||
if (strcmp(keyword, "type")==0)
|
||||
importState = BEFORESTRINGVAL;
|
||||
else
|
||||
importState = SKIPVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BEFORENUMVAL:
|
||||
if( (c>='0'&&c<='9') || c=='-') { value[0] = c; valuepos=1; importState++; }
|
||||
break;
|
||||
case COPYNUMVAL:
|
||||
if( !(c>='0'&&c<='9') && c!='-' && c!='.' ) {
|
||||
value[valuepos]=0; importState=SKIPVAL; usekeyvalue();
|
||||
if(c!=',' && c!='}') break;
|
||||
}
|
||||
else { value[valuepos++] = c; break; }
|
||||
// intenionall fall-through
|
||||
case SKIPVAL:
|
||||
// This is rather fragile, we *should* handle more escaping and so on but do not do so so far, only simple quotes
|
||||
if(c=='"') quotes = !quotes;
|
||||
if(quotes) break;
|
||||
if(c==',') importState = BEFOREKEY;
|
||||
if(c=='}') {
|
||||
// we have an ID and all key/value pairs, check if its good....
|
||||
if( !isnan(lat) && !isnan(lon) && !isnan(freq) && type[0] ) {
|
||||
printf("SondeHub import: populate %s %f %f %f %s\n", id, lat, lon, freq, type);
|
||||
populate(id, lat, lon, freq, type);
|
||||
} else {
|
||||
printf("Skipping incomplete %s\n", id);
|
||||
}
|
||||
importState = ENDORNEXT;
|
||||
}
|
||||
break;
|
||||
case BEFORESTRINGVAL:
|
||||
if(c=='"') importState++;
|
||||
break;
|
||||
case COPYSTRINGVAL:
|
||||
if(c=='"') { importState=SKIPVAL; value[valuepos]=0; usekeyvalue(); }
|
||||
else value[valuepos++] = c;
|
||||
break;
|
||||
case ENDORNEXT:
|
||||
// next we have to see either a final "}', or a comma before the next id
|
||||
if(c==',') importState = BEFOREID;
|
||||
else if (c=='}') { importState = ENDREACHED; cleanup(); return 1; }
|
||||
break;
|
||||
case ENDREACHED:
|
||||
Serial.println("REPLY: END REACHED");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// lat lon in deg, dist in km, time in minutes
|
||||
int ShFreqImport::shImportSendRequest(WiFiClient *client, float lat, float lon, int dist, int time) {
|
||||
if(!client->connected()) {
|
||||
if(!client->connect(sonde.config.sondehub.host, 80)) {
|
||||
Serial.println("Connection FAILED");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
Serial.println("Sending SondeHub import request");
|
||||
char req[300];
|
||||
snprintf(req, 200, "GET /sondes?lat=%f&lon=%f&distance=%d&last=%d HTTP/1.1\r\n"
|
||||
"Host: %s\r\n"
|
||||
"Accept: application/json\r\n"
|
||||
"Cache-Control: no-cache\r\n\r\n",
|
||||
lat, lon, dist*1000, time*60, sonde.config.sondehub.host);
|
||||
client->print(req);
|
||||
Serial.print(req);
|
||||
importState = START;
|
||||
homelat = lat;
|
||||
homelon = lon;
|
||||
memset(inuse, 0, sizeof(inuse));
|
||||
ppos = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return 0 if more data should be read (later), 1 if finished (close connection...)
|
||||
int ShFreqImport::shImportHandleReply(WiFiClient *client) {
|
||||
if(!client->connected()) return 1;
|
||||
while(client->available()) {
|
||||
int res = handleChar(client->read());
|
||||
if(res) return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
30
RX_FSK/src/ShFreqImport.h
Normal file
30
RX_FSK/src/ShFreqImport.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef SH_FREQ_IMPORT_
|
||||
#define SH_FREQ_IMPORT_H
|
||||
// Automated frequency import from SondeHub
|
||||
|
||||
#include <WiFi.h>
|
||||
|
||||
enum ImportState { START, BEFOREID, COPYID, AFTERID, BEFOREKEY, COPYKEY, AFTERKEY, SKIPVAL, BEFORENUMVAL, COPYNUMVAL, BEFORESTRINGVAL, COPYSTRINGVAL, AFTERPAYLOAD, ENDORNEXT, ENDREACHED };
|
||||
|
||||
class ShFreqImport {
|
||||
public:
|
||||
// Fetch data from sondehub and populate qrg.txt with result
|
||||
// return: 0: ok; 1: failure
|
||||
static int shImportSendRequest(WiFiClient *client, float lat, float lon, int dist, int time);
|
||||
|
||||
// return 0: ok, need more data; 1: finished/failure, close connection
|
||||
// Asynchronous I/O. Handle data if available
|
||||
static int shImportHandleReply(WiFiClient *client);
|
||||
|
||||
private:
|
||||
static int stringToStype(const char *type);
|
||||
static void setLabel(int idx, char *id, float lat, float lon);
|
||||
static void usekeyvalue();
|
||||
static int handleChar(char c);
|
||||
|
||||
// add one entry on available slot at or after ppos
|
||||
static void populate(char *id, float lat, float lon, float freq, const char *type);
|
||||
static void cleanup();
|
||||
};
|
||||
|
||||
#endif
|
736
RX_FSK/src/Sonde.cpp
Normal file
736
RX_FSK/src/Sonde.cpp
Normal file
|
@ -0,0 +1,736 @@
|
|||
#include <U8x8lib.h>
|
||||
#include <U8g2lib.h>
|
||||
|
||||
#include "Sonde.h"
|
||||
#include "RS41.h"
|
||||
#include "RS92.h"
|
||||
#include "DFM.h"
|
||||
#include "M10M20.h"
|
||||
#include "MP3H.h"
|
||||
#include "SX1278FSK.h"
|
||||
#include "Display.h"
|
||||
#include <Wire.h>
|
||||
|
||||
uint8_t debug = 255-8-16;
|
||||
|
||||
RXTask rxtask = { -1, -1, -1, 0xFFFF, 0 };
|
||||
|
||||
const char *evstring[]={"NONE", "KEY1S", "KEY1D", "KEY1M", "KEY1L", "KEY2S", "KEY2D", "KEY2M", "KEY2L",
|
||||
"VIEWTO", "RXTO", "NORXTO", "(max)"};
|
||||
|
||||
const char *RXstr[]={"RX_OK", "RX_TIMEOUT", "RX_ERROR", "RX_UNKNOWN"};
|
||||
|
||||
// Dependency to enum SondeType
|
||||
const char *sondeTypeStr[NSondeTypes] = { "DFM ", "RS41", "RS92", "Mxx ", "M10 ", "M20 ", "MP3H" };
|
||||
const char *sondeTypeLongStr[NSondeTypes] = { "DFM (all)", "RS41", "RS92", "M10/M20", "M10 ", "M20 ", "MP3-H1" };
|
||||
const char sondeTypeChar[NSondeTypes] = { 'D', '4', 'R', 'M', 'M', '2', '3' };
|
||||
const char *manufacturer_string[]={"Graw", "Vaisala", "Vaisala", "Meteomodem", "Meteomodem", "Meteomodem", "Meteo-Radiy"};
|
||||
|
||||
int fingerprintValue[]={ 17, 31, 64, 4, 55, 48, 23, 128+23, 119, 128+119, -1 };
|
||||
const char *fingerprintText[]={
|
||||
"TTGO T-Beam (new version 1.0), I2C not working after powerup, assuming 0.9\" OLED@21,22",
|
||||
"TTGO LORA32 v2.1_1.6 (0.9\" OLED@21,22)",
|
||||
"TTGO LORA v1.0 (0.9\" OLED@4,15)",
|
||||
"Heltec v1/v2 (0.9\"OLED@4,15)",
|
||||
"TTGO T-Beam (V0.7), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V0.7), SPI TFT@4,21,22",
|
||||
"TTGO T-Beam (V1.0), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V1.0), SPI TFT@4,13,14",
|
||||
"TTGO T-Beam (V1.1), 0.9\" OLED@21,22",
|
||||
"TTGO T-Beam (V1.1), SPI TFT@4,13,14",
|
||||
};
|
||||
|
||||
/* global variables from RX_FSK.ino */
|
||||
int getKeyPressEvent();
|
||||
int handlePMUirq();
|
||||
extern uint8_t pmu_irq;
|
||||
extern SX1278FSK sx1278;
|
||||
|
||||
/* Task model:
|
||||
* There is a background task for all SX1278 interaction.
|
||||
* - On startup and on each mode/frequency change (requested by setting requestNextSonde
|
||||
* to an sonde index >=0) it calls Sonde::setup(), which will call the new decoder's
|
||||
* setup function. Setup will update the value currentSonde.
|
||||
* - Periodically it calls Sonde::receive(), which calls the current decoder's receive()
|
||||
* function. It should return control to the SX1278 main loop at least once per second.
|
||||
* It will also set the internal variable receiveResult. The decoder's receive function
|
||||
* must make sure that there are no FIFO overflows in the SX1278.
|
||||
* - the Arduino main loop will call the waitRXcomplete function, which should return as
|
||||
* soon as there is some new data to display, or no later than after 1s, returning the
|
||||
* value of receiveResult (or timeout, if receiveResult was not set within 1s). It
|
||||
* should also return immediately if there is some keyboard input.
|
||||
*/
|
||||
int initlevels[40];
|
||||
|
||||
Sonde::Sonde() {
|
||||
for (int i = 0; i < 39; i++) {
|
||||
initlevels[i] = gpio_get_level((gpio_num_t)i);
|
||||
}
|
||||
}
|
||||
|
||||
void Sonde::defaultConfig() {
|
||||
fingerprint = initlevels[4];
|
||||
fingerprint = (fingerprint<<1) | initlevels[12];
|
||||
fingerprint = (fingerprint<<1) | initlevels[16];
|
||||
fingerprint = (fingerprint<<1) | initlevels[17];
|
||||
fingerprint = (fingerprint<<1) | initlevels[21];
|
||||
fingerprint = (fingerprint<<1) | initlevels[22];
|
||||
fingerprint = (fingerprint<<1) | initlevels[23];
|
||||
Serial.printf("Board fingerprint is %d\n", fingerprint);
|
||||
|
||||
sondeList = (SondeInfo *)malloc((MAXSONDE+1)*sizeof(SondeInfo));
|
||||
// addSonde should initialize everything anyway, so this should not strictly be necessary, but does no harm either
|
||||
memset(sondeList, 0, (MAXSONDE+1)*sizeof(SondeInfo));
|
||||
for(int i=0; i<(MAXSONDE+1); i++) {
|
||||
sondeList[i].freq=400;
|
||||
sondeList[i].type=STYPE_RS41;
|
||||
clearAllData(&sondeList[i]);
|
||||
}
|
||||
config.touch_thresh = 70;
|
||||
config.led_pout = -1;
|
||||
config.power_pout = -1;
|
||||
config.spectrum=10;
|
||||
// Try autodetecting board type
|
||||
config.type = TYPE_TTGO;
|
||||
// Seems like on startup, GPIO4 is 1 on v1 boards, 0 on v2.1 boards?
|
||||
config.gps_rxd = -1;
|
||||
config.gps_txd = -1;
|
||||
config.batt_adc = -1;
|
||||
config.sx1278_ss = SS; // default SS pin, on all TTGOs
|
||||
config.sx1278_miso = MISO;
|
||||
config.sx1278_mosi = MOSI;
|
||||
config.sx1278_sck = SCK;
|
||||
config.oled_rst = 16;
|
||||
config.disptype = 0;
|
||||
config.dispcontrast = -1;
|
||||
config.oled_orient = 1;
|
||||
config.button2_axp = 0;
|
||||
config.norx_timeout = 20;
|
||||
config.screenfile = 1;
|
||||
|
||||
if(initlevels[16]==0) {
|
||||
config.oled_sda = 4;
|
||||
config.oled_scl = 15;
|
||||
config.button_pin = 0;
|
||||
config.button2_pin = T4 + 128; // T4 == GPIO13
|
||||
config.power_pout = 21; // for Heltec v2
|
||||
config.led_pout = 2;
|
||||
Serial.println("Autoconfig: looks like TTGO v1 / Heltec v1/V2 board");
|
||||
} else {
|
||||
config.oled_sda = 21;
|
||||
config.oled_scl = 22;
|
||||
if(initlevels[17]==0) { // T-Beam or M5Stack Core2?
|
||||
int tbeam=7;
|
||||
if(initlevels[12]==0) {
|
||||
tbeam = 10;
|
||||
Serial.println("Autoconfig: looks like T-Beam 1.0 or M5Stack Core2 board");
|
||||
} else if ( initlevels[4]==1 && initlevels[12]==1 ) {
|
||||
tbeam = 11;
|
||||
Serial.println("Autoconfig: looks like T-Beam 1.1 board");
|
||||
}
|
||||
if(tbeam == 10 || tbeam == 11) { // T-Beam v1.0 or T-Beam v1.1
|
||||
Wire.begin(21, 22);
|
||||
#define BM8563_ADDRESS 0x51
|
||||
Wire.beginTransmission(BM8563_ADDRESS);
|
||||
byte err = Wire.endTransmission();
|
||||
if(err) { // try again
|
||||
delay(400);
|
||||
Wire.beginTransmission(BM8563_ADDRESS);
|
||||
err = Wire.endTransmission();
|
||||
}
|
||||
if(err==0) {
|
||||
Serial.println("M5stack Core2 board detected\n");
|
||||
config.type = TYPE_M5_CORE2;
|
||||
config.button_pin = 255;
|
||||
config.button2_pin = 255;
|
||||
config.button2_axp = 1;
|
||||
config.disptype = 4; // ILI9342
|
||||
config.oled_sda = 23;
|
||||
config.oled_scl = 18;
|
||||
config.oled_rst = -1;
|
||||
config.screenfile = 4;
|
||||
config.gps_rxd = 13;
|
||||
config.gps_txd = -1; // 14
|
||||
config.sx1278_ss = 33;
|
||||
config.sx1278_miso = 38;
|
||||
config.sx1278_mosi = 23; //MOSI;
|
||||
config.sx1278_sck = 18; // SCK;
|
||||
} else { // some t-beam...
|
||||
config.button_pin = 38;
|
||||
config.button2_pin = 15 + 128; //T4 + 128; // T4 = GPIO13
|
||||
// Maybe in future use as default only PWR as button2?
|
||||
//config.button2_pin = 255;
|
||||
config.button2_axp = 1;
|
||||
config.gps_rxd = 34;
|
||||
config.gps_txd = 12;
|
||||
// Check for I2C-Display@21,22
|
||||
#define SSD1306_ADDRESS 0x3c
|
||||
Wire.beginTransmission(SSD1306_ADDRESS);
|
||||
err = Wire.endTransmission();
|
||||
delay(100); // otherwise its too fast?!
|
||||
Wire.beginTransmission(SSD1306_ADDRESS);
|
||||
err = Wire.endTransmission();
|
||||
if(err!=0 && fingerprint!=17) { // hmm. 17 after powerup with oled commected and no i2c answer!?!?
|
||||
fingerprint |= 128;
|
||||
Serial.println("no I2C display found, assuming large TFT display\n");
|
||||
// CS=0, RST=14, RS=2, SDA=4, CLK=13
|
||||
Serial.println("... with large TFT display\n");
|
||||
config.disptype = 1;
|
||||
config.oled_sda = 4;
|
||||
config.oled_scl = 13;
|
||||
config.oled_rst = 14;
|
||||
|
||||
config.spectrum = -1; // no spectrum for now on large display
|
||||
config.screenfile = 2;
|
||||
} else {
|
||||
// OLED display, pins 21,22 ok...
|
||||
config.disptype = 0;
|
||||
Serial.println("... with small OLED display\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Serial.println("Autoconfig: looks like T-Beam v0.7 board");
|
||||
config.button_pin = 39;
|
||||
config.button2_pin = T4 + 128; // T4 == GPIO13
|
||||
config.gps_rxd = 12;
|
||||
// Check if we possibly have a large display
|
||||
if(initlevels[21]==0) {
|
||||
Serial.println("Autoconfig: looks like T-Beam v0.7 board with large TFT display");
|
||||
config.disptype = 1;
|
||||
config.oled_sda = 4;
|
||||
config.oled_scl = 21;
|
||||
config.oled_rst = 22;
|
||||
|
||||
config.spectrum = -1; // no spectrum for now on large display
|
||||
config.screenfile = 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Likely a TTGO V2.1_1.6
|
||||
config.button_pin = 2 + 128; // GPIO2 / T2
|
||||
config.button2_pin = 14 + 128; // GPIO14 / T6
|
||||
config.led_pout = 25;
|
||||
config.batt_adc = 35;
|
||||
}
|
||||
}
|
||||
//
|
||||
config.noisefloor = -125;
|
||||
strcpy(config.call,"NOCALL");
|
||||
config.passcode = -1;
|
||||
strcpy(config.mdnsname, "radiosonde");
|
||||
config.maxsonde=15;
|
||||
config.debug=0;
|
||||
config.wifi=1;
|
||||
config.buzzerOn=0;
|
||||
config.buzzerFreq=700;
|
||||
config.buzzerPort=12;
|
||||
config.dbsmetre=0;
|
||||
config.degdec=0;
|
||||
config.display[0]=0;
|
||||
config.display[1]=1;
|
||||
config.display[2]=-1;
|
||||
config.startfreq=400;
|
||||
config.channelbw=10;
|
||||
config.marker=0;
|
||||
config.freqofs=0;
|
||||
config.rs41.agcbw=12500;
|
||||
config.rs41.rxbw=6300;
|
||||
config.rs92.rxbw=12500;
|
||||
config.rs92.alt2d=480;
|
||||
config.dfm.agcbw=20800;
|
||||
config.dfm.rxbw=10400;
|
||||
config.m10m20.agcbw=20800;
|
||||
config.m10m20.rxbw=12500;
|
||||
config.mp3h.agcbw=12500;
|
||||
config.mp3h.rxbw=12500;
|
||||
config.udpfeed.active = 1;
|
||||
config.udpfeed.type = 0;
|
||||
strcpy(config.udpfeed.host, "192.168.42.20");
|
||||
strcpy(config.udpfeed.symbol, "/O");
|
||||
config.udpfeed.port = 9002;
|
||||
config.udpfeed.highrate = 1;
|
||||
config.tcpfeed.active = 0;
|
||||
config.tcpfeed.type = 1;
|
||||
strcpy(config.tcpfeed.host, "radiosondy.info");
|
||||
strcpy(config.tcpfeed.symbol, "/O");
|
||||
config.tcpfeed.port = 12345;
|
||||
config.tcpfeed.highrate = 10;
|
||||
config.kisstnc.active = 0;
|
||||
strcpy(config.ephftp,"igs.bkg.bund.de/IGS/BRDC/");
|
||||
|
||||
config.mqtt.active = 0;
|
||||
strcpy(config.mqtt.id, "rdz_sonde_server");
|
||||
config.mqtt.port = 1883;
|
||||
strcpy(config.mqtt.username, "/0");
|
||||
strcpy(config.mqtt.password, "/0");
|
||||
strcpy(config.mqtt.prefix, "rdz_sonde_server/");
|
||||
}
|
||||
|
||||
extern struct st_configitems config_list[];
|
||||
extern const int N_CONFIG;
|
||||
|
||||
void Sonde::checkConfig() {
|
||||
if(config.maxsonde > MAXSONDE) config.maxsonde = MAXSONDE;
|
||||
if(config.sondehub.fiinterval<5) config.sondehub.fiinterval = 5;
|
||||
if(config.sondehub.fimaxdist>700) config.sondehub.fimaxdist = 700;
|
||||
if(config.sondehub.fimaxage>48) config.sondehub.fimaxage = 48;
|
||||
if(config.sondehub.fimaxdist==0) config.sondehub.fimaxdist = 150;
|
||||
if(config.sondehub.fimaxage==0) config.sondehub.fimaxage = 2;
|
||||
}
|
||||
void Sonde::setConfig(const char *cfg) {
|
||||
while(*cfg==' '||*cfg=='\t') cfg++;
|
||||
if(*cfg=='#') return;
|
||||
char *s = strchr(cfg,'=');
|
||||
if(!s) return;
|
||||
char *val = s+1;
|
||||
*s=0; s--;
|
||||
while(s>cfg && (*s==' '||*s=='\t')) { *s=0; s--; }
|
||||
Serial.printf("configuration option '%s'=%s \n", cfg, val);
|
||||
|
||||
// new code: use config_list to find config entry...
|
||||
int i;
|
||||
for(i=0; i<N_CONFIG; i++) {
|
||||
if(strcmp(cfg, config_list[i].name)!=0) continue;
|
||||
|
||||
if(config_list[i].type>0) { // string with that length
|
||||
strlcpy((char *)config_list[i].data, val, config_list[i].type+1);
|
||||
break;
|
||||
}
|
||||
switch(config_list[i].type) {
|
||||
case 0: // integer
|
||||
case -4: // integer (with "touch button" checkbox in web form)
|
||||
case -3: // integer (boolean on/off swith in web form)
|
||||
case -2: // integer (ID type)
|
||||
*(int *)config_list[i].data = atoi(val);
|
||||
break;
|
||||
case -7: // double
|
||||
{
|
||||
double d = atof(val);
|
||||
if(*val == 0 || d==0) d = NAN;
|
||||
*(double *)config_list[i].data = d;
|
||||
break;
|
||||
}
|
||||
case -6: // display list
|
||||
{
|
||||
int idx = 0;
|
||||
char *ptr;
|
||||
while(val) {
|
||||
ptr = strchr(val,',');
|
||||
if(ptr) *ptr = 0;
|
||||
config.display[idx++] = atoi(val);
|
||||
val = ptr?ptr+1:NULL;
|
||||
Serial.printf("appending value %d next is %s\n", config.display[idx-1], val?val:"");
|
||||
}
|
||||
config.display[idx] = -1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// skipping non-supported types
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if(i==N_CONFIG) {
|
||||
Serial.printf("Invalid config option '%s'=%s \n", cfg, val);
|
||||
}
|
||||
}
|
||||
|
||||
void Sonde::setIP(String ip, bool AP) {
|
||||
ipaddr = ip;
|
||||
isAP = AP;
|
||||
}
|
||||
|
||||
void Sonde::clearSonde() {
|
||||
nSonde = 0;
|
||||
}
|
||||
void Sonde::addSonde(float frequency, SondeType type, int active, char *launchsite) {
|
||||
if(nSonde>=config.maxsonde) {
|
||||
Serial.println("Cannot add another sonde, MAXSONDE reached");
|
||||
return;
|
||||
}
|
||||
Serial.printf("Adding %f - %d - %d - %s\n", frequency, type, active, launchsite);
|
||||
// reset all data if type or frequency has changed
|
||||
if(type != sondeList[nSonde].type || frequency != sondeList[nSonde].freq) {
|
||||
//TODO: Check for potential race condition with decoders
|
||||
// do not clear extra while decoder is potentiall still accessing it!
|
||||
if(sondeList[nSonde].extra) free(sondeList[nSonde].extra);
|
||||
memset(&sondeList[nSonde], 0, sizeof(SondeInfo));
|
||||
sondeList[nSonde].type = type;
|
||||
sondeList[nSonde].d.typestr[0] = 0;
|
||||
sondeList[nSonde].freq = frequency;
|
||||
memcpy(sondeList[nSonde].rxStat, "\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3", 18); // unknown/undefined
|
||||
clearAllData(sondeList+nSonde);
|
||||
}
|
||||
sondeList[nSonde].active = active;
|
||||
strncpy(sondeList[nSonde].launchsite, launchsite, 17);
|
||||
nSonde++;
|
||||
}
|
||||
|
||||
// called by updateState (only)
|
||||
void Sonde::nextConfig() {
|
||||
currentSonde++;
|
||||
if(currentSonde>=config.maxsonde) {
|
||||
currentSonde=0;
|
||||
}
|
||||
// Skip non-active entries (but don't loop forever if there are no active ones)
|
||||
for(int i=0; i<config.maxsonde - 1; i++) {
|
||||
if(!sondeList[currentSonde].active) {
|
||||
currentSonde++;
|
||||
if(currentSonde>=config.maxsonde) currentSonde=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void Sonde::nextRxSonde() {
|
||||
rxtask.currentSonde++;
|
||||
if(rxtask.currentSonde>=config.maxsonde) {
|
||||
rxtask.currentSonde=0;
|
||||
}
|
||||
for(int i=0; i<config.maxsonde - 1; i++) {
|
||||
if(!sondeList[rxtask.currentSonde].active) {
|
||||
rxtask.currentSonde++;
|
||||
if(rxtask.currentSonde>=config.maxsonde) rxtask.currentSonde=0;
|
||||
}
|
||||
}
|
||||
//Serial.printf("nextRxSonde: %d\n", rxtask.currentSonde);
|
||||
}
|
||||
void Sonde::nextRxFreq(int addkhz) {
|
||||
// last entry is for the variable frequency
|
||||
rxtask.currentSonde = nSonde - 1;
|
||||
sondeList[rxtask.currentSonde].active = 1;
|
||||
sondeList[rxtask.currentSonde].freq += addkhz*0.001;
|
||||
if(sondeList[rxtask.currentSonde].freq>406)
|
||||
sondeList[rxtask.currentSonde].freq = 400;
|
||||
Serial.printf("nextRxFreq: %d\n", rxtask.currentSonde);
|
||||
}
|
||||
SondeInfo *Sonde::si() {
|
||||
return &sondeList[currentSonde];
|
||||
}
|
||||
|
||||
void Sonde::setup() {
|
||||
if(rxtask.currentSonde<0 || rxtask.currentSonde>=config.maxsonde) {
|
||||
Serial.print("Invalid rxtask.currentSonde: ");
|
||||
Serial.println(rxtask.currentSonde);
|
||||
rxtask.currentSonde = 0;
|
||||
for(int i=0; i<config.maxsonde - 1; i++) {
|
||||
if(!sondeList[rxtask.currentSonde].active) {
|
||||
rxtask.currentSonde++;
|
||||
if(rxtask.currentSonde>=config.maxsonde) rxtask.currentSonde=0;
|
||||
}
|
||||
}
|
||||
sonde.currentSonde = rxtask.currentSonde;
|
||||
}
|
||||
|
||||
// update receiver config
|
||||
Serial.print("Sonde::setup() start on index ");
|
||||
Serial.println(rxtask.currentSonde);
|
||||
switch(sondeList[rxtask.currentSonde].type) {
|
||||
case STYPE_RS41:
|
||||
rs41.setup(sondeList[rxtask.currentSonde].freq * 1000000);
|
||||
break;
|
||||
case STYPE_DFM:
|
||||
dfm.setup( sondeList[rxtask.currentSonde].freq * 1000000, sondeList[rxtask.currentSonde].type );
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
rs92.setup( sondeList[rxtask.currentSonde].freq * 1000000);
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
case STYPE_M10M20:
|
||||
m10m20.setup( sondeList[rxtask.currentSonde].freq * 1000000);
|
||||
break;
|
||||
case STYPE_MP3H:
|
||||
mp3h.setup( sondeList[rxtask.currentSonde].freq * 1000000);
|
||||
break;
|
||||
}
|
||||
// debug
|
||||
int freq = (int)sx1278.getFrequency();
|
||||
int afcbw = (int)sx1278.getAFCBandwidth();
|
||||
int rxbw = (int)sx1278.getRxBandwidth();
|
||||
Serial.printf("Sonde::setup() done: Type %s Freq %f, AFC BW: %d, RX BW: %d\n", sondeTypeStr[sondeList[rxtask.currentSonde].type], 0.000001*freq, afcbw, rxbw);
|
||||
|
||||
// reset rxtimer / norxtimer state
|
||||
sonde.sondeList[sonde.currentSonde].lastState = -1;
|
||||
}
|
||||
|
||||
extern void flashLed(int ms);
|
||||
extern void buzzerLed(int temps);
|
||||
|
||||
void Sonde::receive() {
|
||||
uint16_t res = 0;
|
||||
SondeInfo *si = &sondeList[rxtask.currentSonde];
|
||||
switch(si->type) {
|
||||
case STYPE_RS41:
|
||||
res = rs41.receive();
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
res = rs92.receive();
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
case STYPE_M10M20:
|
||||
res = m10m20.receive();
|
||||
break;
|
||||
case STYPE_DFM:
|
||||
res = dfm.receive();
|
||||
break;
|
||||
case STYPE_MP3H:
|
||||
res = mp3h.receive();
|
||||
break;
|
||||
}
|
||||
|
||||
// state information for RX_TIMER / NORX_TIMER events
|
||||
if(res==RX_OK || res==RX_ERROR) { // something was received...
|
||||
|
||||
flashLed(700);
|
||||
if(sonde.config.buzzerOn==1) {
|
||||
buzzerLed(500);
|
||||
}
|
||||
if(si->lastState != 1) {
|
||||
si->rxStart = millis();
|
||||
si->lastState = 1;
|
||||
sonde.dispsavectlON();
|
||||
}
|
||||
} else { // RX Timeout
|
||||
flashLed( (res==RX_OK)?700:100);
|
||||
ledcWriteTone(0, 0);
|
||||
//Serial.printf("Sonde::receive(): result %d (%s), laststate was %d\n", res, (res<=3)?RXstr[res]:"?", si->lastState);
|
||||
if(si->lastState != 0) {
|
||||
si->norxStart = millis();
|
||||
si->lastState = 0;
|
||||
}
|
||||
}
|
||||
// Serial.printf("debug: res was %d, now lastState is %d\n", res, si->lastState);
|
||||
|
||||
|
||||
// we should handle timer events here, because after returning from receive,
|
||||
// we'll directly enter setup
|
||||
rxtask.receiveSonde = rxtask.currentSonde; // pass info about decoded sonde to main loop
|
||||
|
||||
int event = getKeyPressEvent();
|
||||
if (!event) event = timeoutEvent(si);
|
||||
else sonde.dispsavectlON();
|
||||
int action = (event==EVT_NONE) ? ACT_NONE : disp.layout->actions[event];
|
||||
//if(action!=ACT_NONE) { Serial.printf("event %x: action is %x\n", event, action); }
|
||||
// If action is to move to a different sonde index, we do update things here, set activate
|
||||
// to force the sx1278 task to call sonde.setup(), and pass information about sonde to
|
||||
// main loop (display update...)
|
||||
if(action == ACT_DISPLAY_SCANNER || action == ACT_NEXTSONDE || action==ACT_PREVSONDE || (action>64&&action<128) ) {
|
||||
// handled here...
|
||||
if(action==ACT_DISPLAY_SCANNER) {
|
||||
// nothing to do here, be re-call setup() for M10/M20 for repeating AFC
|
||||
}
|
||||
else {
|
||||
if(action==ACT_NEXTSONDE||action==ACT_PREVSONDE)
|
||||
nextRxSonde();
|
||||
else
|
||||
nextRxFreq( action-64 );
|
||||
action = ACT_SONDE(rxtask.currentSonde);
|
||||
}
|
||||
if(rxtask.activate==-1) {
|
||||
// race condition here. maybe better use mutex. TODO
|
||||
rxtask.activate = ACT_SONDE(rxtask.currentSonde);
|
||||
}
|
||||
}
|
||||
Serial.printf("Sonde:receive(): result %d (%s), event %02x => action %02x\n", res, (res<=3)?RXstr[res]:"?", event, action);
|
||||
res = (action<<8) | (res&0xff);
|
||||
// let waitRXcomplete resume...
|
||||
rxtask.receiveResult = res;
|
||||
}
|
||||
|
||||
// return (action<<8) | (rxresult)
|
||||
uint16_t Sonde::waitRXcomplete() {
|
||||
uint16_t res=0;
|
||||
uint32_t t0 = millis();
|
||||
rxloop:
|
||||
while( (pmu_irq!=1) && rxtask.receiveResult==0xFFFF && millis()-t0 < 3000) { delay(50); }
|
||||
if( pmu_irq ) {
|
||||
handlePMUirq();
|
||||
if(pmu_irq!=2) goto rxloop;
|
||||
}
|
||||
if( rxtask.receiveResult == RX_UPDATERSSI ) {
|
||||
rxtask.receiveResult = 0xFFFF;
|
||||
Serial.printf("RSSI update: %d/2\n", sonde.si()->rssi);
|
||||
disp.updateDisplayRSSI();
|
||||
goto rxloop;
|
||||
}
|
||||
|
||||
if( rxtask.receiveResult==0xFFFF) {
|
||||
Serial.println("TIMEOUT in waitRXcomplete. Should never happen!\n");
|
||||
res = RX_TIMEOUT;
|
||||
} else {
|
||||
res = rxtask.receiveResult;
|
||||
}
|
||||
rxtask.receiveResult = 0xFFFF;
|
||||
/// TODO: THis has caused an exception when swithcing back to spectrumm...
|
||||
Serial.printf("waitRXcomplete returning %04x (%s)\n", res, (res&0xff)<4?RXstr[res&0xff]:"");
|
||||
// currently used only by RS92
|
||||
switch(sondeList[rxtask.receiveSonde].type) {
|
||||
case STYPE_RS41:
|
||||
rs41.waitRXcomplete();
|
||||
break;
|
||||
case STYPE_RS92:
|
||||
rs92.waitRXcomplete();
|
||||
break;
|
||||
case STYPE_M10:
|
||||
case STYPE_M20:
|
||||
case STYPE_M10M20:
|
||||
m10m20.waitRXcomplete();
|
||||
break;
|
||||
case STYPE_DFM:
|
||||
dfm.waitRXcomplete();
|
||||
break;
|
||||
case STYPE_MP3H:
|
||||
mp3h.waitRXcomplete();
|
||||
break;
|
||||
}
|
||||
memmove(sonde.si()->rxStat+1, sonde.si()->rxStat, 17);
|
||||
sonde.si()->rxStat[0] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint8_t Sonde::timeoutEvent(SondeInfo *si) {
|
||||
uint32_t now = millis();
|
||||
#if 0
|
||||
Serial.printf("Timeout check: %d - %d vs %d; %d - %d vs %d; %d - %d vs %d; lastState: %d\n",
|
||||
now, si->viewStart, disp.layout->timeouts[0],
|
||||
now, si->rxStart, disp.layout->timeouts[1],
|
||||
now, si->norxStart, disp.layout->timeouts[2], si->lastState);
|
||||
#endif
|
||||
if(disp.layout->timeouts[0]>=0 && now - si->viewStart >= disp.layout->timeouts[0]) {
|
||||
Serial.println("Sonde::timeoutEvent: View");
|
||||
return EVT_VIEWTO;
|
||||
}
|
||||
if(si->lastState==1 && disp.layout->timeouts[1]>=0 && now - si->rxStart >= disp.layout->timeouts[1]) {
|
||||
Serial.println("Sonde::timeoutEvent: RX");
|
||||
return EVT_RXTO;
|
||||
}
|
||||
if(si->lastState==0 && disp.layout->timeouts[2]>=0 && now - si->norxStart >= disp.layout->timeouts[2]) {
|
||||
Serial.println("Sonde::timeoutEvent: NORX");
|
||||
return EVT_NORXTO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t Sonde::updateState(uint8_t event) {
|
||||
//Serial.printf("Sonde::updateState for event %02x\n", event);
|
||||
// No change
|
||||
if(event==ACT_NONE) return 0xFF;
|
||||
|
||||
// In all cases (new display mode, new sonde) we reset the mode change timers
|
||||
sonde.sondeList[sonde.currentSonde].viewStart = millis();
|
||||
sonde.sondeList[sonde.currentSonde].lastState = -1;
|
||||
|
||||
// Moving to a different display mode
|
||||
if (event==ACT_DISPLAY_SPECTRUM || event==ACT_DISPLAY_WIFI) {
|
||||
// main loop will call setMode() and disable sx1278 background task
|
||||
return event;
|
||||
}
|
||||
int n = event;
|
||||
if(event==ACT_DISPLAY_DEFAULT) {
|
||||
n = config.display[1];
|
||||
} else if(event==ACT_DISPLAY_SCANNER) {
|
||||
n= config.display[0];
|
||||
} else if(event==ACT_DISPLAY_NEXT) {
|
||||
int i;
|
||||
for(i=0; config.display[i]!=-1; i++) {
|
||||
if(config.display[i] == disp.layoutIdx) break;
|
||||
}
|
||||
if(config.display[i]==-1 || config.display[i+1]==-1) {
|
||||
//unknown index, or end of list => loop to start
|
||||
n = config.display[1];
|
||||
} else {
|
||||
n = config.display[i+1];
|
||||
}
|
||||
}
|
||||
if(n>=0 && n<ACT_MAXDISPLAY) {
|
||||
if(n>=disp.nLayouts) {
|
||||
Serial.println("WARNNG: next layout out of range");
|
||||
n = config.display[1];
|
||||
}
|
||||
Serial.printf("Setting display mode %d\n", n);
|
||||
disp.setLayout(n);
|
||||
sonde.clearDisplay();
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
// Moving to a different value for currentSonde
|
||||
// TODO: THis should be done in sx1278 task, not in main loop!!!!!
|
||||
if(event==ACT_NEXTSONDE) {
|
||||
sonde.nextConfig();
|
||||
Serial.printf("advancing to next sonde %d\n", sonde.currentSonde);
|
||||
return event;
|
||||
}
|
||||
if (event==ACT_PREVSONDE) {
|
||||
// TODO
|
||||
Serial.printf("previous not supported, advancing to next sonde\n");
|
||||
sonde.nextConfig();
|
||||
return ACT_NEXTSONDE;
|
||||
}
|
||||
if(event&0x80) {
|
||||
sonde.currentSonde = (event&0x7F);
|
||||
return ACT_NEXTSONDE;
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
|
||||
void Sonde::clearAllData(SondeInfo *si) {
|
||||
// set everything to 0
|
||||
memset(&(si->d), 0, sizeof(SondeData));
|
||||
// set floats to NaN
|
||||
si->d.lat = si->d.lon = si->d.alt = si->d.vs = si->d.hs = si->d.dir = NAN;
|
||||
si->d.temperature = si->d.tempRHSensor = si->d.relativeHumidity = si->d.pressure = si->d.batteryVoltage = NAN;
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayPos() {
|
||||
disp.updateDisplayPos();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayPos2() {
|
||||
disp.updateDisplayPos2();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayID() {
|
||||
disp.updateDisplayID();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayRSSI() {
|
||||
disp.updateDisplayRSSI();
|
||||
}
|
||||
|
||||
void Sonde::updateStat() {
|
||||
disp.updateStat();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayRXConfig() {
|
||||
disp.updateDisplayRXConfig();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplayIP() {
|
||||
disp.updateDisplayIP();
|
||||
}
|
||||
|
||||
void Sonde::updateDisplay()
|
||||
{
|
||||
disp.updateDisplay();
|
||||
}
|
||||
|
||||
void Sonde::clearDisplay() {
|
||||
disp.rdis->clear();
|
||||
}
|
||||
|
||||
void Sonde::dispsavectlON() {
|
||||
disp.dispsavectlON();
|
||||
}
|
||||
|
||||
void Sonde::dispsavectlOFF(int rxactive) {
|
||||
disp.dispsavectlOFF(rxactive);
|
||||
}
|
||||
|
||||
|
||||
SondeType Sonde::realType(SondeInfo *si) {
|
||||
if(TYPE_IS_METEO(si->type) && si->d.subtype>0 ) { return si->d.subtype==1 ? STYPE_M10:STYPE_M20; }
|
||||
else return si->type;
|
||||
}
|
||||
|
||||
Sonde sonde = Sonde();
|
377
RX_FSK/src/Sonde.h
Normal file
377
RX_FSK/src/Sonde.h
Normal file
|
@ -0,0 +1,377 @@
|
|||
|
||||
#ifndef Sonde_h
|
||||
#define Sonde_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
enum DbgLevel { DEBUG_OFF=0, DEBUG_INFO=1, DEBUG_SPARSER=16, DEBUG_DISPLAY=8 }; // to be extended for configuring serial debug output
|
||||
extern uint8_t debug;
|
||||
|
||||
#define DebugPrint(l,x) if(debug&l) { Serial.print(x); }
|
||||
#define DebugPrintln(l,x) if(debug&l) { Serial.println(x); }
|
||||
#define DebugPrintf(l,...) if(debug&l) { Serial.printf(__VA_ARGS__); }
|
||||
|
||||
// RX_TIMEOUT: no header detected
|
||||
// RX_ERROR: header detected, but data not decoded (crc error, etc.)
|
||||
// RX_PARTIAL: header detected, some data ok, some with errors
|
||||
// For RS41: Some blocks with CRC error, some blocks ok in a single frame
|
||||
// For DFM: In +- 1s, some but not all DAT-subframes 1,2,3,4,5,6,7,8 received
|
||||
// For RS92 ??? unclear
|
||||
// For M10/M20 its always all or nothing, no PARTIAL data
|
||||
// For MP3H its alway all or nothing, no PARTIAL data
|
||||
// RX_OK: header and all data ok
|
||||
enum RxResult { RX_OK, RX_TIMEOUT, RX_ERROR, RX_UNKNOWN, RX_NOPOS };
|
||||
#define RX_UPDATERSSI 0xFFFE
|
||||
|
||||
// Events that change what is displayed (mode, sondenr)
|
||||
// Keys:
|
||||
// 1 Button (short) or Touch (short)
|
||||
// 2 Button (double) or Touch (double)
|
||||
// 3 Button (mid) or Touch (mid)
|
||||
// 4 Button (long) or Touch (long)
|
||||
// 5 Touch1/2 (short)
|
||||
// 6 Touch1/2 (double)
|
||||
// 7 Touch1/2 (mid)
|
||||
// 8 Touch1/2 (long)
|
||||
|
||||
/* Keypress => Sonde++ / Sonde-- / Display:=N*/
|
||||
enum Events { EVT_NONE, EVT_KEY1SHORT, EVT_KEY1DOUBLE, EVT_KEY1MID, EVT_KEY1LONG,
|
||||
EVT_KEY2SHORT, EVT_KEY2DOUBLE, EVT_KEY2MID, EVT_KEY2LONG,
|
||||
EVT_VIEWTO, EVT_RXTO, EVT_NORXTO,
|
||||
EVT_MAX };
|
||||
extern const char *evstring[];
|
||||
extern const char *RXstr[];
|
||||
#define EVENTNAME(s) evstring[s]
|
||||
|
||||
//int8_t actions[EVT_MAX];
|
||||
#define ACT_NONE 255
|
||||
#define ACT_DISPLAY(n) (n)
|
||||
#define ACT_MAXDISPLAY 50
|
||||
#define ACT_DISPLAY_SCANNER 0
|
||||
#define ACT_DISPLAY_NEXT 64
|
||||
#define ACT_DISPLAY_DEFAULT 63
|
||||
#define ACT_DISPLAY_SPECTRUM 62
|
||||
#define ACT_DISPLAY_WIFI 61
|
||||
#define ACT_NEXTSONDE 65
|
||||
#define ACT_PREVSONDE 66
|
||||
#define ACT_ADDFREQ(n) ((n)+64)
|
||||
#define ACT_SONDE(n) ((n)+128)
|
||||
|
||||
// 0000nnnn => goto display nnnn
|
||||
// 01000000 => goto sonde -1
|
||||
// 01000001 => goto sonde +1
|
||||
|
||||
#define NSondeTypes 7
|
||||
enum SondeType { STYPE_DFM, STYPE_RS41, STYPE_RS92, STYPE_M10M20, STYPE_M10, STYPE_M20, STYPE_MP3H };
|
||||
extern const char *sondeTypeStr[NSondeTypes];
|
||||
extern const char *sondeTypeLongStr[NSondeTypes];
|
||||
extern const char sondeTypeChar[NSondeTypes];
|
||||
extern const char *manufacturer_string[NSondeTypes];
|
||||
|
||||
#define ISOLED(cfg) ((cfg).disptype==0 || (cfg).disptype==2)
|
||||
|
||||
#define TYPE_IS_DFM(t) ( (t)==STYPE_DFM )
|
||||
#define TYPE_IS_METEO(t) ( (t)==STYPE_M10M20 || (t)==STYPE_M10 || (t)==STYPE_M20 )
|
||||
|
||||
#define VALIDPOS(x) (((x)&0x03)==0x03)
|
||||
#define VALIDALT(x) ((x)&0x04)
|
||||
#define VALIDVS(x) ((x)&0x08)
|
||||
#define VALIDHS(x) ((x)&0x10)
|
||||
#define VALIDDIR(x) ((x)&0x20)
|
||||
#define VALIDSATS(x) ((x)&0x40)
|
||||
|
||||
typedef struct st_sondedata {
|
||||
// decoded ID
|
||||
char id[10];
|
||||
char ser[12];
|
||||
bool validID;
|
||||
char typestr[5]; // decoded type (use type if *typestr==0)
|
||||
int8_t subtype; /* 0 for none/unknown, hex type for dfm, 1/2 for M10/M20 */
|
||||
// decoded position
|
||||
float lat; // latitude
|
||||
float lon; // longitude
|
||||
float alt; // altitude
|
||||
float vs; // vertical speed in m/s
|
||||
float hs; // horizontal speed in m/s
|
||||
float dir; // 0..360
|
||||
uint8_t sats; // number of sats
|
||||
uint8_t validPos; // bit pattern for validity of above 7 fields; 0x80: position is old
|
||||
// decoded GPS time
|
||||
uint32_t time;
|
||||
uint32_t frame;
|
||||
uint32_t vframe; // vframe==frame if frame is unique/continous, otherweise vframe is derived from gps time
|
||||
bool validTime;
|
||||
// shut down timers, currently only for RS41; -1=disabled
|
||||
uint16_t launchKT, burstKT, countKT;
|
||||
uint16_t crefKT; // frame number in which countKT was last sent
|
||||
// sonde specific extra data, NULL if unused or not yet initialized, currently used for RS41 subframe data (calibration)
|
||||
float temperature; // platinum resistor temperature
|
||||
float tempRHSensor; // temperature of relative humidity sensor
|
||||
float relativeHumidity; // relative humidity
|
||||
float pressure;
|
||||
float batteryVoltage = -1;
|
||||
} SondeData;
|
||||
|
||||
typedef struct st_sondeinfo {
|
||||
// First part: static configuration, not decoded data.
|
||||
// receiver configuration
|
||||
bool active;
|
||||
SondeType type;
|
||||
float freq;
|
||||
char launchsite[18];
|
||||
|
||||
// Second part: internal decoder state. no need to clear this on new sonde
|
||||
// RSSI from receiver
|
||||
int rssi; // signal strength
|
||||
int32_t afc; // afc correction value
|
||||
// statistics
|
||||
uint8_t rxStat[20];
|
||||
uint32_t rxStart; // millis() timestamp of continuous rx start
|
||||
uint32_t norxStart; // millis() timestamp of continuous no rx start
|
||||
uint32_t viewStart; // millis() timestamp of viewinf this sonde with current display
|
||||
int8_t lastState; // -1: disabled; 0: norx; 1: rx
|
||||
// Third part: decoded data. Clear if reception of a new sonde has started
|
||||
SondeData d;
|
||||
|
||||
// Decoder-specific data, dynamically allocated (for RS41: calibration data)
|
||||
void *extra;
|
||||
} SondeInfo;
|
||||
// rxStat: 3=undef[empty] 1=timeout[.] 2=errro[E] 0=ok[|] 4=no valid position[°]
|
||||
|
||||
// Used for interacting with the RX background task
|
||||
typedef struct st_RXTask {
|
||||
// Variables set by Arduino main loop to value >=0 for requesting
|
||||
// mode change to sonde reception for sonde <value) in RXTask.
|
||||
// Will be reset to -1 by RXTask
|
||||
int activate;
|
||||
// Variables set by RXTask, corresponding to mode ST_DECODER (if active) or something else,
|
||||
// and currently received sonde
|
||||
int mainState;
|
||||
int currentSonde;
|
||||
// Variable set by RXTask to communicate status to Arduino task
|
||||
// via waitRXcomplete function
|
||||
uint16_t receiveResult;
|
||||
uint16_t receiveSonde; // sonde inde corresponding to receiveResult
|
||||
// status variabe set by decoder to indicate something is broken
|
||||
// int fifoOverflow;
|
||||
} RXTask;
|
||||
|
||||
extern RXTask rxtask;
|
||||
|
||||
struct st_rs41config {
|
||||
int agcbw;
|
||||
int rxbw;
|
||||
};
|
||||
struct st_rs92config {
|
||||
int rxbw;
|
||||
int alt2d;
|
||||
};
|
||||
struct st_dfmconfig {
|
||||
int agcbw;
|
||||
int rxbw;
|
||||
};
|
||||
struct st_m10m20config {
|
||||
int agcbw;
|
||||
int rxbw;
|
||||
};
|
||||
struct st_mp3hconfig {
|
||||
int agcbw;
|
||||
int rxbw;
|
||||
};
|
||||
|
||||
|
||||
struct st_feedinfo {
|
||||
bool active;
|
||||
int type; // 0:UDP(axudp), 1:TCP(aprs.fi)
|
||||
char host[64];
|
||||
int port;
|
||||
char symbol[3];
|
||||
int lowrate;
|
||||
int highrate;
|
||||
int lowlimit;
|
||||
};
|
||||
|
||||
// maybe extend for external Bluetooth interface?
|
||||
// internal bluetooth consumes too much memory
|
||||
struct st_kisstnc {
|
||||
bool active;
|
||||
};
|
||||
|
||||
struct st_mqtt {
|
||||
int active;
|
||||
char id[64];
|
||||
char host[64];
|
||||
int port;
|
||||
char username[64];
|
||||
char password[64];
|
||||
char prefix[64];
|
||||
};
|
||||
|
||||
struct st_cm {
|
||||
int active;
|
||||
char host[64];
|
||||
int port;
|
||||
};
|
||||
|
||||
struct st_sondehub {
|
||||
int active;
|
||||
int chase;
|
||||
char host[64];
|
||||
char callsign[64];
|
||||
char antenna[64];
|
||||
char email[64];
|
||||
int fiactive;
|
||||
int fiinterval;
|
||||
int fimaxdist;
|
||||
double fimaxage;
|
||||
};
|
||||
|
||||
// to be extended
|
||||
enum { TYPE_TTGO, TYPE_M5_CORE2 };
|
||||
|
||||
typedef struct st_rdzconfig {
|
||||
int type; // autodetected type, TTGO or M5_CORE2
|
||||
// hardware configuration
|
||||
int button_pin; // PIN port number menu button (+128 for touch mode)
|
||||
int button2_pin; // PIN port number menu button (+128 for touch mode)
|
||||
int button2_axp; // Use AXP192 power button as button2
|
||||
int touch_thresh; // Threshold value (0..100) for touch input button
|
||||
int led_pout; // POUT port number of LED (used as serial monitor)
|
||||
int power_pout; // Power control pin (for Heltec v2)
|
||||
int disptype; // 0=OLED; 1=ILI9225
|
||||
int oled_sda; // OLED/TFT data pin
|
||||
int oled_scl; // OLED/TFT clock pin
|
||||
int oled_rst; // OLED/TFT reset pin
|
||||
int oled_orient; // OLED/TFT orientation (default: 1)
|
||||
int gps_rxd; // GPS module RXD pin. We expect 9600 baud NMEA data.
|
||||
int gps_txd; // GPS module TXD pin
|
||||
int batt_adc; // Pin for ADC battery measurement (GPIO35 on TTGO V2.1_1.6)
|
||||
int sx1278_ss; // SPI slave select for sx1278
|
||||
int sx1278_miso; // SPI MISO for sx1278
|
||||
int sx1278_mosi; // SPI MOSI for sx1278
|
||||
int sx1278_sck; // SPI SCK for sx1278
|
||||
// software configuration
|
||||
int debug; // show port and config options after reboot
|
||||
double rxlat;
|
||||
double rxlon;
|
||||
double rxalt;
|
||||
int wifi; // connect to known WLAN 0=skip
|
||||
int screenfile;
|
||||
int8_t display[30]; // list of display mode (0:scanner, 1:default, 2,... additional modes)
|
||||
int dispsaver; // Turn display on/off (0=always on, 10*n+1: off after n seconds,
|
||||
// 10*n+2: scanner off after n seconds, RX always shown)
|
||||
int dispcontrast; // For OLED: set contrast to 0..255 (-1: don't set/leave at factory default)
|
||||
int startfreq; // spectrum display start freq (400, 401, ...)
|
||||
int channelbw; // spectrum channel bandwidth (valid: 5, 10, 20, 25, 50, 100 kHz)
|
||||
int spectrum; // show freq spectrum for n seconds -1=disable; 0=forever
|
||||
int marker; // show freq marker in spectrum 0=disable
|
||||
int maxsonde; // number of max sonde in scan (range=1-99)
|
||||
int norx_timeout; // Time after which rx mode switches to scan mode (without rx signal)
|
||||
int noisefloor; // for spectrum display
|
||||
char mdnsname[15]; // mDNS-Name, defaults to rdzsonde
|
||||
// Add f4IYT
|
||||
int buzzerPort; // Buzzer port
|
||||
int buzzerFreq; // Buzzer Frequency
|
||||
int buzzerOn; // Buzzer On
|
||||
int dbsmetre; // Db or Smetre display
|
||||
int degdec; // Degres or Decimal 0=decimal 1=degres
|
||||
// receiver configuration
|
||||
int freqofs; // frequency offset (tuner config = rx frequency + freqofs) in Hz
|
||||
struct st_rs41config rs41; // configuration options specific for RS41 receiver
|
||||
struct st_rs92config rs92;
|
||||
struct st_dfmconfig dfm;
|
||||
struct st_m10m20config m10m20;
|
||||
struct st_mp3hconfig mp3h;
|
||||
char ephftp[40];
|
||||
// data feed configuration
|
||||
// for now, one feed for each type is enough, but might get extended to more?
|
||||
char call[10]; // APRS callsign
|
||||
int passcode; // APRS passcode
|
||||
int chase;
|
||||
char objcall[10]; // APRS object call (for wettersonde.net)
|
||||
char beaconsym[5]; // APRS beacon symbol
|
||||
char comment[32];
|
||||
struct st_feedinfo udpfeed; // target for AXUDP messages
|
||||
struct st_feedinfo tcpfeed; // target for APRS-IS TCP connections
|
||||
struct st_kisstnc kisstnc; // target for KISS TNC (via TCP, mainly for APRSdroid)
|
||||
struct st_mqtt mqtt;
|
||||
struct st_sondehub sondehub;
|
||||
struct st_cm cm;
|
||||
} RDZConfig;
|
||||
|
||||
|
||||
struct st_configitems {
|
||||
const char *name;
|
||||
// const char *label; => now handled in JS
|
||||
int type; // 0: numeric; i>0 string of length i; -1: separator; -2: type selector
|
||||
void *data;
|
||||
};
|
||||
|
||||
// defined in RX_FSK.ino
|
||||
extern struct st_configitems config_list[];
|
||||
extern const int N_CONFIG;
|
||||
|
||||
|
||||
#define MAXSONDE 50
|
||||
|
||||
extern int fingerprintValue[];
|
||||
extern const char *fingerprintText[];
|
||||
|
||||
class Sonde
|
||||
{
|
||||
private:
|
||||
public:
|
||||
RDZConfig config;
|
||||
int fingerprint = 0;
|
||||
int currentSonde = 0;
|
||||
int nSonde;
|
||||
String ipaddr;
|
||||
bool isAP;
|
||||
// moved to heap, saving space in .bss
|
||||
//SondeInfo sondeList[MAXSONDE+1];
|
||||
SondeInfo *sondeList;
|
||||
// helper function for type string
|
||||
static SondeType realType(SondeInfo *si);
|
||||
|
||||
Sonde();
|
||||
void defaultConfig();
|
||||
void checkConfig();
|
||||
void setConfig(const char *str);
|
||||
|
||||
void clearSonde();
|
||||
void addSonde(float frequency, SondeType type, int active, char *launchsite);
|
||||
void nextConfig();
|
||||
void nextRxSonde();
|
||||
void nextRxFreq(int addkhz);
|
||||
|
||||
/* new interface */
|
||||
void setup();
|
||||
void receive();
|
||||
uint16_t waitRXcomplete();
|
||||
|
||||
SondeInfo *si();
|
||||
void clearAllData(SondeInfo *si);
|
||||
|
||||
uint8_t timeoutEvent(SondeInfo *si);
|
||||
uint8_t updateState(uint8_t event);
|
||||
|
||||
void updateDisplayPos();
|
||||
void updateDisplayPos2();
|
||||
void updateDisplayID();
|
||||
void updateDisplayRSSI();
|
||||
void updateDisplayRXConfig();
|
||||
void updateStat();
|
||||
void updateDisplayIP();
|
||||
void updateDisplay();
|
||||
void clearDisplay();
|
||||
void dispsavectlON();
|
||||
void dispsavectlOFF(int rxactive);
|
||||
|
||||
void setIP(String ip, bool isAP);
|
||||
};
|
||||
|
||||
extern Sonde sonde;
|
||||
|
||||
#endif
|
||||
|
391
RX_FSK/src/aprs.cpp
Normal file
391
RX_FSK/src/aprs.cpp
Normal file
|
@ -0,0 +1,391 @@
|
|||
/* Copyright (C) Hansi Reiser, dl9rdz
|
||||
*
|
||||
* partially based on dxlAPRS toolchain
|
||||
*
|
||||
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <WString.h>
|
||||
#include <stdlib.h>
|
||||
//#include <arpa/inet.h>
|
||||
//#include <sys/socket.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include "aprs.h"
|
||||
|
||||
extern const char *version_name;
|
||||
extern const char *version_id;
|
||||
#if 0
|
||||
int openudp(const char *ip, int port, struct sockaddr_in *si) {
|
||||
int fd;
|
||||
if((fd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1) return -1;
|
||||
memset((char *)&si, 0, sizeof(si));
|
||||
si->sin_family = AF_INET;
|
||||
si->sin_port = htons(port);
|
||||
if(inet_aton(ip, &(si->sin_addr))==0) {
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
int sendudp(int fd, struct sockaddr_in *si, char *frame, int framelen)
|
||||
{
|
||||
if(sendto(fd, frame, framelen, 0, (struct sockaddr *)si, sizeof(struct sockaddr_in))==-1) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void aprsstr_append(char *b, const char *data)
|
||||
{
|
||||
int blen=strlen(b);
|
||||
int len=strlen(data);
|
||||
if(blen+len>APRS_MAXLEN) len=APRS_MAXLEN-blen;
|
||||
strncat(b, data, len);
|
||||
}
|
||||
|
||||
uint32_t realcard(float x) {
|
||||
if(x<0) return 0;
|
||||
else return (uint32_t)x;
|
||||
}
|
||||
|
||||
|
||||
/* CRC for AXUDP frames */
|
||||
|
||||
#define APRSCRC_POLY 0x8408
|
||||
static uint8_t CRCL[256];
|
||||
static uint8_t CRCH[256];
|
||||
|
||||
void aprs_gencrctab(void)
|
||||
{
|
||||
uint32_t c;
|
||||
uint32_t crc;
|
||||
uint32_t i;
|
||||
for (c = 0UL; c<=255UL; c++) {
|
||||
crc = 255UL-c;
|
||||
for (i = 0UL; i<=7UL; i++) {
|
||||
if ((crc&1)) crc = (uint32_t)((uint32_t)(crc>>1)^APRSCRC_POLY);
|
||||
else crc = crc>>1;
|
||||
} /* end for */
|
||||
CRCL[c] = (uint8_t)crc;
|
||||
CRCH[c] = (uint8_t)(255UL-(crc>>8));
|
||||
} /* end for */
|
||||
} /* end Gencrctab() */
|
||||
|
||||
static void aprsstr_appcrc(char frame[], uint32_t frame_len, int32_t size)
|
||||
{
|
||||
uint8_t h;
|
||||
uint8_t l;
|
||||
uint8_t b;
|
||||
int32_t i;
|
||||
int32_t tmp;
|
||||
l = 0U;
|
||||
h = 0U;
|
||||
tmp = size-1L;
|
||||
i = 0L;
|
||||
if (i<=tmp) for (;; i++) {
|
||||
b = (uint8_t)((uint8_t)(uint8_t)frame[i]^l);
|
||||
l = CRCL[b]^h;
|
||||
h = CRCH[b];
|
||||
if (i==tmp) break;
|
||||
} /* end for */
|
||||
frame[size] = (char)l;
|
||||
frame[size+1L] = (char)h;
|
||||
} /* end aprsstr_appcrc() */
|
||||
|
||||
|
||||
static int mkaprscall(int32_t * p, char raw[],
|
||||
uint32_t * i, const char mon[],
|
||||
char sep1, char sep2, char sep3,
|
||||
uint32_t sbase)
|
||||
{
|
||||
uint32_t s;
|
||||
uint32_t l;
|
||||
l = 0UL;
|
||||
while ((((mon[*i] && mon[*i]!=sep1) && mon[*i]!=sep2) && mon[*i]!=sep3)
|
||||
&& mon[*i]!='-') {
|
||||
s = (uint32_t)(uint8_t)mon[*i]*2UL&255UL;
|
||||
if (s<=64UL) return 0;
|
||||
raw[*p] = (char)s;
|
||||
++*p;
|
||||
++*i;
|
||||
++l;
|
||||
if (l>=7UL) return 0;
|
||||
}
|
||||
while (l<6UL) {
|
||||
raw[*p] = '@';
|
||||
++*p;
|
||||
++l;
|
||||
}
|
||||
s = 0UL;
|
||||
if (mon[*i]=='-') {
|
||||
++*i;
|
||||
while ((uint8_t)mon[*i]>='0' && (uint8_t)mon[*i]<='9') {
|
||||
s = (s*10UL+(uint32_t)(uint8_t)mon[*i])-48UL;
|
||||
++*i;
|
||||
}
|
||||
if (s>15UL) return 0;
|
||||
}
|
||||
raw[*p] = (char)((s+sbase)*2UL);
|
||||
++*p;
|
||||
return 1;
|
||||
} /* end call() */
|
||||
|
||||
|
||||
|
||||
// returns raw len, 0 in case of error
|
||||
extern int aprsstr_mon2raw(const char *mon, char raw[], int raw_len)
|
||||
{
|
||||
uint32_t r;
|
||||
uint32_t n;
|
||||
uint32_t i;
|
||||
uint32_t tmp;
|
||||
int p = 7L;
|
||||
i = 0UL;
|
||||
fprintf(stderr,"mon2raw for %s\n", mon);
|
||||
if (!mkaprscall(&p, raw, &i, mon, '>', 0, 0, 48UL)) {
|
||||
return 0;
|
||||
}
|
||||
p = 0L;
|
||||
if (mon[i]!='>') return 0;
|
||||
/* ">" */
|
||||
++i;
|
||||
if (!mkaprscall(&p, raw, &i, mon, ':', ',', 0, 112UL)) {
|
||||
return 0;
|
||||
}
|
||||
p = 14L;
|
||||
n = 0UL;
|
||||
while (mon[i]==',') {
|
||||
++i;
|
||||
if (!mkaprscall(&p, raw, &i, mon, ':', ',', '*', 48UL)) {
|
||||
return 0;
|
||||
}
|
||||
++n;
|
||||
if (n>8UL) {
|
||||
return 0;
|
||||
}
|
||||
if (mon[i]=='*') {
|
||||
/* "*" has repeatet sign */
|
||||
++i;
|
||||
r = (uint32_t)p;
|
||||
if (r>=21UL) for (tmp = (uint32_t)(r-21UL)/7UL;;) {
|
||||
raw[r-1UL] = (char)((uint32_t)(uint8_t)raw[r-1UL]+128UL);
|
||||
/* set "has repeated" flags */
|
||||
if (!tmp) break;
|
||||
--tmp;
|
||||
r -= 7UL;
|
||||
} /* end for */
|
||||
}
|
||||
}
|
||||
if (p==0L || mon[i]!=':') {
|
||||
return 0;
|
||||
}
|
||||
raw[p-1L] = (char)((uint32_t)(uint8_t)raw[p-1L]+1UL);
|
||||
/* end address field mark */
|
||||
raw[p] = '\003';
|
||||
++p;
|
||||
raw[p] = '\360';
|
||||
++p;
|
||||
++i;
|
||||
n = 256UL;
|
||||
while (mon[i]) {
|
||||
/* copy info part */
|
||||
if (p>=(int32_t)(raw_len-1)-2L || n==0UL) {
|
||||
return 0;
|
||||
}
|
||||
raw[p] = mon[i];
|
||||
++p;
|
||||
++i;
|
||||
--n;
|
||||
}
|
||||
aprsstr_appcrc(raw, raw_len, p);
|
||||
//fprintf(stderr,"results in %s\n",raw);
|
||||
return p+2;
|
||||
} /* end mon2raw() */
|
||||
|
||||
extern int aprsstr_mon2kiss(const char *mon, char raw[], int raw_len)
|
||||
{
|
||||
char tmp[201];
|
||||
int len = aprsstr_mon2raw(mon, tmp, 201);
|
||||
if(len==0) return 0;
|
||||
int idx=0;
|
||||
raw[idx++] = '\xC0';
|
||||
raw[idx++] = 0; // channel 0
|
||||
for(int i=0; i<len-2; i++) { // -2: discard CRC, not used in KISS
|
||||
if(tmp[i]=='\xC0') {
|
||||
raw[idx++] = '\xDB';
|
||||
raw[idx++] = '\xDC';
|
||||
} else if (tmp[i]=='\xDB') {
|
||||
raw[idx++] = '\xDB';
|
||||
raw[idx++] = '\xDD';
|
||||
} else {
|
||||
raw[idx++] = tmp[i];
|
||||
}
|
||||
if(idx>=raw_len)
|
||||
return 0;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
#define FEET (1.0/0.3048)
|
||||
#define KNOTS (1.851984)
|
||||
|
||||
static uint32_t truncc(double r)
|
||||
{
|
||||
if (r<=0.0) return 0UL;
|
||||
else if (r>=2.E+9) return 2000000000UL;
|
||||
else return (uint32_t)r;
|
||||
return 0;
|
||||
} /* end truncc() */
|
||||
|
||||
|
||||
|
||||
static uint32_t dao91(double x)
|
||||
/* radix91(xx/1.1) of dddmm.mmxx */
|
||||
{
|
||||
double a;
|
||||
a = fabs(x);
|
||||
return ((truncc((a-(double)(float)truncc(a))*6.E+5)%100UL)
|
||||
*20UL+11UL)/22UL;
|
||||
} /* end dao91() */
|
||||
|
||||
|
||||
char b[251];
|
||||
//char raw[201];
|
||||
const char *destcall="APRRDZ";
|
||||
|
||||
char *aprs_send_beacon(const char *usercall, float lat, float lon, const char *sym, const char *comment) {
|
||||
*b = 0;
|
||||
aprsstr_append(b, usercall);
|
||||
aprsstr_append(b, ">");
|
||||
aprsstr_append(b, destcall);
|
||||
#if 0
|
||||
aprsstr_append(b, ":/"); // / is report with timestamp
|
||||
int i = strlen(b);
|
||||
int sec = 0; // TODO: NOW!!!
|
||||
snprintf(b+i, APRS_MAXLEN, "%02d%02d%02dh", sec/(60*60), (sec%(60*60))/60, sec%60);
|
||||
#else
|
||||
// report without timestamp
|
||||
aprsstr_append(b, ":!"); // ! is report w/p timestamp
|
||||
#endif
|
||||
// lat
|
||||
int i = strlen(b);
|
||||
int lati = abs((int)lat);
|
||||
int latm = (fabs(lat)-lati)*6000;
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, lat<0?'S':'N', sym[0]);
|
||||
// lon
|
||||
i = strlen(b);
|
||||
int loni = abs((int)lon);
|
||||
int lonm = (fabs(lon)-loni)*6000;
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, lon<0?'W':'E', sym[1]);
|
||||
// maybe add alt
|
||||
// maybe add DAO?
|
||||
i = strlen(b);
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%s", comment);
|
||||
|
||||
i = strlen(b);
|
||||
snprintf(b+i, APRS_MAXLEN-i, " %s-%s", version_name, version_id);
|
||||
//sprintf(b + strlen(b), "%s", version_name);
|
||||
return b;
|
||||
}
|
||||
|
||||
char *aprs_senddata(SondeInfo *si, const char *usercall, const char *objcall, const char *sym) {
|
||||
SondeData *s = &(si->d);
|
||||
*b=0;
|
||||
aprsstr_append(b, *objcall ? objcall : usercall);
|
||||
aprsstr_append(b, ">");
|
||||
// const char *destcall="APRARX,SONDEGATE,TCPIP,qAR,oh3bsg";
|
||||
aprsstr_append(b, destcall);
|
||||
// if(*objcall) { aprsstr_append(b, ","); aprsstr_append(b, usercall); }
|
||||
// uncompressed
|
||||
aprsstr_append(b, ":;");
|
||||
char tmp[10];
|
||||
snprintf(tmp,10,"%s ",s->id);
|
||||
aprsstr_append(b, tmp);
|
||||
aprsstr_append(b, "*");
|
||||
// time
|
||||
int i = strlen(b);
|
||||
int sec = s->time % 86400;
|
||||
snprintf(b+i, APRS_MAXLEN-1, "%02d%02d%02dh", sec/(60*60), (sec%(60*60))/60, sec%60);
|
||||
i = strlen(b);
|
||||
//aprsstr_append_data(time, ds);
|
||||
int lati = abs((int)s->lat);
|
||||
int latm = (fabs(s->lat)-lati)*6000;
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%02d%02d.%02d%c%c", lati, latm/100, latm%100, s->lat<0?'S':'N', sym[0]);
|
||||
i = strlen(b);
|
||||
int loni = abs((int)s->lon);
|
||||
int lonm = (fabs(s->lon)-loni)*6000;
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%03d%02d.%02d%c%c", loni, lonm/100, lonm%100, s->lon<0?'W':'E', sym[1]);
|
||||
if(s->hs>0.5) {
|
||||
i=strlen(b);
|
||||
snprintf(b+i, APRS_MAXLEN-i, "%03d/%03d", realcard(s->dir+1.5), realcard(s->hs*3.6/KNOTS+0.5));
|
||||
}
|
||||
if(s->alt>0.5) {
|
||||
i=strlen(b);
|
||||
snprintf(b+i, APRS_MAXLEN-i, "/A=%06d", realcard(s->alt*FEET+0.5));
|
||||
}
|
||||
// always use DAO
|
||||
i=strlen(b);
|
||||
snprintf(b+i, APRS_MAXLEN-i, "!w%c%c!", 33+dao91(s->lat), 33+dao91(s->lon));
|
||||
|
||||
// ??? strcat(b, "&");
|
||||
i=strlen(b);
|
||||
i += snprintf(b+i, APRS_MAXLEN-i, "Clb=%.1fm/s ", s->vs );
|
||||
if( !isnan(s->pressure) ) {
|
||||
sprintf(b+strlen(b), "p=%.1fhPa ", s->pressure);
|
||||
}
|
||||
if( !isnan(s->temperature) ) {
|
||||
sprintf(b+strlen(b), "t=%.1fC ", s->temperature);
|
||||
}
|
||||
if( !isnan(s->relativeHumidity) ) {
|
||||
sprintf(b+strlen(b), "h=%.1f%% ", s->relativeHumidity);
|
||||
}
|
||||
char type[12];
|
||||
if ( si->type == STYPE_RS41 && RS41::getSubtype(type, 11, si) == 0 ) {
|
||||
// type was copied to type
|
||||
} else {
|
||||
strncpy(type, sondeTypeStr[sonde.realType(si)], 11); type[11]=0;
|
||||
}
|
||||
|
||||
sprintf(b+strlen(b), "%.3fMHz Type=%s ", si->freq, type /* sondeTypeStr[sonde.realType(si)] */ );
|
||||
if( s->countKT != 0xffff && s->vframe - s->crefKT < 51 ) {
|
||||
sprintf(b+strlen(b), "TxOff=%dh%dm ", s->countKT/3600, (s->countKT-s->countKT/3600*3600)/60);
|
||||
}
|
||||
if( TYPE_IS_DFM(si->type) || TYPE_IS_METEO(si->type) ) {
|
||||
sprintf(b + strlen(b), "ser=%s ", s->ser);
|
||||
}
|
||||
sprintf(b + strlen(b), "%s", version_name);
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Gencrctab();
|
||||
|
||||
struct sockaddr_in si;
|
||||
int fd = openudp("127.0.0.1",9002,&si);
|
||||
if(fd<0) { fprintf(stderr,"open failed\n"); return 1; }
|
||||
|
||||
float lat=48, lon=10;
|
||||
while(1) {
|
||||
const char *str = aprs_senddata(lat, lon, 543, 5, 180, 1.5, "RS41", "TE0ST", "TE1ST", "EO");
|
||||
int rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
|
||||
sendudp(fd, raw, rawlen);
|
||||
|
||||
str = "OE3XKC>APMI06,qAR,OE3XLR:;ER-341109*111111z4803.61NE01532.39E0145.650MHz R15k OE3XPA";
|
||||
rawlen = aprsstr_mon2raw(str, raw, APRS_MAXLEN);
|
||||
sendudp(fd, &si, raw, rawlen);
|
||||
lat += 0.002; lon += 0.01;
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
#endif
|
16
RX_FSK/src/aprs.h
Normal file
16
RX_FSK/src/aprs.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
#ifndef _aprs_h
|
||||
#define _aprs_h
|
||||
#include "Sonde.h"
|
||||
#include "RS41.h"
|
||||
|
||||
|
||||
#define APRS_MAXLEN 201
|
||||
void aprs_gencrctab(void);
|
||||
int aprsstr_mon2raw(const char *mon, char raw[], int raw_len);
|
||||
int aprsstr_mon2kiss(const char *mon, char raw[], int raw_len);
|
||||
char *aprs_send_beacon(const char *call, float lat, float lon, const char *sym, const char *comment);
|
||||
char *aprs_senddata(SondeInfo *s, const char *usercall, const char *objcall, const char *sym);
|
||||
|
||||
|
||||
#endif
|
87
RX_FSK/src/autodetect-infos
Normal file
87
RX_FSK/src/autodetect-infos
Normal file
|
@ -0,0 +1,87 @@
|
|||
Heltec board v1 => fingerprint 0000100 => 4
|
||||
(sda,scl: 4,15) (same as LORA v1.0)
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:0 17:0 18:0 19:0 20:0 21:1 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
|
||||
Heltec board v2
|
||||
(sda,scl: 4,15) (similar to v1.0, but GPIO21 switches 3V3) => fingerprint 4
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:0 17:0 18:0 19:0 20:0 21:1 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:1 1:1 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:0 17:0 18:0 19:0 20:0 21:1 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup
|
||||
|
||||
TTGO LORA32 v2.1_1.6 (button1: touch gpio 2 => 130; button2: touch gpio14 => 142) fingerprint 0011111 => 31
|
||||
(sda,scl: 21,22)
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:1 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:0 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:0 13:0 14:4 15:4 16:4 17:4 18:0 19:0 20:0 21:4 22:4 23:4 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (in Sonde())
|
||||
|
||||
TTGO LORA v1.0 => fingerprint 1000000 => 64
|
||||
(sda,scl: 4,15) (button1: 0) (button2: touch gpio13 = 141)
|
||||
0:1 1:0 2:0 3:1 4:1 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:0 17:0 18:0 19:0 20:0 21:0 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:4 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:0 13:0 14:4 15:4 16:0 17:0 18:0 19:0 20:0 21:0 22:0 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (in Sonde())
|
||||
|
||||
TTGO T-Beam => fingerprint 0110111 => 55
|
||||
(sda,scl: 21,22) (button1: 39) (button2: touch gpio13 = 141) (gps rx: 12)
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:1 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:0 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:4 13:0 14:4 15:4 16:4 17:0 18:0 19:0 20:0 21:4 22:4 23:4 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
TTGO T-Beam with extern 2" ILI9225 Display => fingerprint 0110000 => 48
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:1 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:0 22:0 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:0 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:4 13:0 14:4 15:4 16:4 17:0 18:0 19:0 20:0 21:0 22:0 23:4 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
TTGO T-Beam 1.0 with OLED display => fingerprint 0010111 => 23
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:4 1:4 2:0 3:4 4:0 5:4 6:0 7:4 8:0 9:4 10:4 11:4 12:0 13:0 14:4 15:4 16:4 17:0 18:0 19:0 20:0 21:4 22:4 23:4 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
TTGO T-Team 1.0 with IL9225 TFT => fingerprint 23
|
||||
0:1 1:0 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:1 1:1 2:0 3:1 4:0 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:1 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
|
||||
M5Stack Core2
|
||||
0:1 1:0 2:0 3:1 4:1 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:1 14:1 15:1 16:1 17:0 18:1 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:1 1:1 2:0 3:1 4:1 5:1 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:1 14:1 15:1 16:1 17:0 18:1 19:0 20:0 21:1 22:1 23:1 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
Board fingerprint is 87 (nach power on)
|
||||
0:1 1:0 2:0 3:1 4:0 5:0 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0
|
||||
0:1 1:1 2:0 3:1 4:0 5:0 6:0 7:1 8:0 9:1 10:1 11:1 12:0 13:0 14:1 15:0 16:1 17:0 18:0 19:0 20:0 21:1 22:1 23:0 24:0 25:0 26:0 27:0 28:0 29:0 30:0 31:0 32:0 33:0 34:0 35:0 36:0 37:0 38:0 (before setup)
|
||||
Board fingerprint is 22 (nach reset)
|
||||
Autoconfig: looks like T-Beam 1.0 board
|
||||
|
||||
|
||||
vs 0010111
|
||||
T-Beam 1.1 seems to be different: 1110111
|
||||
GPIO4 = 1 (additional pullup) => +64
|
||||
GPIO12 = 1 (maybe additional pullup) => +32
|
||||
|
||||
1
|
||||
|
||||
Fingerprint GPIOs: 4, 12, 16, 17, 21, 22, 23,
|
||||
|
||||
Current autodetect strategy:
|
||||
RST always set to 16
|
||||
|
||||
GPIO16=0 (GPio22,23 would also work):
|
||||
==Heltec or TTGO LORA v1.0==
|
||||
SDA,SCL set to (4,15)
|
||||
Button 1 set to GPIO 0
|
||||
Button 2 set to Touch in GPIO 13 (141)
|
||||
|
||||
|
||||
otherwise
|
||||
==LORA32 v2.1 or T-Beam==
|
||||
GPIO17=0:
|
||||
== T-BEAM =
|
||||
GPIO12==0: v1 (or check PMU via I2C?)
|
||||
GPS RX set to 34
|
||||
Button 1 set to GPIO28
|
||||
BUtton 2 set to Touch GPIO13
|
||||
else:
|
||||
GPS RX set to 12
|
||||
Button 1 set to GPIO39
|
||||
Button 2 set to Touch GPIO13 (141)
|
||||
GPIO21=0:
|
||||
large display connected (use ILI9225 contig: SDA4 CLK21 RS2 RST22 CS0)
|
||||
else:
|
||||
small display connected, set SDA,SCL to (21,22)
|
||||
otherweise:
|
||||
SDA,SCL set to (21,22)
|
||||
GPS disabled
|
||||
Button 1 set to Touch GPIO2 (130)
|
||||
Button 2 set to Touch GPIO14 (142)
|
||||
|
227
RX_FSK/src/fonts/FreeMono12pt7b.h
Normal file
227
RX_FSK/src/fonts/FreeMono12pt7b.h
Normal file
|
@ -0,0 +1,227 @@
|
|||
const uint8_t FreeMono12pt7bBitmaps[] PROGMEM = {
|
||||
0x49, 0x24, 0x92, 0x48, 0x01, 0xF8, 0xE7, 0xE7, 0x67, 0x42, 0x42, 0x42,
|
||||
0x42, 0x09, 0x02, 0x41, 0x10, 0x44, 0x11, 0x1F, 0xF1, 0x10, 0x4C, 0x12,
|
||||
0x3F, 0xE1, 0x20, 0x48, 0x12, 0x04, 0x81, 0x20, 0x48, 0x04, 0x07, 0xA2,
|
||||
0x19, 0x02, 0x40, 0x10, 0x03, 0x00, 0x3C, 0x00, 0x80, 0x10, 0x06, 0x01,
|
||||
0xE0, 0xA7, 0xC0, 0x40, 0x10, 0x04, 0x00, 0x3C, 0x19, 0x84, 0x21, 0x08,
|
||||
0x66, 0x0F, 0x00, 0x0C, 0x1C, 0x78, 0x01, 0xE0, 0xCC, 0x21, 0x08, 0x43,
|
||||
0x30, 0x78, 0x3E, 0x30, 0x10, 0x08, 0x02, 0x03, 0x03, 0x47, 0x14, 0x8A,
|
||||
0x43, 0x11, 0x8F, 0x60, 0xFD, 0xA4, 0x90, 0x05, 0x25, 0x24, 0x92, 0x48,
|
||||
0x92, 0x24, 0x11, 0x24, 0x89, 0x24, 0x92, 0x92, 0x90, 0x00, 0x04, 0x02,
|
||||
0x11, 0x07, 0xF0, 0xC0, 0x50, 0x48, 0x42, 0x00, 0x08, 0x04, 0x02, 0x01,
|
||||
0x00, 0x87, 0xFC, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x3B, 0x9C, 0xCE,
|
||||
0x62, 0x00, 0xFF, 0xE0, 0xFF, 0x80, 0x00, 0x80, 0xC0, 0x40, 0x20, 0x20,
|
||||
0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x80,
|
||||
0x80, 0x40, 0x00, 0x1C, 0x31, 0x90, 0x58, 0x38, 0x0C, 0x06, 0x03, 0x01,
|
||||
0x80, 0xC0, 0x60, 0x30, 0x34, 0x13, 0x18, 0x70, 0x30, 0xE1, 0x44, 0x81,
|
||||
0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81, 0x1F, 0xC0, 0x1E, 0x10, 0x90,
|
||||
0x68, 0x10, 0x08, 0x0C, 0x04, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x0E,
|
||||
0x07, 0xFE, 0x3E, 0x10, 0x40, 0x08, 0x02, 0x00, 0x80, 0x40, 0xE0, 0x04,
|
||||
0x00, 0x80, 0x10, 0x04, 0x01, 0x00, 0xD8, 0x63, 0xE0, 0x06, 0x0A, 0x0A,
|
||||
0x12, 0x22, 0x22, 0x42, 0x42, 0x82, 0x82, 0xFF, 0x02, 0x02, 0x02, 0x0F,
|
||||
0x7F, 0x20, 0x10, 0x08, 0x04, 0x02, 0xF1, 0x8C, 0x03, 0x00, 0x80, 0x40,
|
||||
0x20, 0x18, 0x16, 0x18, 0xF0, 0x0F, 0x8C, 0x08, 0x08, 0x04, 0x04, 0x02,
|
||||
0x79, 0x46, 0xC1, 0xE0, 0x60, 0x28, 0x14, 0x19, 0x08, 0x78, 0xFF, 0x81,
|
||||
0x81, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08,
|
||||
0x08, 0x3E, 0x31, 0xB0, 0x70, 0x18, 0x0C, 0x05, 0x8C, 0x38, 0x63, 0x40,
|
||||
0x60, 0x30, 0x18, 0x1B, 0x18, 0xF8, 0x3C, 0x31, 0x30, 0x50, 0x28, 0x0C,
|
||||
0x0F, 0x06, 0x85, 0x3C, 0x80, 0x40, 0x40, 0x20, 0x20, 0x63, 0xE0, 0xFF,
|
||||
0x80, 0x07, 0xFC, 0x39, 0xCE, 0x00, 0x00, 0x06, 0x33, 0x98, 0xC4, 0x00,
|
||||
0x00, 0xC0, 0x60, 0x18, 0x0C, 0x06, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03,
|
||||
0x00, 0x30, 0x01, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x0F, 0xFF, 0xC0, 0x06,
|
||||
0x00, 0x30, 0x01, 0x80, 0x18, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x02,
|
||||
0x00, 0x00, 0x3E, 0x60, 0xA0, 0x20, 0x10, 0x08, 0x08, 0x18, 0x10, 0x08,
|
||||
0x00, 0x00, 0x00, 0x01, 0xC0, 0xE0, 0x1C, 0x31, 0x10, 0x50, 0x28, 0x14,
|
||||
0x3A, 0x25, 0x22, 0x91, 0x4C, 0xA3, 0xF0, 0x08, 0x02, 0x01, 0x80, 0x7C,
|
||||
0x3F, 0x00, 0x0C, 0x00, 0x48, 0x01, 0x20, 0x04, 0x40, 0x21, 0x00, 0x84,
|
||||
0x04, 0x08, 0x1F, 0xE0, 0x40, 0x82, 0x01, 0x08, 0x04, 0x20, 0x13, 0xE1,
|
||||
0xF0, 0xFF, 0x08, 0x11, 0x01, 0x20, 0x24, 0x04, 0x81, 0x1F, 0xC2, 0x06,
|
||||
0x40, 0x68, 0x05, 0x00, 0xA0, 0x14, 0x05, 0xFF, 0x00, 0x1E, 0x48, 0x74,
|
||||
0x05, 0x01, 0x80, 0x20, 0x08, 0x02, 0x00, 0x80, 0x20, 0x04, 0x01, 0x01,
|
||||
0x30, 0x87, 0xC0, 0xFE, 0x10, 0x44, 0x09, 0x02, 0x40, 0x50, 0x14, 0x05,
|
||||
0x01, 0x40, 0x50, 0x14, 0x0D, 0x02, 0x41, 0x3F, 0x80, 0xFF, 0xC8, 0x09,
|
||||
0x01, 0x20, 0x04, 0x00, 0x88, 0x1F, 0x02, 0x20, 0x40, 0x08, 0x01, 0x00,
|
||||
0xA0, 0x14, 0x03, 0xFF, 0xC0, 0xFF, 0xE8, 0x05, 0x00, 0xA0, 0x04, 0x00,
|
||||
0x88, 0x1F, 0x02, 0x20, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x01, 0xF0,
|
||||
0x00, 0x1F, 0x46, 0x19, 0x01, 0x60, 0x28, 0x01, 0x00, 0x20, 0x04, 0x00,
|
||||
0x83, 0xF0, 0x0B, 0x01, 0x20, 0x23, 0x0C, 0x3E, 0x00, 0xE1, 0xD0, 0x24,
|
||||
0x09, 0x02, 0x40, 0x90, 0x27, 0xF9, 0x02, 0x40, 0x90, 0x24, 0x09, 0x02,
|
||||
0x40, 0xB8, 0x70, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x20,
|
||||
0x40, 0x81, 0x1F, 0xC0, 0x0F, 0xE0, 0x10, 0x02, 0x00, 0x40, 0x08, 0x01,
|
||||
0x00, 0x20, 0x04, 0x80, 0x90, 0x12, 0x02, 0x40, 0xC6, 0x30, 0x7C, 0x00,
|
||||
0xF1, 0xE4, 0x0C, 0x41, 0x04, 0x20, 0x44, 0x04, 0x80, 0x5C, 0x06, 0x60,
|
||||
0x43, 0x04, 0x10, 0x40, 0x84, 0x08, 0x40, 0xCF, 0x07, 0xF8, 0x04, 0x00,
|
||||
0x80, 0x10, 0x02, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x04, 0x80,
|
||||
0x90, 0x12, 0x03, 0xFF, 0xC0, 0xE0, 0x3B, 0x01, 0x94, 0x14, 0xA0, 0xA4,
|
||||
0x89, 0x24, 0x49, 0x14, 0x48, 0xA2, 0x45, 0x12, 0x10, 0x90, 0x04, 0x80,
|
||||
0x24, 0x01, 0x78, 0x3C, 0xE0, 0xF6, 0x02, 0x50, 0x25, 0x02, 0x48, 0x24,
|
||||
0xC2, 0x44, 0x24, 0x22, 0x43, 0x24, 0x12, 0x40, 0xA4, 0x0A, 0x40, 0x6F,
|
||||
0x06, 0x0F, 0x03, 0x0C, 0x60, 0x64, 0x02, 0x80, 0x18, 0x01, 0x80, 0x18,
|
||||
0x01, 0x80, 0x18, 0x01, 0x40, 0x26, 0x06, 0x30, 0xC0, 0xF0, 0xFF, 0x10,
|
||||
0x64, 0x05, 0x01, 0x40, 0x50, 0x34, 0x19, 0xFC, 0x40, 0x10, 0x04, 0x01,
|
||||
0x00, 0x40, 0x3E, 0x00, 0x0F, 0x03, 0x0C, 0x60, 0x64, 0x02, 0x80, 0x18,
|
||||
0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x40, 0x26, 0x06, 0x30, 0xC1,
|
||||
0xF0, 0x0C, 0x01, 0xF1, 0x30, 0xE0, 0xFF, 0x04, 0x18, 0x40, 0xC4, 0x04,
|
||||
0x40, 0x44, 0x0C, 0x41, 0x87, 0xE0, 0x43, 0x04, 0x10, 0x40, 0x84, 0x04,
|
||||
0x40, 0x4F, 0x03, 0x1F, 0x48, 0x34, 0x05, 0x01, 0x40, 0x08, 0x01, 0xC0,
|
||||
0x0E, 0x00, 0x40, 0x18, 0x06, 0x01, 0xE1, 0xA7, 0xC0, 0xFF, 0xF0, 0x86,
|
||||
0x10, 0x82, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10,
|
||||
0x02, 0x00, 0x40, 0x7F, 0x00, 0xF0, 0xF4, 0x02, 0x40, 0x24, 0x02, 0x40,
|
||||
0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x22, 0x04, 0x30,
|
||||
0xC0, 0xF0, 0xF8, 0x7C, 0x80, 0x22, 0x01, 0x04, 0x04, 0x10, 0x20, 0x40,
|
||||
0x80, 0x82, 0x02, 0x10, 0x08, 0x40, 0x11, 0x00, 0x48, 0x01, 0xA0, 0x03,
|
||||
0x00, 0x0C, 0x00, 0xF8, 0x7C, 0x80, 0x22, 0x00, 0x88, 0xC2, 0x23, 0x10,
|
||||
0x8E, 0x42, 0x29, 0x09, 0x24, 0x24, 0x90, 0x91, 0x41, 0x85, 0x06, 0x14,
|
||||
0x18, 0x70, 0x60, 0x80, 0xF0, 0xF2, 0x06, 0x30, 0x41, 0x08, 0x09, 0x80,
|
||||
0x50, 0x06, 0x00, 0x60, 0x0D, 0x00, 0x88, 0x10, 0xC2, 0x04, 0x60, 0x2F,
|
||||
0x0F, 0xF0, 0xF2, 0x02, 0x10, 0x41, 0x04, 0x08, 0x80, 0x50, 0x05, 0x00,
|
||||
0x20, 0x02, 0x00, 0x20, 0x02, 0x00, 0x20, 0x02, 0x01, 0xFC, 0xFF, 0x40,
|
||||
0xA0, 0x90, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x50, 0x30, 0x18,
|
||||
0x0F, 0xFC, 0xF2, 0x49, 0x24, 0x92, 0x49, 0x24, 0x9C, 0x80, 0x60, 0x10,
|
||||
0x08, 0x02, 0x01, 0x00, 0x40, 0x20, 0x08, 0x04, 0x01, 0x00, 0x80, 0x20,
|
||||
0x10, 0x04, 0x02, 0x00, 0x80, 0x40, 0xE4, 0x92, 0x49, 0x24, 0x92, 0x49,
|
||||
0x3C, 0x08, 0x0C, 0x09, 0x0C, 0x4C, 0x14, 0x04, 0xFF, 0xFC, 0x84, 0x21,
|
||||
0x3E, 0x00, 0x60, 0x08, 0x02, 0x3F, 0x98, 0x28, 0x0A, 0x02, 0xC3, 0x9F,
|
||||
0x30, 0xE0, 0x01, 0x00, 0x08, 0x00, 0x40, 0x02, 0x00, 0x13, 0xE0, 0xA0,
|
||||
0x86, 0x02, 0x20, 0x09, 0x00, 0x48, 0x02, 0x40, 0x13, 0x01, 0x14, 0x1B,
|
||||
0x9F, 0x00, 0x1F, 0x4C, 0x19, 0x01, 0x40, 0x28, 0x01, 0x00, 0x20, 0x02,
|
||||
0x00, 0x60, 0x43, 0xF0, 0x00, 0xC0, 0x08, 0x01, 0x00, 0x20, 0x04, 0x3C,
|
||||
0x98, 0x52, 0x06, 0x80, 0x50, 0x0A, 0x01, 0x40, 0x24, 0x0C, 0xC2, 0x87,
|
||||
0x98, 0x3F, 0x18, 0x68, 0x06, 0x01, 0xFF, 0xE0, 0x08, 0x03, 0x00, 0x60,
|
||||
0xC7, 0xC0, 0x0F, 0x98, 0x08, 0x04, 0x02, 0x07, 0xF8, 0x80, 0x40, 0x20,
|
||||
0x10, 0x08, 0x04, 0x02, 0x01, 0x03, 0xF8, 0x1E, 0x6C, 0x39, 0x03, 0x40,
|
||||
0x28, 0x05, 0x00, 0xA0, 0x12, 0x06, 0x61, 0x43, 0xC8, 0x01, 0x00, 0x20,
|
||||
0x08, 0x3E, 0x00, 0xC0, 0x10, 0x04, 0x01, 0x00, 0x40, 0x13, 0x87, 0x11,
|
||||
0x82, 0x40, 0x90, 0x24, 0x09, 0x02, 0x40, 0x90, 0x2E, 0x1C, 0x08, 0x04,
|
||||
0x02, 0x00, 0x00, 0x03, 0xC0, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00,
|
||||
0x80, 0x43, 0xFE, 0x04, 0x08, 0x10, 0x00, 0x1F, 0xC0, 0x81, 0x02, 0x04,
|
||||
0x08, 0x10, 0x20, 0x40, 0x81, 0x02, 0x0B, 0xE0, 0xE0, 0x02, 0x00, 0x20,
|
||||
0x02, 0x00, 0x20, 0x02, 0x3C, 0x21, 0x02, 0x60, 0x2C, 0x03, 0x80, 0x24,
|
||||
0x02, 0x20, 0x21, 0x02, 0x08, 0xE1, 0xF0, 0x78, 0x04, 0x02, 0x01, 0x00,
|
||||
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x43, 0xFE,
|
||||
0xDC, 0xE3, 0x19, 0x90, 0x84, 0x84, 0x24, 0x21, 0x21, 0x09, 0x08, 0x48,
|
||||
0x42, 0x42, 0x17, 0x18, 0xC0, 0x67, 0x83, 0x84, 0x20, 0x22, 0x02, 0x20,
|
||||
0x22, 0x02, 0x20, 0x22, 0x02, 0x20, 0x2F, 0x07, 0x1F, 0x04, 0x11, 0x01,
|
||||
0x40, 0x18, 0x03, 0x00, 0x60, 0x0A, 0x02, 0x20, 0x83, 0xE0, 0xCF, 0x85,
|
||||
0x06, 0x60, 0x24, 0x01, 0x40, 0x14, 0x01, 0x40, 0x16, 0x02, 0x50, 0x44,
|
||||
0xF8, 0x40, 0x04, 0x00, 0x40, 0x0F, 0x00, 0x1E, 0x6C, 0x3B, 0x03, 0x40,
|
||||
0x28, 0x05, 0x00, 0xA0, 0x12, 0x06, 0x61, 0x43, 0xC8, 0x01, 0x00, 0x20,
|
||||
0x04, 0x03, 0xC0, 0xE3, 0x8B, 0x13, 0x80, 0x80, 0x20, 0x08, 0x02, 0x00,
|
||||
0x80, 0x20, 0x3F, 0x80, 0x1F, 0x58, 0x34, 0x05, 0x80, 0x1E, 0x00, 0x60,
|
||||
0x06, 0x01, 0xC0, 0xAF, 0xC0, 0x20, 0x04, 0x00, 0x80, 0x10, 0x0F, 0xF0,
|
||||
0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10, 0x03, 0x04, 0x3F,
|
||||
0x00, 0xC1, 0xC8, 0x09, 0x01, 0x20, 0x24, 0x04, 0x80, 0x90, 0x12, 0x02,
|
||||
0x61, 0xC7, 0xCC, 0xF8, 0xF9, 0x01, 0x08, 0x10, 0x60, 0x81, 0x08, 0x08,
|
||||
0x40, 0x22, 0x01, 0x20, 0x05, 0x00, 0x30, 0x00, 0xF0, 0x7A, 0x01, 0x10,
|
||||
0x08, 0x8C, 0x42, 0x62, 0x12, 0x90, 0xA5, 0x05, 0x18, 0x28, 0xC0, 0x86,
|
||||
0x00, 0x78, 0xF3, 0x04, 0x18, 0x80, 0xD0, 0x06, 0x00, 0x70, 0x09, 0x81,
|
||||
0x0C, 0x20, 0x6F, 0x8F, 0xF0, 0xF2, 0x02, 0x20, 0x41, 0x04, 0x10, 0x80,
|
||||
0x88, 0x09, 0x00, 0x50, 0x06, 0x00, 0x20, 0x04, 0x00, 0x40, 0x08, 0x0F,
|
||||
0xE0, 0xFF, 0x41, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0xBF,
|
||||
0xC0, 0x19, 0x08, 0x42, 0x10, 0x84, 0x64, 0x18, 0x42, 0x10, 0x84, 0x20,
|
||||
0xC0, 0xFF, 0xFF, 0xC0, 0xC1, 0x08, 0x42, 0x10, 0x84, 0x10, 0x4C, 0x42,
|
||||
0x10, 0x84, 0x26, 0x00, 0x38, 0x13, 0x38, 0x38 };
|
||||
|
||||
const GFXglyph FreeMono12pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 14, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 3, 15, 14, 6, -14 }, // 0x21 '!'
|
||||
{ 6, 8, 7, 14, 3, -14 }, // 0x22 '"'
|
||||
{ 13, 10, 16, 14, 2, -14 }, // 0x23 '#'
|
||||
{ 33, 10, 17, 14, 2, -14 }, // 0x24 '$'
|
||||
{ 55, 10, 15, 14, 2, -14 }, // 0x25 '%'
|
||||
{ 74, 9, 12, 14, 3, -11 }, // 0x26 '&'
|
||||
{ 88, 3, 7, 14, 5, -14 }, // 0x27 '''
|
||||
{ 91, 3, 18, 14, 7, -14 }, // 0x28 '('
|
||||
{ 98, 3, 18, 14, 4, -14 }, // 0x29 ')'
|
||||
{ 105, 9, 9, 14, 3, -14 }, // 0x2A '*'
|
||||
{ 116, 9, 11, 14, 3, -11 }, // 0x2B '+'
|
||||
{ 129, 5, 7, 14, 3, -3 }, // 0x2C ','
|
||||
{ 134, 11, 1, 14, 2, -6 }, // 0x2D '-'
|
||||
{ 136, 3, 3, 14, 5, -2 }, // 0x2E '.'
|
||||
{ 138, 9, 18, 14, 3, -15 }, // 0x2F '/'
|
||||
{ 159, 9, 15, 14, 3, -14 }, // 0x30 '0'
|
||||
{ 176, 7, 14, 14, 4, -13 }, // 0x31 '1'
|
||||
{ 189, 9, 15, 14, 2, -14 }, // 0x32 '2'
|
||||
{ 206, 10, 15, 14, 2, -14 }, // 0x33 '3'
|
||||
{ 225, 8, 15, 14, 3, -14 }, // 0x34 '4'
|
||||
{ 240, 9, 15, 14, 3, -14 }, // 0x35 '5'
|
||||
{ 257, 9, 15, 14, 3, -14 }, // 0x36 '6'
|
||||
{ 274, 8, 15, 14, 3, -14 }, // 0x37 '7'
|
||||
{ 289, 9, 15, 14, 3, -14 }, // 0x38 '8'
|
||||
{ 306, 9, 15, 14, 3, -14 }, // 0x39 '9'
|
||||
{ 323, 3, 10, 14, 5, -9 }, // 0x3A ':'
|
||||
{ 327, 5, 13, 14, 3, -9 }, // 0x3B ';'
|
||||
{ 336, 11, 11, 14, 2, -11 }, // 0x3C '<'
|
||||
{ 352, 12, 4, 14, 1, -8 }, // 0x3D '='
|
||||
{ 358, 11, 11, 14, 2, -11 }, // 0x3E '>'
|
||||
{ 374, 9, 14, 14, 3, -13 }, // 0x3F '?'
|
||||
{ 390, 9, 16, 14, 3, -14 }, // 0x40 '@'
|
||||
{ 408, 14, 14, 14, 0, -13 }, // 0x41 'A'
|
||||
{ 433, 11, 14, 14, 2, -13 }, // 0x42 'B'
|
||||
{ 453, 10, 14, 14, 2, -13 }, // 0x43 'C'
|
||||
{ 471, 10, 14, 14, 2, -13 }, // 0x44 'D'
|
||||
{ 489, 11, 14, 14, 2, -13 }, // 0x45 'E'
|
||||
{ 509, 11, 14, 14, 2, -13 }, // 0x46 'F'
|
||||
{ 529, 11, 14, 14, 2, -13 }, // 0x47 'G'
|
||||
{ 549, 10, 14, 14, 2, -13 }, // 0x48 'H'
|
||||
{ 567, 7, 14, 14, 4, -13 }, // 0x49 'I'
|
||||
{ 580, 11, 14, 14, 2, -13 }, // 0x4A 'J'
|
||||
{ 600, 12, 14, 14, 2, -13 }, // 0x4B 'K'
|
||||
{ 621, 11, 14, 14, 2, -13 }, // 0x4C 'L'
|
||||
{ 641, 13, 14, 14, 1, -13 }, // 0x4D 'M'
|
||||
{ 664, 12, 14, 14, 1, -13 }, // 0x4E 'N'
|
||||
{ 685, 12, 14, 14, 1, -13 }, // 0x4F 'O'
|
||||
{ 706, 10, 14, 14, 2, -13 }, // 0x50 'P'
|
||||
{ 724, 12, 17, 14, 1, -13 }, // 0x51 'Q'
|
||||
{ 750, 12, 14, 14, 2, -13 }, // 0x52 'R'
|
||||
{ 771, 10, 14, 14, 2, -13 }, // 0x53 'S'
|
||||
{ 789, 11, 14, 14, 2, -13 }, // 0x54 'T'
|
||||
{ 809, 12, 14, 14, 1, -13 }, // 0x55 'U'
|
||||
{ 830, 14, 14, 14, 0, -13 }, // 0x56 'V'
|
||||
{ 855, 14, 14, 14, 0, -13 }, // 0x57 'W'
|
||||
{ 880, 12, 14, 14, 1, -13 }, // 0x58 'X'
|
||||
{ 901, 12, 14, 14, 1, -13 }, // 0x59 'Y'
|
||||
{ 922, 9, 14, 14, 3, -13 }, // 0x5A 'Z'
|
||||
{ 938, 3, 18, 14, 7, -14 }, // 0x5B '['
|
||||
{ 945, 9, 18, 14, 3, -15 }, // 0x5C '\'
|
||||
{ 966, 3, 18, 14, 5, -14 }, // 0x5D ']'
|
||||
{ 973, 9, 6, 14, 3, -14 }, // 0x5E '^'
|
||||
{ 980, 14, 1, 14, 0, 3 }, // 0x5F '_'
|
||||
{ 982, 4, 4, 14, 4, -15 }, // 0x60 '`'
|
||||
{ 984, 10, 10, 14, 2, -9 }, // 0x61 'a'
|
||||
{ 997, 13, 15, 14, 0, -14 }, // 0x62 'b'
|
||||
{ 1022, 11, 10, 14, 2, -9 }, // 0x63 'c'
|
||||
{ 1036, 11, 15, 14, 2, -14 }, // 0x64 'd'
|
||||
{ 1057, 10, 10, 14, 2, -9 }, // 0x65 'e'
|
||||
{ 1070, 9, 15, 14, 4, -14 }, // 0x66 'f'
|
||||
{ 1087, 11, 14, 14, 2, -9 }, // 0x67 'g'
|
||||
{ 1107, 10, 15, 14, 2, -14 }, // 0x68 'h'
|
||||
{ 1126, 9, 15, 14, 3, -14 }, // 0x69 'i'
|
||||
{ 1143, 7, 19, 14, 3, -14 }, // 0x6A 'j'
|
||||
{ 1160, 12, 15, 14, 1, -14 }, // 0x6B 'k'
|
||||
{ 1183, 9, 15, 14, 3, -14 }, // 0x6C 'l'
|
||||
{ 1200, 13, 10, 14, 1, -9 }, // 0x6D 'm'
|
||||
{ 1217, 12, 10, 14, 1, -9 }, // 0x6E 'n'
|
||||
{ 1232, 11, 10, 14, 2, -9 }, // 0x6F 'o'
|
||||
{ 1246, 12, 14, 14, 1, -9 }, // 0x70 'p'
|
||||
{ 1267, 11, 14, 14, 2, -9 }, // 0x71 'q'
|
||||
{ 1287, 10, 10, 14, 3, -9 }, // 0x72 'r'
|
||||
{ 1300, 10, 10, 14, 2, -9 }, // 0x73 's'
|
||||
{ 1313, 11, 14, 14, 1, -13 }, // 0x74 't'
|
||||
{ 1333, 11, 10, 14, 2, -9 }, // 0x75 'u'
|
||||
{ 1347, 13, 10, 14, 1, -9 }, // 0x76 'v'
|
||||
{ 1364, 13, 10, 14, 1, -9 }, // 0x77 'w'
|
||||
{ 1381, 12, 10, 14, 1, -9 }, // 0x78 'x'
|
||||
{ 1396, 12, 14, 14, 1, -9 }, // 0x79 'y'
|
||||
{ 1417, 9, 10, 14, 3, -9 }, // 0x7A 'z'
|
||||
{ 1429, 5, 18, 14, 5, -14 }, // 0x7B '{'
|
||||
{ 1441, 1, 18, 14, 7, -14 }, // 0x7C '|'
|
||||
{ 1444, 5, 18, 14, 5, -14 }, // 0x7D '}'
|
||||
{ 1456, 10, 3, 14, 2, -7 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeMono12pt7b PROGMEM = {
|
||||
(uint8_t *)FreeMono12pt7bBitmaps,
|
||||
(GFXglyph *)FreeMono12pt7bGlyphs,
|
||||
0x20, 0x7E, 24 };
|
||||
|
||||
// Approx. 2132 bytes
|
495
RX_FSK/src/fonts/FreeMono12pt8b.h
Normal file
495
RX_FSK/src/fonts/FreeMono12pt8b.h
Normal file
|
@ -0,0 +1,495 @@
|
|||
const uint8_t FreeMono12pt8bBitmaps[] PROGMEM = {
|
||||
0x00, 0xDB, 0x6D, 0x92, 0x48, 0x01, 0xB8, 0xF7, 0x67, 0x67, 0x67, 0x66,
|
||||
0x66, 0x62, 0x00, 0x02, 0x40, 0x90, 0x44, 0x11, 0x04, 0x87, 0xFC, 0x48,
|
||||
0x12, 0x04, 0x87, 0xF8, 0x48, 0x12, 0x04, 0x81, 0x20, 0x48, 0x12, 0x00,
|
||||
0x08, 0x04, 0x0F, 0x0C, 0x6C, 0x14, 0x02, 0x00, 0xC0, 0x1E, 0x00, 0x80,
|
||||
0x30, 0x18, 0x17, 0x18, 0x70, 0x10, 0x08, 0x04, 0x00, 0x18, 0x19, 0x04,
|
||||
0x21, 0x08, 0x44, 0x0F, 0x00, 0x0C, 0x1C, 0x78, 0x20, 0xC0, 0xC8, 0x22,
|
||||
0x08, 0x42, 0x20, 0x78, 0x3E, 0x40, 0x40, 0x40, 0x20, 0x60, 0x91, 0x8A,
|
||||
0x8A, 0x86, 0x86, 0x7B, 0xFF, 0x6D, 0xB0, 0x01, 0x26, 0x44, 0xCC, 0xCC,
|
||||
0xCC, 0x44, 0x62, 0x31, 0x13, 0x24, 0xC9, 0x24, 0x92, 0xD6, 0x90, 0x00,
|
||||
0x04, 0x02, 0x11, 0x17, 0xF0, 0xC0, 0x50, 0x4C, 0x42, 0x00, 0x04, 0x00,
|
||||
0x80, 0x10, 0x02, 0x00, 0x40, 0x08, 0x3F, 0xF8, 0x20, 0x04, 0x00, 0x80,
|
||||
0x10, 0x02, 0x00, 0x3B, 0x9C, 0xC4, 0x60, 0xFF, 0xE0, 0x6F, 0x70, 0x00,
|
||||
0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x06,
|
||||
0x02, 0x01, 0x01, 0x00, 0x80, 0x80, 0x40, 0x00, 0x1C, 0x33, 0x10, 0x50,
|
||||
0x28, 0x14, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x2C, 0x12, 0x18,
|
||||
0xF8, 0x18, 0x1C, 0x1A, 0x19, 0x08, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
|
||||
0x02, 0x01, 0x00, 0x80, 0x43, 0xFE, 0x1E, 0x11, 0x90, 0x38, 0x10, 0x08,
|
||||
0x04, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x07, 0xFE, 0x1E,
|
||||
0x08, 0x64, 0x08, 0x02, 0x00, 0x80, 0x20, 0x70, 0x1C, 0x00, 0x80, 0x10,
|
||||
0x04, 0x01, 0x00, 0x70, 0x23, 0xF0, 0x06, 0x0A, 0x0A, 0x12, 0x12, 0x22,
|
||||
0x62, 0x42, 0x82, 0x82, 0xFF, 0x02, 0x02, 0x02, 0x0F, 0x3F, 0x08, 0x22,
|
||||
0x00, 0x80, 0x20, 0x08, 0x03, 0xF0, 0x02, 0x00, 0x40, 0x10, 0x04, 0x01,
|
||||
0x00, 0xD0, 0x23, 0xF0, 0x07, 0x8E, 0x0C, 0x0C, 0x04, 0x02, 0x02, 0x31,
|
||||
0x66, 0xA0, 0xE0, 0x60, 0x28, 0x14, 0x09, 0x08, 0x7C, 0xFF, 0x81, 0x81,
|
||||
0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08,
|
||||
0x1C, 0x31, 0x20, 0x50, 0x28, 0x14, 0x09, 0x08, 0x78, 0x43, 0x40, 0xA0,
|
||||
0x30, 0x18, 0x16, 0x09, 0xF8, 0x1C, 0x31, 0x10, 0x50, 0x18, 0x0C, 0x05,
|
||||
0x06, 0x87, 0x3E, 0x80, 0x40, 0x20, 0x20, 0x30, 0x33, 0xF0, 0x7F, 0x70,
|
||||
0x00, 0x06, 0xF7, 0x39, 0xCE, 0x00, 0x00, 0x07, 0x73, 0x98, 0xCC, 0x00,
|
||||
0x00, 0xC0, 0x60, 0x18, 0x0C, 0x06, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03,
|
||||
0x00, 0x30, 0x01, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x07, 0xFF, 0xC0, 0x06,
|
||||
0x00, 0x30, 0x01, 0x80, 0x18, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x02,
|
||||
0x00, 0x00, 0x3C, 0x61, 0xA0, 0x40, 0x10, 0x08, 0x08, 0x08, 0x18, 0x08,
|
||||
0x04, 0x00, 0x00, 0x01, 0xC0, 0xE0, 0x3C, 0x62, 0xC1, 0x81, 0x81, 0x87,
|
||||
0x99, 0x91, 0x91, 0x91, 0x8F, 0x81, 0x80, 0x80, 0x40, 0x3F, 0x1F, 0x00,
|
||||
0x0C, 0x00, 0x48, 0x01, 0x20, 0x04, 0x80, 0x21, 0x00, 0x84, 0x02, 0x08,
|
||||
0x1F, 0xE0, 0x40, 0x81, 0x01, 0x08, 0x04, 0x20, 0x13, 0xE1, 0xF0, 0x7E,
|
||||
0x02, 0x1C, 0x20, 0x62, 0x02, 0x20, 0x22, 0x06, 0x3F, 0x82, 0x1C, 0x20,
|
||||
0x22, 0x01, 0x20, 0x12, 0x01, 0x20, 0x2F, 0xFC, 0x1E, 0x06, 0x39, 0x01,
|
||||
0x40, 0x28, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10, 0x02, 0x00, 0x20,
|
||||
0x16, 0x04, 0x3F, 0x00, 0x7C, 0x08, 0x71, 0x01, 0x20, 0x14, 0x02, 0x80,
|
||||
0x50, 0x0A, 0x01, 0x40, 0x28, 0x05, 0x00, 0xA0, 0x24, 0x0D, 0xFE, 0x00,
|
||||
0x7F, 0xE4, 0x04, 0x80, 0x90, 0x12, 0x00, 0x44, 0x0F, 0x81, 0x10, 0x22,
|
||||
0x04, 0x00, 0x80, 0x90, 0x12, 0x03, 0xFF, 0xC0, 0x7F, 0xE4, 0x04, 0x80,
|
||||
0x90, 0x12, 0x00, 0x44, 0x0F, 0x81, 0x10, 0x22, 0x04, 0x00, 0x80, 0x10,
|
||||
0x02, 0x01, 0xFC, 0x00, 0x0F, 0x06, 0x39, 0x01, 0x40, 0x08, 0x01, 0x00,
|
||||
0x20, 0x04, 0x00, 0x83, 0xF0, 0x0A, 0x01, 0x60, 0x26, 0x04, 0x7F, 0x80,
|
||||
0x70, 0xE2, 0x04, 0x20, 0x42, 0x04, 0x20, 0x42, 0x04, 0x3F, 0xC2, 0x04,
|
||||
0x20, 0x42, 0x04, 0x20, 0x42, 0x04, 0x20, 0x4F, 0x8F, 0xFF, 0x04, 0x02,
|
||||
0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x87,
|
||||
0xFC, 0x0F, 0xE0, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80, 0x08, 0x00, 0x80,
|
||||
0x08, 0x80, 0x88, 0x08, 0x80, 0x88, 0x08, 0xC1, 0x03, 0xE0, 0x78, 0xF1,
|
||||
0x01, 0x08, 0x10, 0x43, 0x02, 0x30, 0x13, 0x00, 0xB0, 0x06, 0x60, 0x21,
|
||||
0x81, 0x04, 0x08, 0x10, 0x40, 0x82, 0x06, 0x7C, 0x1C, 0xFC, 0x04, 0x00,
|
||||
0x80, 0x10, 0x02, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x04, 0x80,
|
||||
0x90, 0x12, 0x03, 0xFF, 0xC0, 0x70, 0x18, 0xC0, 0x73, 0x02, 0x8A, 0x0A,
|
||||
0x28, 0x48, 0x91, 0x22, 0x48, 0x88, 0xA2, 0x23, 0x08, 0x84, 0x22, 0x00,
|
||||
0x88, 0x02, 0x20, 0x0B, 0xE1, 0xF0, 0xE0, 0xF6, 0x02, 0x50, 0x25, 0x82,
|
||||
0x48, 0x24, 0x42, 0x44, 0x24, 0x22, 0x43, 0x24, 0x12, 0x40, 0xA4, 0x0A,
|
||||
0x40, 0x6F, 0x86, 0x0F, 0x01, 0x8C, 0x20, 0x64, 0x02, 0x40, 0x18, 0x01,
|
||||
0x80, 0x18, 0x01, 0x80, 0x1C, 0x01, 0x40, 0x36, 0x02, 0x30, 0x41, 0xF8,
|
||||
0x7E, 0x04, 0x38, 0x81, 0x10, 0x12, 0x02, 0x40, 0x48, 0x11, 0xFC, 0x20,
|
||||
0x04, 0x00, 0x80, 0x10, 0x02, 0x01, 0xFC, 0x00, 0x0F, 0x01, 0x8C, 0x20,
|
||||
0x64, 0x02, 0x40, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0x40,
|
||||
0x36, 0x02, 0x30, 0x41, 0xF8, 0x04, 0x01, 0xF9, 0x10, 0xE0, 0x7E, 0x01,
|
||||
0x0E, 0x08, 0x10, 0x40, 0x42, 0x02, 0x10, 0x30, 0x83, 0x07, 0xE0, 0x21,
|
||||
0x81, 0x06, 0x08, 0x10, 0x40, 0x42, 0x02, 0x7C, 0x0C, 0x1E, 0x0C, 0x74,
|
||||
0x0D, 0x01, 0x40, 0x18, 0x03, 0x80, 0x1E, 0x00, 0xC0, 0x18, 0x06, 0x01,
|
||||
0xC0, 0xEF, 0xC0, 0xFF, 0xF0, 0x86, 0x10, 0xC2, 0x10, 0x40, 0x08, 0x01,
|
||||
0x00, 0x20, 0x04, 0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x7F, 0x00, 0xF0,
|
||||
0xF4, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40,
|
||||
0x24, 0x02, 0x60, 0x22, 0x06, 0x30, 0x41, 0xF8, 0x78, 0x3C, 0x80, 0x22,
|
||||
0x01, 0x08, 0x04, 0x10, 0x10, 0x40, 0x80, 0x82, 0x02, 0x10, 0x08, 0x40,
|
||||
0x11, 0x00, 0x48, 0x01, 0xA0, 0x03, 0x00, 0x0C, 0x00, 0x78, 0x39, 0x00,
|
||||
0x22, 0x00, 0x88, 0xC2, 0x23, 0x08, 0x8A, 0x42, 0x29, 0x09, 0x24, 0x24,
|
||||
0x90, 0x91, 0x41, 0x85, 0x06, 0x14, 0x18, 0x50, 0x60, 0xC0, 0x70, 0x76,
|
||||
0x02, 0x20, 0x41, 0x0C, 0x08, 0x80, 0xD0, 0x06, 0x00, 0x60, 0x0D, 0x00,
|
||||
0x98, 0x10, 0x82, 0x04, 0x60, 0x2F, 0x0F, 0x70, 0x76, 0x02, 0x20, 0x41,
|
||||
0x0C, 0x18, 0x80, 0x90, 0x05, 0x00, 0x60, 0x02, 0x00, 0x20, 0x02, 0x00,
|
||||
0x20, 0x02, 0x01, 0xFC, 0x7F, 0x90, 0x24, 0x09, 0x04, 0x42, 0x00, 0x80,
|
||||
0x40, 0x20, 0x18, 0x04, 0x12, 0x05, 0x01, 0x40, 0x7F, 0xF0, 0xE8, 0x88,
|
||||
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x8F, 0x80, 0x40, 0x10, 0x08, 0x02,
|
||||
0x01, 0x00, 0x40, 0x20, 0x18, 0x04, 0x02, 0x00, 0x80, 0x40, 0x10, 0x08,
|
||||
0x02, 0x01, 0x00, 0x40, 0xF1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||
0x1F, 0x00, 0x0C, 0x0D, 0x04, 0x44, 0x34, 0x08, 0x00, 0xFF, 0xFC, 0x84,
|
||||
0x30, 0x7F, 0x00, 0x10, 0x02, 0x00, 0x43, 0xF9, 0x81, 0x20, 0x24, 0x04,
|
||||
0x81, 0x8F, 0xDC, 0xC0, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0xFC,
|
||||
0x50, 0x66, 0x02, 0x60, 0x14, 0x01, 0x40, 0x16, 0x01, 0x60, 0x25, 0x06,
|
||||
0xCF, 0xC0, 0x3F, 0xCC, 0x19, 0x01, 0x40, 0x08, 0x01, 0x00, 0x20, 0x02,
|
||||
0x01, 0x60, 0x47, 0xF0, 0x00, 0xC0, 0x04, 0x00, 0x40, 0x04, 0x00, 0x43,
|
||||
0xE4, 0x41, 0xC8, 0x0C, 0x80, 0x48, 0x04, 0x80, 0x48, 0x04, 0x80, 0xC4,
|
||||
0x1C, 0x3E, 0x70, 0x3F, 0x10, 0x28, 0x06, 0x01, 0xFF, 0xE0, 0x08, 0x02,
|
||||
0x00, 0x40, 0x4F, 0xE0, 0x00, 0x07, 0xF1, 0x00, 0x40, 0x10, 0x3F, 0xE1,
|
||||
0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x0F, 0xF0, 0x3E,
|
||||
0x68, 0x2A, 0x03, 0x40, 0x68, 0x05, 0x01, 0xA0, 0x36, 0x0E, 0x63, 0x43,
|
||||
0x88, 0x01, 0x00, 0x40, 0x08, 0x3E, 0x00, 0x60, 0x02, 0x00, 0x20, 0x02,
|
||||
0x00, 0x20, 0x02, 0xF8, 0x30, 0x42, 0x04, 0x20, 0x42, 0x04, 0x20, 0x42,
|
||||
0x04, 0x20, 0x42, 0x04, 0xF8, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x00,
|
||||
0x1F, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x0F,
|
||||
0xFC, 0x04, 0x08, 0x10, 0x00, 0x1F, 0xC0, 0x81, 0x02, 0x04, 0x08, 0x10,
|
||||
0x20, 0x40, 0x81, 0x02, 0x0F, 0xF0, 0xC0, 0x08, 0x01, 0x00, 0x20, 0x04,
|
||||
0x00, 0x8F, 0x90, 0x82, 0x20, 0x48, 0x0F, 0x01, 0xB0, 0x23, 0x04, 0x30,
|
||||
0x83, 0x30, 0x78, 0x3C, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40,
|
||||
0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x0F, 0xFC, 0xFE, 0xF0,
|
||||
0xC6, 0x22, 0x10, 0x88, 0x42, 0x21, 0x08, 0x84, 0x22, 0x10, 0x88, 0x42,
|
||||
0x21, 0x0B, 0xC6, 0x30, 0x6F, 0x83, 0x04, 0x20, 0x42, 0x02, 0x20, 0x22,
|
||||
0x02, 0x20, 0x22, 0x02, 0x20, 0x2F, 0x8F, 0x3F, 0x0C, 0x13, 0x01, 0x40,
|
||||
0x28, 0x03, 0x00, 0x60, 0x14, 0x02, 0x40, 0x87, 0xE0, 0xCF, 0xC5, 0x06,
|
||||
0x60, 0x26, 0x01, 0x40, 0x16, 0x01, 0x60, 0x17, 0x02, 0x58, 0xC4, 0x70,
|
||||
0x40, 0x04, 0x00, 0x40, 0x0F, 0x80, 0x3F, 0x74, 0x1C, 0x80, 0xC8, 0x04,
|
||||
0x80, 0x48, 0x04, 0x80, 0x4C, 0x0C, 0x63, 0x41, 0xC4, 0x00, 0x40, 0x04,
|
||||
0x00, 0x40, 0x1E, 0x73, 0xC2, 0xC4, 0x60, 0x08, 0x01, 0x00, 0x20, 0x04,
|
||||
0x00, 0x80, 0x10, 0x1F, 0xF0, 0x3F, 0x90, 0x24, 0x09, 0x80, 0x1E, 0x00,
|
||||
0x60, 0x06, 0x01, 0xC0, 0xEF, 0xE0, 0x00, 0x04, 0x00, 0x80, 0x10, 0x0F,
|
||||
0xF8, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10, 0x01, 0x02,
|
||||
0x3F, 0x80, 0xE1, 0xE2, 0x02, 0x20, 0x22, 0x02, 0x20, 0x22, 0x02, 0x20,
|
||||
0x22, 0x06, 0x20, 0xA1, 0xF3, 0xF8, 0xF9, 0x01, 0x08, 0x10, 0x60, 0x81,
|
||||
0x0C, 0x08, 0x40, 0x22, 0x01, 0x20, 0x05, 0x00, 0x30, 0x00, 0xF0, 0x7A,
|
||||
0x01, 0x10, 0x08, 0x8C, 0x42, 0x62, 0x12, 0x90, 0xA5, 0x05, 0x18, 0x28,
|
||||
0xC0, 0x86, 0x00, 0x78, 0xF3, 0x04, 0x18, 0x80, 0xD0, 0x06, 0x00, 0x70,
|
||||
0x09, 0x81, 0x0C, 0x20, 0x6F, 0x8F, 0xF0, 0xF2, 0x02, 0x20, 0x41, 0x04,
|
||||
0x10, 0x80, 0x88, 0x09, 0x00, 0x50, 0x05, 0x00, 0x20, 0x02, 0x00, 0x40,
|
||||
0x04, 0x07, 0xE0, 0xFF, 0x41, 0xA0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81,
|
||||
0xC0, 0xFF, 0xC0, 0x00, 0x61, 0x04, 0x10, 0x41, 0x04, 0x63, 0x02, 0x04,
|
||||
0x10, 0x41, 0x04, 0x10, 0x30, 0x7F, 0xFF, 0xC0, 0x03, 0x02, 0x08, 0x20,
|
||||
0x82, 0x08, 0x30, 0x72, 0x08, 0x20, 0x82, 0x08, 0x43, 0x00, 0x78, 0x71,
|
||||
0x30, 0x30, 0xFF, 0xFE, 0x00, 0x18, 0x00, 0x61, 0xE1, 0x98, 0x66, 0x40,
|
||||
0x98, 0x01, 0x60, 0x05, 0x80, 0x26, 0x01, 0x18, 0x18, 0x60, 0x41, 0x81,
|
||||
0x06, 0x00, 0x18, 0x00, 0x60, 0xE1, 0x83, 0x86, 0x00, 0x1F, 0xFF, 0xC0,
|
||||
0x00, 0xFC, 0x00, 0x92, 0x4B, 0x6D, 0xB0, 0x08, 0x08, 0x08, 0x3E, 0x63,
|
||||
0x81, 0x80, 0x80, 0x80, 0x80, 0x41, 0x3E, 0x08, 0x08, 0x08, 0x0E, 0x0C,
|
||||
0xC2, 0x00, 0x80, 0x20, 0x08, 0x0F, 0xC0, 0x40, 0x10, 0x04, 0x01, 0x00,
|
||||
0x80, 0x20, 0x7F, 0xF0, 0x07, 0x81, 0x87, 0x30, 0x32, 0x02, 0x40, 0x04,
|
||||
0x00, 0xFF, 0x84, 0x00, 0xFF, 0x84, 0x00, 0x60, 0x02, 0x00, 0x10, 0x30,
|
||||
0xFC, 0x70, 0x76, 0x02, 0x20, 0x41, 0x0C, 0x18, 0x80, 0x90, 0x07, 0x03,
|
||||
0xFC, 0x02, 0x00, 0x20, 0x3F, 0xC0, 0x20, 0x02, 0x01, 0xF8, 0x20, 0x84,
|
||||
0xC0, 0xE0, 0x10, 0x1E, 0x0C, 0x74, 0x0D, 0x01, 0x40, 0x18, 0x03, 0x80,
|
||||
0x1E, 0x00, 0xC0, 0x18, 0x06, 0x01, 0xC0, 0xEF, 0xC0, 0x1F, 0xC4, 0x08,
|
||||
0x81, 0x10, 0x0D, 0x81, 0x18, 0x20, 0xC3, 0x06, 0x30, 0x61, 0x84, 0x0B,
|
||||
0x80, 0xC0, 0x08, 0x83, 0x1F, 0xC0, 0x31, 0x86, 0x80, 0xC0, 0x00, 0x00,
|
||||
0x0F, 0xE4, 0x09, 0x02, 0x60, 0x07, 0x80, 0x18, 0x01, 0x80, 0x70, 0x3B,
|
||||
0xF8, 0x07, 0x80, 0x61, 0x82, 0x01, 0x10, 0xD2, 0x4C, 0xC6, 0x21, 0x18,
|
||||
0x80, 0x62, 0x01, 0x88, 0x06, 0x21, 0x14, 0x7C, 0xD8, 0x02, 0x30, 0x30,
|
||||
0x3F, 0x80, 0x30, 0x90, 0x13, 0xE8, 0x50, 0xBF, 0x80, 0x08, 0x23, 0x08,
|
||||
0xC2, 0x30, 0xCC, 0x31, 0x86, 0x18, 0x61, 0x84, 0x18, 0x41, 0x04, 0xFF,
|
||||
0xE0, 0x04, 0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x08, 0xFF, 0xE0, 0x07,
|
||||
0x80, 0x61, 0x82, 0x01, 0x13, 0xC2, 0x44, 0xC6, 0x11, 0x18, 0x44, 0x61,
|
||||
0xE1, 0x84, 0x86, 0x11, 0x14, 0xE6, 0xD8, 0x02, 0x30, 0x30, 0x3F, 0x80,
|
||||
0xFE, 0x79, 0x0A, 0x0C, 0x18, 0x49, 0x8C, 0x00, 0x04, 0x00, 0x80, 0x10,
|
||||
0x02, 0x00, 0x41, 0xFF, 0xC1, 0x00, 0x20, 0x04, 0x00, 0x80, 0x00, 0x00,
|
||||
0x0F, 0xFE, 0x31, 0x28, 0x41, 0x08, 0x42, 0x30, 0xFC, 0x31, 0x20, 0x42,
|
||||
0x18, 0x10, 0x61, 0x78, 0x21, 0x84, 0xC0, 0xC0, 0x00, 0x7F, 0x90, 0x24,
|
||||
0x09, 0x04, 0x42, 0x00, 0x80, 0x40, 0x20, 0x18, 0x04, 0x12, 0x05, 0x01,
|
||||
0x40, 0x7F, 0xF0, 0xE1, 0xE2, 0x02, 0x20, 0x22, 0x02, 0x20, 0x22, 0x02,
|
||||
0x20, 0x22, 0x06, 0x20, 0xE3, 0xF3, 0x20, 0x02, 0x00, 0x20, 0x02, 0x00,
|
||||
0x20, 0x00, 0x07, 0xCF, 0xA3, 0x14, 0x62, 0x8C, 0x51, 0x8A, 0x31, 0x43,
|
||||
0xA8, 0x1D, 0x00, 0xA0, 0x14, 0x02, 0x80, 0x50, 0x0A, 0x01, 0x41, 0xE6,
|
||||
0x74, 0x42, 0x1A, 0x06, 0x00, 0x00, 0x07, 0xFA, 0x0D, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x0E, 0x07, 0xFE, 0x27, 0x08, 0x42, 0x10, 0x84, 0xF8,
|
||||
0x39, 0x8A, 0x0C, 0x18, 0x30, 0x9E, 0x00, 0x84, 0x18, 0x41, 0x84, 0x18,
|
||||
0xC1, 0x8C, 0x31, 0x8C, 0x63, 0x08, 0xC2, 0x10, 0x80, 0x03, 0xFC, 0x74,
|
||||
0x12, 0x10, 0x50, 0x41, 0x41, 0x06, 0x04, 0x88, 0x1E, 0x20, 0x48, 0x81,
|
||||
0x23, 0x04, 0x04, 0x10, 0x58, 0x41, 0x31, 0x04, 0x3F, 0xF0, 0x3C, 0xF1,
|
||||
0x0A, 0x24, 0x30, 0xE0, 0x41, 0x81, 0xFE, 0x04, 0x08, 0x10, 0x10, 0xC0,
|
||||
0x42, 0x84, 0xF1, 0xE0, 0x38, 0xC1, 0x8C, 0x00, 0x07, 0x07, 0x60, 0x22,
|
||||
0x04, 0x10, 0xC1, 0x88, 0x09, 0x00, 0x50, 0x06, 0x00, 0x20, 0x02, 0x00,
|
||||
0x20, 0x02, 0x00, 0x20, 0x1F, 0xC0, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x08,
|
||||
0x18, 0x60, 0xC0, 0x80, 0x80, 0x81, 0xC1, 0x7E, 0x08, 0x00, 0x30, 0x00,
|
||||
0x20, 0x00, 0x40, 0x00, 0x00, 0x7C, 0x00, 0x30, 0x01, 0x20, 0x04, 0x80,
|
||||
0x12, 0x00, 0x84, 0x02, 0x10, 0x08, 0x20, 0x7F, 0x81, 0x02, 0x04, 0x04,
|
||||
0x20, 0x10, 0x80, 0x4F, 0x87, 0xC0, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x7C, 0x00, 0x30, 0x01, 0x20, 0x04, 0x80, 0x12, 0x00,
|
||||
0x84, 0x02, 0x10, 0x08, 0x20, 0x7F, 0x81, 0x02, 0x04, 0x04, 0x20, 0x10,
|
||||
0x80, 0x4F, 0x87, 0xC0, 0x03, 0x00, 0x1A, 0x00, 0x84, 0x00, 0x00, 0x1F,
|
||||
0x00, 0x0C, 0x00, 0x48, 0x01, 0x20, 0x04, 0x80, 0x21, 0x00, 0x84, 0x02,
|
||||
0x08, 0x1F, 0xE0, 0x40, 0x81, 0x01, 0x08, 0x04, 0x20, 0x13, 0xE1, 0xF0,
|
||||
0x06, 0x20, 0x27, 0x00, 0x00, 0x07, 0xC0, 0x03, 0x00, 0x12, 0x00, 0x48,
|
||||
0x01, 0x20, 0x08, 0x40, 0x21, 0x00, 0x82, 0x07, 0xF8, 0x10, 0x20, 0x40,
|
||||
0x42, 0x01, 0x08, 0x04, 0xF8, 0x7C, 0x08, 0x60, 0x71, 0x80, 0x00, 0x07,
|
||||
0xC0, 0x03, 0x00, 0x12, 0x00, 0x48, 0x01, 0x20, 0x08, 0x40, 0x21, 0x00,
|
||||
0x82, 0x07, 0xF8, 0x10, 0x20, 0x40, 0x42, 0x01, 0x08, 0x04, 0xF8, 0x7C,
|
||||
0x03, 0x80, 0x12, 0x00, 0x48, 0x01, 0xE0, 0x00, 0x00, 0x7C, 0x00, 0x30,
|
||||
0x01, 0x20, 0x04, 0x80, 0x12, 0x00, 0x84, 0x02, 0x10, 0x08, 0x20, 0x7F,
|
||||
0x81, 0x02, 0x04, 0x04, 0x20, 0x10, 0x80, 0x4F, 0x87, 0xC0, 0x1F, 0xFC,
|
||||
0x14, 0x10, 0x50, 0x42, 0x41, 0x09, 0x04, 0x24, 0x80, 0x9E, 0x04, 0x48,
|
||||
0x1F, 0x20, 0x44, 0x02, 0x10, 0x48, 0x41, 0x21, 0x07, 0xDF, 0xF0, 0x1E,
|
||||
0x06, 0x39, 0x01, 0x40, 0x28, 0x01, 0x00, 0x20, 0x04, 0x00, 0x80, 0x10,
|
||||
0x02, 0x00, 0x20, 0x16, 0x04, 0x3F, 0x01, 0x00, 0x30, 0x02, 0x03, 0xC0,
|
||||
0x10, 0x01, 0x00, 0x10, 0x01, 0x00, 0x00, 0xFF, 0xC8, 0x09, 0x01, 0x20,
|
||||
0x24, 0x00, 0x88, 0x1F, 0x02, 0x20, 0x44, 0x08, 0x01, 0x01, 0x20, 0x24,
|
||||
0x07, 0xFF, 0x80, 0x00, 0x00, 0x60, 0x18, 0x06, 0x00, 0x00, 0xFF, 0xC8,
|
||||
0x09, 0x01, 0x20, 0x24, 0x00, 0x88, 0x1F, 0x02, 0x20, 0x44, 0x08, 0x01,
|
||||
0x01, 0x20, 0x24, 0x07, 0xFF, 0x80, 0x06, 0x01, 0xE0, 0x42, 0x00, 0x07,
|
||||
0xFE, 0x40, 0x48, 0x09, 0x01, 0x20, 0x04, 0x40, 0xF8, 0x11, 0x02, 0x20,
|
||||
0x40, 0x08, 0x09, 0x01, 0x20, 0x3F, 0xFC, 0x30, 0xC6, 0x38, 0x00, 0x3F,
|
||||
0xF2, 0x02, 0x40, 0x48, 0x09, 0x00, 0x22, 0x07, 0xC0, 0x88, 0x11, 0x02,
|
||||
0x00, 0x40, 0x48, 0x09, 0x01, 0xFF, 0xE0, 0x00, 0x18, 0x06, 0x01, 0x80,
|
||||
0x07, 0xF8, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20,
|
||||
0x10, 0x08, 0x04, 0x3F, 0xE0, 0x00, 0x01, 0x03, 0x03, 0x00, 0x07, 0xF8,
|
||||
0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08,
|
||||
0x04, 0x3F, 0xE0, 0x18, 0x1A, 0x10, 0xC0, 0x0F, 0xF0, 0x40, 0x20, 0x10,
|
||||
0x08, 0x04, 0x02, 0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x7F, 0xC0,
|
||||
0x43, 0x71, 0x80, 0x1F, 0xE0, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02,
|
||||
0x01, 0x00, 0x80, 0x40, 0x20, 0x10, 0xFF, 0x80, 0x3E, 0x02, 0x1C, 0x20,
|
||||
0x22, 0x01, 0x20, 0x12, 0x01, 0x7E, 0x1A, 0x11, 0x20, 0x12, 0x01, 0x20,
|
||||
0x12, 0x02, 0x20, 0x67, 0xF8, 0x1C, 0x43, 0x38, 0x00, 0x0E, 0x0F, 0x60,
|
||||
0x25, 0x02, 0x58, 0x24, 0x82, 0x44, 0x24, 0x42, 0x42, 0x24, 0x32, 0x41,
|
||||
0x24, 0x0A, 0x40, 0xA4, 0x06, 0xF8, 0x60, 0x00, 0x00, 0x80, 0x06, 0x00,
|
||||
0x20, 0x00, 0x00, 0xF0, 0x18, 0xC2, 0x06, 0x40, 0x24, 0x01, 0x80, 0x18,
|
||||
0x01, 0x80, 0x18, 0x01, 0xC0, 0x14, 0x03, 0x60, 0x23, 0x04, 0x1F, 0x80,
|
||||
0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x00, 0x00, 0xF0, 0x18, 0xC2, 0x06,
|
||||
0x40, 0x24, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0xC0, 0x14, 0x03,
|
||||
0x60, 0x23, 0x04, 0x1F, 0x80, 0x06, 0x00, 0xD0, 0x10, 0x80, 0x00, 0x0F,
|
||||
0x01, 0x8C, 0x20, 0x64, 0x02, 0x40, 0x18, 0x01, 0x80, 0x18, 0x01, 0x80,
|
||||
0x1C, 0x01, 0x40, 0x36, 0x02, 0x30, 0x41, 0xF8, 0x0C, 0x41, 0x38, 0x00,
|
||||
0x00, 0xF0, 0x18, 0xC2, 0x06, 0x40, 0x24, 0x01, 0x80, 0x18, 0x01, 0x80,
|
||||
0x18, 0x01, 0xC0, 0x14, 0x03, 0x60, 0x23, 0x04, 0x1F, 0x80, 0x10, 0xC3,
|
||||
0x8C, 0x00, 0x00, 0xF0, 0x18, 0xC2, 0x06, 0x40, 0x24, 0x01, 0x80, 0x18,
|
||||
0x01, 0x80, 0x18, 0x01, 0xC0, 0x14, 0x03, 0x60, 0x23, 0x04, 0x1F, 0x80,
|
||||
0x81, 0xA1, 0x89, 0x83, 0x81, 0x81, 0xA1, 0x89, 0x82, 0x80, 0x00, 0x00,
|
||||
0x00, 0xF1, 0x18, 0xE2, 0x06, 0x40, 0x64, 0x09, 0x81, 0x18, 0x21, 0x86,
|
||||
0x18, 0x41, 0xC8, 0x15, 0x03, 0x60, 0x27, 0x04, 0x5F, 0x88, 0x00, 0x00,
|
||||
0x00, 0x80, 0x06, 0x00, 0x20, 0x00, 0x0F, 0x0F, 0x40, 0x24, 0x02, 0x40,
|
||||
0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x26, 0x02, 0x20,
|
||||
0x63, 0x04, 0x1F, 0x80, 0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x00, 0x0F,
|
||||
0x0F, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24,
|
||||
0x02, 0x40, 0x26, 0x02, 0x20, 0x63, 0x04, 0x1F, 0x80, 0x06, 0x00, 0xD0,
|
||||
0x10, 0x80, 0x00, 0xF0, 0xF4, 0x02, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02,
|
||||
0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x60, 0x22, 0x06, 0x30, 0x41, 0xF8,
|
||||
0x10, 0xC3, 0x8C, 0x00, 0x0F, 0x0F, 0x40, 0x24, 0x02, 0x40, 0x24, 0x02,
|
||||
0x40, 0x24, 0x02, 0x40, 0x24, 0x02, 0x40, 0x26, 0x02, 0x20, 0x63, 0x04,
|
||||
0x1F, 0x80, 0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x00, 0x07, 0x07, 0x60,
|
||||
0x22, 0x04, 0x10, 0xC1, 0x88, 0x09, 0x00, 0x50, 0x06, 0x00, 0x20, 0x02,
|
||||
0x00, 0x20, 0x02, 0x00, 0x20, 0x1F, 0xC0, 0x7E, 0x04, 0x00, 0x80, 0x1F,
|
||||
0x02, 0x1C, 0x40, 0x88, 0x09, 0x01, 0x20, 0x24, 0x08, 0xFE, 0x10, 0x02,
|
||||
0x01, 0xFC, 0x00, 0x00, 0x03, 0xE0, 0x84, 0x30, 0x44, 0x08, 0x82, 0x11,
|
||||
0xC2, 0x0C, 0x40, 0x48, 0x05, 0x00, 0xA0, 0x14, 0x42, 0x88, 0xF8, 0xF0,
|
||||
0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x20, 0x04, 0x00,
|
||||
0x87, 0xF3, 0x02, 0x40, 0x48, 0x09, 0x03, 0x1F, 0xB8, 0x02, 0x00, 0x80,
|
||||
0x20, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x20, 0x04, 0x00, 0x87, 0xF3, 0x02,
|
||||
0x40, 0x48, 0x09, 0x03, 0x1F, 0xB8, 0x0C, 0x03, 0xC0, 0x8C, 0x00, 0x00,
|
||||
0x00, 0xFE, 0x00, 0x20, 0x04, 0x00, 0x87, 0xF3, 0x02, 0x40, 0x48, 0x09,
|
||||
0x03, 0x1F, 0xB8, 0x18, 0x84, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x01, 0x00,
|
||||
0x20, 0x04, 0x3F, 0x98, 0x12, 0x02, 0x40, 0x48, 0x18, 0xFD, 0xC0, 0x63,
|
||||
0x8C, 0x70, 0x00, 0x00, 0x07, 0xF0, 0x01, 0x00, 0x20, 0x04, 0x3F, 0x98,
|
||||
0x12, 0x02, 0x40, 0x48, 0x18, 0xFD, 0xC0, 0x0E, 0x02, 0x40, 0x48, 0x07,
|
||||
0x00, 0x00, 0x00, 0x1F, 0xC0, 0x04, 0x00, 0x80, 0x10, 0xFE, 0x60, 0x48,
|
||||
0x09, 0x01, 0x20, 0x63, 0xF7, 0x3E, 0xF0, 0x0A, 0x20, 0x10, 0x80, 0x41,
|
||||
0x3F, 0xFD, 0x04, 0x08, 0x10, 0x20, 0x40, 0x43, 0x85, 0xF7, 0xE0, 0x3F,
|
||||
0xCC, 0x19, 0x01, 0x40, 0x08, 0x01, 0x00, 0x20, 0x02, 0x01, 0x60, 0x47,
|
||||
0xF0, 0x10, 0x03, 0x00, 0x20, 0x3C, 0x00, 0x10, 0x02, 0x00, 0x40, 0x00,
|
||||
0x00, 0x0F, 0xC4, 0x0A, 0x01, 0x80, 0x7F, 0xF8, 0x02, 0x00, 0x80, 0x10,
|
||||
0x13, 0xF8, 0x03, 0x01, 0x00, 0x80, 0x00, 0x00, 0x0F, 0xC4, 0x0A, 0x01,
|
||||
0x80, 0x7F, 0xF8, 0x02, 0x00, 0x80, 0x10, 0x13, 0xF8, 0x04, 0x06, 0x83,
|
||||
0x10, 0x82, 0x00, 0x0F, 0xC4, 0x0A, 0x01, 0x80, 0x7F, 0xF8, 0x02, 0x00,
|
||||
0x80, 0x10, 0x13, 0xF8, 0x31, 0x8C, 0x60, 0x00, 0x00, 0x3F, 0x10, 0x28,
|
||||
0x06, 0x01, 0xFF, 0xE0, 0x08, 0x02, 0x00, 0x40, 0x4F, 0xE0, 0x30, 0x02,
|
||||
0x00, 0x40, 0x00, 0x00, 0x1F, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40,
|
||||
0x10, 0x04, 0x01, 0x0F, 0xFC, 0x02, 0x01, 0x00, 0x80, 0x00, 0x00, 0x1F,
|
||||
0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x0F, 0xFC,
|
||||
0x08, 0x05, 0x82, 0x30, 0x00, 0x00, 0x1F, 0x00, 0x40, 0x10, 0x04, 0x01,
|
||||
0x00, 0x40, 0x10, 0x04, 0x01, 0x0F, 0xFC, 0x63, 0x98, 0xE0, 0x00, 0x00,
|
||||
0x7C, 0x01, 0x00, 0x40, 0x10, 0x04, 0x01, 0x00, 0x40, 0x10, 0x04, 0x3F,
|
||||
0xF0, 0x30, 0x81, 0xE0, 0x78, 0x00, 0x80, 0x08, 0x7F, 0x98, 0x36, 0x02,
|
||||
0x80, 0x70, 0x06, 0x00, 0xC0, 0x2C, 0x04, 0xC1, 0x0F, 0xC0, 0x1C, 0x43,
|
||||
0x38, 0x00, 0x00, 0x00, 0x6F, 0x83, 0x04, 0x20, 0x42, 0x02, 0x20, 0x22,
|
||||
0x02, 0x20, 0x22, 0x02, 0x20, 0x2F, 0x8F, 0x10, 0x01, 0x00, 0x10, 0x00,
|
||||
0x00, 0x00, 0x7E, 0x18, 0x26, 0x02, 0x80, 0x50, 0x06, 0x00, 0xC0, 0x28,
|
||||
0x04, 0x81, 0x0F, 0xC0, 0x02, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x7E,
|
||||
0x18, 0x26, 0x02, 0x80, 0x50, 0x06, 0x00, 0xC0, 0x28, 0x04, 0x81, 0x0F,
|
||||
0xC0, 0x0C, 0x03, 0x40, 0xC4, 0x00, 0x00, 0x00, 0x7E, 0x18, 0x26, 0x02,
|
||||
0x80, 0x50, 0x06, 0x00, 0xC0, 0x28, 0x04, 0x81, 0x0F, 0xC0, 0x18, 0x84,
|
||||
0xE0, 0x00, 0x00, 0x03, 0xF0, 0xC1, 0x30, 0x14, 0x02, 0x80, 0x30, 0x06,
|
||||
0x01, 0x40, 0x24, 0x08, 0x7E, 0x00, 0x71, 0x8E, 0x30, 0x00, 0x00, 0x03,
|
||||
0xF0, 0xC1, 0x30, 0x14, 0x02, 0x80, 0x30, 0x06, 0x01, 0x40, 0x24, 0x08,
|
||||
0x7E, 0x00, 0x0C, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0x11, 0xFA, 0x30, 0x46,
|
||||
0x0A, 0x41, 0x24, 0x21, 0x44, 0x14, 0x82, 0x70, 0x22, 0x04, 0x5F, 0x88,
|
||||
0x00, 0x08, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x0E, 0x1E, 0x20, 0x22,
|
||||
0x02, 0x20, 0x22, 0x02, 0x20, 0x22, 0x02, 0x20, 0x62, 0x0A, 0x1F, 0x30,
|
||||
0x01, 0x00, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x0E, 0x1E, 0x20, 0x22, 0x02,
|
||||
0x20, 0x22, 0x02, 0x20, 0x22, 0x02, 0x20, 0x62, 0x0A, 0x1F, 0x30, 0x06,
|
||||
0x00, 0xF0, 0x18, 0x80, 0x00, 0x00, 0x0E, 0x1E, 0x20, 0x22, 0x02, 0x20,
|
||||
0x22, 0x02, 0x20, 0x22, 0x02, 0x20, 0x62, 0x0A, 0x1F, 0x30, 0x30, 0xC3,
|
||||
0x0C, 0x00, 0x00, 0x00, 0xE1, 0xE2, 0x02, 0x20, 0x22, 0x02, 0x20, 0x22,
|
||||
0x02, 0x20, 0x22, 0x06, 0x20, 0xA1, 0xF3, 0x00, 0x80, 0x10, 0x02, 0x00,
|
||||
0x00, 0x00, 0x0F, 0x0F, 0x20, 0x22, 0x04, 0x10, 0x41, 0x08, 0x08, 0x80,
|
||||
0x90, 0x05, 0x00, 0x50, 0x02, 0x00, 0x20, 0x04, 0x00, 0x40, 0x7E, 0x00,
|
||||
0xC0, 0x04, 0x00, 0x40, 0x04, 0x00, 0x4F, 0xC5, 0x06, 0x60, 0x26, 0x01,
|
||||
0x40, 0x16, 0x01, 0x60, 0x17, 0x02, 0x58, 0xC4, 0x70, 0x40, 0x04, 0x00,
|
||||
0x40, 0x0F, 0x80, 0x38, 0xC3, 0x8C, 0x00, 0x00, 0x00, 0xF0, 0xF2, 0x02,
|
||||
0x20, 0x41, 0x04, 0x10, 0x80, 0x88, 0x09, 0x00, 0x50, 0x05, 0x00, 0x20,
|
||||
0x02, 0x00, 0x40, 0x04, 0x07, 0xE0 };
|
||||
|
||||
const GFXglyph FreeMono12pt8bGlyphs[] PROGMEM = {
|
||||
{ 0, 1, 1, 14, 0, 0 }, // 0x20 ' ' U+0020
|
||||
{ 1, 3, 15, 14, 6, -14 }, // 0x21 '!' U+0021
|
||||
{ 7, 8, 7, 14, 3, -14 }, // 0x22 '"' U+0022
|
||||
{ 14, 10, 17, 14, 2, -15 }, // 0x23 '#' U+0023
|
||||
{ 36, 9, 18, 14, 3, -15 }, // 0x24 '$' U+0024
|
||||
{ 57, 10, 15, 14, 2, -14 }, // 0x25 '%' U+0025
|
||||
{ 76, 8, 12, 14, 3, -11 }, // 0x26 '&' U+0026
|
||||
{ 88, 3, 7, 14, 6, -14 }, // 0x27 ''' U+0027
|
||||
{ 91, 4, 18, 14, 7, -14 }, // 0x28 '(' U+0028
|
||||
{ 100, 3, 18, 14, 4, -14 }, // 0x29 ')' U+0029
|
||||
{ 107, 9, 9, 14, 3, -14 }, // 0x2a '*' U+002A
|
||||
{ 118, 11, 12, 14, 2, -12 }, // 0x2b '+' U+002B
|
||||
{ 135, 5, 6, 14, 3, -2 }, // 0x2c ',' U+002C
|
||||
{ 139, 11, 1, 14, 2, -6 }, // 0x2d '-' U+002D
|
||||
{ 141, 4, 3, 14, 5, -2 }, // 0x2e '.' U+002E
|
||||
{ 143, 9, 18, 14, 3, -15 }, // 0x2f '/' U+002F
|
||||
{ 164, 9, 15, 14, 3, -14 }, // 0x30 '0' U+0030
|
||||
{ 181, 9, 15, 14, 3, -14 }, // 0x31 '1' U+0031
|
||||
{ 198, 9, 15, 14, 2, -14 }, // 0x32 '2' U+0032
|
||||
{ 215, 10, 15, 14, 2, -14 }, // 0x33 '3' U+0033
|
||||
{ 234, 8, 15, 14, 3, -14 }, // 0x34 '4' U+0034
|
||||
{ 249, 10, 15, 14, 2, -14 }, // 0x35 '5' U+0035
|
||||
{ 268, 9, 15, 14, 3, -14 }, // 0x36 '6' U+0036
|
||||
{ 285, 8, 15, 14, 3, -14 }, // 0x37 '7' U+0037
|
||||
{ 300, 9, 15, 14, 3, -14 }, // 0x38 '8' U+0038
|
||||
{ 317, 9, 15, 14, 3, -14 }, // 0x39 '9' U+0039
|
||||
{ 334, 4, 10, 14, 5, -9 }, // 0x3a ':' U+003A
|
||||
{ 339, 5, 13, 14, 3, -9 }, // 0x3b ';' U+003B
|
||||
{ 348, 11, 11, 14, 2, -11 }, // 0x3c '<' U+003C
|
||||
{ 364, 12, 4, 14, 1, -8 }, // 0x3d '=' U+003D
|
||||
{ 370, 11, 11, 14, 2, -11 }, // 0x3e '>' U+003E
|
||||
{ 386, 9, 14, 14, 3, -13 }, // 0x3f '?' U+003F
|
||||
{ 402, 8, 16, 14, 3, -14 }, // 0x40 '@' U+0040
|
||||
{ 418, 14, 14, 14, 0, -13 }, // 0x41 'A' U+0041
|
||||
{ 443, 12, 14, 14, 1, -13 }, // 0x42 'B' U+0042
|
||||
{ 464, 11, 14, 14, 2, -13 }, // 0x43 'C' U+0043
|
||||
{ 484, 11, 14, 14, 1, -13 }, // 0x44 'D' U+0044
|
||||
{ 504, 11, 14, 14, 1, -13 }, // 0x45 'E' U+0045
|
||||
{ 524, 11, 14, 14, 1, -13 }, // 0x46 'F' U+0046
|
||||
{ 544, 11, 14, 14, 2, -13 }, // 0x47 'G' U+0047
|
||||
{ 564, 12, 14, 14, 1, -13 }, // 0x48 'H' U+0048
|
||||
{ 585, 9, 14, 14, 3, -13 }, // 0x49 'I' U+0049
|
||||
{ 601, 12, 14, 14, 2, -13 }, // 0x4a 'J' U+004A
|
||||
{ 622, 13, 14, 14, 1, -13 }, // 0x4b 'K' U+004B
|
||||
{ 645, 11, 14, 14, 2, -13 }, // 0x4c 'L' U+004C
|
||||
{ 665, 14, 14, 14, 0, -13 }, // 0x4d 'M' U+004D
|
||||
{ 690, 12, 14, 14, 1, -13 }, // 0x4e 'N' U+004E
|
||||
{ 711, 12, 14, 14, 1, -13 }, // 0x4f 'O' U+004F
|
||||
{ 732, 11, 14, 14, 1, -13 }, // 0x50 'P' U+0050
|
||||
{ 752, 12, 17, 14, 1, -13 }, // 0x51 'Q' U+0051
|
||||
{ 778, 13, 14, 14, 1, -13 }, // 0x52 'R' U+0052
|
||||
{ 801, 10, 14, 14, 2, -13 }, // 0x53 'S' U+0053
|
||||
{ 819, 11, 14, 14, 2, -13 }, // 0x54 'T' U+0054
|
||||
{ 839, 12, 14, 14, 1, -13 }, // 0x55 'U' U+0055
|
||||
{ 860, 14, 14, 14, 0, -13 }, // 0x56 'V' U+0056
|
||||
{ 885, 14, 14, 14, 0, -13 }, // 0x57 'W' U+0057
|
||||
{ 910, 12, 14, 14, 1, -13 }, // 0x58 'X' U+0058
|
||||
{ 931, 12, 14, 14, 1, -13 }, // 0x59 'Y' U+0059
|
||||
{ 952, 10, 14, 14, 2, -13 }, // 0x5a 'Z' U+005A
|
||||
{ 970, 4, 18, 14, 7, -14 }, // 0x5b '[' U+005B
|
||||
{ 979, 9, 18, 14, 3, -15 }, // 0x5c '\' U+005C
|
||||
{ 1000, 4, 18, 14, 4, -14 }, // 0x5d ']' U+005D
|
||||
{ 1009, 9, 7, 14, 3, -14 }, // 0x5e '^' U+005E
|
||||
{ 1017, 14, 1, 14, 0, 3 }, // 0x5f '_' U+005F
|
||||
{ 1019, 4, 3, 14, 4, -14 }, // 0x60 '`' U+0060
|
||||
{ 1021, 11, 10, 14, 2, -9 }, // 0x61 'a' U+0061
|
||||
{ 1035, 12, 15, 14, 1, -14 }, // 0x62 'b' U+0062
|
||||
{ 1058, 11, 10, 14, 2, -9 }, // 0x63 'c' U+0063
|
||||
{ 1072, 12, 15, 14, 2, -14 }, // 0x64 'd' U+0064
|
||||
{ 1095, 10, 10, 14, 2, -9 }, // 0x65 'e' U+0065
|
||||
{ 1108, 10, 15, 14, 3, -14 }, // 0x66 'f' U+0066
|
||||
{ 1127, 11, 14, 14, 2, -9 }, // 0x67 'g' U+0067
|
||||
{ 1147, 12, 15, 14, 1, -14 }, // 0x68 'h' U+0068
|
||||
{ 1170, 10, 15, 14, 2, -14 }, // 0x69 'i' U+0069
|
||||
{ 1189, 7, 19, 14, 4, -14 }, // 0x6a 'j' U+006A
|
||||
{ 1206, 11, 15, 14, 2, -14 }, // 0x6b 'k' U+006B
|
||||
{ 1227, 10, 15, 14, 2, -14 }, // 0x6c 'l' U+006C
|
||||
{ 1246, 14, 10, 14, 0, -9 }, // 0x6d 'm' U+006D
|
||||
{ 1264, 12, 10, 14, 1, -9 }, // 0x6e 'n' U+006E
|
||||
{ 1279, 11, 10, 14, 2, -9 }, // 0x6f 'o' U+006F
|
||||
{ 1293, 12, 14, 14, 1, -9 }, // 0x70 'p' U+0070
|
||||
{ 1314, 12, 14, 14, 2, -9 }, // 0x71 'q' U+0071
|
||||
{ 1335, 11, 10, 14, 2, -9 }, // 0x72 'r' U+0072
|
||||
{ 1349, 10, 10, 14, 2, -9 }, // 0x73 's' U+0073
|
||||
{ 1362, 11, 14, 14, 1, -13 }, // 0x74 't' U+0074
|
||||
{ 1382, 12, 10, 14, 1, -9 }, // 0x75 'u' U+0075
|
||||
{ 1397, 13, 10, 14, 1, -9 }, // 0x76 'v' U+0076
|
||||
{ 1414, 13, 10, 14, 1, -9 }, // 0x77 'w' U+0077
|
||||
{ 1431, 12, 10, 14, 1, -9 }, // 0x78 'x' U+0078
|
||||
{ 1446, 12, 14, 14, 1, -9 }, // 0x79 'y' U+0079
|
||||
{ 1467, 9, 10, 14, 3, -9 }, // 0x7a 'z' U+007A
|
||||
{ 1479, 6, 18, 14, 4, -14 }, // 0x7b '{' U+007B
|
||||
{ 1493, 1, 18, 14, 7, -14 }, // 0x7c '|' U+007C
|
||||
{ 1496, 6, 18, 14, 5, -14 }, // 0x7d '}' U+007D
|
||||
{ 1510, 10, 3, 14, 2, -7 }, // 0x7e '~' U+007E
|
||||
{ 1514, 14, 19, 14, 0, -16 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370
|
||||
{ 1548, 1, 1, 14, 0, 0 }, // 0x80 'NO-BREAK SPACE' U+00A0
|
||||
{ 1549, 3, 15, 14, 6, -10 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1
|
||||
{ 1555, 8, 15, 14, 3, -14 }, // 0x82 'CENT SIGN' U+00A2
|
||||
{ 1570, 10, 14, 14, 2, -13 }, // 0x83 'POUND SIGN' U+00A3
|
||||
{ 1588, 12, 14, 14, 1, -13 }, // 0x84 'EURO SIGN *' U+20AC
|
||||
{ 1609, 12, 14, 14, 1, -13 }, // 0x85 'YEN SIGN' U+00A5
|
||||
{ 1630, 10, 18, 14, 2, -17 }, // 0x86 'LATIN CAPITAL LETTER S WITH CARON *' U+0160
|
||||
{ 1653, 11, 15, 14, 2, -13 }, // 0x87 'SECTION SIGN' U+00A7
|
||||
{ 1674, 10, 15, 14, 2, -14 }, // 0x88 'LATIN SMALL LETTER S WITH CARON *' U+0161
|
||||
{ 1693, 14, 14, 14, 0, -13 }, // 0x89 'COPYRIGHT SIGN' U+00A9
|
||||
{ 1718, 7, 7, 14, 4, -13 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA
|
||||
{ 1725, 11, 10, 14, 2, -9 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB
|
||||
{ 1739, 11, 7, 14, 2, -10 }, // 0x8c 'NOT SIGN' U+00AC
|
||||
{ 1749, 11, 1, 14, 2, -6 }, // 0x8d 'SOFT HYPHEN' U+00AD
|
||||
{ 1751, 14, 14, 14, 0, -13 }, // 0x8e 'REGISTERED SIGN' U+00AE
|
||||
{ 1776, 7, 1, 14, 4, -13 }, // 0x8f 'MACRON' U+00AF
|
||||
{ 1777, 7, 7, 14, 4, -14 }, // 0x90 'DEGREE SIGN' U+00B0
|
||||
{ 1784, 11, 13, 14, 2, -12 }, // 0x91 'PLUS-MINUS SIGN' U+00B1
|
||||
{ 1802, 6, 9, 14, 4, -14 }, // 0x92 'SUPERSCRIPT TWO' U+00B2
|
||||
{ 1809, 6, 9, 14, 4, -14 }, // 0x93 'SUPERSCRIPT THREE' U+00B3
|
||||
{ 1816, 10, 18, 14, 2, -17 }, // 0x94 'LATIN CAPITAL LETTER Z WITH CARON *' U+017D
|
||||
{ 1839, 12, 15, 14, 1, -9 }, // 0x95 'MICRO SIGN' U+00B5
|
||||
{ 1862, 11, 16, 14, 2, -14 }, // 0x96 'PILCROW SIGN' U+00B6
|
||||
{ 1884, 2, 3, 14, 6, -6 }, // 0x97 'MIDDLE DOT' U+00B7
|
||||
{ 1885, 9, 15, 14, 3, -14 }, // 0x98 'LATIN SMALL LETTER Z WITH CARON *' U+017E
|
||||
{ 1902, 5, 9, 14, 5, -14 }, // 0x99 'SUPERSCRIPT ONE' U+00B9
|
||||
{ 1908, 7, 7, 14, 4, -13 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA
|
||||
{ 1915, 11, 10, 14, 2, -9 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB
|
||||
{ 1929, 14, 14, 14, 0, -13 }, // 0x9c 'LATIN CAPITAL LIGATURE OE *' U+0152
|
||||
{ 1954, 14, 10, 14, 0, -9 }, // 0x9d 'LATIN SMALL LIGATURE OE *' U+0153
|
||||
{ 1972, 12, 17, 14, 1, -16 }, // 0x9e 'LATIN CAPITAL LETTER Y WITH DIAERESIS *' U+0178
|
||||
{ 1998, 8, 14, 14, 3, -9 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF
|
||||
{ 2012, 14, 19, 14, 0, -18 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0
|
||||
{ 2046, 14, 19, 14, 0, -18 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1
|
||||
{ 2080, 14, 18, 14, 0, -17 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2
|
||||
{ 2112, 14, 17, 14, 0, -16 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3
|
||||
{ 2142, 14, 17, 14, 0, -16 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4
|
||||
{ 2172, 14, 19, 14, 0, -18 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5
|
||||
{ 2206, 14, 14, 14, 0, -13 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6
|
||||
{ 2231, 11, 18, 14, 2, -13 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7
|
||||
{ 2256, 11, 19, 14, 1, -18 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8
|
||||
{ 2283, 11, 19, 14, 1, -18 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9
|
||||
{ 2310, 11, 18, 14, 1, -17 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA
|
||||
{ 2335, 11, 17, 14, 1, -16 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB
|
||||
{ 2359, 9, 19, 14, 3, -18 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC
|
||||
{ 2381, 9, 19, 14, 3, -18 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD
|
||||
{ 2403, 9, 18, 14, 3, -17 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE
|
||||
{ 2424, 9, 17, 14, 3, -16 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF
|
||||
{ 2444, 12, 14, 14, 0, -13 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0
|
||||
{ 2465, 12, 17, 14, 1, -16 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1
|
||||
{ 2491, 12, 19, 14, 1, -18 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2
|
||||
{ 2520, 12, 19, 14, 1, -18 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3
|
||||
{ 2549, 12, 18, 14, 1, -17 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4
|
||||
{ 2576, 12, 17, 14, 1, -16 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5
|
||||
{ 2602, 12, 17, 14, 1, -16 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6
|
||||
{ 2628, 9, 9, 14, 3, -10 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7
|
||||
{ 2639, 12, 16, 14, 1, -14 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8
|
||||
{ 2663, 12, 19, 14, 1, -18 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9
|
||||
{ 2692, 12, 19, 14, 1, -18 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA
|
||||
{ 2721, 12, 18, 14, 1, -17 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB
|
||||
{ 2748, 12, 17, 14, 1, -16 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC
|
||||
{ 2774, 12, 19, 14, 1, -18 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD
|
||||
{ 2803, 11, 14, 14, 1, -13 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE
|
||||
{ 2823, 11, 15, 14, 1, -14 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF
|
||||
{ 2844, 11, 15, 14, 2, -14 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0
|
||||
{ 2865, 11, 15, 14, 2, -14 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1
|
||||
{ 2886, 11, 15, 14, 2, -14 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2
|
||||
{ 2907, 11, 14, 14, 2, -13 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3
|
||||
{ 2927, 11, 14, 14, 2, -13 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4
|
||||
{ 2947, 11, 16, 14, 2, -15 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5
|
||||
{ 2969, 14, 10, 14, 0, -9 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6
|
||||
{ 2987, 11, 14, 14, 2, -9 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7
|
||||
{ 3007, 10, 15, 14, 2, -14 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8
|
||||
{ 3026, 10, 15, 14, 2, -14 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9
|
||||
{ 3045, 10, 15, 14, 2, -14 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA
|
||||
{ 3064, 10, 14, 14, 2, -13 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB
|
||||
{ 3082, 10, 15, 14, 2, -14 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC
|
||||
{ 3101, 10, 15, 14, 2, -14 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED
|
||||
{ 3120, 10, 15, 14, 2, -14 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE
|
||||
{ 3139, 10, 14, 14, 2, -13 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF
|
||||
{ 3157, 11, 15, 14, 2, -14 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0
|
||||
{ 3178, 12, 14, 14, 1, -13 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1
|
||||
{ 3199, 11, 15, 14, 2, -14 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2
|
||||
{ 3220, 11, 15, 14, 2, -14 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3
|
||||
{ 3241, 11, 15, 14, 2, -14 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4
|
||||
{ 3262, 11, 14, 14, 2, -13 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5
|
||||
{ 3282, 11, 14, 14, 2, -13 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6
|
||||
{ 3302, 11, 12, 14, 2, -12 }, // 0xd7 'DIVISION SIGN' U+00F7
|
||||
{ 3319, 12, 12, 14, 1, -10 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8
|
||||
{ 3337, 12, 15, 14, 1, -14 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9
|
||||
{ 3360, 12, 15, 14, 1, -14 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA
|
||||
{ 3383, 12, 15, 14, 1, -14 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB
|
||||
{ 3406, 12, 14, 14, 1, -13 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC
|
||||
{ 3427, 12, 19, 14, 1, -14 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD
|
||||
{ 3456, 12, 18, 14, 1, -13 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE
|
||||
{ 3483, 12, 18, 14, 1, -13 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF
|
||||
|
||||
const GFXfont FreeMono12pt8b PROGMEM = {
|
||||
(uint8_t *)FreeMono12pt8bBitmaps,
|
||||
(GFXglyph *)FreeMono12pt8bGlyphs,
|
||||
0x20, 0xDF, 26 };
|
||||
|
||||
// Approx. 4861 bytes
|
176
RX_FSK/src/fonts/FreeMono9pt7b.h
Normal file
176
RX_FSK/src/fonts/FreeMono9pt7b.h
Normal file
|
@ -0,0 +1,176 @@
|
|||
const uint8_t FreeMono9pt7bBitmaps[] PROGMEM = {
|
||||
0xAA, 0xA8, 0x0C, 0xED, 0x24, 0x92, 0x48, 0x24, 0x48, 0x91, 0x2F, 0xE4,
|
||||
0x89, 0x7F, 0x28, 0x51, 0x22, 0x40, 0x08, 0x3E, 0x62, 0x40, 0x30, 0x0E,
|
||||
0x01, 0x81, 0xC3, 0xBE, 0x08, 0x08, 0x71, 0x12, 0x23, 0x80, 0x23, 0xB8,
|
||||
0x0E, 0x22, 0x44, 0x70, 0x38, 0x81, 0x02, 0x06, 0x1A, 0x65, 0x46, 0xC8,
|
||||
0xEC, 0xE9, 0x24, 0x5A, 0xAA, 0xA9, 0x40, 0xA9, 0x55, 0x5A, 0x80, 0x10,
|
||||
0x22, 0x4B, 0xE3, 0x05, 0x11, 0x00, 0x10, 0x20, 0x47, 0xF1, 0x02, 0x04,
|
||||
0x00, 0x6B, 0x48, 0xFF, 0x00, 0xF0, 0x02, 0x08, 0x10, 0x60, 0x81, 0x04,
|
||||
0x08, 0x20, 0x41, 0x02, 0x08, 0x00, 0x38, 0x8A, 0x0C, 0x18, 0x30, 0x60,
|
||||
0xC1, 0x82, 0x88, 0xE0, 0x27, 0x28, 0x42, 0x10, 0x84, 0x21, 0x3E, 0x38,
|
||||
0x8A, 0x08, 0x10, 0x20, 0x82, 0x08, 0x61, 0x03, 0xF8, 0x7C, 0x06, 0x02,
|
||||
0x02, 0x1C, 0x06, 0x01, 0x01, 0x01, 0x42, 0x3C, 0x18, 0xA2, 0x92, 0x8A,
|
||||
0x28, 0xBF, 0x08, 0x21, 0xC0, 0x7C, 0x81, 0x03, 0xE4, 0x40, 0x40, 0x81,
|
||||
0x03, 0x88, 0xE0, 0x1E, 0x41, 0x04, 0x0B, 0x98, 0xB0, 0xC1, 0xC2, 0x88,
|
||||
0xE0, 0xFE, 0x04, 0x08, 0x20, 0x40, 0x82, 0x04, 0x08, 0x20, 0x40, 0x38,
|
||||
0x8A, 0x0C, 0x14, 0x47, 0x11, 0x41, 0x83, 0x8C, 0xE0, 0x38, 0x8A, 0x1C,
|
||||
0x18, 0x68, 0xCE, 0x81, 0x04, 0x13, 0xC0, 0xF0, 0x0F, 0x6C, 0x00, 0xD2,
|
||||
0xD2, 0x00, 0x03, 0x04, 0x18, 0x60, 0x60, 0x18, 0x04, 0x03, 0xFF, 0x80,
|
||||
0x00, 0x1F, 0xF0, 0x40, 0x18, 0x03, 0x00, 0x60, 0x20, 0x60, 0xC0, 0x80,
|
||||
0x3D, 0x84, 0x08, 0x30, 0xC2, 0x00, 0x00, 0x00, 0x30, 0x3C, 0x46, 0x82,
|
||||
0x8E, 0xB2, 0xA2, 0xA2, 0x9F, 0x80, 0x80, 0x40, 0x3C, 0x3C, 0x01, 0x40,
|
||||
0x28, 0x09, 0x01, 0x10, 0x42, 0x0F, 0xC1, 0x04, 0x40, 0x9E, 0x3C, 0xFE,
|
||||
0x21, 0x90, 0x48, 0x67, 0xE2, 0x09, 0x02, 0x81, 0x41, 0xFF, 0x80, 0x3E,
|
||||
0xB0, 0xF0, 0x30, 0x08, 0x04, 0x02, 0x00, 0x80, 0x60, 0x8F, 0x80, 0xFE,
|
||||
0x21, 0x90, 0x68, 0x14, 0x0A, 0x05, 0x02, 0x83, 0x43, 0x7F, 0x00, 0xFF,
|
||||
0x20, 0x90, 0x08, 0x87, 0xC2, 0x21, 0x00, 0x81, 0x40, 0xFF, 0xC0, 0xFF,
|
||||
0xA0, 0x50, 0x08, 0x87, 0xC2, 0x21, 0x00, 0x80, 0x40, 0x78, 0x00, 0x1E,
|
||||
0x98, 0x6C, 0x0A, 0x00, 0x80, 0x20, 0xF8, 0x0B, 0x02, 0x60, 0x87, 0xC0,
|
||||
0xE3, 0xA0, 0x90, 0x48, 0x27, 0xF2, 0x09, 0x04, 0x82, 0x41, 0x71, 0xC0,
|
||||
0xF9, 0x08, 0x42, 0x10, 0x84, 0x27, 0xC0, 0x1F, 0x02, 0x02, 0x02, 0x02,
|
||||
0x02, 0x82, 0x82, 0xC6, 0x78, 0xE3, 0xA1, 0x11, 0x09, 0x05, 0x83, 0x21,
|
||||
0x08, 0x84, 0x41, 0x70, 0xC0, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41,
|
||||
0x41, 0x41, 0xFF, 0xE0, 0xEC, 0x19, 0x45, 0x28, 0xA4, 0xA4, 0x94, 0x91,
|
||||
0x12, 0x02, 0x40, 0x5C, 0x1C, 0xC3, 0xB0, 0x94, 0x4A, 0x24, 0x92, 0x49,
|
||||
0x14, 0x8A, 0x43, 0x70, 0x80, 0x1E, 0x31, 0x90, 0x50, 0x18, 0x0C, 0x06,
|
||||
0x02, 0x82, 0x63, 0x0F, 0x00, 0xFE, 0x43, 0x41, 0x41, 0x42, 0x7C, 0x40,
|
||||
0x40, 0x40, 0xF0, 0x1C, 0x31, 0x90, 0x50, 0x18, 0x0C, 0x06, 0x02, 0x82,
|
||||
0x63, 0x1F, 0x04, 0x07, 0x92, 0x30, 0xFE, 0x21, 0x90, 0x48, 0x24, 0x23,
|
||||
0xE1, 0x10, 0x84, 0x41, 0x70, 0xC0, 0x3A, 0xCD, 0x0A, 0x03, 0x01, 0x80,
|
||||
0xC1, 0xC7, 0x78, 0xFF, 0xC4, 0x62, 0x21, 0x00, 0x80, 0x40, 0x20, 0x10,
|
||||
0x08, 0x1F, 0x00, 0xE3, 0xA0, 0x90, 0x48, 0x24, 0x12, 0x09, 0x04, 0x82,
|
||||
0x22, 0x0E, 0x00, 0xF1, 0xE8, 0x10, 0x82, 0x10, 0x42, 0x10, 0x22, 0x04,
|
||||
0x80, 0x50, 0x0C, 0x00, 0x80, 0xF1, 0xE8, 0x09, 0x11, 0x25, 0x44, 0xA8,
|
||||
0x55, 0x0C, 0xA1, 0x8C, 0x31, 0x84, 0x30, 0xE3, 0xA0, 0x88, 0x82, 0x80,
|
||||
0x80, 0xC0, 0x90, 0x44, 0x41, 0x71, 0xC0, 0xE3, 0xA0, 0x88, 0x82, 0x81,
|
||||
0x40, 0x40, 0x20, 0x10, 0x08, 0x1F, 0x00, 0xFD, 0x0A, 0x20, 0x81, 0x04,
|
||||
0x10, 0x21, 0x83, 0xFC, 0xEA, 0xAA, 0xAA, 0xC0, 0x80, 0x81, 0x03, 0x02,
|
||||
0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0xD5, 0x55, 0x55, 0xC0,
|
||||
0x10, 0x51, 0x22, 0x28, 0x20, 0xFF, 0xE0, 0x88, 0x80, 0x7E, 0x00, 0x80,
|
||||
0x47, 0xEC, 0x14, 0x0A, 0x0C, 0xFB, 0xC0, 0x20, 0x10, 0x0B, 0xC6, 0x12,
|
||||
0x05, 0x02, 0x81, 0x40, 0xB0, 0xB7, 0x80, 0x3A, 0x8E, 0x0C, 0x08, 0x10,
|
||||
0x10, 0x9E, 0x03, 0x00, 0x80, 0x47, 0xA4, 0x34, 0x0A, 0x05, 0x02, 0x81,
|
||||
0x21, 0x8F, 0x60, 0x3C, 0x43, 0x81, 0xFF, 0x80, 0x80, 0x61, 0x3E, 0x3D,
|
||||
0x04, 0x3E, 0x41, 0x04, 0x10, 0x41, 0x0F, 0x80, 0x3D, 0xA1, 0xA0, 0x50,
|
||||
0x28, 0x14, 0x09, 0x0C, 0x7A, 0x01, 0x01, 0x87, 0x80, 0xC0, 0x20, 0x10,
|
||||
0x0B, 0xC6, 0x32, 0x09, 0x04, 0x82, 0x41, 0x20, 0xB8, 0xE0, 0x10, 0x01,
|
||||
0xC0, 0x81, 0x02, 0x04, 0x08, 0x11, 0xFC, 0x10, 0x3E, 0x10, 0x84, 0x21,
|
||||
0x08, 0x42, 0x3F, 0x00, 0xC0, 0x40, 0x40, 0x4F, 0x44, 0x58, 0x70, 0x48,
|
||||
0x44, 0x42, 0xC7, 0x70, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x23,
|
||||
0xF8, 0xB7, 0x64, 0x62, 0x31, 0x18, 0x8C, 0x46, 0x23, 0x91, 0x5E, 0x31,
|
||||
0x90, 0x48, 0x24, 0x12, 0x09, 0x05, 0xC7, 0x3E, 0x31, 0xA0, 0x30, 0x18,
|
||||
0x0C, 0x05, 0x8C, 0x7C, 0xDE, 0x30, 0x90, 0x28, 0x14, 0x0A, 0x05, 0x84,
|
||||
0xBC, 0x40, 0x20, 0x38, 0x00, 0x3D, 0xA1, 0xA0, 0x50, 0x28, 0x14, 0x09,
|
||||
0x0C, 0x7A, 0x01, 0x00, 0x80, 0xE0, 0xCE, 0xA1, 0x82, 0x04, 0x08, 0x10,
|
||||
0x7C, 0x3A, 0x8D, 0x0B, 0x80, 0xF0, 0x70, 0xDE, 0x40, 0x40, 0xFC, 0x40,
|
||||
0x40, 0x40, 0x40, 0x40, 0x41, 0x3E, 0xC3, 0x41, 0x41, 0x41, 0x41, 0x41,
|
||||
0x43, 0x3D, 0xE3, 0xA0, 0x90, 0x84, 0x42, 0x20, 0xA0, 0x50, 0x10, 0xE3,
|
||||
0xC0, 0x92, 0x4B, 0x25, 0x92, 0xA9, 0x98, 0x44, 0xE3, 0x31, 0x05, 0x01,
|
||||
0x01, 0x41, 0x11, 0x05, 0xC7, 0xE3, 0xA0, 0x90, 0x84, 0x42, 0x40, 0xA0,
|
||||
0x60, 0x10, 0x10, 0x08, 0x3E, 0x00, 0xFD, 0x08, 0x20, 0x82, 0x08, 0x10,
|
||||
0xBF, 0x29, 0x24, 0xA2, 0x49, 0x26, 0xFF, 0xF8, 0x89, 0x24, 0x8A, 0x49,
|
||||
0x2C, 0x61, 0x24, 0x30 };
|
||||
|
||||
const GFXglyph FreeMono9pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 11, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 2, 11, 11, 4, -10 }, // 0x21 '!'
|
||||
{ 3, 6, 5, 11, 2, -10 }, // 0x22 '"'
|
||||
{ 7, 7, 12, 11, 2, -10 }, // 0x23 '#'
|
||||
{ 18, 8, 12, 11, 1, -10 }, // 0x24 '$'
|
||||
{ 30, 7, 11, 11, 2, -10 }, // 0x25 '%'
|
||||
{ 40, 7, 10, 11, 2, -9 }, // 0x26 '&'
|
||||
{ 49, 3, 5, 11, 4, -10 }, // 0x27 '''
|
||||
{ 51, 2, 13, 11, 5, -10 }, // 0x28 '('
|
||||
{ 55, 2, 13, 11, 4, -10 }, // 0x29 ')'
|
||||
{ 59, 7, 7, 11, 2, -10 }, // 0x2A '*'
|
||||
{ 66, 7, 7, 11, 2, -8 }, // 0x2B '+'
|
||||
{ 73, 3, 5, 11, 2, -1 }, // 0x2C ','
|
||||
{ 75, 9, 1, 11, 1, -5 }, // 0x2D '-'
|
||||
{ 77, 2, 2, 11, 4, -1 }, // 0x2E '.'
|
||||
{ 78, 7, 13, 11, 2, -11 }, // 0x2F '/'
|
||||
{ 90, 7, 11, 11, 2, -10 }, // 0x30 '0'
|
||||
{ 100, 5, 11, 11, 3, -10 }, // 0x31 '1'
|
||||
{ 107, 7, 11, 11, 2, -10 }, // 0x32 '2'
|
||||
{ 117, 8, 11, 11, 1, -10 }, // 0x33 '3'
|
||||
{ 128, 6, 11, 11, 3, -10 }, // 0x34 '4'
|
||||
{ 137, 7, 11, 11, 2, -10 }, // 0x35 '5'
|
||||
{ 147, 7, 11, 11, 2, -10 }, // 0x36 '6'
|
||||
{ 157, 7, 11, 11, 2, -10 }, // 0x37 '7'
|
||||
{ 167, 7, 11, 11, 2, -10 }, // 0x38 '8'
|
||||
{ 177, 7, 11, 11, 2, -10 }, // 0x39 '9'
|
||||
{ 187, 2, 8, 11, 4, -7 }, // 0x3A ':'
|
||||
{ 189, 3, 11, 11, 3, -7 }, // 0x3B ';'
|
||||
{ 194, 8, 8, 11, 1, -8 }, // 0x3C '<'
|
||||
{ 202, 9, 4, 11, 1, -6 }, // 0x3D '='
|
||||
{ 207, 9, 8, 11, 1, -8 }, // 0x3E '>'
|
||||
{ 216, 7, 10, 11, 2, -9 }, // 0x3F '?'
|
||||
{ 225, 8, 12, 11, 2, -10 }, // 0x40 '@'
|
||||
{ 237, 11, 10, 11, 0, -9 }, // 0x41 'A'
|
||||
{ 251, 9, 10, 11, 1, -9 }, // 0x42 'B'
|
||||
{ 263, 9, 10, 11, 1, -9 }, // 0x43 'C'
|
||||
{ 275, 9, 10, 11, 1, -9 }, // 0x44 'D'
|
||||
{ 287, 9, 10, 11, 1, -9 }, // 0x45 'E'
|
||||
{ 299, 9, 10, 11, 1, -9 }, // 0x46 'F'
|
||||
{ 311, 10, 10, 11, 1, -9 }, // 0x47 'G'
|
||||
{ 324, 9, 10, 11, 1, -9 }, // 0x48 'H'
|
||||
{ 336, 5, 10, 11, 3, -9 }, // 0x49 'I'
|
||||
{ 343, 8, 10, 11, 2, -9 }, // 0x4A 'J'
|
||||
{ 353, 9, 10, 11, 1, -9 }, // 0x4B 'K'
|
||||
{ 365, 8, 10, 11, 2, -9 }, // 0x4C 'L'
|
||||
{ 375, 11, 10, 11, 0, -9 }, // 0x4D 'M'
|
||||
{ 389, 9, 10, 11, 1, -9 }, // 0x4E 'N'
|
||||
{ 401, 9, 10, 11, 1, -9 }, // 0x4F 'O'
|
||||
{ 413, 8, 10, 11, 1, -9 }, // 0x50 'P'
|
||||
{ 423, 9, 13, 11, 1, -9 }, // 0x51 'Q'
|
||||
{ 438, 9, 10, 11, 1, -9 }, // 0x52 'R'
|
||||
{ 450, 7, 10, 11, 2, -9 }, // 0x53 'S'
|
||||
{ 459, 9, 10, 11, 1, -9 }, // 0x54 'T'
|
||||
{ 471, 9, 10, 11, 1, -9 }, // 0x55 'U'
|
||||
{ 483, 11, 10, 11, 0, -9 }, // 0x56 'V'
|
||||
{ 497, 11, 10, 11, 0, -9 }, // 0x57 'W'
|
||||
{ 511, 9, 10, 11, 1, -9 }, // 0x58 'X'
|
||||
{ 523, 9, 10, 11, 1, -9 }, // 0x59 'Y'
|
||||
{ 535, 7, 10, 11, 2, -9 }, // 0x5A 'Z'
|
||||
{ 544, 2, 13, 11, 5, -10 }, // 0x5B '['
|
||||
{ 548, 7, 13, 11, 2, -11 }, // 0x5C '\'
|
||||
{ 560, 2, 13, 11, 4, -10 }, // 0x5D ']'
|
||||
{ 564, 7, 5, 11, 2, -10 }, // 0x5E '^'
|
||||
{ 569, 11, 1, 11, 0, 2 }, // 0x5F '_'
|
||||
{ 571, 3, 3, 11, 3, -11 }, // 0x60 '`'
|
||||
{ 573, 9, 8, 11, 1, -7 }, // 0x61 'a'
|
||||
{ 582, 9, 11, 11, 1, -10 }, // 0x62 'b'
|
||||
{ 595, 7, 8, 11, 2, -7 }, // 0x63 'c'
|
||||
{ 602, 9, 11, 11, 1, -10 }, // 0x64 'd'
|
||||
{ 615, 8, 8, 11, 1, -7 }, // 0x65 'e'
|
||||
{ 623, 6, 11, 11, 3, -10 }, // 0x66 'f'
|
||||
{ 632, 9, 11, 11, 1, -7 }, // 0x67 'g'
|
||||
{ 645, 9, 11, 11, 1, -10 }, // 0x68 'h'
|
||||
{ 658, 7, 10, 11, 2, -9 }, // 0x69 'i'
|
||||
{ 667, 5, 13, 11, 3, -9 }, // 0x6A 'j'
|
||||
{ 676, 8, 11, 11, 2, -10 }, // 0x6B 'k'
|
||||
{ 687, 7, 11, 11, 2, -10 }, // 0x6C 'l'
|
||||
{ 697, 9, 8, 11, 1, -7 }, // 0x6D 'm'
|
||||
{ 706, 9, 8, 11, 1, -7 }, // 0x6E 'n'
|
||||
{ 715, 9, 8, 11, 1, -7 }, // 0x6F 'o'
|
||||
{ 724, 9, 11, 11, 1, -7 }, // 0x70 'p'
|
||||
{ 737, 9, 11, 11, 1, -7 }, // 0x71 'q'
|
||||
{ 750, 7, 8, 11, 3, -7 }, // 0x72 'r'
|
||||
{ 757, 7, 8, 11, 2, -7 }, // 0x73 's'
|
||||
{ 764, 8, 10, 11, 2, -9 }, // 0x74 't'
|
||||
{ 774, 8, 8, 11, 1, -7 }, // 0x75 'u'
|
||||
{ 782, 9, 8, 11, 1, -7 }, // 0x76 'v'
|
||||
{ 791, 9, 8, 11, 1, -7 }, // 0x77 'w'
|
||||
{ 800, 9, 8, 11, 1, -7 }, // 0x78 'x'
|
||||
{ 809, 9, 11, 11, 1, -7 }, // 0x79 'y'
|
||||
{ 822, 7, 8, 11, 2, -7 }, // 0x7A 'z'
|
||||
{ 829, 3, 13, 11, 4, -10 }, // 0x7B '{'
|
||||
{ 834, 1, 13, 11, 5, -10 }, // 0x7C '|'
|
||||
{ 836, 3, 13, 11, 4, -10 }, // 0x7D '}'
|
||||
{ 841, 7, 3, 11, 2, -6 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeMono9pt7b PROGMEM = {
|
||||
(uint8_t *)FreeMono9pt7bBitmaps,
|
||||
(GFXglyph *)FreeMono9pt7bGlyphs,
|
||||
0x20, 0x7E, 18 };
|
||||
|
||||
// Approx. 1516 bytes
|
374
RX_FSK/src/fonts/FreeMono9pt8b.h
Normal file
374
RX_FSK/src/fonts/FreeMono9pt8b.h
Normal file
|
@ -0,0 +1,374 @@
|
|||
const uint8_t FreeMono9pt8bBitmaps[] PROGMEM = {
|
||||
0x00, 0x55, 0x54, 0x1C, 0xDE, 0xF7, 0x39, 0x80, 0x20, 0x50, 0xA1, 0x42,
|
||||
0x9F, 0xCA, 0x14, 0xFE, 0x91, 0x22, 0x44, 0x80, 0x10, 0x21, 0xB4, 0x08,
|
||||
0x08, 0x0F, 0x01, 0x83, 0x0B, 0xE0, 0x81, 0x02, 0x00, 0x71, 0x22, 0x44,
|
||||
0x86, 0x23, 0xB8, 0x0E, 0x22, 0x44, 0x70, 0x78, 0x81, 0x02, 0x06, 0x12,
|
||||
0xA6, 0x44, 0x76, 0xD9, 0x24, 0x25, 0x25, 0x24, 0x49, 0x12, 0x91, 0x24,
|
||||
0x9B, 0x49, 0x48, 0x10, 0x22, 0x4B, 0xE2, 0x89, 0x00, 0x00, 0x08, 0x04,
|
||||
0x02, 0x01, 0x00, 0x83, 0xF8, 0x20, 0x10, 0x08, 0x00, 0x37, 0x64, 0x40,
|
||||
0x7F, 0x00, 0xFC, 0x02, 0x08, 0x10, 0x40, 0x82, 0x04, 0x10, 0x20, 0x41,
|
||||
0x02, 0x08, 0x00, 0x38, 0x8A, 0x14, 0x18, 0x30, 0x60, 0xC1, 0x82, 0x89,
|
||||
0xE0, 0x30, 0xA2, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x23, 0xF8, 0x79,
|
||||
0x0A, 0x10, 0x20, 0x41, 0x04, 0x10, 0x41, 0x07, 0xF8, 0x79, 0x08, 0x08,
|
||||
0x20, 0xC3, 0x80, 0x81, 0x02, 0x07, 0xF0, 0x0C, 0x28, 0x91, 0x24, 0x48,
|
||||
0xA1, 0x7F, 0x04, 0x08, 0x78, 0x7D, 0x02, 0x04, 0x07, 0xC0, 0x40, 0x81,
|
||||
0x03, 0x09, 0xF0, 0x1E, 0x41, 0x02, 0x08, 0x96, 0xB0, 0xC1, 0x42, 0x84,
|
||||
0xF0, 0xFF, 0x04, 0x10, 0x20, 0x41, 0x02, 0x04, 0x10, 0x20, 0x40, 0x79,
|
||||
0x0A, 0x0C, 0x14, 0x47, 0x31, 0x41, 0x83, 0x09, 0xF0, 0x38, 0x8A, 0x0C,
|
||||
0x18, 0x28, 0xCE, 0x81, 0x04, 0x09, 0xE0, 0x1F, 0x00, 0x3F, 0x03, 0x30,
|
||||
0x03, 0x76, 0x44, 0x00, 0x03, 0x04, 0x18, 0x60, 0x60, 0x18, 0x04, 0x03,
|
||||
0xFF, 0x80, 0x00, 0x1F, 0xF0, 0x40, 0x18, 0x03, 0x00, 0x60, 0x20, 0x60,
|
||||
0xC0, 0x80, 0xFD, 0x04, 0x08, 0x10, 0xC2, 0x04, 0x00, 0x10, 0x70, 0x78,
|
||||
0x8A, 0x14, 0x29, 0xD4, 0xA9, 0x4A, 0x89, 0x01, 0x01, 0xE0, 0x3C, 0x01,
|
||||
0x40, 0x48, 0x09, 0x01, 0x10, 0x42, 0x0F, 0xC1, 0x04, 0x40, 0x9E, 0x3C,
|
||||
0xFE, 0x20, 0x90, 0x48, 0x27, 0xE2, 0x09, 0x02, 0x81, 0x41, 0x7F, 0x00,
|
||||
0x3F, 0x20, 0xA0, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x41, 0x1F, 0x00,
|
||||
0xFC, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0xFC, 0xFF, 0x41,
|
||||
0x41, 0x40, 0x78, 0x48, 0x40, 0x41, 0x41, 0xFF, 0xFF, 0x41, 0x40, 0x40,
|
||||
0x78, 0x48, 0x40, 0x40, 0x40, 0xF8, 0x3F, 0x20, 0xA0, 0x10, 0x08, 0x04,
|
||||
0x3E, 0x05, 0x02, 0x41, 0x1F, 0x80, 0xE3, 0x20, 0x90, 0x48, 0x27, 0xF2,
|
||||
0x09, 0x04, 0x82, 0x41, 0x73, 0xC0, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04,
|
||||
0x08, 0x11, 0xFC, 0x3F, 0x02, 0x01, 0x00, 0x80, 0x40, 0x22, 0x11, 0x08,
|
||||
0x84, 0x3C, 0x00, 0xF3, 0xA1, 0x11, 0x09, 0x05, 0x83, 0x21, 0x08, 0x84,
|
||||
0x42, 0x78, 0xC0, 0xF8, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x82, 0x41,
|
||||
0x20, 0xFF, 0xC0, 0xE0, 0xCC, 0x29, 0x45, 0x29, 0x24, 0xA4, 0x94, 0x91,
|
||||
0x12, 0x02, 0x40, 0x5E, 0x3C, 0x61, 0xCC, 0x23, 0x08, 0xA2, 0x24, 0x89,
|
||||
0x22, 0x28, 0x8A, 0x21, 0x9C, 0x20, 0x3E, 0x20, 0xA0, 0x50, 0x18, 0x0C,
|
||||
0x06, 0x03, 0x02, 0x41, 0x1F, 0x00, 0xFE, 0x41, 0x41, 0x41, 0x42, 0x7C,
|
||||
0x40, 0x40, 0x40, 0xF8, 0x3E, 0x20, 0xA0, 0x50, 0x18, 0x0C, 0x06, 0x03,
|
||||
0x02, 0x41, 0x1B, 0x06, 0x07, 0xF0, 0xFE, 0x10, 0x44, 0x11, 0x04, 0x42,
|
||||
0x1F, 0x04, 0x21, 0x08, 0x41, 0x3C, 0x30, 0x7F, 0x06, 0x0C, 0x07, 0x01,
|
||||
0x80, 0x81, 0x83, 0xF8, 0xFF, 0xC4, 0x42, 0x01, 0x00, 0x80, 0x40, 0x20,
|
||||
0x10, 0x08, 0x1F, 0x00, 0xE3, 0xA0, 0x90, 0x48, 0x24, 0x12, 0x09, 0x04,
|
||||
0x82, 0x41, 0x1F, 0x00, 0xF1, 0xE8, 0x10, 0x82, 0x10, 0x82, 0x10, 0x22,
|
||||
0x04, 0x80, 0x50, 0x0C, 0x00, 0x80, 0xF1, 0xD0, 0x14, 0x49, 0x32, 0x4A,
|
||||
0x92, 0xA3, 0x28, 0xCA, 0x31, 0x88, 0x60, 0xE3, 0xA1, 0x08, 0x82, 0x80,
|
||||
0x80, 0xC0, 0x50, 0x44, 0x41, 0x71, 0xC0, 0xE3, 0xA1, 0x08, 0x82, 0x81,
|
||||
0x80, 0x40, 0x20, 0x10, 0x08, 0x1F, 0x00, 0xFD, 0x0A, 0x20, 0x41, 0x04,
|
||||
0x10, 0xA1, 0x83, 0xFC, 0xF2, 0x49, 0x24, 0x92, 0x4E, 0x81, 0x01, 0x02,
|
||||
0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0xE4, 0x92, 0x49,
|
||||
0x24, 0x9E, 0x10, 0x51, 0x24, 0x28, 0x20, 0xFF, 0xE0, 0x11, 0x80, 0x1C,
|
||||
0x31, 0x00, 0x83, 0xC6, 0x24, 0x12, 0x08, 0xFB, 0xE0, 0x08, 0x02, 0x00,
|
||||
0xB8, 0x31, 0x88, 0x22, 0x04, 0x81, 0x20, 0x48, 0x2F, 0xF0, 0x38, 0x46,
|
||||
0x82, 0x80, 0x80, 0x80, 0x81, 0x7E, 0x03, 0x00, 0x40, 0x10, 0x64, 0x67,
|
||||
0x20, 0x48, 0x12, 0x04, 0x81, 0x10, 0xC3, 0xD8, 0x1C, 0x62, 0x81, 0x81,
|
||||
0xFE, 0x80, 0x40, 0x3F, 0x1F, 0x20, 0x20, 0x7C, 0x20, 0x20, 0x20, 0x20,
|
||||
0x20, 0x20, 0xFE, 0x39, 0xA3, 0xA0, 0x50, 0x28, 0x14, 0x09, 0x0C, 0x7A,
|
||||
0x01, 0x01, 0x07, 0x80, 0xC0, 0x20, 0x10, 0x0B, 0x86, 0x22, 0x09, 0x04,
|
||||
0x82, 0x41, 0x20, 0xB8, 0xE0, 0x10, 0x20, 0x03, 0x81, 0x02, 0x04, 0x08,
|
||||
0x10, 0x23, 0xF8, 0x10, 0x81, 0xF0, 0x84, 0x21, 0x08, 0x42, 0x10, 0xFC,
|
||||
0xC0, 0x20, 0x10, 0x08, 0xC4, 0x42, 0x41, 0x40, 0x50, 0x44, 0x21, 0x31,
|
||||
0xE0, 0xF0, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, 0x23, 0xF8, 0x59,
|
||||
0x8C, 0xD1, 0x11, 0x22, 0x24, 0x44, 0x88, 0x91, 0x17, 0x33, 0x5C, 0x31,
|
||||
0x10, 0x48, 0x24, 0x12, 0x09, 0x05, 0xC7, 0x1C, 0x31, 0x10, 0x50, 0x28,
|
||||
0x14, 0x09, 0x04, 0x7C, 0x6E, 0x0C, 0x62, 0x08, 0x81, 0x20, 0x48, 0x23,
|
||||
0x08, 0xBC, 0x20, 0x08, 0x07, 0x00, 0x1D, 0x98, 0xC8, 0x12, 0x04, 0x81,
|
||||
0x20, 0x44, 0x30, 0xF4, 0x01, 0x00, 0x40, 0x38, 0xC6, 0x59, 0x20, 0x40,
|
||||
0x40, 0x40, 0x40, 0xFC, 0x39, 0x8E, 0x03, 0x01, 0xC0, 0x60, 0xFE, 0x40,
|
||||
0x40, 0xFC, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x3F, 0xC3, 0x20, 0x90,
|
||||
0x48, 0x24, 0x12, 0x09, 0x0C, 0x7B, 0xE3, 0xA0, 0x90, 0x84, 0x42, 0x21,
|
||||
0x20, 0x50, 0x10, 0xC1, 0xC0, 0xA2, 0x49, 0x25, 0x52, 0xB1, 0x98, 0x44,
|
||||
0x63, 0x20, 0x88, 0x83, 0x81, 0x81, 0x21, 0x09, 0xC7, 0xC3, 0x20, 0x90,
|
||||
0x44, 0x42, 0x20, 0xA0, 0x50, 0x10, 0x08, 0x08, 0x1E, 0x00, 0xFF, 0x0A,
|
||||
0x20, 0x81, 0x04, 0x10, 0xFF, 0x12, 0x22, 0x22, 0xC2, 0x22, 0x22, 0x30,
|
||||
0xFF, 0xF8, 0xC1, 0x08, 0x42, 0x10, 0x64, 0x21, 0x08, 0x44, 0x00, 0xE2,
|
||||
0x38, 0xFF, 0xF0, 0x06, 0xFC, 0xD0, 0x58, 0x0B, 0x01, 0x60, 0xCC, 0x21,
|
||||
0x84, 0x30, 0x06, 0x10, 0xC7, 0x18, 0x03, 0xFF, 0xC0, 0x00, 0xC0, 0x55,
|
||||
0x54, 0x10, 0x43, 0x91, 0x82, 0x08, 0x11, 0x38, 0x41, 0x00, 0x3C, 0x20,
|
||||
0x20, 0x20, 0xF8, 0x20, 0x20, 0x20, 0x21, 0x7F, 0x3F, 0xA0, 0x90, 0x10,
|
||||
0x0F, 0xE7, 0xE2, 0x00, 0x80, 0x20, 0x8F, 0x80, 0xE3, 0xA1, 0x08, 0x82,
|
||||
0x81, 0x83, 0xF8, 0x20, 0x7C, 0x08, 0x1F, 0x00, 0x6C, 0x20, 0x03, 0xF8,
|
||||
0x30, 0x60, 0x38, 0x0C, 0x04, 0x0C, 0x1F, 0xC0, 0x1F, 0x10, 0x88, 0x4C,
|
||||
0x09, 0x82, 0x30, 0x84, 0x31, 0x07, 0x01, 0x10, 0x8F, 0x80, 0x00, 0xD8,
|
||||
0x40, 0x03, 0x98, 0xE0, 0x30, 0x1C, 0x06, 0x0F, 0xE0, 0x3F, 0x08, 0x12,
|
||||
0x3D, 0x48, 0x9A, 0x03, 0x40, 0x64, 0x4A, 0x72, 0x40, 0x87, 0xE0, 0xF0,
|
||||
0xBD, 0x2F, 0x80, 0x00, 0x08, 0x88, 0x88, 0xCC, 0x43, 0x10, 0x44, 0x11,
|
||||
0xFF, 0x80, 0x40, 0x20, 0x10, 0x00, 0x7F, 0x00, 0x3F, 0x08, 0x12, 0x79,
|
||||
0x49, 0x19, 0x23, 0x3C, 0x64, 0x8A, 0xCA, 0x40, 0x87, 0xE0, 0xF8, 0xF4,
|
||||
0x63, 0x17, 0x00, 0x00, 0x04, 0x02, 0x01, 0x0F, 0xF0, 0x40, 0x20, 0x10,
|
||||
0x00, 0x7F, 0x80, 0x79, 0x12, 0x4F, 0x71, 0x13, 0x1F, 0x04, 0xD0, 0x40,
|
||||
0x0F, 0xD0, 0xA2, 0x04, 0x10, 0x41, 0x0A, 0x18, 0x3F, 0xC0, 0xC3, 0x20,
|
||||
0x90, 0x48, 0x24, 0x12, 0x09, 0x0C, 0xDB, 0x50, 0x20, 0x10, 0x08, 0x00,
|
||||
0x3F, 0x6A, 0xCA, 0xCA, 0x4A, 0x7A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x3B,
|
||||
0x50, 0x00, 0xD8, 0x40, 0x0F, 0xF0, 0xA2, 0x08, 0x10, 0x41, 0x0F, 0xF0,
|
||||
0x62, 0x22, 0x27, 0xF4, 0x63, 0x17, 0x00, 0x00, 0x22, 0x18, 0x86, 0x61,
|
||||
0x11, 0x11, 0x11, 0x10, 0x3F, 0xC8, 0x8A, 0x11, 0x42, 0x08, 0x71, 0x0A,
|
||||
0x21, 0x02, 0x21, 0x44, 0x27, 0xFC, 0x31, 0x92, 0x98, 0x46, 0x11, 0x87,
|
||||
0xA1, 0x04, 0xC1, 0xEF, 0x22, 0x11, 0x00, 0x1C, 0x74, 0x21, 0x10, 0x50,
|
||||
0x30, 0x08, 0x04, 0x02, 0x01, 0x03, 0xE0, 0x10, 0xE0, 0x00, 0x10, 0xC4,
|
||||
0x20, 0x82, 0x17, 0xC0, 0x10, 0x01, 0x00, 0x10, 0x00, 0x03, 0xC0, 0x14,
|
||||
0x04, 0x80, 0x90, 0x11, 0x04, 0x20, 0xFC, 0x10, 0x44, 0x09, 0xE3, 0xC0,
|
||||
0x02, 0x00, 0x80, 0x20, 0x00, 0x03, 0xC0, 0x14, 0x04, 0x80, 0x90, 0x11,
|
||||
0x04, 0x20, 0xFC, 0x10, 0x44, 0x09, 0xE3, 0xC0, 0x04, 0x01, 0x40, 0x44,
|
||||
0x00, 0x03, 0xC0, 0x14, 0x04, 0x80, 0x90, 0x11, 0x04, 0x20, 0xFC, 0x10,
|
||||
0x44, 0x09, 0xE3, 0xC0, 0x08, 0x02, 0xE0, 0x00, 0x1E, 0x00, 0xA0, 0x24,
|
||||
0x04, 0x80, 0x88, 0x21, 0x07, 0xE0, 0x82, 0x20, 0x4F, 0x1E, 0x11, 0x02,
|
||||
0x20, 0x00, 0x1E, 0x00, 0xA0, 0x24, 0x04, 0x80, 0x88, 0x21, 0x07, 0xE0,
|
||||
0x82, 0x20, 0x4F, 0x1E, 0x0E, 0x02, 0x40, 0x30, 0x00, 0x03, 0xC0, 0x14,
|
||||
0x04, 0x80, 0x90, 0x11, 0x04, 0x20, 0xFC, 0x10, 0x44, 0x09, 0xE3, 0xC0,
|
||||
0x3F, 0xC2, 0x88, 0x51, 0x0A, 0x02, 0x70, 0x4A, 0x0F, 0x01, 0x21, 0x44,
|
||||
0x3D, 0xFC, 0x3F, 0x20, 0xA0, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x41,
|
||||
0x1B, 0x02, 0x00, 0x81, 0xC0, 0x20, 0x10, 0x08, 0x00, 0xFF, 0x41, 0x41,
|
||||
0x40, 0x78, 0x48, 0x40, 0x41, 0x41, 0xFF, 0x04, 0x08, 0x10, 0x00, 0xFF,
|
||||
0x41, 0x41, 0x40, 0x78, 0x48, 0x40, 0x41, 0x41, 0xFF, 0x00, 0x1C, 0x22,
|
||||
0x00, 0xFF, 0x41, 0x41, 0x40, 0x78, 0x48, 0x40, 0x41, 0x41, 0xFF, 0x22,
|
||||
0x66, 0x00, 0xFF, 0x41, 0x41, 0x40, 0x78, 0x48, 0x40, 0x41, 0x41, 0xFF,
|
||||
0x20, 0x20, 0x00, 0x0F, 0xE2, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81, 0x1F,
|
||||
0xC0, 0x04, 0x10, 0x40, 0x0F, 0xE2, 0x04, 0x08, 0x10, 0x20, 0x40, 0x81,
|
||||
0x1F, 0xC0, 0x10, 0x51, 0x10, 0x0F, 0xE2, 0x04, 0x08, 0x10, 0x20, 0x40,
|
||||
0x81, 0x1F, 0xC0, 0x44, 0x88, 0x07, 0xF1, 0x02, 0x04, 0x08, 0x10, 0x20,
|
||||
0x40, 0x8F, 0xE0, 0x7E, 0x10, 0x88, 0x24, 0x1F, 0xC9, 0x04, 0x82, 0x41,
|
||||
0x21, 0x3F, 0x00, 0x19, 0x09, 0x80, 0x01, 0x87, 0x30, 0x8C, 0x22, 0x88,
|
||||
0x92, 0x24, 0x88, 0xA2, 0x28, 0x86, 0x70, 0x80, 0x20, 0x0C, 0x00, 0x00,
|
||||
0x03, 0xE2, 0x0A, 0x05, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x24, 0x11, 0xF0,
|
||||
0x04, 0x04, 0x04, 0x00, 0x03, 0xE2, 0x0A, 0x05, 0x01, 0x80, 0xC0, 0x60,
|
||||
0x30, 0x24, 0x11, 0xF0, 0x08, 0x0A, 0x08, 0x80, 0x03, 0xE2, 0x0A, 0x05,
|
||||
0x01, 0x80, 0xC0, 0x60, 0x30, 0x24, 0x11, 0xF0, 0x10, 0x17, 0x00, 0x07,
|
||||
0xC4, 0x14, 0x0A, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x48, 0x23, 0xE0, 0x22,
|
||||
0x11, 0x00, 0x07, 0xC4, 0x14, 0x0A, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x48,
|
||||
0x23, 0xE0, 0x84, 0x90, 0xC1, 0x84, 0x90, 0x80, 0x00, 0x9F, 0x90, 0x50,
|
||||
0x68, 0x4C, 0x46, 0x43, 0x21, 0xA1, 0x20, 0xAD, 0x81, 0x00, 0x20, 0x0C,
|
||||
0x00, 0x00, 0x0E, 0x3A, 0x09, 0x04, 0x82, 0x41, 0x20, 0x90, 0x48, 0x24,
|
||||
0x11, 0xF0, 0x04, 0x04, 0x04, 0x00, 0x0E, 0x3A, 0x09, 0x04, 0x82, 0x41,
|
||||
0x20, 0x90, 0x48, 0x24, 0x11, 0xF0, 0x08, 0x0A, 0x08, 0x80, 0x0E, 0x3A,
|
||||
0x09, 0x04, 0x82, 0x41, 0x20, 0x90, 0x48, 0x24, 0x11, 0xF0, 0x22, 0x11,
|
||||
0x00, 0x1C, 0x74, 0x12, 0x09, 0x04, 0x82, 0x41, 0x20, 0x90, 0x48, 0x23,
|
||||
0xE0, 0x04, 0x04, 0x04, 0x00, 0x0E, 0x3A, 0x10, 0x88, 0x28, 0x18, 0x04,
|
||||
0x02, 0x01, 0x00, 0x81, 0xF0, 0xF8, 0x40, 0x7C, 0x43, 0x41, 0x41, 0x41,
|
||||
0x7E, 0x40, 0xF8, 0x1C, 0x11, 0x08, 0x84, 0x42, 0xC1, 0x18, 0x82, 0x41,
|
||||
0x20, 0x94, 0x79, 0xC0, 0x20, 0x08, 0x02, 0x00, 0x01, 0xC3, 0x10, 0x08,
|
||||
0x3C, 0x62, 0x41, 0x20, 0x8F, 0xB0, 0x00, 0x06, 0x04, 0x00, 0x01, 0xC3,
|
||||
0x10, 0x08, 0x3C, 0x62, 0x41, 0x20, 0x8F, 0xB0, 0x18, 0x12, 0x00, 0x03,
|
||||
0x86, 0x20, 0x10, 0x78, 0xC4, 0x82, 0x41, 0x1F, 0x60, 0x3E, 0x00, 0x07,
|
||||
0x0C, 0x40, 0x20, 0xF1, 0x89, 0x04, 0x82, 0x3E, 0xC0, 0x22, 0x33, 0x00,
|
||||
0x03, 0x86, 0x20, 0x10, 0x78, 0xC4, 0x82, 0x41, 0x1F, 0x60, 0x1C, 0x12,
|
||||
0x05, 0x01, 0x01, 0xC3, 0x10, 0x08, 0x3C, 0x62, 0x41, 0x20, 0x8F, 0xB0,
|
||||
0x39, 0x91, 0x90, 0x44, 0xF1, 0x47, 0xA1, 0x08, 0x41, 0xFF, 0x38, 0x46,
|
||||
0x82, 0x80, 0x80, 0x80, 0x81, 0x6E, 0x10, 0x08, 0x38, 0x00, 0x10, 0x08,
|
||||
0x00, 0x1C, 0x62, 0x81, 0x81, 0xFE, 0x80, 0x40, 0x3F, 0x00, 0x04, 0x18,
|
||||
0x00, 0x1C, 0x62, 0x81, 0x81, 0xFE, 0x80, 0x40, 0x3F, 0x08, 0x36, 0x00,
|
||||
0x1C, 0x62, 0x81, 0x81, 0xFE, 0x80, 0x40, 0x3F, 0x22, 0x22, 0x00, 0x1C,
|
||||
0x62, 0x81, 0x81, 0xFE, 0x80, 0x40, 0x3F, 0x40, 0x40, 0x40, 0x07, 0x02,
|
||||
0x04, 0x08, 0x10, 0x20, 0x47, 0xF0, 0x00, 0x30, 0x80, 0x07, 0x02, 0x04,
|
||||
0x08, 0x10, 0x20, 0x47, 0xF0, 0x30, 0x90, 0x03, 0x81, 0x02, 0x04, 0x08,
|
||||
0x10, 0x23, 0xF8, 0x45, 0x98, 0x03, 0x81, 0x02, 0x04, 0x08, 0x10, 0x23,
|
||||
0xF8, 0x36, 0x0E, 0x00, 0x83, 0xC6, 0x32, 0x0A, 0x05, 0x02, 0x81, 0x20,
|
||||
0x8F, 0x80, 0x3E, 0x00, 0x17, 0x0C, 0x44, 0x12, 0x09, 0x04, 0x82, 0x41,
|
||||
0x71, 0xC0, 0x00, 0x08, 0x02, 0x00, 0x01, 0xC3, 0x11, 0x05, 0x02, 0x81,
|
||||
0x40, 0x90, 0x47, 0xC0, 0x00, 0x02, 0x06, 0x00, 0x01, 0xC3, 0x11, 0x05,
|
||||
0x02, 0x81, 0x40, 0x90, 0x47, 0xC0, 0x18, 0x13, 0x00, 0x03, 0x86, 0x22,
|
||||
0x0A, 0x05, 0x02, 0x81, 0x20, 0x8F, 0x80, 0x3E, 0x00, 0x07, 0x0C, 0x44,
|
||||
0x14, 0x0A, 0x05, 0x02, 0x41, 0x1F, 0x00, 0x22, 0x11, 0x00, 0x03, 0x86,
|
||||
0x22, 0x0A, 0x05, 0x02, 0x81, 0x20, 0x8F, 0x80, 0x08, 0x04, 0x00, 0x00,
|
||||
0x00, 0x03, 0xF8, 0x00, 0x00, 0x08, 0x04, 0x00, 0x1D, 0x31, 0x10, 0xD0,
|
||||
0xA8, 0x94, 0x89, 0x84, 0xEC, 0x88, 0x00, 0x00, 0x08, 0x02, 0x00, 0x0C,
|
||||
0x32, 0x09, 0x04, 0x82, 0x41, 0x20, 0x90, 0xC7, 0xB0, 0x04, 0x04, 0x04,
|
||||
0x00, 0x0C, 0x32, 0x09, 0x04, 0x82, 0x41, 0x20, 0x90, 0xC7, 0xB0, 0x18,
|
||||
0x12, 0x00, 0x18, 0x64, 0x12, 0x09, 0x04, 0x82, 0x41, 0x21, 0x8F, 0x60,
|
||||
0x22, 0x33, 0x00, 0x18, 0x64, 0x12, 0x09, 0x04, 0x82, 0x41, 0x21, 0x8F,
|
||||
0x60, 0x02, 0x02, 0x02, 0x00, 0x0C, 0x32, 0x09, 0x04, 0x44, 0x22, 0x0A,
|
||||
0x05, 0x01, 0x00, 0x80, 0x81, 0xE0, 0xE0, 0x08, 0x02, 0x00, 0xB8, 0x31,
|
||||
0x88, 0x22, 0x04, 0x81, 0x20, 0x8C, 0x22, 0xF0, 0x80, 0x20, 0x1C, 0x00,
|
||||
0x22, 0x11, 0x00, 0x18, 0x64, 0x12, 0x08, 0x88, 0x44, 0x14, 0x0A, 0x02,
|
||||
0x01, 0x01, 0x03, 0xC0 };
|
||||
|
||||
const GFXglyph FreeMono9pt8bGlyphs[] PROGMEM = {
|
||||
{ 0, 1, 1, 11, 0, 0 }, // 0x20 ' ' U+0020
|
||||
{ 1, 2, 11, 11, 4, -10 }, // 0x21 '!' U+0021
|
||||
{ 4, 5, 5, 11, 3, -10 }, // 0x22 '"' U+0022
|
||||
{ 8, 7, 13, 11, 2, -11 }, // 0x23 '#' U+0023
|
||||
{ 20, 7, 14, 11, 2, -11 }, // 0x24 '$' U+0024
|
||||
{ 33, 7, 11, 11, 2, -10 }, // 0x25 '%' U+0025
|
||||
{ 43, 7, 9, 11, 2, -8 }, // 0x26 '&' U+0026
|
||||
{ 51, 3, 5, 11, 4, -10 }, // 0x27 ''' U+0027
|
||||
{ 53, 3, 13, 11, 5, -10 }, // 0x28 '(' U+0028
|
||||
{ 58, 3, 13, 11, 3, -10 }, // 0x29 ')' U+0029
|
||||
{ 63, 7, 7, 11, 2, -10 }, // 0x2a '*' U+002A
|
||||
{ 70, 9, 9, 11, 1, -9 }, // 0x2b '+' U+002B
|
||||
{ 81, 4, 6, 11, 2, -2 }, // 0x2c ',' U+002C
|
||||
{ 84, 9, 1, 11, 1, -5 }, // 0x2d '-' U+002D
|
||||
{ 86, 3, 2, 11, 4, -1 }, // 0x2e '.' U+002E
|
||||
{ 87, 7, 13, 11, 2, -11 }, // 0x2f '/' U+002F
|
||||
{ 99, 7, 11, 11, 2, -10 }, // 0x30 '0' U+0030
|
||||
{ 109, 7, 11, 11, 2, -10 }, // 0x31 '1' U+0031
|
||||
{ 119, 7, 11, 11, 2, -10 }, // 0x32 '2' U+0032
|
||||
{ 129, 7, 11, 11, 2, -10 }, // 0x33 '3' U+0033
|
||||
{ 139, 7, 11, 11, 2, -10 }, // 0x34 '4' U+0034
|
||||
{ 149, 7, 11, 11, 2, -10 }, // 0x35 '5' U+0035
|
||||
{ 159, 7, 11, 11, 2, -10 }, // 0x36 '6' U+0036
|
||||
{ 169, 7, 11, 11, 2, -10 }, // 0x37 '7' U+0037
|
||||
{ 179, 7, 11, 11, 2, -10 }, // 0x38 '8' U+0038
|
||||
{ 189, 7, 11, 11, 2, -10 }, // 0x39 '9' U+0039
|
||||
{ 199, 3, 8, 11, 4, -7 }, // 0x3a ':' U+003A
|
||||
{ 202, 4, 11, 11, 2, -7 }, // 0x3b ';' U+003B
|
||||
{ 208, 8, 8, 11, 1, -8 }, // 0x3c '<' U+003C
|
||||
{ 216, 9, 4, 11, 1, -6 }, // 0x3d '=' U+003D
|
||||
{ 221, 9, 8, 11, 1, -8 }, // 0x3e '>' U+003E
|
||||
{ 230, 7, 10, 11, 2, -9 }, // 0x3f '?' U+003F
|
||||
{ 239, 7, 12, 11, 2, -10 }, // 0x40 '@' U+0040
|
||||
{ 250, 11, 10, 11, 0, -9 }, // 0x41 'A' U+0041
|
||||
{ 264, 9, 10, 11, 1, -9 }, // 0x42 'B' U+0042
|
||||
{ 276, 9, 10, 11, 1, -9 }, // 0x43 'C' U+0043
|
||||
{ 288, 8, 10, 11, 1, -9 }, // 0x44 'D' U+0044
|
||||
{ 298, 8, 10, 11, 1, -9 }, // 0x45 'E' U+0045
|
||||
{ 308, 8, 10, 11, 1, -9 }, // 0x46 'F' U+0046
|
||||
{ 318, 9, 10, 11, 1, -9 }, // 0x47 'G' U+0047
|
||||
{ 330, 9, 10, 11, 1, -9 }, // 0x48 'H' U+0048
|
||||
{ 342, 7, 10, 11, 2, -9 }, // 0x49 'I' U+0049
|
||||
{ 351, 9, 10, 11, 2, -9 }, // 0x4a 'J' U+004A
|
||||
{ 363, 9, 10, 11, 1, -9 }, // 0x4b 'K' U+004B
|
||||
{ 375, 9, 10, 11, 1, -9 }, // 0x4c 'L' U+004C
|
||||
{ 387, 11, 10, 11, 0, -9 }, // 0x4d 'M' U+004D
|
||||
{ 401, 10, 10, 11, 0, -9 }, // 0x4e 'N' U+004E
|
||||
{ 414, 9, 10, 11, 1, -9 }, // 0x4f 'O' U+004F
|
||||
{ 426, 8, 10, 11, 1, -9 }, // 0x50 'P' U+0050
|
||||
{ 436, 9, 12, 11, 1, -9 }, // 0x51 'Q' U+0051
|
||||
{ 450, 10, 10, 11, 1, -9 }, // 0x52 'R' U+0052
|
||||
{ 463, 7, 10, 11, 2, -9 }, // 0x53 'S' U+0053
|
||||
{ 472, 9, 10, 11, 1, -9 }, // 0x54 'T' U+0054
|
||||
{ 484, 9, 10, 11, 1, -9 }, // 0x55 'U' U+0055
|
||||
{ 496, 11, 10, 11, 0, -9 }, // 0x56 'V' U+0056
|
||||
{ 510, 10, 10, 11, 0, -9 }, // 0x57 'W' U+0057
|
||||
{ 523, 9, 10, 11, 1, -9 }, // 0x58 'X' U+0058
|
||||
{ 535, 9, 10, 11, 1, -9 }, // 0x59 'Y' U+0059
|
||||
{ 547, 7, 10, 11, 2, -9 }, // 0x5a 'Z' U+005A
|
||||
{ 556, 3, 13, 11, 5, -10 }, // 0x5b '[' U+005B
|
||||
{ 561, 7, 13, 11, 2, -11 }, // 0x5c '\' U+005C
|
||||
{ 573, 3, 13, 11, 3, -10 }, // 0x5d ']' U+005D
|
||||
{ 578, 7, 5, 11, 2, -10 }, // 0x5e '^' U+005E
|
||||
{ 583, 11, 1, 11, 0, 2 }, // 0x5f '_' U+005F
|
||||
{ 585, 3, 3, 11, 3, -11 }, // 0x60 '`' U+0060
|
||||
{ 587, 9, 8, 11, 1, -7 }, // 0x61 'a' U+0061
|
||||
{ 596, 10, 11, 11, 0, -10 }, // 0x62 'b' U+0062
|
||||
{ 610, 8, 8, 11, 2, -7 }, // 0x63 'c' U+0063
|
||||
{ 618, 10, 11, 11, 1, -10 }, // 0x64 'd' U+0064
|
||||
{ 632, 8, 8, 11, 1, -7 }, // 0x65 'e' U+0065
|
||||
{ 640, 8, 11, 11, 2, -10 }, // 0x66 'f' U+0066
|
||||
{ 651, 9, 11, 11, 1, -7 }, // 0x67 'g' U+0067
|
||||
{ 664, 9, 11, 11, 1, -10 }, // 0x68 'h' U+0068
|
||||
{ 677, 7, 11, 11, 2, -10 }, // 0x69 'i' U+0069
|
||||
{ 687, 5, 14, 11, 3, -10 }, // 0x6a 'j' U+006A
|
||||
{ 696, 9, 11, 11, 1, -10 }, // 0x6b 'k' U+006B
|
||||
{ 709, 7, 11, 11, 2, -10 }, // 0x6c 'l' U+006C
|
||||
{ 719, 11, 8, 11, 0, -7 }, // 0x6d 'm' U+006D
|
||||
{ 730, 9, 8, 11, 1, -7 }, // 0x6e 'n' U+006E
|
||||
{ 739, 9, 8, 11, 1, -7 }, // 0x6f 'o' U+006F
|
||||
{ 748, 10, 11, 11, 0, -7 }, // 0x70 'p' U+0070
|
||||
{ 762, 10, 11, 11, 1, -7 }, // 0x71 'q' U+0071
|
||||
{ 776, 8, 8, 11, 2, -7 }, // 0x72 'r' U+0072
|
||||
{ 784, 7, 8, 11, 2, -7 }, // 0x73 's' U+0073
|
||||
{ 791, 8, 10, 11, 1, -9 }, // 0x74 't' U+0074
|
||||
{ 801, 9, 8, 11, 1, -7 }, // 0x75 'u' U+0075
|
||||
{ 810, 9, 8, 11, 1, -7 }, // 0x76 'v' U+0076
|
||||
{ 819, 9, 8, 11, 1, -7 }, // 0x77 'w' U+0077
|
||||
{ 828, 9, 8, 11, 1, -7 }, // 0x78 'x' U+0078
|
||||
{ 837, 9, 11, 11, 1, -7 }, // 0x79 'y' U+0079
|
||||
{ 850, 7, 8, 11, 2, -7 }, // 0x7a 'z' U+007A
|
||||
{ 857, 4, 13, 11, 3, -10 }, // 0x7b '{' U+007B
|
||||
{ 864, 1, 13, 11, 5, -10 }, // 0x7c '|' U+007C
|
||||
{ 866, 5, 13, 11, 3, -10 }, // 0x7d '}' U+007D
|
||||
{ 875, 7, 2, 11, 2, -5 }, // 0x7e '~' U+007E
|
||||
{ 877, 11, 14, 11, 0, -11 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370
|
||||
{ 897, 1, 1, 11, 0, 0 }, // 0x80 'NO-BREAK SPACE' U+00A0
|
||||
{ 898, 2, 11, 11, 4, -7 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1
|
||||
{ 901, 6, 11, 11, 2, -10 }, // 0x82 'CENT SIGN' U+00A2
|
||||
{ 910, 8, 10, 11, 1, -9 }, // 0x83 'POUND SIGN' U+00A3
|
||||
{ 920, 9, 10, 11, 1, -9 }, // 0x84 'EURO SIGN *' U+20AC
|
||||
{ 932, 9, 10, 11, 1, -9 }, // 0x85 'YEN SIGN' U+00A5
|
||||
{ 944, 7, 13, 11, 2, -12 }, // 0x86 'LATIN CAPITAL LETTER S WITH CARON *' U+0160
|
||||
{ 956, 9, 12, 11, 1, -10 }, // 0x87 'SECTION SIGN' U+00A7
|
||||
{ 970, 7, 12, 11, 2, -11 }, // 0x88 'LATIN SMALL LETTER S WITH CARON *' U+0161
|
||||
{ 981, 11, 10, 11, 0, -9 }, // 0x89 'COPYRIGHT SIGN' U+00A9
|
||||
{ 995, 5, 5, 11, 3, -9 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA
|
||||
{ 999, 9, 8, 11, 1, -7 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB
|
||||
{ 1008, 9, 5, 11, 1, -7 }, // 0x8c 'NOT SIGN' U+00AC
|
||||
{ 1014, 9, 1, 11, 1, -5 }, // 0x8d 'SOFT HYPHEN' U+00AD
|
||||
{ 1016, 11, 10, 11, 0, -9 }, // 0x8e 'REGISTERED SIGN' U+00AE
|
||||
{ 1030, 5, 1, 11, 3, -10 }, // 0x8f 'MACRON' U+00AF
|
||||
{ 1031, 5, 5, 11, 3, -10 }, // 0x90 'DEGREE SIGN' U+00B0
|
||||
{ 1035, 9, 10, 11, 1, -9 }, // 0x91 'PLUS-MINUS SIGN' U+00B1
|
||||
{ 1047, 4, 6, 11, 3, -10 }, // 0x92 'SUPERSCRIPT TWO' U+00B2
|
||||
{ 1050, 4, 6, 11, 3, -10 }, // 0x93 'SUPERSCRIPT THREE' U+00B3
|
||||
{ 1053, 7, 14, 11, 2, -13 }, // 0x94 'LATIN CAPITAL LETTER Z WITH CARON *' U+017D
|
||||
{ 1066, 9, 12, 11, 1, -7 }, // 0x95 'MICRO SIGN' U+00B5
|
||||
{ 1080, 8, 12, 11, 1, -10 }, // 0x96 'PILCROW SIGN' U+00B6
|
||||
{ 1092, 2, 2, 11, 4, -4 }, // 0x97 'MIDDLE DOT' U+00B7
|
||||
{ 1093, 7, 12, 11, 2, -11 }, // 0x98 'LATIN SMALL LETTER Z WITH CARON *' U+017E
|
||||
{ 1104, 4, 6, 11, 3, -10 }, // 0x99 'SUPERSCRIPT ONE' U+00B9
|
||||
{ 1107, 5, 5, 11, 3, -9 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA
|
||||
{ 1111, 9, 8, 11, 1, -7 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB
|
||||
{ 1120, 11, 10, 11, 0, -9 }, // 0x9c 'LATIN CAPITAL LIGATURE OE *' U+0152
|
||||
{ 1134, 10, 8, 11, 0, -7 }, // 0x9d 'LATIN SMALL LIGATURE OE *' U+0153
|
||||
{ 1144, 9, 13, 11, 1, -12 }, // 0x9e 'LATIN CAPITAL LETTER Y WITH DIAERESIS *' U+0178
|
||||
{ 1159, 6, 11, 11, 2, -7 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF
|
||||
{ 1168, 11, 14, 11, 0, -13 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0
|
||||
{ 1188, 11, 14, 11, 0, -13 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1
|
||||
{ 1208, 11, 14, 11, 0, -13 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2
|
||||
{ 1228, 11, 13, 11, 0, -12 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3
|
||||
{ 1246, 11, 13, 11, 0, -12 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4
|
||||
{ 1264, 11, 14, 11, 0, -13 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5
|
||||
{ 1284, 11, 10, 11, 0, -9 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6
|
||||
{ 1298, 9, 13, 11, 1, -9 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7
|
||||
{ 1313, 8, 14, 11, 1, -13 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8
|
||||
{ 1327, 8, 14, 11, 1, -13 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9
|
||||
{ 1341, 8, 14, 11, 1, -13 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA
|
||||
{ 1355, 8, 13, 11, 1, -12 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB
|
||||
{ 1368, 7, 14, 11, 2, -13 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC
|
||||
{ 1381, 7, 14, 11, 2, -13 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD
|
||||
{ 1394, 7, 14, 11, 2, -13 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE
|
||||
{ 1407, 7, 13, 11, 2, -12 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF
|
||||
{ 1419, 9, 10, 11, 0, -9 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0
|
||||
{ 1431, 10, 13, 11, 0, -12 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1
|
||||
{ 1448, 9, 14, 11, 1, -13 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2
|
||||
{ 1464, 9, 14, 11, 1, -13 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3
|
||||
{ 1480, 9, 14, 11, 1, -13 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4
|
||||
{ 1496, 9, 13, 11, 1, -12 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5
|
||||
{ 1511, 9, 13, 11, 1, -12 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6
|
||||
{ 1526, 7, 6, 11, 2, -7 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7
|
||||
{ 1532, 9, 12, 11, 1, -10 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8
|
||||
{ 1546, 9, 14, 11, 1, -13 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9
|
||||
{ 1562, 9, 14, 11, 1, -13 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA
|
||||
{ 1578, 9, 14, 11, 1, -13 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB
|
||||
{ 1594, 9, 13, 11, 1, -12 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC
|
||||
{ 1609, 9, 14, 11, 1, -13 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD
|
||||
{ 1625, 8, 10, 11, 1, -9 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE
|
||||
{ 1635, 9, 11, 11, 0, -10 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF
|
||||
{ 1648, 9, 12, 11, 1, -11 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0
|
||||
{ 1662, 9, 12, 11, 1, -11 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1
|
||||
{ 1676, 9, 11, 11, 1, -10 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2
|
||||
{ 1689, 9, 10, 11, 1, -9 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3
|
||||
{ 1701, 9, 11, 11, 1, -10 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4
|
||||
{ 1714, 9, 12, 11, 1, -11 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5
|
||||
{ 1728, 10, 8, 11, 0, -7 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6
|
||||
{ 1738, 8, 11, 11, 2, -7 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7
|
||||
{ 1749, 8, 12, 11, 1, -11 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8
|
||||
{ 1761, 8, 12, 11, 1, -11 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9
|
||||
{ 1773, 8, 11, 11, 1, -10 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA
|
||||
{ 1784, 8, 11, 11, 1, -10 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB
|
||||
{ 1795, 7, 12, 11, 2, -11 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC
|
||||
{ 1806, 7, 12, 11, 2, -11 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED
|
||||
{ 1817, 7, 11, 11, 2, -10 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE
|
||||
{ 1827, 7, 11, 11, 2, -10 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF
|
||||
{ 1837, 9, 11, 11, 1, -10 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0
|
||||
{ 1850, 9, 10, 11, 1, -9 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1
|
||||
{ 1862, 9, 12, 11, 1, -11 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2
|
||||
{ 1876, 9, 12, 11, 1, -11 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3
|
||||
{ 1890, 9, 11, 11, 1, -10 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4
|
||||
{ 1903, 9, 10, 11, 1, -9 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5
|
||||
{ 1915, 9, 11, 11, 1, -10 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6
|
||||
{ 1928, 9, 10, 11, 1, -9 }, // 0xd7 'DIVISION SIGN' U+00F7
|
||||
{ 1940, 9, 9, 11, 1, -7 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8
|
||||
{ 1951, 9, 12, 11, 1, -11 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9
|
||||
{ 1965, 9, 12, 11, 1, -11 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA
|
||||
{ 1979, 9, 11, 11, 1, -10 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB
|
||||
{ 1992, 9, 11, 11, 1, -10 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC
|
||||
{ 2005, 9, 15, 11, 1, -11 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD
|
||||
{ 2022, 10, 14, 11, 0, -10 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE
|
||||
{ 2040, 9, 14, 11, 1, -10 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF
|
||||
|
||||
const GFXfont FreeMono9pt8b PROGMEM = {
|
||||
(uint8_t *)FreeMono9pt8bBitmaps,
|
||||
(GFXglyph *)FreeMono9pt8bGlyphs,
|
||||
0x20, 0xDF, 19 };
|
||||
|
||||
// Approx. 3407 bytes
|
270
RX_FSK/src/fonts/FreeSans12pt7b.h
Normal file
270
RX_FSK/src/fonts/FreeSans12pt7b.h
Normal file
|
@ -0,0 +1,270 @@
|
|||
const uint8_t FreeSans12pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xCF, 0x3C, 0xF3, 0x8A, 0x20, 0x06, 0x30,
|
||||
0x31, 0x03, 0x18, 0x18, 0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x03, 0x18, 0x18,
|
||||
0xC7, 0xFF, 0xBF, 0xFC, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30,
|
||||
0x04, 0x03, 0xE1, 0xFF, 0x72, 0x6C, 0x47, 0x88, 0xF1, 0x07, 0x20, 0x7E,
|
||||
0x03, 0xF0, 0x17, 0x02, 0x3C, 0x47, 0x88, 0xF1, 0x1B, 0x26, 0x7F, 0xC3,
|
||||
0xE0, 0x10, 0x02, 0x00, 0x00, 0x06, 0x03, 0xC0, 0x40, 0x7E, 0x0C, 0x0E,
|
||||
0x70, 0x80, 0xC3, 0x18, 0x0C, 0x31, 0x00, 0xE7, 0x30, 0x07, 0xE6, 0x00,
|
||||
0x3C, 0x40, 0x00, 0x0C, 0x7C, 0x00, 0x8F, 0xE0, 0x19, 0xC7, 0x01, 0x18,
|
||||
0x30, 0x31, 0x83, 0x02, 0x1C, 0x70, 0x40, 0xFE, 0x04, 0x07, 0xC0, 0x0F,
|
||||
0x00, 0x7E, 0x03, 0x9C, 0x0C, 0x30, 0x30, 0xC0, 0xE7, 0x01, 0xF8, 0x03,
|
||||
0x80, 0x3E, 0x01, 0xCC, 0x6E, 0x19, 0xB0, 0x7C, 0xC0, 0xF3, 0x03, 0xCE,
|
||||
0x1F, 0x9F, 0xE6, 0x1E, 0x1C, 0xFF, 0xA0, 0x08, 0x8C, 0x66, 0x31, 0x98,
|
||||
0xC6, 0x31, 0x8C, 0x63, 0x08, 0x63, 0x08, 0x61, 0x0C, 0x20, 0x82, 0x18,
|
||||
0xC3, 0x18, 0xC3, 0x18, 0xC6, 0x31, 0x8C, 0x62, 0x31, 0x88, 0xC4, 0x62,
|
||||
0x00, 0x10, 0x23, 0x5B, 0xE3, 0x8D, 0x91, 0x00, 0x0C, 0x03, 0x00, 0xC0,
|
||||
0x30, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0xF5, 0x60,
|
||||
0xFF, 0xF0, 0xF0, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20,
|
||||
0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x00, 0x1F, 0x07, 0xF1, 0xC7, 0x30,
|
||||
0x6E, 0x0F, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C,
|
||||
0x0E, 0xC1, 0x9C, 0x71, 0xFC, 0x1F, 0x00, 0x08, 0xCF, 0xFF, 0x8C, 0x63,
|
||||
0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0x1F, 0x0F, 0xF9, 0x87, 0x60, 0x7C,
|
||||
0x06, 0x00, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x06, 0x00,
|
||||
0x80, 0x30, 0x07, 0xFF, 0xFF, 0xE0, 0x3F, 0x0F, 0xF3, 0x87, 0x60, 0x6C,
|
||||
0x0C, 0x01, 0x80, 0x70, 0x7C, 0x0F, 0x80, 0x18, 0x01, 0x80, 0x3C, 0x07,
|
||||
0x80, 0xD8, 0x73, 0xFC, 0x1F, 0x00, 0x01, 0x80, 0x70, 0x0E, 0x03, 0xC0,
|
||||
0xD8, 0x1B, 0x06, 0x61, 0x8C, 0x21, 0x8C, 0x33, 0x06, 0x7F, 0xFF, 0xFE,
|
||||
0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xCF, 0xF9, 0x80, 0x30, 0x06,
|
||||
0x00, 0xDE, 0x1F, 0xE7, 0x0E, 0x00, 0xE0, 0x0C, 0x01, 0x80, 0x30, 0x07,
|
||||
0x81, 0xF8, 0x73, 0xFC, 0x1F, 0x00, 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x74,
|
||||
0x01, 0x80, 0x33, 0xC7, 0xFE, 0xF0, 0xDC, 0x1F, 0x01, 0xE0, 0x3C, 0x06,
|
||||
0xC1, 0xDC, 0x71, 0xFC, 0x1F, 0x00, 0xFF, 0xFF, 0xFC, 0x01, 0x00, 0x60,
|
||||
0x18, 0x02, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x04, 0x01, 0x80,
|
||||
0x30, 0x06, 0x01, 0x80, 0x30, 0x00, 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x66,
|
||||
0x0C, 0xC1, 0x8C, 0x61, 0xFC, 0x3F, 0x8E, 0x3B, 0x01, 0xE0, 0x3C, 0x07,
|
||||
0x80, 0xD8, 0x31, 0xFC, 0x1F, 0x00, 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x6C,
|
||||
0x07, 0x80, 0xF0, 0x1E, 0x07, 0x61, 0xEF, 0xFC, 0x79, 0x80, 0x30, 0x05,
|
||||
0x81, 0x98, 0x73, 0xFC, 0x1E, 0x00, 0xF0, 0x00, 0x03, 0xC0, 0xF0, 0x00,
|
||||
0x0F, 0x56, 0x00, 0x00, 0x07, 0x01, 0xE0, 0xF8, 0x3C, 0x0F, 0x00, 0xE0,
|
||||
0x07, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xFF, 0xFF, 0xFF, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x0E, 0x00, 0x78, 0x01, 0xF0, 0x07,
|
||||
0xC0, 0x0F, 0x00, 0x70, 0x1E, 0x0F, 0x03, 0xC0, 0xF0, 0x08, 0x00, 0x1F,
|
||||
0x1F, 0xEE, 0x1B, 0x03, 0xC0, 0xC0, 0x30, 0x0C, 0x06, 0x03, 0x81, 0xC0,
|
||||
0xE0, 0x30, 0x0C, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x03, 0x00, 0x00, 0xFE,
|
||||
0x00, 0x0F, 0xFE, 0x00, 0xF0, 0x3E, 0x07, 0x00, 0x3C, 0x38, 0x00, 0x30,
|
||||
0xC1, 0xE0, 0x66, 0x0F, 0xD9, 0xD8, 0x61, 0xC3, 0xC3, 0x07, 0x0F, 0x1C,
|
||||
0x1C, 0x3C, 0x60, 0x60, 0xF1, 0x81, 0x83, 0xC6, 0x06, 0x1B, 0x18, 0x38,
|
||||
0xEE, 0x71, 0xE7, 0x18, 0xFD, 0xF8, 0x71, 0xE7, 0xC0, 0xE0, 0x00, 0x01,
|
||||
0xE0, 0x00, 0x01, 0xFF, 0xC0, 0x01, 0xFC, 0x00, 0x03, 0xC0, 0x03, 0xC0,
|
||||
0x03, 0xC0, 0x07, 0xE0, 0x06, 0x60, 0x06, 0x60, 0x0E, 0x70, 0x0C, 0x30,
|
||||
0x0C, 0x30, 0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x1C,
|
||||
0x30, 0x0C, 0x70, 0x0E, 0x60, 0x06, 0x60, 0x06, 0xFF, 0xC7, 0xFF, 0x30,
|
||||
0x19, 0x80, 0x6C, 0x03, 0x60, 0x1B, 0x00, 0xD8, 0x0C, 0xFF, 0xC7, 0xFF,
|
||||
0x30, 0x0D, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x06, 0xFF, 0xF7,
|
||||
0xFE, 0x00, 0x07, 0xE0, 0x3F, 0xF0, 0xE0, 0x73, 0x80, 0x66, 0x00, 0x6C,
|
||||
0x00, 0x30, 0x00, 0x60, 0x00, 0xC0, 0x01, 0x80, 0x03, 0x00, 0x06, 0x00,
|
||||
0x06, 0x00, 0x6C, 0x00, 0xDC, 0x03, 0x1E, 0x0E, 0x1F, 0xF8, 0x0F, 0xC0,
|
||||
0xFF, 0x83, 0xFF, 0x8C, 0x07, 0x30, 0x0E, 0xC0, 0x1B, 0x00, 0x7C, 0x00,
|
||||
0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00,
|
||||
0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xC0,
|
||||
0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0,
|
||||
0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xDF,
|
||||
0xFB, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x00,
|
||||
0x07, 0xF0, 0x1F, 0xFC, 0x3C, 0x1E, 0x70, 0x06, 0x60, 0x03, 0xE0, 0x00,
|
||||
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xC0, 0x03, 0xC0, 0x03,
|
||||
0x60, 0x03, 0x60, 0x07, 0x30, 0x0F, 0x3C, 0x1F, 0x1F, 0xFB, 0x07, 0xE1,
|
||||
0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78,
|
||||
0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x01,
|
||||
0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60,
|
||||
0x3C, 0x1E, 0x0F, 0x07, 0xC7, 0x7F, 0x1F, 0x00, 0xC0, 0x3B, 0x01, 0xCC,
|
||||
0x0E, 0x30, 0x70, 0xC3, 0x83, 0x1C, 0x0C, 0xE0, 0x33, 0x80, 0xDE, 0x03,
|
||||
0xDC, 0x0E, 0x38, 0x30, 0x60, 0xC1, 0xC3, 0x03, 0x8C, 0x06, 0x30, 0x1C,
|
||||
0xC0, 0x3B, 0x00, 0x60, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C,
|
||||
0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xFF, 0xFF, 0xF0, 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xD0,
|
||||
0x0F, 0xD8, 0x1B, 0xD8, 0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC,
|
||||
0x33, 0xC6, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC1, 0x83, 0xE0, 0x1F, 0x00, 0xFC, 0x07, 0xE0, 0x3D, 0x81, 0xEE,
|
||||
0x0F, 0x30, 0x79, 0xC3, 0xC6, 0x1E, 0x18, 0xF0, 0xE7, 0x83, 0x3C, 0x1D,
|
||||
0xE0, 0x6F, 0x01, 0xF8, 0x0F, 0xC0, 0x3E, 0x01, 0xC0, 0x03, 0xE0, 0x0F,
|
||||
0xFC, 0x0F, 0x07, 0x86, 0x00, 0xC6, 0x00, 0x33, 0x00, 0x1B, 0x00, 0x07,
|
||||
0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x36, 0x00,
|
||||
0x33, 0x00, 0x18, 0xC0, 0x18, 0x78, 0x3C, 0x1F, 0xFC, 0x03, 0xF8, 0x00,
|
||||
0xFF, 0x8F, 0xFE, 0xC0, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x07,
|
||||
0xFF, 0xEF, 0xFC, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00,
|
||||
0xC0, 0x0C, 0x00, 0x03, 0xE0, 0x0F, 0xFC, 0x0F, 0x07, 0x86, 0x00, 0xC6,
|
||||
0x00, 0x33, 0x00, 0x1B, 0x00, 0x07, 0x80, 0x03, 0xC0, 0x01, 0xE0, 0x00,
|
||||
0xF0, 0x00, 0x78, 0x00, 0x36, 0x00, 0x33, 0x01, 0x98, 0xC0, 0xFC, 0x78,
|
||||
0x3C, 0x1F, 0xFF, 0x03, 0xF9, 0x80, 0x00, 0x40, 0xFF, 0xC3, 0xFF, 0xCC,
|
||||
0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x0C, 0xFF, 0xE3,
|
||||
0xFF, 0xCC, 0x03, 0xB0, 0x06, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xB0, 0x06,
|
||||
0xC0, 0x1B, 0x00, 0x70, 0x0F, 0xE0, 0x7F, 0xC3, 0x83, 0x9C, 0x07, 0x60,
|
||||
0x0D, 0x80, 0x06, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F, 0x80,
|
||||
0x07, 0xC0, 0x0F, 0x00, 0x3E, 0x00, 0xDE, 0x0E, 0x3F, 0xF0, 0x3F, 0x80,
|
||||
0xFF, 0xFF, 0xFF, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
|
||||
0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60,
|
||||
0x06, 0x00, 0x60, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0,
|
||||
0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01,
|
||||
0xE0, 0x0F, 0x80, 0xEE, 0x0E, 0x3F, 0xE0, 0x7C, 0x00, 0x60, 0x06, 0xC0,
|
||||
0x1D, 0xC0, 0x31, 0x80, 0x63, 0x01, 0xC7, 0x03, 0x06, 0x06, 0x0C, 0x1C,
|
||||
0x1C, 0x30, 0x18, 0x60, 0x31, 0xC0, 0x73, 0x00, 0x66, 0x00, 0xDC, 0x01,
|
||||
0xF0, 0x01, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0xE0, 0x30, 0x1D, 0x80, 0xE0,
|
||||
0x76, 0x07, 0x81, 0xD8, 0x1E, 0x06, 0x70, 0x7C, 0x18, 0xC1, 0xB0, 0xE3,
|
||||
0x0C, 0xC3, 0x8C, 0x33, 0x0C, 0x38, 0xC6, 0x30, 0x67, 0x18, 0xC1, 0x98,
|
||||
0x67, 0x06, 0x61, 0xD8, 0x1D, 0x83, 0x60, 0x3C, 0x0D, 0x80, 0xF0, 0x3E,
|
||||
0x03, 0xC0, 0x70, 0x0F, 0x01, 0xC0, 0x18, 0x07, 0x00, 0x70, 0x0E, 0x60,
|
||||
0x38, 0xE0, 0x60, 0xE1, 0xC0, 0xC3, 0x01, 0xCC, 0x01, 0xF8, 0x01, 0xE0,
|
||||
0x03, 0x80, 0x07, 0x80, 0x1F, 0x00, 0x33, 0x00, 0xE7, 0x03, 0x86, 0x06,
|
||||
0x0E, 0x1C, 0x0E, 0x70, 0x0C, 0xC0, 0x1C, 0x60, 0x06, 0x70, 0x0E, 0x30,
|
||||
0x1C, 0x38, 0x18, 0x1C, 0x38, 0x0C, 0x30, 0x0E, 0x70, 0x06, 0x60, 0x03,
|
||||
0xC0, 0x03, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xC0, 0x0E,
|
||||
0x00, 0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x30, 0x03,
|
||||
0x80, 0x38, 0x03, 0x80, 0x18, 0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF,
|
||||
0xC0, 0xFF, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF,
|
||||
0xF0, 0x81, 0x81, 0x02, 0x06, 0x04, 0x08, 0x18, 0x10, 0x20, 0x60, 0x40,
|
||||
0x81, 0x81, 0x02, 0x06, 0x04, 0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
||||
0x33, 0x33, 0x33, 0x3F, 0xF0, 0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19,
|
||||
0x8C, 0x83, 0xC1, 0x80, 0xFF, 0xFE, 0xE3, 0x8C, 0x30, 0x3F, 0x07, 0xF8,
|
||||
0xE1, 0xCC, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xCF, 0x8C, 0xC0, 0xCC, 0x0C,
|
||||
0xE3, 0xC7, 0xEF, 0x3C, 0x70, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0,
|
||||
0x0C, 0xF8, 0xDF, 0xCF, 0x0E, 0xE0, 0x7C, 0x03, 0xC0, 0x3C, 0x03, 0xC0,
|
||||
0x3C, 0x03, 0xE0, 0x6F, 0x0E, 0xDF, 0xCC, 0xF8, 0x1F, 0x0F, 0xE7, 0x1B,
|
||||
0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x37, 0x1C, 0xFE, 0x1F,
|
||||
0x00, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xCF, 0xFB, 0x8F,
|
||||
0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8F, 0x3F,
|
||||
0x63, 0xCC, 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x3C, 0x07, 0xFF, 0xFF, 0xFE,
|
||||
0x00, 0xC0, 0x1C, 0x0D, 0xC3, 0x1F, 0xE1, 0xF0, 0x3B, 0xD8, 0xC6, 0x7F,
|
||||
0xEC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x00, 0x1E, 0x67, 0xFD, 0xC7,
|
||||
0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x9F,
|
||||
0xB1, 0xE6, 0x00, 0xC0, 0x3E, 0x0E, 0x7F, 0xC7, 0xE0, 0xC0, 0x30, 0x0C,
|
||||
0x03, 0x00, 0xC0, 0x33, 0xCD, 0xFB, 0xC7, 0xE0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30, 0xF0, 0x3F, 0xFF, 0xFF,
|
||||
0xF0, 0x33, 0x00, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F,
|
||||
0xE0, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x83, 0x30, 0xC6, 0x30,
|
||||
0xCC, 0x1B, 0x83, 0xF0, 0x77, 0x0C, 0x61, 0x8E, 0x30, 0xE6, 0x0C, 0xC1,
|
||||
0xD8, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xCF, 0x1F, 0x6F, 0xDF, 0xFC,
|
||||
0x78, 0xFC, 0x18, 0x3C, 0x0C, 0x1E, 0x06, 0x0F, 0x03, 0x07, 0x81, 0x83,
|
||||
0xC0, 0xC1, 0xE0, 0x60, 0xF0, 0x30, 0x78, 0x18, 0x3C, 0x0C, 0x18, 0xCF,
|
||||
0x37, 0xEF, 0x1F, 0x83, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xC0, 0x1F, 0x07, 0xF1, 0xC7, 0x70, 0x7C, 0x07, 0x80,
|
||||
0xF0, 0x1E, 0x03, 0xC0, 0x7C, 0x1D, 0xC7, 0x1F, 0xC1, 0xF0, 0xCF, 0x8D,
|
||||
0xFC, 0xF0, 0xEE, 0x06, 0xC0, 0x3C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x3E,
|
||||
0x07, 0xF0, 0xEF, 0xFC, 0xCF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x00,
|
||||
0x1E, 0x67, 0xFD, 0xC7, 0xF0, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0,
|
||||
0x7C, 0x1D, 0xC7, 0x9F, 0xF1, 0xE6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60,
|
||||
0xCF, 0x7F, 0x38, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x3E, 0x1F,
|
||||
0xEE, 0x1B, 0x00, 0xC0, 0x3C, 0x07, 0xF0, 0x3E, 0x01, 0xF0, 0x3E, 0x1D,
|
||||
0xFE, 0x3E, 0x00, 0x63, 0x19, 0xFF, 0xB1, 0x8C, 0x63, 0x18, 0xC6, 0x31,
|
||||
0xE7, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
|
||||
0xF0, 0x7E, 0x3D, 0xFB, 0x3C, 0xC0, 0xE0, 0x66, 0x06, 0x60, 0x67, 0x0C,
|
||||
0x30, 0xC3, 0x0C, 0x39, 0x81, 0x98, 0x19, 0x81, 0xF0, 0x0F, 0x00, 0xE0,
|
||||
0x0E, 0x00, 0xC1, 0xC1, 0xB0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36,
|
||||
0x31, 0x9B, 0x18, 0xCD, 0x98, 0x64, 0x6C, 0x16, 0x36, 0x0F, 0x1A, 0x07,
|
||||
0x8F, 0x03, 0x83, 0x80, 0xC1, 0xC0, 0x60, 0xEE, 0x18, 0xC6, 0x0C, 0xC1,
|
||||
0xF0, 0x1C, 0x01, 0x80, 0x78, 0x1B, 0x03, 0x30, 0xC7, 0x30, 0x66, 0x06,
|
||||
0xE0, 0x6C, 0x0D, 0x83, 0x38, 0x63, 0x0C, 0x63, 0x0E, 0x60, 0xCC, 0x1B,
|
||||
0x03, 0x60, 0x3C, 0x07, 0x00, 0xE0, 0x18, 0x03, 0x00, 0xE0, 0x78, 0x0E,
|
||||
0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0C, 0x07, 0x03, 0x81, 0xC0, 0x60, 0x30,
|
||||
0x18, 0x0E, 0x03, 0xFF, 0xFF, 0xC0, 0x19, 0xCC, 0x63, 0x18, 0xC6, 0x31,
|
||||
0x99, 0x86, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1C, 0x60, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFC, 0xC7, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x0C, 0x33, 0x31,
|
||||
0x8C, 0x63, 0x18, 0xC6, 0x73, 0x00, 0x70, 0x3E, 0x09, 0xE4, 0x1F, 0x03,
|
||||
0x80 };
|
||||
|
||||
const GFXglyph FreeSans12pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 6, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 2, 18, 8, 3, -17 }, // 0x21 '!'
|
||||
{ 5, 6, 6, 8, 1, -16 }, // 0x22 '"'
|
||||
{ 10, 13, 16, 13, 0, -15 }, // 0x23 '#'
|
||||
{ 36, 11, 20, 13, 1, -17 }, // 0x24 '$'
|
||||
{ 64, 20, 17, 21, 1, -16 }, // 0x25 '%'
|
||||
{ 107, 14, 17, 16, 1, -16 }, // 0x26 '&'
|
||||
{ 137, 2, 6, 5, 1, -16 }, // 0x27 '''
|
||||
{ 139, 5, 23, 8, 2, -17 }, // 0x28 '('
|
||||
{ 154, 5, 23, 8, 1, -17 }, // 0x29 ')'
|
||||
{ 169, 7, 7, 9, 1, -17 }, // 0x2A '*'
|
||||
{ 176, 10, 11, 14, 2, -10 }, // 0x2B '+'
|
||||
{ 190, 2, 6, 7, 2, -1 }, // 0x2C ','
|
||||
{ 192, 6, 2, 8, 1, -7 }, // 0x2D '-'
|
||||
{ 194, 2, 2, 6, 2, -1 }, // 0x2E '.'
|
||||
{ 195, 7, 18, 7, 0, -17 }, // 0x2F '/'
|
||||
{ 211, 11, 17, 13, 1, -16 }, // 0x30 '0'
|
||||
{ 235, 5, 17, 13, 3, -16 }, // 0x31 '1'
|
||||
{ 246, 11, 17, 13, 1, -16 }, // 0x32 '2'
|
||||
{ 270, 11, 17, 13, 1, -16 }, // 0x33 '3'
|
||||
{ 294, 11, 17, 13, 1, -16 }, // 0x34 '4'
|
||||
{ 318, 11, 17, 13, 1, -16 }, // 0x35 '5'
|
||||
{ 342, 11, 17, 13, 1, -16 }, // 0x36 '6'
|
||||
{ 366, 11, 17, 13, 1, -16 }, // 0x37 '7'
|
||||
{ 390, 11, 17, 13, 1, -16 }, // 0x38 '8'
|
||||
{ 414, 11, 17, 13, 1, -16 }, // 0x39 '9'
|
||||
{ 438, 2, 13, 6, 2, -12 }, // 0x3A ':'
|
||||
{ 442, 2, 16, 6, 2, -11 }, // 0x3B ';'
|
||||
{ 446, 12, 12, 14, 1, -11 }, // 0x3C '<'
|
||||
{ 464, 12, 6, 14, 1, -8 }, // 0x3D '='
|
||||
{ 473, 12, 12, 14, 1, -11 }, // 0x3E '>'
|
||||
{ 491, 10, 18, 13, 2, -17 }, // 0x3F '?'
|
||||
{ 514, 22, 21, 24, 1, -17 }, // 0x40 '@'
|
||||
{ 572, 16, 18, 16, 0, -17 }, // 0x41 'A'
|
||||
{ 608, 13, 18, 16, 2, -17 }, // 0x42 'B'
|
||||
{ 638, 15, 18, 17, 1, -17 }, // 0x43 'C'
|
||||
{ 672, 14, 18, 17, 2, -17 }, // 0x44 'D'
|
||||
{ 704, 12, 18, 15, 2, -17 }, // 0x45 'E'
|
||||
{ 731, 11, 18, 14, 2, -17 }, // 0x46 'F'
|
||||
{ 756, 16, 18, 18, 1, -17 }, // 0x47 'G'
|
||||
{ 792, 13, 18, 17, 2, -17 }, // 0x48 'H'
|
||||
{ 822, 2, 18, 7, 2, -17 }, // 0x49 'I'
|
||||
{ 827, 9, 18, 13, 1, -17 }, // 0x4A 'J'
|
||||
{ 848, 14, 18, 16, 2, -17 }, // 0x4B 'K'
|
||||
{ 880, 10, 18, 14, 2, -17 }, // 0x4C 'L'
|
||||
{ 903, 16, 18, 20, 2, -17 }, // 0x4D 'M'
|
||||
{ 939, 13, 18, 18, 2, -17 }, // 0x4E 'N'
|
||||
{ 969, 17, 18, 19, 1, -17 }, // 0x4F 'O'
|
||||
{ 1008, 12, 18, 16, 2, -17 }, // 0x50 'P'
|
||||
{ 1035, 17, 19, 19, 1, -17 }, // 0x51 'Q'
|
||||
{ 1076, 14, 18, 17, 2, -17 }, // 0x52 'R'
|
||||
{ 1108, 14, 18, 16, 1, -17 }, // 0x53 'S'
|
||||
{ 1140, 12, 18, 15, 1, -17 }, // 0x54 'T'
|
||||
{ 1167, 13, 18, 17, 2, -17 }, // 0x55 'U'
|
||||
{ 1197, 15, 18, 15, 0, -17 }, // 0x56 'V'
|
||||
{ 1231, 22, 18, 22, 0, -17 }, // 0x57 'W'
|
||||
{ 1281, 15, 18, 16, 0, -17 }, // 0x58 'X'
|
||||
{ 1315, 16, 18, 16, 0, -17 }, // 0x59 'Y'
|
||||
{ 1351, 13, 18, 15, 1, -17 }, // 0x5A 'Z'
|
||||
{ 1381, 4, 23, 7, 2, -17 }, // 0x5B '['
|
||||
{ 1393, 7, 18, 7, 0, -17 }, // 0x5C '\'
|
||||
{ 1409, 4, 23, 7, 1, -17 }, // 0x5D ']'
|
||||
{ 1421, 9, 9, 11, 1, -16 }, // 0x5E '^'
|
||||
{ 1432, 15, 1, 13, -1, 4 }, // 0x5F '_'
|
||||
{ 1434, 5, 4, 6, 1, -17 }, // 0x60 '`'
|
||||
{ 1437, 12, 13, 13, 1, -12 }, // 0x61 'a'
|
||||
{ 1457, 12, 18, 13, 1, -17 }, // 0x62 'b'
|
||||
{ 1484, 10, 13, 12, 1, -12 }, // 0x63 'c'
|
||||
{ 1501, 11, 18, 13, 1, -17 }, // 0x64 'd'
|
||||
{ 1526, 11, 13, 13, 1, -12 }, // 0x65 'e'
|
||||
{ 1544, 5, 18, 7, 1, -17 }, // 0x66 'f'
|
||||
{ 1556, 11, 18, 13, 1, -12 }, // 0x67 'g'
|
||||
{ 1581, 10, 18, 13, 1, -17 }, // 0x68 'h'
|
||||
{ 1604, 2, 18, 5, 2, -17 }, // 0x69 'i'
|
||||
{ 1609, 4, 23, 6, 0, -17 }, // 0x6A 'j'
|
||||
{ 1621, 11, 18, 12, 1, -17 }, // 0x6B 'k'
|
||||
{ 1646, 2, 18, 5, 1, -17 }, // 0x6C 'l'
|
||||
{ 1651, 17, 13, 19, 1, -12 }, // 0x6D 'm'
|
||||
{ 1679, 10, 13, 13, 1, -12 }, // 0x6E 'n'
|
||||
{ 1696, 11, 13, 13, 1, -12 }, // 0x6F 'o'
|
||||
{ 1714, 12, 17, 13, 1, -12 }, // 0x70 'p'
|
||||
{ 1740, 11, 17, 13, 1, -12 }, // 0x71 'q'
|
||||
{ 1764, 6, 13, 8, 1, -12 }, // 0x72 'r'
|
||||
{ 1774, 10, 13, 12, 1, -12 }, // 0x73 's'
|
||||
{ 1791, 5, 16, 7, 1, -15 }, // 0x74 't'
|
||||
{ 1801, 10, 13, 13, 1, -12 }, // 0x75 'u'
|
||||
{ 1818, 12, 13, 12, 0, -12 }, // 0x76 'v'
|
||||
{ 1838, 17, 13, 17, 0, -12 }, // 0x77 'w'
|
||||
{ 1866, 11, 13, 11, 0, -12 }, // 0x78 'x'
|
||||
{ 1884, 11, 18, 11, 0, -12 }, // 0x79 'y'
|
||||
{ 1909, 10, 13, 12, 1, -12 }, // 0x7A 'z'
|
||||
{ 1926, 5, 23, 8, 1, -17 }, // 0x7B '{'
|
||||
{ 1941, 2, 23, 6, 2, -17 }, // 0x7C '|'
|
||||
{ 1947, 5, 23, 8, 2, -17 }, // 0x7D '}'
|
||||
{ 1962, 10, 5, 12, 1, -10 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSans12pt7b PROGMEM = {
|
||||
(uint8_t *)FreeSans12pt7bBitmaps,
|
||||
(GFXglyph *)FreeSans12pt7bGlyphs,
|
||||
0x20, 0x7E, 29 };
|
||||
|
||||
// Approx. 2641 bytes
|
596
RX_FSK/src/fonts/FreeSans12pt8b.h
Normal file
596
RX_FSK/src/fonts/FreeSans12pt8b.h
Normal file
|
@ -0,0 +1,596 @@
|
|||
const uint8_t FreeSans12pt8bBitmaps[] PROGMEM = {
|
||||
0x00, 0xFF, 0xFF, 0xFF, 0xF3, 0xF0, 0xCF, 0x3C, 0xF3, 0x4D, 0x10, 0x06,
|
||||
0x30, 0x31, 0x01, 0x18, 0x18, 0xC0, 0xC6, 0x3F, 0xFD, 0xFF, 0xE1, 0x98,
|
||||
0x18, 0xC0, 0xC6, 0x06, 0x31, 0xFF, 0xE1, 0x88, 0x08, 0xC0, 0xC6, 0x06,
|
||||
0x30, 0x31, 0x80, 0x04, 0x03, 0xF1, 0xFF, 0x32, 0x7C, 0x47, 0x88, 0xF1,
|
||||
0x07, 0x20, 0x7C, 0x07, 0xF0, 0x1F, 0x02, 0x70, 0x47, 0x88, 0xF1, 0x1E,
|
||||
0x23, 0x64, 0xE7, 0xF8, 0x10, 0x02, 0x00, 0x40, 0x00, 0x06, 0x07, 0xC0,
|
||||
0x40, 0xE6, 0x0C, 0x0C, 0x30, 0x80, 0x83, 0x18, 0x0C, 0x31, 0x00, 0xC6,
|
||||
0x30, 0x07, 0xE2, 0x00, 0x38, 0x60, 0x00, 0x0C, 0x38, 0x00, 0xC7, 0xC0,
|
||||
0x18, 0xC6, 0x01, 0x18, 0x30, 0x31, 0x83, 0x02, 0x08, 0x20, 0x60, 0xC6,
|
||||
0x04, 0x07, 0xC0, 0x0F, 0x00, 0x7E, 0x03, 0x8C, 0x0C, 0x30, 0x30, 0xC0,
|
||||
0x67, 0x01, 0xF8, 0x03, 0xC0, 0x1E, 0x00, 0xCC, 0x66, 0x39, 0xB0, 0x7C,
|
||||
0xC0, 0xF3, 0x01, 0x8E, 0x0F, 0x1C, 0xFE, 0x3F, 0x9C, 0x10, 0x00, 0xFF,
|
||||
0x50, 0x08, 0x8C, 0x46, 0x31, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC2,
|
||||
0x18, 0x43, 0x08, 0x60, 0x86, 0x18, 0xC3, 0x18, 0x43, 0x18, 0xC6, 0x31,
|
||||
0x8C, 0x63, 0x11, 0x8C, 0x46, 0x23, 0x00, 0x10, 0x22, 0x4F, 0xF3, 0x85,
|
||||
0x1B, 0x00, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x0F, 0xFF, 0x06,
|
||||
0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0x97, 0xA0, 0xFC, 0xFF,
|
||||
0x80, 0x06, 0x0C, 0x10, 0x20, 0xC1, 0x02, 0x0C, 0x10, 0x20, 0xC1, 0x02,
|
||||
0x0C, 0x10, 0x20, 0xC1, 0x00, 0x1F, 0x07, 0xF1, 0xC7, 0x30, 0x6E, 0x0F,
|
||||
0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3E, 0x06, 0xC1,
|
||||
0xD8, 0x31, 0xCE, 0x3F, 0x80, 0x80, 0x04, 0x30, 0xFF, 0xFC, 0x30, 0xC3,
|
||||
0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x1F, 0x07, 0xF9, 0xC3, 0xB0,
|
||||
0x3C, 0x07, 0x80, 0xC0, 0x18, 0x07, 0x01, 0xC0, 0xF0, 0x78, 0x1C, 0x07,
|
||||
0x01, 0xC0, 0x30, 0x07, 0xFF, 0xFF, 0xE0, 0x1F, 0x0F, 0xF9, 0x83, 0x70,
|
||||
0x7C, 0x0E, 0x01, 0xC0, 0x30, 0x7C, 0x0F, 0x80, 0x38, 0x01, 0x80, 0x3C,
|
||||
0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x80, 0x80, 0x01, 0x80, 0x70, 0x0E,
|
||||
0x03, 0xC0, 0xD8, 0x33, 0x06, 0x61, 0x8C, 0x61, 0x8C, 0x33, 0x06, 0x7F,
|
||||
0xFF, 0xFE, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xCF, 0xF9, 0x80,
|
||||
0x30, 0x06, 0x00, 0xC0, 0x1F, 0xE3, 0xFE, 0xE0, 0xE0, 0x0C, 0x01, 0x80,
|
||||
0x30, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x80, 0x80, 0x0F, 0x07, 0xF9,
|
||||
0xC3, 0x30, 0x36, 0x01, 0x80, 0x30, 0x86, 0xFC, 0xF9, 0xDC, 0x1F, 0x81,
|
||||
0xE0, 0x3C, 0x06, 0xC0, 0xD8, 0x3B, 0xCE, 0x3F, 0x80, 0x80, 0xFF, 0xFF,
|
||||
0xFC, 0x01, 0x80, 0x60, 0x0C, 0x03, 0x00, 0xC0, 0x18, 0x06, 0x00, 0xC0,
|
||||
0x30, 0x06, 0x00, 0xC0, 0x30, 0x06, 0x00, 0xC0, 0x38, 0x00, 0x1F, 0x07,
|
||||
0xF9, 0xC3, 0x30, 0x7E, 0x06, 0xC1, 0xD8, 0x31, 0xFC, 0x3F, 0x8E, 0x1B,
|
||||
0x81, 0xE0, 0x3C, 0x07, 0x80, 0xF8, 0x3B, 0x8E, 0x3F, 0x80, 0x80, 0x1F,
|
||||
0x07, 0xF1, 0x87, 0x70, 0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x07, 0x60, 0xEF,
|
||||
0xFC, 0x7D, 0x80, 0x30, 0x07, 0x81, 0x98, 0x33, 0x9C, 0x3F, 0x00, 0x80,
|
||||
0xFC, 0x00, 0x0F, 0xC0, 0xFC, 0x00, 0x0F, 0xD7, 0x00, 0x00, 0x30, 0x1F,
|
||||
0x07, 0x81, 0xE0, 0xF8, 0x0E, 0x00, 0x78, 0x01, 0xE0, 0x07, 0xC0, 0x0F,
|
||||
0x00, 0x30, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xF0, 0xC0, 0x0F,
|
||||
0x80, 0x1E, 0x00, 0x78, 0x01, 0xF0, 0x03, 0x01, 0xE0, 0x78, 0x3E, 0x0F,
|
||||
0x00, 0xC0, 0x00, 0x1E, 0x1F, 0xE6, 0x1F, 0x03, 0xC0, 0xF0, 0x30, 0x0C,
|
||||
0x06, 0x03, 0x01, 0x80, 0xC0, 0x30, 0x0C, 0x00, 0x00, 0x00, 0x30, 0x0C,
|
||||
0x03, 0x00, 0x00, 0x7C, 0x00, 0x0F, 0xFE, 0x00, 0x70, 0x3C, 0x07, 0x00,
|
||||
0x38, 0x38, 0x00, 0x70, 0xC0, 0x40, 0xE6, 0x0F, 0xD9, 0x98, 0x71, 0xC7,
|
||||
0xC3, 0x87, 0x0F, 0x0C, 0x0C, 0x3C, 0x30, 0x70, 0xF1, 0xC1, 0x86, 0xC7,
|
||||
0x06, 0x1B, 0x1C, 0x38, 0xEC, 0x39, 0xE7, 0x18, 0x7D, 0xF8, 0x70, 0x01,
|
||||
0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0xF3, 0xC0, 0x03, 0xFF, 0x00,
|
||||
0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x60, 0x06, 0x60,
|
||||
0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8,
|
||||
0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x70, 0x0E, 0x60, 0x06, 0x60, 0x07,
|
||||
0xFE, 0x07, 0xFF, 0x30, 0x79, 0x80, 0xEC, 0x03, 0x60, 0x1B, 0x00, 0xD8,
|
||||
0x0C, 0xFF, 0xC7, 0xFF, 0x30, 0x1D, 0x80, 0x7C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0xF8, 0x0E, 0xFF, 0xF7, 0xFE, 0x00, 0x03, 0xC0, 0x1F, 0xF0, 0xF0, 0xE1,
|
||||
0x80, 0xE7, 0x00, 0xEC, 0x01, 0xF8, 0x00, 0x70, 0x00, 0xC0, 0x01, 0x80,
|
||||
0x03, 0x00, 0x07, 0x00, 0x06, 0x00, 0x6C, 0x01, 0xDC, 0x03, 0x9C, 0x0E,
|
||||
0x1F, 0x78, 0x1F, 0xE0, 0x04, 0x00, 0xFE, 0x03, 0xFF, 0x8C, 0x1F, 0x30,
|
||||
0x0E, 0xC0, 0x1B, 0x00, 0x6C, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C,
|
||||
0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6C, 0x03, 0xB0, 0x1C, 0xFF, 0xE3,
|
||||
0xFF, 0x00, 0xFF, 0xF7, 0xFF, 0xB0, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03,
|
||||
0x00, 0x18, 0x00, 0xFF, 0xF7, 0xFF, 0xB0, 0x01, 0x80, 0x0C, 0x00, 0x60,
|
||||
0x03, 0x00, 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xFF, 0xFF, 0xC0,
|
||||
0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xFF, 0xEF, 0xFE, 0xC0,
|
||||
0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0x03,
|
||||
0xE0, 0x0F, 0xF8, 0x1E, 0x3C, 0x38, 0x0E, 0x70, 0x06, 0x60, 0x07, 0xE0,
|
||||
0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x7F, 0xC0, 0x7F, 0xE0, 0x03, 0xE0,
|
||||
0x03, 0x60, 0x03, 0x70, 0x07, 0x38, 0x0F, 0x1F, 0x7B, 0x0F, 0xF3, 0x00,
|
||||
0x80, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F,
|
||||
0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFC, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03,
|
||||
0x00, 0xC0, 0x30, 0x0C, 0x03, 0xE0, 0xF8, 0x3E, 0x0D, 0x87, 0x73, 0x8F,
|
||||
0xE0, 0x40, 0xC0, 0x1F, 0x00, 0xEC, 0x07, 0x30, 0x38, 0xC1, 0xC3, 0x0E,
|
||||
0x0C, 0x70, 0x33, 0x80, 0xDE, 0x03, 0xFC, 0x0F, 0x38, 0x38, 0x60, 0xC1,
|
||||
0xC3, 0x03, 0x8C, 0x06, 0x30, 0x1C, 0xC0, 0x3B, 0x00, 0x60, 0xC0, 0x18,
|
||||
0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x18, 0x03,
|
||||
0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xFF, 0xFF, 0xFC, 0xE0,
|
||||
0x07, 0xE0, 0x07, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x0F, 0xD8, 0x1B, 0xD8,
|
||||
0x1B, 0xD8, 0x1B, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xC6, 0x63, 0xC6,
|
||||
0x63, 0xC6, 0x63, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC1, 0x83, 0xC0,
|
||||
0x1F, 0x80, 0x7F, 0x01, 0xFC, 0x07, 0xF8, 0x1F, 0x60, 0x7C, 0xC1, 0xF3,
|
||||
0x87, 0xC6, 0x1F, 0x0C, 0x7C, 0x39, 0xF0, 0x67, 0xC1, 0xDF, 0x03, 0xFC,
|
||||
0x07, 0xF0, 0x1F, 0xC0, 0x3F, 0x00, 0x70, 0x03, 0xE0, 0x07, 0xFC, 0x0F,
|
||||
0x8F, 0x07, 0x01, 0xC7, 0x00, 0x73, 0x00, 0x1B, 0x80, 0x0D, 0x80, 0x07,
|
||||
0xC0, 0x01, 0xE0, 0x00, 0xF0, 0x00, 0x78, 0x00, 0x7E, 0x00, 0x33, 0x00,
|
||||
0x19, 0xC0, 0x1C, 0x70, 0x1C, 0x1F, 0x7C, 0x07, 0xFC, 0x00, 0x20, 0x00,
|
||||
0xFE, 0x07, 0xFF, 0x30, 0x7D, 0x80, 0x6C, 0x03, 0xE0, 0x1F, 0x00, 0xF8,
|
||||
0x07, 0xC0, 0xF7, 0xFF, 0x3F, 0xC1, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00,
|
||||
0x18, 0x00, 0xC0, 0x06, 0x00, 0x00, 0x03, 0xE0, 0x07, 0xFC, 0x0F, 0x8F,
|
||||
0x07, 0x01, 0xC7, 0x00, 0x73, 0x00, 0x1B, 0x80, 0x0D, 0x80, 0x07, 0xC0,
|
||||
0x01, 0xE0, 0x00, 0xF0, 0x00, 0xF8, 0x00, 0x7E, 0x00, 0x33, 0x01, 0x19,
|
||||
0xC0, 0xDC, 0x70, 0x3C, 0x1F, 0x7E, 0x07, 0xFF, 0x80, 0x20, 0xC0, 0xFF,
|
||||
0x03, 0xFF, 0xCC, 0x0F, 0xB0, 0x06, 0xC0, 0x1F, 0x00, 0x7C, 0x01, 0xB0,
|
||||
0x06, 0xC0, 0xF3, 0xFF, 0x8C, 0x0F, 0x30, 0x06, 0xC0, 0x1B, 0x00, 0x6C,
|
||||
0x01, 0xB0, 0x06, 0xC0, 0x1F, 0x00, 0x70, 0x07, 0x80, 0xFF, 0x87, 0x87,
|
||||
0x18, 0x0E, 0x60, 0x19, 0x80, 0x66, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F,
|
||||
0xC0, 0x0F, 0x80, 0x07, 0xC0, 0x1F, 0x00, 0x3E, 0x01, 0xDC, 0x06, 0x7E,
|
||||
0xF8, 0x7F, 0x80, 0x20, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x38, 0x00, 0xE0,
|
||||
0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38,
|
||||
0x00, 0xE0, 0x03, 0x80, 0x0E, 0x00, 0x38, 0x00, 0xE0, 0x03, 0x80, 0x0E,
|
||||
0x00, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00,
|
||||
0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F,
|
||||
0x80, 0x6C, 0x07, 0x7D, 0xF1, 0xFF, 0x00, 0x80, 0xC0, 0x0F, 0x00, 0x3E,
|
||||
0x01, 0xD8, 0x06, 0x70, 0x18, 0xC0, 0xE3, 0x03, 0x0E, 0x0C, 0x18, 0x70,
|
||||
0x61, 0x81, 0xC6, 0x03, 0x38, 0x0C, 0xC0, 0x3B, 0x00, 0x6C, 0x01, 0xE0,
|
||||
0x07, 0x80, 0x0E, 0x00, 0xC0, 0x70, 0x1E, 0x03, 0x80, 0xF0, 0x1C, 0x0F,
|
||||
0xC1, 0xE0, 0x76, 0x0D, 0x83, 0x30, 0x6C, 0x19, 0x83, 0x61, 0xCE, 0x33,
|
||||
0x8E, 0x31, 0x8C, 0x61, 0x8C, 0x63, 0x0C, 0xE3, 0x18, 0x76, 0x0D, 0xC1,
|
||||
0xB0, 0x6C, 0x0D, 0x83, 0x60, 0x78, 0x1F, 0x03, 0xC0, 0x78, 0x0E, 0x03,
|
||||
0x80, 0x70, 0x1C, 0x00, 0xE0, 0x0C, 0xC0, 0x39, 0xC0, 0xE1, 0xC1, 0x81,
|
||||
0x87, 0x03, 0x9C, 0x03, 0xB0, 0x03, 0xC0, 0x07, 0x80, 0x0F, 0x00, 0x1E,
|
||||
0x00, 0x76, 0x01, 0xCE, 0x03, 0x0C, 0x0E, 0x0C, 0x38, 0x1C, 0x60, 0x1D,
|
||||
0xC0, 0x38, 0xE0, 0x07, 0x70, 0x06, 0x30, 0x0E, 0x38, 0x1C, 0x18, 0x18,
|
||||
0x1C, 0x38, 0x0E, 0x30, 0x06, 0x70, 0x07, 0x60, 0x03, 0xC0, 0x01, 0xC0,
|
||||
0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||
0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xC0, 0x0E, 0x00, 0xE0, 0x06, 0x00, 0x70,
|
||||
0x07, 0x00, 0x70, 0x07, 0x00, 0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0x18,
|
||||
0x01, 0xC0, 0x1C, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xFF, 0xCC, 0xCC, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xF0, 0x81, 0x03, 0x02, 0x04,
|
||||
0x0C, 0x08, 0x10, 0x30, 0x20, 0x40, 0xC0, 0x81, 0x03, 0x02, 0x04, 0x0C,
|
||||
0xFF, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0xF0,
|
||||
0x0C, 0x0E, 0x05, 0x86, 0xC3, 0x21, 0x19, 0x8C, 0x83, 0xC1, 0x80, 0xFF,
|
||||
0xFE, 0xC3, 0x0C, 0x20, 0x1F, 0x07, 0xFC, 0x60, 0xC6, 0x0C, 0x00, 0xC0,
|
||||
0x1C, 0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C, 0xC0, 0xCE, 0x3E, 0x7E, 0x70,
|
||||
0x02, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0xF0, 0xDF, 0xCF,
|
||||
0x0E, 0xE0, 0x6E, 0x06, 0xC0, 0x6C, 0x07, 0xC0, 0x7C, 0x06, 0xE0, 0x6E,
|
||||
0x0E, 0xF9, 0xCD, 0xF8, 0x00, 0x00, 0x1F, 0x0F, 0xE6, 0x1F, 0x83, 0xC0,
|
||||
0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x3E, 0x0D, 0xC7, 0x3F, 0x81, 0x00,
|
||||
0x00, 0x60, 0x0C, 0x01, 0x80, 0x30, 0x06, 0x3C, 0xDF, 0xDB, 0x8F, 0xE0,
|
||||
0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x3F, 0x07, 0x7B, 0xE7,
|
||||
0xEC, 0x10, 0x00, 0x0F, 0x07, 0xF9, 0xC3, 0x30, 0x3C, 0x07, 0x80, 0xFF,
|
||||
0xFE, 0x00, 0xC0, 0x18, 0x0D, 0x83, 0xBC, 0xE3, 0xF8, 0x08, 0x00, 0x04,
|
||||
0x73, 0x0C, 0x33, 0xFF, 0xCC, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30,
|
||||
0xC0, 0x1E, 0x67, 0xED, 0x87, 0xF0, 0x7C, 0x0F, 0x80, 0xF0, 0x1E, 0x03,
|
||||
0xC0, 0x78, 0x1F, 0x83, 0xB9, 0xF3, 0xF6, 0x00, 0xF0, 0x37, 0x06, 0x7F,
|
||||
0xC7, 0xE0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0xCF, 0xFB, 0x87,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0,
|
||||
0x30, 0xFC, 0x3F, 0xFF, 0xFF, 0xF0, 0x33, 0x30, 0x03, 0x33, 0x33, 0x33,
|
||||
0x33, 0x33, 0x33, 0x33, 0x3F, 0xE0, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C,
|
||||
0x01, 0x81, 0xB0, 0x66, 0x18, 0xC6, 0x19, 0x83, 0x70, 0x7B, 0x0E, 0x71,
|
||||
0x86, 0x30, 0xE6, 0x0C, 0xC0, 0xD8, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
|
||||
0xDE, 0x1E, 0xFF, 0x7F, 0xE3, 0xC3, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83,
|
||||
0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83, 0xC1, 0x83,
|
||||
0xC1, 0x83, 0xCF, 0x3F, 0xEE, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x1F, 0x07, 0xF1, 0xC7, 0x70,
|
||||
0x7C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0D, 0x83, 0xBD, 0xE3,
|
||||
0xF8, 0x08, 0x00, 0xCF, 0x0D, 0xFC, 0xF0, 0xCE, 0x06, 0xE0, 0x6C, 0x06,
|
||||
0xC0, 0x7C, 0x07, 0xC0, 0x6E, 0x06, 0xE0, 0xEF, 0x9C, 0xDF, 0x8C, 0x00,
|
||||
0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0x1E, 0x6F, 0xFD, 0xC7, 0xF0, 0x7C,
|
||||
0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x1F, 0x83, 0xBD, 0xF3, 0xF6,
|
||||
0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0xDF, 0xFF, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC3, 0x0C, 0x30, 0xC0, 0x1E, 0x1F, 0xEE, 0x1B, 0x06, 0xC0, 0x3C,
|
||||
0x07, 0xF0, 0x3E, 0x01, 0xF0, 0x3C, 0x0F, 0xCE, 0x7F, 0x82, 0x00, 0x30,
|
||||
0xC3, 0x3F, 0xFC, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0F, 0x08,
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC1, 0xF0,
|
||||
0x7C, 0x1F, 0x8F, 0x7E, 0xC4, 0x00, 0xE0, 0x76, 0x06, 0x60, 0x67, 0x0C,
|
||||
0x30, 0xC3, 0x0C, 0x39, 0x81, 0x98, 0x19, 0x81, 0xB0, 0x0F, 0x00, 0xE0,
|
||||
0x0E, 0x00, 0xC1, 0xC1, 0xF0, 0xE1, 0xD8, 0x70, 0xCC, 0x2C, 0x66, 0x36,
|
||||
0x31, 0x9B, 0x38, 0xCD, 0x98, 0x64, 0x6C, 0x36, 0x36, 0x0F, 0x1E, 0x07,
|
||||
0x8F, 0x03, 0x83, 0x80, 0xC1, 0x80, 0x60, 0x6E, 0x1C, 0xC3, 0x0C, 0xC1,
|
||||
0xF0, 0x1E, 0x01, 0x80, 0x78, 0x0F, 0x03, 0x30, 0xC7, 0x38, 0x66, 0x06,
|
||||
0x60, 0x6C, 0x0D, 0x81, 0x98, 0x63, 0x0C, 0x63, 0x86, 0x60, 0xCC, 0x1B,
|
||||
0x81, 0xE0, 0x3C, 0x07, 0x00, 0x60, 0x0C, 0x03, 0x00, 0x60, 0x78, 0x0F,
|
||||
0x00, 0xFF, 0xFF, 0xF0, 0x18, 0x0E, 0x07, 0x03, 0x80, 0xC0, 0x60, 0x30,
|
||||
0x1C, 0x0E, 0x03, 0xFF, 0xFF, 0xC0, 0x04, 0xF3, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC6, 0x30, 0xE1, 0x83, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xE1, 0xC0,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x87, 0x18, 0x42, 0x10, 0x84, 0x21,
|
||||
0x8C, 0x31, 0x98, 0xC4, 0x21, 0x08, 0x42, 0x73, 0x80, 0x00, 0x3E, 0x1D,
|
||||
0xC6, 0x1F, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x07, 0x80, 0x3C, 0x01,
|
||||
0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C,
|
||||
0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0xFC,
|
||||
0xFF, 0xFF, 0xFF, 0xF0, 0x04, 0x00, 0x80, 0x3C, 0x1F, 0xE7, 0x4E, 0xC8,
|
||||
0xD9, 0x1E, 0x20, 0xC4, 0x18, 0x83, 0x10, 0x32, 0x36, 0x46, 0x7B, 0x87,
|
||||
0xE0, 0x30, 0x04, 0x00, 0x80, 0x00, 0x01, 0xF8, 0x79, 0xC6, 0x0E, 0xE0,
|
||||
0x6E, 0x06, 0xE0, 0x06, 0x00, 0x70, 0x0F, 0xF0, 0x38, 0x01, 0x80, 0x18,
|
||||
0x01, 0x00, 0x30, 0x06, 0x00, 0xFF, 0xEE, 0xFF, 0x00, 0x80, 0x01, 0xF0,
|
||||
0x1F, 0xF0, 0xE0, 0x87, 0x00, 0x18, 0x00, 0xC0, 0x0F, 0xFF, 0x3F, 0xFC,
|
||||
0x30, 0x03, 0xFF, 0x8F, 0xFC, 0x0C, 0x00, 0x38, 0x00, 0x60, 0x01, 0xC0,
|
||||
0x03, 0xC6, 0x07, 0xF8, 0x00, 0x00, 0x60, 0x1B, 0x01, 0x8C, 0x0C, 0x60,
|
||||
0xC1, 0x86, 0x0C, 0x60, 0x36, 0x00, 0xF0, 0x07, 0xF1, 0xFF, 0x80, 0xC0,
|
||||
0x06, 0x03, 0xFF, 0x01, 0x80, 0x0C, 0x00, 0x60, 0x03, 0x00, 0x0C, 0xC0,
|
||||
0x16, 0x00, 0x78, 0x00, 0x00, 0x07, 0x80, 0xFF, 0x87, 0x87, 0x18, 0x0E,
|
||||
0x60, 0x19, 0x80, 0x66, 0x00, 0x1E, 0x00, 0x3F, 0x80, 0x3F, 0xC0, 0x0F,
|
||||
0x80, 0x07, 0xC0, 0x1F, 0x00, 0x3E, 0x01, 0xDC, 0x06, 0x7E, 0xF8, 0x7F,
|
||||
0x80, 0x20, 0x00, 0x00, 0x03, 0xF0, 0xE7, 0x18, 0x63, 0x0C, 0x60, 0x0E,
|
||||
0x01, 0xF0, 0x67, 0x98, 0x7B, 0x03, 0xE0, 0x37, 0x06, 0xF0, 0xC7, 0x18,
|
||||
0x7E, 0x07, 0x80, 0x31, 0x87, 0x30, 0x67, 0x1C, 0x7F, 0x07, 0xC0, 0x21,
|
||||
0x0C, 0xC1, 0xE0, 0x70, 0x00, 0x07, 0x87, 0xFB, 0x86, 0xC1, 0xB0, 0x0F,
|
||||
0x01, 0xFC, 0x0F, 0x80, 0x7C, 0x0F, 0x03, 0xF3, 0x9F, 0xE0, 0x80, 0x03,
|
||||
0xE0, 0x03, 0xFF, 0x01, 0x80, 0xE0, 0xC0, 0x0C, 0x61, 0xE1, 0xB0, 0xCC,
|
||||
0x6C, 0x61, 0x8F, 0x10, 0x63, 0x8C, 0x00, 0xE3, 0x00, 0x38, 0xC0, 0x0F,
|
||||
0x10, 0x63, 0xC6, 0x18, 0x90, 0xFC, 0x66, 0x1E, 0x30, 0xC0, 0x1C, 0x1C,
|
||||
0x0E, 0x01, 0xFE, 0x00, 0x08, 0x00, 0x39, 0xDB, 0x10, 0x67, 0x50, 0xA3,
|
||||
0x7F, 0x01, 0xFF, 0xF8, 0x00, 0x18, 0xDC, 0xF8, 0xC8, 0x47, 0x31, 0xCE,
|
||||
0x23, 0xFF, 0xFF, 0xFF, 0x00, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x30,
|
||||
0xFC, 0x03, 0xE0, 0x03, 0xFF, 0x01, 0x80, 0xE0, 0xC0, 0x0C, 0x67, 0xF1,
|
||||
0xB1, 0x8E, 0x6C, 0x61, 0x8F, 0x18, 0x63, 0x86, 0x38, 0xE1, 0xFC, 0x38,
|
||||
0x61, 0x8F, 0x18, 0x63, 0xC6, 0x18, 0x91, 0x86, 0x66, 0x60, 0xF0, 0xC0,
|
||||
0x1C, 0x1C, 0x0E, 0x01, 0xFE, 0x00, 0x08, 0x00, 0xFF, 0xF0, 0x7D, 0x8A,
|
||||
0x1C, 0x38, 0x7F, 0x8E, 0x00, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
|
||||
0x0F, 0xFF, 0xFF, 0xF0, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xF0, 0x3C, 0x66, 0x43, 0x43, 0x02, 0x0E, 0x38, 0x60,
|
||||
0x40, 0xFF, 0x3C, 0x66, 0x42, 0x02, 0x1E, 0x1E, 0x03, 0xC3, 0x43, 0x7E,
|
||||
0x00, 0x08, 0xC0, 0x6C, 0x01, 0xC0, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00,
|
||||
0xE0, 0x0E, 0x00, 0x60, 0x07, 0x00, 0x70, 0x07, 0x00, 0x70, 0x03, 0x80,
|
||||
0x38, 0x03, 0x80, 0x38, 0x01, 0x80, 0x1C, 0x01, 0xC0, 0x0F, 0xFF, 0xFF,
|
||||
0xFC, 0xC0, 0xD8, 0x1B, 0x03, 0x60, 0x6C, 0x0D, 0x81, 0xB0, 0x36, 0x06,
|
||||
0xC1, 0xD8, 0x3B, 0x07, 0x71, 0xEF, 0xEF, 0xA0, 0x30, 0x06, 0x00, 0xC0,
|
||||
0x18, 0x00, 0x03, 0xF3, 0xFF, 0x7E, 0x47, 0xE4, 0xFE, 0x4F, 0xE4, 0xFE,
|
||||
0x4F, 0xE4, 0x7E, 0x47, 0xE4, 0x3E, 0x40, 0xE4, 0x06, 0x40, 0x64, 0x06,
|
||||
0x40, 0x64, 0x06, 0x40, 0x64, 0x06, 0x40, 0x64, 0x06, 0x40, 0x64, 0xFF,
|
||||
0x80, 0x21, 0x0C, 0xC1, 0xE0, 0x30, 0x00, 0x3F, 0xFF, 0xFC, 0x06, 0x03,
|
||||
0x81, 0xC0, 0xE0, 0x30, 0x18, 0x0C, 0x07, 0x03, 0x80, 0xFF, 0xFF, 0xF0,
|
||||
0x33, 0xF3, 0x33, 0x33, 0x33, 0x38, 0xDB, 0x1C, 0x38, 0x70, 0xF1, 0x3E,
|
||||
0x01, 0xFF, 0xF8, 0xC4, 0x73, 0x8C, 0xE2, 0x13, 0x1F, 0x3B, 0x18, 0x00,
|
||||
0x07, 0x8F, 0xFC, 0x7F, 0xBF, 0xF3, 0x87, 0xC0, 0x1C, 0x0F, 0x00, 0x60,
|
||||
0x1C, 0x01, 0x80, 0x30, 0x0E, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xC0, 0x0F,
|
||||
0xFF, 0x00, 0x3F, 0xFC, 0x00, 0xC0, 0x30, 0x03, 0x00, 0xE0, 0x0C, 0x01,
|
||||
0x80, 0x30, 0x06, 0x01, 0xC0, 0x1C, 0x0F, 0x00, 0x3F, 0xEF, 0xFC, 0x3F,
|
||||
0x3F, 0xF0, 0x1F, 0x07, 0x83, 0xF9, 0xFE, 0x71, 0xF8, 0x7E, 0x0F, 0x03,
|
||||
0xC0, 0x60, 0x3C, 0x06, 0x03, 0xC0, 0x7F, 0xFC, 0x06, 0x00, 0xC0, 0x60,
|
||||
0x0C, 0x07, 0x03, 0x60, 0xF0, 0x77, 0xBF, 0xCE, 0x3F, 0x9F, 0xC0, 0x40,
|
||||
0x20, 0x06, 0x60, 0x06, 0x60, 0x00, 0x00, 0xE0, 0x07, 0x70, 0x06, 0x30,
|
||||
0x0E, 0x38, 0x1C, 0x18, 0x18, 0x1C, 0x38, 0x0E, 0x30, 0x06, 0x70, 0x07,
|
||||
0x60, 0x03, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x0C, 0x03, 0x00, 0xC0, 0x00,
|
||||
0x00, 0x03, 0x00, 0xC0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x00, 0xC0, 0xF0,
|
||||
0x3C, 0x0F, 0x86, 0x7F, 0x87, 0x80, 0x07, 0x00, 0x03, 0x00, 0x01, 0x80,
|
||||
0x00, 0x00, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x60,
|
||||
0x06, 0x60, 0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x38, 0x18, 0x18,
|
||||
0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x70, 0x0E, 0x60, 0x06,
|
||||
0x60, 0x07, 0x00, 0xE0, 0x00, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x01, 0xC0,
|
||||
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x60, 0x06, 0x60, 0x0E, 0x70,
|
||||
0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8, 0x3F, 0xFC,
|
||||
0x30, 0x0C, 0x30, 0x0C, 0x70, 0x0E, 0x60, 0x06, 0x60, 0x07, 0x03, 0xC0,
|
||||
0x03, 0xC0, 0x06, 0x60, 0x00, 0x00, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
|
||||
0x03, 0xE0, 0x06, 0x60, 0x06, 0x60, 0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30,
|
||||
0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C,
|
||||
0x70, 0x0E, 0x60, 0x06, 0x60, 0x07, 0x07, 0xB0, 0x0D, 0xE0, 0x00, 0x00,
|
||||
0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xE0, 0x06, 0x60, 0x06, 0x60,
|
||||
0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8,
|
||||
0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x70, 0x0E, 0x60, 0x06, 0x60, 0x07,
|
||||
0x06, 0x60, 0x06, 0x60, 0x00, 0x00, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0,
|
||||
0x03, 0xE0, 0x06, 0x60, 0x06, 0x60, 0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30,
|
||||
0x1C, 0x38, 0x18, 0x18, 0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C,
|
||||
0x70, 0x0E, 0x60, 0x06, 0x60, 0x07, 0x03, 0xC0, 0x03, 0x40, 0x06, 0x60,
|
||||
0x03, 0xC0, 0x01, 0x80, 0x01, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xE0,
|
||||
0x06, 0x60, 0x06, 0x60, 0x0E, 0x70, 0x0C, 0x30, 0x0C, 0x30, 0x1C, 0x38,
|
||||
0x18, 0x18, 0x1F, 0xF8, 0x3F, 0xFC, 0x30, 0x0C, 0x30, 0x0C, 0x70, 0x0E,
|
||||
0x60, 0x06, 0x60, 0x07, 0x01, 0xFF, 0xFC, 0x03, 0xFF, 0xF8, 0x06, 0x60,
|
||||
0x00, 0x18, 0xC0, 0x00, 0x31, 0x80, 0x00, 0xE3, 0x00, 0x01, 0x86, 0x00,
|
||||
0x03, 0x0C, 0x00, 0x0C, 0x1F, 0xFC, 0x18, 0x3F, 0xF8, 0x70, 0x60, 0x00,
|
||||
0xFF, 0xC0, 0x01, 0xFF, 0x80, 0x07, 0x03, 0x00, 0x0C, 0x06, 0x00, 0x38,
|
||||
0x0C, 0x00, 0x60, 0x1F, 0xFF, 0xC0, 0x3F, 0xFC, 0x03, 0xC0, 0x1F, 0xF0,
|
||||
0xF0, 0xE1, 0x80, 0xE7, 0x00, 0xEC, 0x01, 0xF8, 0x00, 0x70, 0x00, 0xC0,
|
||||
0x01, 0x80, 0x03, 0x00, 0x07, 0x00, 0x06, 0x00, 0x6C, 0x01, 0xDC, 0x03,
|
||||
0x9C, 0x0E, 0x1F, 0x78, 0x1F, 0xE0, 0x04, 0x00, 0x0C, 0x00, 0x0C, 0x00,
|
||||
0x18, 0x01, 0xF0, 0x00, 0x1C, 0x00, 0x30, 0x00, 0x80, 0x00, 0x0F, 0xFF,
|
||||
0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F,
|
||||
0xFF, 0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80,
|
||||
0x0F, 0xFF, 0xFF, 0xFC, 0x03, 0x80, 0x18, 0x01, 0x80, 0x00, 0x0F, 0xFF,
|
||||
0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F,
|
||||
0xFF, 0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80,
|
||||
0x0F, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x6C, 0x06, 0x60, 0x00, 0x0F, 0xFF,
|
||||
0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F,
|
||||
0xFF, 0x7F, 0xFB, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80,
|
||||
0x0F, 0xFF, 0xFF, 0xFC, 0x1D, 0xC0, 0xEE, 0x00, 0x01, 0xFF, 0xEF, 0xFF,
|
||||
0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0xFF, 0xEF,
|
||||
0xFF, 0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0x80, 0xE1, 0x84, 0x13, 0x9C, 0xE7, 0x39, 0xCE, 0x73, 0x9C,
|
||||
0xE7, 0x39, 0xCE, 0x73, 0x9C, 0x33, 0x30, 0x0E, 0x73, 0x9C, 0xE7, 0x39,
|
||||
0xCE, 0x73, 0x9C, 0xE7, 0x39, 0xCE, 0x70, 0x38, 0xD9, 0x14, 0x03, 0x87,
|
||||
0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1,
|
||||
0xC3, 0x87, 0x00, 0xEF, 0xDC, 0x01, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70,
|
||||
0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0x80, 0x3F, 0x80,
|
||||
0x3F, 0xF8, 0x30, 0x7C, 0x30, 0x0E, 0x30, 0x06, 0x30, 0x06, 0x30, 0x07,
|
||||
0x30, 0x03, 0xFF, 0x03, 0xFF, 0x03, 0x30, 0x03, 0x30, 0x03, 0x30, 0x07,
|
||||
0x30, 0x06, 0x30, 0x0E, 0x30, 0x1C, 0x3F, 0xF8, 0x3F, 0xF0, 0x0C, 0x40,
|
||||
0x7F, 0x01, 0x08, 0x30, 0x07, 0xE0, 0x1F, 0xC0, 0x7F, 0x01, 0xFE, 0x07,
|
||||
0xD8, 0x1F, 0x30, 0x7C, 0xE1, 0xF1, 0x87, 0xC3, 0x1F, 0x0E, 0x7C, 0x19,
|
||||
0xF0, 0x77, 0xC0, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x1C, 0x07,
|
||||
0x00, 0x00, 0xC0, 0x00, 0x20, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x7F, 0xC0,
|
||||
0xF8, 0xF0, 0x70, 0x1C, 0x70, 0x07, 0x30, 0x01, 0xB8, 0x00, 0xD8, 0x00,
|
||||
0x7C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x07, 0xE0, 0x03, 0x30,
|
||||
0x01, 0x9C, 0x01, 0xC7, 0x01, 0xC1, 0xF7, 0xC0, 0x7F, 0xC0, 0x02, 0x00,
|
||||
0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x7F,
|
||||
0xC0, 0xF8, 0xF0, 0x70, 0x1C, 0x70, 0x07, 0x30, 0x01, 0xB8, 0x00, 0xD8,
|
||||
0x00, 0x7C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x07, 0xE0, 0x03,
|
||||
0x30, 0x01, 0x9C, 0x01, 0xC7, 0x01, 0xC1, 0xF7, 0xC0, 0x7F, 0xC0, 0x02,
|
||||
0x00, 0x01, 0xC0, 0x01, 0xB0, 0x01, 0x88, 0x00, 0x00, 0x00, 0x3E, 0x00,
|
||||
0x7F, 0xC0, 0xF8, 0xF0, 0x70, 0x1C, 0x70, 0x07, 0x30, 0x01, 0xB8, 0x00,
|
||||
0xD8, 0x00, 0x7C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x07, 0x80, 0x07, 0xE0,
|
||||
0x03, 0x30, 0x01, 0x9C, 0x01, 0xC7, 0x01, 0xC1, 0xF7, 0xC0, 0x7F, 0xC0,
|
||||
0x02, 0x00, 0x07, 0xB0, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF,
|
||||
0x81, 0xF1, 0xE0, 0xE0, 0x38, 0xE0, 0x0E, 0x60, 0x03, 0x70, 0x01, 0xB0,
|
||||
0x00, 0xF8, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F, 0xC0, 0x06,
|
||||
0x60, 0x03, 0x38, 0x03, 0x8E, 0x03, 0x83, 0xEF, 0x80, 0xFF, 0x80, 0x04,
|
||||
0x00, 0x07, 0x70, 0x03, 0xB8, 0x00, 0x00, 0x00, 0x7C, 0x00, 0xFF, 0x81,
|
||||
0xF1, 0xE0, 0xE0, 0x38, 0xE0, 0x0E, 0x60, 0x03, 0x70, 0x01, 0xB0, 0x00,
|
||||
0xF8, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x0F, 0x00, 0x0F, 0xC0, 0x06, 0x60,
|
||||
0x03, 0x38, 0x03, 0x8E, 0x03, 0x83, 0xEF, 0x80, 0xFF, 0x80, 0x04, 0x00,
|
||||
0x40, 0x98, 0x63, 0x30, 0x78, 0x0C, 0x07, 0x83, 0x31, 0x86, 0x40, 0x80,
|
||||
0x03, 0xC1, 0x87, 0xFD, 0x8F, 0x8F, 0x86, 0x01, 0xC7, 0x00, 0xF7, 0x00,
|
||||
0xDB, 0x00, 0xCD, 0x80, 0xC7, 0xC0, 0xC3, 0xE0, 0xC1, 0xF0, 0xC0, 0xF8,
|
||||
0xC0, 0x7E, 0xC0, 0x33, 0xC0, 0x19, 0xC0, 0x18, 0x70, 0x1C, 0x5F, 0x7C,
|
||||
0x67, 0xFC, 0x00, 0x20, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x0C,
|
||||
0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80,
|
||||
0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF8, 0x06,
|
||||
0xC0, 0x77, 0xDF, 0x1F, 0xF0, 0x08, 0x00, 0x01, 0xC0, 0x18, 0x00, 0x80,
|
||||
0x08, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00, 0xF0,
|
||||
0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E, 0x00,
|
||||
0xF8, 0x06, 0xC0, 0x77, 0xDF, 0x1F, 0xF0, 0x08, 0x00, 0x07, 0x00, 0x2C,
|
||||
0x03, 0x30, 0x00, 0x0C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1E,
|
||||
0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0,
|
||||
0x1E, 0x00, 0xF8, 0x06, 0xC0, 0x77, 0xDF, 0x1F, 0xF0, 0x08, 0x00, 0x0C,
|
||||
0xC0, 0x66, 0x00, 0x01, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03,
|
||||
0xC0, 0x1E, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x01, 0xE0, 0x0F, 0x00, 0x78,
|
||||
0x03, 0xC0, 0x1F, 0x00, 0xD8, 0x0E, 0xFB, 0xE3, 0xFE, 0x01, 0x00, 0x00,
|
||||
0xE0, 0x00, 0xC0, 0x01, 0x80, 0x00, 0x00, 0xE0, 0x07, 0x70, 0x06, 0x30,
|
||||
0x0E, 0x38, 0x1C, 0x18, 0x18, 0x1C, 0x38, 0x0E, 0x30, 0x06, 0x70, 0x07,
|
||||
0x60, 0x03, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xC0, 0x06, 0x00, 0x30, 0x01,
|
||||
0xFE, 0x0F, 0xFE, 0x60, 0x7B, 0x00, 0xD8, 0x07, 0xC0, 0x3E, 0x01, 0xF0,
|
||||
0x0D, 0x83, 0xEF, 0xFE, 0x60, 0x03, 0x00, 0x18, 0x00, 0xC0, 0x06, 0x00,
|
||||
0x00, 0x7F, 0x8F, 0x3C, 0xC0, 0xEC, 0x06, 0xC0, 0x6C, 0x0E, 0xC1, 0xCC,
|
||||
0x78, 0xC7, 0xEC, 0x06, 0xC0, 0x7C, 0x07, 0xC0, 0x7C, 0x06, 0xC0, 0x6C,
|
||||
0xFC, 0xCF, 0x80, 0x1C, 0x00, 0xC0, 0x06, 0x00, 0x00, 0x1F, 0x07, 0xFC,
|
||||
0x60, 0xC6, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C,
|
||||
0xC0, 0xCE, 0x3E, 0x7E, 0x70, 0x02, 0x03, 0x00, 0x60, 0x0C, 0x00, 0x00,
|
||||
0x1F, 0x07, 0xFC, 0x60, 0xC6, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xC7, 0x8C,
|
||||
0xE0, 0xCC, 0x0C, 0xC0, 0xCE, 0x3E, 0x7E, 0x70, 0x02, 0x0E, 0x01, 0xB0,
|
||||
0x11, 0x80, 0x00, 0x1F, 0x07, 0xFC, 0x60, 0xC6, 0x0C, 0x00, 0xC0, 0x1C,
|
||||
0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C, 0xC0, 0xCE, 0x3E, 0x7E, 0x70, 0x02,
|
||||
0x1C, 0x83, 0xF8, 0x00, 0x00, 0x00, 0x1F, 0x07, 0xFC, 0x60, 0xC6, 0x0C,
|
||||
0x00, 0xC0, 0x1C, 0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C, 0xC0, 0xCE, 0x3E,
|
||||
0x7E, 0x70, 0x02, 0x3B, 0x83, 0xB8, 0x00, 0x00, 0x00, 0x1F, 0x07, 0xFC,
|
||||
0x60, 0xC6, 0x0C, 0x00, 0xC0, 0x1C, 0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C,
|
||||
0xC0, 0xCE, 0x3E, 0x7E, 0x70, 0x02, 0x04, 0x00, 0xF0, 0x19, 0x01, 0xB0,
|
||||
0x0F, 0x00, 0x00, 0x1F, 0x07, 0xFC, 0x60, 0xC6, 0x0C, 0x00, 0xC0, 0x1C,
|
||||
0x3F, 0xC7, 0x8C, 0xE0, 0xCC, 0x0C, 0xC0, 0xCE, 0x3E, 0x7E, 0x70, 0x02,
|
||||
0x1F, 0x0F, 0x0F, 0xF7, 0xF9, 0x83, 0xC3, 0xB0, 0x70, 0x30, 0x0C, 0x06,
|
||||
0x03, 0x80, 0xCF, 0xFF, 0xFB, 0xC6, 0x00, 0xE0, 0xC0, 0x18, 0x1C, 0x0F,
|
||||
0x03, 0x83, 0xF1, 0xDC, 0xE7, 0xE3, 0xF8, 0x00, 0x08, 0x00, 0x1F, 0x0F,
|
||||
0xE6, 0x1F, 0x83, 0xC0, 0xF0, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x3E, 0x0D,
|
||||
0xC7, 0x3F, 0x83, 0x00, 0xC0, 0x0C, 0x03, 0x0F, 0x80, 0x38, 0x03, 0x80,
|
||||
0x30, 0x03, 0x00, 0x00, 0x1E, 0x0F, 0xF3, 0x86, 0x60, 0x78, 0x0F, 0x01,
|
||||
0xFF, 0xFC, 0x01, 0x80, 0x30, 0x1B, 0x07, 0x79, 0xC7, 0xF0, 0x10, 0x00,
|
||||
0x03, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, 0x1E, 0x0F, 0xF3, 0x86, 0x60,
|
||||
0x78, 0x0F, 0x01, 0xFF, 0xFC, 0x01, 0x80, 0x30, 0x1B, 0x07, 0x79, 0xC7,
|
||||
0xF0, 0x10, 0x00, 0x0F, 0x03, 0x60, 0x66, 0x00, 0x00, 0xF0, 0x7F, 0x9C,
|
||||
0x33, 0x03, 0xC0, 0x78, 0x0F, 0xFF, 0xE0, 0x0C, 0x01, 0x80, 0xD8, 0x3B,
|
||||
0xCE, 0x3F, 0x80, 0x80, 0x19, 0x83, 0x30, 0x00, 0x00, 0x00, 0xF0, 0x7F,
|
||||
0x9C, 0x33, 0x03, 0xC0, 0x78, 0x0F, 0xFF, 0xE0, 0x0C, 0x01, 0x80, 0xD8,
|
||||
0x3B, 0xCE, 0x3F, 0x80, 0x80, 0xE3, 0x0C, 0x30, 0x18, 0xC6, 0x31, 0x8C,
|
||||
0x63, 0x18, 0xC6, 0x31, 0x80, 0x39, 0x99, 0x80, 0x31, 0x8C, 0x63, 0x18,
|
||||
0xC6, 0x31, 0x8C, 0x63, 0x00, 0x30, 0xF1, 0xB6, 0x20, 0x06, 0x0C, 0x18,
|
||||
0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xCF, 0x30, 0x00,
|
||||
0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0x20, 0x07,
|
||||
0xE0, 0x70, 0x3F, 0x00, 0x30, 0x3F, 0x0F, 0xF3, 0x8E, 0xE0, 0xF8, 0x0F,
|
||||
0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1B, 0x07, 0x7B, 0xC7, 0xF0, 0x10,
|
||||
0x00, 0x39, 0x1F, 0xC4, 0x20, 0x00, 0xCF, 0x3F, 0xEE, 0x1F, 0x03, 0xC0,
|
||||
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xC0, 0x38,
|
||||
0x03, 0x00, 0x30, 0x03, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8,
|
||||
0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1B, 0x07, 0x7B, 0xC7, 0xF0,
|
||||
0x10, 0x00, 0x03, 0x80, 0xE0, 0x18, 0x06, 0x00, 0x00, 0x3E, 0x0F, 0xE3,
|
||||
0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1B, 0x07,
|
||||
0x7B, 0xC7, 0xF0, 0x10, 0x00, 0x0E, 0x01, 0xC0, 0x6C, 0x18, 0xC0, 0x00,
|
||||
0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80,
|
||||
0xF0, 0x1B, 0x07, 0x7B, 0xC7, 0xF0, 0x10, 0x00, 0x1C, 0x87, 0xF0, 0x00,
|
||||
0x00, 0x01, 0xF0, 0x7F, 0x1C, 0x77, 0x07, 0xC0, 0x78, 0x0F, 0x01, 0xE0,
|
||||
0x3C, 0x07, 0x80, 0xD8, 0x3B, 0xDE, 0x3F, 0x80, 0x80, 0x3B, 0x87, 0x70,
|
||||
0xEE, 0x00, 0x00, 0x00, 0x3E, 0x0F, 0xE3, 0x8E, 0xE0, 0xF8, 0x0F, 0x01,
|
||||
0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1B, 0x07, 0x7B, 0xC7, 0xF0, 0x10, 0x00,
|
||||
0x06, 0x00, 0x60, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x60, 0x06, 0x00, 0x0F, 0x80, 0xFE, 0x8E, 0x38, 0xE0, 0xE6,
|
||||
0x0B, 0x30, 0x99, 0x8C, 0xCC, 0xC6, 0x6C, 0x33, 0x41, 0x8C, 0x1C, 0x79,
|
||||
0xC5, 0xFC, 0x01, 0x00, 0x70, 0x0C, 0x01, 0x80, 0x30, 0x00, 0x30, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7C, 0x1F, 0x07,
|
||||
0xE3, 0xDF, 0xB1, 0x00, 0x07, 0x03, 0x80, 0xC0, 0x60, 0x00, 0x30, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7C, 0x1F, 0x07,
|
||||
0xE3, 0xDF, 0xB1, 0x00, 0x1C, 0x07, 0x03, 0x60, 0x8C, 0x00, 0x30, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7C, 0x1F, 0x07,
|
||||
0xE3, 0xDF, 0xB1, 0x00, 0x77, 0x1D, 0xC7, 0x70, 0x00, 0x00, 0x30, 0x3C,
|
||||
0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x7C, 0x1F, 0x07,
|
||||
0xE3, 0xDF, 0xB1, 0x00, 0x03, 0x80, 0x60, 0x18, 0x06, 0x00, 0x00, 0xC0,
|
||||
0xD8, 0x1B, 0x03, 0x30, 0xC6, 0x18, 0xC7, 0x0C, 0xC1, 0x98, 0x37, 0x03,
|
||||
0xC0, 0x78, 0x0E, 0x00, 0xC0, 0x18, 0x06, 0x00, 0xC0, 0xF0, 0x1E, 0x00,
|
||||
0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xCF, 0x0D, 0xFC, 0xF0, 0xCE, 0x06,
|
||||
0xE0, 0x6C, 0x06, 0xC0, 0x7C, 0x07, 0xC0, 0x6E, 0x06, 0xE0, 0xEF, 0x9C,
|
||||
0xDF, 0x8C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x0C, 0x00, 0x19, 0x83, 0x30,
|
||||
0x66, 0x00, 0x00, 0x00, 0xC0, 0xD8, 0x1B, 0x03, 0x30, 0xC6, 0x18, 0xC7,
|
||||
0x0C, 0xC1, 0x98, 0x37, 0x03, 0xC0, 0x78, 0x0E, 0x00, 0xC0, 0x18, 0x06,
|
||||
0x00, 0xC0, 0xF0, 0x1E, 0x00 };
|
||||
|
||||
const GFXglyph FreeSans12pt8bGlyphs[] PROGMEM = {
|
||||
{ 0, 1, 1, 7, 0, 0 }, // 0x20 ' ' U+0020
|
||||
{ 1, 2, 18, 7, 3, -17 }, // 0x21 '!' U+0021
|
||||
{ 6, 6, 6, 9, 1, -16 }, // 0x22 '"' U+0022
|
||||
{ 11, 13, 17, 13, 0, -16 }, // 0x23 '#' U+0023
|
||||
{ 39, 11, 21, 13, 1, -17 }, // 0x24 '$' U+0024
|
||||
{ 68, 20, 17, 21, 1, -16 }, // 0x25 '%' U+0025
|
||||
{ 111, 14, 18, 16, 1, -16 }, // 0x26 '&' U+0026
|
||||
{ 143, 2, 6, 5, 1, -16 }, // 0x27 ''' U+0027
|
||||
{ 145, 5, 23, 8, 2, -17 }, // 0x28 '(' U+0028
|
||||
{ 160, 5, 23, 8, 1, -17 }, // 0x29 ')' U+0029
|
||||
{ 175, 7, 7, 9, 1, -17 }, // 0x2a '*' U+002A
|
||||
{ 182, 12, 11, 14, 1, -10 }, // 0x2b '+' U+002B
|
||||
{ 199, 3, 7, 7, 2, -2 }, // 0x2c ',' U+002C
|
||||
{ 202, 6, 1, 8, 1, -6 }, // 0x2d '-' U+002D
|
||||
{ 203, 3, 3, 7, 2, -2 }, // 0x2e '.' U+002E
|
||||
{ 205, 7, 18, 7, 0, -17 }, // 0x2f '/' U+002F
|
||||
{ 221, 11, 18, 13, 1, -16 }, // 0x30 '0' U+0030
|
||||
{ 246, 6, 17, 13, 2, -16 }, // 0x31 '1' U+0031
|
||||
{ 259, 11, 17, 13, 1, -16 }, // 0x32 '2' U+0032
|
||||
{ 283, 11, 18, 13, 1, -16 }, // 0x33 '3' U+0033
|
||||
{ 308, 11, 17, 13, 1, -16 }, // 0x34 '4' U+0034
|
||||
{ 332, 11, 18, 13, 1, -16 }, // 0x35 '5' U+0035
|
||||
{ 357, 11, 18, 13, 1, -16 }, // 0x36 '6' U+0036
|
||||
{ 382, 11, 17, 13, 1, -16 }, // 0x37 '7' U+0037
|
||||
{ 406, 11, 18, 13, 1, -16 }, // 0x38 '8' U+0038
|
||||
{ 431, 11, 18, 13, 1, -16 }, // 0x39 '9' U+0039
|
||||
{ 456, 2, 13, 7, 3, -12 }, // 0x3a ':' U+003A
|
||||
{ 460, 2, 17, 7, 3, -12 }, // 0x3b ';' U+003B
|
||||
{ 465, 12, 11, 14, 1, -10 }, // 0x3c '<' U+003C
|
||||
{ 482, 12, 5, 14, 1, -7 }, // 0x3d '=' U+003D
|
||||
{ 490, 12, 11, 14, 1, -10 }, // 0x3e '>' U+003E
|
||||
{ 507, 10, 18, 13, 2, -17 }, // 0x3f '?' U+003F
|
||||
{ 530, 22, 21, 24, 1, -17 }, // 0x40 '@' U+0040
|
||||
{ 588, 16, 18, 16, 0, -17 }, // 0x41 'A' U+0041
|
||||
{ 624, 13, 18, 16, 2, -17 }, // 0x42 'B' U+0042
|
||||
{ 654, 15, 19, 17, 1, -17 }, // 0x43 'C' U+0043
|
||||
{ 690, 14, 18, 17, 2, -17 }, // 0x44 'D' U+0044
|
||||
{ 722, 13, 18, 16, 2, -17 }, // 0x45 'E' U+0045
|
||||
{ 752, 12, 18, 15, 2, -17 }, // 0x46 'F' U+0046
|
||||
{ 779, 16, 19, 19, 1, -17 }, // 0x47 'G' U+0047
|
||||
{ 817, 13, 18, 17, 2, -17 }, // 0x48 'H' U+0048
|
||||
{ 847, 3, 18, 7, 2, -17 }, // 0x49 'I' U+0049
|
||||
{ 854, 10, 19, 12, 0, -17 }, // 0x4a 'J' U+004A
|
||||
{ 878, 14, 18, 16, 2, -17 }, // 0x4b 'K' U+004B
|
||||
{ 910, 11, 18, 13, 2, -17 }, // 0x4c 'L' U+004C
|
||||
{ 935, 16, 18, 20, 2, -17 }, // 0x4d 'M' U+004D
|
||||
{ 971, 14, 18, 17, 2, -17 }, // 0x4e 'N' U+004E
|
||||
{ 1003, 17, 19, 19, 1, -17 }, // 0x4f 'O' U+004F
|
||||
{ 1044, 13, 18, 16, 2, -17 }, // 0x50 'P' U+0050
|
||||
{ 1074, 17, 19, 19, 1, -17 }, // 0x51 'Q' U+0051
|
||||
{ 1115, 14, 18, 17, 2, -17 }, // 0x52 'R' U+0052
|
||||
{ 1147, 14, 19, 16, 1, -17 }, // 0x53 'S' U+0053
|
||||
{ 1181, 14, 18, 15, 0, -17 }, // 0x54 'T' U+0054
|
||||
{ 1213, 13, 19, 17, 2, -17 }, // 0x55 'U' U+0055
|
||||
{ 1244, 14, 18, 16, 1, -17 }, // 0x56 'V' U+0056
|
||||
{ 1276, 21, 18, 23, 1, -17 }, // 0x57 'W' U+0057
|
||||
{ 1324, 15, 18, 16, 1, -17 }, // 0x58 'X' U+0058
|
||||
{ 1358, 16, 18, 16, 0, -17 }, // 0x59 'Y' U+0059
|
||||
{ 1394, 13, 18, 15, 1, -17 }, // 0x5a 'Z' U+005A
|
||||
{ 1424, 4, 23, 7, 2, -17 }, // 0x5b '[' U+005B
|
||||
{ 1436, 7, 18, 7, 0, -17 }, // 0x5c '\' U+005C
|
||||
{ 1452, 4, 23, 7, 1, -17 }, // 0x5d ']' U+005D
|
||||
{ 1464, 9, 9, 11, 1, -16 }, // 0x5e '^' U+005E
|
||||
{ 1475, 15, 1, 13, -1, 4 }, // 0x5f '_' U+005F
|
||||
{ 1477, 5, 4, 8, 1, -17 }, // 0x60 '`' U+0060
|
||||
{ 1480, 12, 14, 13, 1, -12 }, // 0x61 'a' U+0061
|
||||
{ 1501, 12, 19, 13, 1, -17 }, // 0x62 'b' U+0062
|
||||
{ 1530, 10, 14, 12, 1, -12 }, // 0x63 'c' U+0063
|
||||
{ 1548, 11, 19, 13, 1, -17 }, // 0x64 'd' U+0064
|
||||
{ 1575, 11, 14, 13, 1, -12 }, // 0x65 'e' U+0065
|
||||
{ 1595, 6, 18, 7, 0, -17 }, // 0x66 'f' U+0066
|
||||
{ 1609, 11, 18, 13, 1, -12 }, // 0x67 'g' U+0067
|
||||
{ 1634, 10, 18, 13, 2, -17 }, // 0x68 'h' U+0068
|
||||
{ 1657, 2, 18, 5, 2, -17 }, // 0x69 'i' U+0069
|
||||
{ 1662, 4, 23, 5, 0, -17 }, // 0x6a 'j' U+006A
|
||||
{ 1674, 11, 18, 12, 1, -17 }, // 0x6b 'k' U+006B
|
||||
{ 1699, 2, 18, 5, 2, -17 }, // 0x6c 'l' U+006C
|
||||
{ 1704, 16, 13, 20, 2, -12 }, // 0x6d 'm' U+006D
|
||||
{ 1730, 10, 13, 13, 2, -12 }, // 0x6e 'n' U+006E
|
||||
{ 1747, 11, 14, 13, 1, -12 }, // 0x6f 'o' U+006F
|
||||
{ 1767, 12, 18, 13, 1, -12 }, // 0x70 'p' U+0070
|
||||
{ 1794, 11, 18, 13, 1, -12 }, // 0x71 'q' U+0071
|
||||
{ 1819, 6, 13, 8, 2, -12 }, // 0x72 'r' U+0072
|
||||
{ 1829, 10, 14, 12, 1, -12 }, // 0x73 's' U+0073
|
||||
{ 1847, 6, 17, 7, 0, -15 }, // 0x74 't' U+0074
|
||||
{ 1860, 10, 14, 13, 2, -12 }, // 0x75 'u' U+0075
|
||||
{ 1878, 12, 13, 12, 0, -12 }, // 0x76 'v' U+0076
|
||||
{ 1898, 17, 13, 17, 0, -12 }, // 0x77 'w' U+0077
|
||||
{ 1926, 11, 13, 12, 0, -12 }, // 0x78 'x' U+0078
|
||||
{ 1944, 11, 18, 12, 0, -12 }, // 0x79 'y' U+0079
|
||||
{ 1969, 10, 13, 12, 1, -12 }, // 0x7a 'z' U+007A
|
||||
{ 1986, 6, 23, 8, 1, -17 }, // 0x7b '{' U+007B
|
||||
{ 2004, 2, 23, 6, 2, -17 }, // 0x7c '|' U+007C
|
||||
{ 2010, 5, 23, 8, 1, -17 }, // 0x7d '}' U+007D
|
||||
{ 2025, 10, 5, 14, 2, -10 }, // 0x7e '~' U+007E
|
||||
{ 2032, 13, 18, 17, 2, -17 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370
|
||||
{ 2062, 1, 1, 7, 0, 0 }, // 0x80 'NO-BREAK SPACE' U+00A0
|
||||
{ 2063, 2, 18, 7, 3, -12 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1
|
||||
{ 2068, 11, 18, 13, 1, -14 }, // 0x82 'CENT SIGN' U+00A2
|
||||
{ 2093, 12, 19, 13, 1, -17 }, // 0x83 'POUND SIGN' U+00A3
|
||||
{ 2122, 14, 18, 16, 1, -16 }, // 0x84 'EURO SIGN *' U+20AC
|
||||
{ 2154, 13, 17, 13, 0, -16 }, // 0x85 'YEN SIGN' U+00A5
|
||||
{ 2182, 14, 23, 16, 1, -21 }, // 0x86 'LATIN CAPITAL LETTER S WITH CARON *' U+0160
|
||||
{ 2223, 11, 23, 13, 1, -17 }, // 0x87 'SECTION SIGN' U+00A7
|
||||
{ 2255, 10, 19, 12, 1, -17 }, // 0x88 'LATIN SMALL LETTER S WITH CARON *' U+0161
|
||||
{ 2279, 18, 19, 18, 0, -17 }, // 0x89 'COPYRIGHT SIGN' U+00A9
|
||||
{ 2322, 7, 11, 9, 1, -17 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA
|
||||
{ 2332, 9, 8, 11, 1, -10 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB
|
||||
{ 2341, 12, 7, 14, 1, -8 }, // 0x8c 'NOT SIGN' U+00AC
|
||||
{ 2352, 6, 1, 8, 1, -6 }, // 0x8d 'SOFT HYPHEN' U+00AD
|
||||
{ 2353, 18, 19, 18, 0, -17 }, // 0x8e 'REGISTERED SIGN' U+00AE
|
||||
{ 2396, 6, 2, 8, 1, -16 }, // 0x8f 'MACRON' U+00AF
|
||||
{ 2398, 7, 7, 15, 4, -15 }, // 0x90 'DEGREE SIGN' U+00B0
|
||||
{ 2405, 12, 15, 14, 1, -14 }, // 0x91 'PLUS-MINUS SIGN' U+00B1
|
||||
{ 2428, 8, 10, 8, 0, -16 }, // 0x92 'SUPERSCRIPT TWO' U+00B2
|
||||
{ 2438, 8, 11, 8, 0, -16 }, // 0x93 'SUPERSCRIPT THREE' U+00B3
|
||||
{ 2449, 13, 22, 15, 1, -21 }, // 0x94 'LATIN CAPITAL LETTER Z WITH CARON *' U+017D
|
||||
{ 2485, 11, 18, 13, 2, -12 }, // 0x95 'MICRO SIGN' U+00B5
|
||||
{ 2510, 12, 22, 13, 1, -17 }, // 0x96 'PILCROW SIGN' U+00B6
|
||||
{ 2543, 3, 3, 7, 2, -7 }, // 0x97 'MIDDLE DOT' U+00B7
|
||||
{ 2545, 10, 18, 12, 1, -17 }, // 0x98 'LATIN SMALL LETTER Z WITH CARON *' U+017E
|
||||
{ 2568, 4, 10, 8, 2, -16 }, // 0x99 'SUPERSCRIPT ONE' U+00B9
|
||||
{ 2573, 7, 11, 9, 1, -17 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA
|
||||
{ 2583, 9, 8, 11, 1, -9 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB
|
||||
{ 2592, 22, 18, 24, 1, -17 }, // 0x9c 'LATIN CAPITAL LIGATURE OE *' U+0152
|
||||
{ 2642, 20, 14, 23, 1, -12 }, // 0x9d 'LATIN SMALL LIGATURE OE *' U+0153
|
||||
{ 2677, 16, 21, 16, 0, -20 }, // 0x9e 'LATIN CAPITAL LETTER Y WITH DIAERESIS *' U+0178
|
||||
{ 2719, 10, 18, 13, 3, -12 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF
|
||||
{ 2742, 16, 22, 16, 0, -21 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0
|
||||
{ 2786, 16, 22, 16, 0, -21 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1
|
||||
{ 2830, 16, 22, 16, 0, -21 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2
|
||||
{ 2874, 16, 21, 16, 0, -20 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3
|
||||
{ 2916, 16, 21, 16, 0, -20 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4
|
||||
{ 2958, 16, 23, 16, 0, -22 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5
|
||||
{ 3004, 23, 18, 24, 0, -17 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6
|
||||
{ 3056, 15, 23, 17, 1, -17 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7
|
||||
{ 3100, 13, 22, 16, 2, -21 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8
|
||||
{ 3136, 13, 22, 16, 2, -21 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9
|
||||
{ 3172, 13, 22, 16, 2, -21 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA
|
||||
{ 3208, 13, 21, 16, 2, -20 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB
|
||||
{ 3243, 5, 22, 7, 0, -21 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC
|
||||
{ 3257, 5, 22, 7, 2, -21 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD
|
||||
{ 3271, 7, 22, 7, 0, -21 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE
|
||||
{ 3291, 7, 21, 7, 0, -20 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF
|
||||
{ 3310, 16, 18, 17, 0, -17 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0
|
||||
{ 3346, 14, 21, 17, 2, -20 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1
|
||||
{ 3383, 17, 23, 19, 1, -21 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2
|
||||
{ 3432, 17, 23, 19, 1, -21 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3
|
||||
{ 3481, 17, 23, 19, 1, -21 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4
|
||||
{ 3530, 17, 22, 19, 1, -20 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5
|
||||
{ 3577, 17, 22, 19, 1, -20 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6
|
||||
{ 3624, 10, 9, 14, 2, -9 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7
|
||||
{ 3636, 17, 19, 19, 1, -17 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8
|
||||
{ 3677, 13, 23, 17, 2, -21 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9
|
||||
{ 3715, 13, 23, 17, 2, -21 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA
|
||||
{ 3753, 13, 23, 17, 2, -21 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB
|
||||
{ 3791, 13, 22, 17, 2, -20 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC
|
||||
{ 3827, 16, 22, 16, 0, -21 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD
|
||||
{ 3871, 13, 18, 16, 2, -17 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE
|
||||
{ 3901, 12, 17, 15, 2, -16 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF
|
||||
{ 3927, 12, 18, 13, 1, -16 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0
|
||||
{ 3954, 12, 18, 13, 1, -16 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1
|
||||
{ 3981, 12, 18, 13, 1, -16 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2
|
||||
{ 4008, 12, 18, 13, 1, -16 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3
|
||||
{ 4035, 12, 18, 13, 1, -16 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4
|
||||
{ 4062, 12, 20, 13, 1, -18 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5
|
||||
{ 4092, 19, 14, 22, 1, -12 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6
|
||||
{ 4126, 10, 18, 12, 1, -12 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7
|
||||
{ 4149, 11, 19, 13, 1, -17 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8
|
||||
{ 4176, 11, 19, 13, 1, -17 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9
|
||||
{ 4203, 11, 18, 13, 1, -16 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA
|
||||
{ 4228, 11, 18, 13, 1, -16 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB
|
||||
{ 4253, 5, 18, 6, 0, -17 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC
|
||||
{ 4265, 5, 18, 6, 1, -17 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED
|
||||
{ 4277, 7, 18, 6, 0, -17 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE
|
||||
{ 4293, 6, 17, 6, 0, -16 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF
|
||||
{ 4306, 11, 19, 13, 1, -17 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0
|
||||
{ 4333, 10, 17, 13, 2, -16 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1
|
||||
{ 4355, 11, 19, 13, 1, -17 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2
|
||||
{ 4382, 11, 19, 13, 1, -17 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3
|
||||
{ 4409, 11, 19, 13, 1, -17 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4
|
||||
{ 4436, 11, 18, 13, 1, -16 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5
|
||||
{ 4461, 11, 19, 13, 1, -17 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6
|
||||
{ 4488, 12, 11, 14, 1, -10 }, // 0xd7 'DIVISION SIGN' U+00F7
|
||||
{ 4505, 13, 14, 15, 0, -12 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8
|
||||
{ 4528, 10, 19, 13, 2, -17 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9
|
||||
{ 4552, 10, 19, 13, 2, -17 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA
|
||||
{ 4576, 10, 19, 13, 2, -17 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB
|
||||
{ 4600, 10, 19, 13, 2, -17 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC
|
||||
{ 4624, 11, 23, 12, 0, -17 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD
|
||||
{ 4656, 12, 22, 13, 1, -16 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE
|
||||
{ 4689, 11, 23, 12, 0, -17 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF
|
||||
|
||||
const GFXfont FreeSans12pt8b PROGMEM = {
|
||||
(uint8_t *)FreeSans12pt8bBitmaps,
|
||||
(GFXglyph *)FreeSans12pt8bGlyphs,
|
||||
0x20, 0xDF, 33 };
|
||||
|
||||
// Approx. 6072 bytes
|
451
RX_FSK/src/fonts/FreeSans18pt7b.h
Normal file
451
RX_FSK/src/fonts/FreeSans18pt7b.h
Normal file
|
@ -0,0 +1,451 @@
|
|||
const uint8_t FreeSans18pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0x20, 0x3F, 0xFC, 0xE3, 0xF1,
|
||||
0xF8, 0xFC, 0x7E, 0x3F, 0x1F, 0x8E, 0x82, 0x41, 0x00, 0x01, 0xC3, 0x80,
|
||||
0x38, 0x70, 0x06, 0x0E, 0x00, 0xC1, 0x80, 0x38, 0x70, 0x07, 0x0E, 0x0F,
|
||||
0xFF, 0xF9, 0xFF, 0xFF, 0x3F, 0xFF, 0xE0, 0xE1, 0xC0, 0x1C, 0x38, 0x03,
|
||||
0x87, 0x00, 0x70, 0xE0, 0x0C, 0x18, 0x3F, 0xFF, 0xF7, 0xFF, 0xFE, 0xFF,
|
||||
0xFF, 0xC1, 0xC3, 0x80, 0x30, 0x60, 0x06, 0x0C, 0x01, 0xC3, 0x80, 0x38,
|
||||
0x70, 0x07, 0x0E, 0x00, 0xC1, 0x80, 0x03, 0x00, 0x0F, 0xC0, 0x3F, 0xF0,
|
||||
0x3F, 0xF8, 0x7B, 0x3C, 0xF3, 0x1C, 0xE3, 0x0E, 0xE3, 0x0E, 0xE3, 0x0E,
|
||||
0xE3, 0x00, 0xE3, 0x00, 0xF3, 0x00, 0x7B, 0x00, 0x7F, 0x80, 0x1F, 0xF0,
|
||||
0x07, 0xFC, 0x03, 0x7E, 0x03, 0x0F, 0x03, 0x07, 0xE3, 0x07, 0xE3, 0x07,
|
||||
0xE3, 0x07, 0xE3, 0x0F, 0x73, 0x3E, 0x7F, 0xFC, 0x3F, 0xF8, 0x0F, 0xE0,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x78, 0x00,
|
||||
0xE0, 0x0F, 0xF0, 0x06, 0x00, 0xFF, 0xC0, 0x70, 0x07, 0x0E, 0x07, 0x00,
|
||||
0x70, 0x38, 0x38, 0x03, 0x00, 0xC3, 0x80, 0x18, 0x06, 0x1C, 0x00, 0xE0,
|
||||
0x71, 0xC0, 0x03, 0x87, 0x8C, 0x00, 0x1F, 0xF8, 0xE0, 0x00, 0x7F, 0x86,
|
||||
0x00, 0x01, 0xF8, 0x70, 0x00, 0x00, 0x03, 0x03, 0xC0, 0x00, 0x38, 0x7F,
|
||||
0x80, 0x01, 0x87, 0xFE, 0x00, 0x1C, 0x38, 0x70, 0x00, 0xC3, 0x81, 0xC0,
|
||||
0x0E, 0x18, 0x06, 0x00, 0xE0, 0xC0, 0x30, 0x07, 0x07, 0x03, 0x80, 0x70,
|
||||
0x1C, 0x38, 0x03, 0x80, 0xFF, 0xC0, 0x38, 0x03, 0xFC, 0x01, 0x80, 0x07,
|
||||
0x80, 0x01, 0xF0, 0x00, 0x7F, 0x80, 0x0F, 0xFC, 0x01, 0xE1, 0xE0, 0x1C,
|
||||
0x0E, 0x01, 0xC0, 0xE0, 0x1C, 0x0E, 0x01, 0xE1, 0xE0, 0x0E, 0x3C, 0x00,
|
||||
0x77, 0x80, 0x07, 0xF0, 0x00, 0x7C, 0x00, 0x0F, 0xE0, 0x03, 0xCF, 0x1C,
|
||||
0x78, 0x79, 0xC7, 0x03, 0xDC, 0xE0, 0x1F, 0x8E, 0x00, 0xF8, 0xE0, 0x0F,
|
||||
0x0E, 0x00, 0x70, 0xF0, 0x0F, 0x87, 0xC3, 0xFC, 0x7F, 0xFD, 0xC3, 0xFF,
|
||||
0x0E, 0x0F, 0xC0, 0xF0, 0xFF, 0xFF, 0xFA, 0x40, 0x06, 0x06, 0x0C, 0x0C,
|
||||
0x18, 0x18, 0x38, 0x30, 0x70, 0x70, 0x70, 0x60, 0xE0, 0xE0, 0xE0, 0xE0,
|
||||
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x60, 0x70, 0x70, 0x70, 0x30, 0x38, 0x18,
|
||||
0x18, 0x0C, 0x0C, 0x06, 0x03, 0xC0, 0x60, 0x30, 0x30, 0x38, 0x18, 0x1C,
|
||||
0x0C, 0x0E, 0x0E, 0x0E, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x06, 0x0E, 0x0E, 0x0E, 0x0C, 0x1C, 0x18, 0x38, 0x30, 0x30,
|
||||
0x60, 0xC0, 0x0C, 0x03, 0x00, 0xC3, 0xB7, 0xFF, 0xC7, 0x81, 0xE0, 0xEC,
|
||||
0x73, 0x88, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x80, 0x01,
|
||||
0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0xFF,
|
||||
0xF6, 0xDA, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0xC0, 0x30, 0x18,
|
||||
0x06, 0x01, 0x80, 0xC0, 0x30, 0x0C, 0x06, 0x01, 0x80, 0x60, 0x30, 0x0C,
|
||||
0x03, 0x00, 0xC0, 0x60, 0x18, 0x06, 0x03, 0x00, 0xC0, 0x30, 0x18, 0x06,
|
||||
0x01, 0x80, 0xC0, 0x30, 0x00, 0x07, 0xE0, 0x0F, 0xF8, 0x1F, 0xFC, 0x3C,
|
||||
0x3C, 0x78, 0x1E, 0x70, 0x0E, 0x70, 0x0E, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
|
||||
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0,
|
||||
0x07, 0xE0, 0x07, 0xE0, 0x0F, 0x70, 0x0E, 0x70, 0x0E, 0x78, 0x1E, 0x3C,
|
||||
0x3C, 0x1F, 0xF8, 0x1F, 0xF0, 0x07, 0xE0, 0x03, 0x03, 0x07, 0x0F, 0x3F,
|
||||
0xFF, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0xE0, 0x1F, 0xF8,
|
||||
0x3F, 0xFC, 0x7C, 0x3E, 0x70, 0x0F, 0xF0, 0x0F, 0xE0, 0x07, 0xE0, 0x07,
|
||||
0x00, 0x07, 0x00, 0x07, 0x00, 0x0F, 0x00, 0x1E, 0x00, 0x3C, 0x00, 0xF8,
|
||||
0x03, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0x3C, 0x00, 0x38, 0x00, 0x70, 0x00,
|
||||
0x60, 0x00, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0xF0,
|
||||
0x07, 0xFE, 0x07, 0xFF, 0x87, 0x83, 0xC3, 0x80, 0xF3, 0x80, 0x39, 0xC0,
|
||||
0x1C, 0xE0, 0x0E, 0x00, 0x07, 0x00, 0x0F, 0x00, 0x7F, 0x00, 0x3F, 0x00,
|
||||
0x1F, 0xE0, 0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0x00, 0x03, 0xF0, 0x01,
|
||||
0xF8, 0x00, 0xFE, 0x00, 0x77, 0x00, 0x73, 0xE0, 0xF8, 0xFF, 0xF8, 0x3F,
|
||||
0xF8, 0x07, 0xF0, 0x00, 0x00, 0x38, 0x00, 0x38, 0x00, 0x78, 0x00, 0xF8,
|
||||
0x00, 0xF8, 0x01, 0xF8, 0x03, 0xB8, 0x03, 0x38, 0x07, 0x38, 0x0E, 0x38,
|
||||
0x1C, 0x38, 0x18, 0x38, 0x38, 0x38, 0x70, 0x38, 0x60, 0x38, 0xE0, 0x38,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38,
|
||||
0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x1F, 0xFF, 0x0F, 0xFF, 0x8F, 0xFF,
|
||||
0xC7, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x39,
|
||||
0xF0, 0x3F, 0xFE, 0x1F, 0xFF, 0x8F, 0x83, 0xE7, 0x00, 0xF0, 0x00, 0x3C,
|
||||
0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xFC, 0x00,
|
||||
0xEF, 0x00, 0x73, 0xC0, 0xF0, 0xFF, 0xF8, 0x3F, 0xF8, 0x07, 0xE0, 0x00,
|
||||
0x03, 0xE0, 0x0F, 0xF8, 0x1F, 0xFC, 0x3C, 0x1E, 0x38, 0x0E, 0x70, 0x0E,
|
||||
0x70, 0x00, 0x60, 0x00, 0xE0, 0x00, 0xE3, 0xE0, 0xEF, 0xF8, 0xFF, 0xFC,
|
||||
0xFC, 0x3E, 0xF0, 0x0E, 0xF0, 0x0F, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07,
|
||||
0x60, 0x07, 0x70, 0x0F, 0x70, 0x0E, 0x3C, 0x3E, 0x3F, 0xFC, 0x1F, 0xF8,
|
||||
0x07, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x06, 0x00, 0x0E,
|
||||
0x00, 0x1C, 0x00, 0x18, 0x00, 0x38, 0x00, 0x70, 0x00, 0x60, 0x00, 0xE0,
|
||||
0x00, 0xC0, 0x01, 0xC0, 0x01, 0x80, 0x03, 0x80, 0x03, 0x80, 0x07, 0x00,
|
||||
0x07, 0x00, 0x07, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x0C, 0x00,
|
||||
0x1C, 0x00, 0x1C, 0x00, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0xFF, 0x87, 0x83,
|
||||
0xC7, 0x80, 0xF3, 0x80, 0x39, 0xC0, 0x1C, 0xE0, 0x0E, 0x78, 0x0F, 0x1E,
|
||||
0x0F, 0x07, 0xFF, 0x01, 0xFF, 0x03, 0xFF, 0xE3, 0xE0, 0xF9, 0xC0, 0x1D,
|
||||
0xC0, 0x0F, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0xF7, 0x00,
|
||||
0x73, 0xE0, 0xF8, 0xFF, 0xF8, 0x3F, 0xF8, 0x07, 0xF0, 0x00, 0x07, 0xE0,
|
||||
0x1F, 0xF8, 0x3F, 0xFC, 0x7C, 0x3C, 0x70, 0x0E, 0xF0, 0x0E, 0xE0, 0x06,
|
||||
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x0F, 0x70, 0x0F, 0x78, 0x3F,
|
||||
0x3F, 0xFF, 0x1F, 0xF7, 0x07, 0xC7, 0x00, 0x07, 0x00, 0x06, 0x00, 0x0E,
|
||||
0x70, 0x0E, 0x70, 0x1C, 0x78, 0x3C, 0x3F, 0xF8, 0x1F, 0xF0, 0x07, 0xC0,
|
||||
0xFF, 0xF0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x80, 0xFF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x07, 0xFF, 0xB6, 0xD6, 0x00, 0x00, 0x80, 0x03, 0xC0, 0x07, 0xE0,
|
||||
0x0F, 0xC0, 0x3F, 0x80, 0x7E, 0x00, 0xFC, 0x01, 0xF0, 0x00, 0xE0, 0x00,
|
||||
0x7C, 0x00, 0x1F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x80, 0x07, 0xF0, 0x00,
|
||||
0x7E, 0x00, 0x0F, 0x00, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x80, 0x80, 0x00, 0x70, 0x00, 0x3E, 0x00, 0x0F, 0xE0, 0x00, 0xFC,
|
||||
0x00, 0x1F, 0xC0, 0x03, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0x80, 0x0F, 0xC0,
|
||||
0x1F, 0x80, 0x7F, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x01, 0xC0, 0x00,
|
||||
0x80, 0x00, 0x00, 0x0F, 0xC0, 0x7F, 0xE1, 0xFF, 0xE3, 0xC3, 0xEF, 0x01,
|
||||
0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0x00, 0x0E, 0x00, 0x38, 0x00, 0xF0,
|
||||
0x07, 0xC0, 0x1F, 0x00, 0x7C, 0x00, 0xE0, 0x03, 0xC0, 0x07, 0x00, 0x0E,
|
||||
0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x03, 0x80,
|
||||
0x07, 0x00, 0x0E, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0x00,
|
||||
0x00, 0xFF, 0xFF, 0xC0, 0x01, 0xF8, 0x0F, 0xE0, 0x03, 0xE0, 0x01, 0xF0,
|
||||
0x07, 0x80, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x3C, 0x1E, 0x00, 0x00, 0x1E,
|
||||
0x3C, 0x03, 0xE0, 0x1E, 0x38, 0x0F, 0xF3, 0x8E, 0x78, 0x1E, 0x3F, 0x0F,
|
||||
0x70, 0x38, 0x1F, 0x07, 0x70, 0x78, 0x0F, 0x07, 0xE0, 0x70, 0x0E, 0x07,
|
||||
0xE0, 0x70, 0x0E, 0x07, 0xE0, 0xE0, 0x0E, 0x07, 0xE0, 0xE0, 0x1C, 0x07,
|
||||
0xE0, 0xE0, 0x1C, 0x0E, 0xE0, 0xE0, 0x1C, 0x0E, 0xE0, 0xE0, 0x38, 0x1C,
|
||||
0xF0, 0x70, 0x78, 0x3C, 0x70, 0x78, 0xFC, 0x78, 0x78, 0x3F, 0xDF, 0xF0,
|
||||
0x38, 0x1F, 0x0F, 0xC0, 0x3C, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x80, 0x00, 0x00, 0x07, 0xF0, 0x0E, 0x00, 0x01, 0xFF, 0xFE, 0x00,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0xF8, 0x00, 0x03,
|
||||
0xE0, 0x00, 0x0F, 0xC0, 0x00, 0x7F, 0x00, 0x01, 0xDC, 0x00, 0x07, 0x78,
|
||||
0x00, 0x3C, 0xE0, 0x00, 0xE3, 0x80, 0x03, 0x8F, 0x00, 0x1E, 0x1C, 0x00,
|
||||
0x70, 0x70, 0x01, 0xC1, 0xE0, 0x0E, 0x03, 0x80, 0x38, 0x0E, 0x00, 0xE0,
|
||||
0x3C, 0x07, 0xFF, 0xF0, 0x1F, 0xFF, 0xE0, 0xFF, 0xFF, 0x83, 0xC0, 0x0E,
|
||||
0x0E, 0x00, 0x3C, 0x78, 0x00, 0xF1, 0xE0, 0x01, 0xC7, 0x00, 0x07, 0xBC,
|
||||
0x00, 0x1E, 0xF0, 0x00, 0x3B, 0x80, 0x00, 0xF0, 0xFF, 0xFC, 0x1F, 0xFF,
|
||||
0xE3, 0xFF, 0xFE, 0x70, 0x03, 0xCE, 0x00, 0x3D, 0xC0, 0x03, 0xB8, 0x00,
|
||||
0x77, 0x00, 0x0E, 0xE0, 0x01, 0xDC, 0x00, 0x73, 0x80, 0x1E, 0x7F, 0xFF,
|
||||
0x8F, 0xFF, 0xF1, 0xFF, 0xFF, 0x38, 0x00, 0xF7, 0x00, 0x0E, 0xE0, 0x00,
|
||||
0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x03,
|
||||
0xF8, 0x00, 0xF7, 0xFF, 0xFC, 0xFF, 0xFF, 0x1F, 0xFF, 0x80, 0x00, 0xFF,
|
||||
0x00, 0x0F, 0xFF, 0x00, 0xFF, 0xFE, 0x07, 0xE0, 0x7C, 0x3E, 0x00, 0x78,
|
||||
0xF0, 0x00, 0xE7, 0x80, 0x03, 0xDC, 0x00, 0x07, 0x70, 0x00, 0x03, 0x80,
|
||||
0x00, 0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x03, 0x80, 0x00,
|
||||
0x0E, 0x00, 0x00, 0x38, 0x00, 0x00, 0xE0, 0x00, 0x1D, 0xC0, 0x00, 0x77,
|
||||
0x00, 0x03, 0xDE, 0x00, 0x0E, 0x3C, 0x00, 0x78, 0xF8, 0x03, 0xC1, 0xF8,
|
||||
0x1F, 0x03, 0xFF, 0xF8, 0x03, 0xFF, 0xC0, 0x03, 0xF8, 0x00, 0xFF, 0xF8,
|
||||
0x0F, 0xFF, 0xE0, 0xFF, 0xFF, 0x0E, 0x00, 0xF8, 0xE0, 0x03, 0xCE, 0x00,
|
||||
0x1C, 0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x00, 0xFE, 0x00, 0x07, 0xE0,
|
||||
0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x07, 0xE0, 0x00, 0x7E,
|
||||
0x00, 0x07, 0xE0, 0x00, 0x7E, 0x00, 0x0F, 0xE0, 0x00, 0xEE, 0x00, 0x0E,
|
||||
0xE0, 0x01, 0xEE, 0x00, 0x3C, 0xE0, 0x0F, 0x8F, 0xFF, 0xF0, 0xFF, 0xFE,
|
||||
0x0F, 0xFF, 0x80, 0xFF, 0xFF, 0xBF, 0xFF, 0xEF, 0xFF, 0xFB, 0x80, 0x00,
|
||||
0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0, 0x00, 0x38,
|
||||
0x00, 0x0E, 0x00, 0x03, 0xFF, 0xFE, 0xFF, 0xFF, 0xBF, 0xFF, 0xEE, 0x00,
|
||||
0x03, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00,
|
||||
0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x0E, 0x00,
|
||||
0x07, 0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38,
|
||||
0x00, 0x1F, 0xFF, 0xCF, 0xFF, 0xE7, 0xFF, 0xF3, 0x80, 0x01, 0xC0, 0x00,
|
||||
0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,
|
||||
0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x00, 0x00, 0x7F,
|
||||
0x80, 0x03, 0xFF, 0xE0, 0x07, 0xFF, 0xF8, 0x0F, 0x80, 0xFC, 0x1E, 0x00,
|
||||
0x3E, 0x3C, 0x00, 0x0E, 0x78, 0x00, 0x0F, 0x70, 0x00, 0x07, 0x70, 0x00,
|
||||
0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x00, 0x00, 0xE0, 0x03,
|
||||
0xFF, 0xE0, 0x03, 0xFF, 0xE0, 0x03, 0xFF, 0xE0, 0x00, 0x07, 0xF0, 0x00,
|
||||
0x07, 0x70, 0x00, 0x07, 0x70, 0x00, 0x0F, 0x78, 0x00, 0x0F, 0x3C, 0x00,
|
||||
0x1F, 0x1E, 0x00, 0x3F, 0x0F, 0xC0, 0xF7, 0x07, 0xFF, 0xE7, 0x03, 0xFF,
|
||||
0xC3, 0x00, 0xFF, 0x03, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0,
|
||||
0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0,
|
||||
0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80,
|
||||
0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00,
|
||||
0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00,
|
||||
0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0,
|
||||
0x07, 0x00, 0x1C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x80, 0x7E,
|
||||
0x01, 0xF8, 0x07, 0xE0, 0x1F, 0xC0, 0xF7, 0x87, 0x9F, 0xFE, 0x3F, 0xF0,
|
||||
0x3F, 0x00, 0xE0, 0x01, 0xEE, 0x00, 0x3C, 0xE0, 0x07, 0x8E, 0x00, 0xF0,
|
||||
0xE0, 0x1E, 0x0E, 0x03, 0xE0, 0xE0, 0x7C, 0x0E, 0x0F, 0x80, 0xE1, 0xF0,
|
||||
0x0E, 0x1E, 0x00, 0xE3, 0xC0, 0x0E, 0x7C, 0x00, 0xEF, 0xE0, 0x0F, 0xCE,
|
||||
0x00, 0xF8, 0xF0, 0x0F, 0x07, 0x80, 0xE0, 0x3C, 0x0E, 0x03, 0xC0, 0xE0,
|
||||
0x1E, 0x0E, 0x00, 0xF0, 0xE0, 0x0F, 0x0E, 0x00, 0x78, 0xE0, 0x03, 0xCE,
|
||||
0x00, 0x3C, 0xE0, 0x01, 0xEE, 0x00, 0x0F, 0xE0, 0x01, 0xC0, 0x03, 0x80,
|
||||
0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x01,
|
||||
0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70,
|
||||
0x00, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x1C, 0x00,
|
||||
0x38, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF8, 0x00, 0x1F, 0xF8,
|
||||
0x00, 0x1F, 0xF8, 0x00, 0x1F, 0xFC, 0x00, 0x3F, 0xFC, 0x00, 0x3F, 0xFC,
|
||||
0x00, 0x3F, 0xEE, 0x00, 0x77, 0xEE, 0x00, 0x77, 0xEE, 0x00, 0x77, 0xE7,
|
||||
0x00, 0xE7, 0xE7, 0x00, 0xE7, 0xE7, 0x00, 0xE7, 0xE3, 0x81, 0xC7, 0xE3,
|
||||
0x81, 0xC7, 0xE3, 0x81, 0xC7, 0xE1, 0xC3, 0x87, 0xE1, 0xC3, 0x87, 0xE1,
|
||||
0xC3, 0x87, 0xE0, 0xE7, 0x07, 0xE0, 0xE7, 0x07, 0xE0, 0xE7, 0x07, 0xE0,
|
||||
0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x7E, 0x07, 0xE0, 0x3C, 0x07, 0xE0,
|
||||
0x3C, 0x07, 0xF0, 0x00, 0x7F, 0x00, 0x07, 0xF8, 0x00, 0x7F, 0xC0, 0x07,
|
||||
0xFC, 0x00, 0x7F, 0xE0, 0x07, 0xEF, 0x00, 0x7E, 0x70, 0x07, 0xE7, 0x80,
|
||||
0x7E, 0x3C, 0x07, 0xE1, 0xC0, 0x7E, 0x1E, 0x07, 0xE0, 0xE0, 0x7E, 0x0F,
|
||||
0x07, 0xE0, 0x78, 0x7E, 0x03, 0x87, 0xE0, 0x3C, 0x7E, 0x01, 0xE7, 0xE0,
|
||||
0x0E, 0x7E, 0x00, 0xF7, 0xE0, 0x07, 0xFE, 0x00, 0x3F, 0xE0, 0x03, 0xFE,
|
||||
0x00, 0x1F, 0xE0, 0x01, 0xFE, 0x00, 0x0F, 0x00, 0x7F, 0x00, 0x01, 0xFF,
|
||||
0xF0, 0x01, 0xFF, 0xFC, 0x01, 0xF0, 0x1F, 0x01, 0xE0, 0x03, 0xC1, 0xE0,
|
||||
0x00, 0xF1, 0xE0, 0x00, 0x3C, 0xE0, 0x00, 0x0E, 0x70, 0x00, 0x07, 0x70,
|
||||
0x00, 0x03, 0xF8, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3F,
|
||||
0x00, 0x00, 0x1F, 0x80, 0x00, 0x0F, 0xC0, 0x00, 0x07, 0xE0, 0x00, 0x03,
|
||||
0xB8, 0x00, 0x03, 0x9C, 0x00, 0x01, 0xCF, 0x00, 0x01, 0xE3, 0xC0, 0x01,
|
||||
0xE0, 0xF0, 0x01, 0xE0, 0x3E, 0x03, 0xE0, 0x0F, 0xFF, 0xE0, 0x03, 0xFF,
|
||||
0xE0, 0x00, 0x3F, 0x80, 0x00, 0xFF, 0xFC, 0x3F, 0xFF, 0x8F, 0xFF, 0xF3,
|
||||
0x80, 0x3E, 0xE0, 0x03, 0xF8, 0x00, 0x7E, 0x00, 0x1F, 0x80, 0x07, 0xE0,
|
||||
0x01, 0xF8, 0x00, 0x7E, 0x00, 0x3F, 0x80, 0x1E, 0xFF, 0xFF, 0x3F, 0xFF,
|
||||
0x8F, 0xFF, 0xC3, 0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03,
|
||||
0x80, 0x00, 0xE0, 0x00, 0x38, 0x00, 0x0E, 0x00, 0x03, 0x80, 0x00, 0xE0,
|
||||
0x00, 0x38, 0x00, 0x00, 0x00, 0x7F, 0x00, 0x01, 0xFF, 0xF0, 0x01, 0xFF,
|
||||
0xFC, 0x01, 0xF0, 0x1F, 0x01, 0xE0, 0x03, 0xC1, 0xE0, 0x00, 0xF1, 0xE0,
|
||||
0x00, 0x3C, 0xE0, 0x00, 0x0E, 0x70, 0x00, 0x07, 0x70, 0x00, 0x01, 0xF8,
|
||||
0x00, 0x00, 0xFC, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x1F,
|
||||
0x80, 0x00, 0x0F, 0xC0, 0x00, 0x07, 0xE0, 0x00, 0x07, 0xB8, 0x00, 0x03,
|
||||
0x9C, 0x00, 0x01, 0xCF, 0x00, 0x39, 0xE3, 0xC0, 0x1F, 0xE0, 0xF0, 0x07,
|
||||
0xE0, 0x3E, 0x03, 0xF0, 0x0F, 0xFF, 0xFC, 0x03, 0xFF, 0xEE, 0x00, 0x3F,
|
||||
0x83, 0x80, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x20, 0xFF, 0xFE, 0x0F, 0xFF,
|
||||
0xF8, 0xFF, 0xFF, 0xCE, 0x00, 0x3C, 0xE0, 0x01, 0xEE, 0x00, 0x0E, 0xE0,
|
||||
0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x01, 0xCE,
|
||||
0x00, 0x3C, 0xFF, 0xFF, 0x8F, 0xFF, 0xF0, 0xFF, 0xFF, 0x8E, 0x00, 0x3C,
|
||||
0xE0, 0x01, 0xEE, 0x00, 0x0E, 0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x00,
|
||||
0xEE, 0x00, 0x0E, 0xE0, 0x00, 0xEE, 0x00, 0x0E, 0xE0, 0x00, 0xFE, 0x00,
|
||||
0x0F, 0x03, 0xFC, 0x00, 0xFF, 0xF0, 0x1F, 0xFF, 0x83, 0xE0, 0x7C, 0x38,
|
||||
0x01, 0xE7, 0x00, 0x0E, 0x70, 0x00, 0xE7, 0x00, 0x00, 0x70, 0x00, 0x07,
|
||||
0x80, 0x00, 0x3E, 0x00, 0x01, 0xFE, 0x00, 0x0F, 0xFE, 0x00, 0x3F, 0xF8,
|
||||
0x00, 0x3F, 0xE0, 0x00, 0x3E, 0x00, 0x00, 0xF0, 0x00, 0x07, 0xE0, 0x00,
|
||||
0x7E, 0x00, 0x07, 0xF0, 0x00, 0x77, 0x80, 0x0E, 0x7C, 0x03, 0xE3, 0xFF,
|
||||
0xFC, 0x1F, 0xFF, 0x80, 0x3F, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x80, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07,
|
||||
0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E,
|
||||
0x00, 0x01, 0xC0, 0x00, 0x38, 0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C,
|
||||
0x00, 0x03, 0x80, 0x00, 0x70, 0x00, 0x0E, 0x00, 0x01, 0xC0, 0x00, 0x38,
|
||||
0x00, 0x07, 0x00, 0x00, 0xE0, 0x00, 0x1C, 0x00, 0xE0, 0x00, 0xFC, 0x00,
|
||||
0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00,
|
||||
0x3F, 0x00, 0x07, 0xE0, 0x00, 0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00,
|
||||
0x7E, 0x00, 0x0F, 0xC0, 0x01, 0xF8, 0x00, 0x3F, 0x00, 0x07, 0xE0, 0x00,
|
||||
0xFC, 0x00, 0x1F, 0x80, 0x03, 0xF0, 0x00, 0x7F, 0x00, 0x1E, 0xF0, 0x07,
|
||||
0x9F, 0x01, 0xF1, 0xFF, 0xFC, 0x1F, 0xFE, 0x00, 0x7F, 0x00, 0xE0, 0x00,
|
||||
0x7F, 0x80, 0x03, 0xFC, 0x00, 0x1C, 0xE0, 0x01, 0xE7, 0x80, 0x0F, 0x3C,
|
||||
0x00, 0x70, 0xE0, 0x07, 0x87, 0x80, 0x3C, 0x1C, 0x01, 0xC0, 0xE0, 0x0E,
|
||||
0x07, 0x80, 0xE0, 0x1C, 0x07, 0x00, 0xE0, 0x38, 0x07, 0x83, 0x80, 0x1C,
|
||||
0x1C, 0x00, 0xE0, 0xE0, 0x07, 0x8E, 0x00, 0x1C, 0x70, 0x00, 0xE3, 0x80,
|
||||
0x07, 0xB8, 0x00, 0x1D, 0xC0, 0x00, 0xEE, 0x00, 0x07, 0xE0, 0x00, 0x1F,
|
||||
0x00, 0x00, 0xF8, 0x00, 0x03, 0x80, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x70,
|
||||
0x03, 0xC0, 0x0F, 0x78, 0x03, 0xE0, 0x0F, 0x78, 0x03, 0xE0, 0x0E, 0x38,
|
||||
0x07, 0xE0, 0x0E, 0x38, 0x07, 0xF0, 0x1E, 0x3C, 0x07, 0x70, 0x1E, 0x3C,
|
||||
0x07, 0x70, 0x1C, 0x1C, 0x0E, 0x70, 0x1C, 0x1C, 0x0E, 0x38, 0x3C, 0x1C,
|
||||
0x0E, 0x38, 0x3C, 0x1E, 0x1E, 0x38, 0x38, 0x0E, 0x1C, 0x38, 0x38, 0x0E,
|
||||
0x1C, 0x1C, 0x38, 0x0E, 0x1C, 0x1C, 0x78, 0x0F, 0x3C, 0x1C, 0x70, 0x07,
|
||||
0x38, 0x0E, 0x70, 0x07, 0x38, 0x0E, 0x70, 0x07, 0x38, 0x0E, 0x70, 0x07,
|
||||
0x70, 0x0E, 0xE0, 0x03, 0xF0, 0x07, 0xE0, 0x03, 0xF0, 0x07, 0xE0, 0x03,
|
||||
0xF0, 0x07, 0xE0, 0x03, 0xE0, 0x03, 0xC0, 0x01, 0xE0, 0x03, 0xC0, 0x01,
|
||||
0xE0, 0x03, 0xC0, 0xF0, 0x00, 0x7B, 0xC0, 0x07, 0x8F, 0x00, 0x38, 0x78,
|
||||
0x03, 0xC1, 0xE0, 0x3C, 0x07, 0x81, 0xC0, 0x3C, 0x1E, 0x00, 0xF1, 0xE0,
|
||||
0x03, 0x8E, 0x00, 0x1E, 0xF0, 0x00, 0x7F, 0x00, 0x01, 0xF0, 0x00, 0x0F,
|
||||
0x80, 0x00, 0x7C, 0x00, 0x07, 0xF0, 0x00, 0x3B, 0x80, 0x03, 0xDE, 0x00,
|
||||
0x3C, 0x78, 0x01, 0xC1, 0xC0, 0x1E, 0x0F, 0x01, 0xE0, 0x3C, 0x0E, 0x00,
|
||||
0xE0, 0xF0, 0x07, 0x8F, 0x00, 0x1E, 0x70, 0x00, 0xF7, 0x80, 0x03, 0xC0,
|
||||
0xF0, 0x00, 0x3C, 0xF0, 0x00, 0x78, 0xF0, 0x01, 0xE1, 0xE0, 0x03, 0x81,
|
||||
0xE0, 0x0F, 0x01, 0xC0, 0x1C, 0x03, 0xC0, 0x78, 0x03, 0xC1, 0xE0, 0x07,
|
||||
0x83, 0x80, 0x07, 0x8F, 0x00, 0x07, 0x1C, 0x00, 0x0F, 0x78, 0x00, 0x0E,
|
||||
0xE0, 0x00, 0x0F, 0x80, 0x00, 0x1F, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38,
|
||||
0x00, 0x00, 0x70, 0x00, 0x00, 0xE0, 0x00, 0x01, 0xC0, 0x00, 0x03, 0x80,
|
||||
0x00, 0x07, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x38, 0x00,
|
||||
0x00, 0x70, 0x00, 0x7F, 0xFF, 0xEF, 0xFF, 0xFD, 0xFF, 0xFF, 0x80, 0x00,
|
||||
0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x80, 0x01, 0xE0, 0x00, 0x78, 0x00, 0x1E,
|
||||
0x00, 0x07, 0x80, 0x00, 0xF0, 0x00, 0x3C, 0x00, 0x0F, 0x00, 0x03, 0xC0,
|
||||
0x00, 0x78, 0x00, 0x1E, 0x00, 0x07, 0x80, 0x01, 0xE0, 0x00, 0x7C, 0x00,
|
||||
0x0F, 0x00, 0x03, 0xC0, 0x00, 0xF0, 0x00, 0x3E, 0x00, 0x07, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFF, 0xFF, 0xF8, 0xE3, 0x8E, 0x38, 0xE3,
|
||||
0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3, 0x8E, 0x38, 0xE3,
|
||||
0x8E, 0x38, 0xE3, 0x8F, 0xFF, 0xFC, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x60,
|
||||
0x0C, 0x03, 0x00, 0xC0, 0x18, 0x06, 0x01, 0x80, 0x20, 0x0C, 0x03, 0x00,
|
||||
0x40, 0x18, 0x06, 0x01, 0x80, 0x30, 0x0C, 0x03, 0x00, 0x60, 0x18, 0x06,
|
||||
0x00, 0xC0, 0x30, 0xFF, 0xFF, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7,
|
||||
0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7,
|
||||
0x1C, 0x7F, 0xFF, 0xFC, 0x07, 0x00, 0x78, 0x03, 0xC0, 0x3F, 0x01, 0xD8,
|
||||
0x0C, 0xE0, 0xE3, 0x06, 0x1C, 0x70, 0xE3, 0x83, 0x18, 0x1D, 0xC0, 0x6C,
|
||||
0x03, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xF0, 0xF0, 0xE0, 0xE0,
|
||||
0xE0, 0x07, 0xF0, 0x0F, 0xFC, 0x0F, 0xFF, 0x0F, 0x03, 0xC7, 0x00, 0xE0,
|
||||
0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0xFE, 0x0F, 0xFF, 0x1F, 0xF3,
|
||||
0x9F, 0x01, 0xCF, 0x00, 0xE7, 0x00, 0x73, 0x80, 0x79, 0xE0, 0xFC, 0x7F,
|
||||
0xEF, 0x9F, 0xE3, 0xC7, 0xE1, 0xE0, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
|
||||
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE3, 0xE0, 0xEF, 0xF8,
|
||||
0xFF, 0xFC, 0xFC, 0x3E, 0xF8, 0x1E, 0xF0, 0x0E, 0xE0, 0x0F, 0xE0, 0x07,
|
||||
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0E,
|
||||
0xF8, 0x1E, 0xFC, 0x3C, 0xEF, 0xFC, 0xEF, 0xF8, 0xE3, 0xE0, 0x07, 0xF0,
|
||||
0x1F, 0xF8, 0x3F, 0xFC, 0x3C, 0x1E, 0x78, 0x0E, 0x70, 0x07, 0xE0, 0x00,
|
||||
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x07,
|
||||
0x70, 0x07, 0x78, 0x0E, 0x7C, 0x1E, 0x3F, 0xFC, 0x1F, 0xF8, 0x07, 0xE0,
|
||||
0x00, 0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00,
|
||||
0x1C, 0x00, 0x0E, 0x0F, 0xC7, 0x1F, 0xFB, 0x9F, 0xFF, 0xDF, 0x07, 0xEF,
|
||||
0x01, 0xF7, 0x00, 0x7F, 0x80, 0x3F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03,
|
||||
0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x77, 0x00, 0x7B, 0xC0, 0x7D, 0xF0,
|
||||
0x7E, 0x7F, 0xFB, 0x1F, 0xF9, 0x83, 0xF0, 0xC0, 0x07, 0xE0, 0x1F, 0xF8,
|
||||
0x3F, 0xFC, 0x7C, 0x1E, 0x70, 0x0E, 0x60, 0x06, 0xE0, 0x07, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x70, 0x07,
|
||||
0x78, 0x0E, 0x3C, 0x1E, 0x3F, 0xFC, 0x1F, 0xF8, 0x07, 0xE0, 0x0E, 0x3C,
|
||||
0xF9, 0xC3, 0x87, 0x0E, 0x7F, 0xFF, 0xFC, 0xE1, 0xC3, 0x87, 0x0E, 0x1C,
|
||||
0x38, 0x70, 0xE1, 0xC3, 0x87, 0x0E, 0x1C, 0x38, 0x70, 0x07, 0xC7, 0x1F,
|
||||
0xF7, 0x3F, 0xFF, 0x3C, 0x3F, 0x78, 0x0F, 0x70, 0x0F, 0xE0, 0x07, 0xE0,
|
||||
0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0x70,
|
||||
0x0F, 0x78, 0x0F, 0x7C, 0x3F, 0x3F, 0xF7, 0x1F, 0xE7, 0x07, 0xC7, 0x00,
|
||||
0x07, 0x00, 0x07, 0x00, 0x0E, 0x70, 0x0E, 0x78, 0x1E, 0x3F, 0xFC, 0x1F,
|
||||
0xF8, 0x07, 0xE0, 0xE0, 0x01, 0xC0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00,
|
||||
0x1C, 0x00, 0x38, 0x00, 0x71, 0xF8, 0xE7, 0xFD, 0xDF, 0xFB, 0xF0, 0xFF,
|
||||
0xC0, 0xFF, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0,
|
||||
0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07,
|
||||
0xE0, 0x0F, 0xC0, 0x1C, 0xFF, 0xF0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFC, 0x1C, 0x71, 0xC7, 0x00, 0x00, 0x07, 0x1C, 0x71, 0xC7, 0x1C,
|
||||
0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7, 0x1C,
|
||||
0x73, 0xFF, 0xFB, 0xC0, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00,
|
||||
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x3C, 0xE0, 0x78, 0xE0, 0xF0,
|
||||
0xE1, 0xE0, 0xE3, 0xC0, 0xE7, 0x80, 0xEF, 0x00, 0xEF, 0x80, 0xFF, 0x80,
|
||||
0xFB, 0xC0, 0xF1, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xE0, 0x70, 0xE0, 0x78,
|
||||
0xE0, 0x3C, 0xE0, 0x1C, 0xE0, 0x1E, 0xE0, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xE3, 0xE0, 0xF8, 0xE7, 0xF1, 0xFE,
|
||||
0xEF, 0xFB, 0xFE, 0xF8, 0x7F, 0x0F, 0xF0, 0x3E, 0x07, 0xF0, 0x1C, 0x07,
|
||||
0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07,
|
||||
0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07,
|
||||
0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07, 0xE0, 0x1C, 0x07,
|
||||
0xE0, 0x1C, 0x07, 0xE3, 0xF1, 0xCF, 0xFB, 0xBF, 0xF7, 0xE1, 0xFF, 0x81,
|
||||
0xFE, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F,
|
||||
0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07, 0xE0, 0x0F, 0xC0,
|
||||
0x1F, 0x80, 0x38, 0x07, 0xF0, 0x0F, 0xFE, 0x0F, 0xFF, 0x87, 0x83, 0xC7,
|
||||
0x80, 0xF3, 0x80, 0x3B, 0x80, 0x1F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01,
|
||||
0xF8, 0x00, 0xFC, 0x00, 0x7E, 0x00, 0x3B, 0x80, 0x39, 0xE0, 0x3C, 0x78,
|
||||
0x3C, 0x3F, 0xFE, 0x0F, 0xFE, 0x01, 0xFC, 0x00, 0xE3, 0xE0, 0xE7, 0xF8,
|
||||
0xEF, 0xFC, 0xFC, 0x3E, 0xF8, 0x1E, 0xF0, 0x0E, 0xE0, 0x0F, 0xE0, 0x07,
|
||||
0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xE0, 0x07, 0xF0, 0x0E,
|
||||
0xF8, 0x1E, 0xFC, 0x3E, 0xFF, 0xFC, 0xEF, 0xF8, 0xE3, 0xE0, 0xE0, 0x00,
|
||||
0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0xE0, 0x00, 0x07, 0xE1,
|
||||
0x8F, 0xFC, 0xCF, 0xFF, 0x67, 0x83, 0xF7, 0x80, 0xFB, 0x80, 0x3F, 0xC0,
|
||||
0x1F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8, 0x00, 0xFC, 0x00, 0x7E,
|
||||
0x00, 0x3B, 0x80, 0x3D, 0xE0, 0x3E, 0xF8, 0x3F, 0x3F, 0xFF, 0x8F, 0xFD,
|
||||
0xC1, 0xF8, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0E, 0x00,
|
||||
0x07, 0x00, 0x03, 0x80, 0xE3, 0xF7, 0xFB, 0xFF, 0x8F, 0x07, 0x83, 0x81,
|
||||
0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 0x81, 0xC0, 0xE0, 0x70,
|
||||
0x38, 0x00, 0x0F, 0xC0, 0xFF, 0x87, 0xFF, 0x3C, 0x1E, 0xE0, 0x3B, 0x80,
|
||||
0x0E, 0x00, 0x3C, 0x00, 0x7F, 0x00, 0xFF, 0x80, 0xFF, 0x80, 0x7F, 0x00,
|
||||
0x3F, 0x80, 0x7E, 0x01, 0xFC, 0x1F, 0x7F, 0xF8, 0xFF, 0xC1, 0xFC, 0x00,
|
||||
0x38, 0x70, 0xE1, 0xCF, 0xFF, 0xFF, 0x9C, 0x38, 0x70, 0xE1, 0xC3, 0x87,
|
||||
0x0E, 0x1C, 0x38, 0x70, 0xE1, 0xC3, 0xE7, 0xC7, 0x80, 0xE0, 0x0F, 0xC0,
|
||||
0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x01, 0xF8, 0x03, 0xF0, 0x07,
|
||||
0xE0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7E, 0x00, 0xFC, 0x03, 0xFC,
|
||||
0x0F, 0xFC, 0x3F, 0x7F, 0xEE, 0xFF, 0x9C, 0x7E, 0x38, 0x70, 0x03, 0xB8,
|
||||
0x03, 0x9C, 0x01, 0xC7, 0x00, 0xE3, 0x80, 0xE1, 0xC0, 0x70, 0x70, 0x38,
|
||||
0x38, 0x38, 0x1C, 0x1C, 0x07, 0x0E, 0x03, 0x8E, 0x01, 0xC7, 0x00, 0x77,
|
||||
0x00, 0x3B, 0x80, 0x1D, 0xC0, 0x07, 0xC0, 0x03, 0xE0, 0x01, 0xF0, 0x00,
|
||||
0x70, 0x00, 0xF0, 0x1C, 0x03, 0xB8, 0x1F, 0x03, 0xDC, 0x0F, 0x81, 0xCE,
|
||||
0x07, 0xC0, 0xE7, 0x83, 0xE0, 0x71, 0xC3, 0xB8, 0x70, 0xE1, 0xDC, 0x38,
|
||||
0x70, 0xEE, 0x1C, 0x1C, 0x63, 0x0E, 0x0E, 0x71, 0xCE, 0x07, 0x38, 0xE7,
|
||||
0x03, 0x9C, 0x73, 0x80, 0xEC, 0x19, 0x80, 0x7E, 0x0F, 0xC0, 0x3F, 0x07,
|
||||
0xE0, 0x0F, 0x83, 0xF0, 0x07, 0x80, 0xF0, 0x03, 0xC0, 0x78, 0x01, 0xE0,
|
||||
0x3C, 0x00, 0x70, 0x07, 0x38, 0x0E, 0x3C, 0x1C, 0x1C, 0x1C, 0x0E, 0x38,
|
||||
0x0F, 0x70, 0x07, 0x70, 0x03, 0xE0, 0x03, 0xC0, 0x01, 0xC0, 0x03, 0xE0,
|
||||
0x07, 0xE0, 0x07, 0x70, 0x0E, 0x78, 0x1E, 0x38, 0x1C, 0x1C, 0x38, 0x1E,
|
||||
0x78, 0x0E, 0x70, 0x07, 0x70, 0x07, 0x38, 0x03, 0x9C, 0x01, 0xC7, 0x01,
|
||||
0xC3, 0x80, 0xE1, 0xC0, 0x70, 0x70, 0x70, 0x38, 0x38, 0x1C, 0x3C, 0x07,
|
||||
0x1C, 0x03, 0x8E, 0x01, 0xCE, 0x00, 0x77, 0x00, 0x3B, 0x80, 0x1F, 0x80,
|
||||
0x07, 0xC0, 0x03, 0xE0, 0x01, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x38,
|
||||
0x00, 0x1C, 0x00, 0x1E, 0x00, 0x0E, 0x00, 0x3F, 0x00, 0x1F, 0x00, 0x0F,
|
||||
0x00, 0x00, 0x7F, 0xFC, 0xFF, 0xF9, 0xFF, 0xF0, 0x00, 0xE0, 0x03, 0x80,
|
||||
0x0E, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x1C, 0x00, 0x70,
|
||||
0x01, 0xE0, 0x07, 0x80, 0x1E, 0x00, 0x78, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xF8, 0x07, 0x0F, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
|
||||
0x1C, 0x1C, 0x1C, 0x1C, 0x38, 0xF8, 0xE0, 0xF8, 0x38, 0x1C, 0x1C, 0x1C,
|
||||
0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x0F, 0x07, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xE0, 0xF0, 0xF8, 0x38,
|
||||
0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x1C, 0x1F,
|
||||
0x07, 0x1F, 0x1C, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
|
||||
0x38, 0x38, 0xF8, 0xF0, 0xE0, 0x38, 0x00, 0xFC, 0x03, 0xFC, 0x1F, 0x3E,
|
||||
0x3C, 0x1F, 0xE0, 0x1F, 0x80, 0x1E, 0x00};
|
||||
|
||||
const GFXglyph FreeSans18pt7bGlyphs[] PROGMEM = {
|
||||
{0, 0, 0, 9, 0, 1}, // 0x20 ' '
|
||||
{0, 3, 26, 12, 4, -25}, // 0x21 '!'
|
||||
{10, 9, 9, 12, 1, -24}, // 0x22 '"'
|
||||
{21, 19, 24, 19, 0, -23}, // 0x23 '#'
|
||||
{78, 16, 30, 19, 2, -26}, // 0x24 '$'
|
||||
{138, 29, 25, 31, 1, -24}, // 0x25 '%'
|
||||
{229, 20, 25, 23, 2, -24}, // 0x26 '&'
|
||||
{292, 3, 9, 7, 2, -24}, // 0x27 '''
|
||||
{296, 8, 33, 12, 3, -25}, // 0x28 '('
|
||||
{329, 8, 33, 12, 1, -25}, // 0x29 ')'
|
||||
{362, 10, 10, 14, 2, -25}, // 0x2A '*'
|
||||
{375, 16, 16, 20, 2, -15}, // 0x2B '+'
|
||||
{407, 3, 9, 10, 3, -3}, // 0x2C ','
|
||||
{411, 8, 3, 12, 2, -10}, // 0x2D '-'
|
||||
{414, 3, 4, 9, 3, -3}, // 0x2E '.'
|
||||
{416, 10, 26, 10, 0, -25}, // 0x2F '/'
|
||||
{449, 16, 25, 19, 2, -24}, // 0x30 '0'
|
||||
{499, 8, 25, 19, 4, -24}, // 0x31 '1'
|
||||
{524, 16, 25, 19, 2, -24}, // 0x32 '2'
|
||||
{574, 17, 25, 19, 1, -24}, // 0x33 '3'
|
||||
{628, 16, 25, 19, 1, -24}, // 0x34 '4'
|
||||
{678, 17, 25, 19, 1, -24}, // 0x35 '5'
|
||||
{732, 16, 25, 19, 2, -24}, // 0x36 '6'
|
||||
{782, 16, 25, 19, 2, -24}, // 0x37 '7'
|
||||
{832, 17, 25, 19, 1, -24}, // 0x38 '8'
|
||||
{886, 16, 25, 19, 1, -24}, // 0x39 '9'
|
||||
{936, 3, 19, 9, 3, -18}, // 0x3A ':'
|
||||
{944, 3, 24, 9, 3, -18}, // 0x3B ';'
|
||||
{953, 17, 17, 20, 2, -16}, // 0x3C '<'
|
||||
{990, 17, 9, 20, 2, -12}, // 0x3D '='
|
||||
{1010, 17, 17, 20, 2, -16}, // 0x3E '>'
|
||||
{1047, 15, 26, 19, 3, -25}, // 0x3F '?'
|
||||
{1096, 32, 31, 36, 1, -25}, // 0x40 '@'
|
||||
{1220, 22, 26, 23, 1, -25}, // 0x41 'A'
|
||||
{1292, 19, 26, 23, 3, -25}, // 0x42 'B'
|
||||
{1354, 22, 26, 25, 1, -25}, // 0x43 'C'
|
||||
{1426, 20, 26, 24, 3, -25}, // 0x44 'D'
|
||||
{1491, 18, 26, 22, 3, -25}, // 0x45 'E'
|
||||
{1550, 17, 26, 21, 3, -25}, // 0x46 'F'
|
||||
{1606, 24, 26, 27, 1, -25}, // 0x47 'G'
|
||||
{1684, 19, 26, 25, 3, -25}, // 0x48 'H'
|
||||
{1746, 3, 26, 10, 4, -25}, // 0x49 'I'
|
||||
{1756, 14, 26, 18, 1, -25}, // 0x4A 'J'
|
||||
{1802, 20, 26, 24, 3, -25}, // 0x4B 'K'
|
||||
{1867, 15, 26, 20, 3, -25}, // 0x4C 'L'
|
||||
{1916, 24, 26, 30, 3, -25}, // 0x4D 'M'
|
||||
{1994, 20, 26, 26, 3, -25}, // 0x4E 'N'
|
||||
{2059, 25, 26, 27, 1, -25}, // 0x4F 'O'
|
||||
{2141, 18, 26, 23, 3, -25}, // 0x50 'P'
|
||||
{2200, 25, 28, 27, 1, -25}, // 0x51 'Q'
|
||||
{2288, 20, 26, 25, 3, -25}, // 0x52 'R'
|
||||
{2353, 20, 26, 23, 1, -25}, // 0x53 'S'
|
||||
{2418, 19, 26, 22, 1, -25}, // 0x54 'T'
|
||||
{2480, 19, 26, 25, 3, -25}, // 0x55 'U'
|
||||
{2542, 21, 26, 23, 1, -25}, // 0x56 'V'
|
||||
{2611, 32, 26, 33, 0, -25}, // 0x57 'W'
|
||||
{2715, 21, 26, 23, 1, -25}, // 0x58 'X'
|
||||
{2784, 23, 26, 24, 0, -25}, // 0x59 'Y'
|
||||
{2859, 19, 26, 22, 1, -25}, // 0x5A 'Z'
|
||||
{2921, 6, 33, 10, 2, -25}, // 0x5B '['
|
||||
{2946, 10, 26, 10, 0, -25}, // 0x5C '\'
|
||||
{2979, 6, 33, 10, 1, -25}, // 0x5D ']'
|
||||
{3004, 13, 13, 16, 2, -24}, // 0x5E '^'
|
||||
{3026, 21, 2, 19, -1, 5}, // 0x5F '_'
|
||||
{3032, 7, 5, 9, 1, -25}, // 0x60 '`'
|
||||
{3037, 17, 19, 19, 1, -18}, // 0x61 'a'
|
||||
{3078, 16, 26, 20, 2, -25}, // 0x62 'b'
|
||||
{3130, 16, 19, 18, 1, -18}, // 0x63 'c'
|
||||
{3168, 17, 26, 20, 1, -25}, // 0x64 'd'
|
||||
{3224, 16, 19, 19, 1, -18}, // 0x65 'e'
|
||||
{3262, 7, 26, 10, 1, -25}, // 0x66 'f'
|
||||
{3285, 16, 27, 19, 1, -18}, // 0x67 'g'
|
||||
{3339, 15, 26, 19, 2, -25}, // 0x68 'h'
|
||||
{3388, 3, 26, 8, 2, -25}, // 0x69 'i'
|
||||
{3398, 6, 34, 9, 0, -25}, // 0x6A 'j'
|
||||
{3424, 16, 26, 18, 2, -25}, // 0x6B 'k'
|
||||
{3476, 3, 26, 7, 2, -25}, // 0x6C 'l'
|
||||
{3486, 24, 19, 28, 2, -18}, // 0x6D 'm'
|
||||
{3543, 15, 19, 19, 2, -18}, // 0x6E 'n'
|
||||
{3579, 17, 19, 19, 1, -18}, // 0x6F 'o'
|
||||
{3620, 16, 25, 20, 2, -18}, // 0x70 'p'
|
||||
{3670, 17, 25, 20, 1, -18}, // 0x71 'q'
|
||||
{3724, 9, 19, 12, 2, -18}, // 0x72 'r'
|
||||
{3746, 14, 19, 17, 2, -18}, // 0x73 's'
|
||||
{3780, 7, 23, 10, 1, -22}, // 0x74 't'
|
||||
{3801, 15, 19, 19, 2, -18}, // 0x75 'u'
|
||||
{3837, 17, 19, 17, 0, -18}, // 0x76 'v'
|
||||
{3878, 25, 19, 25, 0, -18}, // 0x77 'w'
|
||||
{3938, 16, 19, 17, 0, -18}, // 0x78 'x'
|
||||
{3976, 17, 27, 17, 0, -18}, // 0x79 'y'
|
||||
{4034, 15, 19, 17, 1, -18}, // 0x7A 'z'
|
||||
{4070, 8, 33, 12, 1, -25}, // 0x7B '{'
|
||||
{4103, 2, 33, 9, 3, -25}, // 0x7C '|'
|
||||
{4112, 8, 33, 12, 3, -25}, // 0x7D '}'
|
||||
{4145, 15, 7, 18, 1, -15}}; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSans18pt7b PROGMEM = {(uint8_t *)FreeSans18pt7bBitmaps,
|
||||
(GFXglyph *)FreeSans18pt7bGlyphs, 0x20,
|
||||
0x7E, 42};
|
||||
|
||||
// Approx. 4831 bytes
|
1030
RX_FSK/src/fonts/FreeSans18pt8b.h
Normal file
1030
RX_FSK/src/fonts/FreeSans18pt8b.h
Normal file
File diff suppressed because it is too large
Load Diff
201
RX_FSK/src/fonts/FreeSans9pt7b.h
Normal file
201
RX_FSK/src/fonts/FreeSans9pt7b.h
Normal file
|
@ -0,0 +1,201 @@
|
|||
const uint8_t FreeSans9pt7bBitmaps[] PROGMEM = {
|
||||
0xFF, 0xFF, 0xF8, 0xC0, 0xDE, 0xF7, 0x20, 0x09, 0x86, 0x41, 0x91, 0xFF,
|
||||
0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, 0x10, 0x1F,
|
||||
0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35,
|
||||
0x33, 0xF0, 0x40, 0x20, 0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40,
|
||||
0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63,
|
||||
0x04, 0x63, 0x04, 0x77, 0x08, 0x3C, 0x0E, 0x06, 0x60, 0xCC, 0x19, 0x81,
|
||||
0xE0, 0x18, 0x0F, 0x03, 0x36, 0xC2, 0xD8, 0x73, 0x06, 0x31, 0xE3, 0xC4,
|
||||
0xFE, 0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, 0x8C, 0x46,
|
||||
0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, 0x25, 0x7E, 0xA5, 0x00, 0x30,
|
||||
0xC3, 0x3F, 0x30, 0xC3, 0x0C, 0xD6, 0xF0, 0xC0, 0x08, 0x44, 0x21, 0x10,
|
||||
0x84, 0x42, 0x11, 0x08, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x11, 0x3F, 0x33, 0x33, 0x33, 0x33,
|
||||
0x30, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18,
|
||||
0x10, 0x08, 0x07, 0xF8, 0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07,
|
||||
0x03, 0xC3, 0xC3, 0x66, 0x3C, 0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46,
|
||||
0xFE, 0x18, 0x30, 0x60, 0xC0, 0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3,
|
||||
0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, 0x1E, 0x31, 0x98, 0x78,
|
||||
0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, 0xFF,
|
||||
0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30,
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0,
|
||||
0x6C, 0x63, 0xE0, 0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03,
|
||||
0x03, 0xC2, 0x66, 0x3C, 0xC0, 0x00, 0x30, 0xC0, 0x00, 0x00, 0x64, 0xA0,
|
||||
0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, 0xFF,
|
||||
0x80, 0x00, 0x1F, 0xF0, 0x00, 0x70, 0x0E, 0x01, 0xC0, 0x18, 0x38, 0x71,
|
||||
0xC0, 0x80, 0x00, 0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18,
|
||||
0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, 0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01,
|
||||
0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC,
|
||||
0x31, 0xE6, 0x11, 0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00,
|
||||
0x70, 0x40, 0x0F, 0xE0, 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81,
|
||||
0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30,
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0,
|
||||
0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, 0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C,
|
||||
0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0,
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0,
|
||||
0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06,
|
||||
0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, 0xFF, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x0F, 0x83,
|
||||
0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36,
|
||||
0x03, 0x60, 0x73, 0x0F, 0x0F, 0x10, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C,
|
||||
0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06,
|
||||
0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07,
|
||||
0x8F, 0x1E, 0x27, 0x80, 0xC0, 0xD8, 0x33, 0x0C, 0x63, 0x0C, 0xC1, 0xB8,
|
||||
0x3F, 0x07, 0x30, 0xC3, 0x18, 0x63, 0x06, 0x60, 0x6C, 0x0C, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xE0,
|
||||
0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13,
|
||||
0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80, 0xE0, 0x7C, 0x0F,
|
||||
0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07,
|
||||
0xE0, 0x7C, 0x0E, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0,
|
||||
0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0,
|
||||
0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, 0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0,
|
||||
0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C,
|
||||
0x60, 0xC0, 0xFB, 0x00, 0x08, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x70, 0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00,
|
||||
0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, 0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0,
|
||||
0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0xC0, 0x78, 0x0F,
|
||||
0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01,
|
||||
0xB0, 0x61, 0xF0, 0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04,
|
||||
0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, 0xC1, 0x81, 0x30,
|
||||
0xE1, 0x98, 0x70, 0xCC, 0x28, 0x66, 0x26, 0x21, 0x13, 0x30, 0xC8, 0x98,
|
||||
0x6C, 0x4C, 0x14, 0x34, 0x0A, 0x1A, 0x07, 0x07, 0x03, 0x03, 0x80, 0x81,
|
||||
0x80, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x0F, 0x00, 0xE0, 0x06, 0x00,
|
||||
0xF0, 0x19, 0x01, 0x98, 0x30, 0xC6, 0x0E, 0x60, 0x60, 0xC0, 0x36, 0x06,
|
||||
0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60,
|
||||
0x06, 0x00, 0x60, 0x06, 0x00, 0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03,
|
||||
0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, 0xFB, 0x6D,
|
||||
0xB6, 0xDB, 0x6D, 0xB6, 0xE0, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84,
|
||||
0x10, 0x80, 0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, 0x30, 0x60, 0xA2,
|
||||
0x44, 0xD8, 0xA1, 0x80, 0xFF, 0xC0, 0xC6, 0x30, 0x7E, 0x71, 0xB0, 0xC0,
|
||||
0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, 0xC0, 0x60, 0x30, 0x1B,
|
||||
0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, 0x3C,
|
||||
0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x03, 0x03, 0x03,
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x3C, 0x66,
|
||||
0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x36, 0x6F, 0x66, 0x66,
|
||||
0x66, 0x66, 0x60, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67,
|
||||
0x3B, 0x03, 0x03, 0xC6, 0x7C, 0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC0, 0x30, 0x03,
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x4C,
|
||||
0x46, 0x63, 0x61, 0xF0, 0xEC, 0x62, 0x31, 0x98, 0x6C, 0x30, 0xFF, 0xFF,
|
||||
0xFF, 0xC0, 0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F,
|
||||
0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0x66, 0x3C, 0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
|
||||
0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, 0xDF, 0x31, 0x8C, 0x63, 0x18,
|
||||
0xC6, 0x00, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E,
|
||||
0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC7, 0x7B, 0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0,
|
||||
0x28, 0x1C, 0x0C, 0x00, 0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3,
|
||||
0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, 0x43, 0x62, 0x36,
|
||||
0x1C, 0x18, 0x1C, 0x3C, 0x26, 0x62, 0x43, 0xC1, 0x21, 0x98, 0xCC, 0x42,
|
||||
0x61, 0xB0, 0xD0, 0x38, 0x1C, 0x0C, 0x06, 0x03, 0x01, 0x03, 0x00, 0xFE,
|
||||
0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, 0x36, 0x66, 0x66, 0x6E,
|
||||
0xCE, 0x66, 0x66, 0x66, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC6, 0x66,
|
||||
0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, 0x61, 0x24, 0x38 };
|
||||
|
||||
const GFXglyph FreeSans9pt7bGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 5, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 2, 13, 6, 2, -12 }, // 0x21 '!'
|
||||
{ 4, 5, 4, 6, 1, -12 }, // 0x22 '"'
|
||||
{ 7, 10, 12, 10, 0, -11 }, // 0x23 '#'
|
||||
{ 22, 9, 16, 10, 1, -13 }, // 0x24 '$'
|
||||
{ 40, 16, 13, 16, 1, -12 }, // 0x25 '%'
|
||||
{ 66, 11, 13, 12, 1, -12 }, // 0x26 '&'
|
||||
{ 84, 2, 4, 4, 1, -12 }, // 0x27 '''
|
||||
{ 85, 4, 17, 6, 1, -12 }, // 0x28 '('
|
||||
{ 94, 4, 17, 6, 1, -12 }, // 0x29 ')'
|
||||
{ 103, 5, 5, 7, 1, -12 }, // 0x2A '*'
|
||||
{ 107, 6, 8, 11, 3, -7 }, // 0x2B '+'
|
||||
{ 113, 2, 4, 5, 2, 0 }, // 0x2C ','
|
||||
{ 114, 4, 1, 6, 1, -4 }, // 0x2D '-'
|
||||
{ 115, 2, 1, 5, 1, 0 }, // 0x2E '.'
|
||||
{ 116, 5, 13, 5, 0, -12 }, // 0x2F '/'
|
||||
{ 125, 8, 13, 10, 1, -12 }, // 0x30 '0'
|
||||
{ 138, 4, 13, 10, 3, -12 }, // 0x31 '1'
|
||||
{ 145, 9, 13, 10, 1, -12 }, // 0x32 '2'
|
||||
{ 160, 8, 13, 10, 1, -12 }, // 0x33 '3'
|
||||
{ 173, 7, 13, 10, 2, -12 }, // 0x34 '4'
|
||||
{ 185, 9, 13, 10, 1, -12 }, // 0x35 '5'
|
||||
{ 200, 9, 13, 10, 1, -12 }, // 0x36 '6'
|
||||
{ 215, 8, 13, 10, 0, -12 }, // 0x37 '7'
|
||||
{ 228, 9, 13, 10, 1, -12 }, // 0x38 '8'
|
||||
{ 243, 8, 13, 10, 1, -12 }, // 0x39 '9'
|
||||
{ 256, 2, 10, 5, 1, -9 }, // 0x3A ':'
|
||||
{ 259, 3, 12, 5, 1, -8 }, // 0x3B ';'
|
||||
{ 264, 9, 9, 11, 1, -8 }, // 0x3C '<'
|
||||
{ 275, 9, 4, 11, 1, -5 }, // 0x3D '='
|
||||
{ 280, 9, 9, 11, 1, -8 }, // 0x3E '>'
|
||||
{ 291, 9, 13, 10, 1, -12 }, // 0x3F '?'
|
||||
{ 306, 17, 16, 18, 1, -12 }, // 0x40 '@'
|
||||
{ 340, 12, 13, 12, 0, -12 }, // 0x41 'A'
|
||||
{ 360, 11, 13, 12, 1, -12 }, // 0x42 'B'
|
||||
{ 378, 11, 13, 13, 1, -12 }, // 0x43 'C'
|
||||
{ 396, 11, 13, 13, 1, -12 }, // 0x44 'D'
|
||||
{ 414, 9, 13, 11, 1, -12 }, // 0x45 'E'
|
||||
{ 429, 8, 13, 11, 1, -12 }, // 0x46 'F'
|
||||
{ 442, 12, 13, 14, 1, -12 }, // 0x47 'G'
|
||||
{ 462, 11, 13, 13, 1, -12 }, // 0x48 'H'
|
||||
{ 480, 2, 13, 5, 2, -12 }, // 0x49 'I'
|
||||
{ 484, 7, 13, 10, 1, -12 }, // 0x4A 'J'
|
||||
{ 496, 11, 13, 12, 1, -12 }, // 0x4B 'K'
|
||||
{ 514, 8, 13, 10, 1, -12 }, // 0x4C 'L'
|
||||
{ 527, 13, 13, 15, 1, -12 }, // 0x4D 'M'
|
||||
{ 549, 11, 13, 13, 1, -12 }, // 0x4E 'N'
|
||||
{ 567, 13, 13, 14, 1, -12 }, // 0x4F 'O'
|
||||
{ 589, 10, 13, 12, 1, -12 }, // 0x50 'P'
|
||||
{ 606, 13, 14, 14, 1, -12 }, // 0x51 'Q'
|
||||
{ 629, 12, 13, 13, 1, -12 }, // 0x52 'R'
|
||||
{ 649, 10, 13, 12, 1, -12 }, // 0x53 'S'
|
||||
{ 666, 9, 13, 11, 1, -12 }, // 0x54 'T'
|
||||
{ 681, 11, 13, 13, 1, -12 }, // 0x55 'U'
|
||||
{ 699, 11, 13, 12, 0, -12 }, // 0x56 'V'
|
||||
{ 717, 17, 13, 17, 0, -12 }, // 0x57 'W'
|
||||
{ 745, 12, 13, 12, 0, -12 }, // 0x58 'X'
|
||||
{ 765, 12, 13, 12, 0, -12 }, // 0x59 'Y'
|
||||
{ 785, 10, 13, 11, 1, -12 }, // 0x5A 'Z'
|
||||
{ 802, 3, 17, 5, 1, -12 }, // 0x5B '['
|
||||
{ 809, 5, 13, 5, 0, -12 }, // 0x5C '\'
|
||||
{ 818, 3, 17, 5, 0, -12 }, // 0x5D ']'
|
||||
{ 825, 7, 7, 8, 1, -12 }, // 0x5E '^'
|
||||
{ 832, 10, 1, 10, 0, 3 }, // 0x5F '_'
|
||||
{ 834, 4, 3, 5, 0, -12 }, // 0x60 '`'
|
||||
{ 836, 9, 10, 10, 1, -9 }, // 0x61 'a'
|
||||
{ 848, 9, 13, 10, 1, -12 }, // 0x62 'b'
|
||||
{ 863, 8, 10, 9, 1, -9 }, // 0x63 'c'
|
||||
{ 873, 8, 13, 10, 1, -12 }, // 0x64 'd'
|
||||
{ 886, 8, 10, 10, 1, -9 }, // 0x65 'e'
|
||||
{ 896, 4, 13, 5, 1, -12 }, // 0x66 'f'
|
||||
{ 903, 8, 14, 10, 1, -9 }, // 0x67 'g'
|
||||
{ 917, 8, 13, 10, 1, -12 }, // 0x68 'h'
|
||||
{ 930, 2, 13, 4, 1, -12 }, // 0x69 'i'
|
||||
{ 934, 4, 17, 4, 0, -12 }, // 0x6A 'j'
|
||||
{ 943, 9, 13, 9, 1, -12 }, // 0x6B 'k'
|
||||
{ 958, 2, 13, 4, 1, -12 }, // 0x6C 'l'
|
||||
{ 962, 13, 10, 15, 1, -9 }, // 0x6D 'm'
|
||||
{ 979, 8, 10, 10, 1, -9 }, // 0x6E 'n'
|
||||
{ 989, 8, 10, 10, 1, -9 }, // 0x6F 'o'
|
||||
{ 999, 9, 13, 10, 1, -9 }, // 0x70 'p'
|
||||
{ 1014, 8, 13, 10, 1, -9 }, // 0x71 'q'
|
||||
{ 1027, 5, 10, 6, 1, -9 }, // 0x72 'r'
|
||||
{ 1034, 8, 10, 9, 1, -9 }, // 0x73 's'
|
||||
{ 1044, 4, 12, 5, 1, -11 }, // 0x74 't'
|
||||
{ 1050, 8, 10, 10, 1, -9 }, // 0x75 'u'
|
||||
{ 1060, 9, 10, 9, 0, -9 }, // 0x76 'v'
|
||||
{ 1072, 13, 10, 13, 0, -9 }, // 0x77 'w'
|
||||
{ 1089, 8, 10, 9, 0, -9 }, // 0x78 'x'
|
||||
{ 1099, 9, 14, 9, 0, -9 }, // 0x79 'y'
|
||||
{ 1115, 7, 10, 9, 1, -9 }, // 0x7A 'z'
|
||||
{ 1124, 4, 17, 6, 1, -12 }, // 0x7B '{'
|
||||
{ 1133, 2, 17, 4, 2, -12 }, // 0x7C '|'
|
||||
{ 1138, 4, 17, 6, 1, -12 }, // 0x7D '}'
|
||||
{ 1147, 7, 3, 9, 1, -7 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont FreeSans9pt7b PROGMEM = {
|
||||
(uint8_t *)FreeSans9pt7bBitmaps,
|
||||
(GFXglyph *)FreeSans9pt7bGlyphs,
|
||||
0x20, 0x7E, 22 };
|
||||
|
||||
// Approx. 1822 bytes
|
421
RX_FSK/src/fonts/FreeSans9pt8b.h
Normal file
421
RX_FSK/src/fonts/FreeSans9pt8b.h
Normal file
|
@ -0,0 +1,421 @@
|
|||
const uint8_t FreeSans9pt8bBitmaps[] PROGMEM = {
|
||||
0x00, 0xFF, 0xFF, 0x83, 0xC0, 0xDD, 0xD9, 0x90, 0x09, 0x82, 0x61, 0x90,
|
||||
0x64, 0x7F, 0xC4, 0xC1, 0x30, 0xC8, 0xFF, 0xBF, 0xE2, 0x20, 0x98, 0x26,
|
||||
0x00, 0x10, 0x3C, 0x76, 0xD3, 0x93, 0xD0, 0xF0, 0x7C, 0x17, 0x13, 0x91,
|
||||
0x91, 0xD3, 0x7E, 0x10, 0x10, 0x00, 0x21, 0xE1, 0x08, 0x84, 0x23, 0x20,
|
||||
0x8C, 0x83, 0x64, 0x07, 0x10, 0x00, 0x8E, 0x06, 0x6C, 0x13, 0x10, 0xCC,
|
||||
0x42, 0x11, 0x18, 0x78, 0x1C, 0x0F, 0x86, 0x21, 0x88, 0x36, 0x0F, 0x03,
|
||||
0x81, 0xB2, 0xC6, 0xA0, 0xEC, 0x13, 0x1E, 0x7C, 0xC0, 0xFE, 0x80, 0x12,
|
||||
0x26, 0x44, 0xCC, 0xCC, 0x44, 0x46, 0x22, 0x10, 0x84, 0x46, 0x22, 0x23,
|
||||
0x33, 0x22, 0x26, 0x4C, 0x80, 0x25, 0x5C, 0xA5, 0x00, 0x08, 0x04, 0x02,
|
||||
0x01, 0x0F, 0xF8, 0x40, 0x20, 0x10, 0x08, 0x00, 0xF0, 0xFF, 0xC0, 0x08,
|
||||
0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00, 0x18, 0x7E, 0x42, 0xC3,
|
||||
0xC3, 0x83, 0x83, 0x83, 0x83, 0xC3, 0xC3, 0x46, 0x7C, 0x11, 0x7F, 0x11,
|
||||
0x11, 0x11, 0x11, 0x10, 0x3C, 0x7E, 0xC3, 0xC1, 0x81, 0x03, 0x06, 0x1C,
|
||||
0x30, 0x60, 0xC0, 0xFF, 0xFF, 0x3C, 0x7E, 0xC3, 0xC3, 0x03, 0x06, 0x1C,
|
||||
0x03, 0x03, 0x83, 0x83, 0xC3, 0x7E, 0x02, 0x03, 0x01, 0x81, 0x41, 0xA1,
|
||||
0x90, 0x88, 0xC4, 0xC2, 0x7F, 0xC0, 0x80, 0x40, 0x20, 0x7F, 0x7F, 0x40,
|
||||
0x40, 0xC0, 0xFE, 0xC3, 0x03, 0x01, 0x01, 0x83, 0xC3, 0x7E, 0x1C, 0x7E,
|
||||
0x43, 0xC3, 0xC0, 0xBC, 0xFE, 0xC3, 0xC1, 0xC1, 0xC3, 0x63, 0x7E, 0xFF,
|
||||
0xFF, 0x03, 0x02, 0x04, 0x0C, 0x08, 0x18, 0x10, 0x30, 0x30, 0x20, 0x20,
|
||||
0x3C, 0x7E, 0xC3, 0xC3, 0xC3, 0x66, 0x7C, 0xC3, 0x83, 0x81, 0x83, 0xC3,
|
||||
0x7E, 0x38, 0x7E, 0xC2, 0x83, 0x83, 0x83, 0xC3, 0x7D, 0x13, 0x03, 0xC3,
|
||||
0xC6, 0x7C, 0xC0, 0x03, 0xC0, 0xC0, 0x03, 0xD6, 0x00, 0x01, 0xC3, 0x8F,
|
||||
0x0C, 0x07, 0x00, 0xF0, 0x0E, 0x01, 0x80, 0xFF, 0x80, 0x00, 0x1F, 0xF0,
|
||||
0x00, 0x60, 0x1E, 0x01, 0xC0, 0x38, 0x3C, 0x71, 0xE0, 0x80, 0x00, 0x3E,
|
||||
0x63, 0x43, 0xC1, 0x03, 0x06, 0x0C, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18,
|
||||
0x07, 0xF0, 0x1C, 0x1C, 0x30, 0x0E, 0x60, 0x06, 0x43, 0xD3, 0xC6, 0x33,
|
||||
0x8C, 0x31, 0x8C, 0x23, 0x88, 0x23, 0x8C, 0x62, 0xCC, 0xEC, 0xC7, 0x38,
|
||||
0x60, 0x00, 0x38, 0x00, 0x0F, 0xF0, 0x01, 0x80, 0x06, 0x00, 0xF0, 0x0F,
|
||||
0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x06, 0x60,
|
||||
0x66, 0x06, 0xC0, 0x30, 0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xB0, 0xEF,
|
||||
0xFB, 0x03, 0xC0, 0xF0, 0x1C, 0x0F, 0x07, 0xFF, 0x00, 0x1F, 0x86, 0x19,
|
||||
0x81, 0xE0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x78, 0x0D, 0x81,
|
||||
0xB8, 0x63, 0xF8, 0xFE, 0x20, 0xC8, 0x1A, 0x03, 0x80, 0xE0, 0x38, 0x0E,
|
||||
0x03, 0x80, 0xE0, 0x38, 0x1A, 0x1C, 0xFE, 0x00, 0xFF, 0xC0, 0x20, 0x10,
|
||||
0x08, 0x04, 0x03, 0xFD, 0x00, 0x80, 0x40, 0x20, 0x10, 0x0F, 0xF8, 0xFF,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x1F, 0x83, 0x0E, 0x60, 0x6C, 0x03, 0xC0, 0x0C, 0x00, 0x83, 0xFC, 0x3F,
|
||||
0xC0, 0x3C, 0x03, 0x60, 0x77, 0x0F, 0x1F, 0x90, 0xC0, 0x78, 0x0F, 0x01,
|
||||
0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0,
|
||||
0x3C, 0x06, 0xFF, 0xF8, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0xC3, 0xC3, 0x66, 0x7E, 0xC0, 0xD8, 0x33, 0x0C, 0x63, 0x0C, 0xC1,
|
||||
0xB8, 0x3F, 0x07, 0x30, 0xC3, 0x18, 0x63, 0x06, 0x60, 0x6C, 0x04, 0xC0,
|
||||
0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18,
|
||||
0x0F, 0xF8, 0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F,
|
||||
0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71, 0x80,
|
||||
0xE0, 0x7C, 0x0F, 0xC1, 0xEC, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3,
|
||||
0x78, 0x2F, 0x07, 0xE0, 0x7C, 0x0E, 0x1F, 0x87, 0x0E, 0x60, 0x6C, 0x03,
|
||||
0xC0, 0x38, 0x01, 0x80, 0x18, 0x01, 0xC0, 0x3C, 0x03, 0x60, 0x67, 0x0E,
|
||||
0x1F, 0x80, 0xFF, 0x41, 0xE0, 0x70, 0x38, 0x1C, 0x0F, 0xFD, 0x00, 0x80,
|
||||
0x40, 0x20, 0x10, 0x08, 0x00, 0x1F, 0x87, 0x0E, 0x60, 0x6C, 0x03, 0xC0,
|
||||
0x38, 0x01, 0x80, 0x18, 0x01, 0xC0, 0x3C, 0x03, 0x61, 0xE7, 0x0E, 0x1F,
|
||||
0xF0, 0x01, 0xFF, 0x20, 0x68, 0x0E, 0x03, 0x80, 0xE0, 0x6F, 0xF2, 0x06,
|
||||
0x80, 0xA0, 0x28, 0x0A, 0x03, 0x80, 0xC0, 0x3F, 0x18, 0x6C, 0x0F, 0x03,
|
||||
0xC0, 0x1E, 0x01, 0xF0, 0x0F, 0x00, 0xF0, 0x3C, 0x0D, 0x87, 0x3F, 0x80,
|
||||
0xFF, 0xE0, 0x80, 0x10, 0x02, 0x00, 0x40, 0x08, 0x01, 0x00, 0x20, 0x04,
|
||||
0x00, 0x80, 0x10, 0x02, 0x00, 0x40, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80,
|
||||
0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x3C, 0x0B, 0x86, 0x7F, 0x00, 0xC0,
|
||||
0x58, 0x1B, 0x03, 0x30, 0x46, 0x18, 0x43, 0x0C, 0x41, 0x98, 0x13, 0x03,
|
||||
0x40, 0x78, 0x07, 0x00, 0xC0, 0x41, 0xC1, 0xB0, 0xE1, 0x98, 0x50, 0xCC,
|
||||
0x28, 0x62, 0x36, 0x31, 0x9B, 0x10, 0xC8, 0x98, 0x64, 0x6C, 0x16, 0x36,
|
||||
0x0B, 0x0A, 0x07, 0x07, 0x03, 0x83, 0x80, 0xC1, 0xC0, 0x60, 0x63, 0x0C,
|
||||
0x30, 0xC1, 0x98, 0x0F, 0x00, 0x70, 0x06, 0x00, 0xF0, 0x09, 0x81, 0x98,
|
||||
0x30, 0xC6, 0x06, 0x60, 0x60, 0x60, 0x36, 0x06, 0x30, 0xC1, 0x0C, 0x19,
|
||||
0x80, 0xD0, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
|
||||
0x00, 0x7F, 0xC0, 0x18, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x80, 0x60,
|
||||
0x18, 0x06, 0x01, 0x80, 0x30, 0x0F, 0xFE, 0xFC, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0xF0, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10,
|
||||
0x80, 0xF3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xF0, 0x30, 0x60,
|
||||
0xA2, 0x44, 0xD8, 0xA1, 0x00, 0xFF, 0xC0, 0x63, 0x3C, 0x3F, 0x30, 0x80,
|
||||
0x60, 0x73, 0xFB, 0x0D, 0x06, 0xC7, 0x7D, 0xC0, 0x80, 0x80, 0x80, 0x9C,
|
||||
0xBE, 0xC3, 0xC1, 0xC1, 0x81, 0xC1, 0xC3, 0xE3, 0xBE, 0x38, 0x7E, 0xC2,
|
||||
0x82, 0x80, 0x80, 0x80, 0x82, 0xC6, 0x7C, 0x01, 0x80, 0xC0, 0x63, 0xB3,
|
||||
0xFB, 0x0D, 0x06, 0x83, 0xC1, 0xA0, 0xD0, 0x6C, 0x73, 0xE8, 0x18, 0x7E,
|
||||
0xC3, 0xC3, 0x81, 0xFF, 0x80, 0xC3, 0xC3, 0x7E, 0x39, 0x08, 0x4F, 0x90,
|
||||
0x84, 0x21, 0x08, 0x42, 0x00, 0x38, 0x7F, 0xC7, 0x83, 0x83, 0x83, 0x83,
|
||||
0x83, 0xC7, 0x7F, 0x03, 0x82, 0xE6, 0x7C, 0xC0, 0xC0, 0xC0, 0xDC, 0xFE,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xF0, 0xFF, 0xFF, 0xC0,
|
||||
0x6C, 0x06, 0xDB, 0x6D, 0xB6, 0xDB, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC6,
|
||||
0xCC, 0xD8, 0xF8, 0xD8, 0xCC, 0xC4, 0xC6, 0xC3, 0xFF, 0xFF, 0xFF, 0xC0,
|
||||
0x1C, 0x67, 0xFF, 0xB0, 0xC7, 0x84, 0x3C, 0x21, 0xE1, 0x0F, 0x08, 0x78,
|
||||
0x43, 0xC2, 0x1E, 0x10, 0xC0, 0x1C, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0x38, 0x7E, 0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6,
|
||||
0x7E, 0x1C, 0xBE, 0xC3, 0xC1, 0xC1, 0x81, 0xC1, 0xC3, 0xE3, 0xBE, 0x80,
|
||||
0x80, 0x80, 0x80, 0x1C, 0x1F, 0x58, 0x68, 0x34, 0x1E, 0x0D, 0x06, 0x83,
|
||||
0x63, 0x9F, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x1F, 0xF9, 0x8C, 0x63, 0x18,
|
||||
0xC6, 0x00, 0x39, 0xFB, 0x1C, 0x0E, 0x07, 0x81, 0xC1, 0xC7, 0xF8, 0x21,
|
||||
0x09, 0xF2, 0x10, 0x84, 0x21, 0x08, 0x70, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC7, 0x7F, 0x41, 0x31, 0x98, 0xC4, 0x42, 0x61, 0xA0, 0x50,
|
||||
0x38, 0x18, 0x00, 0xC7, 0x12, 0x38, 0x99, 0x4C, 0xCA, 0x62, 0xDA, 0x14,
|
||||
0xD0, 0xE3, 0x87, 0x18, 0x18, 0xC0, 0x63, 0x13, 0x0D, 0x03, 0x81, 0xC0,
|
||||
0xE0, 0xD8, 0xC6, 0x43, 0x00, 0x41, 0x31, 0x98, 0xC4, 0x43, 0x61, 0xA0,
|
||||
0x50, 0x38, 0x18, 0x0C, 0x06, 0x0E, 0x06, 0x00, 0xFE, 0x08, 0x30, 0xC3,
|
||||
0x0C, 0x10, 0x60, 0xFE, 0x36, 0x66, 0x66, 0x4C, 0x84, 0x66, 0x66, 0x66,
|
||||
0x30, 0xFF, 0xFF, 0x80, 0xC4, 0x44, 0x44, 0x46, 0x36, 0x44, 0x44, 0x44,
|
||||
0x80, 0x60, 0x59, 0x8F, 0xFF, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03,
|
||||
0x01, 0x80, 0xC0, 0x60, 0x30, 0x1F, 0xF8, 0x00, 0xF0, 0x7F, 0xFF, 0xC0,
|
||||
0x08, 0x1C, 0x7E, 0x4B, 0xC9, 0xC8, 0xC8, 0xC8, 0xCB, 0x6B, 0x3E, 0x08,
|
||||
0x08, 0x1F, 0x0C, 0xE6, 0x19, 0x82, 0x60, 0x08, 0x0F, 0xE0, 0x40, 0x10,
|
||||
0x04, 0x03, 0x01, 0xF2, 0x7F, 0xC0, 0x07, 0x07, 0xF3, 0x04, 0x80, 0x60,
|
||||
0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x18, 0x03, 0x00, 0x61, 0x0F, 0xC0, 0xC0,
|
||||
0xD0, 0x22, 0x18, 0xCC, 0x12, 0x07, 0x80, 0xC1, 0xFE, 0x0C, 0x1F, 0xE0,
|
||||
0xC0, 0x30, 0x0C, 0x00, 0x12, 0x07, 0x80, 0xC0, 0x00, 0x3F, 0x18, 0x6C,
|
||||
0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0F, 0x00, 0xF0, 0x3C, 0x0D, 0x87,
|
||||
0x3F, 0x80, 0x3C, 0x66, 0x62, 0x62, 0x30, 0x5C, 0x8E, 0x83, 0xC1, 0x61,
|
||||
0x3B, 0x1E, 0x06, 0xC6, 0x46, 0x7E, 0x38, 0x6C, 0x70, 0x41, 0xCF, 0xD8,
|
||||
0xE0, 0x70, 0x3C, 0x0E, 0x0E, 0x3F, 0xC0, 0x1F, 0xC0, 0xC1, 0x86, 0x31,
|
||||
0x33, 0x66, 0x88, 0xCA, 0x60, 0x29, 0x80, 0xE6, 0x12, 0x88, 0xCB, 0x36,
|
||||
0x66, 0x71, 0x0C, 0x18, 0x1F, 0xC0, 0xF4, 0x9D, 0x29, 0x74, 0x1F, 0x21,
|
||||
0x99, 0xA6, 0x4C, 0x90, 0xFF, 0xFF, 0xC0, 0x20, 0x10, 0x08, 0xFF, 0x1F,
|
||||
0xC0, 0xC1, 0x86, 0xF1, 0x33, 0xF6, 0x88, 0x4A, 0x23, 0x28, 0xF8, 0xE2,
|
||||
0x32, 0x88, 0xCB, 0x23, 0x66, 0x01, 0x0C, 0x18, 0x1F, 0xC0, 0xFF, 0xC0,
|
||||
0xF4, 0x63, 0x17, 0x00, 0x08, 0x04, 0x02, 0x01, 0x0F, 0xF8, 0x40, 0x20,
|
||||
0x10, 0x08, 0x00, 0x3F, 0xE0, 0x39, 0x34, 0x43, 0x19, 0x84, 0x3F, 0x31,
|
||||
0x2C, 0xC6, 0x08, 0x1C, 0xDE, 0x11, 0x01, 0x60, 0x18, 0x00, 0x07, 0xFC,
|
||||
0x01, 0x80, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x06, 0x01, 0x80, 0x60,
|
||||
0x18, 0x03, 0x00, 0xFF, 0xE0, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B,
|
||||
0x0D, 0x8E, 0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x00, 0x3F, 0x7A, 0xFA, 0xFA,
|
||||
0xFA, 0xFA, 0xFA, 0x7A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
|
||||
0xC0, 0x6C, 0x50, 0x40, 0x0F, 0xE0, 0x83, 0x0C, 0x30, 0xC1, 0x06, 0x0F,
|
||||
0xE0, 0x27, 0x92, 0x49, 0xF4, 0x63, 0x19, 0x38, 0x1F, 0x93, 0x26, 0x59,
|
||||
0x98, 0x40, 0x3F, 0xFF, 0x71, 0xC0, 0x40, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
|
||||
0x80, 0xC0, 0x80, 0xFF, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x40, 0xC0,
|
||||
0x61, 0xC0, 0x3F, 0xFF, 0x38, 0x30, 0xFD, 0xFB, 0x0E, 0x1C, 0x18, 0x38,
|
||||
0x10, 0x70, 0x3F, 0xE0, 0x40, 0x61, 0x83, 0xC7, 0x84, 0xFD, 0xF8, 0x19,
|
||||
0x81, 0x98, 0x00, 0x06, 0x03, 0x60, 0x63, 0x0C, 0x10, 0xC1, 0x98, 0x0D,
|
||||
0x00, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x18,
|
||||
0x18, 0x00, 0x00, 0x18, 0x18, 0x30, 0x60, 0xC0, 0x83, 0xC2, 0xC6, 0x7C,
|
||||
0x0C, 0x00, 0x40, 0x02, 0x00, 0x00, 0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90,
|
||||
0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x06, 0x60, 0x66, 0x06,
|
||||
0xC0, 0x30, 0x01, 0x80, 0x30, 0x06, 0x00, 0x00, 0x06, 0x00, 0xF0, 0x0F,
|
||||
0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x06, 0x60,
|
||||
0x66, 0x06, 0xC0, 0x30, 0x06, 0x00, 0xF0, 0x09, 0x00, 0x00, 0x06, 0x00,
|
||||
0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2,
|
||||
0x06, 0x60, 0x66, 0x06, 0xC0, 0x30, 0x0C, 0x81, 0x30, 0x00, 0x00, 0x60,
|
||||
0x0F, 0x00, 0xF0, 0x09, 0x01, 0x98, 0x19, 0x81, 0x08, 0x30, 0xC3, 0xFC,
|
||||
0x20, 0x66, 0x06, 0x60, 0x6C, 0x03, 0x19, 0x81, 0x98, 0x00, 0x00, 0x60,
|
||||
0x0F, 0x00, 0xF0, 0x09, 0x01, 0x98, 0x19, 0x81, 0x08, 0x30, 0xC3, 0xFC,
|
||||
0x20, 0x66, 0x06, 0x60, 0x6C, 0x03, 0x0F, 0x00, 0x90, 0x0F, 0x00, 0x00,
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C,
|
||||
0x3F, 0xC2, 0x06, 0x60, 0x66, 0x06, 0xC0, 0x30, 0x07, 0xFF, 0x83, 0x60,
|
||||
0x01, 0x30, 0x01, 0x98, 0x00, 0x8C, 0x00, 0xC6, 0x00, 0x63, 0xFC, 0x61,
|
||||
0x80, 0x3F, 0xC0, 0x10, 0x60, 0x18, 0x30, 0x0C, 0x18, 0x0C, 0x0F, 0xF8,
|
||||
0x1F, 0x86, 0x19, 0x81, 0xE0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0,
|
||||
0x78, 0x0D, 0x81, 0xB8, 0x63, 0xF8, 0x08, 0x01, 0x80, 0x10, 0x0E, 0x00,
|
||||
0x30, 0x08, 0x02, 0x00, 0x0F, 0xFC, 0x02, 0x01, 0x00, 0x80, 0x40, 0x3F,
|
||||
0xD0, 0x08, 0x04, 0x02, 0x01, 0x00, 0xFF, 0x80, 0x04, 0x04, 0x04, 0x00,
|
||||
0x0F, 0xFC, 0x02, 0x01, 0x00, 0x80, 0x40, 0x3F, 0xD0, 0x08, 0x04, 0x02,
|
||||
0x01, 0x00, 0xFF, 0x80, 0x18, 0x0E, 0x09, 0x00, 0x0F, 0xFC, 0x02, 0x01,
|
||||
0x00, 0x80, 0x40, 0x3F, 0xD0, 0x08, 0x04, 0x02, 0x01, 0x00, 0xFF, 0x80,
|
||||
0x66, 0x33, 0x00, 0x1F, 0xF8, 0x04, 0x02, 0x01, 0x00, 0x80, 0x7F, 0xA0,
|
||||
0x10, 0x08, 0x04, 0x02, 0x01, 0xFF, 0xC6, 0x20, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x20, 0x36, 0x40, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40,
|
||||
0x32, 0xB2, 0x02, 0x10, 0x84, 0x21, 0x08, 0x42, 0x10, 0x84, 0x20, 0xCF,
|
||||
0x30, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x20, 0x82, 0x08, 0x3F,
|
||||
0x82, 0x0C, 0x20, 0x62, 0x03, 0x20, 0x32, 0x03, 0xFC, 0x32, 0x03, 0x20,
|
||||
0x32, 0x03, 0x20, 0x62, 0x1C, 0x3F, 0x80, 0x09, 0x03, 0xE0, 0x00, 0x70,
|
||||
0x3E, 0x07, 0xE0, 0xF6, 0x1E, 0xC3, 0xCC, 0x78, 0x8F, 0x19, 0xE1, 0xBC,
|
||||
0x17, 0x83, 0xF0, 0x3E, 0x07, 0x0C, 0x00, 0x40, 0x02, 0x00, 0x00, 0x1F,
|
||||
0x87, 0x0E, 0x60, 0x6C, 0x03, 0xC0, 0x38, 0x01, 0x80, 0x18, 0x01, 0xC0,
|
||||
0x3C, 0x03, 0x60, 0x67, 0x0E, 0x1F, 0x80, 0x03, 0x00, 0x20, 0x04, 0x00,
|
||||
0x00, 0x1F, 0x87, 0x0E, 0x60, 0x6C, 0x03, 0xC0, 0x38, 0x01, 0x80, 0x18,
|
||||
0x01, 0xC0, 0x3C, 0x03, 0x60, 0x67, 0x0E, 0x1F, 0x80, 0x06, 0x00, 0xF0,
|
||||
0x09, 0x00, 0x00, 0x1F, 0x87, 0x0E, 0x60, 0x6C, 0x03, 0xC0, 0x38, 0x01,
|
||||
0x80, 0x18, 0x01, 0xC0, 0x3C, 0x03, 0x60, 0x67, 0x0E, 0x1F, 0x80, 0x0C,
|
||||
0x81, 0x30, 0x00, 0x01, 0xF8, 0x70, 0xE6, 0x06, 0xC0, 0x3C, 0x03, 0x80,
|
||||
0x18, 0x01, 0x80, 0x1C, 0x03, 0xC0, 0x36, 0x06, 0x70, 0xE1, 0xF8, 0x19,
|
||||
0x81, 0x98, 0x00, 0x01, 0xF8, 0x70, 0xE6, 0x06, 0xC0, 0x3C, 0x03, 0x80,
|
||||
0x18, 0x01, 0x80, 0x1C, 0x03, 0xC0, 0x36, 0x06, 0x70, 0xE1, 0xF8, 0x81,
|
||||
0x89, 0xA1, 0x83, 0x89, 0xA1, 0x80, 0x00, 0x01, 0xF9, 0x70, 0xE6, 0x06,
|
||||
0xC0, 0xBC, 0x13, 0x82, 0x18, 0x41, 0x8C, 0x1D, 0x83, 0xF0, 0x36, 0x06,
|
||||
0x70, 0xE9, 0xF8, 0x30, 0x06, 0x00, 0x80, 0x00, 0x80, 0xE0, 0x38, 0x0E,
|
||||
0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x3C, 0x0B, 0x86, 0x7F,
|
||||
0x00, 0x06, 0x03, 0x00, 0x80, 0x00, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80,
|
||||
0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x3C, 0x0B, 0x86, 0x7F, 0x00, 0x0C,
|
||||
0x05, 0x03, 0x20, 0x00, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38,
|
||||
0x0E, 0x03, 0x80, 0xE0, 0x3C, 0x0B, 0x86, 0x7F, 0x00, 0x33, 0x0C, 0xC0,
|
||||
0x02, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
|
||||
0x80, 0xF0, 0x2E, 0x19, 0xFC, 0x01, 0x00, 0x20, 0x04, 0x00, 0x00, 0x60,
|
||||
0x36, 0x06, 0x30, 0xC1, 0x0C, 0x19, 0x80, 0xD0, 0x0F, 0x00, 0x60, 0x06,
|
||||
0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x80, 0x40, 0x3F, 0x9F, 0xE8,
|
||||
0x1C, 0x0E, 0x07, 0x03, 0xFF, 0x7E, 0x20, 0x10, 0x08, 0x00, 0x3E, 0x31,
|
||||
0xB0, 0x78, 0x3C, 0x16, 0x7B, 0x3D, 0x83, 0xC0, 0xE0, 0x70, 0x78, 0x7C,
|
||||
0xF0, 0x30, 0x0C, 0x02, 0x07, 0x87, 0xE6, 0x10, 0x0C, 0x0E, 0x7F, 0x61,
|
||||
0xA0, 0xD8, 0xEF, 0xB8, 0x0C, 0x0C, 0x04, 0x07, 0x87, 0xE6, 0x10, 0x0C,
|
||||
0x0E, 0x7F, 0x61, 0xA0, 0xD8, 0xEF, 0xB8, 0x18, 0x16, 0x19, 0x07, 0x87,
|
||||
0xE6, 0x10, 0x0C, 0x0E, 0x7F, 0x61, 0xA0, 0xD8, 0xEF, 0xB8, 0x32, 0x3E,
|
||||
0x00, 0x07, 0x87, 0xE6, 0x10, 0x0C, 0x0E, 0x7F, 0x61, 0xA0, 0xD8, 0xEF,
|
||||
0xB8, 0x66, 0x33, 0x00, 0x07, 0x87, 0xE6, 0x10, 0x0C, 0x0E, 0x7F, 0x61,
|
||||
0xA0, 0xD8, 0xEF, 0xB8, 0x18, 0x12, 0x09, 0x03, 0x03, 0xC3, 0xF3, 0x08,
|
||||
0x06, 0x07, 0x3F, 0xB0, 0xD0, 0x6C, 0x77, 0xDC, 0x38, 0x71, 0xFF, 0xEC,
|
||||
0x30, 0xC0, 0xC1, 0x06, 0x05, 0xFF, 0xFC, 0x20, 0x20, 0xC1, 0xC7, 0x8F,
|
||||
0xE7, 0xE0, 0x38, 0x7E, 0xC2, 0x82, 0x80, 0x80, 0x80, 0x83, 0xC6, 0x7C,
|
||||
0x10, 0x18, 0x08, 0x78, 0x30, 0x18, 0x08, 0x18, 0x7E, 0xC3, 0xC3, 0x81,
|
||||
0xFF, 0x80, 0xC3, 0xC3, 0x7E, 0x0C, 0x18, 0x10, 0x18, 0x7E, 0xC3, 0xC3,
|
||||
0x81, 0xFF, 0x80, 0xC3, 0xC3, 0x7E, 0x18, 0x34, 0x22, 0x18, 0x7E, 0xC3,
|
||||
0xC3, 0x81, 0xFF, 0x80, 0xC3, 0xC3, 0x7E, 0x66, 0x66, 0x00, 0x18, 0x7E,
|
||||
0xC3, 0xC3, 0x81, 0xFF, 0x80, 0xC3, 0xC3, 0x7E, 0x42, 0x10, 0x22, 0x22,
|
||||
0x22, 0x22, 0x20, 0x6C, 0x80, 0x44, 0x44, 0x44, 0x44, 0x40, 0x72, 0xA2,
|
||||
0x02, 0x10, 0x84, 0x21, 0x08, 0x42, 0x00, 0xCF, 0x30, 0x00, 0x10, 0x41,
|
||||
0x04, 0x10, 0x41, 0x04, 0x10, 0x6C, 0x30, 0x4C, 0x3E, 0x7E, 0xC3, 0x83,
|
||||
0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E, 0x32, 0x7C, 0x00, 0x1C, 0xFE, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x30, 0x10, 0x08, 0x38, 0x7E,
|
||||
0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E, 0x0C, 0x18, 0x10, 0x38,
|
||||
0x7E, 0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E, 0x18, 0x2C, 0x64,
|
||||
0x38, 0x7E, 0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E, 0x32, 0x5C,
|
||||
0x00, 0x38, 0x7E, 0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E, 0x66,
|
||||
0x66, 0x00, 0x38, 0x7E, 0xC3, 0x83, 0x81, 0x81, 0x81, 0xC3, 0xC6, 0x7E,
|
||||
0x18, 0x0C, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x30, 0x18, 0x00, 0x1C,
|
||||
0x0F, 0xE6, 0x19, 0x8E, 0x44, 0x92, 0x25, 0x09, 0xC6, 0x63, 0x1F, 0xC0,
|
||||
0x00, 0x30, 0x10, 0x08, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC7, 0x7F, 0x0C, 0x18, 0x10, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC7, 0x7F, 0x18, 0x2C, 0x64, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC7, 0x7F, 0x66, 0x66, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC7, 0x7F, 0x0C, 0x04, 0x04, 0x00, 0x04, 0x13, 0x19,
|
||||
0x8C, 0x44, 0x36, 0x1A, 0x05, 0x03, 0x81, 0x80, 0xC0, 0x60, 0xE0, 0x60,
|
||||
0x00, 0x80, 0x80, 0x80, 0x9C, 0xBE, 0xC3, 0xC1, 0xC1, 0x81, 0xC1, 0xC3,
|
||||
0xE3, 0xBE, 0x80, 0x80, 0x80, 0x80, 0x22, 0x11, 0x00, 0x00, 0x04, 0x13,
|
||||
0x19, 0x8C, 0x44, 0x36, 0x1A, 0x05, 0x03, 0x81, 0x80, 0xC0, 0x60, 0xE0,
|
||||
0x60, 0x00 };
|
||||
|
||||
const GFXglyph FreeSans9pt8bGlyphs[] PROGMEM = {
|
||||
{ 0, 1, 1, 5, 0, 0 }, // 0x20 ' ' U+0020
|
||||
{ 1, 2, 13, 5, 2, -12 }, // 0x21 '!' U+0021
|
||||
{ 5, 4, 5, 6, 1, -12 }, // 0x22 '"' U+0022
|
||||
{ 8, 10, 13, 10, 0, -12 }, // 0x23 '#' U+0023
|
||||
{ 25, 8, 16, 10, 1, -13 }, // 0x24 '$' U+0024
|
||||
{ 41, 14, 13, 16, 1, -12 }, // 0x25 '%' U+0025
|
||||
{ 64, 10, 13, 12, 1, -12 }, // 0x26 '&' U+0026
|
||||
{ 81, 2, 5, 3, 1, -12 }, // 0x27 ''' U+0027
|
||||
{ 83, 4, 17, 6, 1, -12 }, // 0x28 '(' U+0028
|
||||
{ 92, 4, 17, 6, 1, -12 }, // 0x29 ')' U+0029
|
||||
{ 101, 5, 5, 7, 1, -12 }, // 0x2a '*' U+002A
|
||||
{ 105, 9, 9, 11, 1, -8 }, // 0x2b '+' U+002B
|
||||
{ 116, 1, 5, 5, 2, -1 }, // 0x2c ',' U+002C
|
||||
{ 117, 4, 2, 6, 1, -5 }, // 0x2d '-' U+002D
|
||||
{ 118, 1, 2, 5, 2, -1 }, // 0x2e '.' U+002E
|
||||
{ 119, 5, 13, 5, 0, -12 }, // 0x2f '/' U+002F
|
||||
{ 128, 8, 13, 10, 1, -12 }, // 0x30 '0' U+0030
|
||||
{ 141, 4, 13, 10, 2, -12 }, // 0x31 '1' U+0031
|
||||
{ 148, 8, 13, 10, 1, -12 }, // 0x32 '2' U+0032
|
||||
{ 161, 8, 13, 10, 1, -12 }, // 0x33 '3' U+0033
|
||||
{ 174, 9, 13, 10, 0, -12 }, // 0x34 '4' U+0034
|
||||
{ 189, 8, 13, 10, 1, -12 }, // 0x35 '5' U+0035
|
||||
{ 202, 8, 13, 10, 1, -12 }, // 0x36 '6' U+0036
|
||||
{ 215, 8, 13, 10, 1, -12 }, // 0x37 '7' U+0037
|
||||
{ 228, 8, 13, 10, 1, -12 }, // 0x38 '8' U+0038
|
||||
{ 241, 8, 13, 10, 1, -12 }, // 0x39 '9' U+0039
|
||||
{ 254, 2, 9, 5, 2, -8 }, // 0x3a ':' U+003A
|
||||
{ 257, 2, 12, 5, 2, -8 }, // 0x3b ';' U+003B
|
||||
{ 260, 9, 9, 11, 1, -8 }, // 0x3c '<' U+003C
|
||||
{ 271, 9, 4, 11, 1, -5 }, // 0x3d '=' U+003D
|
||||
{ 276, 9, 9, 11, 1, -8 }, // 0x3e '>' U+003E
|
||||
{ 287, 8, 13, 10, 1, -12 }, // 0x3f '?' U+003F
|
||||
{ 300, 16, 16, 18, 1, -12 }, // 0x40 '@' U+0040
|
||||
{ 332, 12, 13, 12, 0, -12 }, // 0x41 'A' U+0041
|
||||
{ 352, 10, 13, 12, 1, -12 }, // 0x42 'B' U+0042
|
||||
{ 369, 11, 13, 13, 1, -12 }, // 0x43 'C' U+0043
|
||||
{ 387, 10, 13, 13, 2, -12 }, // 0x44 'D' U+0044
|
||||
{ 404, 9, 13, 12, 2, -12 }, // 0x45 'E' U+0045
|
||||
{ 419, 8, 13, 11, 2, -12 }, // 0x46 'F' U+0046
|
||||
{ 432, 12, 13, 14, 1, -12 }, // 0x47 'G' U+0047
|
||||
{ 452, 11, 13, 13, 1, -12 }, // 0x48 'H' U+0048
|
||||
{ 470, 1, 13, 5, 2, -12 }, // 0x49 'I' U+0049
|
||||
{ 472, 8, 13, 9, 0, -12 }, // 0x4a 'J' U+004A
|
||||
{ 485, 11, 13, 12, 1, -12 }, // 0x4b 'K' U+004B
|
||||
{ 503, 9, 13, 10, 1, -12 }, // 0x4c 'L' U+004C
|
||||
{ 518, 13, 13, 15, 1, -12 }, // 0x4d 'M' U+004D
|
||||
{ 540, 11, 13, 13, 1, -12 }, // 0x4e 'N' U+004E
|
||||
{ 558, 12, 13, 14, 1, -12 }, // 0x4f 'O' U+004F
|
||||
{ 578, 9, 13, 12, 2, -12 }, // 0x50 'P' U+0050
|
||||
{ 593, 12, 14, 14, 1, -12 }, // 0x51 'Q' U+0051
|
||||
{ 614, 10, 13, 13, 2, -12 }, // 0x52 'R' U+0052
|
||||
{ 631, 10, 13, 12, 1, -12 }, // 0x53 'S' U+0053
|
||||
{ 648, 11, 13, 11, 0, -12 }, // 0x54 'T' U+0054
|
||||
{ 666, 10, 13, 13, 2, -12 }, // 0x55 'U' U+0055
|
||||
{ 683, 11, 13, 12, 1, -12 }, // 0x56 'V' U+0056
|
||||
{ 701, 17, 13, 17, 0, -12 }, // 0x57 'W' U+0057
|
||||
{ 729, 12, 13, 12, 0, -12 }, // 0x58 'X' U+0058
|
||||
{ 749, 12, 13, 12, 0, -12 }, // 0x59 'Y' U+0059
|
||||
{ 769, 11, 13, 11, 0, -12 }, // 0x5a 'Z' U+005A
|
||||
{ 787, 4, 17, 5, 1, -12 }, // 0x5b '[' U+005B
|
||||
{ 796, 5, 13, 5, 0, -12 }, // 0x5c '\' U+005C
|
||||
{ 805, 4, 17, 5, 0, -12 }, // 0x5d ']' U+005D
|
||||
{ 814, 7, 7, 8, 1, -12 }, // 0x5e '^' U+005E
|
||||
{ 821, 10, 1, 10, 0, 3 }, // 0x5f '_' U+005F
|
||||
{ 823, 4, 2, 6, 0, -12 }, // 0x60 '`' U+0060
|
||||
{ 824, 9, 10, 10, 1, -9 }, // 0x61 'a' U+0061
|
||||
{ 836, 8, 13, 10, 1, -12 }, // 0x62 'b' U+0062
|
||||
{ 849, 8, 10, 9, 1, -9 }, // 0x63 'c' U+0063
|
||||
{ 859, 9, 13, 10, 0, -12 }, // 0x64 'd' U+0064
|
||||
{ 874, 8, 10, 10, 1, -9 }, // 0x65 'e' U+0065
|
||||
{ 884, 5, 13, 5, 0, -12 }, // 0x66 'f' U+0066
|
||||
{ 893, 8, 14, 10, 1, -9 }, // 0x67 'g' U+0067
|
||||
{ 907, 8, 13, 10, 1, -12 }, // 0x68 'h' U+0068
|
||||
{ 920, 2, 13, 4, 1, -12 }, // 0x69 'i' U+0069
|
||||
{ 924, 3, 17, 4, 0, -12 }, // 0x6a 'j' U+006A
|
||||
{ 931, 8, 13, 9, 1, -12 }, // 0x6b 'k' U+006B
|
||||
{ 944, 2, 13, 4, 1, -12 }, // 0x6c 'l' U+006C
|
||||
{ 948, 13, 10, 15, 1, -9 }, // 0x6d 'm' U+006D
|
||||
{ 965, 8, 10, 10, 1, -9 }, // 0x6e 'n' U+006E
|
||||
{ 975, 8, 10, 10, 1, -9 }, // 0x6f 'o' U+006F
|
||||
{ 985, 8, 14, 10, 1, -9 }, // 0x70 'p' U+0070
|
||||
{ 999, 9, 14, 10, 0, -9 }, // 0x71 'q' U+0071
|
||||
{ 1015, 5, 10, 6, 1, -9 }, // 0x72 'r' U+0072
|
||||
{ 1022, 7, 10, 9, 1, -9 }, // 0x73 's' U+0073
|
||||
{ 1031, 5, 12, 5, 0, -11 }, // 0x74 't' U+0074
|
||||
{ 1039, 8, 9, 10, 1, -8 }, // 0x75 'u' U+0075
|
||||
{ 1048, 9, 9, 9, 0, -8 }, // 0x76 'v' U+0076
|
||||
{ 1059, 13, 9, 13, 0, -8 }, // 0x77 'w' U+0077
|
||||
{ 1074, 9, 9, 9, 0, -8 }, // 0x78 'x' U+0078
|
||||
{ 1085, 9, 13, 9, 0, -8 }, // 0x79 'y' U+0079
|
||||
{ 1100, 7, 9, 9, 1, -8 }, // 0x7a 'z' U+007A
|
||||
{ 1108, 4, 17, 6, 1, -12 }, // 0x7b '{' U+007B
|
||||
{ 1117, 1, 17, 5, 2, -12 }, // 0x7c '|' U+007C
|
||||
{ 1120, 4, 17, 6, 1, -12 }, // 0x7d '}' U+007D
|
||||
{ 1129, 8, 3, 11, 1, -7 }, // 0x7e '~' U+007E
|
||||
{ 1132, 9, 13, 13, 2, -12 }, // 0x7f 'REPLACEMENT CHARACTER *' U+2370
|
||||
{ 1147, 1, 1, 5, 0, 0 }, // 0x80 'NO-BREAK SPACE' U+00A0
|
||||
{ 1148, 2, 13, 5, 2, -8 }, // 0x81 'INVERTED EXCLAMATION MARK' U+00A1
|
||||
{ 1152, 8, 13, 10, 1, -10 }, // 0x82 'CENT SIGN' U+00A2
|
||||
{ 1165, 10, 13, 10, 0, -12 }, // 0x83 'POUND SIGN' U+00A3
|
||||
{ 1182, 10, 13, 12, 1, -12 }, // 0x84 'EURO SIGN *' U+20AC
|
||||
{ 1199, 10, 13, 10, 0, -12 }, // 0x85 'YEN SIGN' U+00A5
|
||||
{ 1216, 10, 17, 12, 1, -16 }, // 0x86 'LATIN CAPITAL LETTER S WITH CARON *' U+0160
|
||||
{ 1238, 8, 17, 10, 1, -12 }, // 0x87 'SECTION SIGN' U+00A7
|
||||
{ 1255, 7, 13, 9, 1, -12 }, // 0x88 'LATIN SMALL LETTER S WITH CARON *' U+0161
|
||||
{ 1267, 14, 13, 13, 0, -12 }, // 0x89 'COPYRIGHT SIGN' U+00A9
|
||||
{ 1290, 5, 8, 7, 1, -12 }, // 0x8a 'FEMININE ORDINAL INDICATOR' U+00AA
|
||||
{ 1295, 6, 6, 8, 1, -7 }, // 0x8b 'LEFT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00AB
|
||||
{ 1300, 9, 5, 11, 1, -6 }, // 0x8c 'NOT SIGN' U+00AC
|
||||
{ 1306, 4, 2, 6, 1, -5 }, // 0x8d 'SOFT HYPHEN' U+00AD
|
||||
{ 1307, 14, 13, 13, 0, -12 }, // 0x8e 'REGISTERED SIGN' U+00AE
|
||||
{ 1330, 5, 2, 6, 0, -12 }, // 0x8f 'MACRON' U+00AF
|
||||
{ 1332, 5, 5, 11, 3, -11 }, // 0x90 'DEGREE SIGN' U+00B0
|
||||
{ 1336, 9, 11, 11, 1, -10 }, // 0x91 'PLUS-MINUS SIGN' U+00B1
|
||||
{ 1349, 6, 8, 6, 0, -12 }, // 0x92 'SUPERSCRIPT TWO' U+00B2
|
||||
{ 1355, 6, 8, 6, 0, -12 }, // 0x93 'SUPERSCRIPT THREE' U+00B3
|
||||
{ 1361, 11, 17, 11, 0, -16 }, // 0x94 'LATIN CAPITAL LETTER Z WITH CARON *' U+017D
|
||||
{ 1385, 9, 13, 10, 1, -8 }, // 0x95 'MICRO SIGN' U+00B5
|
||||
{ 1400, 8, 16, 10, 1, -12 }, // 0x96 'PILCROW SIGN' U+00B6
|
||||
{ 1416, 1, 2, 5, 2, -5 }, // 0x97 'MIDDLE DOT' U+00B7
|
||||
{ 1417, 7, 13, 9, 1, -12 }, // 0x98 'LATIN SMALL LETTER Z WITH CARON *' U+017E
|
||||
{ 1429, 3, 8, 6, 1, -12 }, // 0x99 'SUPERSCRIPT ONE' U+00B9
|
||||
{ 1432, 5, 8, 7, 1, -12 }, // 0x9a 'MASCULINE ORDINAL INDICATOR' U+00BA
|
||||
{ 1437, 6, 6, 8, 1, -7 }, // 0x9b 'RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK' U+00BB
|
||||
{ 1442, 16, 13, 18, 1, -12 }, // 0x9c 'LATIN CAPITAL LIGATURE OE *' U+0152
|
||||
{ 1468, 15, 10, 17, 1, -9 }, // 0x9d 'LATIN SMALL LIGATURE OE *' U+0153
|
||||
{ 1487, 12, 16, 12, 0, -15 }, // 0x9e 'LATIN CAPITAL LETTER Y WITH DIAERESIS *' U+0178
|
||||
{ 1511, 8, 13, 10, 2, -8 }, // 0x9f 'INVERTED QUESTION MARK' U+00BF
|
||||
{ 1524, 12, 17, 12, 0, -16 }, // 0xa0 'LATIN CAPITAL LETTER A WITH GRAVE' U+00C0
|
||||
{ 1550, 12, 17, 12, 0, -16 }, // 0xa1 'LATIN CAPITAL LETTER A WITH ACUTE' U+00C1
|
||||
{ 1576, 12, 17, 12, 0, -16 }, // 0xa2 'LATIN CAPITAL LETTER A WITH CIRCUMFLEX' U+00C2
|
||||
{ 1602, 12, 16, 12, 0, -15 }, // 0xa3 'LATIN CAPITAL LETTER A WITH TILDE' U+00C3
|
||||
{ 1626, 12, 16, 12, 0, -15 }, // 0xa4 'LATIN CAPITAL LETTER A WITH DIAERESIS' U+00C4
|
||||
{ 1650, 12, 17, 12, 0, -16 }, // 0xa5 'LATIN CAPITAL LETTER A WITH RING ABOVE' U+00C5
|
||||
{ 1676, 17, 13, 18, 0, -12 }, // 0xa6 'LATIN CAPITAL LETTER AE' U+00C6
|
||||
{ 1704, 11, 17, 13, 1, -12 }, // 0xa7 'LATIN CAPITAL LETTER C WITH CEDILLA' U+00C7
|
||||
{ 1728, 9, 17, 12, 2, -16 }, // 0xa8 'LATIN CAPITAL LETTER E WITH GRAVE' U+00C8
|
||||
{ 1748, 9, 17, 12, 2, -16 }, // 0xa9 'LATIN CAPITAL LETTER E WITH ACUTE' U+00C9
|
||||
{ 1768, 9, 17, 12, 2, -16 }, // 0xaa 'LATIN CAPITAL LETTER E WITH CIRCUMFLEX' U+00CA
|
||||
{ 1788, 9, 16, 12, 2, -15 }, // 0xab 'LATIN CAPITAL LETTER E WITH DIAERESIS' U+00CB
|
||||
{ 1806, 4, 17, 5, 0, -16 }, // 0xac 'LATIN CAPITAL LETTER I WITH GRAVE' U+00CC
|
||||
{ 1815, 4, 17, 5, 1, -16 }, // 0xad 'LATIN CAPITAL LETTER I WITH ACUTE' U+00CD
|
||||
{ 1824, 5, 17, 5, 0, -16 }, // 0xae 'LATIN CAPITAL LETTER I WITH CIRCUMFLEX' U+00CE
|
||||
{ 1835, 6, 16, 5, 0, -15 }, // 0xaf 'LATIN CAPITAL LETTER I WITH DIAERESIS' U+00CF
|
||||
{ 1847, 12, 13, 13, 0, -12 }, // 0xb0 'LATIN CAPITAL LETTER ETH' U+00D0
|
||||
{ 1867, 11, 16, 13, 1, -15 }, // 0xb1 'LATIN CAPITAL LETTER N WITH TILDE' U+00D1
|
||||
{ 1889, 12, 17, 14, 1, -16 }, // 0xb2 'LATIN CAPITAL LETTER O WITH GRAVE' U+00D2
|
||||
{ 1915, 12, 17, 14, 1, -16 }, // 0xb3 'LATIN CAPITAL LETTER O WITH ACUTE' U+00D3
|
||||
{ 1941, 12, 17, 14, 1, -16 }, // 0xb4 'LATIN CAPITAL LETTER O WITH CIRCUMFLEX' U+00D4
|
||||
{ 1967, 12, 16, 14, 1, -15 }, // 0xb5 'LATIN CAPITAL LETTER O WITH TILDE' U+00D5
|
||||
{ 1991, 12, 16, 14, 1, -15 }, // 0xb6 'LATIN CAPITAL LETTER O WITH DIAERESIS' U+00D6
|
||||
{ 2015, 7, 7, 11, 2, -7 }, // 0xb7 'MULTIPLICATION SIGN' U+00D7
|
||||
{ 2022, 12, 14, 14, 1, -13 }, // 0xb8 'LATIN CAPITAL LETTER O WITH STROKE' U+00D8
|
||||
{ 2043, 10, 17, 13, 2, -16 }, // 0xb9 'LATIN CAPITAL LETTER U WITH GRAVE' U+00D9
|
||||
{ 2065, 10, 17, 13, 2, -16 }, // 0xba 'LATIN CAPITAL LETTER U WITH ACUTE' U+00DA
|
||||
{ 2087, 10, 17, 13, 2, -16 }, // 0xbb 'LATIN CAPITAL LETTER U WITH CIRCUMFLEX' U+00DB
|
||||
{ 2109, 10, 16, 13, 2, -15 }, // 0xbc 'LATIN CAPITAL LETTER U WITH DIAERESIS' U+00DC
|
||||
{ 2129, 12, 17, 12, 0, -16 }, // 0xbd 'LATIN CAPITAL LETTER Y WITH ACUTE' U+00DD
|
||||
{ 2155, 9, 13, 12, 2, -12 }, // 0xbe 'LATIN CAPITAL LETTER THORN' U+00DE
|
||||
{ 2170, 9, 13, 11, 1, -12 }, // 0xbf 'LATIN SMALL LETTER SHARP S' U+00DF
|
||||
{ 2185, 9, 13, 10, 1, -12 }, // 0xc0 'LATIN SMALL LETTER A WITH GRAVE' U+00E0
|
||||
{ 2200, 9, 13, 10, 1, -12 }, // 0xc1 'LATIN SMALL LETTER A WITH ACUTE' U+00E1
|
||||
{ 2215, 9, 13, 10, 1, -12 }, // 0xc2 'LATIN SMALL LETTER A WITH CIRCUMFLEX' U+00E2
|
||||
{ 2230, 9, 13, 10, 1, -12 }, // 0xc3 'LATIN SMALL LETTER A WITH TILDE' U+00E3
|
||||
{ 2245, 9, 13, 10, 1, -12 }, // 0xc4 'LATIN SMALL LETTER A WITH DIAERESIS' U+00E4
|
||||
{ 2260, 9, 14, 10, 1, -13 }, // 0xc5 'LATIN SMALL LETTER A WITH RING ABOVE' U+00E5
|
||||
{ 2276, 14, 10, 16, 1, -9 }, // 0xc6 'LATIN SMALL LETTER AE' U+00E6
|
||||
{ 2294, 8, 14, 9, 1, -9 }, // 0xc7 'LATIN SMALL LETTER C WITH CEDILLA' U+00E7
|
||||
{ 2308, 8, 13, 10, 1, -12 }, // 0xc8 'LATIN SMALL LETTER E WITH GRAVE' U+00E8
|
||||
{ 2321, 8, 13, 10, 1, -12 }, // 0xc9 'LATIN SMALL LETTER E WITH ACUTE' U+00E9
|
||||
{ 2334, 8, 13, 10, 1, -12 }, // 0xca 'LATIN SMALL LETTER E WITH CIRCUMFLEX' U+00EA
|
||||
{ 2347, 8, 13, 10, 1, -12 }, // 0xcb 'LATIN SMALL LETTER E WITH DIAERESIS' U+00EB
|
||||
{ 2360, 4, 13, 5, 0, -12 }, // 0xcc 'LATIN SMALL LETTER I WITH GRAVE' U+00EC
|
||||
{ 2367, 4, 13, 5, 1, -12 }, // 0xcd 'LATIN SMALL LETTER I WITH ACUTE' U+00ED
|
||||
{ 2374, 5, 13, 5, 0, -12 }, // 0xce 'LATIN SMALL LETTER I WITH CIRCUMFLEX' U+00EE
|
||||
{ 2383, 6, 13, 5, -1, -12 }, // 0xcf 'LATIN SMALL LETTER I WITH DIAERESIS' U+00EF
|
||||
{ 2393, 8, 13, 10, 1, -12 }, // 0xd0 'LATIN SMALL LETTER ETH' U+00F0
|
||||
{ 2406, 8, 13, 10, 1, -12 }, // 0xd1 'LATIN SMALL LETTER N WITH TILDE' U+00F1
|
||||
{ 2419, 8, 13, 10, 1, -12 }, // 0xd2 'LATIN SMALL LETTER O WITH GRAVE' U+00F2
|
||||
{ 2432, 8, 13, 10, 1, -12 }, // 0xd3 'LATIN SMALL LETTER O WITH ACUTE' U+00F3
|
||||
{ 2445, 8, 13, 10, 1, -12 }, // 0xd4 'LATIN SMALL LETTER O WITH CIRCUMFLEX' U+00F4
|
||||
{ 2458, 8, 13, 10, 1, -12 }, // 0xd5 'LATIN SMALL LETTER O WITH TILDE' U+00F5
|
||||
{ 2471, 8, 13, 10, 1, -12 }, // 0xd6 'LATIN SMALL LETTER O WITH DIAERESIS' U+00F6
|
||||
{ 2484, 9, 9, 11, 1, -8 }, // 0xd7 'DIVISION SIGN' U+00F7
|
||||
{ 2495, 10, 11, 11, 0, -9 }, // 0xd8 'LATIN SMALL LETTER O WITH STROKE' U+00F8
|
||||
{ 2509, 8, 13, 10, 1, -12 }, // 0xd9 'LATIN SMALL LETTER U WITH GRAVE' U+00F9
|
||||
{ 2522, 8, 13, 10, 1, -12 }, // 0xda 'LATIN SMALL LETTER U WITH ACUTE' U+00FA
|
||||
{ 2535, 8, 13, 10, 1, -12 }, // 0xdb 'LATIN SMALL LETTER U WITH CIRCUMFLEX' U+00FB
|
||||
{ 2548, 8, 13, 10, 1, -12 }, // 0xdc 'LATIN SMALL LETTER U WITH DIAERESIS' U+00FC
|
||||
{ 2561, 9, 17, 9, 0, -12 }, // 0xdd 'LATIN SMALL LETTER Y WITH ACUTE' U+00FD
|
||||
{ 2581, 8, 17, 10, 1, -12 }, // 0xde 'LATIN SMALL LETTER THORN' U+00FE
|
||||
{ 2598, 9, 17, 9, 0, -12 } }; // 0xdf 'LATIN SMALL LETTER Y WITH DIAERESIS' U+000FF
|
||||
|
||||
const GFXfont FreeSans9pt8b PROGMEM = {
|
||||
(uint8_t *)FreeSans9pt8bBitmaps,
|
||||
(GFXglyph *)FreeSans9pt8bGlyphs,
|
||||
0x20, 0xDF, 25 };
|
||||
|
||||
// Approx. 3969 bytes
|
123
RX_FSK/src/fonts/Picopixel.h
Normal file
123
RX_FSK/src/fonts/Picopixel.h
Normal file
|
@ -0,0 +1,123 @@
|
|||
// Picopixel by Sebastian Weber. A tiny font
|
||||
// with all characters within a 6 pixel height.
|
||||
|
||||
const uint8_t PicopixelBitmaps[] PROGMEM = {
|
||||
0xE8, 0xB4, 0x57, 0xD5, 0xF5, 0x00, 0x4E, 0x3E, 0x80, 0xA5, 0x4A, 0x4A,
|
||||
0x5A, 0x50, 0xC0, 0x6A, 0x40, 0x95, 0x80, 0xAA, 0x80, 0x5D, 0x00, 0x60,
|
||||
0xE0, 0x80, 0x25, 0x48, 0x56, 0xD4, 0x75, 0x40, 0xC5, 0x4E, 0xC5, 0x1C,
|
||||
0x97, 0x92, 0xF3, 0x1C, 0x53, 0x54, 0xE5, 0x48, 0x55, 0x54, 0x55, 0x94,
|
||||
0xA0, 0x46, 0x64, 0xE3, 0x80, 0x98, 0xC5, 0x04, 0x56, 0xC6, 0x57, 0xDA,
|
||||
0xD7, 0x5C, 0x72, 0x46, 0xD6, 0xDC, 0xF3, 0xCE, 0xF3, 0x48, 0x72, 0xD4,
|
||||
0xB7, 0xDA, 0xF8, 0x24, 0xD4, 0xBB, 0x5A, 0x92, 0x4E, 0x8E, 0xEB, 0x58,
|
||||
0x80, 0x9D, 0xB9, 0x90, 0x56, 0xD4, 0xD7, 0x48, 0x56, 0xD4, 0x40, 0xD7,
|
||||
0x5A, 0x71, 0x1C, 0xE9, 0x24, 0xB6, 0xD4, 0xB6, 0xA4, 0x8C, 0x6B, 0x55,
|
||||
0x00, 0xB5, 0x5A, 0xB5, 0x24, 0xE5, 0x4E, 0xEA, 0xC0, 0x91, 0x12, 0xD5,
|
||||
0xC0, 0x54, 0xF0, 0x90, 0xC7, 0xF0, 0x93, 0x5E, 0x71, 0x80, 0x25, 0xDE,
|
||||
0x5E, 0x30, 0x6E, 0x80, 0x77, 0x9C, 0x93, 0x5A, 0xB8, 0x45, 0x60, 0x92,
|
||||
0xEA, 0xAA, 0x40, 0xD5, 0x6A, 0xD6, 0x80, 0x55, 0x00, 0xD7, 0x40, 0x75,
|
||||
0x90, 0xE8, 0x71, 0xE0, 0xBA, 0x40, 0xB5, 0x80, 0xB5, 0x00, 0x8D, 0x54,
|
||||
0xAA, 0x80, 0xAC, 0xE0, 0xE5, 0x70, 0x6A, 0x26, 0xFC, 0xC8, 0xAC, 0x5A };
|
||||
|
||||
const GFXglyph PicopixelGlyphs[] PROGMEM = {
|
||||
{ 0, 0, 0, 2, 0, 1 }, // 0x20 ' '
|
||||
{ 0, 1, 5, 2, 0, -4 }, // 0x21 '!'
|
||||
{ 1, 3, 2, 4, 0, -4 }, // 0x22 '"'
|
||||
{ 2, 5, 5, 6, 0, -4 }, // 0x23 '#'
|
||||
{ 6, 3, 6, 4, 0, -4 }, // 0x24 '$'
|
||||
{ 9, 3, 5, 4, 0, -4 }, // 0x25 '%'
|
||||
{ 11, 4, 5, 5, 0, -4 }, // 0x26 '&'
|
||||
{ 14, 1, 2, 2, 0, -4 }, // 0x27 '''
|
||||
{ 15, 2, 5, 3, 0, -4 }, // 0x28 '('
|
||||
{ 17, 2, 5, 3, 0, -4 }, // 0x29 ')'
|
||||
{ 19, 3, 3, 4, 0, -3 }, // 0x2A '*'
|
||||
{ 21, 3, 3, 4, 0, -3 }, // 0x2B '+'
|
||||
{ 23, 2, 2, 3, 0, 0 }, // 0x2C ','
|
||||
{ 24, 3, 1, 4, 0, -2 }, // 0x2D '-'
|
||||
{ 25, 1, 1, 2, 0, 0 }, // 0x2E '.'
|
||||
{ 26, 3, 5, 4, 0, -4 }, // 0x2F '/'
|
||||
{ 28, 3, 5, 4, 0, -4 }, // 0x30 '0'
|
||||
{ 30, 2, 5, 3, 0, -4 }, // 0x31 '1'
|
||||
{ 32, 3, 5, 4, 0, -4 }, // 0x32 '2'
|
||||
{ 34, 3, 5, 4, 0, -4 }, // 0x33 '3'
|
||||
{ 36, 3, 5, 4, 0, -4 }, // 0x34 '4'
|
||||
{ 38, 3, 5, 4, 0, -4 }, // 0x35 '5'
|
||||
{ 40, 3, 5, 4, 0, -4 }, // 0x36 '6'
|
||||
{ 42, 3, 5, 4, 0, -4 }, // 0x37 '7'
|
||||
{ 44, 3, 5, 4, 0, -4 }, // 0x38 '8'
|
||||
{ 46, 3, 5, 4, 0, -4 }, // 0x39 '9'
|
||||
{ 48, 1, 3, 2, 0, -3 }, // 0x3A ':'
|
||||
{ 49, 2, 4, 3, 0, -3 }, // 0x3B ';'
|
||||
{ 50, 2, 3, 3, 0, -3 }, // 0x3C '<'
|
||||
{ 51, 3, 3, 4, 0, -3 }, // 0x3D '='
|
||||
{ 53, 2, 3, 3, 0, -3 }, // 0x3E '>'
|
||||
{ 54, 3, 5, 4, 0, -4 }, // 0x3F '?'
|
||||
{ 56, 3, 5, 4, 0, -4 }, // 0x40 '@'
|
||||
{ 58, 3, 5, 4, 0, -4 }, // 0x41 'A'
|
||||
{ 60, 3, 5, 4, 0, -4 }, // 0x42 'B'
|
||||
{ 62, 3, 5, 4, 0, -4 }, // 0x43 'C'
|
||||
{ 64, 3, 5, 4, 0, -4 }, // 0x44 'D'
|
||||
{ 66, 3, 5, 4, 0, -4 }, // 0x45 'E'
|
||||
{ 68, 3, 5, 4, 0, -4 }, // 0x46 'F'
|
||||
{ 70, 3, 5, 4, 0, -4 }, // 0x47 'G'
|
||||
{ 72, 3, 5, 4, 0, -4 }, // 0x48 'H'
|
||||
{ 74, 1, 5, 2, 0, -4 }, // 0x49 'I'
|
||||
{ 75, 3, 5, 4, 0, -4 }, // 0x4A 'J'
|
||||
{ 77, 3, 5, 4, 0, -4 }, // 0x4B 'K'
|
||||
{ 79, 3, 5, 4, 0, -4 }, // 0x4C 'L'
|
||||
{ 81, 5, 5, 6, 0, -4 }, // 0x4D 'M'
|
||||
{ 85, 4, 5, 5, 0, -4 }, // 0x4E 'N'
|
||||
{ 88, 3, 5, 4, 0, -4 }, // 0x4F 'O'
|
||||
{ 90, 3, 5, 4, 0, -4 }, // 0x50 'P'
|
||||
{ 92, 3, 6, 4, 0, -4 }, // 0x51 'Q'
|
||||
{ 95, 3, 5, 4, 0, -4 }, // 0x52 'R'
|
||||
{ 97, 3, 5, 4, 0, -4 }, // 0x53 'S'
|
||||
{ 99, 3, 5, 4, 0, -4 }, // 0x54 'T'
|
||||
{ 101, 3, 5, 4, 0, -4 }, // 0x55 'U'
|
||||
{ 103, 3, 5, 4, 0, -4 }, // 0x56 'V'
|
||||
{ 105, 5, 5, 6, 0, -4 }, // 0x57 'W'
|
||||
{ 109, 3, 5, 4, 0, -4 }, // 0x58 'X'
|
||||
{ 111, 3, 5, 4, 0, -4 }, // 0x59 'Y'
|
||||
{ 113, 3, 5, 4, 0, -4 }, // 0x5A 'Z'
|
||||
{ 115, 2, 5, 3, 0, -4 }, // 0x5B '['
|
||||
{ 117, 3, 5, 4, 0, -4 }, // 0x5C '\'
|
||||
{ 119, 2, 5, 3, 0, -4 }, // 0x5D ']'
|
||||
{ 121, 3, 2, 4, 0, -4 }, // 0x5E '^'
|
||||
{ 122, 4, 1, 4, 0, 1 }, // 0x5F '_'
|
||||
{ 123, 2, 2, 3, 0, -4 }, // 0x60 '`'
|
||||
{ 124, 3, 4, 4, 0, -3 }, // 0x61 'a'
|
||||
{ 126, 3, 5, 4, 0, -4 }, // 0x62 'b'
|
||||
{ 128, 3, 3, 4, 0, -2 }, // 0x63 'c'
|
||||
{ 130, 3, 5, 4, 0, -4 }, // 0x64 'd'
|
||||
{ 132, 3, 4, 4, 0, -3 }, // 0x65 'e'
|
||||
{ 134, 2, 5, 3, 0, -4 }, // 0x66 'f'
|
||||
{ 136, 3, 5, 4, 0, -3 }, // 0x67 'g'
|
||||
{ 138, 3, 5, 4, 0, -4 }, // 0x68 'h'
|
||||
{ 140, 1, 5, 2, 0, -4 }, // 0x69 'i'
|
||||
{ 141, 2, 6, 3, 0, -4 }, // 0x6A 'j'
|
||||
{ 143, 3, 5, 4, 0, -4 }, // 0x6B 'k'
|
||||
{ 145, 2, 5, 3, 0, -4 }, // 0x6C 'l'
|
||||
{ 147, 5, 3, 6, 0, -2 }, // 0x6D 'm'
|
||||
{ 149, 3, 3, 4, 0, -2 }, // 0x6E 'n'
|
||||
{ 151, 3, 3, 4, 0, -2 }, // 0x6F 'o'
|
||||
{ 153, 3, 4, 4, 0, -2 }, // 0x70 'p'
|
||||
{ 155, 3, 4, 4, 0, -2 }, // 0x71 'q'
|
||||
{ 157, 2, 3, 3, 0, -2 }, // 0x72 'r'
|
||||
{ 158, 3, 4, 4, 0, -3 }, // 0x73 's'
|
||||
{ 160, 2, 5, 3, 0, -4 }, // 0x74 't'
|
||||
{ 162, 3, 3, 4, 0, -2 }, // 0x75 'u'
|
||||
{ 164, 3, 3, 4, 0, -2 }, // 0x76 'v'
|
||||
{ 166, 5, 3, 6, 0, -2 }, // 0x77 'w'
|
||||
{ 168, 3, 3, 4, 0, -2 }, // 0x78 'x'
|
||||
{ 170, 3, 4, 4, 0, -2 }, // 0x79 'y'
|
||||
{ 172, 3, 4, 4, 0, -3 }, // 0x7A 'z'
|
||||
{ 174, 3, 5, 4, 0, -4 }, // 0x7B '{'
|
||||
{ 176, 1, 6, 2, 0, -4 }, // 0x7C '|'
|
||||
{ 177, 3, 5, 4, 0, -4 }, // 0x7D '}'
|
||||
{ 179, 4, 2, 5, 0, -3 } }; // 0x7E '~'
|
||||
|
||||
const GFXfont Picopixel PROGMEM = {
|
||||
(uint8_t *)PicopixelBitmaps,
|
||||
(GFXglyph *)PicopixelGlyphs,
|
||||
0x20, 0x7E, 7 };
|
||||
|
||||
// Approx. 852 bytes
|
221
RX_FSK/src/fonts/Terminal11x16.h
Normal file
221
RX_FSK/src/fonts/Terminal11x16.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
const uint8_t Terminal11x16Bitmap[] = {
|
||||
0x0C, 0x18, 0x78, 0xF1, 0xE3, 0xC7, 0x86, 0x0C, 0x18, 0x00, 0x00, 0xC1,
|
||||
0x80, 0x33, 0x33, 0x33, 0x33, 0x0C, 0xC1, 0x98, 0x33, 0x3F, 0xF1, 0x98,
|
||||
0x33, 0x0C, 0xC1, 0x98, 0xFF, 0x8C, 0xC1, 0x98, 0x33, 0x00, 0x0C, 0x06,
|
||||
0x0F, 0xCF, 0xF6, 0xC3, 0x61, 0xFC, 0x7F, 0x0D, 0x86, 0xDF, 0xE7, 0xE0,
|
||||
0xC0, 0x60, 0x00, 0x2E, 0x0D, 0xC3, 0xB8, 0xE0, 0x38, 0x0E, 0x03, 0x80,
|
||||
0xE0, 0x38, 0x0E, 0x3B, 0x87, 0x60, 0xE0, 0x0E, 0x06, 0xC3, 0x30, 0xCC,
|
||||
0x36, 0x07, 0x03, 0xC1, 0xF0, 0x66, 0xD9, 0xE6, 0x31, 0xDE, 0x3C, 0xC0,
|
||||
0x1C, 0x71, 0xC3, 0x0C, 0x60, 0x07, 0x0C, 0x1C, 0x18, 0x38, 0x38, 0x38,
|
||||
0x38, 0x38, 0x38, 0x18, 0x1C, 0x0C, 0x07, 0x38, 0x0C, 0x0E, 0x06, 0x07,
|
||||
0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x0E, 0x0C, 0x38, 0x6D, 0xB6, 0xCF,
|
||||
0xC3, 0xC7, 0xF8, 0xF0, 0xFC, 0xDB, 0x6D, 0x80, 0x0C, 0x06, 0x03, 0x0F,
|
||||
0xF7, 0xF8, 0x60, 0x30, 0x18, 0x1C, 0x71, 0xC3, 0x18, 0x7F, 0xBF, 0xC0,
|
||||
0x1C, 0x71, 0xC0, 0x00, 0x20, 0x0C, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03,
|
||||
0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0x60, 0x00, 0x1F, 0x0F, 0xF9, 0x83,
|
||||
0x60, 0x7C, 0x1F, 0x86, 0xF1, 0x9E, 0x63, 0xD8, 0x7E, 0x0F, 0x81, 0xB0,
|
||||
0x67, 0xFC, 0x3E, 0x00, 0x06, 0x03, 0x83, 0xE0, 0xF8, 0x06, 0x01, 0x80,
|
||||
0x60, 0x18, 0x06, 0x01, 0x80, 0x60, 0x18, 0x3F, 0xCF, 0xF0, 0x3F, 0x8F,
|
||||
0xFB, 0x83, 0xE0, 0x3C, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0E, 0x03, 0x80,
|
||||
0xE0, 0x38, 0x0F, 0xFF, 0xFF, 0xC0, 0x3F, 0x8F, 0xFB, 0x83, 0xE0, 0x30,
|
||||
0x06, 0x01, 0xC7, 0xF0, 0xFC, 0x00, 0xC0, 0x0F, 0x01, 0xF0, 0x77, 0xFC,
|
||||
0x7F, 0x00, 0x03, 0x80, 0xF0, 0x3E, 0x0E, 0xC3, 0x98, 0xE3, 0x38, 0x66,
|
||||
0x0C, 0xFF, 0xFF, 0xFC, 0x06, 0x00, 0xC0, 0x18, 0x03, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0x60, 0x0C, 0x01, 0xFF, 0x1F, 0xF0, 0x07, 0x00, 0x60, 0x0F,
|
||||
0x01, 0xF0, 0x77, 0xFC, 0x7F, 0x00, 0x07, 0x81, 0xF0, 0x70, 0x1C, 0x07,
|
||||
0x00, 0xC0, 0x3F, 0xE7, 0xFE, 0xE0, 0xF8, 0x0F, 0x01, 0xF0, 0x77, 0xFC,
|
||||
0x7F, 0x00, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0x60, 0x18, 0x03, 0x00, 0xC0,
|
||||
0x18, 0x06, 0x00, 0xC0, 0x30, 0x06, 0x01, 0x80, 0x30, 0x00, 0x1F, 0x07,
|
||||
0xF1, 0xC7, 0x30, 0x66, 0x0C, 0xE3, 0x8F, 0xE3, 0xFE, 0xE0, 0xF8, 0x0F,
|
||||
0x01, 0xF0, 0x77, 0xFC, 0x7F, 0x00, 0x3F, 0x8F, 0xFB, 0x83, 0xE0, 0x3C,
|
||||
0x07, 0xC1, 0xDF, 0xF9, 0xFF, 0x00, 0xC0, 0x38, 0x0E, 0x03, 0x83, 0xE0,
|
||||
0x78, 0x00, 0x1C, 0x71, 0xC0, 0x00, 0x01, 0xC7, 0x1C, 0x1C, 0x71, 0xC0,
|
||||
0x00, 0x01, 0xC7, 0x1C, 0x30, 0xC6, 0x01, 0x81, 0xC1, 0xC1, 0xC1, 0xC1,
|
||||
0xC1, 0xC0, 0xE0, 0x38, 0x0E, 0x03, 0x80, 0xE0, 0x38, 0x0C, 0x7F, 0xDF,
|
||||
0xF0, 0x00, 0x00, 0x7F, 0xDF, 0xF0, 0x60, 0x38, 0x0E, 0x03, 0x80, 0xE0,
|
||||
0x38, 0x0E, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x00, 0x3F, 0x1F,
|
||||
0xEE, 0x1F, 0x03, 0xC1, 0xC0, 0xE0, 0x70, 0x38, 0x0C, 0x03, 0x00, 0xC0,
|
||||
0x00, 0x0C, 0x03, 0x00, 0x3F, 0x8F, 0xF9, 0x83, 0x67, 0xBD, 0xF7, 0xB6,
|
||||
0xF6, 0xDE, 0xDB, 0xDB, 0x7B, 0xFB, 0x3E, 0x70, 0x07, 0xF8, 0x3F, 0x00,
|
||||
0x0C, 0x03, 0x01, 0xE0, 0x78, 0x1E, 0x0C, 0xC3, 0x30, 0xCC, 0x61, 0x9F,
|
||||
0xE7, 0xFB, 0x03, 0xC0, 0xF0, 0x30, 0xFE, 0x3F, 0xCC, 0x3B, 0x06, 0xC1,
|
||||
0xB0, 0xEF, 0xF3, 0xFE, 0xC1, 0xF0, 0x3C, 0x0F, 0x07, 0xFF, 0xBF, 0xC0,
|
||||
0x1F, 0x0F, 0xE7, 0x1D, 0x83, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
|
||||
0x06, 0x0D, 0xC7, 0x3F, 0x87, 0xC0, 0xFE, 0x3F, 0xCC, 0x3B, 0x06, 0xC0,
|
||||
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x1B, 0x0E, 0xFF, 0x3F, 0x80,
|
||||
0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0, 0x30, 0x0F, 0xF3, 0xFC, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xFC, 0x03, 0x00, 0xC0,
|
||||
0x30, 0x0F, 0xF3, 0xFC, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00,
|
||||
0x1F, 0x8F, 0xF7, 0x0D, 0x80, 0xC0, 0x30, 0x0C, 0x7F, 0x1F, 0xC0, 0xF0,
|
||||
0x36, 0x0D, 0xC3, 0x3F, 0xC7, 0xF0, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
|
||||
0xF0, 0x3F, 0xFF, 0xFF, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x30,
|
||||
0x3F, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x3F, 0x3F, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03,
|
||||
0x00, 0xF0, 0x3C, 0x0F, 0x86, 0x7F, 0x8F, 0xC0, 0xC0, 0xF0, 0x7C, 0x3B,
|
||||
0x1C, 0xCE, 0x37, 0x0F, 0x83, 0xE0, 0xDC, 0x33, 0x8C, 0x73, 0x0E, 0xC1,
|
||||
0xF0, 0x30, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xC0, 0x30, 0x0C, 0x03, 0x00, 0xFF, 0xFF, 0xF0, 0xC0, 0xF8, 0x7E, 0x1F,
|
||||
0xCF, 0xF3, 0xF7, 0xBD, 0xEF, 0x33, 0xCC, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
|
||||
0xF0, 0x30, 0xC0, 0xF8, 0x3E, 0x0F, 0xC3, 0xD8, 0xF6, 0x3C, 0xCF, 0x33,
|
||||
0xC6, 0xF1, 0xBC, 0x3F, 0x07, 0xC1, 0xF0, 0x30, 0x1E, 0x0F, 0xC7, 0x39,
|
||||
0x86, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x36, 0x19, 0xCE, 0x3F,
|
||||
0x07, 0x80, 0xFF, 0x3F, 0xEC, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0xFE,
|
||||
0xFF, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00, 0x1E, 0x0F, 0xC7, 0x39,
|
||||
0x86, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF1, 0xB6, 0x79, 0xCE, 0x3F,
|
||||
0xC7, 0xB0, 0xFF, 0x3F, 0xEC, 0x1F, 0x03, 0xC0, 0xF0, 0x3C, 0x1F, 0xFE,
|
||||
0xFF, 0x33, 0x8C, 0x73, 0x0E, 0xC1, 0xF0, 0x30, 0x3F, 0x1F, 0xEE, 0x1F,
|
||||
0x03, 0xC0, 0x38, 0x07, 0xF0, 0xFE, 0x01, 0xC0, 0x3C, 0x0F, 0x87, 0x7F,
|
||||
0x8F, 0xC0, 0x7F, 0xBF, 0xC3, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C,
|
||||
0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
|
||||
0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0D, 0x86, 0x7F, 0x8F, 0xC0,
|
||||
0xC0, 0xF0, 0x3C, 0x0D, 0x86, 0x61, 0x98, 0x63, 0x30, 0xCC, 0x33, 0x07,
|
||||
0x81, 0xE0, 0x78, 0x0C, 0x03, 0x00, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0,
|
||||
0xF0, 0x3C, 0x0F, 0x33, 0xCC, 0xF7, 0xBF, 0x3F, 0x87, 0xE1, 0xF0, 0x30,
|
||||
0xC0, 0xF0, 0x36, 0x19, 0x86, 0x33, 0x07, 0x80, 0xC0, 0x30, 0x1E, 0x0C,
|
||||
0xC6, 0x19, 0x86, 0xC0, 0xF0, 0x30, 0xC0, 0xF0, 0x36, 0x19, 0x86, 0x33,
|
||||
0x0C, 0xC1, 0xE0, 0x78, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xFF, 0xFF, 0xF0, 0x18, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C,
|
||||
0x06, 0x01, 0x80, 0xFF, 0xFF, 0xF0, 0x3F, 0x3F, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3F, 0x3F, 0x80, 0x18, 0x03, 0x80,
|
||||
0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0x38, 0x03, 0x80, 0x38, 0x03, 0x80,
|
||||
0x30, 0x3F, 0x3F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x3F, 0x3F, 0x04, 0x01, 0xC0, 0x7C, 0x1D, 0xC7, 0x1D, 0xC1, 0xF0,
|
||||
0x18, 0xFF, 0xFF, 0xFC, 0x0E, 0x1C, 0x38, 0x60, 0xC0, 0xC0, 0x3F, 0x9F,
|
||||
0xF0, 0x0C, 0xFF, 0x7F, 0xF0, 0x3C, 0x0F, 0xFF, 0x7F, 0xC0, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0x00, 0xC0, 0x37, 0xCF, 0xFB, 0x87, 0xC0, 0xF0, 0x3C, 0x0F,
|
||||
0x07, 0xFF, 0xBF, 0xC0, 0x3F, 0x1F, 0xEE, 0x0F, 0x00, 0xC0, 0x30, 0x0E,
|
||||
0x0D, 0xFE, 0x3F, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xCF, 0xB7,
|
||||
0xFF, 0x8F, 0xC0, 0xF0, 0x3C, 0x0F, 0x83, 0x7F, 0xCF, 0xF0, 0x3F, 0x1F,
|
||||
0xEE, 0x0F, 0xFF, 0xFF, 0xB0, 0x0E, 0x01, 0xFE, 0x3F, 0x00, 0x0F, 0x1F,
|
||||
0x38, 0x30, 0x30, 0x30, 0xFE, 0xFE, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x3F, 0xDF, 0xFE, 0x0F, 0x03, 0xE1, 0xDF, 0xF3, 0xEC, 0x03, 0x01, 0xDF,
|
||||
0xE7, 0xF0, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0xF3, 0xFD, 0xC7, 0xC1,
|
||||
0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0C, 0x0C, 0x0C, 0x00, 0x1C, 0x1C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x3F, 0x03, 0x03, 0x00, 0x07, 0x07, 0x03,
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x33, 0x3F, 0x1E, 0x60, 0x30, 0x18, 0x0C,
|
||||
0x06, 0x03, 0x19, 0x9C, 0xDC, 0x7C, 0x3E, 0x1B, 0x8C, 0xE6, 0x3B, 0x0C,
|
||||
0x1C, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x3F, 0x3F, 0xB3, 0x3F, 0xEF, 0xFF, 0x33, 0xCC, 0xF3, 0x3C, 0xCF, 0x33,
|
||||
0xCC, 0xC0, 0x7F, 0x1F, 0xE6, 0x1D, 0x83, 0x60, 0xD8, 0x36, 0x0D, 0x83,
|
||||
0x60, 0xC0, 0x3F, 0x1F, 0xEE, 0x1F, 0x03, 0xC0, 0xF0, 0x3E, 0x1D, 0xFE,
|
||||
0x3F, 0x00, 0xFF, 0x3F, 0xEC, 0x1F, 0x03, 0xC0, 0xF8, 0x7F, 0xFB, 0x7C,
|
||||
0xC0, 0x30, 0x0C, 0x00, 0x3F, 0xDF, 0xFE, 0x0F, 0x03, 0xC0, 0xF8, 0x77,
|
||||
0xFC, 0xFB, 0x00, 0xC0, 0x30, 0x0C, 0x6F, 0x9F, 0xF7, 0x0D, 0x80, 0x60,
|
||||
0x18, 0x06, 0x01, 0x80, 0x60, 0x00, 0x7E, 0xFF, 0xC0, 0xFE, 0x7F, 0x03,
|
||||
0x03, 0xFF, 0x7E, 0x30, 0x30, 0x30, 0x30, 0xFE, 0xFE, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x3F, 0x1F, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC0, 0xF0, 0x3E,
|
||||
0x1D, 0xFF, 0x3E, 0xC0, 0xC0, 0xF0, 0x36, 0x19, 0x86, 0x33, 0x0C, 0xC1,
|
||||
0xE0, 0x78, 0x0C, 0x00, 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xF7, 0xB7,
|
||||
0xF9, 0xCE, 0x21, 0x00, 0xC1, 0xF1, 0xDD, 0xC7, 0xC1, 0xC1, 0xF1, 0xDD,
|
||||
0xC7, 0xC1, 0x80, 0x61, 0xB0, 0xCC, 0xC6, 0x61, 0xE0, 0xF0, 0x30, 0x18,
|
||||
0x18, 0x0C, 0x0C, 0x00, 0xFF, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
|
||||
0xFF, 0xFF, 0x80, 0x07, 0x87, 0xC7, 0x03, 0x01, 0x80, 0xC0, 0xE0, 0xE0,
|
||||
0x38, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x7C, 0x1E, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0x78, 0x3E, 0x03, 0x80, 0xC0,
|
||||
0x60, 0x30, 0x1C, 0x07, 0x07, 0x03, 0x01, 0x80, 0xC0, 0xE3, 0xE1, 0xE0,
|
||||
0x38, 0xDB, 0x6C, 0x70, 0x0C, 0x07, 0x83, 0x31, 0x86, 0xC0, 0xF0, 0x3F,
|
||||
0xFF, 0xFF,
|
||||
};
|
||||
|
||||
const GFXglyph Terminal11x16Glyphs[] = {
|
||||
{ 0, 6, 0, 7, 0, 4 }, // 0x20 ' '
|
||||
{ 0, 7, 14, 8, 0, -12 }, // 0x21 '!'
|
||||
{ 13, 8, 4, 9, 0, -10 }, // 0x22 '"'
|
||||
{ 17, 11, 12, 12, 0, -11 }, // 0x23 '#'
|
||||
{ 34, 9, 14, 10, 0, -12 }, // 0x24 '$'
|
||||
{ 50, 11, 12, 12, 0, -10 }, // 0x25 '%'
|
||||
{ 67, 10, 13, 11, 0, -11 }, // 0x26 '&'
|
||||
{ 84, 6, 6, 7, 0, -12 }, // 0x27 '''
|
||||
{ 89, 8, 14, 9, 0, -12 }, // 0x28 '('
|
||||
{ 103, 8, 14, 9, 0, -12 }, // 0x29 ')'
|
||||
{ 117, 9, 9, 10, 0, -9 }, // 0x2a '*'
|
||||
{ 128, 9, 8, 10, 0, -8 }, // 0x2b '+'
|
||||
{ 137, 6, 5, 7, 0, -1 }, // 0x2c ','
|
||||
{ 141, 9, 2, 10, 0, -5 }, // 0x2d '-'
|
||||
{ 144, 6, 3, 7, 0, -1 }, // 0x2e '.'
|
||||
{ 147, 11, 12, 12, 0, -11 }, // 0x2f '/'
|
||||
{ 164, 11, 14, 12, 0, -12 }, // 0x30 '0'
|
||||
{ 184, 10, 14, 11, 0, -12 }, // 0x31 '1'
|
||||
{ 202, 11, 14, 12, 0, -12 }, // 0x32 '2'
|
||||
{ 222, 11, 14, 12, 0, -12 }, // 0x33 '3'
|
||||
{ 242, 11, 14, 12, 0, -12 }, // 0x34 '4'
|
||||
{ 262, 11, 14, 12, 0, -12 }, // 0x35 '5'
|
||||
{ 282, 11, 14, 12, 0, -12 }, // 0x36 '6'
|
||||
{ 302, 11, 14, 12, 0, -12 }, // 0x37 '7'
|
||||
{ 322, 11, 14, 12, 0, -12 }, // 0x38 '8'
|
||||
{ 342, 11, 14, 12, 0, -12 }, // 0x39 '9'
|
||||
{ 362, 6, 9, 7, 0, -8 }, // 0x3a ':'
|
||||
{ 369, 6, 12, 7, 0, -8 }, // 0x3b ';'
|
||||
{ 378, 9, 14, 10, 0, -12 }, // 0x3c '<'
|
||||
{ 394, 10, 6, 11, 0, -7 }, // 0x3d '='
|
||||
{ 402, 9, 14, 10, 0, -12 }, // 0x3e '>'
|
||||
{ 418, 10, 14, 11, 0, -12 }, // 0x3f '?'
|
||||
{ 436, 11, 14, 12, 0, -12 }, // 0x40 '@'
|
||||
{ 456, 10, 14, 11, 0, -12 }, // 0x41 'A'
|
||||
{ 474, 10, 14, 11, 0, -12 }, // 0x42 'B'
|
||||
{ 492, 10, 14, 11, 0, -12 }, // 0x43 'C'
|
||||
{ 510, 10, 14, 11, 0, -12 }, // 0x44 'D'
|
||||
{ 528, 10, 14, 11, 0, -12 }, // 0x45 'E'
|
||||
{ 546, 10, 14, 11, 0, -12 }, // 0x46 'F'
|
||||
{ 564, 10, 14, 11, 0, -12 }, // 0x47 'G'
|
||||
{ 582, 10, 14, 11, 0, -12 }, // 0x48 'H'
|
||||
{ 600, 8, 14, 9, 0, -12 }, // 0x49 'I'
|
||||
{ 614, 10, 14, 11, 0, -12 }, // 0x4a 'J'
|
||||
{ 632, 10, 14, 11, 0, -12 }, // 0x4b 'K'
|
||||
{ 650, 10, 14, 11, 0, -12 }, // 0x4c 'L'
|
||||
{ 668, 10, 14, 11, 0, -12 }, // 0x4d 'M'
|
||||
{ 686, 10, 14, 11, 0, -12 }, // 0x4e 'N'
|
||||
{ 704, 10, 14, 11, 0, -12 }, // 0x4f 'O'
|
||||
{ 722, 10, 14, 11, 0, -12 }, // 0x50 'P'
|
||||
{ 740, 10, 14, 11, 0, -12 }, // 0x51 'Q'
|
||||
{ 758, 10, 14, 11, 0, -12 }, // 0x52 'R'
|
||||
{ 776, 10, 14, 11, 0, -12 }, // 0x53 'S'
|
||||
{ 794, 9, 14, 10, 0, -12 }, // 0x54 'T'
|
||||
{ 810, 10, 14, 11, 0, -12 }, // 0x55 'U'
|
||||
{ 828, 10, 14, 11, 0, -12 }, // 0x56 'V'
|
||||
{ 846, 10, 14, 11, 0, -12 }, // 0x57 'W'
|
||||
{ 864, 10, 14, 11, 0, -12 }, // 0x58 'X'
|
||||
{ 882, 10, 14, 11, 0, -12 }, // 0x59 'Y'
|
||||
{ 900, 10, 14, 11, 0, -12 }, // 0x5a 'Z'
|
||||
{ 918, 8, 14, 9, 0, -12 }, // 0x5b '['
|
||||
{ 932, 11, 12, 12, 0, -11 }, // 0x5c '\'
|
||||
{ 949, 8, 14, 9, 0, -12 }, // 0x5d ']'
|
||||
{ 963, 11, 7, 12, 0, -12 }, // 0x5e '^'
|
||||
{ 973, 11, 2, 12, 0, 2 }, // 0x5f '_'
|
||||
{ 976, 7, 6, 8, 0, -11 }, // 0x60 '`'
|
||||
{ 982, 10, 9, 11, 0, -7 }, // 0x61 'a'
|
||||
{ 994, 10, 14, 11, 0, -12 }, // 0x62 'b'
|
||||
{ 1012, 10, 9, 11, 0, -7 }, // 0x63 'c'
|
||||
{ 1024, 10, 14, 11, 0, -12 }, // 0x64 'd'
|
||||
{ 1042, 10, 9, 11, 0, -7 }, // 0x65 'e'
|
||||
{ 1054, 8, 14, 9, 0, -12 }, // 0x66 'f'
|
||||
{ 1068, 10, 11, 11, 0, -7 }, // 0x67 'g'
|
||||
{ 1082, 9, 14, 10, 0, -12 }, // 0x68 'h'
|
||||
{ 1098, 8, 12, 9, 0, -10 }, // 0x69 'i'
|
||||
{ 1110, 8, 14, 9, 0, -10 }, // 0x6a 'j'
|
||||
{ 1124, 9, 14, 10, 0, -12 }, // 0x6b 'k'
|
||||
{ 1140, 8, 14, 9, 0, -12 }, // 0x6c 'l'
|
||||
{ 1154, 10, 9, 11, 0, -7 }, // 0x6d 'm'
|
||||
{ 1166, 10, 9, 11, 0, -7 }, // 0x6e 'n'
|
||||
{ 1178, 10, 9, 11, 0, -7 }, // 0x6f 'o'
|
||||
{ 1190, 10, 11, 11, 0, -7 }, // 0x70 'p'
|
||||
{ 1204, 10, 11, 11, 0, -7 }, // 0x71 'q'
|
||||
{ 1218, 10, 9, 11, 0, -7 }, // 0x72 'r'
|
||||
{ 1230, 8, 9, 9, 0, -7 }, // 0x73 's'
|
||||
{ 1239, 8, 13, 9, 0, -11 }, // 0x74 't'
|
||||
{ 1252, 10, 9, 11, 0, -7 }, // 0x75 'u'
|
||||
{ 1264, 10, 9, 11, 0, -7 }, // 0x76 'v'
|
||||
{ 1276, 10, 9, 11, 0, -7 }, // 0x77 'w'
|
||||
{ 1288, 9, 9, 10, 0, -7 }, // 0x78 'x'
|
||||
{ 1299, 9, 11, 10, 0, -7 }, // 0x79 'y'
|
||||
{ 1312, 9, 9, 10, 0, -7 }, // 0x7a 'z'
|
||||
{ 1323, 9, 15, 10, 0, -12 }, // 0x7b '{'
|
||||
{ 1340, 6, 14, 7, 0, -12 }, // 0x7c '|'
|
||||
{ 1351, 9, 15, 10, 0, -12 }, // 0x7d '}'
|
||||
{ 1368, 10, 3, 11, 0, -10 }, // 0x7e '~'
|
||||
{ 1372, 10, 8, 11, 0, -8 }, // 0x7f ''
|
||||
};
|
||||
const GFXfont Terminal11x16Font = {
|
||||
(uint8_t *)Terminal11x16Bitmap,
|
||||
(GFXglyph *)Terminal11x16Glyphs,
|
||||
0x20, 0x7F, 18 };
|
25
RX_FSK/src/fonts/fonts.cpp
Normal file
25
RX_FSK/src/fonts/fonts.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include <inttypes.h>
|
||||
#include "gfxfont.h"
|
||||
|
||||
#define PROGMEM
|
||||
|
||||
#include "FreeMono12pt8b.h"
|
||||
#include "FreeMono9pt8b.h"
|
||||
#include "FreeSans12pt8b.h"
|
||||
#include "FreeSans18pt8b.h"
|
||||
#include "FreeSans9pt8b.h"
|
||||
#include "Picopixel.h"
|
||||
#include "Terminal11x16.h"
|
||||
|
||||
__attribute__((used)) const GFXfont * const allfonts[]={
|
||||
(const GFXfont *)0x544E4F46,
|
||||
&Terminal11x16Font,
|
||||
&Terminal11x16Font,
|
||||
&FreeSans9pt8b,
|
||||
&FreeSans12pt8b,
|
||||
&Picopixel,
|
||||
&FreeSans18pt8b,
|
||||
&FreeMono9pt8b,
|
||||
&FreeMono12pt8b,
|
||||
0,
|
||||
};
|
31
RX_FSK/src/fonts/gfxfont.h
Normal file
31
RX_FSK/src/fonts/gfxfont.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Font structures for newer Adafruit_GFX (1.1 and later).
|
||||
// Example fonts are included in 'Fonts' directory.
|
||||
// To use a font in your Arduino sketch, #include the corresponding .h
|
||||
// file and pass address of GFXfont struct to setFont(). Pass NULL to
|
||||
// revert to 'classic' fixed-space bitmap font.
|
||||
|
||||
#ifndef _GFXFONT_H_
|
||||
#define _GFXFONT_H_
|
||||
|
||||
/// Font data stored PER GLYPH
|
||||
typedef struct
|
||||
{
|
||||
uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
|
||||
uint8_t width; ///< Bitmap dimensions in pixels
|
||||
uint8_t height; ///< Bitmap dimensions in pixels
|
||||
uint8_t xAdvance; ///< Distance to advance cursor (x axis)
|
||||
int8_t xOffset; ///< X dist from cursor pos to UL corner
|
||||
int8_t yOffset; ///< Y dist from cursor pos to UL corner
|
||||
} GFXglyph;
|
||||
|
||||
/// Data stored for FONT AS A WHOLE
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *bitmap; ///< Glyph bitmaps, concatenated
|
||||
GFXglyph *glyph; ///< Glyph array
|
||||
uint8_t first; ///< ASCII extents (first char)
|
||||
uint8_t last; ///< ASCII extents (last char)
|
||||
uint8_t yAdvance; ///< Newline distance (y axis)
|
||||
} GFXfont;
|
||||
|
||||
#endif // _GFXFONT_H_
|
238
RX_FSK/src/geteph.cpp
Normal file
238
RX_FSK/src/geteph.cpp
Normal file
|
@ -0,0 +1,238 @@
|
|||
#include "time.h"
|
||||
#include "geteph.h"
|
||||
#include <SPIFFS.h>
|
||||
#include <WiFi.h>
|
||||
#include <rom/miniz.h>
|
||||
#include <inttypes.h>
|
||||
#include <WiFi.h>
|
||||
#include "Display.h"
|
||||
#include "Sonde.h"
|
||||
|
||||
extern WiFiClient client;
|
||||
|
||||
//static const char *ftpserver = "www.ngs.noaa.gov";
|
||||
char outbuf[128];
|
||||
uint8_t ephstate = EPH_NOTUSED;
|
||||
//enum EPHSTATE { EPH_NOTUSED, EPH_PENDING, EPH_TIMEERR, EPH_ERROR, EPH_EPHERROR, EPH_GOOD };
|
||||
const char *ephtxt[] = { "Disabled", "Pending", "Time error", "Fetch error", "Read error", "Good" };
|
||||
|
||||
uint8_t getreply() {
|
||||
String s = client.readStringUntil('\n');
|
||||
Serial.println(s);
|
||||
const char *str = s.c_str();
|
||||
if(strlen(str)<4) return 255; // something unusual...
|
||||
if(str[3]=='-') { // multi-line resonse...
|
||||
String s2;
|
||||
const char *str2;
|
||||
do {
|
||||
s2 = client.readStringUntil('\n');
|
||||
Serial.println(s2);
|
||||
str2 = s2.c_str();
|
||||
if(strlen(str2)<4) return 255; // something is wrong
|
||||
} while( str[0]!=str2[0] || str[1]!=str2[1] || str[2]!=str2[2] || str2[3]!=' ' );
|
||||
}
|
||||
return str[0];
|
||||
}
|
||||
|
||||
void writeFully(File &file, uint8_t *buf, size_t len)
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
while(len) {
|
||||
olen = file.write(buf, len);
|
||||
Serial.printf("written: %d of %d\n", olen, len);
|
||||
len -= olen;
|
||||
buf += olen;
|
||||
}
|
||||
}
|
||||
|
||||
void geteph() {
|
||||
// Set current time via network...
|
||||
ephstate = EPH_PENDING;
|
||||
struct tm tinfo;
|
||||
configTime(0, 0, "pool.ntp.org");
|
||||
bool ok = getLocalTime(&tinfo, 2000); // wait max 2 seconds to get current time via ntp
|
||||
if(!ok) {
|
||||
ephstate = EPH_TIMEERR;
|
||||
Serial.println("Failed to get current date/time");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check time of last update
|
||||
int year = tinfo.tm_year + 1900;
|
||||
int day = tinfo.tm_yday + 1;
|
||||
Serial.printf("year %d, day %d\n", year, day);
|
||||
char nowstr[20];
|
||||
snprintf(nowstr, 20, "%04d%03d%02d", year, day, tinfo.tm_hour);
|
||||
File status = SPIFFS.open("/brdc.time", "r");
|
||||
if(status) {
|
||||
String ts = status.readStringUntil('\n');
|
||||
const char *tsstr = ts.c_str();
|
||||
if(tsstr && strlen(tsstr)>=9) {
|
||||
if(strcmp(nowstr, ts.c_str())<=0) {
|
||||
Serial.println("local brdc is up to date\n");
|
||||
ephstate = EPH_GOOD;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Serial.printf("now: %s, existing: %s => updating\n", nowstr, tsstr);
|
||||
}
|
||||
status.close();
|
||||
File fh = SPIFFS.open("/brdc.gz","w");
|
||||
if(!fh) {
|
||||
Serial.println("cannot open file\n");
|
||||
return;
|
||||
}
|
||||
char host[252];
|
||||
strcpy(host, sonde.config.ephftp);
|
||||
char *buf = strchr(host, '/');
|
||||
if(!buf) { Serial.println("Invalid FTP host config"); return; }
|
||||
*buf = 0;
|
||||
buf++;
|
||||
uint8_t dispw, disph, dispxs, dispys;
|
||||
disp.rdis->getDispSize(&disph, &dispw, &dispxs, &dispys);
|
||||
disp.rdis->clear();
|
||||
disp.rdis->setFont(FONT_SMALL);
|
||||
disp.rdis->drawString(0, 0, host);
|
||||
// fetch rinex from server
|
||||
char *ptr = buf + strlen(buf);
|
||||
snprintf(ptr, 128, "%04d/%03d/brdc%03d0.%02dn.gz", year, day, day, year-2000);
|
||||
Serial.println("running geteph\n");
|
||||
disp.rdis->drawString(0, 1*dispys, ptr+9);
|
||||
|
||||
if(!client.connect(host, 21)) {
|
||||
Serial.printf("FTP connection to %s failed\n", host);
|
||||
return;
|
||||
}
|
||||
if(getreply()>='4') { Serial.println("connected failed"); return; }
|
||||
client.print("USER anonymous\r\n");
|
||||
if(getreply()>='4') { Serial.println("USER failed"); return; }
|
||||
client.print("PASS anonymous\r\n");
|
||||
if(getreply()>='4') { Serial.println("PASS failed"); return; }
|
||||
client.print("TYPE I\r\n");
|
||||
if(getreply()>='4') { Serial.println("TYPE I failed"); return; }
|
||||
client.print("PASV\r\n");
|
||||
String s = client.readStringUntil('\n');
|
||||
Serial.println(s);
|
||||
if(s.c_str()[0]>='4') { Serial.println("PASV failed"); return; }
|
||||
int array_pasv[6];
|
||||
char *tStr = strtok((char *)s.c_str(), "(,");
|
||||
for(int i=0; i<6; i++) {
|
||||
tStr = strtok(NULL, "(,");
|
||||
if(tStr==NULL) {
|
||||
Serial.println("strange response to PASV");
|
||||
return;
|
||||
}
|
||||
array_pasv[i] = atoi(tStr);
|
||||
Serial.println(array_pasv[i]);
|
||||
}
|
||||
uint16_t port = (array_pasv[4]<<8) | (array_pasv[5]&0xff);
|
||||
WiFiClient dclient;
|
||||
Serial.printf("connecting to %s:%d\n", host, port);
|
||||
dclient.connect(host, port);
|
||||
if(!dclient) {
|
||||
Serial.println("data connection failed");
|
||||
return;
|
||||
}
|
||||
client.print("RETR ");
|
||||
Serial.printf("fetching %s with FTP...\n", buf);
|
||||
client.println(buf);
|
||||
s = client.readStringUntil('\n');
|
||||
Serial.println(s);
|
||||
if(s.c_str()[0]>='4') { Serial.println("RETR failed"); return; }
|
||||
int len=0;
|
||||
while(dclient.connected()) {
|
||||
while(dclient.available()) {
|
||||
int c = dclient.read();
|
||||
if(c==-1) {
|
||||
Serial.println("dclient.read() returned -1 inspite of available() being true?!");
|
||||
} else {
|
||||
fh.write(c);
|
||||
len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Serial.printf("fetched %d bytes\n", len);
|
||||
fh.close();
|
||||
snprintf(buf, 16, "Fetched %d B ",len);
|
||||
buf[16]=0;
|
||||
disp.rdis->drawString(0,2*dispys,buf);
|
||||
|
||||
disp.rdis->drawString(0,4*dispys,"Decompressing...");
|
||||
// decompression
|
||||
tinfl_decompressor *decomp = (tinfl_decompressor *)malloc(sizeof(tinfl_decompressor));
|
||||
tinfl_init(decomp);
|
||||
File file = SPIFFS.open("/brdc.gz","r");
|
||||
if(!file) {
|
||||
Serial.println("cannot open file\n");
|
||||
return;
|
||||
}
|
||||
File ofile = SPIFFS.open("/brdc", "w");
|
||||
if(!ofile) {
|
||||
Serial.println("cannot open file /brdc for writing");
|
||||
return;
|
||||
}
|
||||
file.readBytes(buf, 10); // skip gzip header
|
||||
char flags = buf[3];
|
||||
if(flags&0x07) {
|
||||
Serial.println("Unsupported flags in gzip header, may or may not cause a problem");
|
||||
}
|
||||
if(flags&0x08) { // skip file name extra header
|
||||
do {
|
||||
int res=file.readBytes(buf, 1);
|
||||
if(res!=1) return;
|
||||
} while(*buf);
|
||||
}
|
||||
if(flags&0x10) { // skip file name extra header
|
||||
do {
|
||||
int res=file.readBytes(buf, 1);
|
||||
if(res!=1) return;
|
||||
} while(*buf);
|
||||
}
|
||||
int opos = 0;
|
||||
int total = 0;
|
||||
Serial.println("Decompressing ephemeris data...\n");
|
||||
char *obuf =(char *)malloc(32768);
|
||||
char *ibuf =(char *)malloc(8192);
|
||||
while(file.available()) {
|
||||
size_t len = file.readBytes(ibuf, 8192);
|
||||
size_t inofs = 0;
|
||||
size_t inlen = len;
|
||||
while(inofs<len) {
|
||||
size_t outlen=32768-opos;
|
||||
int res = tinfl_decompress(decomp, (const mz_uint8 *)ibuf+inofs, &inlen, (uint8_t *)obuf, (mz_uint8 *)obuf+opos, &outlen, TINFL_FLAG_HAS_MORE_INPUT);
|
||||
if(res<0) break;
|
||||
if(outlen==0) break;
|
||||
Serial.printf("... (res=%d) decompressed %d into %d bytes\n", res, inlen, outlen);
|
||||
inofs += inlen;
|
||||
inlen = len - inofs;
|
||||
//size_t retv = ofile.write((uint8_t *)(obuf+opos), outlen);
|
||||
//Serial.printf("write %d bytes\n", retv);
|
||||
writeFully(ofile, (uint8_t *)(obuf+opos), outlen);
|
||||
//Serial.write((uint8_t *)(obuf+opos), outlen);
|
||||
total += outlen;
|
||||
opos += outlen;
|
||||
if(res==0) break; // done indication
|
||||
if(opos>=32768) {
|
||||
Serial.printf("... decompressed %d bytes\n", total);
|
||||
opos=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// maybe todo: check crc?!?
|
||||
Serial.printf("done extracing content (total length: %d)\n", total);
|
||||
status = SPIFFS.open("/brdc.time","w");
|
||||
status.println(nowstr);
|
||||
status.close();
|
||||
snprintf(buf, 16, "Done: %d B ",total);
|
||||
buf[16]=0;
|
||||
disp.rdis->drawString(0,5*dispys,buf);
|
||||
ephstate = EPH_GOOD;
|
||||
delay(1000);
|
||||
|
||||
free(obuf);
|
||||
free(ibuf);
|
||||
free(decomp);
|
||||
file.close();
|
||||
ofile.close();
|
||||
}
|
11
RX_FSK/src/geteph.h
Normal file
11
RX_FSK/src/geteph.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <inttypes.h>
|
||||
|
||||
#ifndef GETEPH_H
|
||||
#define GETEPH_H
|
||||
void geteph();
|
||||
|
||||
enum EPHSTATE { EPH_NOTUSED, EPH_PENDING, EPH_TIMEERR, EPH_ERROR, EPH_EPHERROR, EPH_GOOD };
|
||||
|
||||
extern uint8_t ephstate;
|
||||
extern const char *ephtxt[];
|
||||
#endif
|
26
RX_FSK/src/gfxfont.h
Normal file
26
RX_FSK/src/gfxfont.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-3.0
|
||||
// original source: https://github.com/Nkawu/TFT_22_ILI9225
|
||||
|
||||
// Font structures like Adafruit_GFX (1.1 and later).
|
||||
// Example fonts are included in 'fonts' directory.
|
||||
// To use a font in your Arduino sketch, #include the corresponding .h
|
||||
// file and pass address of GFXfont struct to setFont().
|
||||
|
||||
#ifndef _GFFFONT_H_
|
||||
#define _GFFFONT_H_
|
||||
|
||||
typedef struct { // Data stored PER GLYPH
|
||||
uint16_t bitmapOffset; // Pointer into GFXfont->bitmap
|
||||
uint8_t width, height; // Bitmap dimensions in pixels
|
||||
uint8_t xAdvance; // Distance to advance cursor (x axis)
|
||||
int8_t xOffset, yOffset; // Dist from cursor pos to UL corner
|
||||
} GFXglyph;
|
||||
|
||||
typedef struct { // Data stored for FONT AS A WHOLE:
|
||||
uint8_t *bitmap; // Glyph bitmaps, concatenated
|
||||
GFXglyph *glyph; // Glyph array
|
||||
uint8_t first, last; // ASCII extents
|
||||
uint8_t yAdvance; // Newline distance (y axis)
|
||||
} GFXfont;
|
||||
|
||||
#endif // _GFFFONT_H_
|
106
RX_FSK/src/json.cpp
Normal file
106
RX_FSK/src/json.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include "json.h"
|
||||
#include "RS41.h"
|
||||
|
||||
extern const char *sondeTypeStrSH[];
|
||||
extern const char *dfmSubtypeStrSH[];
|
||||
|
||||
static char typestr[11];
|
||||
|
||||
const char *getType(SondeInfo *si) {
|
||||
if( si->type == STYPE_RS41 ) {
|
||||
if ( RS41::getSubtype(typestr, 11, si) == 0 ) return typestr;
|
||||
} else if ( TYPE_IS_DFM(si->type) && si->d.subtype > 0 && si->d.subtype < 16 ) {
|
||||
const char *t = dfmSubtypeStrSH[si->d.subtype];
|
||||
if(t) return t;
|
||||
sprintf(typestr, "DFMx%X", si->d.subtype);
|
||||
return typestr;
|
||||
}
|
||||
return sondeTypeStrSH[sonde.realType(si)];
|
||||
}
|
||||
|
||||
int float2json(char **buf, int *maxlen, const char *fmt, float value) {
|
||||
if(isnan(value)) return 0;
|
||||
int n = snprintf(*buf, *maxlen, fmt, value);
|
||||
if(n>*maxlen) return -1;
|
||||
*buf += n; *maxlen -= n;
|
||||
return n;
|
||||
}
|
||||
|
||||
// To be used by
|
||||
// - MQTT
|
||||
// - rdzJSON (for Android app)
|
||||
// - Web map
|
||||
int sonde2json(char *buf, int maxlen, SondeInfo *si)
|
||||
{
|
||||
SondeData *s = &(si->d);
|
||||
int n;
|
||||
|
||||
n = float2json(&buf, &maxlen, "\"lat\": %.5f,", s->lat);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"lon\": %.5f,", s->lon);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"alt\": %.1f,", s->alt);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"vs\": %.1f,", s->vs);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"hs\": %.1f,", s->hs);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"climb\": %.1f,", s->vs); // used by HTML map, to be removed (-> vs)
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"speed\": %.1f,", s->hs); // used by HTML map, to be removed (-> hs)
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"dir\": %.1f,", s->dir);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"temp\": %.1f,", s->temperature );
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"humidity\": %.1f,", s->relativeHumidity);
|
||||
if(n<0) return -1;
|
||||
n = float2json(&buf, &maxlen, "\"pressure\": %.1f,", s->pressure);
|
||||
if(n<0) return -1;
|
||||
n = snprintf(buf, maxlen,
|
||||
"\"type\":\"%s\","
|
||||
"\"id\": \"%s\"," // TODO: maybe remove in the future, ser is enough, client can calculate APRS id if needed
|
||||
"\"ser\": \"%s\","
|
||||
"\"frame\": %u," // raw frame, from sonde, can be 0. (TODO: add virtual frame # as in sondehub?)
|
||||
"\"vframe\": %d,"
|
||||
"\"time\": %u,"
|
||||
"\"sats\": %d,"
|
||||
"\"freq\": %.2f,"
|
||||
"\"rssi\": %d,"
|
||||
"\"afc\": %d,"
|
||||
"\"launchKT\": %d,"
|
||||
"\"burstKT\": %d,"
|
||||
"\"countKT\": %d,"
|
||||
"\"crefKT\": %d,"
|
||||
"\"launchsite\": \"%s\","
|
||||
"\"res\": %d",
|
||||
getType(si),
|
||||
s->id,
|
||||
s->ser,
|
||||
s->frame,
|
||||
s->vframe,
|
||||
s->time,
|
||||
s->sats,
|
||||
si->freq,
|
||||
si->rssi,
|
||||
si->afc,
|
||||
s->launchKT,
|
||||
s->burstKT,
|
||||
s->countKT,
|
||||
s->crefKT,
|
||||
si->launchsite,
|
||||
(int)si->rxStat[0]
|
||||
);
|
||||
if(n>=maxlen) return -1;
|
||||
buf += n; maxlen -= n;
|
||||
|
||||
// add only if available
|
||||
if(s->batteryVoltage > 0) {
|
||||
n = snprintf(buf, maxlen, ",\"batt\": %.1f", s->batteryVoltage);
|
||||
if(n>=maxlen) return -1;
|
||||
buf += n; maxlen -= n;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
8
RX_FSK/src/json.h
Normal file
8
RX_FSK/src/json.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef _JSON_H
|
||||
#define _JSON_H
|
||||
|
||||
#include "Sonde.h"
|
||||
|
||||
int sonde2json(char *buf, int maxlen, SondeInfo *si);
|
||||
|
||||
#endif
|
11
RX_FSK/src/library.json
Normal file
11
RX_FSK/src/library.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
|
||||
"dependencies":
|
||||
[
|
||||
{
|
||||
"owner": "olikraus",
|
||||
"name": "U8g2",
|
||||
"version": "^2.28.8"
|
||||
}
|
||||
]
|
||||
}
|
165
RX_FSK/src/mqtt.cpp
Normal file
165
RX_FSK/src/mqtt.cpp
Normal file
|
@ -0,0 +1,165 @@
|
|||
#include <Arduino.h>
|
||||
#include "mqtt.h"
|
||||
#include <WiFi.h>
|
||||
//#include <AsyncMqttClient.h>
|
||||
#include <AsyncMqtt_Generic.h>
|
||||
#include <ESPmDNS.h>
|
||||
#include "RS41.h"
|
||||
#include "json.h"
|
||||
|
||||
extern const char *version_name;
|
||||
extern const char *version_id;
|
||||
|
||||
TimerHandle_t mqttReconnectTimer;
|
||||
|
||||
void mqttCallback(char* topic, byte* payload, unsigned int length) {
|
||||
Serial.print("Message arrived [");
|
||||
Serial.print(topic);
|
||||
Serial.print("] ");
|
||||
for (int i=0;i<length;i++) {
|
||||
Serial.print((char)payload[i]);
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
static char buffer[21];
|
||||
void MQTT::init(const char* host, uint16_t port, const char* id, const char *username, const char *password, const char *prefix)
|
||||
{
|
||||
WiFi.hostByName(host, this->ip);
|
||||
this->port = port;
|
||||
this->username = username;
|
||||
this->password = password;
|
||||
this->prefix = prefix;
|
||||
|
||||
Serial.println("[MQTT] pubsub client");
|
||||
mqttClient.setServer(ip, port);
|
||||
snprintf(buffer, 20, "%s%04d", id, (int)random(0, 1000));
|
||||
buffer[20] = 0;
|
||||
Serial.print(buffer);
|
||||
mqttClient.setClientId(buffer);
|
||||
if (strlen(password) > 0) {
|
||||
mqttClient.setCredentials(username, password);
|
||||
}
|
||||
}
|
||||
|
||||
void MQTT::connectToMqtt() {
|
||||
Serial.println("Connecting to MQTT...");
|
||||
mqttClient.connect();
|
||||
}
|
||||
|
||||
void MQTT::publishUptime()
|
||||
{
|
||||
mqttClient.connect(); // ensure we've got connection
|
||||
|
||||
Serial.println("[MQTT] writing");
|
||||
char payload[256];
|
||||
// maybe TODO: Use dynamic position if GPS is available?
|
||||
// rxlat, rxlon only if not empty
|
||||
snprintf(payload, 256, "{\"uptime\": %lu, \"user\": \"%s\", ", millis(), username);
|
||||
if( !isnan(sonde.config.rxlat) && !isnan(sonde.config.rxlon) ) {
|
||||
snprintf(payload, 256, "%s\"rxlat\": %.5f, \"rxlon\": %.5f, ", payload, sonde.config.rxlat, sonde.config.rxlon);
|
||||
}
|
||||
snprintf(payload, 256, "%s\"SW\": \"%s\", \"VER\": \"%s\"}", payload, version_name, version_id);
|
||||
Serial.println(payload);
|
||||
char topic[128];
|
||||
snprintf(topic, 128, "%s%s", this->prefix, "uptime");
|
||||
mqttClient.publish(topic, 1, 1, payload);
|
||||
}
|
||||
|
||||
void MQTT::publishPacket(SondeInfo *si)
|
||||
{
|
||||
SondeData *s = &(si->d);
|
||||
mqttClient.connect(); // ensure we've got connection
|
||||
|
||||
char payload[1024];
|
||||
payload[0] = '{';
|
||||
int n = sonde2json(payload+1, 1023, si);
|
||||
if(n<0) {
|
||||
// ERROR
|
||||
Serial.println("publishPacket: sonde2json failed, string too long");
|
||||
}
|
||||
|
||||
#if 0
|
||||
snprintf(payload, 1024, "{"
|
||||
"\"active\": %d,"
|
||||
"\"freq\": %.2f,"
|
||||
"\"id\": \"%s\","
|
||||
"\"ser\": \"%s\","
|
||||
"\"validId\": %d,"
|
||||
"\"launchsite\": \"%s\","
|
||||
"\"lat\": %.5f,"
|
||||
"\"lon\": %.5f,"
|
||||
"\"alt\": %.1f,"
|
||||
"\"vs\": %.1f,"
|
||||
"\"hs\": %.1f,"
|
||||
"\"dir\": %.1f,"
|
||||
"\"sats\": %d,"
|
||||
"\"validPos\": %d,"
|
||||
"\"time\": %u,"
|
||||
"\"frame\": %u,"
|
||||
"\"validTime\": %d,"
|
||||
"\"rssi\": %d,"
|
||||
"\"afc\": %d,"
|
||||
"\"rxStat\": \"%s\","
|
||||
"\"rxStart\": %u,"
|
||||
"\"norxStart\": %u,"
|
||||
"\"viewStart\": %u,"
|
||||
"\"lastState\": %d,"
|
||||
"\"launchKT\": %d,"
|
||||
"\"burstKT\": %d,"
|
||||
"\"countKT\": %d,"
|
||||
"\"crefKT\": %d",
|
||||
(int)si->active,
|
||||
si->freq,
|
||||
s->id,
|
||||
s->ser,
|
||||
(int)s->validID,
|
||||
si->launchsite,
|
||||
s->lat,
|
||||
s->lon,
|
||||
s->alt,
|
||||
s->vs,
|
||||
s->hs,
|
||||
s->dir,
|
||||
s->sats,
|
||||
s->validPos,
|
||||
s->time,
|
||||
s->frame,
|
||||
(int)s->validTime,
|
||||
si->rssi,
|
||||
si->afc,
|
||||
si->rxStat,
|
||||
si->rxStart,
|
||||
si->norxStart,
|
||||
si->viewStart,
|
||||
si->lastState,
|
||||
s->launchKT,
|
||||
s->burstKT,
|
||||
s->countKT,
|
||||
s->crefKT
|
||||
);
|
||||
if ( !isnan( s->temperature ) ) {
|
||||
snprintf(payload, 1024, "%s%s%.1f", payload, ",\"temp\": ", s->temperature );
|
||||
}
|
||||
if ( !isnan( s->relativeHumidity ) ) {
|
||||
snprintf(payload, 1024, "%s%s%.1f", payload, ",\"humidity\": ", s->relativeHumidity );
|
||||
}
|
||||
if ( !isnan( s->pressure ) ) {
|
||||
snprintf(payload, 1024, "%s%s%.1f", payload, ",\"pressure\": ", s->pressure );
|
||||
}
|
||||
if ( !isnan( s->batteryVoltage && s->batteryVoltage > 0 ) ) {
|
||||
snprintf(payload, 1024, "%s%s%.1f", payload, ",\"batt\": ", s->batteryVoltage );
|
||||
}
|
||||
char subtype[11];
|
||||
if ( RS41::getSubtype( subtype, 11, si) == 0 ) {
|
||||
snprintf(payload, 1024, "%s%s%s%s", payload, ",\"subtype\": \"", subtype, "\"" );
|
||||
}
|
||||
snprintf(payload, 1024, "%s%s", payload, "}" ); // terminate payload string
|
||||
#endif
|
||||
strcat(payload, "}"); // terminate payload string
|
||||
|
||||
char topic[128];
|
||||
snprintf(topic, 128, "%s%s", this->prefix, "packet");
|
||||
Serial.print(payload);
|
||||
mqttClient.publish(topic, 1, 1, payload);
|
||||
}
|
29
RX_FSK/src/mqtt.h
Normal file
29
RX_FSK/src/mqtt.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifndef MQTT_h
|
||||
#define MQTT_h
|
||||
|
||||
#include <WiFi.h>
|
||||
//#include <AsyncMqttClient.h>
|
||||
#include <AsyncMqtt_Generic.h>
|
||||
#include "Sonde.h"
|
||||
#include "RS41.h"
|
||||
|
||||
class MQTT
|
||||
{
|
||||
public:
|
||||
WiFiClient mqttWifiClient;
|
||||
AsyncMqttClient mqttClient;
|
||||
TimerHandle_t mqttReconnectTimer;
|
||||
IPAddress ip;
|
||||
uint16_t port;
|
||||
const char *username;
|
||||
const char *password;
|
||||
const char *prefix;
|
||||
|
||||
void init(const char *host, uint16_t port, const char *id, const char *username, const char *password, const char *prefix);
|
||||
void publishPacket(SondeInfo *s);
|
||||
void publishUptime();
|
||||
private:
|
||||
void connectToMqtt();
|
||||
};
|
||||
|
||||
#endif
|
1715
RX_FSK/src/nav_gps_vel.cpp
Normal file
1715
RX_FSK/src/nav_gps_vel.cpp
Normal file
File diff suppressed because it is too large
Load Diff
148
RX_FSK/src/nav_gps_vel.h
Normal file
148
RX_FSK/src/nav_gps_vel.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
|
||||
|
||||
typedef struct {
|
||||
uint16_t prn;
|
||||
uint16_t week;
|
||||
uint32_t toa;
|
||||
char epoch[20];
|
||||
double toe;
|
||||
double toc;
|
||||
double e;
|
||||
double delta_n;
|
||||
double delta_i;
|
||||
double i0;
|
||||
double OmegaDot;
|
||||
double sqrta;
|
||||
double Omega0;
|
||||
double w;
|
||||
double M0;
|
||||
double tgd;
|
||||
double idot;
|
||||
double cuc;
|
||||
double cus;
|
||||
double crc;
|
||||
double crs;
|
||||
double cic;
|
||||
double cis;
|
||||
double af0;
|
||||
double af1;
|
||||
double af2;
|
||||
int gpsweek;
|
||||
uint16_t svn;
|
||||
uint8_t ura;
|
||||
uint8_t health;
|
||||
uint8_t conf;
|
||||
} EPHEM_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t t;
|
||||
double pseudorange;
|
||||
double pseudorate;
|
||||
double clock_corr;
|
||||
double clock_drift;
|
||||
double X;
|
||||
double Y;
|
||||
double Z;
|
||||
double vX;
|
||||
double vY;
|
||||
double vZ;
|
||||
int ephhr;
|
||||
double PR;
|
||||
double ephtime;
|
||||
int prn;
|
||||
} SAT_t;
|
||||
|
||||
|
||||
typedef struct {double X; double Y; double Z;} LOC_t;
|
||||
|
||||
typedef struct {double X; double Y; double Z;
|
||||
double vX; double vY; double vZ;} VEL_t;
|
||||
|
||||
|
||||
double dist(double X1, double Y1, double Z1, double X2, double Y2, double Z2);
|
||||
|
||||
void GPS_SatelliteClockCorrection(
|
||||
const unsigned short transmission_gpsweek, // GPS week when signal was transmit (0-1024+) [weeks]
|
||||
const double transmission_gpstow, // GPS time of week when signal was transmit [s]
|
||||
const unsigned short ephem_week, // ephemeris: GPS week (0-1024+) [weeks]
|
||||
const double toe, // ephemeris: time of week [s]
|
||||
const double toc, // ephemeris: clock reference time of week [s]
|
||||
const double af0, // ephemeris: polynomial clock correction coefficient [s],
|
||||
const double af1, // ephemeris: polynomial clock correction coefficient [s/s],
|
||||
const double af2, // ephemeris: polynomial clock correction coefficient [s/s^2]
|
||||
const double ecc, // ephemeris: eccentricity of satellite orbit []
|
||||
const double sqrta, // ephemeris: square root of the semi-major axis of orbit [m^(1/2)]
|
||||
const double delta_n, // ephemeris: mean motion difference from computed value [rad]
|
||||
const double m0, // ephemeris: mean anomaly at reference time [rad]
|
||||
const double tgd, // ephemeris: group delay differential between L1 and L2 [s]
|
||||
double* clock_correction );
|
||||
|
||||
void GPS_SatellitePosition_Ephem(
|
||||
const unsigned short gpsweek, // gps week of signal transmission (0-1024+) [week]
|
||||
const double gpstow, // time of week of signal transmission (gpstow-psr/c) [s]
|
||||
EPHEM_t ephem,
|
||||
double* clock_correction, // clock correction for this satellite for this epoch [m]
|
||||
double* satX, // satellite X position WGS84 ECEF [m]
|
||||
double* satY, // satellite Y position WGS84 ECEF [m]
|
||||
double* satZ // satellite Z position WGS84 ECEF [m]
|
||||
);
|
||||
|
||||
void GPS_SatelliteClockDriftCorrection(
|
||||
const unsigned short transmission_gpsweek, // GPS week when signal was transmit (0-1024+) [weeks]
|
||||
const double transmission_gpstow, // GPS time of week when signal was transmit [s]
|
||||
const unsigned short ephem_week, // ephemeris: GPS week (0-1024+) [weeks]
|
||||
const double toe, // ephemeris: time of week [s]
|
||||
const double toc, // ephemeris: clock reference time of week [s]
|
||||
const double af0, // ephemeris: polynomial clock correction coefficient [s],
|
||||
const double af1, // ephemeris: polynomial clock correction coefficient [s/s],
|
||||
const double af2, // ephemeris: polynomial clock correction coefficient [s/s^2]
|
||||
const double ecc, // ephemeris: eccentricity of satellite orbit []
|
||||
const double sqrta, // ephemeris: square root of the semi-major axis of orbit [m^(1/2)]
|
||||
const double delta_n, // ephemeris: mean motion difference from computed value [rad]
|
||||
const double m0, // ephemeris: mean anomaly at reference time [rad]
|
||||
const double tgd, // ephemeris: group delay differential between L1 and L2 [s]
|
||||
double* clock_correction, // ephemeris: satellite clock correction [m]
|
||||
double* clock_drift ) ;
|
||||
|
||||
void GPS_SatellitePositionVelocity_Ephem(
|
||||
const unsigned short gpsweek, // gps week of signal transmission (0-1024+) [week]
|
||||
const double gpstow, // time of week of signal transmission (gpstow-psr/c) [s]
|
||||
EPHEM_t ephem,
|
||||
double* clock_correction, // clock correction for this satellite for this epoch [m]
|
||||
double* clock_drift, // clock correction for this satellite for this epoch [m]
|
||||
double* satX, // satellite X position WGS84 ECEF [m]
|
||||
double* satY, // satellite Y position WGS84 ECEF [m]
|
||||
double* satZ, // satellite Z position WGS84 ECEF [m]
|
||||
double* satvX, // satellite X velocity WGS84 ECEF [m]
|
||||
double* satvY, // satellite Y velocity WGS84 ECEF [m]
|
||||
double* satvZ // satellite Z velocity WGS84 ECEF [m]
|
||||
);
|
||||
|
||||
|
||||
int NAV_ClosedFormSolution_FromPseudorange(
|
||||
SAT_t sats[4], // input: satellite position and pseudorange
|
||||
double* latitude, // output: ellipsoid latitude [rad]
|
||||
double* longitude, // ellipsoid longitude [rad]
|
||||
double* height, // ellipsoid height [m]
|
||||
double* rx_clock_bias, // receiver clock bias [m]
|
||||
double pos_ecef[3] );
|
||||
|
||||
int calc_DOPn(int n, SAT_t satss[], double pos_ecef[3], double DOP[4]);
|
||||
|
||||
int NAV_LinP(int N, SAT_t satv[], double pos_ecef[3], double dt,
|
||||
double dpos_ecef[3], double *cc);
|
||||
void ecef2elli(double X, double Y, double Z, double *lat, double *lon, double *alt);
|
||||
|
||||
int NAV_LinP(int N, SAT_t satv[], double pos_ecef[3], double dt,
|
||||
double dpos_ecef[3], double *cc);
|
||||
|
||||
int NAV_LinV(int N, SAT_t satv[], double pos_ecef[3],
|
||||
double vel_ecef[3], double dt,
|
||||
double dvel_ecef[3], double *cc);
|
||||
|
||||
int NAV_bancroft1(int N, SAT_t sats[], double pos_ecef[3], double *cc);
|
||||
|
||||
EPHEM_t *read_RNXpephs(const char *file);
|
||||
|
||||
|
1204
RX_FSK/src/rs92gps.cpp
Normal file
1204
RX_FSK/src/rs92gps.cpp
Normal file
File diff suppressed because it is too large
Load Diff
22
RX_FSK/src/rs92gps.h
Normal file
22
RX_FSK/src/rs92gps.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
typedef struct {
|
||||
int frnr;
|
||||
char id[11];
|
||||
int week; int gpssec;
|
||||
int jahr; int monat; int tag;
|
||||
int wday;
|
||||
int std; int min; float sek;
|
||||
double lat; double lon; double alt;
|
||||
double vH; double vD; double vU;
|
||||
int k;
|
||||
int sats[4];
|
||||
double dop;
|
||||
int freq;
|
||||
unsigned short aux[4];
|
||||
double diter;
|
||||
} gpx_t;
|
||||
|
||||
extern gpx_t gpx;
|
||||
|
||||
void print_frame(uint8_t *data, int len);
|
||||
void get_eph(const char *file);
|
32
RX_FSK/src/rsc.cpp
Normal file
32
RX_FSK/src/rsc.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* dxlAPRS toolchain
|
||||
*
|
||||
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef inttypes_h
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define N 255
|
||||
#define R 24
|
||||
#define K (N-R)
|
||||
|
||||
void *init_rs_char(int symsize,int gfpoly,int fcr,int prim,int nroots,int pad);
|
||||
int decode_rs_char(void *arg,
|
||||
unsigned char *data, int *eras_pos, int no_eras);
|
||||
|
||||
void *rs;
|
||||
|
||||
void initrsc()
|
||||
{
|
||||
rs = init_rs_char( 8, 0x11d, 0, 1, R, 0);
|
||||
}
|
||||
|
||||
|
||||
int decodersc(char *data, uint32_t *eras_pos, uint32_t no_eras)
|
||||
{
|
||||
return decode_rs_char(rs, (unsigned char *)data, (int *)eras_pos, no_eras);
|
||||
}
|
17
RX_FSK/src/rsc.h
Normal file
17
RX_FSK/src/rsc.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* dxlAPRS toolchain
|
||||
*
|
||||
* Copyright (C) Christian Rabler <oe5dxl@oevsv.at>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#ifndef rsc_H_
|
||||
#define rsc_H_
|
||||
|
||||
|
||||
long decodersc(char [], uint32_t [], uint32_t);
|
||||
|
||||
void initrsc(void);
|
||||
|
||||
|
||||
#endif /* rsc_H_ */
|
436
RX_FSK/src/rsc_decode.cpp
Normal file
436
RX_FSK/src/rsc_decode.cpp
Normal file
|
@ -0,0 +1,436 @@
|
|||
/*
|
||||
* Copyright 2016 Hannes Schmelzer, OE5HPM
|
||||
* doing several cleanups and architecture changes, no functional change yet
|
||||
*
|
||||
* General purpose Reed-Solomon decoder for 8-bit symbols or less
|
||||
* Copyright 2003 Phil Karn, KA9Q
|
||||
* May be used under the terms of the GNU Lesser General Public License (LGPL)
|
||||
*
|
||||
* The guts of the Reed-Solomon decoder, meant to be #included
|
||||
* into a function body with the following typedefs, macros and variables supplied
|
||||
* according to the code parameters:
|
||||
|
||||
* data_t - a typedef for the data symbol
|
||||
* data_t data[] - array of rs->nn data and parity symbols to be corrected in place
|
||||
* retval - an integer lvalue into which the decoder's return code is written
|
||||
* NROOTS - the number of roots in the RS code generator polynomial,
|
||||
* which is the same as the number of parity symbols in a block.
|
||||
Integer variable or literal.
|
||||
* rs->nn - the total number of symbols in a RS block. Integer variable or literal.
|
||||
* rs->pad - the number of pad symbols in a block. Integer variable or literal.
|
||||
* rs->alpha_to - The address of an array of rs->nn elements to convert Galois field
|
||||
* elements in index (log) form to polynomial form. Read only.
|
||||
* rs->index_of - The address of an array of rs->nn elements to convert Galois field
|
||||
* elements in polynomial form to index (log) form. Read only.
|
||||
* MODNN - a function to reduce its argument modulo rs->nn. May be inline or a macro.
|
||||
* rs->fcr - An integer literal or variable specifying the first consecutive root of the
|
||||
* Reed-Solomon generator polynomial. Integer variable or literal.
|
||||
* rs->prim - The primitive root of the generator poly. Integer variable or literal.
|
||||
* DEBUG - If set to 1 or more, do various internal consistency checking. Leave this
|
||||
* undefined for production code
|
||||
|
||||
* The memset(), memmove(), and memcpy() functions are used. The appropriate header
|
||||
* file declaring these functions (usually <string.h>) must be included by the calling
|
||||
* program.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct rs {
|
||||
unsigned int magic; /* struct magic */
|
||||
int mm; /* Bits per symbol */
|
||||
int nn; /* Symbols per block (= (1<<mm)-1) */
|
||||
unsigned char *alpha_to; /* log lookup table */
|
||||
unsigned char *index_of; /* Antilog lookup table */
|
||||
unsigned char *genpoly; /* Generator polynomial */
|
||||
int nroots; /*
|
||||
* Number of generator
|
||||
* roots = number of parity symbols
|
||||
*/
|
||||
int fcr; /* First consecutive root, index form */
|
||||
int prim; /* Primitive element, index form */
|
||||
int iprim; /* prim-th root of 1, index form */
|
||||
int pad; /* Padding bytes in shortened block */
|
||||
};
|
||||
|
||||
static inline int modnn(struct rs *rs,int x)
|
||||
{
|
||||
while (x >= rs->nn) {
|
||||
x -= rs->nn;
|
||||
x = (x >> rs->mm) + (x & rs->nn);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
#define MODNN(x) modnn(rs, x)
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#define MAGIC 0xABCD6722
|
||||
|
||||
void free_rs_char(void *arg)
|
||||
{
|
||||
struct rs *rs = (struct rs *)arg;
|
||||
|
||||
if (rs == NULL)
|
||||
return;
|
||||
if (rs->magic != MAGIC)
|
||||
return;
|
||||
|
||||
if (rs->alpha_to != NULL)
|
||||
free(rs->alpha_to);
|
||||
if (rs->index_of != NULL)
|
||||
free(rs->index_of);
|
||||
if (rs->genpoly != NULL)
|
||||
free(rs->genpoly);
|
||||
free(rs);
|
||||
}
|
||||
|
||||
/* Initialize a Reed-Solomon codec
|
||||
* symsize = symbol size, bits
|
||||
* gfpoly = Field generator polynomial coefficients
|
||||
* fcr = first root of RS code generator polynomial, index form
|
||||
* prim = primitive element to generate polynomial roots
|
||||
* nroots = RS code generator polynomial degree (number of roots)
|
||||
* pad = padding bytes at front of shortened block
|
||||
*/
|
||||
void *init_rs_char(int symsize, int gfpoly, int fcr, int prim,
|
||||
int nroots, int pad)
|
||||
{
|
||||
struct rs *rs;
|
||||
|
||||
int i, j, sr,root,iprim;
|
||||
|
||||
/* Check parameter ranges */
|
||||
if (symsize < 0 || symsize > 8*sizeof(unsigned char))
|
||||
return NULL;
|
||||
if (fcr < 0 || fcr >= (1<<symsize))
|
||||
return NULL;
|
||||
if (prim <= 0 || prim >= (1<<symsize))
|
||||
return NULL;
|
||||
if (nroots < 0 || nroots >= (1<<symsize))
|
||||
return NULL;
|
||||
if (pad < 0 || pad >= ((1<<symsize) -1 - nroots))
|
||||
return NULL;
|
||||
|
||||
rs = (struct rs*)malloc(sizeof(*rs));
|
||||
if (rs == NULL) {
|
||||
printf("%s: cannot allocate memory!\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
memset(rs, 0, sizeof(*rs));
|
||||
rs->magic = MAGIC;
|
||||
|
||||
rs->mm = symsize;
|
||||
rs->nn = (1<<symsize)-1;
|
||||
rs->pad = pad;
|
||||
|
||||
rs->alpha_to = (unsigned char *)malloc(sizeof(unsigned char)*(rs->nn+1));
|
||||
if (rs->alpha_to == NULL) {
|
||||
free(rs);
|
||||
return NULL;
|
||||
}
|
||||
rs->index_of = (unsigned char *)malloc(sizeof(unsigned char)*(rs->nn+1));
|
||||
if (rs->index_of == NULL) {
|
||||
free(rs->alpha_to);
|
||||
free(rs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Generate Galois field lookup tables */
|
||||
rs->index_of[0] = rs->nn; /* log(zero) = -inf */
|
||||
rs->alpha_to[rs->nn] = 0; /* alpha**-inf = 0 */
|
||||
sr = 1;
|
||||
for (i = 0; i < rs->nn; i++) {
|
||||
rs->index_of[sr] = i;
|
||||
rs->alpha_to[i] = sr;
|
||||
sr <<= 1;
|
||||
if (sr & (1<<symsize))
|
||||
sr ^= gfpoly;
|
||||
sr &= rs->nn;
|
||||
}
|
||||
if (sr != 1) {
|
||||
/* field generator polynomial is not primitive! */
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Form RS code generator polynomial from its roots */
|
||||
rs->genpoly = (unsigned char *)malloc(sizeof(unsigned char)*(nroots+1));
|
||||
if(rs->genpoly == NULL) {
|
||||
free(rs->alpha_to);
|
||||
free(rs->index_of);
|
||||
free(rs);
|
||||
return NULL;
|
||||
}
|
||||
rs->fcr = fcr;
|
||||
rs->prim = prim;
|
||||
rs->nroots = nroots;
|
||||
|
||||
/* Find prim-th root of 1, used in decoding */
|
||||
for (iprim = 1; (iprim % prim) != 0; iprim += rs->nn)
|
||||
;
|
||||
rs->iprim = iprim / prim;
|
||||
|
||||
rs->genpoly[0] = 1;
|
||||
for (i = 0, root = fcr*prim; i < nroots; i++, root += prim) {
|
||||
rs->genpoly[i+1] = 1;
|
||||
|
||||
/* Multiply rs->genpoly[] by @**(root + x) */
|
||||
for (j = i; j > 0; j--) {
|
||||
if (rs->genpoly[j] != 0)
|
||||
rs->genpoly[j] = rs->genpoly[j-1] ^ rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[j]] + root)];
|
||||
else
|
||||
rs->genpoly[j] = rs->genpoly[j-1];
|
||||
}
|
||||
/* rs->genpoly[0] can never be zero */
|
||||
rs->genpoly[0] = rs->alpha_to[modnn(rs,rs->index_of[rs->genpoly[0]] + root)];
|
||||
}
|
||||
/* convert rs->genpoly[] to index form for quicker encoding */
|
||||
for (i = 0; i <= nroots; i++)
|
||||
rs->genpoly[i] = rs->index_of[rs->genpoly[i]];
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
int decode_rs_char(void *arg,
|
||||
unsigned char *data, int *eras_pos, int no_eras)
|
||||
{
|
||||
struct rs *rs = (struct rs *)arg;
|
||||
|
||||
if (rs == NULL)
|
||||
return -1;
|
||||
if (rs->magic != MAGIC)
|
||||
return -1;
|
||||
|
||||
int retval;
|
||||
int deg_lambda, el, deg_omega;
|
||||
int i, j, r,k;
|
||||
|
||||
unsigned char u,q,tmp,num1,num2,den,discr_r;
|
||||
unsigned char lambda[rs->nroots+1], s[rs->nroots]; /* Err+Eras Locator poly
|
||||
* and syndrome poly */
|
||||
unsigned char b[rs->nroots+1], t[rs->nroots+1], omega[rs->nroots+1];
|
||||
unsigned char root[rs->nroots], reg[rs->nroots+1], loc[rs->nroots];
|
||||
int syn_error, count;
|
||||
|
||||
/* form the syndromes; i.e., evaluate data(x) at roots of g(x) */
|
||||
for (i = 0; i < rs->nroots; i++)
|
||||
s[i] = data[0];
|
||||
|
||||
for (j = 1; j < rs->nn-rs->pad; j++) {
|
||||
for(i=0;i<rs->nroots;i++) {
|
||||
if(s[i] == 0) {
|
||||
s[i] = data[j];
|
||||
} else {
|
||||
s[i] = data[j] ^ rs->alpha_to[MODNN(rs->index_of[s[i]] + (rs->fcr+i)*rs->prim)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert syndromes to index form, checking for nonzero condition */
|
||||
syn_error = 0;
|
||||
for (i = 0; i < rs->nroots; i++) {
|
||||
syn_error |= s[i];
|
||||
s[i] = rs->index_of[s[i]];
|
||||
}
|
||||
|
||||
if (!syn_error) {
|
||||
/* if syndrome is zero, data[] is a codeword and there are no
|
||||
* errors to correct. So return data[] unmodified
|
||||
*/
|
||||
count = 0;
|
||||
goto finish;
|
||||
}
|
||||
memset(&lambda[1], 0, rs->nroots*sizeof(lambda[0]));
|
||||
lambda[0] = 1;
|
||||
|
||||
if (no_eras > 0) {
|
||||
/* Init lambda to be the erasure locator polynomial */
|
||||
lambda[1] = rs->alpha_to[MODNN(rs->prim*(rs->nn-1-eras_pos[0]))];
|
||||
for (i = 1; i < no_eras; i++) {
|
||||
u = MODNN(rs->prim*(rs->nn-1-eras_pos[i]));
|
||||
for (j = i+1; j > 0; j--) {
|
||||
tmp = rs->index_of[lambda[j - 1]];
|
||||
if(tmp != rs->nn)
|
||||
lambda[j] ^= rs->alpha_to[MODNN(u + tmp)];
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG >= 1
|
||||
/* Test code that verifies the erasure locator polynomial just constructed
|
||||
Needed only for decoder debugging. */
|
||||
|
||||
/* find roots of the erasure location polynomial */
|
||||
for(i=1;i<=no_eras;i++)
|
||||
reg[i] = rs->index_of[lambda[i]];
|
||||
|
||||
count = 0;
|
||||
for (i = 1,k=rs->iprim-1; i <= rs->nn; i++,k = MODNN(k+rs->iprim)) {
|
||||
q = 1;
|
||||
for (j = 1; j <= no_eras; j++)
|
||||
if (reg[j] != rs->nn) {
|
||||
reg[j] = MODNN(reg[j] + j);
|
||||
q ^= rs->alpha_to[reg[j]];
|
||||
}
|
||||
if (q != 0)
|
||||
continue;
|
||||
/* store root and error location number indices */
|
||||
root[count] = i;
|
||||
loc[count] = k;
|
||||
count++;
|
||||
}
|
||||
if (count != no_eras) {
|
||||
printf("count = %d no_eras = %d\n lambda(x) is WRONG\n",count,no_eras);
|
||||
count = -1;
|
||||
goto finish;
|
||||
}
|
||||
#if DEBUG >= 2
|
||||
printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");
|
||||
for (i = 0; i < count; i++)
|
||||
printf("%d ", loc[i]);
|
||||
printf("\n");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
for (i = 0; i < rs->nroots+1; i++)
|
||||
b[i] = rs->index_of[lambda[i]];
|
||||
|
||||
/*
|
||||
* Begin Berlekamp-Massey algorithm to determine error+erasure
|
||||
* locator polynomial
|
||||
*/
|
||||
r = no_eras;
|
||||
el = no_eras;
|
||||
while (++r <= rs->nroots) { /* r is the step number */
|
||||
/* Compute discrepancy at the r-th step in poly-form */
|
||||
discr_r = 0;
|
||||
for (i = 0; i < r; i++) {
|
||||
if ((lambda[i] != 0) && (s[r-i-1] != rs->nn)) {
|
||||
discr_r ^= rs->alpha_to[MODNN(rs->index_of[lambda[i]] + s[r-i-1])];
|
||||
}
|
||||
}
|
||||
discr_r = rs->index_of[discr_r]; /* Index form */
|
||||
if (discr_r == rs->nn) {
|
||||
/* 2 lines below: B(x) <-- x*B(x) */
|
||||
memmove(&b[1],b,rs->nroots*sizeof(b[0]));
|
||||
b[0] = rs->nn;
|
||||
} else {
|
||||
/* 7 lines below: T(x) <-- lambda(x) - discr_r*x*b(x) */
|
||||
t[0] = lambda[0];
|
||||
for (i = 0 ; i < rs->nroots; i++) {
|
||||
if(b[i] != rs->nn)
|
||||
t[i+1] = lambda[i+1] ^ rs->alpha_to[MODNN(discr_r + b[i])];
|
||||
else
|
||||
t[i+1] = lambda[i+1];
|
||||
}
|
||||
if (2 * el <= r + no_eras - 1) {
|
||||
el = r + no_eras - el;
|
||||
/*
|
||||
* 2 lines below: B(x) <-- inv(discr_r) *
|
||||
* lambda(x)
|
||||
*/
|
||||
for (i = 0; i <= rs->nroots; i++)
|
||||
b[i] = (lambda[i] == 0) ? rs->nn : MODNN(rs->index_of[lambda[i]] - discr_r + rs->nn);
|
||||
} else {
|
||||
/* 2 lines below: B(x) <-- x*B(x) */
|
||||
memmove(&b[1],b,rs->nroots*sizeof(b[0]));
|
||||
b[0] = rs->nn;
|
||||
}
|
||||
memcpy(lambda,t,(rs->nroots+1)*sizeof(t[0]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert lambda to index form and compute deg(lambda(x)) */
|
||||
deg_lambda = 0;
|
||||
for (i = 0;i < rs->nroots+1; i++){
|
||||
lambda[i] = rs->index_of[lambda[i]];
|
||||
if(lambda[i] != rs->nn)
|
||||
deg_lambda = i;
|
||||
}
|
||||
/* Find roots of the error+erasure locator polynomial by Chien search */
|
||||
memcpy(®[1], &lambda[1], rs->nroots*sizeof(reg[0]));
|
||||
count = 0; /* Number of roots of lambda(x) */
|
||||
for (i = 1,k=rs->iprim-1; i <= rs->nn; i++,k = MODNN(k+rs->iprim)) {
|
||||
q = 1; /* lambda[0] is always 0 */
|
||||
for (j = deg_lambda; j > 0; j--) {
|
||||
if (reg[j] != rs->nn) {
|
||||
reg[j] = MODNN(reg[j] + j);
|
||||
q ^= rs->alpha_to[reg[j]];
|
||||
}
|
||||
}
|
||||
if (q != 0)
|
||||
continue; /* Not a root */
|
||||
/* store root (index-form) and error location number */
|
||||
#if DEBUG>=2
|
||||
printf("count %d root %d loc %d\n",count,i,k);
|
||||
#endif
|
||||
root[count] = i;
|
||||
loc[count] = k;
|
||||
/* If we've already found max possible roots,
|
||||
* abort the search to save time
|
||||
*/
|
||||
if(++count == deg_lambda)
|
||||
break;
|
||||
}
|
||||
if (deg_lambda != count) {
|
||||
/*
|
||||
* deg(lambda) unequal to number of roots => uncorrectable
|
||||
* error detected
|
||||
*/
|
||||
count = -1;
|
||||
goto finish;
|
||||
}
|
||||
/*
|
||||
* Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo
|
||||
* x**rs->nroots). in index form. Also find deg(omega).
|
||||
*/
|
||||
deg_omega = deg_lambda-1;
|
||||
for (i = 0; i <= deg_omega;i++) {
|
||||
tmp = 0;
|
||||
for (j = i; j >= 0; j--) {
|
||||
if ((s[i - j] != rs->nn) && (lambda[j] != rs->nn))
|
||||
tmp ^= rs->alpha_to[MODNN(s[i - j] + lambda[j])];
|
||||
}
|
||||
omega[i] = rs->index_of[tmp];
|
||||
}
|
||||
/*
|
||||
* Compute error values in poly-form. num1 = omega(inv(X(l))), num2 =
|
||||
* inv(X(l))**(rs->fcr-1) and den = lambda_pr(inv(X(l))) all in poly-form
|
||||
*/
|
||||
for (j = count-1; j >=0; j--) {
|
||||
num1 = 0;
|
||||
for (i = deg_omega; i >= 0; i--) {
|
||||
if (omega[i] != rs->nn)
|
||||
num1 ^= rs->alpha_to[MODNN(omega[i] + i * root[j])];
|
||||
}
|
||||
num2 = rs->alpha_to[MODNN(root[j] * (rs->fcr - 1) + rs->nn)];
|
||||
den = 0;
|
||||
|
||||
/* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */
|
||||
for (i = MIN(deg_lambda, rs->nroots-1) & ~1; i >= 0; i -=2) {
|
||||
if(lambda[i+1] != rs->nn)
|
||||
den ^= rs->alpha_to[MODNN(lambda[i+1] + i * root[j])];
|
||||
}
|
||||
#if DEBUG >= 1
|
||||
if (den == 0) {
|
||||
printf("\n ERROR: denominator = 0\n");
|
||||
count = -1;
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
/* Apply error to data */
|
||||
if (num1 != 0 && loc[j] >= rs->pad) {
|
||||
data[loc[j]-rs->pad] ^= rs->alpha_to[MODNN(rs->index_of[num1] + rs->index_of[num2] + rs->nn - rs->index_of[den])];
|
||||
}
|
||||
}
|
||||
finish:
|
||||
if(eras_pos != NULL) {
|
||||
for (i = 0; i < count; i++)
|
||||
eras_pos[i] = loc[i];
|
||||
}
|
||||
retval = count;
|
||||
|
||||
return retval;
|
||||
}
|
BIN
RX_FSK/update.ino.bin
Normal file
BIN
RX_FSK/update.ino.bin
Normal file
Binary file not shown.
4
RX_FSK/version.h
Normal file
4
RX_FSK/version.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
const char *version_name = "RadioSonde";
|
||||
const char *version_id = "1.0.0";
|
||||
const int SPIFFS_MAJOR=1;
|
||||
const int SPIFFS_MINOR=0;
|
99
Setup.md
Executable file
99
Setup.md
Executable file
|
@ -0,0 +1,99 @@
|
|||
# Près-requis
|
||||
<img src="http://xavier.debert.free.fr/RS/TTGO2.jpg" width="50%">
|
||||
|
||||
|
||||
## Arduino IDE
|
||||
|
||||
Avoir une version à jour exemple 1.8.13(juillet2020)
|
||||
|
||||
## ESP32 support
|
||||
|
||||
Fichier -> Préférences
|
||||
|
||||
en bas dans la case "URL de gestionnaire de cartes supplémentaires"
|
||||
|
||||
Ajouter *https://dl.espressif.com/dl/package_esp32_index.json* et appuier sur oK
|
||||
|
||||
Puis dans Outils
|
||||
Outils -> type de cartes -> Gestionnaire de cartes
|
||||
|
||||
dans la case de recherche taper "esp32"
|
||||
|
||||
Installer "esp32 by Espressif Systems"
|
||||
|
||||
Puis après
|
||||
|
||||
## ESP32 Flash Filesystem Upload support
|
||||
|
||||
Télécharger le fichier zip de la dernière version
|
||||
https://github.com/me-no-dev/arduino-esp32fs-plugin/releases/
|
||||
|
||||
Décompresser l'archive dans le répértoire tools de votre Arduino IDE
|
||||
|
||||
## Ajouter les bibliothèques
|
||||
|
||||
Séléctionner Outils -> Gestionnaire de bibliothèques
|
||||
|
||||
Installer "U8g2"
|
||||
|
||||
Installer "MicroNMEA"
|
||||
|
||||
mais pour les fonts, car le TTGO fonctionne avec OLED SSD1306 par défaut!
|
||||
|
||||
## Ajouter les bibliothèques, parties 2
|
||||
|
||||
Depuis https://github.com/me-no-dev/ESPAsyncWebServer télécharger le ZIP , l'extraire dans "libraries"
|
||||
, renommer le répertoire en ESPAsyncWebServer (supprimer juste "-master")
|
||||
|
||||
Depuis https://github.com/me-no-dev/AsyncTCP télécharger le ZIP, l'extraire dans "libraries", et renommer le répertoire en AsyncTCP
|
||||
|
||||
de même pour https://github.com/lewisxhe/AXP202X_Library télécharger le ZIP, l'extraire dans "libraries", et renommer le répertoire en AXP202X_Library
|
||||
|
||||
|
||||
## Ajouter les bibliothèques, parties 3
|
||||
|
||||
Copier libraries/SX1278FSK
|
||||
et libraries/SondeLib
|
||||
et libraries/fonts
|
||||
|
||||
fourni dans libraries
|
||||
|
||||
|
||||
```
|
||||
ou sous Linux un lien symbolique est aussi possible mais pas obligatoire!
|
||||
cd ~/Arduino/libraries
|
||||
ln -s <whereyouclonedthegit>/radiosonde/libraries/SondeLib/ .
|
||||
ln -s <whereyouclonedthegit>/radiosonde/libraries/SX1278FSK/ .
|
||||
```
|
||||
Redémarrer Arduino IDE
|
||||
|
||||
## Ajout carte esp32
|
||||
|
||||
Allez dans Outils-> type de cartes -> gestionnaire de cartes
|
||||
|
||||
puis dans la case taper esp32 et Installer.
|
||||
|
||||
## Dernière parties
|
||||
|
||||
Dans Outils -> Esp32 arduino: ->
|
||||
Séléctionner "TTGO LoRa32-OLED v1"
|
||||
|
||||
Puis il vous faut ouvrir le fichier
|
||||
RadioSonde_FSK.ino
|
||||
|
||||
Compiler et Téléverser le dans votre TTGO
|
||||
|
||||
puis il faut téléverser maintenant les DATA!
|
||||
|
||||
Dans Outils
|
||||
cliquer sur ESP32 Sketch Data Upload
|
||||
|
||||
voila le TTGO est prêt!
|
||||
|
||||
Pour les futur mise à jour,
|
||||
j'ai prévue une mise à jour directe via OTA depuis le TTGO donc
|
||||
s'il est connecté à internet depuis votre Smartphone ou votre Box.
|
||||
Cela se fera depuis le menu de la page Web.
|
||||
73
|
||||
Xavier
|
||||
|
Loading…
Reference in New Issue
Block a user