Running OpenWRT on the Pine64 LoRa Gateway

Sunday, October 13, 2024

Pine64 offers a LoRa gateway built around their Pine A64-LTS SBC.

I was fortunate enough to receive an engineering sample from Pine64, allowing me to test the gateway and provide a custom OS image before it became available for purchase. RTP (@RTP on Fosstodon ) later created a custom image based on Armbian, which worked well.

I’ve been running one of RTP’s early image for a few years now. It’s connected on the TTN (The Things Network) , and I use it to get the data from my LoRa water meter .

I’m now planning on buying a better antenna and install the gateway in a sealed enclosure to mount it on the outdoor wall of my garage. I would like this setup to be a “install and forget” setup : it should just run with very minimal maintenance.

The downside of my current setup based on Armbian is the SD card : it will fail at some point.

So my idea was to use OpenWRT instead of Armbian to run the gateway. OpenWRT is very lightweight and run from RAM, which makes it a very good fit for this use-case.

This should be definitely possible to achieve since there are a few LoRa gateways from 3rd party providers that run on OpenWRT.

OpenWRT also provides a few LoRa related packages on their repo(libloragw , libloragw-utils , libloragw-tests ).

I thought it should be an easy project but… I eventually didn’t manage to make it run. Since I’ll probably not have the time to continue the project in the near future, I decided to write this post with all the notes I took during my experiments. This way, someone might be able to continue the project, or I’ll at least remember what I did when I’ll find the time to continue it later on!

Gateway documentation

The documentation related to the LoRa gateway is available on the Pine64 community website . The most important part is the pin mapping between the board PI-2 connector and the RAK5146 LoRa module.

OpenWRT image and DTS

The support for the Pine A64-LTS board is provided by the SOPINE image. However, the DTS file in this default image does not enable the spidev driver for the SPI0 bus, that is needed to drive the LoRa module. So we’ll need to build our own version of OpenWRT to enable it (and probably make a few other changes).

To do so, I followed the documentation of the project to download and build OpenWRT v23.05.0 .

To modify the DTS, I simply edited the file <git folder>/openwrt/build_dir/target-aarch64_cortex-a53_musl/linux-sunxi_cortexa53/linux-5.15.134/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi so that the spi0 node looks like this :

&spi0  {
	status = "okay";

	spidev@0 {
		compatible = "semtech,sx1301";
		status = "okay";
		reg = <0>;
		spi-max-frequency = <8000000>;
	};
};

Note that this is a hacky way to edit the sources of OpenWRT and those changes will be reverted as soon as OpenWRT will refresh the build directory. The correct way to do this involves creating a patch file and inserting it in the build system.

SPIDEV driver

The spidev driver must also be added to the image. To do so, in the make menuconfig interface, go to Kernel modules --> SPI support and enable kmod-spi-dev.

GPIO

Most of the scripts from RAK use the now deprecated sysfs api to set and clear the RESET pin of the LoRa module. This API is deprecated and does not seem to work anymore on newer kernels (>6.6). Instead, you should use gpioset to drive the GPIO pins. In this case, use gpioset gpiochip2 71=0 to reset the LoRa module and gpioset gpiochip2 71=1 to enable it again.

The package gpiod-tools must be enabled in the make menuconfig interface for this tool to be available.

Testing the communication with the LoRa module.

I’m stuck at this step : the /dev/spidev0.0 device driver is available and seems to work, but all the test programs (util_* and test_*) fail with errors.

For example, here is the result of test_loragw_reg, which is supposed to read the content of the registers of the LoRa module:

root@OpenWrt:/# test_loragw_reg 
Beginning of test for loragw_reg.c
ERROR: CONCENTRATOR UNCONNECTED
IMPLICIT_PAYLOAD_LENGHT = 0 (should be 197)
FRAME_SYNCH_PEAK2_POS = 0 (should be 11)
PREAMBLE_SYMB1_NB = 0 (should be 49253)
ADJUST_MODEM_START_OFFSET_SF12_RDX4 = 0 (should be 3173)
IF_FREQ_1 = 0 (should be -1947)
End of test for loragw_reg.c

As you can see, it read all 0s when it was expecting other specific values.

I checked with my logic analyzer : data is sent on the MOSI, CS and CLK pins, but the module never writes data on the MISO pin.

That’s as far as I got. I don’t know how to go further and fix this issue. Note that this is not a hardware issue since this exact same board work fine on Armbian with the RAK tools running.

If you have any idea about this or if you want to continue this project, feel free email me at jf[at]codingfield[dot]com or reach out to me on Matrix at @jf:matrix.codingfield.com.

LoRalorapine64WIPopenwrt

JF

I am passionate about IT, (embedded) software development and open source technologies in general. I’m mainly working on the InfiniTime project , an open source firmware for the PineTime smartwatch from Pine64 .

Install Frigate in Proxmox on the OrangePi5+ (RK3588)