Odd behavior with Ethercard library

Why does pin D10 initialize "HIGH" on power up/reset?

I have a standalone ATMEG328 with an ENC28J60 connected to pin 13,12,11,8(CS) and a DS1307 to A4, A5 and and eight relays connected to the remaining pins. Everything works fine except for D10 which happen to have a relay on it driven by a pass transistor the same way as the other 7 relays. D10 initializes to HIGH on reset/power up! All the other pins stay low as expected. It will go low or high as instructed in the code without issue. It's on bootup that it is a problem. This isn't the result of my code, so I will try to explain in the next few test.

  1. I decide to explicitly set pin 10 low in setup but it still briefly blip high before going low as instructed in the code.
  2. I leave pin 10 out of the sketch all together, pin 10 still goes high on it's own
  3. Leaving ethercard out, I write a simple sketch to turn on and off all the relays one by one. Everything stays low on reset and work as expected. Hmmmm.
  4. Using the simple sketch in test 3 I added in ethercard library and initialize and assign a MAC and IP to the ENJ2860 and do nothing else with it. D10 goes high again. Looking like ethercard is the culprit
  5. I happened to have another project with the same setup but with two relays. One of the relays happens to be on D10 as well. Proceeded to apply test 1-4 from above with exact same result.
  6. Last and final straw. I cut the traces on the pcb and route pin D10 as the CS pin for the ENC28J60 and route pin D8 to the relay that use to be on D10. I specify pin D10 as CS "ether.begin(sizeof Ethernet::buffer, mymac, 10)" and everything works fine. Expecting that pin D8 or some other pin would go high now but nothing did. Happy to find a solution but puzzled.

Obviously I'm going to use pin 10 as CS from now on but I find this a bit odd since pin 8 is the default. From searching for an answer I know pin 10 use to be the CS pin for the ENC28J60 before ethercard came along so maybe something is buried in the code about pin 10. Anyone run into this issue before? or have a clue as to why?

This is normal.

To use the SPI hardware, the 'SS' pin must be set to output.
The 'SS' pin is digital pin 10.
The software is able to use 'SS' for ChipSelect, but can also use another pin.

That is what you have. You have another pin (pin 8 ) for ChipSelect, but the SPI hardware still requires that the 'SS' is set as output.

As far as I know this is for the ATmega328p, and I know it is the same for the Mega 2560 (SS is pin 53), but I'm not sure this is still required for the Arduino Leonardo.

I would suggest to use the 'SS' pin 10 as ChipSelect. Change the ethernet.begin() function and add a third parameter for the ChipSelect in your sketch.

if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
    Serial.println( "Failed to access Ethernet controller");

Do you use a bootloader and if yes, which one?

Were you able to measure how long D10 stays high before your code in setup sets it to low (this may give us a hint where to look for in the code)?

Probably the offending code is here:

void ENC28J60::initSPI () {
    pinMode(SS, OUTPUT);
    digitalWrite(SS, HIGH);
    pinMode(MOSI, OUTPUT);
    pinMode(SCK, OUTPUT);   
    pinMode(MISO, INPUT);
    
    digitalWrite(MOSI, HIGH);
    digitalWrite(MOSI, LOW);
    digitalWrite(SCK, LOW);

    SPCR = bit(SPE) | bit(MSTR); // 8 MHz @ 16
    bitSet(SPSR, SPI2X);
}

You can comment out the digitalWrite(SS, HIGH), without any problems and you may have solved your issue.

Erdin:
This is normal.

To use the SPI hardware, the 'SS' pin must be set to output.
The 'SS' pin is digital pin 10.
The software is able to use 'SS' for ChipSelect, but can also use another pin.

That is what you have. You have another pin (pin 8 ) for ChipSelect, but the SPI hardware still requires that the 'SS' is set as output.

As far as I know this is for the ATmega328p, and I know it is the same for the Mega 2560 (SS is pin 53), but I'm not sure this is still required for the Arduino Leonardo.

I would suggest to use the 'SS' pin 10 as ChipSelect. Change the ethernet.begin() function and add a third parameter for the ChipSelect in your sketch.

if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)

Serial.println( "Failed to access Ethernet controller");

Thanks for the explanation. I will use 10 as CS for ENC28J60 from now on. Easier/better route for the trace on my pcb template anyway.

pylon:
Do you use a bootloader and if yes, which one?

Were you able to measure how long D10 stays high before your code in setup sets it to low (this may give us a hint where to look for in the code)?

Probably the offending code is here:

void ENC28J60::initSPI () {

pinMode(SS, OUTPUT);
   digitalWrite(SS, HIGH);
   pinMode(MOSI, OUTPUT);
   pinMode(SCK, OUTPUT);  
   pinMode(MISO, INPUT);
   
   digitalWrite(MOSI, HIGH);
   digitalWrite(MOSI, LOW);
   digitalWrite(SCK, LOW);

SPCR = bit(SPE) | bit(MSTR); // 8 MHz @ 16
   bitSet(SPSR, SPI2X);
}




You can comment out the digitalWrite(SS, HIGH), without any problems and you may have solved your issue.

Bootloader is for the current UNO, whichever the Arduino IDE uses.

I don't have a way to precisely measure how long D10 stays high but it is long enough to light the LED and engage the relay that is on D10. You can see and hear it. LED is just status of the relay wired in parallel with the relay...typical stuff.

I tried your suggestion of commenting out "digitalWrite(SS, HIGH)" and that worked, Thanks! Tested on both board, one with CS on 8 and one with CS on 10 without any problem.

I don't understand things at that low of a level so my question is, will this have implications on a broader scope for future projects?

I don't understand things at that low of a level so my question is, will this have implications on a broader scope for future projects?

No, it shouldn't Setting pin 10 as an output is necessary for the hardware (it may go to slave mode otherwise) but also setting it HIGH is not necessary and just a precaution if other equipment is connected to the SPI bus and wired to the SS pin. But in this case the educated user is controlling all the slave select pins anyway so in my opinion is completely unnecessary.