dln2 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dln2
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Unified DLN2 driver — SPI, GPIO, I2C, ADC over a single USB connection. Originally developed for the Pico USB I/O Board.
5
5
  Home-page: https://github.com/syabyr/dln2_wrapper
6
6
  Author: IPM Group
@@ -187,6 +187,27 @@ python3 examples/adc_info.py
187
187
  | Multi-device | Manual USB enumeration | `list_devices()` |
188
188
  | Cross-module data flow | Impossible (4 echo counters) | Trivial (same counter) |
189
189
 
190
+ ## Pin Constraints
191
+
192
+ | Pins | Capability |
193
+ |---|---|
194
+ | 0–22, 26–28 | Full GPIO (input/output + events) |
195
+ | 23, 24, 29 | Output-only (reserved for SMPS / VBUS / VSYS) |
196
+ | 25 | Output-only (on-board LED) |
197
+ | ADC 0–2 | Map to GPIO 26, 27, 28 respectively |
198
+
199
+ ## Firmware Compatibility
200
+
201
+ | dln2 Python | Minimum firmware | Notes |
202
+ |---|---|---|
203
+ | 0.2.1 | [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) `>= v0.2` | SPI bpw validation, ADC pin-sharing fix |
204
+ | 0.2.0 | any | Works with all firmware versions |
205
+
206
+ To flash updated firmware:
207
+ 1. Hold the BOOTSEL button while connecting the Pico (or press and release RESET while holding BOOTSEL)
208
+ 2. Copy `dln2.uf2` to the `RPI-RP2` USB drive that appears
209
+ 3. The Pico reboots automatically with the new firmware
210
+
190
211
  ## Related
191
212
 
192
213
  - [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) — RP2040 firmware
@@ -152,6 +152,27 @@ python3 examples/adc_info.py
152
152
  | Multi-device | Manual USB enumeration | `list_devices()` |
153
153
  | Cross-module data flow | Impossible (4 echo counters) | Trivial (same counter) |
154
154
 
155
+ ## Pin Constraints
156
+
157
+ | Pins | Capability |
158
+ |---|---|
159
+ | 0–22, 26–28 | Full GPIO (input/output + events) |
160
+ | 23, 24, 29 | Output-only (reserved for SMPS / VBUS / VSYS) |
161
+ | 25 | Output-only (on-board LED) |
162
+ | ADC 0–2 | Map to GPIO 26, 27, 28 respectively |
163
+
164
+ ## Firmware Compatibility
165
+
166
+ | dln2 Python | Minimum firmware | Notes |
167
+ |---|---|---|
168
+ | 0.2.1 | [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) `>= v0.2` | SPI bpw validation, ADC pin-sharing fix |
169
+ | 0.2.0 | any | Works with all firmware versions |
170
+
171
+ To flash updated firmware:
172
+ 1. Hold the BOOTSEL button while connecting the Pico (or press and release RESET while holding BOOTSEL)
173
+ 2. Copy `dln2.uf2` to the `RPI-RP2` USB drive that appears
174
+ 3. The Pico reboots automatically with the new firmware
175
+
155
176
  ## Related
156
177
 
157
178
  - [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) — RP2040 firmware
@@ -127,18 +127,25 @@ class Dln2Connection:
127
127
  self._setup()
128
128
 
129
129
  def _setup(self):
130
- # Reset USB to clear stale state
131
- try:
132
- self._dev.reset()
133
- except Exception:
134
- pass
130
+ # NOTE: Do NOT call self._dev.reset() here.
131
+ # A USB bus reset only resets the USB peripheral on the RP2040 —
132
+ # SPI PIO/DMA state machines survive it. Commands that hit a
133
+ # half-configured PIO cause a hard fault that kills the firmware
134
+ # and requires a physical replug. Instead, just set configuration.
135
135
 
136
136
  try:
137
137
  self._dev.set_configuration()
138
138
  except Exception:
139
139
  pass
140
140
 
141
- cfg = self._dev.get_active_configuration()
141
+ try:
142
+ cfg = self._dev.get_active_configuration()
143
+ except Exception:
144
+ raise RuntimeError(
145
+ "DLN2 device is not responding — "
146
+ "the Pico firmware may have crashed.\n"
147
+ "Please replug the USB cable to power-cycle the board."
148
+ )
142
149
  intf = cfg[(0, 0)]
143
150
 
144
151
  ep_out = ep_in = None
@@ -339,10 +339,10 @@ def spi_test():
339
339
 
340
340
  try:
341
341
  print("Opening SpiDev (DLN backend)...")
342
- dev.open(0, 0)
343
342
  dev.max_speed_hz = 1_000_000
344
343
  dev.mode = 0
345
344
  dev.bits_per_word = 8
345
+ dev.open(0, 0)
346
346
  tx = [0x9F, 0x00, 0x00, 0x00]
347
347
  print("Sending JEDEC (0x9F) via DLN wrapper... host_hold_cs=", dev.host_hold_cs)
348
348
  rx = dev.xfer2(tx)
@@ -359,23 +359,22 @@ def spi_test():
359
359
 
360
360
 
361
361
  def bpw_test():
