diff --git a/camera_example/camera.cpp b/camera_example/camera.cpp index 62e80f5..4ca4664 100644 --- a/camera_example/camera.cpp +++ b/camera_example/camera.cpp @@ -168,6 +168,7 @@ void processRequest(Request *request) int main() { std::signal(SIGPIPE, SIG_IGN); + std::signal(SIGINT, [](int) { loop.exit(0); }); std::thread(serverThread).detach(); auto cm = std::make_unique(); diff --git a/chip_test_example/Makefile b/chip_test_example/Makefile new file mode 100644 index 0000000..0809bcc --- /dev/null +++ b/chip_test_example/Makefile @@ -0,0 +1,28 @@ +# Build on device: +# apt install g++ +# make +# All deps (spidev, gpiochip, i2c-dev, termios) are kernel headers — no apt libs needed. + +CXX ?= g++ +CXXFLAGS ?= -O2 -std=c++17 -Wall -Wextra + +TARGETS = lora_tx lora_rx imu_test gps_test + +all: $(TARGETS) + +lora_tx: lora_tx.cpp lr1121_malnus.hpp + $(CXX) $(CXXFLAGS) $< -lpthread -o $@ + +lora_rx: lora_rx.cpp lr1121_malnus.hpp + $(CXX) $(CXXFLAGS) $< -lpthread -o $@ + +imu_test: imu_test.cpp icm20948.hpp + $(CXX) $(CXXFLAGS) $< -lpthread -o $@ + +gps_test: gps_test.cpp gps.hpp + $(CXX) $(CXXFLAGS) $< -o $@ + +clean: + rm -f $(TARGETS) + +.PHONY: all clean diff --git a/chip_test_example/README.md b/chip_test_example/README.md index 79de62d..7a86aa0 100644 --- a/chip_test_example/README.md +++ b/chip_test_example/README.md @@ -3,24 +3,32 @@ Tests for LR1121 LoRa, ICM-20948 IMU, u-blox GPS on Raspberry Pi Zero W 2. Header-only drivers, kernel ioctls, no external libs. +Driver: `lr1121_malnus.hpp` — crystal oscillator, RF switch via DIO5/DIO6. + --- ## Wiring ### LR1121 (SPI0) -| Module | Pi GPIO | Pi pin | -|--------|---------|--------| -| SCK | GPIO11 | 23 | -| MOSI | GPIO10 | 19 | -| MISO | GPIO9 | 21 | -| NSS | GPIO8 | 24 | -| BUSY | GPIO24 | 18 | -| NRESET | GPIO25 | 22 | -| DIO9 | GPIO4 | 7 | -| DIO8 | GPIO23 | 16 | +| Module | Pi GPIO | Pi pin | +|---------|---------|--------| +| SCK | GPIO11 | 23 | +| MOSI | GPIO10 | 19 | +| MISO | GPIO9 | 21 | +| NSS | GPIO8 | 24 | +| BUSY | GPIO24 | 18 | +| NRESET | GPIO25 | 22 | +| DIO5 | — | chip-driven RF switch (RFSW0) | +| DIO6 | — | chip-driven RF switch (RFSW1) | +| DIO9 | GPIO4 | 7 | +| DIO8 | GPIO23 | 16 | -Enable: `sudo raspi-config` → Interfaces → SPI → Yes → reboot +DIO5 and DIO6 are driven directly by the LR1121 — they go to your module's RF +switch and do not connect to the Pi. The driver configures them automatically +via `SetDioAsRfSwitch`: HIGH on DIO5 in RX, HIGH on DIO6 in TX, both LOW in standby. + +Enable SPI: `sudo raspi-config` → Interfaces → SPI → Yes → reboot ### ICM-20948 (I2C1) @@ -63,28 +71,29 @@ sudo ./imu_test -v ## LoRa debug ```sh -ls /dev/spidev0.0 # SPI on? +ls /dev/spidev0.0 # SPI enabled? sudo ./lora_rx -v --433 # step labels show exactly which command hangs ``` -If it hangs at `Calibrate` — that's a TCXO config issue. Try in order: +If it hangs at `Calibrate` — the chip isn't responding over SPI at all. +Check wiring, CS, and that SPI is enabled. The crystal needs no tuning. -```sh -sudo ./lora_rx -v --433 --tcxo-none # skip TCXO entirely (crystal mode) -sudo ./lora_rx -v --433 --tcxo-27 # TCXO 2.7V -sudo ./lora_rx -v --433 --tcxo-33 # TCXO 3.3V (default) -``` +If TX/RX runs but packets never arrive — check that DIO5/DIO6 reach the RF +switch on your module. Without the switch, the antenna path is disconnected. -The one that gets past "Calibrate done" is your module's config. -Use the same TCXO flag on TX and RX. - -If using the 2.4 GHz antenna instead: +To try 2.4 GHz instead (different antenna required): ```sh sudo ./lora_rx -v --24 sudo ./lora_tx -v --24 ``` +If the chip is stuck in bootloader (fw < 0x02xx), escape with: + +```sh +sudo ./lora_rx --reset +``` + --- ## IMU debug @@ -107,14 +116,3 @@ stty -F /dev/serial0 38400 raw && cat /dev/serial0 # raw NMEA bytes ./gps_test -v -a # all sentences ./gps_test -b 9600 # try different baud ``` - ---- - -## TCXO voltage reference - -| Flag | Value | Voltage | -|------|-------|---------| -| `--tcxo-none` | 0xFF | no TCXO (crystal) | -| `--tcxo-27` | 0x05 | 2.7V | -| `--tcxo-33` | 0x07 | 3.3V | -| `--tcxo-v N` | 0x00–0x07 | raw byte | diff --git a/shader_example/shader.cpp b/shader_example/shader.cpp index fc4c952..0f038d9 100644 --- a/shader_example/shader.cpp +++ b/shader_example/shader.cpp @@ -30,7 +30,7 @@ GLuint compile(GLenum t, const std::string& src) if (!ok) { char log[1024]; glGetShaderInfoLog(s, sizeof(log), NULL, log); - std::cout << "shader compile failed:\n" << log; + std::cerr << "shader compile failed:\n" << log; } return s; } @@ -51,8 +51,8 @@ int main() if(!img1 || !img2) { - std::cout << "image load failed\n"; - return 0; + std::cerr << "image load failed\n"; + return 1; } // ---------------- TEXTURES ---------------- @@ -99,7 +99,8 @@ int main() if (!linked) { char log[1024]; glGetProgramInfoLog(prog, sizeof(log), NULL, log); - std::cout << "program link failed:\n" << log; + std::cerr << "program link failed:\n" << log; + return 1; } // ---------------- QUAD (FIXED) ---------------- @@ -133,8 +134,10 @@ int main() glBindFramebuffer(GL_FRAMEBUFFER,fbo); glFramebufferTexture2D(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,outTex,0); - if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - std::cout << "FBO broken\n"; + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + std::cerr << "FBO broken\n"; + return 1; + } // ---------------- RENDER ---------------- glUseProgram(prog);