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
parts/Wifi.tsx
import type { ChipProps } from "tscircuit"
import { Nrf7002Qfn48, Crystal2016, pad, courtyard, outline } from "../lib/footprints"
/** Nordic nRF7002-QFAA-R7 Wi-Fi 6 companion IC (JLC C5370744), used here only for SSID scanning (Wi-Fi
* positioning). The nRF7000 (scan-only variant) is pin compatible. Pin table: nRF7002 Product
* Specification v1.2 Table 24, rechecked against v1.3 (May 2026) Table 1 (research/nrf7002.md), with the unused-pin handling of nRF7002 Revision 1 Errata
* [9] ("IOVDD leakage current increases with floating pins"): pins 2-5 (renamed Reserved) and the unused
* 39 QSPI_DATA2, 40 QSPI_DATA3, 41 COEX_STATUS0, 42 COEX_REQ, 45 COEX_STATUS1/SW_CTRL1 go to GND; 6, 21-24,
* 43, 44 stay open; 35/37/38 (SPI CLK/MOSI/MISO) need pull-downs, done in the host GPIO configuration
* (docs/firmware.md), which the erratum allows. VBAT 2.9-4.5 V, IOVDD 1.62-3.6 V, shutdown 1.7 uA,
* scan 60 mA average, TX 191 mA (2.4 GHz) / 260 mA (5 GHz) peak. */
export const nrf7002Pins = {
pin1: ["OTPVDD"], pin2: ["RSV2"], pin3: ["RSV3"], pin4: ["RSV4"], pin5: ["RSV5"], pin6: ["RSV6"],
pin7: ["TXRF1"], pin8: ["PAVDD1"], pin9: ["TXRF0"], pin10: ["PAVDD0"], pin11: ["SXLDO"], pin12: ["PALDO"],
pin13: ["VBAT"], pin14: ["RFVDD"], pin15: ["RFBUCKVDD"], pin16: ["XOLDO"], pin17: ["XOP"], pin18: ["XON"],
pin19: ["AFELDO"], pin20: ["AFEVBAT"], pin21: ["NC21"], pin22: ["NC22"], pin23: ["NC23"], pin24: ["NC24"],
pin25: ["BUCKVBAT"], pin26: ["BUCKOUT"], pin27: ["BUCKVSS1"], pin28: ["BUCKVSS2"], pin29: ["BUCKVMID"], pin30: ["BUCKEN"],
pin31: ["BUCKVBATS"], pin32: ["PWRBUCKVDD"], pin33: ["DIGVDD"], pin34: ["PWRIOVDD"],
pin35: ["SPI_CLK", "QSPI_CLK"], pin36: ["SPI_SS", "QSPI_SS"], pin37: ["SPI_MOSI", "QSPI_DATA0"], pin38: ["SPI_MISO", "QSPI_DATA1"],
pin39: ["QSPI_DATA2"], pin40: ["QSPI_DATA3"], pin41: ["COEX_STATUS0"], pin42: ["COEX_REQ"], pin43: ["COEX_GRANT"],
pin44: ["SW_CTRL0"], pin45: ["SW_CTRL1", "COEX_STATUS1"], pin46: ["HOST_IRQ"], pin47: ["VSS"], pin48: ["IOVDD"], pin49: ["EP"],
} as const
const ncPins = ["RSV6", "NC21", "NC22", "NC23", "NC24", "COEX_GRANT", "SW_CTRL0"]
/** tied to GND per Revision 1 Errata [9] (floating, they raise IOVDD leakage) */
export const nrf7002GroundedPins = ["RSV2", "RSV3", "RSV4", "RSV5", "QSPI_DATA2", "QSPI_DATA3", "COEX_STATUS0", "COEX_REQ", "SW_CTRL1"] as const
export const Nrf7002 = (props: ChipProps<typeof nrf7002Pins>) => (
<chip
{...props}
manufacturerPartNumber="NRF7002-QFAA-R7"
supplierPartNumbers={{ jlcpcb: ["C5370744"] }}
pinLabels={nrf7002Pins}
internallyConnectedPins={[["VSS", "EP", "BUCKVSS1", "BUCKVSS2"]]}
footprint={<Nrf7002Qfn48 />}
cadModel={{ objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C5370744.obj?uuid=d0fbea2586a94bf4a0c0b2823af3d10c", rotationOffset: { x: 0, y: 0, z: 0 }, positionOffset: { x: 0, y: 0, z: 0 } }}
schWidth={2.75}
schHeight={4.35}
schPinArrangement={{
leftSide: { direction: "top-to-bottom", pins: ["VBAT", "AFEVBAT", "BUCKVBAT", "BUCKVBATS", "BUCKOUT", "PWRBUCKVDD", "RFBUCKVDD", "BUCKVMID", "IOVDD", "OTPVDD", "PWRIOVDD", "DIGVDD", "PALDO", "PAVDD0", "PAVDD1", "SXLDO", "RFVDD", "XOLDO", "AFELDO"] },
rightSide: { direction: "top-to-bottom", pins: ["SPI_CLK", "SPI_SS", "SPI_MOSI", "SPI_MISO", "HOST_IRQ", "BUCKEN", "TXRF0", "TXRF1", "XOP", "XON", "QSPI_DATA2", "QSPI_DATA3", "COEX_STATUS0", "COEX_REQ", "COEX_GRANT", "SW_CTRL0", "SW_CTRL1"] },
bottomSide: { direction: "left-to-right", pins: ["VSS", "EP", "BUCKVSS1", "BUCKVSS2"] },
topSide: { direction: "left-to-right", pins: ["RSV2", "RSV3", "RSV4", "RSV5", "RSV6", "NC21", "NC22", "NC23", "NC24"] },
}}
pinAttributes={{
VBAT: { requiresPower: true }, IOVDD: { requiresPower: true }, VSS: { requiresGround: true }, EP: { requiresGround: true },
...Object.fromEntries(ncPins.map((p) => [p, { doNotConnect: true }])),
...Object.fromEntries(nrf7002GroundedPins.map((p) => [p, { requiresGround: true }])),
}}
/>
)
/** TDK DPX165950DT-8148A1 2.4 / 5 GHz WLAN diplexer, 1.6 x 0.8 mm, 6 terminals (JLC C307668, 6.7k in stock).
* Pins (JLC/EasyEDA symbol): 1 LOW_BAND (2.4 GHz), 3 HIGH_BAND (5 GHz), 5 COM (antenna), 2/4/6 GND.
* Land pattern = the EasyEDA one of C307668 (0.35 x 0.625 mm lands, 0.55 mm pitch, rows +/-0.54 mm; pins 1-3 on
* the lower row left to right, 4-6 on the upper row right to left), drawn explicitly because the matching
* dfn6 footprinter string renders with width and length swapped in this core. Plays the role of U2
* "2.4 / 5 GHz WLAN Dual Band Diplexer" in Nordic's nRF7002 reference schematic. */
export const diplexerPins = { pin1: ["LOW_BAND"], pin2: ["GND3"], pin3: ["HIGH_BAND"], pin4: ["GND2"], pin5: ["COM"], pin6: ["GND1"] } as const
export const Diplexer = (props: ChipProps<typeof diplexerPins>) => (
<chip
{...props}
manufacturerPartNumber="DPX165950DT-8148A1"
supplierPartNumbers={{ jlcpcb: ["C307668"] }}
pinLabels={diplexerPins}
internallyConnectedPins={[["GND1", "GND2", "GND3"]]}
footprint={
<footprint>
{[1, 2, 3].map((p, i) => pad(p, -0.55 + i * 0.55, -0.54, 0.35, 0.625))}
{[4, 5, 6].map((p, i) => pad(p, 0.55 - i * 0.55, 0.54, 0.35, 0.625))}
{outline(1.6, 0.8)}
{courtyard(2.2, 2.0)}
</footprint>
}
cadModel={{ objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C307668.obj?uuid=65fbddda7e9a4bb69de86e05fa1ddb6b", rotationOffset: { x: 0, y: 0, z: 0 }, positionOffset: { x: 0, y: 0, z: 0 } }}
schPinArrangement={{ leftSide: { direction: "top-to-bottom", pins: ["LOW_BAND", "HIGH_BAND", "GND1"] }, rightSide: { direction: "top-to-bottom", pins: ["COM", "GND2", "GND3"] } }}
pinAttributes={{ GND1: { requiresGround: true }, GND2: { requiresGround: true }, GND3: { requiresGround: true } }}
/>
)
/** 40 MHz crystal, 2016, CL 8 pF, ESR 30 ohm, +/-10 ppm (Hosonic/TKD K2B400000810, JLC C2835990, 20k in stock).
* Nordic: 40 MHz, CL = 8 pF, ESR <= 100 ohm; no external load capacitors (nRF7002 reference schematic X1). */
export const crystalPins = { pin1: ["X1"], pin2: ["GND1"], pin3: ["X2"], pin4: ["GND2"] } as const
export const Crystal40M = (props: ChipProps<typeof crystalPins>) => (
<chip
{...props}
manufacturerPartNumber="K2B400000810"
supplierPartNumbers={{ jlcpcb: ["C2835990"] }}
pinLabels={crystalPins}
footprint={<Crystal2016 />}
cadModel={{ objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C2835990.obj?uuid=51ae9b24ba7a408881f7752b57b66e45", rotationOffset: { x: 0, y: 0, z: 0 }, positionOffset: { x: 0, y: 0, z: 0 } }}
schWidth={0.6}
schHeight={1.15}
schPinArrangement={{ leftSide: { direction: "top-to-bottom", pins: ["X1"] }, rightSide: { direction: "top-to-bottom", pins: ["X2"] }, bottomSide: { direction: "left-to-right", pins: ["GND1", "GND2"] } }}
pinAttributes={{ GND1: { requiresGround: true }, GND2: { requiresGround: true } }}
/>
)
/** Richtek RT9080-33GJ5 3.3 V / 600 mA LDO, TSOT-23-5 (JLC C841192, 67k in stock): 2 uA quiescent, VIN up to 5.5 V
* (VSYS follows VBUS while charging, so the nRF7002's 4.5 V VBAT maximum rules out feeding it from VSYS directly,
* and its 260 mA TX peak exceeds the nPM1300 bucks' 200 mA). Pins: 1 VIN, 2 GND, 3 EN, 4 NC, 5 VOUT. */
export const rt9080Pins = { pin1: ["VIN"], pin2: ["GND"], pin3: ["EN"], pin4: ["NC"], pin5: ["VOUT"] } as const
export const Rt9080 = (props: ChipProps<typeof rt9080Pins>) => (
<chip
{...props}
manufacturerPartNumber="RT9080-33GJ5"
supplierPartNumbers={{ jlcpcb: ["C841192"] }}
pinLabels={rt9080Pins}
footprint="sot25_w2.3mm_pw0.53mm_pl1.05mm_pin1location(bottomside,left)"
cadModel={{ objUrl: "https://modelcdn.tscircuit.com/easyeda_models/assets/C841192.obj?uuid=c7fdf6dae3ca4abaabd1bafd2d31350d", rotationOffset: { x: 0, y: 0, z: 90 }, positionOffset: { x: 0, y: 0, z: 0 } }}
schPinArrangement={{ leftSide: { direction: "top-to-bottom", pins: ["VIN", "EN"] }, rightSide: { direction: "top-to-bottom", pins: ["VOUT", "NC"] }, bottomSide: { direction: "left-to-right", pins: ["GND"] } }}
pinAttributes={{ VIN: { requiresPower: true }, VOUT: { providesPower: true }, GND: { requiresGround: true }, NC: { doNotConnect: true } }}
/>
)