Skip to content

Ethernet software bug - SPI access & external interrupts [imported] #384

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

Closed
cmaglie opened this issue Nov 15, 2012 · 2 comments
Closed

Ethernet software bug - SPI access & external interrupts [imported] #384

cmaglie opened this issue Nov 15, 2012 · 2 comments
Labels
Library: Ethernet The Ethernet Arduino library
Milestone

Comments

@cmaglie
Copy link
Member

cmaglie commented Nov 15, 2012

This is Issue 384 moved from a Google Code project.
Added by 2010-10-21T12:39:08.000Z by akiba.fr...@gmail.com.
Please review that bug for more context and additional comments, but update this bug.

Original labels: Type-Defect, Priority-Medium

Original description

What steps will reproduce the problem?

  1. Use a library that has SPI access inside an ISR.
  2. Run the "Webserver" Ethernet example.
  3. Trigger the SPI interrupt on second device while webserver is running.

What is the expected output? What do you see instead?

The system hangs. The SPI data gets corrupted because both SPI buses are active at the same time. Since the SPI accesses aren't atomic, if an interrupt occurs before the SPI data register is read, its possible that the data will be changed after the ISR exits. There is also the issue of the Wiznet chip. If the chip is selected, then it does not properly release MISO which will corrupt any other device on the SPI. If an interrupt occurs while the Wiznet chip is being accessed, and there is an SPI access to a different chip, the access to the other chip will be corrupted because of a data collision on MISO.

What version of the Arduino software are you using? On what operating
system? Which Arduino board are you using?

Arduino IDE version 0021. Windows XP. Custom board.

Please provide any additional information below.

An example of a fix would be:

uint8_t W5100Class::read(uint16_t _addr)
{
// DISABLE INTERRUPTS
cli();

setSS();
SPI.transfer(0x0F);
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
uint8_t _data = SPI.transfer(0);
resetSS();

// ENABLE INTERRUPTS
sei();

return _data;
}

@matthijskooijman
Copy link
Collaborator

I've also ran into this issue, using an Arduino Ethernet combined with the RF22 shield. When an RF interrupt is received (causing some SPI reads and writes) during an Ethernet transfer, my Arduino would lock up.

The solution above would work, but is not perfect: If for some reason interrupts were already disabled, calling the read function would cause them to become enabled, with all the mess associated with that. Instead, it would be better to use the ATOMIC_BLOCK macro from util/atomic.h to save and restore the interrupt state.

I'll prepare a patch in a minute.

matthijskooijman added a commit to matthijskooijman/Arduino that referenced this issue Mar 26, 2013
When using the Ethernet library combined with another library that does
SPI access inside an interrupt handler, the Arduino could crash if that
interrupted occured while the Ethernet library was doing an SPI
transfer.

This commit makes all Ethernet SPI transfers happen atomically (i.e.,
with the global interrupt flag cleared), preventing such conflicts by
delaying all interrupts until after the SPI transfer.

Closes: arduino#384
@ffissore ffissore added the New label Feb 27, 2014
@cmaglie cmaglie removed the New label Feb 27, 2014
@cmaglie
Copy link
Member Author

cmaglie commented May 27, 2015

Fixed with SPI Transactions

@cmaglie cmaglie closed this as completed May 27, 2015
@cmaglie cmaglie added this to the Release 1.6.5 milestone May 27, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Library: Ethernet The Ethernet Arduino library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants