# Copilot instructions for loramodem

Repository at a glance
- Project: LoRa KISS modem (Zephyr RTOS)
- Purpose: Bridge a KISS serial interface to a LoRa radio (two threads: serial → LoRa, LoRa → serial).
- Key components: app/ (Zephyr application), drivers/lora/lr11xx (Semtech LR11xx driver), boards/ (board overlays).

Quick commands
- Build for a board (recommended):
  west build -b <board> app
  Example: west build -b heltec_wifi_lora32_v3 app
- Flash the built image:
  west flash
- Open Zephyr menuconfig:
  west build -b <board> app -t menuconfig
- CMake alternative (repo root):
  cmake -S app -B build && cmake --build build

Testing & lint
- Testing strategy (from CLAUDE.md): unit tests run on host (arm64/x86) with a mocked HAL; integration tests run on target hardware. No repo-level test runner or lint targets are present by default — look for a tests/ or scripts/ directory if added.

High-level architecture (big picture)
- app/ contains the Zephyr application (app/src/*.c). main.c starts two cooperative threads:
  - kiss_rx_thread: reads bytes from the KISS UART, decodes frames (kiss.c), handles SetHardware commands, and calls lora_modem_send().
  - lora_rx_thread: polls lora_modem_recv() with a finite timeout and writes received payloads as KISS frames to the UART.
- KISS protocol implementation: app/src/kiss.c, kiss.h — encoder/decoder and SetHardware sub-command definitions.
- Radio abstraction: app/src/lora_modem.c, lora_modem.h — stores runtime params (g_params) protected by a mutex and snapshots params at send/recv time so changes take effect on the next call.
- HW driver: drivers/lora/lr11xx implements Zephyr's lora_driver_api. Hardware-specific SPI/GPIO HAL pieces live in lr11xx_hal.c.
- Build integration: app/CMakeLists.txt registers drivers/lora/lr11xx as an extra Zephyr module (ZEPHYR_EXTRA_MODULES).

Key repository conventions and patterns
- Chosen nodes and aliases:
  - The KISS UART is resolved from a chosen node: loramodem_kiss_uart (board overlay must define it).
  - LoRa device is expected as DT alias lora0 (DEVICE_DT_GET(DT_ALIAS(lora0))).
- Kconfig / defaults:
  - app/prj.conf contains project defaults (frequency, SF, BW, TX power, stack sizes, heap pool setting used by the app).
  - Runtime radio params are read from Kconfig at init (lora_modem_init) and stored in g_params.
- Radio parameter updates:
  - lora_modem_set_params() validates values and updates g_params under mutex; changes take effect when lora_modem_send() or lora_modem_recv() is next called (thread-safe snapshotting).
- KISS SetHardware mapping:
  - See kiss.h for sub-commands (SET_FREQ, GET_PARAMS, etc.) and main.c for how responses are encoded and sent.
- Board overlays and confs:
  - Overlays live in boards/ or board-specific .overlay files. App-level overrides can live in app.overlay or per-board .conf files.
- Memory & testing notes (from CLAUDE.md):
  - Target memory budget and testing strategy are documented in CLAUDE.md (unit tests on host, integration on target).

Files to read first when exploring code
- app/src/main.c, app/src/kiss.c/h, app/src/lora_modem.c/h, drivers/lora/lr11xx/{*.c,*.h}, app/prj.conf, app/CMakeLists.txt, CLAUDE.md

AI & editor configs found
- CLAUDE.md contains project constraints and test strategy; consult it for memory and testing guidance.
- .vscode/settings.json points the CMake source directory to app/ in the original developer setup.
- .claude/settings.local.json contains allowed webfetch domains for the Claude assistant.

If you (the user) want, Copilot sessions should:
- Prefer reading the files listed above first.
- Respect chosen DT nodes (loramodem_kiss_uart, alias lora0) and Kconfig defaults in app/prj.conf.
- When suggesting code changes, keep stack/heap and RAM budgets in CLAUDE.md in mind.

