diff --git a/App/apps/aprs_symbols_20.py b/App/apps/aprs_symbols_20.py new file mode 100644 index 00000000..274c3cb8 --- /dev/null +++ b/App/apps/aprs_symbols_20.py @@ -0,0 +1,78 @@ +"""Shared 20x20 monochrome APRS symbol assets. + +Each icon is stored in native ST7565 page order: 20 bytes for each of three +8-pixel pages. Only the low four bits of the third page are used. This lets +the overlay apps copy an icon straight from external flash to the framebuffer. + +The masks were validated pixel by pixel with +aprsrx/test/aprs_symbols_20_editor.html before being packed here. +""" + +WIDTH = 20 +PAGES = 3 +BYTES_PER_ICON = WIDTH * PAGES + +CODES = ( + "/#", "/X", "/&", "/Y", "/'", "/[", "/-", "/\\", + "/.", "/^", "/0", "/_", "/:", "/a", "/;", "/b", + "/<", "/f", "/>", "/g", "/C", "/j", "/E", "/k", + "/I", "/m", "/K", "/O", "/P", "/s", "/R", "/v", + "/y", "/T", "/U", "/V", "\\#", "\\&", "\\-", "/W", + "\\.", "\\0", "E0", "I0", "W0", "YY", "\\^", "\\Y", +) + +_HEX = """ +00000000000000c0f0fcf0c000000000000000000001030787cfffffff7fffffffcf8707030100000000000607030101000000010103070600000000 +800060606020202020a0f0a020202020606060001b1f0e04040c1c3e7fff7f737f7af27c380000000000000000000000010303030303030201000000 +000000001c04047c04c4fcc4047c04041c00000000000000000080f0fccfcfcffcf08000000000000000000000040707050404040507070400000000 +0000000000000080e000fefcf0c000000000000000008080a0b8bebfbf80ffdfdfdfdfdcd0c060200000050505050505050505050505050505000000 +8080000000040c38f0e0c0800000000000000000203f1f0e0e0e0e8eeeff7f3f1f0e0e0e0e0e0e040000000000040603010000000000000000000000 +000000000000000098bcbcbc980000000000000000000000001c1e03e3ff3fffe3031e1c000000000000000000000006070700070706000000000000 +0000000000000080c0c28a2afe2a0a0200000000000000f8fcfe1f1fffff1f1f1ffcf800000000000000000707070707070704040407070000000000 +00000030f090101010101010101090f0300000000000000000030e38e08080e0380e0300000000000000000000000000000303000000000000000000 +00000078f8f0e0c080000080c0e0f0f878000000000000c0e0f1fb7f3f1f1f3f7ffbf1e0c00000000000000303010000000000000000010303000000 +00000000008080c0f0dcdcf0c0808000000000000c0e0e0707070783ffffffff83070707070e0e0c0000000000070303010707010303070000000000 +000000c0e030101808080808181030e0c000000000001f7fe080000000000000000080e07f1f00000000000000010103020202020301010000000000 +00007c381010d0d010386c6c000000000000000000000000181cffff1c180000007cfc7c000000000000000000000707020202020202030000000000 +00000000008000c0f0fcfee08080e0000000000000000038feffff1f0f01031f9ffff9fc3e0000000000000000010302000000020303010000000000 +0080c0c0c0c0c04040c0c0c0f0f87840c0800000007f3f9fdf9939606079797f7f3f9cdc9c3d7e7c0000000103010000000000000000010301000000 +0000000000000000c0f0c0000000000000000000000000c0f0f8fe3f0f070f3ffef8e0c0000000000001010101010101010101010101010101010100 +0000000000000040c0400000101090e0800000000070882474248c722127190905738924772488700000000101010000000000000000000101010000 +00000000000000000000008898f0c000000000003249b5b54933061c3c3c3f1f073349b5b54932000000000000000000000000000000000000000000 +00008080c040406020203010101888888880c0807e3e9fdf9f3f9fdf9f3f617f7c7c3f98d898397f0000010301000103010000000000000103010000 +000000008080c0c0c0c0c0c0c080000000000000787c1c4fefed4c1c3c3f3c3c1d4feeec4c1c7c780000000000000000000000000000000000000000 +0000000000000040c0c0800000000000808000000c1830606070703838191f0f0e060703030101000000000000000000000000000000000000000000 +00000000000000000000000080c07038381000000e1f1f1e9cdc6c34180c161b1d1c1c1c1e1f1f0e0002070703000000000000000000000000000000 +000000000000000000e02020e0202020608000003e3e0e66f6660e1e1f1f1c1c1f0e66f6660f1f3e0000000000000000000000000000000000000000 +000080c06030101888c8c88818103060c080000000070f18306040c78f9f9f8fc7406030180f07000000000000000000000000000000000000000000 +e0e0e0e0e0e0e0e0e0e0e0e0e0e00080808000003f1fcfefcf1f3f1fcfefcf1f3f3f13cfe8c81f3c0000000100000000000100000000000001000000 +000000000000007c44c4c4447c000000000000000000e0203c24e4040407070404e4243c20e000000000010101010100000000000001010101010000 +0000f80601f88c0070f0f070008cf80106f8000000000003040001e0b8cfcfb8e0010004030000000000000000020303020202020303020000000000 +0000000000000080c0e0fee6c680000000000000000000f8fc1e1fffff1c1c1cffff1f1efcf800000000000303030303030000000303030303030000 +0000000000f0fc0cf6fafefaf60cfcf000000000000000000003071c61dfbfdf611c0703000000000000000000000000000606060000000000000000 +000000000000240840606c604008240000000000703898d8dc9e3b79797f7f79793b9edcd89838780000000101000000000000000000000101000000 +00000000000000000000c0d0180c0c0e0e00000000103070787c76767f777f777f777c78703000000000010101010101010101010101010101010000 +0080c0e0e0e0e0e0e0e0e0e0e0606060e0c00000003f1fc8e8c8183f3f2020203f3f19c9ebce1c380000000001000000000000000000000001000000 +00c0c0e0e0e0e0e0e0e0e0e0e06060c080000000003f1fcfefcf1f3f3f3f3f3f3f1ccceccd1f3e3c0000000001000000000000000000000100000000 +00e0000000c0000000c0000000c0000000c00000000f01010107010101ff010101070101010701000000000000000000000300000000000000000000 +00e03090d050505254585854525050d09030e00000ff803f6040424e4240424c424040603f80ff000000010103030301010101010103030301010000 +00e03030f03030f03030f03030f0303070f0e000003f0e66f7660e3f3e3e3f3e0e67f6640c3f3f3c0000000000000000000000000000000000000000 +00000080c0c08000000080c8f8e0c080000000003049b5b54933071f1f1f1f1f073349b5b54932000000000000000000000000000000000000000000 +0000c07018080c0486e2e286040c081870c00000000f30e08003677f3f1f1f3f7f670380e0300f000000000001010302060404060203010100000000 +000080e030180884c6e2f2e2c684081830e0800000001f70c0860f1f3f7fff7f3f1f0f86c0701f000000000000010102060404040602010100000000 +0000000000000082c2ca8a2aff2a0a0a02020000000000f8fcfe1f1fffff1f1f1ffcf800000000000000000707070707070704040407070000000000 +000080c0e0e0f0f8fcfcfefcf8f8f0f0e0c0000000000143630707436307074363070743630100000000000000020300000203000002030000000000 +000000000070787c1c1c1cfcf8f00000000000000000000000000000dcdedf0701000000000000000000000000000000010101000000000000000000 +000080e0301888cce4e4e4e4cc881830e080000000000f3860c78f9f3f3f3f3f9f8fc760380f00000000000000000001010101010100000000000000 +000000000080c0c0ac1e1eacc0c0800000000000000000c0e0f9c5030100000103c5f9e0c00000000000000001010000000000000000010100000000 +0000000000000080dc3e3edc8000000000000000000000c0e0f8eec380808080c3eef8e0c00000000000000103030301000000000103030301000000 +000080603028fc2c26fe262cfc2830608000000000000f3262a7faa222ff22a2faa762320f0000000000000000000101030303010100000000000000 +000000000000c06070607f60c080000000000000000000000000ff5455fd5554ff0f0000000000000000000000000103030303030100000000000000 +008000000000001090f0f0901000000000008000030703030303034347ffff4743030303030307030000000000000000000000000000000000000000 +00000000000080c0e0c0fefe8000000000000000000000000000ffa8faaafaa8ffff0000000000000000000000000102030203020301000000000000 +""" + +BITMAPS = bytes.fromhex(_HEX) + +if len(CODES) != 48 or len(BITMAPS) != len(CODES) * BYTES_PER_ICON: + raise ValueError("invalid APRS 20x20 symbol table") diff --git a/App/apps/aprsrx/README.md b/App/apps/aprsrx/README.md index 37a1a3ec..0f41b391 100644 --- a/App/apps/aprsrx/README.md +++ b/App/apps/aprsrx/README.md @@ -11,7 +11,7 @@ Status: | Audio path an app can sample | **Done** by EPIRB 406: RX audio on PA4, ADC channel 4 at 9.6 kHz | | Integer demodulator, modelled on synthetic audio (`test/model_rx.py`) | **Done** (see below) | | Flipper Zero test transmitter (`test/flipper_aprs.py`) | **Done**, files in `test/flipper/` | -| Radio app (`aprsrx_app.c`) | **v0.1 receives the Flipper frames on the radio**; v0.3 decodes Mic-E (on air: F5RAV via F1PRY-14); v0.4 decodes continuously with 3 slicers (on air: F1PRY-14 via F5KTR-3); v0.5 shows standard positions, the frequency bottom right as Beacon, drops `pp` and the UP/DOWN/5 tuning offset to fit 4 KiB (3976 B); main-screen frequency, WAIT capsule (4068 B); v0.6: speaker off, key 1 toggles it, per-slicer counters dropped (not built yet) | +| Radio app (`aprsrx_app.c`) | **v0.1 receives the Flipper frames on the radio**; v0.3 decodes Mic-E (on air: F5RAV via F1PRY-14); v0.4 decodes continuously with 3 slicers (on air: F1PRY-14 via F5KTR-3); v0.5 shows standard positions; v0.6 adds the speaker key; v0.7 adds the corrected 20x20 APRS symbol bitmaps (not built here) | | Bench test with the Flipper on 433.650 MHz | **Done** (2026-09-30, v0.1: `_long` 10/10 in STD; `_badfcs` not shown) | | Real station: FT3D beacon on 144.800 MHz | **Done** (2026-09-30, v0.1: Mic-E frame `>TXUPX9` received, FCS good, = 48°50.89' N 2°16.25' E) | | Mic-E decoding (`test/mice.py`: spec encoder vs the app's decoder) | **Done** in the model: 6 cases + the FT3D frame | @@ -41,7 +41,7 @@ The screen is redrawn after a new frame, a key, or every 5 s. |---|---| | Status bar | `APRS RX` title, then a `WAIT` capsule until the first frame, the speaker icon while the speaker is on, then in the scroll view ▲ while rows are hidden above and ▼ while rows are hidden below (x = 72-76 as in APRS TX, the speaker icon at x = 59-68; both drawn in one asset read) | | Lines 0-3 | The frame in the small font (18 characters a row, non-ASCII shown as `.`), 4 rows at a time, scrolled pixel by pixel with UP/DOWN (v0.7): source call and frame number in bold (`F4HWN-7 #3`), `>DEST,DIGI*,...` (as many path entries as fit two rows), then the info field, whole. For Mic-E (most Yaesu/Kenwood beacons, v0.3): latitude `48 50.89N`, longitude `002 16.25E`, speed km/h, course and symbol, the message type (`Off Duty`, `En Route`...), then altitude and comment without the device markers; for an uncompressed position (`!` `=` `/` `@`, v0.5): latitude, longitude, then the timestamp if any, the symbol (table + code) and the comment. Compressed positions stay raw text. A new frame scrolls back to the top. Key * switches to the compact view (below) | -| Lines 4-5 | Under a dotted separator (y=31), the frequency drawn as the main screen draws it (big digits up to the kHz, the last two in the small font), centred; same code as APRS TX | +| Lines 4-6 | Under a dotted separator (y=31), the frequency drawn as the main screen draws it (big digits up to the kHz, the last two in the small font), aligned left. A matching 20x20 bitmap from the 48-symbol Yaesu set is shown at x=108 on the right for decoded Mic-E and uncompressed positions; the area stays blank for an unknown or unavailable symbol | | Bottom row y=49 | `ok 12 -89dBm`: frames received, RSSI at the end of the last frame. (v0.4-v0.5 also showed frames per slicer, `sl a/b/c`: on air the outer slicers found frames too; dropped in v0.6 to fit the speaker key) | Keys (UV-K5 and UV-K1): @@ -60,8 +60,8 @@ EPIRB 406); every on-air decode was made in STD and the model shows no gain for RAW, so v0.4 dropped it to fit the 4 KiB overlay. The last good frame is kept on `app_main`'s stack and the demodulator state on -`capture`'s: the 4 KiB overlay also holds `.bss`. The screen texts and the two -cos tables are assets. +`capture`'s: the 4 KiB overlay also holds `.bss`. The screen texts, symbol +bitmaps and the two cos tables are assets. ## Demodulator (`test/model_rx.py`, class `Demod`; the C is a transcription) @@ -154,4 +154,3 @@ the standard position display against real frames; 0.065 LSB/Hz), **measured 734-778** with the Flipper and **916** with a real station (F1PRY-14): ~20 % of full scale, plenty of headroom, and the per-tone AGC makes the absolute level irrelevant. - diff --git a/App/apps/aprsrx/aprsrx_app.c b/App/apps/aprsrx/aprsrx_app.c index e95a644b..9010c307 100644 --- a/App/apps/aprsrx/aprsrx_app.c +++ b/App/apps/aprsrx/aprsrx_app.c @@ -146,6 +146,7 @@ static struct { uint8_t seq, prevKey, redraw, spk; /* spk: speaker amplifier on (key 1) */ bool running; uint8_t top, lim, vrow; /* scroll (px) and its limit, row being drawn */ + uint8_t symTable, symCode; /* symbol extracted from the displayed frame */ uint8_t cw; /* view: 0 scroll, CW_COMPACT compact (saved) */ int16_t rssi; /* RSSI at the end of the last frame */ uint16_t flen, nOk; /* frame length, frames */ @@ -206,10 +207,10 @@ static void tiny(uint8_t y,char *end){ *end='\0'; g.A->print_tiny(str,0,y,false, /* The frequency (10 Hz units) drawn as the main screen draws it (ui/main.c, * ENABLE_BIG_FREQ): the big digits up to the kHz on lines 4-5, the last two - * digits in the small font on line 5 right after them, the group centred. Big - * digits are 13 px (drawn from +2), the point 3 px: the group shows (n big - * digits x 13 + 14) px. No division. As APRS TX, without its 1 GHz case (the - * main screen's small font there): 1296.000 in big digits still fits (105 px). */ + * digits in the small font on line 5 right after them. The group is aligned + * left to reserve the rightmost 20 columns for the APRS symbol. Big digits are + * 13 px (drawn from +2), the point 3 px. No division. As APRS TX, without its + * 1 GHz case (the main screen's small font there): 1296.000 still fits. */ static void drawFreq(uint32_t f){ const app_api_t *A=g.A; uint16_t m=0; @@ -219,10 +220,21 @@ static void drawFreq(uint32_t f){ for(uint8_t i=0;i<5u;i++) *o++=(char)('0'+sub(&f,P10[i])); *o='\0'; uint8_t n=(uint8_t)(o-str), big=(uint8_t)(n-3u); /* digits before "00" */ - uint8_t x=(uint8_t)(((128u-(big*13u+14u))>>1)-2u); - A->print_normal(str+n-2u,(uint8_t)(x+big*13u+3u),0,5); /* "00" */ + A->print_normal(str+n-2u,(uint8_t)(big*13u+3u),0,5); /* "00" */ str[n-2u]='\0'; - A->display_freq(str,x,4,false); /* "144.800" */ + A->display_freq(str,0,4,false); /* "144.800" */ +} + +#define SYM_X 108u +static void drawSymbol(void){ + const app_api_t *A=g.A; + uint8_t hit[3]; + uint8_t slot=(uint8_t)((2u*g.symTable+13u*g.symCode)&127u); + A->asset_read((uint16_t)(SYM_MAP+slot*3u),hit,sizeof hit); + if(!hit[0] || hit[1]!=g.symTable || hit[2]!=g.symCode) return; + uint16_t off=(uint16_t)(SYM_BITMAPS+(uint16_t)(hit[0]-1u)*SYM_BYTES); + for(uint8_t page=0;page<3u;page++) + A->asset_read((uint16_t)(off+page*SYM_W),A->fb[4u+page]+SYM_X,SYM_W); } /* ---- SysTick cycle counter (call at least every 10 ms; wraps every 89 s, @@ -492,6 +504,7 @@ static void drawMicE(const uint8_t *f,uint16_t i,uint16_t end,const char *s){ o=puti(str,(int32_t)((sp*1897u)>>10)); o=put(o,s+T_KMH); o=puti(o,(int32_t)crs); *o++=' '; *o++=safe(f[i+7]); *o++=safe(f[i+8]); + g.symTable=f[i+8]; g.symCode=f[i+7]; o=brk(o); uint8_t idx=(uint8_t)(micBit(c[0])*4u+micBit(c[1])*2u+micBit(c[2])); bool custom=false; @@ -544,6 +557,7 @@ static bool drawPos(const uint8_t *f,uint16_t i,uint16_t end){ *o++=' '; } *o++=safe(q[8]); *o++=safe(q[18]); *o++=' '; + g.symTable=q[8]; g.symCode=q[18]; textRows(o,f,(uint16_t)(p+19u),end); return true; } @@ -561,6 +575,7 @@ static void draw(void){ A->display_clear(); A->status_clear(); g.vrow=0; + g.symTable=g.symCode=0; A->print_inverse(s+T_TITLE,2,0,true,true,(uint8_t)(2u+T_TITLE_CHARS*4u)); A->draw_battery(); @@ -613,6 +628,7 @@ static void draw(void){ * blank px between) */ for(uint8_t x=0;x<128u;x++) b[384u+x]=(uint8_t)((b[384u+x]&0x7Fu)|((~x&1u)<<7)); drawFreq(g.vfoFreq); + drawSymbol(); /* bottom line: "ok 12 -89dBm": frames, RSSI of the last one */ o=put(str,s+T_OK); o=puti(o,g.nOk); *o++=' '; *o++=' '; diff --git a/App/apps/aprsrx/build.sh b/App/apps/aprsrx/build.sh index 46fc46f7..36ecb1a4 100755 --- a/App/apps/aprsrx/build.sh +++ b/App/apps/aprsrx/build.sh @@ -8,7 +8,7 @@ set -euo pipefail APP="$(basename "$PWD")" # breakout, foxhunt, beacon, fm, ... APP_NAME="APRS RX" # <-- the only per-app line -APP_VER="0.6" +APP_VER="0.7" APP_API_MIN=2 APP_VMA=${APP_VMA:-0x20000280} # pinned overlay VMA (Core/py32f071xb.ld) OUT="${APP_NAME// /}" # blob basename ("Broadcast FM" -> BroadcastFM) diff --git a/App/apps/aprsrx/gen_assets.py b/App/apps/aprsrx/gen_assets.py index 84c06abc..e0e9eaa2 100755 --- a/App/apps/aprsrx/gen_assets.py +++ b/App/apps/aprsrx/gen_assets.py @@ -15,6 +15,7 @@ sys.dont_write_bytecode = True HERE = os.path.dirname(os.path.abspath(__file__)) sys.path.insert(0, os.path.join(HERE, "..")) from app_assets import Assets +from aprs_symbols_20 import BITMAPS, BYTES_PER_ICON, CODES, WIDTH FS = 9600 TITLE = "APRS RX" # the version is in the .app header @@ -59,6 +60,17 @@ for i in range(8): tail += [(u if i & 2 else 0) | (d if i & 4 else 0) for u, d in zip(UP, DN)] a.u8("BMP_TAIL", tail) a.const("TAIL_W", len(tail) // 8) +symbol_map = bytearray(128 * 3) +for index, code in enumerate(CODES): + slot = (2 * ord(code[0]) + 13 * ord(code[1])) & 127 + if symbol_map[slot * 3]: + raise ValueError("APRS symbol hash collision") + symbol_map[slot * 3:slot * 3 + 3] = bytes((index + 1, ord(code[0]), ord(code[1]))) +a.raw("SYM_MAP", symbol_map) +a.raw("SYM_BITMAPS", BITMAPS) +a.const("SYM_COUNT", len(CODES)) +a.const("SYM_W", WIDTH) +a.const("SYM_BYTES", BYTES_PER_ICON) a.i8("COS1200", cos_table(1200)) # 8 entries a.i8("COS2200", cos_table(2200)) # 48 entries a.main() diff --git a/App/apps/aprsrx/test/aprs_symbols_20_edited.json b/App/apps/aprsrx/test/aprs_symbols_20_edited.json new file mode 100644 index 00000000..fcf0e990 --- /dev/null +++ b/App/apps/aprsrx/test/aprs_symbols_20_edited.json @@ -0,0 +1,248 @@ +{ + "format": "aprs-symbols-20", + "version": 1, + "width": 20, + "height": 20, + "symbols": [ + { + "code": "/#", + "name": "DIGI", + "pixels": "0000000000000000000000000000000000000000000000000100000000000000000001000000000000000000111000000000000000001110000000000000000111110000000000000001111100000000011111111111111111000011111111111111100000011111111111110000000001111111110000000000001111111000000000000011111110000000000001111111110000000000111110111110000000001111000111100000000111000000011100000001100000000011000000000000000000000000" + }, + { + "code": "/X", + "name": "HELICOPTER", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000001111111111111111100011100000100000111010000000011100000000110000001111100000001110000111111110000001111111111010010000111001111110110110001100001111111111100000000001111111111000000000001111111100000000000001000010000000000000111111101000000000000111111100000000000000000000000000000000000000000000" + }, + { + "code": "/&", + "name": "HF GATEWAY", + "pixels": "0000000000000000000000000000000000000000000011111111111110000000100100100100100000001001001001001000000000010010010000000000000101110100000000000000011100000000000000000111000000000000000001110000000000000000111110000000000000001111100000000000000110001100000000000001100011000000000000011111110000000000001111111110000000000011100011100000000000110000011000000000011111111111000000000000000000000000" + }, + { + "code": "/Y", + "name": "SAILBOAT", + "pixels": "0000000000000000000000000000001000000000000000000011000000000000000000110000000000000000001110000000000000001011100000000000000010111100000000000001101111000000000000011011111000000000001110111110000000000011101111110000000001111011111100000000011110111111100000001111101000000011000000000011111111100011111111111111110000111111111111111000000000000000000000000011111111111111100000000000000000000000" + }, + { + "code": "/'", + "name": "SMALL ACFT", + "pixels": "0000000000000000000000000000000000000000000001100000000000000000001100000000000000000001100000000000000000011100000000000000000011100000000011000000111100000000011000000111100000000111111111111111111001111111111111111111011111111111111111100110000001111000000011000000111100000000000000001110000000000000000111000000000000000001100000000000000000110000000000000000011000000000000000000000000000000000" + }, + { + "code": "/[", + "name": "PERSON", + "pixels": "0000000000000000000000000000000000000000000000000111000000000000000011111000000000000000111110000000000000000111000000000000000000000000000000000000111110000000000000011111110000000000001111111110000000000110011100110000000001100111001100000000011001110011000000000000111110000000000000001101100000000000000011011000000000000000110110000000000000011101110000000000000111011100000000000000000000000000" + }, + { + "code": "/-", + "name": "VHF HOUSE", + "pixels": "0000000000000000000000000000011111110000000000000000100000000000000000111110000000000000000010000000000000000001110000000000000011001000000000000001111010000000000000111111100000000000011111111000000000001111111111000000000111111111111000000001111111111110000000011100110001100000000111001100011000000001110011000110000000011111110001100000000111111100011000000001111111111110000000000000000000000000" + }, + { + "code": "/\\", + "name": "DIRECTION FIND", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111000000110000000000110000000100000000001000000001100000000110000000001000000001000000000011000000110000000000010000001000000000000110000110000000000000100001000000000000001100110000000000000001001000000000000000011110000000000000000011000000000000000000110000000000000000000000000000000000000000000000000" + }, + { + "code": "/.", + "name": "X", + "pixels": "0000000000000000000000000000000000000000000000000000000000000001100000000001100000011100000000111000000111100000011110000001111100001111100000001111100111110000000001111111111000000000001111111100000000000001111110000000000000111111110000000000011111111110000000001111100111110000000111110000111110000001111000000111100000011100000000111000000110000000000110000000000000000000000000000000000000000000" + }, + { + "code": "/^", + "name": "LARGE ACFT", + "pixels": "0000000000000000000000000000000000000000000000000110000000000000000001100000000000000000111100000000000000001001000000000000000111111000000000000111111111100000000111111111111110000111111111111111111011111110111101111111111000001111000001110000000011110000000000000000111100000000000000001111000000000000000111111000000000000111111111100000000001110110111000000000010001100010000000000000000000000000" + }, + { + "code": "/0", + "name": "CIRCLE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000111111000000000000111000011100000000011000000001100000001100000000001100000011000000000011000001100000000000011000011000000000000110000110000000000001100001100000000000011000011000000000000110000011000000000011000000110000000000110000000110000000011000000000111000011100000000000011111100000000000000000000000000000000000000000000000" + }, + { + "code": "/_", + "name": "WEATHER STN", + "pixels": "0000000000000000000000000000000000000000001000000011000000000011000001110000000000111111110000000000001100000111000000000010001100110000000000000011000000000000000000110000000000000000001100000000000000000111100001110000000011111100011100000000111111000111000000000011000001110000000000110000011100000000001100000010000000000011000000100000000000111111111000000000001100000000000000000000000000000000" + }, + { + "code": "/:", + "name": "FIRE", + "pixels": "0000000000000000000000000000001000000000000000000110000000000000000001100000000000000000111000000000000000001111001000000000000111110010000000000101111111100000000001111111111000000000111110111100100000001111100111011000000111111001111110000001111100011111100000011110000001111000000011100000011100000000111000001111000000000110000011100000000000110001110000000000000000000000000000000000000000000000" + }, + { + "code": "/a", + "name": "AMBULANCE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000011100000000000000000111000000011111111111111100001111110011111001100011111100111110001000111100000011100001001111000000111111111011111100111111111110111111001111111111101100011111111000111010010011111100100110001110000000011100000011100000000111000000010000000000100000000000000000000000000000000000000000000" + }, + { + "code": "/;", + "name": "CAMPGROUND", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000100000000000000000011100000000000000000111000000000000000011111000000000000001111111000000000000011111110000000000001111011110000000000111100011100000000001111000111100000000111100000111100000001111000001111000001111111111111111110000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/b", + "name": "BICYCLE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011100000000000000000000100000000000111000001000000000000100000111000000000001111111010000000000101000100100000011110010010011100001000100011001000100100100100100100100101011101110001011101010010010000010010010010001000000010001000011100000000011100000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/<", + "name": "MOTORCYCLE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000011000000000000000000011000000000000000000010000000000000000000110000000000000000111100000011111000011111111001000011000111100001000110011111110011000010010011111001001001011010111110101101010110100111001011010010010000000001001000011000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/f", + "name": "FIRE TRUCK", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000111100000000000001111000000000000011110000000000000111100000000001000111000000000111111001111111111001000111111111111010010000111111111110111100001111111111101111111111111111111011111111111000100011111100011100100010011110010010011101110000001110000111011100000011100000100010000000010000000000000000000000000000000000000000000" + }, + { + "code": "/>", + "name": "CAR", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111000000000001111111111000000000111000100110000000001100001000110000001111111111111111110111111111111111111111110000111111000011111001100111100110011110111100000011110110000110000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/g", + "name": "GLIDER", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111000000000000000000111000001100000000000111001111100000000000111111100010000000001111100000110000011111100000000110011111100000000000111111100000000000000111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/C", + "name": "CANOE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000111100000000000000001110000000000000000110000000000000000011000000011000000001100001101111000000110000111111111111011011111111111111101101111111110111110110111111111000000011000000000000000001100000000000000000110000000000000000111000000000000000011110000000000000000011000000000000000000000000000000000000" + }, + { + "code": "/j", + "name": "JEEP", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111110000000000001001000100000000000010010000100000000001100100001101111111111001111111111111111111111111111111000111111110001111100100111111001001111011100000000111001000111000000001110000000100000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/E", + "name": "EYE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000111111000000000000111000011100000000011000000001100000001100001100001100000110000111100001100011000011111100001100110000111111000011001100001111110000110001100001111000011000001100001100001100000001100000000110000000001110000111000000000000111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/k", + "name": "TRUCK", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111110000001111111111111100000011111111111111011100111111111111111100101111111111111111001011111111111111010011111111111111110111111100011100011110001110010010010011001001001110001110000111000011100011100001110000010000010000001000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/I", + "name": "TCP/IP", + "pixels": "0000000000000000000000000000000000000000000000011111100000000000000100001000000000000001000010000000000000010000100000000000000111111000000000000000011000000000000000000110000000000000000001100000000000001111111111110000000010000000000100000000100000000001000000111110000001111100001000100000010001000010001000000100010000111110000001111100000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/m", + "name": "MIC-E REPEATER", + "pixels": "0000100000000001000000010000000000001000000100100000010010000010011000000110010000100100111100100100001001001111001001000010010011110010010000100110011001100100000100100110010010000001000001100000100000001000011000010000000000001111000000000000000010010000000000000001100110000000000000010110100000000000000111111000000000000011000011000000000001111111111000000000000000000000000000000000000000000000" + }, + { + "code": "/K", + "name": "SCHOOL", + "pixels": "0000000000000000000000000000001110000000000000000011100000000000000000100000000000000000001000000000000000000111000000000000000011111000000000000001111111000000000000111000111000000000011110001111000000001111111111111000000111111111111111000001111111111111110000011001100011001100000110011000110011000001100110001100110000011111100011111100000111111000111111000000000000000000000000000000000000000000" + }, + { + "code": "/O", + "name": "BALLOON", + "pixels": "0000000000000000000000000000111110000000000000111010111000000000001101110110000000000110111110110000000001101111101100000000011011111011000000000110111110110000000001101111101100000000011001110011000000000011011101100000000000010111010000000000000101110100000000000000101010000000000000001101100000000000000001110000000000000000000000000000000000000111000000000000000001110000000000000000000000000000" + }, + { + "code": "/P", + "name": "POLICE", + "pixels": "0000000000000000000000000000000000000000000000100010001000000000000100100100000000000000000000000000000000100111001000000000000011111000000000000000000000000000000000111111110000000000011001100110000000001100011000110000011111111111111111111111111111111111111111000011111111000011100110011111100110010011110000000011110000011000000000011000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/s", + "name": "POWERED SHIP", + "pixels": "0000000000000000000000000000000000011000000000000000011110000000000000001111100000000000000110000000000000000000000000000000000000110000000000000000001100000000000000001111110000000000001111111100000000000111111111100000000011001010101100000111111111111111110000111111111111111100000111111111111110000000000000000000000000111111111111111100000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/R", + "name": "REC VEHICLE", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111110000011111111111111110001111111111110001100011000011000111110000110000110001100110001100001100011000110011111111000111111110110001110001110001101001001111111001001000111000000000111000001110000000001110000001000000000001000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/v", + "name": "VAN", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111000000111111111111111000001111111111110011000011111111111100011000111111111111000011001111111111111111111011111111111111111110110001111111100011101001001111110010011000111000000001110000001110000000011100000001000000000010000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/y", + "name": "YAGI", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000100010001000100010001000100010001000100011111111111111111100100010001000100010001000100010001000100010000000100000000000000000001000000000000000000010000000000000000000100000000000000000001000000000000000000010000000000000000000100000000000000000000000000000000000000000000000000" + }, + { + "code": "/T", + "name": "SSTV", + "pixels": "0000000000000000000000000001000010000000000000001001000000000000000001100000000000111111111111111100011000000000000001100100111111111111001001011000000000011010010100000000000010100101001110101000101001010001000100001010010100010001000010100101000000000000101001011000000000011010010011111111111100100110000000000000011000111111111111111100000011100000011100000000000000000000000000000000000000000000" + }, + { + "code": "/U", + "name": "BUS", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111100011111111111111111100100100100100100111001001001001001000110010010010010010001100111111111111110011001111111111111111111011000111111100011110100100111110010011101011101111101110111000111000000011100000000100000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "/V", + "name": "ATV", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000011000000000000000000010000000000000000000110000000000110000011110000000011110001111110000011111111111111111000000011111111100001000110011111110011000010010011111001001001011010111110101101010110100000001011010010010000000001001000011000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "\\#", + "name": "OVERLAY DIGI", + "pixels": "0000000000000000000000000000111100000000000000111001110000000000111000000111000000011000000000011000000100000110000010000011000001100000110000100000111100000100010001111111111000100100011111111110001001000011111111000010010000011111100000100010000111111000010000110011100111001100000100110000110010000001100000000001100000001110000001110000000000111001110000000000000011110000000000000000000000000000" + }, + { + "code": "\\&", + "name": "OVERLAY GATE", + "pixels": "0000000000000000000000000000111110000000000000011000110000000000011000000011000000001100001000011000000110000111000011000001000011111000010000110001111111000110001000111111111000100010011111111111001000100111111111110010001000111111111000100011000111111100011000010000111110000100000110000111000011000000110000100001100000000110000000110000000000011000110000000000000011111000000000000000000000000000" + }, + { + "code": "\\-", + "name": "HF HOUSE", + "pixels": "0000000000001000000000000001111111111100000000000000100000000000000001111111000000000000000010000000000000000001110000000000000011001000000000000001111010000000000000111111100000000000011111111000000000001111111111000000000111111111111000000001111111111110000000011100110001100000000111001100011000000001110011000110000000011111110001100000000111111100011000000001111111111110000000000000000000000000" + }, + { + "code": "/W", + "name": "NWS SITE", + "pixels": "0000000000000000000000000000001000000000000000001111000000000000000111111100000000000011111111110000000011111111111110000001111111111111110000111111111111111100001111111111111111000001111111111111100000000110011001100000000000000000000000000000000000000000000000001000100010001000000110011001100110000000000000000000000000000010001000100000000001100110011000000000000000000000000000000000000000000000" + }, + { + "code": "\\.", + "name": "AMBIGUOUS", + "pixels": "0000000000000000000000000000000000000000000000011111000000000000001111111000000000000111111111000000000001110001110000000000011100011100000000000000000111000000000000000011100000000000000001110000000000000000111100000000000000001110000000000000000011100000000000000000000000000000000000001110000000000000000011100000000000000000111000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "\\0", + "name": "OVERLAY CIRCLE", + "pixels": "0000000000000000000000000000000000000000000000011111100000000000011100001110000000001100000000110000000110001111000110000001000111111000100000110011111111001100001001111111111001000010011111111110010000100111111111100100001100111111110011000001000111111000100000011000111100011000000011000000001100000000011100001110000000000001111110000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "E0", + "name": "ECHOLINK", + "pixels": "0000000000000000000000000000011000000000000000001111000000000000000011110000000000000000011000000000000000001001000000000000001100001100000000000111100111100000000001111001111000000000000100001000000000000010000001000000000001000000001000000000010000000010000000001100000000110000000111100000011110000001111000000111100000001100000000110000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "I0", + "name": "IRLP", + "pixels": "0000000000000000000000000000011000000000000000001111000000000000000011110000000000000000111100000000000000000110000000000000000010010000000000000001100110000000000000010000100000000000001100001100000000000010000001000000000001100000011000000000010000000010000000001110000001110000000111110000111110000001111111111111100000011111000011111000000011100000011100000000000000000000000000000000000000000000" + }, + { + "code": "W0", + "name": "WIRES", + "pixels": "0000000000000000000000000000111000000000000000111111100000000000011101011100000000001010010010100000000111111111111100000001001001001001000000100010010010001000001001000100010010000011111111111111100000100100010001001000001000100100100010000001001001001001000000011111111111110000000010100100101000000000011101011100000000000011111110000000000000001110000000000000000000000000000000000000000000000000" + }, + { + "code": "YY", + "name": "YAESU RADIO", + "pixels": "0000000000100000000000000000001000000000000000000010000000000000000000100000000000000000101000000000000000011111000000000000001111111000000000000010000011000000000000101110110000000000001000001100000000000011111111000000000000100100110000000000001111111000000000000010010010000000000000111111100000000000001001001000000000000011111110000000000000011111000000000000000000000000000000000000000000000000" + }, + { + "code": "\\^", + "name": "ALT AIRCRAFT", + "pixels": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111110000000000000000110000000000000000001100000000001000000111100000010111111111111111111111111111111111111111101000000111100000010000000000110000000000000000001100000000000000000011000000000000000011111100000000000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + }, + { + "code": "\\Y", + "name": "RADIOS/DEVICES", + "pixels": "0000000000000000000000000000001100000000000000000011000000000000000000110000000000000000001100000000000000001011000000000000000111110000000000000011111110000000000000100000110000000000001011101100000000000010000011000000000000111111110000000000001010101100000000000011111111000000000000101010110000000000001111111100000000000010101011000000000000011111100000000000000000000000000000000000000000000000" + } + ] +} diff --git a/App/apps/aprsrx/test/aprs_symbols_20_editor.html b/App/apps/aprsrx/test/aprs_symbols_20_editor.html new file mode 100644 index 00000000..c18b572a --- /dev/null +++ b/App/apps/aprsrx/test/aprs_symbols_20_editor.html @@ -0,0 +1,431 @@ +
+