Bare-metal Python драйвер для управления LoRa-трансивером Semtech SX1262 напрямую из пользовательского пространства (userspace) Linux через USB-to-SPI конвертер на базе чипа FTDI FT232H.
Большинство примеров работы с LoRa в интернете опираются на массивные C++ библиотеки (например, RadioLib) или готовые обертки MicroPython, которые скрывают под капотом всю физику общения с чипом.
Этот проект создавался для того, чтобы:
- Понять архитектуру SX1262 и научиться управлять им "сырыми" байтами по SPI.
- Отлаживать радиоканал прямо с компьютера на Linux без необходимости прошивать микроконтроллер для каждого теста.
- Разобрать "подводные камни", которые не описаны в даташитах напрямую (питание TCXO, аппаратное управление антенной, сдвиги частоты).
В текущей версии реализован Transmitter (Передатчик), который формирует пакет, дожидается аппаратного прерывания TxDone и корректно освобождает шину.
- Конвертер: Любой модуль на чипе FTDI FT232H (поддерживает аппаратный движок MPSSE для SPI/I2C).
- LoRa Модуль: Протестировано на модулях Seeed Studio SX1262 (с TCXO 1.7V и единым пином управления антенным коммутатором RF Switch).
| FT232H Pin | Назначение в MPSSE | SX1262 Pin | Описание |
|---|---|---|---|
| AD0 | SCK | SCK | Тактовый сигнал SPI |
| AD1 | MOSI | MOSI | Передача данных (Master Out) |
| AD2 | MISO | MISO | Прием данных (Master In) |
| AD3 | CS | NSS | Выбор чипа (Chip Select) |
| AD4 | GPIO (Вход) | BUSY | Флаг занятости чипа (High = занят) |
| AD5 | GPIO (Выход) | RF_SW | Управление антенной (High = TX, Low = RX) |
| AD6 | GPIO (Вход) | DIO1 | Прерывания от модема (TxDone / RxDone) |
| 3.3V | Power | VCC | Питание модуля |
| GND | Ground | GND | Общая земля |
-
Установите зависимости: Для работы с FTDI через
libusbтребуется библиотекаpyftdi:pip3 install pyftdi
(В системах Linux может потребоваться настройка правил
udev, чтобы обращаться к USB безsudo). -
Узнайте адрес вашего FTDI конвертера: Подключите плату по USB и выполните утилиту:
ftdi_urls.py
Скопируйте полученный URL (например,
ftdi://ftdi:232h:1:1a/1). -
Настройте скрипт: Откройте файл
test_spi.pyи вставьте ваш URL в строку инициализации:spi.configure('ftdi://ftdi:232h:1:1a/1')
-
Запуск:
python3 test_spi.py
В процессе реверс-инжиниринга логики работы популярных библиотек (RadioLib / MicroPython) были решены следующие аппаратные нюансы, реализованные в этом коде:
В старых чипах (SX127x) регистр SyncWord занимал 1 байт (стандарт 0x12, 0x34 или 0x2b для Meshtastic). В новом SX1262 этот регистр двухбайтовый.
Высокоуровневые библиотеки сохранили совместимость: когда вы передаете им 1 байт (0x2b), они незаметно разбивают его на полубайты и подставляют в маску Semtech 0xY4Z4. В итоге чип физически получает слово 0x24B4. В нашем скрипте мы отправляем уже вычисленное значение напрямую.
Если у вашего модуля установлен кварц с термокомпенсацией (TCXO), чип не заведется на точной частоте без команды включения питания на пин DIO3. Модули Seeed требуют 1.7 Вольта. Если подать 3.3V или не подать ничего, частота PLL не залочится, и сигнал будет хаотично "гулять" по эфиру на мегагерцы. Решено командой SetDio3AsTcxoCtrl (1.7V).
При запросе статуса аппаратных ошибок (GetDeviceErrors) сдвиговый регистр SPI может выплевывать "застрявший" байт статуса в старшие биты ответа (например, 0xA200), пугая разработчика. В коде применена жесткая маска & 0x01FF, отсекающая SPI-мусор и оставляющая только реальные 9 битов аппаратных ошибок чипа SX1262.
- Реализация передатчика (TX) с аппаратным ожиданием прерываний.
- Реализация скрипта приемника (RX) с режимом RxContinuous и чтением RSSI/SNR.
Contributions and forks are welcome!