Beginner TLC5940 SPI Woes

Hi all.
Ive just started getting into the arduino world and have a specific project in mind...but so far its not going too well!
Basically im wanting to control a single RGB 8x8 matrix via 2xTLC5940s and a single 595 shift register on the annodes (connected to transistors for the current).

My problem lies with the fact that i want to use SPI to control the shift register - and further down the road ill be wanting to add an SPI SD card reader to this project aswell - but no matter what ive tried i just cannot get it to work via my Arduino Uno.
I can control the TLC5940 via SPI on its own fine, and i can control the 595 register via SPI on its own fine, but together its a no go. From reading about it seems that the 5940 doesnt actually support proper SPI so instead it uses a bit of a 'hack' but in turn seems to allow nothing else to run properly? Is my understanding correct or has anyone actually managed to get a 595 AND the 5940 running together on SPI? I dont want to opt for this chip only to be hampered when it comes to adding other components that use SPI further down the road either.

If this is the case (or at least theres no easy option) im thinking of switching out the TLC's for a TPIC6B595 (basically just a high powered shift register and id need 3 of them) and using software PWM for the RGB colours.

What are your thoughts on this ? Any solutions or advice?

Cheers!
Carl.

It's all down to software.

Hacking the TLC5940 library to move the SPI stuff to different pins will be much easier than trying to do software PWM (especially if you want to read an SD card at the same time!)

Hint: Start by looking at "tlc_config.h"...

the config contains nothing that helps though?
you can change 2 digital pins for SPI in there (incidentally for features which i arent using) - the others are all seemingly totally locked down to fixed pins because of custom set timers etc?

correct me if im wrong - or if you have an example to show how to have this running on SPI at the same time as other SPI devices it'd be most helpful.

thanks,
Carl.

carlb007:
the config contains nothing that helps though?
you can change 2 digital pins for SPI in there (incidentally for features which i arent using) - the others are all seemingly totally locked down to fixed pins because of custom set timers etc?

If you move those 2 then SPI is freed up for your other devices. The locked-down ones aren't used for SPI.

Have you read this? http://flipmu.com/files/2011/04/Demystifying-the-TLC5940.pdf

Also are you using seperate CS (Chip Select) pins of the different chips?

Hi.
Yes ive read through the documentation and tried to understand it the best i can.
The document says:

Then add the pin de nitions that cannot be remapped due to the use of hardware features of the AVR, which are only available on certain pins:
#define SIN_DDR DDRB
#define SIN_PORT PORTB
#define SIN_PIN PB3
#define SCLK_DDR DDRB
#define SCLK_PORT PORTB
#define SCLK_PIN PB5
#define BLANK_DDR DDRB
#define BLANK_PORT PORTB
#define BLANK_PIN PB2

so basically it says that you cannot redefine pins 10,11,13 (ie the SPI pins). However because the TLC is using the digital out 10 for the blank pin and has no real slave select option im not sure how to progress or use it alongside any other device without interfering with it.
As i said im pretty new to all this so maybe im just missunderstanding something but i dont think i am. I can run multiple SPI devices (LCD + Shift registers) just not TLC + shift registers...

cheers,
Carl.

carlb007:
so basically it says that you cannot redefine pins 10,11,13 (ie the SPI pins). However because the TLC is using the digital out 10 for the blank pin and has no real slave select option im not sure how to progress or use it alongside any other device without interfering with it.

No. The only one you can't easily move is pin 10 because it's attached to a hardware timer (you could move it if you really want to but that's another story). 10 is the 'standard' SS pin for SPI but you don't need to use it, every SPI device needs a separate SS pin anyway.

11 and 13 can be moved, no problem (and it's a good idea to move them if you want to use SPI). There's some #defines in "tlc_config.h" that help you do it.

Hmm okay.

ive done a fair bit more reading on this now and have kinda progressed a little. I think i was getting thrown off because id read of issues using the ehternet shield with this chip and assumed that the same must be true here. Anyway moving on...
Ive managed to get this working with a single TLC and single 595 running just 2 of the colours on my RGB matrix. Im not too worried about the voltage output etc atm so im keeping them nice and dim just whilst i get this part up and running. Ive left my TLC on SS pin 10 (arduino uno) as is standard, and used all the reference pin outs for this. Ive connected my 595 via SPI to DigitalOutput pin 2 as SS.
I test this with the following:

byte patterns[30] = {
B10000000,
B01000000,
B00100000,
B00010000,
B00001000,
B00000100,
B00000010,
B00000001
};

void loop()
{
Tlc.set(8, 4000);
Tlc.set(9, 4000);
Tlc.set(10, 4000);
Tlc.set(11, 4000);
Tlc.set(12, 4000);
Tlc.set(13, 4000);
Tlc.set(14, 4000);
Tlc.set(15, 4000);
Tlc.update();
delay(1);

//Move ROW
digitalWrite(2, LOW);
SPDR = patterns

;
while (!(SPSR & _BV(SPIF))){}
digitalWrite(2, HIGH);
tt++;
if(tt>7){tt=0;}
}

So if i run this code i basically got a full column of 8 blue leds lit up. the shift register then moves on and lights up each of the rows in turn exactly as it should. However theres a small amount of flicker - which i assume is created by the delay i put in place.
However when i take that delay out all hell breaks loose with the matrix glowing red and blue and pulsing - almost as if the 595 data is ending up muddled in with the TLCs or something? i know i can replace the digitalWrite with the AVR code but is there something im missing? I cant figure it out. Ive tried delays with microseconds also but nothing seems stable.

Thanks all,
Carl.

Ah ha just found this in one of the other examples:

while (Tlc.update());

seems to have done the job almost spot on! I seem to have a bit of red colour leakage into the first row though even though all reds are turned off....

Had to get back up out of bed as this has done my head in heh!
So...the while thing didnt actually do the trick at all. It seems like i cant 'not' communicate to the TLC no matter what i try. i have the following in the loop of my code:

Tlc.clear();
Tlc.set(1, 10);
Tlc.set(14, 100);

while (Tlc.update());

//PORTD &= ~(1<<2);
digitalWrite(2, LOW); 
SPDR = B10101010;
digitalWrite(2, HIGH);
while (!(SPSR & _BV(SPIF)));

Digital 2 is connected to the SS of my 595 (but ive disconnected the LED annodes from it straight to the 5v line to test this). The TLC is still wired up exactly as per the library file (ive checked this more times than i can count).

If i take out my SPDR = B10101010 line the display works as expected. 2 rows of very dimly lit LEDs.
If i add it back in i get the 2 lines i want lit up but at 100% brightness, then a line either side of the 2 lit up dim - as if my attempted SPI data has nudged the TLC's or something.

Ive tried including an spi_init:

void spi_init(void) {
    pinMode(13, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(10, OUTPUT); /* Should be output in Master mode. */
    //  pinMode(2, OUTPUT);
    SPCR &= ~(_BV(DORD)); /* MSB first. */
    SPCR |= _BV(MSTR); /* Act as master. */
        SPCR |= _BV(SPIE);
}

but in the end took this out as it seems the TLC library already includes and sets this stuff up and makes no difference to the outcome.
If i add a delay(10) before my SPDR data theres no problem (aside from the fact id get insane amounts of flicker). As i reduce that delay i can steadily see the LED output becoming more random/corrupt to the point where at around delay(1) it appears okay for a half second and then flickers to the wrong columns being lit up.

really need some advice here :frowning: anyone encountered this before?? im all out of ideas and just cant see where im going wrong. Should i just bitbang the 595 register and be done with it? How much slower would this be?

Thanks,
Carl.