362
- """Cycle SPI bits-per-word 4..16 sending a test pattern at each setting."""
362
+ """Cycle SPI bits-per-word 8 and 16 sending a test pattern at each setting."""
363
363
  from dln2.spi import SpiDev
364
364
 
365
- print("Sending one transfer for each BPW 4..16")
365
+ print("Sending one transfer for BPW 8 and 16")
366
366
  try:
367
367
  with SpiDev() as dev:
368
- dev.open(0, 0)
369
368
  dev.max_speed_hz = 1_000_000
370
369
  dev.mode = 0
371
370
 
372
- for bpw in range(4, 17):
371
+ for bpw in (8, 16):
373
372
  dev.bits_per_word = bpw
373
+ dev.open(0, 0)
374
374
 
375
- if bpw <= 8:
376
- pattern = 0xAA & ((1 << bpw) - 1)
377
- else:
378
- pattern = 0xAAAA & ((1 << bpw) - 1)
375
+ mask = (1 << bpw) - 1
376
+ pattern = 0xAA if bpw <= 8 else 0xAAAA
377
+ pattern &= mask
379
378
 
380
379
  try:
381
380
  rx = dev.xfer2([pattern])
@@ -383,7 +382,8 @@ def bpw_test():
383
382
  except Exception as e:
384
383
  print(f"bpw={bpw:2d} tx={pattern:#06x} FAILED: {e}")
385
384
 
386
- time.sleep(0.1)
385
+ dev.close()
386
+ time.sleep(0.2)
387
387
 
388
388
  print("Done.")
389
389
  except RuntimeError as e:
@@ -46,14 +46,33 @@ class SpiDev:
46
46
 
47
47
  @bits_per_word.setter
48
48
  def bits_per_word(self, v):
49
- self._bits_per_word = int(v)
49
+ v = int(v)
50
+ # RP2040 PIO SPI only reliably supports 8 and 16 bit frames.
51
+ # Other values (4-7, 9-15) can trigger firmware DMA/PIO bugs.
52
+ if v not in (8, 16):
53
+ raise ValueError(
54
+ f"bits_per_word must be 8 or 16, got {v}. "
55
+ f"The Pico firmware does not support other frame sizes."
56
+ )
57
+ self._bits_per_word = v
50
58
 
51
59
  def open(self, bus=0, device=0):
52
- """No-op connection already open. For spidev compatibility."""
60
+ """Enable the SPI module. For spidev compatibility."""
61
+ self._conn.spi_enable()
62
+ self._configure()
53
63
  return self
54
64
 
55
65
  def close(self):
56
- pass # connection is shared, caller manages _conn.close()
66
+ """Disable the SPI module so the firmware releases its PIO/DMA state."""
67
+ try:
68
+ self._conn.spi_disable()
69
+ except Exception:
70
+ pass
71
+
72
+ def _configure(self):
73
+ """Sync current settings to the hardware."""
74
+ self._conn.spi_configure(self._mode, self._max_speed_hz,
75
+ self._bits_per_word)
57
76
 
58
77
  def xfer2(self, data):
59
78
  """Full-duplex transfer. Returns MISO data."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dln2
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Unified DLN2 driver — SPI, GPIO, I2C, ADC over a single USB connection. Originally developed for the Pico USB I/O Board.
5
5
  Home-page: https://github.com/syabyr/dln2_wrapper
6
6
  Author: IPM Group
@@ -187,6 +187,27 @@ python3 examples/adc_info.py
187
187
  | Multi-device | Manual USB enumeration | `list_devices()` |
188
188
  | Cross-module data flow | Impossible (4 echo counters) | Trivial (same counter) |
189
189
 
190
+ ## Pin Constraints
191
+
192
+ | Pins | Capability |
193
+ |---|---|
194
+ | 0–22, 26–28 | Full GPIO (input/output + events) |
195
+ | 23, 24, 29 | Output-only (reserved for SMPS / VBUS / VSYS) |
196
+ | 25 | Output-only (on-board LED) |
197
+ | ADC 0–2 | Map to GPIO 26, 27, 28 respectively |
198
+
199
+ ## Firmware Compatibility
200
+
201
+ | dln2 Python | Minimum firmware | Notes |
202
+ |---|---|---|
203
+ | 0.2.1 | [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) `>= v0.2` | SPI bpw validation, ADC pin-sharing fix |
204
+ | 0.2.0 | any | Works with all firmware versions |
205
+
206
+ To flash updated firmware:
207
+ 1. Hold the BOOTSEL button while connecting the Pico (or press and release RESET while holding BOOTSEL)
208
+ 2. Copy `dln2.uf2` to the `RPI-RP2` USB drive that appears
209
+ 3. The Pico reboots automatically with the new firmware
210
+
190
211
  ## Related
191
212
 
192
213
  - [pico-usb-io-board](https://github.com/syabyr/pico-usb-io-board) — RP2040 firmware
@@ -5,7 +5,7 @@ from setuptools import setup, find_packages
5
5
 
6
6
  setup(
7
7
  name="dln2",
8
- version="0.2.0",
8
+ version="0.2.1",
9
9
  description="Unified DLN2 driver — SPI, GPIO, I2C, ADC over a single USB connection. "
10
10
  "Originally developed for the Pico USB I/O Board.",
11
11
  long_description=open("README.md").read(),
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes