SPI Troubleshooting, Teensy, Arduino, and tri-state

I'm trying to get my SPI bus devices up and running on a custom circuit board that I've soldered together. Unfortunately, I neglected to add probe testing spots on this particular circuit board, and don't think I can directly test the SPI bus signals at the ICs. One is a 20 pin LED Current Sinking Driver in a SSOP package and the other is a microSD card holder.

I can't seem to get either device to work.

My MCU is a Teensy 3.1. (Arduino-compatible) In terms of firmware, I'm using Arduino v1.06 (highest version supported by Teensyduino), and Teensyduino V1.20. I'm using the SPI library/object for comms with the LED driver, and the SdFat library for comms with the sd card.

Here is the schematic of how my LED driver and SD card are hooked up:

According to the TLC59025 Datasheet, the timing diagram for communicating with the LED driver is as so:

My method of testing thus far, other than software (i.e. trying to open a file on the sd card), has been as follows:

• Made sure that the 3.3 V LDO serving the SD card was outputting correct voltage
• Attempted to begin serial comms with SD card using SdFat library (this was a no-go)
• Measured voltage at various LED Driver out pins, before and after sending two 8-bit words to the LED Driver's MOSI pin and pulsing LE high

If the particular LED output pin is latched and sinking current, then the voltage I measure at that pin should be near 0 V, correct?

My Master SPI clock speed is around 2 MHz. I know that the TLC59025 says it's operating point is 30 MHz. I thought that as long as the Master is using a SCK that is lower than the slave's clock, the comms would work. Am I wrong?

I thought that perhaps tri-state behaviour was to blame for my woes, however it looks like the TLC59025 LED Driver is designed to always be accepting data into it's shift register, even when it is not the intended slave being communicated with. It looks to me as though it is designed to simply latch the last 16 bits of data sent over the SPI MOSI bus whenever the LE pin is pulsed high.

I'm stumped as to how to proceed with troubleshooting. I know that the problem shouldn't be due to the MISO bus, since I only have one device (the SD card) hooked up on that bus. Could it be the MOSI bus? Is it possible that there is too much capacitance on the MOSI bus when I'm trying to communicate, thus degrading the data signal? If I add a tri-state buffer to the MOSI/CS signals on the SD card, and a pullup resistor on the chip select signal of the sd card, would that help maintain signal integrity on the MOSI bus (ie cut down capacitance of MOSI bus to the point that at least the LED driver should work?).

• Is there really really no way you can get a probe in there and look at it on a scope? Even if just one line at a time. It would make life so much easier. – Roger Rowland Mar 9 '15 at 12:47
• I have an oscilloscope coming in the mail today. I'll see what kind of probage I end up with. – macdonaldtomw Mar 9 '15 at 15:01

SD Card access is a fair bit more complicated because of the need to consider the FAT file system etc. So if I were you I would concentrate on getting the LED driver working first; at least then you know your SPI bus is working.

1. The voltage at the output of any LED output pin will be the voltage that is required to achieve the programmed constant current. It should not be 0V unless the outputs are set for maximum current. And it should not be the supply voltage unless the LED is supposed to be off.
2. The fact that the LED driver has an internal 30Mhz clock should not be of concern to you. Your device is the master, it controls the clock, and the slave should clock in the data based on the clock your master provides to it. The 30Mhz info is just useful in terms of appreciating the maximum speed you can push data through the device.

A few things to check:

You mention pulsing LE high, but you don't mention holding OE low to enable the LED outputs?

You need to make sure you've configured the master clock and data pins properly. I am not familiar with Arduino stuff so I can't help you with the specifics here, but there are various modes of SPI operation and you'll need to set up your device to match. You need to make sure you have the correct mode set up to output the data on the rising edge of the clock, with data sampled in the middle (for the LED driver - maybe it's different for the SD!).

Where is the chip-select pin on this device? Surely it has one? Couldn't see it on the supplied diagram. If there is no chip-select, how will you switch between data provided to the SD card and data provided to the LED driver? You'll need two SPI peripherals? Unless perhaps the LED driver is happy to just sit there receiving data, even if it isn't the intended recipient, and it's up to you to control the LE and OE pins when it is the intended recipient. It's worth just looking into this to clarify everything.

I'm not sure what is supposed to come out of the LED driver SDO pin? Are you using it?

How is SDI supposed to relate to LED outputs? I notice in the timing diagram SDI is high for bits 0, 2, 5, 10, 11, 12, and 15. But outputs 0, 3 and 15 are shown to respond with an 'ON' condition. Maybe this is explained elsewhere in the datasheet, because it doesn't seem to make any obvious sense from the timing diagram...

Good luck!

• Thanks for the response. To answer a few of the questions you had: -The SDO pin on the LED driver is for daisy-chaining LED drivers together. For example, if I added another of the same LED driver to the board and had the SDO pin of the first driver feed the second driver, I would effectively have a 32 bit LED driver -If you read the data bits backwards in the timing diagram, they correspond to the output status of the various output pins... i.e. bit 15 corresponds to output 1. -I can only assume that there is no slave select pin on this driver, instead it has a latch pin – macdonaldtomw Mar 9 '15 at 14:54
• Okay yep that makes sense. I would definitely concentrate on getting that LED driver working first. Divide and conquer, starting with the easiest first. – Brian J Hoskins Mar 9 '15 at 16:18
• Another thing: the voltage on the LED Driver's output pins should be high when the LED is off, since it is a current sinking driver. When you want the LED to turn on, the driver then changes its resistance on that pin until there is a user-defined current passing through it. So, therefore, I would assume that the resistance of an enabled pin would be zero when that pin is enabled without an actual LED attached (i.e. it would be the same as a short circuit to ground). Anyone see any flaws with that assumption? – macdonaldtomw Mar 9 '15 at 21:42
• Ah okay - in that case my answer still stands except that the 'off' condition is the opposite way around. The 'on' condition will still be whatever voltage is required to achieve the programmed CC. As you say, if no LED is connected then the output should drive all the way to '0V' in an attempt to achieve the constant current. I agree with your assessment of this. I hope you get this working! – Brian J Hoskins Mar 10 '15 at 6:55
• The path of least resistance here, for debugging, is to 'scope the clk/data lines and make sure that both the data and timing of the data is as you are expecting. – Brian J Hoskins Mar 10 '15 at 6:57

So, I got my oscilloscope in the mail, set it up, and managed to carefully hook the probes to the Teensy 3.1 MCU pins related to SPI and my LED driver (i.e. SCK pin and MOSI pin).

I appears as though the problem is with the SPI library that I was using.

The MOSI pin wasn't going high for the second byte when I tried to write two consecutive bytes to the driver. I could set the outputs of pins 8-15 on the LED driver to be activated, however I couldn't seem to get the MOSI pin to go high during the second byte write.

I was able to overcome the problem by adding a delay of about 10 ms between the two byte writes.

I was able to further optimize the speed (so that I wouldn't have to wait for 10 ms between byte writes) by using the SPI.beginTransaction() and SPI.endTransaction() methods of the SPI class.

By wrapping each byte transfer in these transactional methods, I was able to get the LED driver up and running. Here's the type of code structure that ended up working for me:

SPI.beginTransaction(LEDDriverSettings);
SPI.transfer(firstByte);
SPI.endTransaction();
SPI.beginTransaction(LEDDriverSettings);
SPI.transfer(secondByte);
SPI.endTransaction();