Go Down

Topic: SPI bus tristate problem (Read 1 time) previous topic - next topic


I am moving a project over from an Uno to a Due

However i have a problem because the SPI pins on the ICSP header are not tristating on boot

The device i am controlling needs me to keep my SPI bus tristate until I request permission via i2c to drive the bus

This works fine on the Uno as the SPI pins )10,11,12,13 are all tristate until I start the SPI library.

I can see on my scope that with the Due this is definitely not the case, plus my slave board will not boot/self test unless I disconnect the wires to the SPI bus

How do I resolve this (without adding an external bidirectional buffer)? Looking at the SAM3X datasheets there should not be a problem with tristate SPI I think



138 views.... does anyone have any input to this problem?



Apr 21, 2013, 02:55 am Last Edit: Apr 21, 2013, 02:57 am by Graynomad Reason: 1
Every MCU I've dealt with sets pins to inputs at powerup/reset and they stay that way until the program says otherwise. AFAIK the SAM does the same although I cannot find anywhere in the data sheet that spells that out.

How do you know the pins are driven, maybe they are pulled up?

EDIT: Just found it, the pins are set to inputs with the pullup enabled.

Rob Gray aka the GRAYnomad www.robgray.com


Apr 21, 2013, 02:39 pm Last Edit: Apr 21, 2013, 02:42 pm by dicky96 Reason: 1
I can see them clearly on my oscilloscope. MOSI is high and SCK is low (or vice versa, I can't remember without reconnecting everything) I need them tristate at first.

Also my slave device will not boot correctly unless i disconnect the SPI which is another proof of hte problem.  

On the Uno the slave device boots fine with SPI connected, I negotiate permission on i2c bus then can drive the SPI bus to load the device flash RAM no problem

I am using SPI pins on the ICSP header on the Due.  

On the Uno I use pins 10 11 12 13.  From what I read, the Due can't use 10-13 for SPI?



Right, the SPI pins can only be pulled from the "SPI" header (MOSI digital 75, MISO digital 74, SCLK digital 76).  The select lines supported are digital pins 4 and 10.  All these are 3.3 volt logic even though there is a 5 volt pin on the SPI header, apparently for legacy. The pinout diagram is at http://arduino.cc/forum/index.php/topic,132130.0.html

SPI "extended" function call documentation for Due is at http://arduino.cc/en/Reference/DueExtendedSPI  It would infer that the pin state is set in SPI.begin as that is when they can no longer be used for general I/O.

Are your pin numbers, select, and function calls all per above?  Are your logic lines ok with 3.3 volt signals?


I can see nowhere in the code that will do this, the pins should be inputs with PU resistors and therefore read as high with a scope. You can test to see if they driven or just pulled up with an external resistor, although if one is low that is not explained by the above.

Do you get the same behaviour with a blank sketch?

Rob Gray aka the GRAYnomad www.robgray.com


@thekitty. @greynomad
Thanks for the suggestions, I will investigate this a little further and get back to you shortly



OK guys I did a little more investigating

Firstly I can't test with a blank sketch as I don't actually if my slave device has booted properly unless i send some i2c commands to it

However the first thing my sketch does is wait for 10secs while the slave boots up so I think that can be eliminated as the SPI lines are already set hi/low according to my logic analyser

When i said I am using the ICSP header to connect the SPI, that is because it is marked as such on the protoshield. On the Due it is the 6 pin connector near the centre and marked SPI.  So that is the right one according to the image of the Due connectors posted above on this thread

I have now added an external tristate buffer to my Due, and I am controlling it via pin 7

At boot my sketch sets the tristate condition

If you look at the attached screenshot from my Logic16 (great toy by the way!) you can see

i2c SCL on chan 0
i2c SDA on Chan 1
MOSI, SCK, MISO and CS on 2 3 4 5 respectively.  These are monitoring the actual SPI bus on output of my external Tristate buffer (connected directly to the slave SPI bus)

Channel 6 shows MOSI on the SPI header of the Due
Channel 7 shows SCK on the SPI header of the Due

The sample shows conditions from boot up
You can see Slave MOSI and Slave SCK are high and Due MOSI (chan 6) is high and Due SCK (Chan 7 is Low)

The first communication on i2c initialises the slave

Slave MOSI and Slave SCK go low

Then follows 18 commands on i2c, each one you can see the processor on the slave board communicates to it's onboard graphics chips via SPI

This is only working because I added an external tristate buffer on the SPI bus!

On the 19th i2c command (the one with the green arrow) I request permission to control the SPI from the slaves onboard processor

You can see it grants permission (purple arrow) and releases the SPI bus to me

After a bit more chatting on the i2c bus I remove the tristate and start loading flash ram via SPI (red arow)

You can see that when I am not communicating on SPI, (right near the end of the sample) that MOSI is high and SCK is low.  However this is OK as I have control of the SPI bus

So that is proof of the problem - now how do I fix it other than adding external tristate hardware?

Best regards


Oh - PS
Even when I did all this, the damn slave will still not load the flash RAM.  However as soon as I connect my scope probe to SCK on the slave bus (output from my tristate buffer) everying works perfectly!!  What could be causing that? 

I have also noticed that 3.3V on my Due is actually 3.8V which may also be causing a problem as this slave device seems very intollerant.  Is that normal or is it faulty? I am powering Due via Programming USB port


Apr 26, 2013, 03:43 pm Last Edit: Apr 26, 2013, 03:45 pm by dicky96 Reason: 1
OK I sorted out to make this work without having my scope probe attached to the SCK line.  I had to add a 22pF cap on the SCK line to 0V, then it worked at various speeds but setClockDivider(64); seems particularly stable.  

I suspect this 'cludge' is due to different lengths of wire on MOSI and SCK on my handwired prototype

I've still no idea how to fix the tristate issue other than using external buffer like on my prototype.  

Please could some of the experts on here help resolve this, i'm just a beginner at this stuff guys.



Unfortunately I don't think there are many experts on the SAM here yet, personally I'm just reading data sheets so far and that behaviour cannot be explained from that as far as I can see.

Rob Gray aka the GRAYnomad www.robgray.com

Go Up