66 Commits
Author SHA1 Message Date
I12BP8 a906ed32ce Merge pull request #63 from i12bp8/copilot/fix-lint-actions-job
Build / Lint (advisory, non-blocking) (push) Canceled after 0s
Build / Flipper app (dev SDK) (push) Canceled after 0s
Build / Flipper app (release SDK) (push) Canceled after 0s
Build / Cloudflare Worker (push) Canceled after 0s
Build / ESP32-S2 WiFi firmware (push) Canceled after 0s
Build / Web image-prep page (push) Canceled after 0s
Adjust advisory lint job to report warnings without failing its check run
2026-09-17 17:32:17 +02:00
copilot-swe-agent[bot]andi12bp8 97e2d34325 Make advisory lint step non-blocking without failing job
Co-authored-by: i12bp8 <57963363+i12bp8@users.noreply.github.com>
2026-09-17 15:27:39 +00:00
copilot-swe-agent[bot] fd695b1cf0 Initial plan 2026-09-17 15:25:21 +00:00
I12BP8 ac6957fd74 Merge pull request #62 from Hoggormino/custom-size
Add a custom-size option for unrecognized infrared tags
2026-09-17 17:17:20 +02:00
I12BP8 049c6f33b4 Merge pull request #61 from Hoggormino/esp-worker-url
ESP32: make the worker URL a build option instead of a source edit
2026-09-17 17:16:57 +02:00
I12BP8 be3839af32 Merge pull request #60 from Hoggormino/esp-console-fix
ESP32: silence the console that shares UART0 with the Flipper link
2026-09-17 17:16:32 +02:00
I12BP8 1cb4407729 Merge pull request #59 from Hoggormino/docs-hygiene
Docs: fix stale feature claims and worker URL instructions
2026-09-17 17:15:59 +02:00
I12BP8 09aa05d759 Merge pull request #58 from Hoggormino/bmp-bounds
Fix BMP row buffer overflow and show failed sends
2026-09-17 17:14:45 +02:00
I12BP8 160c09cc33 Merge pull request #57 from Hoggormino/unknown-tag-guards
Guard unknown-profile targets and a full target list
2026-09-17 17:14:15 +02:00
I12BP8 fed9b713cd Merge pull request #56 from Hoggormino/nfc-scan-vusion-fixes
NFC scan: keep scanning after a rejected tag, parse NDEF properly, explain unsupported tags
2026-09-17 17:13:11 +02:00
I12BP8 2b0ab41754 Merge pull request #54 from Hoggormino/ci-build-workflow-and-makefile
Add CI build workflow and root Makefile
2026-09-17 17:12:31 +02:00
HoggorminoandClaude Opus 5 6aa67962b6 NFC scan: describe what the tag data shows, not the vendor
The scan only sees NFC data. It cannot sense whether a label's display
listens for infrared or radio, so the messages now say what was found
instead of naming a vendor or a transport as fact.

- "VUSION tag / SES-imagotag uses radio, not IR" becomes "Likely radio
  tag / Link: nfc.imagotag.com / TagTinker is IR-only".
- Match an http:// or https:// link whose host is nfc.imagotag.com
  (case-insensitive), as prefix code 0x03/0x04 or inline after 0x00,
  instead of the substring "imagotag" anywhere in the URL. A "://"
  inside a path, query or fragment is not taken as the scheme.
- "Not a Pricer tag" becomes "Unrecognized tag / No ID TagTinker can
  decode"; "Unsupported chip" becomes "Unreadable chip / Chip answered
  but no data was read".
- Move the decision into tagtinker_nfc_classify() so it can be tested
  off-device.
- De-duplicate on UID and result together. The firmware reports a read
  that stops partway as a success with fewer pages, so a UID-only check
  could keep a tag stuck on "Unrecognized tag" after a partial first
  read.
- Announce an unreadable chip once until the field is empty. Those reads
  carry no UID, so UID de-duplication never applied and the message
  repeated on every poll.
- Bring the prompt back from the scene tick instead of a popup callback.
  A popup with a callback consumes every short press, so Back only
  dismissed the message and a second Back was needed to leave.
- Stop the scanner on the Back event rather than waiting for on_exit, so
  the poll loop is already winding down when the scene is popped and the
  join there is as short as possible. On device, leaving from a message
  takes exactly one Back.
