P2: conflict between Ethernet (W5500) and other SPI device (RFID card reader)

So, the saga continues…

Now I’ve got a P2 flashed, and the Ethernet W5500 seems to be working, when on its own (using SPI + D3/D4/D5).

My new issue seems to be that a conflict with an RFID card reader (SPI + pins cs=D18, irq=D11, rst=D12) appears when ethernet is working. From the code of the driver (MRFC522), it uses SPISettings on each transaction (at 4MHz), which seems a safe way to do that. I have no clue if the Ethernet driver also uses transaction, but I would assume so.

When I disable any access to the rfid driver (no init + no calls), everything works fine.

When using the rfid driver, app stalls (led freezes), before or after connection.

Any suggestion?

Quick note: the same setup was working fine on an Argon, with no stalling (different pins)

Ethernet uses SPI transactions around all operations for that reason.

Make sure your RFID library:

  • Uses SPI.beginTransction() and SPI.endTransaction() around all operations that use SPI
  • Make sure you set the CS line inside the begin/end block. That’s not the bug, it’s an easy mistake to make.
  • Does not disable interrupts using noInterrupts() before any SPI operations
  • Does not make any SPI calls within a SINGLE_THREADED_BLOCK or ATOMIC_BLOCK

The latter two are important because the system calls SPI from the system thread using the SPI transactions. The transactions use a mutex to keep other threads from accessing SPI, but do not disable interrupts. This also means that a thread swap can occur during a transaction.

If your code tries to beginTransaction() with interrupts or thread swapping disabled the application will deadlock if the system already is in a transaction because the system thread cannot be swapped in to release the mutex.


I just checked. All seems correct. Everything uses transactions, CS changes inside the transactions, no use of noInterrupts, and no SINGLE_THREADED or ATOMIC blocks.

The only thing that I could think of is, the RFID_CS uses the default D18 pin of the SPI bus. Is there any chance that the deviceOS implementation of the ethernet driver has some reference to D18 in, still? That would obviously mess up things, since the RFID driver could then be activated unwillingly…

So, I’ve done a bunch of different tests, and it always comes to the same, any time the ethernet is somehow accessed, it ends stalling. Is there a way to have the pieces of my code that access the card reader run on the system thread at specific times, if that makes any sense? Some type of callback from the system thread that could allow me to run some card reader stuff?

I was hoping to find a software way to fix the issue, but I’m starting to believe I’ll have to make use of the second SPI1…

By the way, how come the wiznet config default seems to set the SPI bus at 32MHz, when assumedly SPI on the p2 can only run at 25MHz?

So more tests (and time wasted…) trying to figure a solution to this issue.

I have the ethernet and the rfid reader working, but it ALWAYS stalls after this comm:

0000065195 [comm.coap] TRACE: Sending CoAP message
0000065218 [comm.coap] TRACE: CON 0.00  size=4 token= id=260

When the rfid gets accessed and before the corresponding receiving message (that never comes out)

So actually the Ethernet and system thread stall, not the RFID itself…

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.