pixalynx/nrf9151-gps-tracker

A compact 44×32 mm, 4-layer nRF9151 LTE-M/NB-IoT/GNSS tracker PCB with nPM1300 LiPo/USB-C power, nano-SIM/eSIM switching, nRF7002 Wi‑Fi scanning, accelerometer, antennas, buzzer, LEDs, SOS button, and SWD/debug connectors.

Version
0.1.4
License
unset
Stars
0

docs/firmware.md

# Firmware notes and pin map (nRF Connect SDK / Zephyr)

The nRF9151 application core runs everything: LTE-M/NB-IoT modem, GNSS, the nRF7002 Wi-Fi scanner, the nPM1300 PMIC, the accelerometer, the buzzer and the SIM switch. All GPIOs are on port 0 at VDD_GPIO = 1.8 V (nPM1300 BUCK1). Start from the `nrf9151dk/nrf9151/ns` board files; the Thingy:91 X board (`thingy91x/nrf9151/ns`) is the closest reference for the nRF7002 and nPM1300 parts.

| Signal | nRF9151 pin | Direction | Devicetree / driver hint |
| --- | --- | --- | --- |
| I2C SDA (nPM1300 0x6B, LIS2DW12 0x18) | P0.08 | open-drain, 10 kΩ pull-ups to 1.8 V | `i2c2` (TWIM), 400 kHz |
| I2C SCL | P0.09 | | |
| ACC_INT1 (LIS2DW12 wake-up) | P0.10 | input, wake source | `st,lis2dw12` `irq-gpios` |
| ACC_INT2 | P0.11 | input (spare) | |
| PMIC_INT (nPM1300 GPIO0) | P0.03 | input | `nordic,npm1300` `host-int-gpios`, GPIO0 as interrupt output |
| BUZ_PWM (buzzer MOSFET gate, 100 kΩ pull-down) | P0.04 | PWM output, 4 kHz, 50 % duty | `pwm0` + `pwm-leds`/custom |
| SIM_SEL (NX3DV2567 S, 100 kΩ pull-down) | P0.25 | output: low = nano-SIM, high = eSIM | gpio; switch only with the modem in `AT+CFUN=4`/`0` |
| Wi-Fi SPI SCK | P0.28 | pull-down (nRF7002 Errata [9]) | `spi3` (SPIM), 8 MHz, `nordic,nrf7002-spi` on `reg = <0>` |
| Wi-Fi SPI MOSI | P0.29 | pull-down (nRF7002 Errata [9]) | |
| Wi-Fi SPI MISO | P0.30 | pull-down (nRF7002 Errata [9]) | |
| Wi-Fi SPI CS | P0.31 | | `cs-gpios` |
| WIFI_IRQ (nRF7002 HOST_IRQ) | P0.00 | input | `host-irq-gpios` |
| WIFI_BUCKEN (100 kΩ pull-down) | P0.01 | output | `bucken-gpios` |
| V3V3_EN (RT9080 LDO enable, 100 kΩ pull-down) | P0.02 | output | enable in `nrf_wifi_if_zep_start_board()` and before beeping; wait ≥ 6 ms before BUCKEN |
| COEX0 → GNSS LNA enable | COEX0 | modem-controlled | `AT%XCOEX0=1,1,1565,1586` |
| SWDIO / SWDCLK / nRESET | 4 / 3 / 9 | Tag-Connect TC2030-NL (J7) | logs over SEGGER RTT |

The nRF7002 IOVDD is not on a GPIO: it comes from the nPM1300 load switch 2 (LSOUT2, fed from 1.8 V). Point the Wi-Fi node at it with `iovdd-regulator = <&npm1300_ldo2>` (LDO2 in load-switch mode) instead of `iovdd-ctrl-gpios`. Nordic's power-up order is VBAT, wait ≥ 6 ms, BUCKEN, wait ≥ 1 ms, IOVDD. VBAT here is the RT9080 rail, so switch it on first (`V3V3_EN`) in the board start hook. The driver then handles BUCKEN and IOVDD.