- Move custom event ids to 200+. NfcScanEventSuccess was 100, the same
  id as the target menu's "+ Type Barcode" item.
- Stop the scan LED when "Target list full" ends scanning.
- README: add "Which tags work", with vendor-documented radio examples
  and a table of what each scan message means.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 21:59:32 +02:00
HoggorminoandClaude Opus 4.8 0447f12164 Add a custom-size option for unrecognized infrared tags
A tag whose type code is not in the profile table has no dimensions, so
after the unknown-profile guard its Set Text / Set Image / WiFi Plugins
actions are hidden. This adds a "Set Custom Size" action for those tags:
enter width, height and colour, and the graphics actions become usable.

The IR framing is identical to a table profile; only the screen geometry
differs, so no protocol is guessed. Custom size is applied only when the
barcode's type is not in the table, so a real profile is never overridden.

- New scene (VariableItemList): Width and Height in 8 px steps from 8 to
  800, Colour mono/red/yellow, and Save.
- tagtinker_target_refresh_profile() synthesizes a "Custom" profile from
  the stored size for unknown-type targets, so Show Tag Info, Set Text
  and Set Image all see real dimensions.
- targets.txt gains three optional fields (barcode|name|cw|ch|ccolor);
  older two-field lines still load, with no custom size.
- "Set Custom Size" appears in Target Actions only for unknown-type
  targets (tagtinker_type_is_known()).

Builds clean on release SDK 1.4.3 (API 87.1) and dev SDK; no new
clang-format drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-16 21:58:55 +02:00
HoggorminoandClaude Opus 5 5e204793dd ESP32: make the worker URL a build option instead of a source edit
cloud_client.h hard-coded the worker URL, and wrangler.toml pointed users
at a "WiFi Setup -> Server URL" field that has never existed, so anyone
self-hosting cloud-plugins/ had to edit a header. cloud_client_set_url()
exists but has no callers, and the UART protocol has no frame for it.

Add CONFIG_TT_CLOUD_URL (Kconfig.projbuild, menu "TagTinker") defaulting
to the current URL, and take TT_CLOUD_DEFAULT_URL from it. Setting it in
sdkconfig.defaults or through menuconfig is now enough; rebuild and
reflash still apply, and there is no hidden run-time channel.

Also says so in wrangler.toml and the README WiFi Plugins bullet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 21:30:22 +02:00
HoggorminoandClaude Opus 5 146744de98 ESP32: silence the console that shares UART0 with the Flipper link
sdkconfig.defaults asked for a USB-Serial-JTAG console, but the ESP32-S2
has no such peripheral: the option depends on SOC_USB_SERIAL_JTAG_SUPPORTED,
which esp32s2 does not define. The choice therefore fell back to
ESP_CONSOLE_UART_DEFAULT, so boot and WiFi logs went out on UART0 at
115200 before wifi_link_init() switched it to 230400. That is the same
wire the framed protocol uses, and a log line printed mid-frame corrupts
it; the FAP then drops the frame on the CRC check.

- Select CONFIG_ESP_CONSOLE_NONE, as the Flipper's own devboard firmware
  does. Verified in the generated sdkconfig, not just the defaults file.
- Rename CONFIG_ESP32_WIFI_*_BUFFER_NUM to CONFIG_ESP_WIFI_*, which
  ESP-IDF v5.2 warned about on every build.
- wifi_link.c described UART1 on GPIO17/18. The code uses UART0, whose
  default pins are the ones wired to the Flipper header.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 21:29:23 +02:00
HoggorminoandClaude Opus 5 53ede949b8 Docs: correct stale feature claims and the worker URL instructions
- README: the IR engine allocates heap for payloads, so drop
  "zero-allocation"; the drop folder takes the 1-bit and two-plane BMPs
  the image preparer exports, not any BMP, and type 1626 targets cap
  files at 24 KB; NFC scan only fills the barcode when the tag's NFC
  data decodes; there is no test-pattern feature; the FAQ now says this
  app needs a Flipper even though the protocol does not.
- CONTRIBUTING: the Android companion app was removed in d608afb.
- wrangler.toml pointed users at a "WiFi Setup -> Server URL" field that
  never existed. Say how the URL is actually set today.
- cloud_client.h described a runtime override through
  cloud_client_set_url(), which nothing calls.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 17:10:59 +02:00
