I think sdfat code can be a good SPI bus citizen if it stores the SPCR bits 0 and 1 and SPSR bit 0 on chipSelectLow() and restores it in Sd2Card::chipSelectHigh().
I considered restoring SPI settings in SdFat but this is not the correct solution. I soon encountered a user with an LCD, ADC and SD on the SPI bus. It is not uncommon for three or more devices to be on the SPI bus. The only correct solution is for each library to set its SPI settings.
Ok. Thanks for that info. I understand what you are saying. I tried looking for an SPI protocol document but did not find one, but wikipedia did mention
To begin a communication, the bus master first configures the clock
, using a frequency less than or equal to the maximum frequency the slave device supports. Such frequencies are commonly in the range of 10 kHz–100 MHz.
I suppose that could be interpreted as on SPI initialization and not before each transmission (just like how it is done in Ethernet library). It mentioned there is a lack of SPI protocol standard. I looked at a couple SPI chip datasheet and I did not find any mention of initializing SPI bus before each transmission as a protocol requirement.
Anyway, I took your suggestion and added initialization code to the ethernet library. I am still testing it.
in setSS(), I added one of these (tried several clock setting)
SPCR &= 0xFC;SPSR |= 0x01;
//half speed, since Ethernet library uses this speed, I think this should be part of the code
SPCR &= 0xFC;SPSR &=0xFE;
SPCR = ((SPCR&0xFC) | 0x01);SPSR |= 0x01;
I still see the problem, so now I am thinking if it is a hardware (or hardware/software) issue.
What the program does is, I have an 8 channel relay that switches on and off, and I log the switching event to SD card. It appears like after the SD card write, the network connection drops (no problem on the SD card write). I can comment out the SD card write and the network does not drop. It does not happen all the time, maybe 10% of the time. For now, right after the SD card write, I make a network connection test, and if it fails, I call Ethernet.begin which brings up the ethernet again. I prefer to find the cause of this problem and fix it rather than use a workaround.