Blame

362e46 Peter van Dijk 2026-01-28 23:15:48 1
# Bobcat Miner 300
2
257e20 Peter van Dijk 2026-02-17 17:08:08 3
Documentation below currently based on only observing the G295 model.
4
362e46 Peter van Dijk 2026-01-28 23:15:48 5
LoRa interface: SPI over mPCIe
6
7
Antenna connector: IPEX1
8
9
Software: [a Debian image exists](https://github.com/sicXnull/Bobcat300-Debian)
257e20 Peter van Dijk 2026-02-17 17:08:08 10
e47e2c Peter van Dijk 2026-02-20 15:51:41 11
'3/5 (101)' means gpiochip 3, line 5, which is 101 in the global pin count.
257e20 Peter van Dijk 2026-02-17 17:08:08 12
93c2b1 Peter van Dijk 2026-02-17 21:01:13 13
Currently unclear which CS line is which of 3/1 and 3/2
257e20 Peter van Dijk 2026-02-17 17:08:08 14
e47e2c Peter van Dijk 2026-02-20 15:51:41 15
| Bobcat Miner 300 | Spec label | Top side | Bottom side | Spec label | Bobcat Miner 300 |
16
| ---------------------------------------- | ------------ | -------- | ----------- | ----------- | ---------------- |
17
| 4/21 (149) | WAKE# | 1 | 2 | 3.3V | |
18
| SCK 3/19 (115) | Reserved**** | 3 | 4 | GND | GND |
19
| MISO 3/18 (114) | Reserved**** | 5 | 6 | 1.5V | MOSI 3/17 (113) |
20
| CS (`spidev5.0`) on 3/1 (97) or 3/2 (98) | CLKREQ# | 7 | 8 | VCC** | |
21
| GND | GND | 9 | 10 | I/O** | |
22
| | REFCLK- | 11 | 12 | CLK** | |
23
| | REFCLK+ | 13 | 14 | RST** | |
24
| GND | N/C or GND | 15 | 16 | VPP** | |
25
| | | key | key | | |
26
| CS (`spidev5.1`) on 3/2 (98) or 3/1 (97) | Reserved | 17 | 18 | GND | GND |
27
| 4/19 (147) | Reserved | 19 | 20 | Reserved*** | |
28
| GND | GND | 21 | 22 | PERST# | 4/22 (150) |
29
| 3/3 (99) | PERn0 | 23 | 24 | +3.3Vaux | |
30
| | PERp0 | 25 | 26 | GND | GND |
31
| GND | GND | 27 | 28 | +1.5V | |
32
| GND | GND | 29 | 30 | SMB_CLK | 3/24 (120) |
33
| | PETn0 | 31 | 32 | SMB_DATA | 3/23 (119) |
34
| | PETp0 | 33 | 34 | GND | GND |
d55654 Peter van Dijk 2026-02-21 21:15:29 35
| GND | GND | 35 | 36 | USB_D- | USB_D- |
36
| | Reserved* | 37 | 38 | USB_D+ | USB_D+ |
e47e2c Peter van Dijk 2026-02-20 15:51:41 37
| | Reserved* | 39 | 40 | GND | GND |
38
| | Reserved* | 41 | 42 | LED_WWAN# | |
39
| GND | Reserved* | 43 | 44 | LED_WLAN# | 3/22 (118) |
40
| i2c SCL 4/23 (151) or 4/24 (152) | Reserved* | 45 | 46 | LED_WPAN# | 3/29 (125) |
41
| i2c SDA 4/24 (152) or 4/23 (151) | Reserved* | 47 | 48 | +1.5V | |
42
| | Reserved* | 49 | 50 | GND | GND |
43
| | Reserved* | 51 | 52 | +3.3V | |
eb369c Peter van Dijk 2026-02-21 13:26:16 44
45
## hacky working pymc setup
46
47
There is a `newradios` branch in pymc core & repeater that likely makes all of this possible without local patching (other than perhaps the board definition, in core, while repeater has configuration for that).
48
49
The pinout chosen here may not be the best.
50
Because the bobcat puts SPI on different pins than other boards seen so far, we need to figure out if routing SPI to two sets of pins can create a miniPCIe board that works for the bobcat -and- for other devices.
51
d55654 Peter van Dijk 2026-02-21 21:15:29 52
USB might be the very simplest answer though.
53
eb369c Peter van Dijk 2026-02-21 13:26:16 54
<details>
55
<summary>diff against pymc_core revision ba3ff4c26b9fadda1995c1ef6e21c7f143768c8d (main branch as of 12 Jan 2026)</summary>
56
57
```diff
58
diff --git a/examples/common.py b/examples/common.py
59
index 826b542..8e68faa 100644
60
--- a/examples/common.py
61
+++ b/examples/common.py
62
@@ -121,6 +121,23 @@ def create_radio(radio_type: str = "waveshare", serial_port: str = "/dev/ttyUSB0
63
"coding_rate": 5,
64
"preamble_length": 17,
65
},
66
+ "wibra": {
67
+ "bus_id": 5,
68
+ "cs_id": 0,
69
+ "cs_pin": -1,
70
+ "reset_pin": 150 - 128,
71
+ "busy_pin": 147 - 128,
72
+ "irq_pin": 149 - 128,
73
+ "txen_pin": -1,
74
+ "frequency": int(869.618 * 1000000), # EU: 869.525 MHz,
75
+ "tx_power": 22,
76
+ "spreading_factor": 8,
77
+ "bandwidth": int(62.5 * 1000),
78
+ "coding_rate": 8,
79
+ "preamble_length": 17,
80
+ "use_dio3_tcxo": True
81
+ }
82
+
83
}
84
85
if radio_type not in configs:
86
diff --git a/examples/discover_nodes.py b/examples/discover_nodes.py
87
index 097be79..2db003f 100644
88
--- a/examples/discover_nodes.py
89
+++ b/examples/discover_nodes.py
90
@@ -44,6 +44,11 @@ async def discover_nodes(
91
"""
92
mesh_node, identity = create_mesh_node("DiscoveryNode", radio_type, serial_port)
93
94
+ print(mesh_node.radio)
95
+ print(dir(mesh_node.radio))
96
+ print(dir(mesh_node.radio.lora))
97
+ print(''.join(map(chr, mesh_node.radio.lora.readRegister(0x320, 16))))
98
+
99
# Dictionary to store discovered nodes
100
discovered_nodes = {}
101
102
@@ -149,7 +154,7 @@ def main():
103
parser = argparse.ArgumentParser(description="Discover nearby mesh nodes")
104
parser.add_argument(
105
"--radio-type",
106
- choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
107
+ choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc", "wibra"],
108
default="waveshare",
109
help="Radio hardware type (default: waveshare)",
110
)
111
diff --git a/src/pymc_core/hardware/gpio_manager.py b/src/pymc_core/hardware/gpio_manager.py
112
index 399a5da..fa7f900 100644
113
--- a/src/pymc_core/hardware/gpio_manager.py
114
+++ b/src/pymc_core/hardware/gpio_manager.py
115
@@ -44,7 +44,7 @@ logger = logging.getLogger("GPIOPinManager")
116
class GPIOPinManager:
117
"""Manages GPIO pins abstraction using Linux GPIO character device interface"""
118
119
- def __init__(self, gpio_chip: str = "/dev/gpiochip0"):
120
+ def __init__(self, gpio_chip: str = "/dev/gpiochip4"):
121
"""
122
Initialize GPIO Pin Manager
123
124
diff --git a/src/pymc_core/hardware/lora/LoRaRF/SX126x.py b/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
125
index 31bedd4..3a672ef 100644
126
--- a/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
127
+++ b/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
128
@@ -468,7 +468,7 @@ class SX126x(BaseLoRa):
129
self._cs_define = 17 # Default to GPIO 17 (safe alternative)
130
else:
131
# Keep original hardcoded value for unknown buses
132
- self._cs_define = 21
133
+ self._cs_define = 1
134
135
# open spi line and set bus id, chip select, and spi speed
136
spi.open(bus, cs)
137
@@ -1484,6 +1484,7 @@ class SX126x(BaseLoRa):
138
# Adaptive CS control based on CS pin type
139
if self._cs_define != 8: # Manual CS pin (like Waveshare GPIO 21)
140
# Simple CS control for manual pins
141
+ print("_cs_define", self._cs_define)
142
_get_output(self._cs_define).write(False)
143
buf = [opCode]
144
for i in range(nBytes):
145
```
146
</details>
147
148
pinout:
149
150
* SPI (CLK/MOSI/MISO/CE) on minipcie pins 3, 6, 5, 7.
151
* RST on 22
152
* BUSY on 19
153
* IRQ/DIO1 on 1
154
155
plus 3v3+GND from a wide choice of pins
d9f0c0 Peter van Dijk 2026-02-21 13:29:12 156
157
![photo of bobcat with sx1262 connected to minipcie via protoboard](./PXL_20260221_130951831.jpg)