HoggorminoandClaude Opus 5 692e436fe5 Bound BMP rows to the row buffer and show failed sends
tx_bmp_open() accepted 24- and 32-bit BMPs of any width, then each source
row was read into uint8_t row_buf[128] on the stack. A 24-bit BMP wider
than 42 px, or a 1-bit BMP wider than 1024 px, overran it. The decoder
also reads one bit per pixel, so 24/32-bit files were misread anyway.
A host build of the previous code under AddressSanitizer reports a
132-byte write into the 128-byte buffer for a 24-bit, 43 px wide file.

- Accept only 1bpp and the stacked-plane "2bpp" layout, reject zero or
  over-16-bit sizes, and reject rows wider than TX_BMP_ROW_BUF_SIZE.
- Read header fields as uint32_t. Shifting into bit 31 of an int and
  negating INT32_MIN were undefined.
- The result screen showed "Flipped ;)" and played the success sound
  even when the send failed or was cancelled. Show "Send failed" with
  the error sound, or "Stopped" with no sound when cancelled with Back.
- Check for a stop request after the gap between frames of a sequence.
  tagtinker_ir_transmit() clears the stop flag on entry, so a Back
  pressed during the gap was lost and the next frame went out in full.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 17:10:50 +02:00
HoggorminoandClaude Opus 5 09bcf9ac8a Guard targets with unknown profiles and a full target list
A tag whose type code is not in the profile table gets a zeroed profile:
kind Unknown, 0x0, Mono. NFC scan, targets.txt and web_job.txt (and the
unreachable phone-sync code) all create such targets, and because only
Segment was excluded they were offered Set Text, Set Image and WiFi
Plugins. Set Text on a 0x0 job reaches malloc(0), which the firmware
treats as a fatal error.

- Offer Set Text, Set Image and WiFi Plugins only for dot-matrix
  profiles found in the table; the app has no display size for others.
- Show Tag Info says the type is not in the profile table and which
  actions are hidden, instead of reporting "Size: 0x0" and "Color: Mono".
- Refuse a 0x0 text job before either sized text path allocates.
- Manual barcode entry with all 16 slots used now shows "Target List
  Full". It used to open Target Actions with selected_target -1, where
  Show Tag Info and LED Test index targets[-1].
- Widget buttons call back on press, short press and release, so the
  Back button went back twice. Act on the short press only.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16 17:10:09 +02:00
HoggorminoandClaude Fable 5.1 c3ac9407e1 Makefile: harden build-esp, launch/flash ordering, and clean guard
- Export IDF_TARGET=esp32s2 so ESP-IDF performs the same target consistency
  check locally that the CI action gets from its IDF_TARGET env: a stale
  sdkconfig generated for another chip is now refused instead of built.
- Print an absolute path in the export.sh failure hint; zsh does not
  tilde-expand VAR=~/path, so the old hint produced a literal "~".
- launch depends on build-fap and flash-esp on build-esp, so `make -j`
  cannot run two builders in the same tree.
- clean/distclean refuse to run outside the repository root (they delete
  cwd-relative paths).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 10:10:19 +02:00
HoggorminoandClaude Fable 5.1 464ff1ae67 Add CI build workflow and root Makefile
- .github/workflows/build.yml: build the Flipper FAP (ufbt, release + dev
  SDK channels), the Cloudflare Worker (tsc + wrangler dry-run bundle) and
  the ESP32-S2 firmware (ESP-IDF v5.2.8) on every push to main and every
  pull request; syntax-check the inline scripts of the web image-prep page;
  run `ufbt lint` as a non-blocking advisory job. No path filters, because
  the shared UART protocol header is compiled into both the FAP and the
  ESP firmware.
- Makefile: one entry point for developers (setup, build-all, build-fap,
  build-worker, build-esp, launch, flash-esp, serve-web, lint, clean).
  Works with the stock GNU Make 3.81 on macOS. Auto-detects the ESP-IDF
  Python virtualenv when export.sh would otherwise look for one matching
  a newer system python3.
- esp32-wifi-fw/sdkconfig.defaults: pin CONFIG_IDF_TARGET="esp32s2" so
  clean builds (CI, fresh clones) no longer fall back to plain esp32.
- cloud-plugins/package.json: add the `build` script (wrangler dry-run
  bundle) that the Makefile and CI rely on.
