I am up and running.
Huzzah!
still confused with the difference between SS and CS
People underestimate the importance of hardware signal naming and software variable and function naming.
I shall try to overcome some unfortunate similarities and confusion caused by the fact that for the "genuine" Ethernet Shield the designers chose to use Arduino pin 10 for the "Chip Select." That is not, by any means, a bad design choice, but it's not the only choice they could have made.
"SS" refers to "Slave Select" function of the SPI interface inside the ATMega328p.
When the SPI port is initialized, the "SS" functionality is unavoidably hardwired inside the ATmega328p to Arduino pin 10. This sets the mode of the SPI interface. When the SPI interface is initialized, by writing to certain registers in the SPI interface, if the "SS" pin has been previously set to OUTPUT mode, the SPI interface will be operating in Master mode (that's what we want: we need to be the Master).
If the "SS" pin ever gets changed to INPUT mode (or if it was left at its default INPUT mode after being powered up) and if the input value is LOW, then the SPI interface inside the ATmega328p switched to Slave mode. Automatically. Inescapably. We don't want that. So, we will keep the "SS" pin in the OUTPUT mode for the duration of any sketch that uses the Ethernet Shield.
Now, after the SPI interface has been initialized with the "SS" pin in OUTPUT mode, the "SS" pin can be set to any output state you want. In other words, good old pin 10 can be used for any output function that you want. (It can be just left alone if you don't need it for anything.) The only thing that you can't do is to set pin 10 to the INPUT mode and let the value go LOW.
Now...
For every SD device that we want to control, there are three common signals used by all of them: MOSI, MISO, SCK. These are ATmega328p I/O pins corresponding to Arduino pins 11, 12, and 13. These functions take over in place of the normal I/O functions on these pins. When the SPI interface is initialized, Arduino pins 11, 12, and 13 are unavoidably connected to these three SPI signals. When a program writes or reads SPI data registers, these signals automatically perform their magic to shift the data.
Now, for every SPI device there are four signals that control SPI data transfer: The MOSI, MSIO and SCK signals and another signal that I call the "Chip Select." Each SPI device has its own "Chip Select" signal. A "Chip Select" signal can use any Arduino pin except for ones that have already been committed to other functions. So, in particular the "Chip Select" signal for a SPI device can not be pin 11, 12, or 13. If your sketch uses the Hardware UART for data transfer, that function uses Arduino pins 0 and 1, so neither of those pins can be used for a SPI device "Chip Select." Etc.
The Ethernet library reads and writes to the SPI registers to cause data transfer into or out of the SPI port in the following sequence:
-
It calls a function named setSS() to put the Ethernet Shield "Chip Select" pin in proper state (LOW, as it happens) to perform SPI operations on the Ethernet Shield.
-
It does some other SPI register stuff to set up things to read or write and to fire off the serial transfer.
-
It calls a function named resetSS() to put the "Chip Select" pin in proper state (HIGH) to tell the Ethernet Shield to stay off of the SPI bus.
Those functions are actually macros defined in w5100.h and they do direct bit write operations to the pin that is used for the Ethernet Shield "Chip Select".
For the "genuine" Ethernet Shield, the designers decided to use Arduino pin 10 for the "Chip Select." Remember? After the SPI port is initialized, we are allowed to use pin 10 for any output function we want. They wanted to use it for the Ethernet "Chip Select." Fair enough.
On the Arduino Duemilanove, Arduino pin 10 is wired (on the PC board) to bit 2 of the ATMega328p Port B, so setSS() and resetSS() cause that bit to go to zero or one. The macros use direct port bit manipulation instead of the Arduino core function digitalWrite() because direct port bit writing is faster.
If you want to use another pin for your Ethernet "Chip Select" that's OK, but you have to change those functions to use whatever bit on whatever port your board's designers have chosen.
Your Shield uses Arduino Pin 4.
Well...
On the Duemilanove, Arduino Pin 4 is connected to bit 4 of the ATmega328p Port D, so the changes that I showed will result in that pin being brought low and high by the other library functions to effect the SPI bus transfer.
The other function (macro) that depends on which pin you are using for "Chip Select" is initSS(). This function is used when the device is first initialized (by Ethernet.begin()) so that when the SPI port is first initialized, the "Chip Select" pin will be in the inactive state. (It's actually the same as resetSS().)
All of the actual choreography of the sequence of signal changes required to read and write to the SPI bus are taken care of by the Ethernet library functions, out of the sight of the application sketch programmer.
People who use "genuine" Arduino Duemilanove boards and "genuine" Ethernet Shield boards never have to know all of this stuff, and, indeed, many others are happy to have someone give a cookbook approach to whatever changes are required to "make it work." (See Footnote.)
Some of us like to try actually to understand some of the magic. We're funny that way.
Bottom lines:
-
Leave the "SS" definition in arduino_pins.h alone! It is fixed to a particular CPU pin for a given CPU. The 1280 uses a different port and pin for the SPI "SS", so that's why there is a conditional (#ifdef) that lets the program know which is going to be used.
-
Change definitions of initSS(), setSS(), and resetSS() to use the ATmega328p port and pin that is connected to your Ethernet Shield's "Chip select" pin.
-
Sit back and enjoy the ride.
Regards,
Dave
Footnote:
"Pay no attention to that man behind the curtain."
---The Wizard of Oz