Power-down is the reverse, and nRF7002 PS v1.3 (May 2026) makes the order explicit: drive every host-side line to the nRF7002 low, then switch IOVDD off, then take BUCKEN low, then switch VBAT off. No delays are needed, only that order. Here that means:
1. SCK/MOSI/MISO (P0.28–P0.30) go to `spi3_sleep` (pull-down), and the CS line P0.31 is driven low or disconnected. CS idles high while the SPI is active, and left high it back-feeds the unpowered nRF7002 I/O ring through its ESD diodes.
2. Load switch 2 off (IOVDD).
3. BUCKEN (P0.01) low.
4. `V3V3_EN` (P0.02) low, unless the buzzer is sounding: it shares the 3.3 V rail.

Check the order the NCS `nrf_wifi` driver uses when it powers the chip off. If it drops BUCKEN before IOVDD, or leaves CS high, handle it in the board hook.

## nPM1300 at boot

1. `VBUSINILIM0` = 500 mA, then `TASKUPDATEILIMSW`. The limit reverts to 100 mA every time the USB cable is replugged, so repeat this on each `EVENTVBUSDETECTED`.
2. Charger: ICHG = 0.5 C of the chosen cell (for example 250 mA for 500 mAh), VTERM 4.20 V, ITERM 10 %, `ADCNTCRSEL` = 10 kΩ (the on-board RT1 thermistor), then `BCHGENABLESET`. RT1 sits on the battery side of the board, so keep the cell pressed against it.
3. `IBATLIM` High (1 A) before the modem transmits.
4. BUCK1 is resistor-set to 1.8 V. BUCK2 is unused and disabled in hardware.
5. Load switch 1 → VANT (active GNSS antenna bias, only if L3 is fitted). Load switch 2 → nRF7002 IOVDD.
6. LED1 = charging (hardware default), LED2 = host-controlled status. GPIO0 = interrupt output.
7. SOS button on SHPHLD: ≥ 96 ms wakes from ship mode. Use SHPHLD press/release events for SOS gestures (long-press, triple-press). The 10 s long-press reset stays enabled unless you disable it.
8. Ship mode (`TASKENTERSHIPMODE`) is the "off" state, about 0.4 µA. Enter it only after the VBUS-removed event.

## Modem, GNSS and Wi-Fi

- `AT%XCOEX0=1,1,1565,1586` powers the SKY65943 GNSS LNA only while GNSS is receiving.
- Location: nRF Cloud or a self-hosted service combining GNSS (A-GNSS / P-GPS), Wi-Fi SSID scans (nRF7002) and LTE cell ID. Use the NCS `location` library with method priority GNSS → Wi-Fi → cellular.
- The nRF7002 only scans. It can be swapped for an nRF7000 (scan-only variant, pin compatible) by setting `CONFIG_WIFI_NRF70_SCAN_ONLY`. Keep TX power low in devicetree if active scanning is used.
- PSM/eDRX: `AT+CPSMS`, `AT+CEDRXS`. The motion sensor decides when a fix is worth the energy.

## SIM selection

The nRF9151 has one UICC port. The NX3DV2567 routes it to the nano-SIM socket (SIM_SEL low, the power-on default) or to the MFF2 eSIM (SIM_SEL high). Only change SIM_SEL with the modem offline (`AT+CFUN=4`), then bring it back up. The eSIM chip is supplied by the connectivity provider and fitted separately.

## nRF7002 SPI pull-downs (Revision 1 Errata [9])

Nordic's nRF7002 Rev 1 Erratum [9] ("IOVDD leakage current increases with floating pins") asks for pull-downs on
pins 35 SPI_CLK, 37 SPI_MOSI and 38 SPI_MISO. It allows them on the PCB or in the host GPIO configuration. This board
does it in the host, so give the SPIM pins a pull-down in both pinctrl states:

```dts
&pinctrl {
	spi3_default: spi3_default {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 28)>, <NRF_PSEL(SPIM_MOSI, 0, 29)>, <NRF_PSEL(SPIM_MISO, 0, 30)>;
			bias-pull-down;
		};
	};
	spi3_sleep: spi3_sleep {
		group1 {
			psels = <NRF_PSEL(SPIM_SCK, 0, 28)>, <NRF_PSEL(SPIM_MOSI, 0, 29)>, <NRF_PSEL(SPIM_MISO, 0, 30)>;
			bias-pull-down;
			low-power-enable;
		};
	};
};
```

The other pins the erratum names are handled in hardware: 2-5 and the unused 39-42 and 45 are tied to the grounded
paddle, and 6, 21-24, 43 and 44 stay open.