- README/CONTRIBUTING: document the make targets and CI; add a build badge.
- .gitignore: ignore .venv/ and the .clang-format generated by ufbt lint.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-15 10:02:02 +02:00
I12BP8 b6ebe46d0f Merge pull request #53 from sosnek/add-smarttag-color-1626
Deploy Image Prep to GitHub Pages / deploy (push) Canceled after 0s
Add SmartTAG Color 2.6 (type 1626) support
2026-09-02 18:00:38 +02:00
sosnekandCursor f1447306fa Drop the Color 2.6 host unit test
It was a one-off, unwired pattern this repo does not use.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-31 00:52:39 -04:00
sosnekandCursor 3ebae10ada Fold Color 2.6 helpers into proto.h
One extra header for a single type code did not match how the rest of the protocol layer is laid out.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-31 00:44:27 -04:00
sosnekandCursor 3b8ad97c34 Fix Color 2.6 page default, Set Text heap, and WiFi canvas
Default image page is 2 unless the user picked 2-7. Set Text packs planes instead of 45KB buffers. WiFi and odd-size BMPs use glass 296x152 then transpose.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-31 00:40:50 -04:00
sosnekandCursor b328511d02 Add SmartTAG Color 2.6 (type 1626) support
These tags look like 296x152 but the firmware only takes 152x296, so landscape BMPs get transposed. Tested on a real 2.6 color tag.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-31 00:07:03 -04:00
i12bp8 81adb463eb github plugin: trading-card redesign
- Trading-card layout: accent stripe with github.com/<login> link,
  square dithered avatar with frame, faux-bold display name,
  flexible bio that wraps cleanly (no mid-word cuts, no ellipsis),
  3-column stats panel (STARS / FOLLOWERS / REPOS).
- Bio falls back to a deterministic filler line when the user has
  none, so the slot never reads as a render bug.
- Tighter 7-px line height for the bio gets one extra line into
  the same band on 208x112.
- Drop heatmap + month axis (cleaner card; halves render time).
2026-04-28 13:48:30 +02:00
i12bp8 d2f92b67e8 github plugin: redesign for 208x112 tag
- Add month-initial axis under the heatmap
- Add current-streak counter in caption (accent-highlighted)
- Replace stats/bio fight with a single icon stat row (star, followers, repos)
- Fix bullet/middle-dot rendering bug (U+00B7 -> U+2022, in font table)
- Allow display name at scale 2 on wide tags only; safer truncation
- Robust avatar URL ?s= append (handles avatars without query string)
- Tighter geometry tuned for 208x112; still scales to 296x128
2026-04-28 13:20:03 +02:00
I12BP8 0eae6de165 Update README.md 2026-04-27 14:04:08 +02:00
I12BP8 567eb4b6fa Add files via upload 2026-04-27 14:01:52 +02:00
i12bp8 287481453e WiFi plugins: GitHub Profile + DiceBear identicon + tri-state canvas
Worker (cloud-plugins/):
- New plugin 'GitHub Profile': avatar dithered upper-left, display
  name + @handle (with accent star) + word-wrapped bio in the right
  column, followers/repos line, and a 53x7 contribution heatmap
  with an accent palette (red dots for everyday activity, black for
  the rare hottest days). Tuned for 208x112 ESLs and adapts to
  296x128 with a bigger avatar and roomier heatmap.
- Identicon plugin gains DiceBear style selector (pixel-art /
  bottts / lorelei / adventurer / micah / fun-emoji / shapes) on
  top of the original symmetric grid 'local' mode. Both are
  rendered through the new shared image_util pipeline.
- Crypto plugin redesigned: editorial layout with corner brackets,
  bold price headline, white-knockout delta badge with a real
  triangle glyph, currency symbol prefix using the canvas font's
  new euro / pound / yen glyphs, and a stippled accent fill under
  the sparkline.

Canvas:
- setPixel is now last-write-wins across planes, so drawing black
  on top of an accent-filled area produces a clean black pixel
  instead of the muddy plane-conflict the e-paper driver was
  showing previously. Every pixel is therefore exactly one of
  white / black / accent which is what plugin authors intuit.
- New whitePixel + drawTextWhite primitives for knockout text
  (e.g. white labels punched through a coloured badge).
