Explorar el Código

fix(spoolbuddy): tolerate SPI_NO_CS rejection on Pi 5 (#1424)

  Reporter on a Raspberry Pi 5 couldn't read NFC tags — gauge worked,
  SPI bus and wiring fine, but PN5180 transfers didn't complete.
  Manually commenting out `self._spi.no_cs = True` restored
  communication. Root cause: Pi 5's RP1 southbridge SPI driver
  (spi-rp1) doesn't honour the SPI_NO_CS ioctl the way the historical
  Broadcom driver on Pi 4 did.

  Safe to relax Pi-wide. SpoolBuddy's PN5180 NSS line is wired to
  GPIO23 (manual CS in _cs_low / _cs_high — the kernel's default
  auto-CS timing doesn't meet the PN5180's 5µs setup / 100µs hold
  spec). The hardware CE0 line (GPIO8) is not connected to the
  reader, so whether the kernel auto-toggles it is electrically
  invisible. The no_cs = True call was always cosmetic on this
  hardware.

  Wraps the assignment in try/except OSError in both the daemon and
  the diagnostic script; the daemon logs at debug level so future
  Pi-5-specific triage is greppable. README updated to drop the
  "spidev.no_cs = True resolves this" sentence and explain the
  manual GPIO23 CS scheme carries the timing on its own.
maziggy hace 1 semana
padre
commit
c1123365da
Se han modificado 4 ficheros con 21 adiciones y 4 borrados
  1. 0 0
      CHANGELOG.md
  2. 5 2
      spoolbuddy/README.md
  3. 8 1
      spoolbuddy/daemon/pn5180.py
  4. 8 1
      spoolbuddy/scripts/read_tag.py

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 0 - 0
CHANGELOG.md


+ 5 - 2
spoolbuddy/README.md

@@ -22,8 +22,11 @@
 
 
 > **NSS:** We use GPIO23 for manual chip-select instead of the default SPI CE0
 > **NSS:** We use GPIO23 for manual chip-select instead of the default SPI CE0
 > (GPIO8) because the kernel SPI driver's automatic CS timing does not meet the
 > (GPIO8) because the kernel SPI driver's automatic CS timing does not meet the
-> PN5180's requirements (5µs setup, 100µs hold). Manual CS via GPIO23 with
-> `spidev.no_cs = True` resolves this.
+> PN5180's requirements (5µs setup, 100µs hold). The reader's NSS line is wired
+> to GPIO23 only, so whether the kernel auto-toggles CE0 is electrically
+> invisible to the PN5180. Pi 4 and Pi 5 are both supported — the code asks
+> the driver to disable CE0 toggling but tolerates Pi 5's RP1 driver rejecting
+> that request (#1424).
 
 
 ### Setup Steps
 ### Setup Steps
 
 

+ 8 - 1
spoolbuddy/daemon/pn5180.py

@@ -121,7 +121,14 @@ class PN5180:
         self._spi.open(SPI_BUS, SPI_DEVICE)
         self._spi.open(SPI_BUS, SPI_DEVICE)
         self._spi.max_speed_hz = SPI_SPEED_HZ
         self._spi.max_speed_hz = SPI_SPEED_HZ
         self._spi.mode = 0b00
         self._spi.mode = 0b00
-        self._spi.no_cs = True
+        # #1424: Pi 5's RP1 spi-rp1 driver rejects SPI_NO_CS, which used to
+        # work on Pi 4. Harmless either way on this hardware — NSS is wired
+        # to GPIO23 (manual CS in _cs_low/_cs_high), so the kernel's CE0
+        # toggling has no electrical effect on the reader.
+        try:
+            self._spi.no_cs = True
+        except OSError as e:
+            logger.debug("spidev.no_cs not supported (likely Pi 5 RP1 driver): %s", e)
 
 
     def close(self):
     def close(self):
         self._spi.close()
         self._spi.close()

+ 8 - 1
spoolbuddy/scripts/read_tag.py

@@ -120,7 +120,14 @@ class PN5180:
         self._spi.open(SPI_BUS, SPI_DEVICE)
         self._spi.open(SPI_BUS, SPI_DEVICE)
         self._spi.max_speed_hz = SPI_SPEED_HZ
         self._spi.max_speed_hz = SPI_SPEED_HZ
         self._spi.mode = 0b00
         self._spi.mode = 0b00
-        self._spi.no_cs = True
+        # #1424: Pi 5's RP1 spi-rp1 driver rejects SPI_NO_CS, which used to
+        # work on Pi 4. Harmless either way on this hardware — NSS is wired
+        # to GPIO23 (manual CS in _cs_low/_cs_high), so the kernel's CE0
+        # toggling has no electrical effect on the reader.
+        try:
+            self._spi.no_cs = True
+        except OSError:
+            pass
 
 
     def close(self):
     def close(self):
         self._spi.close()
         self._spi.close()

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio