Using the Arduino Ethernet Shield R3 e.g. on an Due you may/will run in the following fault:
(Arduino 1.5.6-r2 BETA with the standard libs.)
The Problem:
With the bug I could run the SD-card and the Ethernet separately, but curiously not on calling shortly one after the other.
I found the bug when I checked the CS signals with a scope.
The Reason:
Ethernet access:
Pin 102 (PC29) (!) AND (!) pin 111 (PA28) of the controller is connected to pin 10(ETH-CS) of the board connector.
The Arduino Due system software maps the two pins of the controller to the logical pins 10 and 77. The user starts
the Ethernet access via "Ethernet.begin(...)", that calls "W5100.init();" and "SPI.begin(SPI_CS);" where "SPI_CS = 10".
Nothing is done with pin 77.
SD-card access:
Pin 137 (PC26) (!) AND (!) pin 112 (PA29) of the controller is connected to pin 4(SD-CS) of the board connector.
The Arduino Due system software maps the two pins of the controller to the logical pins 4 and 87.
The user starts the SD-card access via "SD.begin(4)" using the logical pin 4 only. Nothing is done with pin 87.
Pin 77 and pin 87 are not controlled by any of the drivers. Both pins must be initialised properly on startup.
Initialisation of the Controller SAM3X8E:
In the file "variant.h" line 58 and "variant.cpp" line 382:
// Disable pull-up on every pin
for (int i = 0; i < PINS_COUNT; i++) // with "#define PINS_COUNT (79u)"
digitalWrite(i, LOW);
Pin 77 (ETH-CS) is initialized as Output low !!!
Pin 87 (SD-CS) looks not to be initialized on startup and at all !!!
Pin 77 initialized to low causes an CS output for the Ethernet W5100 between zero and around 1.65V.
The W5100 chip requires a minimum high signal of 2 volt as noted in the data sheet.
Pin 87 may be output LOW or HIGH or may be an INPUT or INPUT_PULLUP:
- If output LOW it would never reach a valid low signal.
- If output HIGH it would never reach a valid high signal.
- If INPUT or INPUT_PULLUP it will work properly.
(In addition, if one of the CS signals is low, the other must be high to disable the other device.
And on startup, all devices on the SPI bus must be disabled to keep them inactive.)
The Fix:
Do a proper initialisation in "variant.cpp". Set all above four pins to INPUT_PULLUP.
With this fix, nothing is to do within the SPI, SD, Ethernet driver.
A Workaround:
Add the following code at the very beginning:
void setup()
{
pinMode(SDPinCS,INPUT_PULLUP); // SD Pin 4
pinMode(SDPinCS2,INPUT_PULLUP); // SD Pin 87
pinMode(EthPinCS,INPUT_PULLUP); // Eth Pin 10
pinMode(EthPinCS2,INPUT_PULLUP); // Eth Pin 77
.....
}
Stability and Benchmarks:
With this patch I got my application running very well and with speeds of:
- WrToWebIf(4830byte)=30ms -- Transfer via the WebDuino interface using a 14MHz clock on the SPI bus
- FilesReadBin: "CMOS.cfg" (Read=56byte): 3ms -- time from open to close: using the default 42MHz clock
(The speed for SD-card access varies significantly depending on the SD-card. The first access may take
longer. With one of my SD-cards I got sometimes around 2 seconds for a mkdir. I think it is
a hardware problem of this SD-card.)
How many users may be affected by this problem?
Some users will see that their application work, others will see that it is instable, a very few will see
dependencies with boards, temperature, or runtime. I am sure a lot of users will give up.
But nobody can give a true answer how many this are, but a lot.
And as I could see, the Arduino development team is working on the SPI driver.
But they are looking for different things.