- FONT_EXTRA shipped with the canvas for currency / arrow / shape
  / star / bracket glyphs. Plugins can now write '\u20AC1234' and
  have the euro symbol Just Work.

Image pipeline (new image_util.ts):
- One fetchImageGray() that sniffs PNG vs JPEG, decodes via
  upng-js / jpeg-js, composites alpha over white, and returns a
  tightly-packed grayscale buffer.
- One blitGrayDither() that nearest-neighbour scales the gray
  buffer to a destination rect and serpentine Floyd-Steinberg
  dithers it on the way in. Used by identicon and github.

FAP:
- WiFi BMP writer is now plane-aware: writes the same biPlanes=1,
  biBitCount=2, 3-entry palette layout the rest of the IR TX
  pipeline already understood for web-image-prep BMPs. Tri-colour
  tags now actually receive accent ink from cloud-rendered plugins.
- WiFi run scene un-forces accent: plugins are invoked with the
  tag's actual accent capability and the BMP is opened with the
  matching plane count.
- Run scene now calls bmp_abort on exit so an aborted transfer
  doesn't leak the ~10 KB pixel buffer.
- Plugin manifest cache capped at TT_WIFI_MAX_FAP_PLUGINS=8 (down
  from 16) and the UART RX stream buffer shrunk to 8 KB. Together
  these cut WiFi-flow heap pressure by ~23 KB and fix the OOM
  crashes that occasionally happened when opening WiFi Plugins.
- Broadcast scene auto-transmit fix: enter_callback now filters
  by the >> Transmit << row index, and the cursor defaults to
  row 0 instead of Transmit. Previously a stale OK key-release
  from the prior submenu would land on the Transmit row and
  blast the radio without any user action.
2026-04-27 12:49:12 +02:00
i12bp8 99bcc162b8 web-image-prep: chroma-contracted quantiser for newsprint illusion
Deploy Image Prep to GitHub Pages / deploy (push) Failing after 31s
Previous version pulled accent ink too aggressively (accentPull 0.85)
so anything red-leaning collapsed to solid red. Real photographic feel
from a 3-ink palette comes from W/B halftones simulating greys with
the chromatic ink only sparsely overlaid - the newsprint illusion.

Three knobs now make this work:
  - L_WEIGHT 3.5 (was 1.6): lightness completely dominates the metric
  - CHROMA_CAP: source a/b axes pre-scaled to the achievable accent
    chroma so the dither isn't asked for more colour than one ink can
    deliver. Excess chroma gets dropped via FS error diffusion through
    B+W neighbours.
  - accentPull 0.06 (was 0.85): only a tiebreaker bonus, used in the
    most strongly hue-aligned pixels.
2026-04-26 21:03:10 +02:00
i12bp8 ad9b6dd2fe web-image-prep: hue-aligned tri-colour quantiser + serpentine dither
The old quantiser pulled accent ink toward any chromatic pixel using a
flat chroma bonus, which smeared red across shadows and produced flat
red blobs without depth. Two fixes:

- Distance now weights L (lightness) ~1.6x more than chroma, so dark
  pixels go to black and light pixels to white before colour competes.
  That preserves the photograph's tonal structure.
- Accent attraction is the squared *signed projection* of the pixel's
  chroma onto the accent direction. Red ink only pulls red-leaning
  pixels (positive a*); blue/green never picks red. The squaring gives
  a smooth ramp, so faint reds get sparse red dither and saturated
  reds get dense red - matching how a real risograph layers a single
  chromatic ink under W/B halftones.

Also flipped Floyd-Steinberg to a serpentine scan with mirrored kernel
on reverse rows, killing the diagonal worm artefacts that gave smooth
gradients an obviously-dithered look.
2026-04-26 20:59:15 +02:00
I12BP8 c20fc112d1 Update README with new features information
Added details about NFC Tag Scan and WiFi Plugins features.
2026-04-26 20:52:23 +02:00
i12bp8 2739069f22 Add optional WiFi Plugins (ESP32-S2 bridge + Cloudflare Worker)
- Flipper FAP: WiFi Setup, Plugins picker, plugin-run scene wired into
  Targeted Payloads -> <tag> -> WiFi Plugins
- Framed UART link to the dev board with bulk-read RX path and 16 KB
  stream buffer to keep up with full plugin bursts
