Yes, you can get SPI bus contention when using multiple SPI slave devices. It is up to you, the designer, to ensure that each SPI slave device has its chip select (CS or SS) asserted only when no other devices are driving MISO. Normally that is achieved by:
- initialize all of the CS pins high (inactive) during setup
- in the code that accesses SPI device #1,
- assert SPI device #1 CS1 low (active)
- perform SPI transfers on SPI device #1
- release SPI device #1 CS1 high (inactive)
- in the code that accesses SPI device #2,
- assert SPI device #2 CS2 low (active)
- perform SPI transfers on SPI device #1
- release SPI device #2 CS2 high (inactive)
SPI bus contention can also occur during device programming (loading the bootloader or firmware image), if there is an attached SPI slave device, and its chip select (SS) is not pulled inactive by a pullup resistor.
I had a problem with this on one of my designs a few weeks ago. I was trying to burn the bootloader into some blank ATmega328-AU chips post-assembly, and my device programmer wasn't able to successfully program the chips because my one slave device had its chip select connected only to an ATmega328 pin.
I had previously breadboarded this design using an Arduino Pro Mini board, and it was working fine; but when I moved to first prototype PCB there was bus contention on MISO -- the blank ATmega328 wasn't driving the slave device's chip select high or low, but it floated low (active), causing MISO contention.
My solution (workaround) was temporarily contacting the chip-select to VDD 3.3V through a 10kohm resistor. This made my SPI slave device inactive, allowing the device programmer to successfully load the bootloader.
I think there would be no harm in leaving the pullup resistor on chip select (since it's an active-low signal), but it was only really necessary when using the device programmer. After I had the prototype boards initialized with the bootloader image, I was subsequently able to load firmware images as usual.
(One minor unrelated issue was that my assembler purchased ATmega328-AU when I had specified ATmega328P-AU -- they are almost the same, and it doesn't make a difference for my application, but it was annoying that I had to use a slightly different command line argument than then one I used with the Arduino Pro Mini board.)
This means that all the data pins go low
. They don't go LOW, but high impedance input.