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 |
35
| GND | GND | 35 | 36 | USB_D- | |
36
| | Reserved* | 37 | 38 | USB_D+ | |
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
52
<details>
53
<summary>diff against pymc_core revision ba3ff4c26b9fadda1995c1ef6e21c7f143768c8d (main branch as of 12 Jan 2026)</summary>
54
55
```diff
56
diff --git a/examples/common.py b/examples/common.py
57
index 826b542..8e68faa 100644
58
--- a/examples/common.py
59
+++ b/examples/common.py
60
@@ -121,6 +121,23 @@ def create_radio(radio_type: str = "waveshare", serial_port: str = "/dev/ttyUSB0
61
"coding_rate": 5,
62
"preamble_length": 17,
63
},
64
+ "wibra": {
65
+ "bus_id": 5,
66
+ "cs_id": 0,
67
+ "cs_pin": -1,
68
+ "reset_pin": 150 - 128,
69
+ "busy_pin": 147 - 128,
70
+ "irq_pin": 149 - 128,
71
+ "txen_pin": -1,
72
+ "frequency": int(869.618 * 1000000), # EU: 869.525 MHz,
73
+ "tx_power": 22,
74
+ "spreading_factor": 8,
75
+ "bandwidth": int(62.5 * 1000),
76
+ "coding_rate": 8,
77
+ "preamble_length": 17,
78
+ "use_dio3_tcxo": True
79
+ }
80
+
81
}
82
83
if radio_type not in configs:
84
diff --git a/examples/discover_nodes.py b/examples/discover_nodes.py
85
index 097be79..2db003f 100644
86
--- a/examples/discover_nodes.py
87
+++ b/examples/discover_nodes.py
88
@@ -44,6 +44,11 @@ async def discover_nodes(
89
"""
90
mesh_node, identity = create_mesh_node("DiscoveryNode", radio_type, serial_port)
91
92
+ print(mesh_node.radio)
93
+ print(dir(mesh_node.radio))
94
+ print(dir(mesh_node.radio.lora))
95
+ print(''.join(map(chr, mesh_node.radio.lora.readRegister(0x320, 16))))
96
+
97
# Dictionary to store discovered nodes
98
discovered_nodes = {}
99
100
@@ -149,7 +154,7 @@ def main():
101
parser = argparse.ArgumentParser(description="Discover nearby mesh nodes")
102
parser.add_argument(
103
"--radio-type",
104
- choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc"],
105
+ choices=["waveshare", "uconsole", "meshadv-mini", "kiss-tnc", "wibra"],
106
default="waveshare",
107
help="Radio hardware type (default: waveshare)",
108
)
109
diff --git a/src/pymc_core/hardware/gpio_manager.py b/src/pymc_core/hardware/gpio_manager.py
110
index 399a5da..fa7f900 100644
111
--- a/src/pymc_core/hardware/gpio_manager.py
112
+++ b/src/pymc_core/hardware/gpio_manager.py
113
@@ -44,7 +44,7 @@ logger = logging.getLogger("GPIOPinManager")
114
class GPIOPinManager:
115
"""Manages GPIO pins abstraction using Linux GPIO character device interface"""
116
117
- def __init__(self, gpio_chip: str = "/dev/gpiochip0"):
118
+ def __init__(self, gpio_chip: str = "/dev/gpiochip4"):
119
"""
120
Initialize GPIO Pin Manager
121
122
diff --git a/src/pymc_core/hardware/lora/LoRaRF/SX126x.py b/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
123
index 31bedd4..3a672ef 100644
124
--- a/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
125
+++ b/src/pymc_core/hardware/lora/LoRaRF/SX126x.py
126
@@ -468,7 +468,7 @@ class SX126x(BaseLoRa):
127
self._cs_define = 17 # Default to GPIO 17 (safe alternative)
128
else:
129
# Keep original hardcoded value for unknown buses
130
- self._cs_define = 21
131
+ self._cs_define = 1
132
133
# open spi line and set bus id, chip select, and spi speed
134
spi.open(bus, cs)
135
@@ -1484,6 +1484,7 @@ class SX126x(BaseLoRa):
136
# Adaptive CS control based on CS pin type
137
if self._cs_define != 8: # Manual CS pin (like Waveshare GPIO 21)
138
# Simple CS control for manual pins
139
+ print("_cs_define", self._cs_define)
140
_get_output(self._cs_define).write(False)
141
buf = [opCode]
142
for i in range(nBytes):
143
```
144
</details>
145
146
pinout:
147
148
* SPI (CLK/MOSI/MISO/CE) on minipcie pins 3, 6, 5, 7.
149
* RST on 22
150
* BUSY on 19
151
* IRQ/DIO1 on 1
152
153
plus 3v3+GND from a wide choice of pins
d9f0c0 Peter van Dijk 2026-02-21 13:29:12 154
155
![photo of bobcat with sx1262 connected to minipcie via protoboard](./PXL_20260221_130951831.jpg)