- ESP firmware: 900 KB UART<->HTTPS bridge, USB-Serial-JTAG console,
  cert-bundle TLS, 16 KB worker stack to host mbedTLS handshake
- Cloudflare Worker: Crypto, Weather, Identicon plugins out of the
  box; new plugins are a single TypeScript file, no Flipper reflash
- Shared protocol header + 1bpp BMP writer that matches web-image-prep
  palette/stride conventions
2026-04-26 20:50:16 +02:00
i12bp8 8fab06a807 README: add prominent link/badge to hosted Image Prep 2026-04-26 15:41:21 +02:00
i12bp8 d608afb43b Drop-folder image flow + web image preparer
- Add web-image-prep/: self-contained HTML5 image preparer with
  perceptual Oklab 3-colour quantisation, Floyd-Steinberg/Atkinson/
  Bayer dither, all supported tag profiles, BMPs that match the FAP
  reader exactly. Auto-deployed to GitHub Pages.
- Add 'Set Image' under Targeted Payloads. Lists every BMP in
  apps_data/tagtinker/dropped/, scrolls long names, marks foreign-
  resolution files with a '~' prefix.
- Stream-time nearest-neighbour rescaling so any BMP can target any
  tag at any page; image options screen is now Page-only.
- Remove Phone Sync menu and the Android companion app: replaced by
  the browser preparer + drop folder.
- Static, IR-friendly transmit screen ('Tinkering Tag', point hint,
  3-dot loader, 'Flipped ;)').
2026-04-26 15:40:27 +02:00
I12BP8 c74da35ca7 Merge pull request #34 from 7h30th3r0n3/main
Fix formatting for NFC tag decoding contributor mention
2026-04-26 14:13:34 +02:00
7h30th3r0n3 0627bb1720 Fix formatting for NFC tag decoding contributor mention 2026-04-26 14:09:48 +02:00
I12BP8 c1205988c9 Merge pull request #33 from 7h30th3r0n3/fix/contributing-guidelines
docs: update contributing guidelines
2026-04-26 13:50:27 +02:00
7h30th3r0n3 3d733cea6d docs: update contributing guidelines with NFC and merge policy 2026-04-26 13:46:25 +02:00
I12BP8 bf5b155b91 Merge pull request #31 from 7h30th3r0n3/feature/nfc-scan
feat: add NFC tag scanning to auto-fill ESL barcode
2026-04-26 13:35:36 +02:00
I12BP8 41f40c4621 Replace 'New Target' with 'Type Barcode' in menu 2026-04-26 13:34:18 +02:00
7h30th3r0n3 d76403376b docs: update README for v2.1 with NFC scan feature 2026-04-26 13:24:00 +02:00
7h30th3r0n3 9b3524b5f8 feat: add NFC tag scanning to auto-fill ESL barcode
Add "+ Scan NFC" option in the Targeted Payloads menu.
Scans Mifare Ultralight NDEF tags, decodes the encoded
ESL ID, and auto-creates the target — no manual barcode
entry needed. Cyan LED blinks during scan. Loops until
a tag is found or the user presses Back.

New files:
- nfc/tagtinker_nfc.c/.h — NDEF URI decoder module
- scenes/tagtinker_scene_nfc_scan.c — NFC scan scene

Version bumped to 2.1, NFC credit added to About screen.
2026-04-26 13:12:42 +02:00
i12bp8 506e1ad19e Fix barcode validation for non-standard SOLUM tags 2026-04-25 14:43:24 +02:00
I12BP8 678a2c6943 Massive IR transmission speed optimization: ~45s down to ~10s monochrome, ~20s color 2026-04-24 20:42:36 +02:00
I12BP8 955cb86fc1 Fix barcode checksum to include prefix letter
Pricer barcodes validate with (sum of all 17 chars) mod 10 == 0,
with the letter prefix contributing by its ASCII offset from '0'.
The old formula compared sum of the first 16 digits to the 17th,
rejecting valid codes like A4120365539013704.
2026-04-24 20:42:36 +02:00
I12BP8 934bc2e309 Fix demo image link in README.md 2026-04-24 20:42:36 +02:00
I12BP8 0a859fa35d Add demo image to README
Added demo image to README for better visualization.
2026-04-24 20:42:36 +02:00
I12BP8 531a58da9b Add files via upload 2026-04-24 20:42:36 +02:00