Go Down

Topic: SPI.end() causes SPI.transfer() to hang even after a new SPI.begin() (Read 1 time) previous topic - next topic

camt

It appears that something SPI.end() changes isn't being reset by SPI.begin() on the Due. As a result, if SPI.end() is used to disable SPI, it can't be re-enabled later in the program. A simplified example is shown below.

This sequence works:
Code: [Select]

SPI.begin();
SPI.transfer(0);


This sequence hangs on the Due, but works on other Arduino boards:
Code: [Select]

SPI.end();
SPI.begin();
SPI.transfer(0);

stimmer

I can confirm this. (The problem seems to be that SPI.end() calls SPI_Disable(), but SPI.begin doesn't call SPI_Enable() - it's called in the constructor.)

To fix this: open the file hardware/arduino/sam/libraries/SPI/SPI.cpp and at the beginning of the SPIClass::begin() method add the line
SPI_Enable(spi);
The method should now look like this:
Code: [Select]
void SPIClass::begin() {
       SPI_Enable(spi);
       // NPCS control is left to the user

       // Default speed set to 4Mhz
       setClockDivider(BOARD_SPI_DEFAULT_SS, 21);
       setDataMode(BOARD_SPI_DEFAULT_SS, SPI_MODE0);
       setBitOrder(BOARD_SPI_DEFAULT_SS, MSBFIRST);
}


I've added this issue to the Arduino github here: https://github.com/arduino/Arduino/issues/1406
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

camt

Thanks. That fixes the problem. Is there somewhere else I should be posting this to make sure this fix gets into the SPI release version?

stimmer

I've already reported the issue in the official place and as it's a simple one-liner I expect it will get fixed pretty soon.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

PeterVH

I am using the old AVR compatible api's.
I can confirm the above work around works for me too.

But after calling SPI.end(), I want to tristate SCK and MOSI. How do I do that? I tried adding
Code: [Select]

pinMode(MOSI, INPUT);
pinMode(SCK, INPUT);

But after that SPI.begin() does not work anymore.
I dare not configuring them as output before calling SPI.begin() because I noticed that SPIClass::begin() does not have code in it to do so, that is probably done for a reason.

stimmer

Does it work if you add the line:
Code: [Select]
SPI_Configure(spi, id, SPI_MR_MSTR | SPI_MR_PS | SPI_MR_MODFDIS); immediately before each call to SPI.begin(); ?
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

PeterVH

Almost, the initcb() (which is SPI_0_Init()) has to be called too.
Thanks!

cmaglie

Merged the fix upstream:

https://github.com/arduino/Arduino/commit/d101bf51a2c9ebe08be737dd9b5db8b32d64e44a

C
C.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy