Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI.beginTransaction is called twice, locks up on ESP32 #53

Closed
robbi5 opened this issue Sep 25, 2018 · 6 comments
Closed

SPI.beginTransaction is called twice, locks up on ESP32 #53

robbi5 opened this issue Sep 25, 2018 · 6 comments

Comments

@robbi5
Copy link

robbi5 commented Sep 25, 2018

The begin function blocks itself, when SPI_HAS_TRANSACTION is defined and Hardware SPI is used.

In begin SPI.beginTransaction is called first at

SPI.beginTransaction(PN532_SPI_SETTING);

then sendCommandCheckAck is called which itself calles writecommand which tries to start another transaction with SPI.beginTransaction.
if (_hardwareSPI) SPI.beginTransaction(PN532_SPI_SETTING);

On an ESP32 with the arduino-esp32 framework the SPI.beginTransaction calls the spiTransaction function which uses an SPI_MUTEX_LOCK:

https://github.com/espressif/arduino-esp32/blob/1.0.0/cores/esp32/esp32-hal-spi.c#L702-L707

This combination of calling SPI.beginTransaction twice (in begin and writecommand) causes a hang on the second invocation, because the SPI_MUTEX_LOCK is never unlocked.


  • Arduino board: ESP32 w/ arduino-esp32 (tag: 1.0.0)

  • List the steps to reproduce the problem below (if possible attach a sketch or
    copy the sketch code in too):

#define SPI_HAS_TRANSACTION
#include <SPI.h>
#define PN532DEBUG
#include <Adafruit_PN532.h>

Adafruit_PN532 nfc(18);

void setup() {
  nfc.begin(); // see debug output, hangs at "Sending:" (no bytes after this message)
}
void loop() {
}
@ladyada
Copy link
Member

ladyada commented Sep 25, 2018

oof - can you try removing it from begin() does it work now?

@robbi5
Copy link
Author

robbi5 commented Sep 25, 2018

yep, then it doesn't hang anymore. now we're still figuring out why a timeout happens, but the locking problem is gone :)

@ladyada
Copy link
Member

ladyada commented Sep 25, 2018

ok can you submit a PR please :)

robbi5 added a commit to robbi5/Adafruit-PN532 that referenced this issue Sep 25, 2018
if SPI_HAS_TRANSACTION is used. Transaction already happens inside of sendCommandCheckAck. Fixes adafruit#53
@izedgo
Copy link

izedgo commented Feb 10, 2020

Why a PR is not accepted yet? I spent a lot of time to fix this :(

@factor8
Copy link

factor8 commented Feb 20, 2020

We are also running into this problem. Can we get @izedgo 's PR merged soon?

@ladyada
Copy link
Member

ladyada commented Feb 24, 2020

fixed in 1.2.0+

@ladyada ladyada closed this as completed Feb 24, 2020
Hutch67 added a commit to Hutch67/Adafruit_EPD that referenced this issue Dec 30, 2020
ESP32 uses a MUTEX to handle SPI transactions.
So calling beginTransaction twice in a row will block the device.
This happens in current code, if SRAM is used or a display (like 2,7" tricolor IL91874) which uses singleByteTxns = true
Both will call beginTransaction twice in a row and then the device will block for ever in
cores\esp32\esp32-hal-spi.h SPI_MUTEX_LOCK();

To prevent this, I made some changes in Adafruit_EPD.cpp
to track _isInTransaction properly, which was not used before.

See also adafruit/Adafruit-PN532#53 for a similar bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants