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