Hi,
I am literally pulling out my hair as I cannot seem to find why the TLC5955(datasheet) is not working.
I have an Arduino Mega ADK connected to the TLC5955 using the SPI interface.
The TLC5955 has a ridiculous 769 bit main register that must be written... I find this ridiculous as it is not a multiple of 8bits(byte). It is 96bytes and 1bit.
Non the less, my first assumption is that if I write 97bytes per SPI transaction the 7leading bits will fall out and be irrelevant.
So i create the Control Data Latch information, and write it once.
Then I write the Grayscale Data latch every second with all LEDs to Full.
I've been observing random flashes from the LEDs connected to the TLC5955 and not expected continuous full brightness.
Please can someone look at my code and advise on potential issues. I really appreciate your feedback.
My code:
#include "SPI.h" // necessary library
byte cdlFill[1] = {0x00}; //5bits used
byte cdlDC[48]; //7bits used
byte cdlMC[3]; //3bits used
byte cdlBC[3]; //7bits used
byte cdlFC[1]; //5bits used
byte GSDL[96];
byte CDL[47];
byte CDLbuffer[48];
byte counter = 0;
byte mode_cd = 0xFF; //FF=CD
byte mode_gs = 0x00; //00=GS
byte modecdl = 0x96; //mode must be FF followed by 96 for control data.
SPISettings settingsA(1000000, MSBFIRST, SPI_MODE0);
//need to create the Control Data sequence in the required format
void combine_cdl() {
int arrayPosCDL=0;
int arrayPosFill=0;
int arrayPosDC=0;
int arrayPosMC=0;
int arrayPosBC=0;
int arrayPosFC=0;
//append the 0 fill values to CDL
for (int bitPos=0;bitPos<5;bitPos++) {
arrayPosCDL = bitPos/8;
arrayPosFill = (bitPos-0)/5;
bitWrite(CDL[arrayPosCDL], 7-bitPos%8, bitRead(cdlFill[arrayPosFill], 4-((bitPos-0)%5)));
}
//append the DC values to CDL
for (int bitPos=5;bitPos<341;bitPos++) {
arrayPosCDL = bitPos/8;
arrayPosDC = (bitPos-5)/7;
bitWrite(CDL[arrayPosCDL], 7-bitPos%8, bitRead(cdlDC[arrayPosDC], 6-((bitPos-5)%7)));
}
//append the MC values to CDL
for (int bitPos=341;bitPos<350;bitPos++) {
arrayPosCDL = bitPos/8;
arrayPosMC = (bitPos-341)/3;
bitWrite(CDL[arrayPosCDL], 7-bitPos%8, bitRead(cdlMC[arrayPosMC], 2-((bitPos-341)%3)));
}
//append the BC values to CDL
for (int bitPos=350;bitPos<371;bitPos++) {
arrayPosCDL = bitPos/8;
arrayPosBC = (bitPos-350)/7;
bitWrite(CDL[arrayPosCDL], 7-bitPos%8, bitRead(cdlBC[arrayPosBC], 6-((bitPos-350)%7)));
}
//append the FC values to CDL
for (int bitPos=371;bitPos<376;bitPos++) {
arrayPosCDL = bitPos/8;
arrayPosFC = (bitPos-371)/5;
bitWrite(CDL[arrayPosCDL], 7-bitPos%8, bitRead(cdlFC[arrayPosFC], 4-((bitPos-371)%5)));
}
}
void writeCDL(){
SPI.beginTransaction(settingsA);
digitalWrite(SS, LOW);
//set mode bit high
SPI.transfer(mode_cd);
if( mode_cd < 0x10){ Serial.print("0");} Serial.print(mode_cd,HEX);
//TLC5955 Datasheet pg17 bits 767 to 760 must be 0x96
SPI.transfer(modecdl);
if( modecdl < 0x10){ Serial.print("0");} Serial.print(modecdl,HEX);
for (int i=0; i < 48; i++){
SPI.transfer(CDLbuffer[i]); //write out some 00s to "pad" the register
if( CDLbuffer[i] < 0x10){ Serial.print("0");} Serial.print(CDLbuffer[i],HEX);
}
for (int i=0; i < 47; i++){
SPI.transfer(CDL[i]); //write out the configured CDL data
if( CDL[i] < 0x10){ Serial.print("0");} Serial.print(CDL[i],HEX);
}
Serial.println();
digitalWrite(SS, HIGH);
SPI.endTransaction();
}
void setup() {
//I want to enable serial comms for deugging via ide.
Serial.begin (115200); // serial: Typical Rates, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200
Serial.println ("\nDebugging Session On...\n");
//Initialise all variable to some predefined level.
for (int i=0; i < 96; i++){
GSDL[i] = 0xFF; //All LEDs Full on
}
//Set the configuration byes
for (int i=0; i < 47; i++){
CDL[i] = 0x00;
}
for (int i=0; i < 48; i++){
CDLbuffer[i] = 0x00; //Padding reqired to get the Control Data into the full Data register
}
for (int i=0; i < 48; i++){
cdlDC[i] = 0x20; //set DC halfway
}
for (int i=0; i < 3; i++){
cdlMC[i] = 0x04; //set MC halfway
}
for (int i=0; i < 3; i++){
cdlBC[i] = 0x40; //set BC halfway
}
cdlFC[0] = 0x10; //auto display repeat
combine_cdl();
//Initialise MISO,SS,SCK as an output
pinMode(MISO, OUTPUT);
pinMode(SS, OUTPUT);
pinMode(SCK, OUTPUT);
//Need to generate a clock signal for GSCLK. (Using following 5 lines we should get a 1MHz Clock on pin 11 (OC1A Pin))
pinMode(11, OUTPUT); //set OC1A/PB1 as output
TCCR1A = _BV(COM1A0); //toggle OC1A on compare match
OCR1A = 7; //top value for counter
TCCR1B = _BV(WGM12) | _BV(CS10); //CTC mode, prescaler clock/1
SPI.begin();
delay(500);
writeCDL(); //Setup the TLC5955 once.
delay(500);
}
void loop() {
SPI.beginTransaction(settingsA);
digitalWrite(SS, LOW);
SPI.transfer(mode_gs);
if( mode_gs < 0x10){ Serial.print("0");}Serial.print(mode_gs,HEX); //prints to serial monitor value with leading 0
for (int i=0; i < 96; i++){
SPI.transfer(GSDL[i]);
if( GSDL[i] < 0x10){ Serial.print("0");}Serial.print(GSDL[i],HEX); //prints to serial monitor value with leading 0
}
Serial.println();
digitalWrite(SS, HIGH);
SPI.endTransaction();
delay(1000);
}
Here is the initial snip of my Serial Monintor:
Debugging Session On...
FF960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204081020408102040810204081020408102040810204081020408102040810204081020408102040810492040810
00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF