Initial setup
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
.cache/
|
||||
14
.markdownlintrc.json
Normal file
14
.markdownlintrc.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"extends": "default",
|
||||
"rules": {
|
||||
"line-length": {
|
||||
"line_length": 120,
|
||||
"heading_line_length": 120,
|
||||
"code_blocks": false,
|
||||
"code_lines": false,
|
||||
"tables": false
|
||||
},
|
||||
"fenced-code-language": false,
|
||||
"no-trailing-spaces": true
|
||||
}
|
||||
}
|
||||
21
.pre-commit-config.yaml
Normal file
21
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
args: ['--maxkb=1000']
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v4.0.0-alpha.8
|
||||
hooks:
|
||||
- id: prettier
|
||||
types_or: [markdown]
|
||||
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.37.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
args: ['--fix', '--disable', 'MD040', '--disable', 'MD013']
|
||||
219
PROJECT.md
Normal file
219
PROJECT.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# Micro controller LoRa KISS modem
|
||||
|
||||
This project is a LoRa KISS modem for common LoRa capable development boards,
|
||||
such as created by vendors like Heltec, RAK, Seeed, etc.
|
||||
|
||||
It is using the USB-serial interface (optionally hardware serial interface) to
|
||||
allow the user to send and receive LoRa packets using the KISS modem protocol.
|
||||
|
||||
## KISS Modem
|
||||
|
||||
### KISS Framing
|
||||
|
||||
KISS (Keep It Simple, Stupid) is a standard TNC protocol for packet radio.
|
||||
Frames use special bytes for delimiting:
|
||||
|
||||
| Symbol | Value | Meaning |
|
||||
| ------ | ------ | ------------------------------ |
|
||||
| FEND | `0xC0` | Frame end/begin delimiter |
|
||||
| FESC | `0xDB` | Frame escape |
|
||||
| TFEND | `0xDC` | Transposed FEND (follows FESC) |
|
||||
| TFESC | `0xDD` | Transposed FESC (follows FESC) |
|
||||
|
||||
A frame has the structure:
|
||||
|
||||
```text
|
||||
FEND <type byte> <data bytes...> FEND
|
||||
```
|
||||
|
||||
The type byte encodes the port number (upper nibble) and command (lower
|
||||
nibble):
|
||||
|
||||
```text
|
||||
type = (port << 4) | cmd
|
||||
```
|
||||
|
||||
For host-to-modem data frames, `cmd = 0x00`. Any `FEND` or `FESC` bytes
|
||||
appearing in the data payload must be escaped as `FESC TFEND` or `FESC TFESC`
|
||||
respectively.
|
||||
|
||||
### Ports
|
||||
|
||||
The KISS modem uses three ports for communication:
|
||||
|
||||
| Port | Direction | Purpose |
|
||||
| ---- | ------------- | ---------------------------- |
|
||||
| 0 | bidirectional | Raw LoRa packet data |
|
||||
| 1 | TNC → host | Signal quality (SNR + RSSI) |
|
||||
| 2 | bidirectional | Radio configuration commands |
|
||||
|
||||
### Port 1 — Signal Quality
|
||||
|
||||
Before each received LoRa packet delivered on port 0, the modem emits a signal
|
||||
quality frame on port 1. The payload is 3 bytes, big-endian:
|
||||
|
||||
| Offset | Size | Type | Field | Description |
|
||||
| ------ | ---- | ----- | ----- | ------------------------------------- |
|
||||
| 0 | 1 | int8 | SNR | Signal-to-noise ratio in dB (rounded) |
|
||||
| 1 | 2 | int16 | RSSI | Received signal strength in dBm |
|
||||
|
||||
Example: `FEND 0x11 [-7] [0xFF 0x99] FEND` = SNR = -7 dB, RSSI = -103 dBm
|
||||
|
||||
### Configuration Commands (Port 2)
|
||||
|
||||
Configuration commands allow the host to query and control the modem's LoRa
|
||||
parameters. Each configuration frame's data payload (after the KISS type byte)
|
||||
begins with a 1-byte command byte. The modem responds to every SET\_\* command
|
||||
with either RES_OK (`0x01`) or RES_ERROR (`0x02`) on port 2.
|
||||
|
||||
**Commands:**
|
||||
|
||||
| Cmd | Name | Dir | Payload |
|
||||
| ---- | ------------- | --- | ------------------------------ |
|
||||
| 0x00 | Reserved | — | — |
|
||||
| 0x01 | RES_OK | ← | (none) |
|
||||
| 0x02 | RES_ERROR | ← | (none) |
|
||||
| 0x10 | GET_RADIO | → | (none) |
|
||||
| 0x10 | _resp_ | ← | freq_kHz, bw_hz, sf, cr, power |
|
||||
| 0x11 | SET_RADIO | → | freq_kHz, bw_hz, sf, cr, power |
|
||||
| 0x12 | GET_FREQUENCY | → | (none) |
|
||||
| 0x12 | _resp_ | ← | freq_kHz |
|
||||
| 0x13 | SET_FREQUENCY | → | freq_kHz |
|
||||
| 0x14 | GET_BANDWIDTH | → | (none) |
|
||||
| 0x14 | _resp_ | ← | bw_hz |
|
||||
| 0x15 | SET_BANDWIDTH | → | bw_hz |
|
||||
| 0x16 | GET_SF | → | (none) |
|
||||
| 0x16 | _resp_ | ← | sf |
|
||||
| 0x17 | SET_SF | → | sf |
|
||||
| 0x18 | GET_CR | → | (none) |
|
||||
| 0x18 | _resp_ | ← | cr |
|
||||
| 0x19 | SET_CR | → | cr |
|
||||
| 0x1A | GET_POWER | → | (none) |
|
||||
| 0x1A | _resp_ | ← | power_dBm |
|
||||
| 0x1B | SET_POWER | → | power_dBm |
|
||||
| 0x1C | GET_SYNCWORD | → | (none) |
|
||||
| 0x1C | _resp_ | ← | syncword |
|
||||
| 0x1D | SET_SYNCWORD | → | syncword |
|
||||
|
||||
Legend: `→` = host → TNC, `←` = TNC → host
|
||||
|
||||
### Units
|
||||
|
||||
All integer fields are transmitted in big-endian byte order.
|
||||
|
||||
| Parameter | Type | Unit | Encoding | Example |
|
||||
| --------- | ------ | ---- | ------------- | -------------------- |
|
||||
| Frequency | uint32 | kHz | 4 bytes | 869.618 MHz → 869618 |
|
||||
| Bandwidth | uint32 | Hz | 4 bytes | 62.5 kHz → 62500 |
|
||||
| SF | uint8 | — | 1 byte (5–12) | SF 7 → 0x07 |
|
||||
| CR | uint8 | — | 1 byte (5–8) | 4/5 → 0x05 |
|
||||
| Power | int8 | dBm | 1 byte | 22 dBm → 0x16 |
|
||||
| Sync word | uint8 | — | 1 byte | 0x34 → public |
|
||||
|
||||
## LoRa
|
||||
|
||||
### Hardware
|
||||
|
||||
Common LoRa hardware is supported via the RadioLib library:
|
||||
|
||||
| Module | Frequency band | Notes |
|
||||
| --------------- | -------------------- | ------------------------------------ |
|
||||
| SX1262 | 868 / 915 MHz | Used on Heltec, RAK, Seeed boards |
|
||||
| SX1268 | 433 / 470 MHz | 433 MHz ISM band variants |
|
||||
| LR1110 | 150–960 MHz | Semtech LR11xx family |
|
||||
| LR1120 | 150–960 MHz, 2.4 GHz | Semtech LR11xx family |
|
||||
| SX1276 / SX1278 | 137–1020 MHz | Older boards; supported via RadioLib |
|
||||
|
||||
### Bandwidths
|
||||
|
||||
All LoRa bandwidths supported by RadioLib are accepted. SX126x-based boards support:
|
||||
|
||||
| Bandwidth | Wire value (uint32 Hz) |
|
||||
| --------- | ---------------------- |
|
||||
| 7.8 kHz | 7800 |
|
||||
| 10.4 kHz | 10400 |
|
||||
| 15.6 kHz | 15600 |
|
||||
| 20.8 kHz | 20800 |
|
||||
| 31.25 kHz | 31250 |
|
||||
| 41.7 kHz | 41700 |
|
||||
| 62.5 kHz | 62500 |
|
||||
| 125 kHz | 125000 |
|
||||
| 250 kHz | 250000 |
|
||||
| 500 kHz | 500000 |
|
||||
|
||||
Note: SX1272/SX1273-based boards support only 125, 250, and 500 kHz.
|
||||
Not all bandwidths are legal for all frequency bands — consult local regulations.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```text
|
||||
loramodem/
|
||||
├── platformio.ini # Board environments and build configuration
|
||||
├── PROJECT.md # This file
|
||||
├── src/
|
||||
│ ├── main.cpp # Entry point; Arduino setup() and loop()
|
||||
│ ├── kiss.h / kiss.cpp # KISS frame encoder/decoder
|
||||
│ ├── radio.h / radio.cpp # RadioLib wrapper (init, TX, RX, config)
|
||||
│ └── config.h # Default radio parameters and pin definitions
|
||||
├── include/ # Shared headers (if needed)
|
||||
├── lib/ # Local libraries (if needed)
|
||||
├── variants/ # Board-specific hardware definitions
|
||||
│ ├── heltec_wifi_lora_32_v3/pins.h
|
||||
│ ├── rak4631/pins.h
|
||||
│ └── [other boards]/pins.h
|
||||
└── test/ # PlatformIO Unity test suite
|
||||
```
|
||||
|
||||
## Building
|
||||
|
||||
Prerequisites: [PlatformIO](https://platformio.org/) CLI or IDE extension.
|
||||
|
||||
**Build for a specific board:**
|
||||
|
||||
```sh
|
||||
pio run -e heltec_wifi_lora_32_v3
|
||||
```
|
||||
|
||||
**Upload to a connected board:**
|
||||
|
||||
```sh
|
||||
pio run -e heltec_wifi_lora_32_v3 -t upload
|
||||
```
|
||||
|
||||
**Monitor serial output:**
|
||||
|
||||
```sh
|
||||
pio device monitor -b 115200
|
||||
```
|
||||
|
||||
Note: KISS frames are binary. Use a KISS-capable TNC client (e.g., Direwolf,
|
||||
socat) to interact with the modem over serial.
|
||||
|
||||
Available board environments are defined in `platformio.ini`.
|
||||
|
||||
## Configuration Defaults
|
||||
|
||||
The modem initializes with these LoRa parameters at power-on:
|
||||
|
||||
| Parameter | Default value |
|
||||
| --------- | -------------------- |
|
||||
| Frequency | TBD MHz |
|
||||
| Bandwidth | 125 kHz |
|
||||
| SF | TBD |
|
||||
| CR | 4/5 |
|
||||
| Power | TBD dBm |
|
||||
| Sync word | `0x34` (LoRa public) |
|
||||
|
||||
These defaults may be overridden at compile time via `config.h`. Parameters changed
|
||||
via KISS port 2 commands take effect immediately but are **not persisted** across
|
||||
power cycles unless persistent storage (EEPROM/NVS) is implemented.
|
||||
|
||||
## Framework
|
||||
|
||||
This project uses [PlatformIO](https://platformio.org/) as the build system with
|
||||
[RadioLib](https://github.com/jgromes/RadioLib) as the LoRa driver library.
|
||||
Board-specific pin assignments and hardware configurations are isolated in the
|
||||
`variants/` directory, allowing the core KISS modem logic to remain board-agnostic.
|
||||
|
||||
The USB-CDC serial interface is used by default for KISS communication. On supported
|
||||
boards, a hardware UART may be selected instead via compile-time configuration in `config.h`.
|
||||
Reference in New Issue
Block a user