tlc5940 programming problems.

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|

tlc5940 programming problems.

bob_shaftenkluger
Hi.
I have been trying to get a msp430f2012 to control some leds connected to a tlc5940. I have come up with the following code, which seems like it is almost working. The leds light up, and they flicker so I guess the pwm is sort of working. I think the problem is that I am not clocking in the data correctly.
Here is the code, I hope someone here can help me fix it!
Thanks.



//////////////////////////////////////////////
//pinouts bobolobobob
//  tlc5940   f2012
//
//   gsclck=  p1.0  /  P1OUT ^= 0x01
//   xlat  =  p1.1  /  P1OUT ^= 0x02
//   blank =  p1.2  /  P1OUT |= 0x04
//   sclck =  p1.5  /  sclck
//   sin   =  p1.6  /  sdo


//////////////////////////////////////////////

#include <msp430x20x2.h>
volatile unsigned int pants;                  //for testing stuff
volatile unsigned int inputcount;             //counter for input array index. not yet used, included for future
volatile unsigned int outputcount;            //counter for outputarry index
volatile unsigned int inputarray[16];          //input array, not yet used
volatile unsigned int outputarray[16];         //output array buffer thingy
volatile unsigned int converted;              //converted to 12bit from whatever


volatile unsigned int gscnt;
volatile unsigned int firstcyc;




void smeg(void)
{
   if (gscnt != 8191)// give blank pulse after every 4096 .
   {
     gscnt = gscnt +1;
   //start clcok here
     
   }
  else
  {
   TACTL = TASSEL_2 + ID_3 + MC_0;                  //stop gsclk
   // P1OUT ^= 0x04; // test
   P1OUT |= 0x04; // blank on
   //xlat high
   P1OUT |= 0x02; //xlat on
   P1OUT &= ~0x02;// xlat off
   
   ////////////////////////////////////////
   //193rd clock pulse, less than optimal...
   if (firstcyc != 0)
   {
     ///pulse p1.5
     P1DIR |= 0x1F;
      P1OUT |= 0x10; //sclk on
   P1OUT &= ~0x10;// sclk off
   P1DIR |= 0x07;
   firstcyc =0;
   }  
   
   //////////////////////////////////////
   
   
   
   //xlat low
   P1OUT &= ~0x04;//blank  off
    gscnt = 0;// reset counter
    ///start next transfer
     TACTL = TASSEL_2 + ID_3 + MC_1;                  //restart gsclk
     outputcount = 0;                       //  reset output counter
     USICTL0 &= ~USISWRST;                 // USI released for operation
    USICNT = USI16B | 12; //seems rather vulgar way of setting 16bit, but including at top doesnt work
  }
}






void transmit(void)
{
 
  converted = outputarray[outputcount] * 16;
  USISR = converted;
 
 
 
  ///////////////////////////
   //attempt at making look nicer. Working i think????.
  if (outputcount != 15)// deliberatly too high to give nice stable trace on scope.
  {
    outputcount = outputcount +1;
   USICNT = USI16B | 12; //seems rather vulgar way of setting 16bit, but including at top doesnt work
  }
  else{
    //outputcount = 0;
     USICTL0 |= USISWRST;                 // USI locked?
   
    //P1OUT |= 0x02; //xlat on
   //P1OUT &= ~0x02;// xlat off
   
   ////
   //start gs clock here? NNNNNNNNNNOOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!
   //TACTL = TASSEL_2 + ID_3 + MC_1;                  // SMCLK, upmode  (this starts clock?)
  }
  ///////////////////////////
 
 
}




void main(void)
{
  BCSCTL1 = CALBC1_16MHZ; // Calibrated range for DCO
  DCOCTL = CALDCO_16MHZ; // Calibrated tap and modulation
  volatile unsigned int i;
 

  WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer
  //P1OUT =  0x10;                        // P1.4 set, else reset
  P1DIR |= 0x07;                          // P1.0 P1.1 P1.2 output
   //P1DIR |= 0x1f;                          // P1.0 P1.1 P1.2 output
  //P1REN |= 0x10;                        // P1.4 pullup
  //P1DIR = 0x01;                         // P1.0 output, else input
  USICTL0 |= USIPE7 +  USIPE6 + USIPE5 + USIMST + USIOE; // Port, SPI master
  //USICTL0 |= USIPE6 + USIPE5 + USIMST + USIGE + USIOE; // Port, SPI master, added usige, to correct gap between bits,

doesnt seem to work
  //USICNT |= USI16B;
// USICTL1 |= USICKPH + USIIE;                
  USICTL1 |= USIIE;                     // Counter interrupt, flag remains set
  USICKCTL = USIDIV_4 + USISSEL_2;// +USICKPL;      // /64 SMCLK for 250khz
 
  firstcyc =1;
   //////////// test data, because  the input stage isnt progrAammed yet.
  outputarray [0]=0;
  outputarray [1]=4095;
  outputarray [2]=4095;
  outputarray [3]=0;
  outputarray [4]=4095;
  outputarray [5]=0;
  outputarray [6]=4095;
  outputarray [7]=0;
  outputarray [8]=4095;
  outputarray [9]=0;
  outputarray [10]=4095;
  outputarray [11]=0;
  outputarray [12]=4095;
  outputarray [13]=0;
  outputarray [14]=4095;
  outputarray [15]=0;

  ////////////////////////////////////////////////////////////////////////
 
 
 
  CCTL0 = CCIE;                             // CCR0 interrupt enabled
  CCR0 = 4;
  TACTL = TASSEL_2 + ID_1 + MC_1;                  // SMCLK, upmode (moved.......)
  USICTL0 &= ~USISWRST;                 // USI released for operation
 
 
 
 
 
 
 
 
 
 
  //P1DIR |= 0x04;                        // Reset Slave
  //P1DIR &= ~0x04;
 
 
  _BIS_SR(LPM0_bits + GIE);             // Enter LPM0 w/ interrupt
}




//// USI interrupt service routine
#pragma vector=USI_VECTOR
__interrupt void universal_serial_interface(void)
{
   
  transmit();
 
  //USICNT = USI16B | 12; //seems rather vulgar way of setting 16bit, but including at top doesnt work
}






// Timer A0 interrupt service routine
///////////////////////////////////////////////////////////
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  P1OUT ^= 0x01;                            // Toggle P1.0
  //P1OUT |= 0x01; // toggle gsclock
  //P1OUT &= ~0x01;//
 // gscnt = gscnt +1;
 
  smeg();
 
 
}






Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
I guess no-one could be bothered to decypher my terrible code..
If somebody could tell me what the USIGE, USICKPH, and USICKPL bits should be set to, it would help me very much. I tried the settings that my interpretation of the datasheets suggested, the ones that looked right on my scope, and various other combinations, no luck. It may well be that I am misunderstanding the datasheets, as what I would expect to see often does not correspond to what the scope says. (Of course, this could be due to the fact that my scope was due to be calibrated in 1993, and behaves in many bizare ways)
I am also confused about the 193rd clock pulse that may or may not be needed. slvc106, shows that the extra clock pulse is only needed for the first cycle, however the datasheet for the tlc5940 shows a 193rd pulse for each cycle.

Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

Augusto E K Einsfeldt
Bob,
It has been a long time since my last try with TLC5940. It is a nice chip.
I cannot help on these bits but I think I can help regarding the TLC.
The 193rd clock is necessary when the device will output a status information.
It happen just after BLANK goes low. The device needs an extra clock because it outputs
the data in the clock´s rising edge and waiting for the clock for GS2 MSB on SIN would
shift the whole status.
So, after each BLANK->low you must insert one extra clock to synch the status reading.
Hope it helps...

-Augusto


On Qui 27/08/09 22:35 , "bob_shaftenkluger" [hidden email] sent:

> I guess no-one could be bothered to decypher my terrible code..
> If somebody could tell me what the USIGE, USICKPH, and USICKPL bits
> should be set to, it would help me very much. I tried the settings
> that my interpretation of the datasheets suggested, the ones that
> looked right on my scope, and various other combinations, no luck. It
> may well be that I am misunderstanding the datasheets, as what I would
> expect to see often does not correspond to what the scope says. (Of
> course, this could be due to the fact that my scope was due to be
> calibrated in 1993, and behaves in many bizare ways)
> I am also confused about the 193rd clock pulse that may or may not
> be needed. slvc106, shows that the extra clock pulse is only needed
> for the first cycle, however the datasheet for the tlc5940 shows a
> 193rd pulse for each cycle.
>                    
>

Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

bartoegema
It looks like to me in the TLC5940 data sheet that it's operating in
what is similar to SPI mode 0 - serial clock idle low, and the data
latched in on the rising edge of the clock.

USICKPH = 1 (data is captured on the first UCLK edge and changed on
the following edge)
USICKPL = 0 (inactive state is low)

I'm not positive for the USIGE bit because I've never used this
particular interface or the TLC5940, but I think you want to leave it
cleared, having the data latched out with the clock.

- Bart

On Thu, Aug 27, 2009 at 7:02 PM, Augusto Einsfeldt<[hidden email]> wrote:

>
>
> Bob,
> It has been a long time since my last try with TLC5940. It is a nice chip.
> I cannot help on these bits but I think I can help regarding the TLC.
> The 193rd clock is necessary when the device will output a status
> information.
> It happen just after BLANK goes low. The device needs an extra clock because
> it outputs
> the data in the clock´s rising edge and waiting for the clock for GS2 MSB on
> SIN would
> shift the whole status.
> So, after each BLANK->low you must insert one extra clock to synch the
> status reading.
> Hope it helps...
>
> -Augusto
>
> On Qui 27/08/09 22:35 , "bob_shaftenkluger" [hidden email]
> sent:
>
>> I guess no-one could be bothered to decypher my terrible code..
>> If somebody could tell me what the USIGE, USICKPH, and USICKPL bits
>> should be set to, it would help me very much. I tried the settings
>> that my interpretation of the datasheets suggested, the ones that
>> looked right on my scope, and various other combinations, no luck. It
>> may well be that I am misunderstanding the datasheets, as what I would
>> expect to see often does not correspond to what the scope says. (Of
>> course, this could be due to the fact that my scope was due to be
>> calibrated in 1993, and behaves in many bizare ways)
>> I am also confused about the 193rd clock pulse that may or may not
>> be needed. slvc106, shows that the extra clock pulse is only needed
>> for the first cycle, however the datasheet for the tlc5940 shows a
>> 193rd pulse for each cycle.
>>
>>
>
>
Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
Thanks guys.
This is turning out to be an absolute nightmare..
I think I need to start again. The interupts are making it hard for me to understand the flow of the program, so I will try writing it without them.

Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
Can somebody give me a sugestion of what to use for the gsclk signal? I was thinking timer A would be suitable, but I seem to be going round in circles trying to write a program. I figured there are two ways of doing this...
1-- Use timer a to count the 4096 gsclk pulses.  Output the smclk through p1.4 to the pin on the tlc5940. Use the scg1 bit to switch off and after the 4096 pulses, then back on after latching the gs data. I tried this, and had a few problems. The first one, which is inconveniant, but perhaps not too much of a problem, is that single stepping with IAR, the smclk seems to run even when my software has turned it off. The other problem, is that the smclk output seems to be active low, and I can find nothing in the documentation to change that.

2-- Use timer A to count each individual pulse, for example 24 smclk pulses for each gsclk, and use a software counter to check if it has reached 4096 yet. The problem with this is that I cannot figure out how to maintain the correct timing while also using a software counter to count the 16 blocks of greyscale data.

Basicly I can't figure out how program two things at once. Maybe its my inexperience with C. Maybe it was too many years programming Basic.


Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

old_cow_yellow
You could just use bit-banging to generate gsclk. If P1.4 is set up for gsclk, simply do:

for (int n = 4096; n>0; n--) {
P1OUT |= BIT4;
P1OUT &= ~BIT4;
}

I do not know if you did successfully store data in GS and DC Registers or not. How did you accomplish loading those Registers? What are the pin assignments? Also, how are the LEDs physically arranged?  What kind of visual patterns are you trying to show?

I read the TLC5940 data-sheet today. Maybe I can help you now. If you can program F2012 in assembly, it would be easier for me to understand you. But if you have to use c, it is okay too. Just do NOT put any comments -- they often make it harder for me.

--- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@...> wrote:
>
> Can somebody give me a sugestion of what to use for the gsclk signal? I was thinking timer A would be suitable, but I seem to be going round in circles trying to write a program. I figured there are two ways of doing this...
> 1-- Use timer a to count the 4096 gsclk pulses.  Output the smclk through p1.4 to the pin on the tlc5940. Use the scg1 bit to switch off and after the 4096 pulses, then back on after latching the gs data. I tried this, and had a few problems. The first one, which is inconveniant, but perhaps not too much of a problem, is that single stepping with IAR, the smclk seems to run even when my software has turned it off. The other problem, is that the smclk output seems to be active low, and I can find nothing in the documentation to change that.
>
> 2-- Use timer A to count each individual pulse, for example 24 smclk pulses for each gsclk, and use a software counter to check if it has reached 4096 yet. The problem with this is that I cannot figure out how to maintain the correct timing while also using a software counter to count the 16 blocks of greyscale data.
>
> Basicly I can't figure out how program two things at once. Maybe its my inexperience with C. Maybe it was too many years programming Basic.
>


Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
I used the spi to put the data into the tlc5940 registers, I think it is getting transfered properly. The pin conections are included in the code.
At the moment the leds are just stuck into my proto board to test. I am not trying to show any particular patern, just trying to figure out how to get the chip to work. Ultimatly I hope to send data from a pc serial port with this program--
http://blogger.xs4all.nl/loosen/articles/408184.aspx
I have a uart to spi chip to handle the comunication with the pc.
Programming in assembly is not really an opton for me as I'm rubish at it. Here my current attempt at the program, with comments removed.



#include <msp430x20x2.h>

int main( void )

{

  WDTCTL = WDTPW + WDTHOLD;                

  P1DIR |= 0xFF;                            

  CCTL0 = CCIE;                              

  volatile unsigned int FKSRCNT;                    

  volatile unsigned int GSBLKCNT;                  

  volatile unsigned int CONVERTED;        

  volatile unsigned int PWAIT;              

  volatile  int TESTGSDATA[16]={0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0};

     

  //These comments left in to show how I have the pins connected

  P1OUT &= ~0x10;  //GSCLK    = P1.4 = low

  P1OUT &= ~0x20;  //FAKESCLK = P1.5 = low

  P1OUT &= ~0x08;  //DCPRG    = P1.3 = low

  P1OUT |= 0x01;   //VPRG     = P1.0 = high

  P1OUT &= ~0x02;  //XLAT     = P1.1 = low

  P1OUT |= 0x04;   //BLANK    = P1.2 = high

  P1OUT &= ~0x40;  //FAKESERIAL P1.6 = low

  P1OUT &= ~0x08;//set dcprg low

  P1OUT &= ~0x01;//set vprg low

 FKSRCNT =0;

  while (FKSRCNT !=192)

  {

   

    P1OUT |= 0x20;       //FAKESCLK high

    P1OUT &= ~0x20;     //FAKESCLK low

    FKSRCNT = FKSRCNT + 1;

  }

  P1SEL |= 0x10;                            

  USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE;

  USICTL1 |= USICKPH;  

  USICKCTL = USIDIV_0 + USISSEL_2;

  USICTL0 &= ~USISWRST;                

  CCTL0 = CCIE;                            

  CCR0 = 4095;                

  _BIS_SR(SCG1);              

 while (1)

 {

    _BIS_SR(SCG1);

   P1OUT |= 0x04;  

   P1OUT |= 0x02;  

   P1OUT &= ~0x02;  

   GSBLKCNT = 0;

   PWAIT = 0;

   

   P1OUT &= ~0x04;  

   

   TACTL = TASSEL_2 + ID_0 + MC_1;

   _BIC_SR(SCG1);

   while (GSBLKCNT !=15)

   {

     CONVERTED = TESTGSDATA[GSBLKCNT] << 4;

     USISR = CONVERTED;                      

     USICNT = USI16B | 12;

     while (PWAIT != 20)

       PWAIT = PWAIT + 1;

     }

     PWAIT = 0;

     GSBLKCNT = GSBLKCNT +1;

   }

  _BIS_SR(LPM0_bits + GIE);                  

 }

}











#pragma vector=TIMERA0_VECTOR

__interrupt void Timer_A (void)

{

   _BIS_SR(SCG1);              

   TACTL = TASSEL_2 + ID_0 + MC_0;

   //_BIC_SR(LPM0_bits );                

   _BIC_SR_IRQ(LPM0_bits);                



}

Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

old_cow_yellow
I do not think your code reflects what the data-sheet says. Do you have any other references?

Anyway, I took a shoot in the dark and have the following:

#include <msp430.h>

#define VPRG  BIT0
#define XLAT  BIT1
#define BLANK BIT2
#define DCPRG BIT3
#define GSCLK BIT4
#define SCLK  BIT5
#define SIN   BIT6

const char dc[16]=
{63,63,63,63, 63,63,63,63, 63,63,63,63, 63,63,63,63};

const int gs[16]=
{0,4095,4095,4095, 4095,4095,4095,4095,
4095,4095,4095,4095, 4095,4095,4095,0};

void main (void)
{//0
WDTCTL = WDTPW | WDTHOLD;

P1OUT = DCPRG | BLANK | VPRG;
P1DIR = 0xFF;

for (int n=16; n>0; n--)
{//1
int dcn = dc[n-1];
for (int b=6; b>0; b--)
{//2
if (dcn & BIT5) P1OUT |= SIN; else P1OUT &= ~SIN;
dcn = dcn << 1;
P1OUT |= SCLK;
P1OUT &= ~SCLK;
}//2
}//1

P1OUT |= XLAT;
P1OUT &= ~XLAT;

P1OUT &= ~VPRG;

while (1)
{//1a
for (int n=16; n>0; n--)
{//2a
int gsn = gs[n-1];
for (int b=12; b>0; b--)
{//3a
if (gsn & BITB) P1OUT |= SIN;
else P1OUT &= ~SIN;
gsn = gsn << 1;
P1OUT |= SCLK;
P1OUT &= ~SCLK;
}//3a
}//2a

P1OUT |= XLAT;
P1OUT &= ~XLAT;

P1OUT &= ~BLANK;

for (int p=4096; p>0; p--)
{//2c
P1OUT |= GSCLK;
P1OUT &= ~GSCLK;
}//2c

P1OUT |= BLANK;
}//1a
}//0

--- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@...> wrote:

>
> I used the spi to put the data into the tlc5940 registers, I think it is getting transfered properly. The pin conections are included in the code.
> At the moment the leds are just stuck into my proto board to test. I am not trying to show any particular patern, just trying to figure out how to get the chip to work. Ultimatly I hope to send data from a pc serial port with this program--
> http://blogger.xs4all.nl/loosen/articles/408184.aspx
> I have a uart to spi chip to handle the comunication with the pc.
> Programming in assembly is not really an opton for me as I'm rubish at it. Here my current attempt at the program, with comments removed.
>
>
>
> #include <msp430x20x2.h>
>
> int main( void )
>
> {
>
>   WDTCTL = WDTPW + WDTHOLD;                
>
>   P1DIR |= 0xFF;                            
>
>   CCTL0 = CCIE;                              
>
>   volatile unsigned int FKSRCNT;                    
>
>   volatile unsigned int GSBLKCNT;                  
>
>   volatile unsigned int CONVERTED;        
>
>   volatile unsigned int PWAIT;              
>
>   volatile  int TESTGSDATA[16]={0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0};
>
>      
>
>   //These comments left in to show how I have the pins connected
>
>   P1OUT &= ~0x10;  //GSCLK    = P1.4 = low
>
>   P1OUT &= ~0x20;  //FAKESCLK = P1.5 = low
>
>   P1OUT &= ~0x08;  //DCPRG    = P1.3 = low
>
>   P1OUT |= 0x01;   //VPRG     = P1.0 = high
>
>   P1OUT &= ~0x02;  //XLAT     = P1.1 = low
>
>   P1OUT |= 0x04;   //BLANK    = P1.2 = high
>
>   P1OUT &= ~0x40;  //FAKESERIAL P1.6 = low
>
>   P1OUT &= ~0x08;//set dcprg low
>
>   P1OUT &= ~0x01;//set vprg low
>
>  FKSRCNT =0;
>
>   while (FKSRCNT !=192)
>
>   {
>
>    
>
>     P1OUT |= 0x20;       //FAKESCLK high
>
>     P1OUT &= ~0x20;     //FAKESCLK low
>
>     FKSRCNT = FKSRCNT + 1;
>
>   }
>
>   P1SEL |= 0x10;                            
>
>   USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE;
>
>   USICTL1 |= USICKPH;  
>
>   USICKCTL = USIDIV_0 + USISSEL_2;
>
>   USICTL0 &= ~USISWRST;                
>
>   CCTL0 = CCIE;                            
>
>   CCR0 = 4095;                
>
>   _BIS_SR(SCG1);              
>
>  while (1)
>
>  {
>
>     _BIS_SR(SCG1);
>
>    P1OUT |= 0x04;  
>
>    P1OUT |= 0x02;  
>
>    P1OUT &= ~0x02;  
>
>    GSBLKCNT = 0;
>
>    PWAIT = 0;
>
>    
>
>    P1OUT &= ~0x04;  
>
>    
>
>    TACTL = TASSEL_2 + ID_0 + MC_1;
>
>    _BIC_SR(SCG1);
>
>    while (GSBLKCNT !=15)
>
>    {
>
>      CONVERTED = TESTGSDATA[GSBLKCNT] << 4;
>
>      USISR = CONVERTED;                      
>
>      USICNT = USI16B | 12;
>
>      while (PWAIT != 20)
>
>        PWAIT = PWAIT + 1;
>
>      }
>
>      PWAIT = 0;
>
>      GSBLKCNT = GSBLKCNT +1;
>
>    }
>
>   _BIS_SR(LPM0_bits + GIE);                  
>
>  }
>
> }
>
>
>
>
>
>
>
>
>
>
>
> #pragma vector=TIMERA0_VECTOR
>
> __interrupt void Timer_A (void)
>
> {
>
>    _BIS_SR(SCG1);              
>
>    TACTL = TASSEL_2 + ID_0 + MC_0;
>
>    //_BIC_SR(LPM0_bits );                
>
>    _BIC_SR_IRQ(LPM0_bits);                
>
>
>
> }
>


Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
Ha, you make it look so simple.
The code you posted works well, but I had to increase the clock speed.  It flashes horibly otherwise.
Thanks.
--- In [hidden email], "old_cow_yellow" <old_cow_yellow@...> wrote:

>
> I do not think your code reflects what the data-sheet says. Do you have any other references?
>
> Anyway, I took a shoot in the dark and have the following:
>
> #include <msp430.h>
>
> #define VPRG  BIT0
> #define XLAT  BIT1
> #define BLANK BIT2
> #define DCPRG BIT3
> #define GSCLK BIT4
> #define SCLK  BIT5
> #define SIN   BIT6
>
> const char dc[16]=
> {63,63,63,63, 63,63,63,63, 63,63,63,63, 63,63,63,63};
>
> const int gs[16]=
> {0,4095,4095,4095, 4095,4095,4095,4095,
> 4095,4095,4095,4095, 4095,4095,4095,0};
>
> void main (void)
> {//0
> WDTCTL = WDTPW | WDTHOLD;
>
> P1OUT = DCPRG | BLANK | VPRG;
> P1DIR = 0xFF;
>
> for (int n=16; n>0; n--)
> {//1
> int dcn = dc[n-1];
> for (int b=6; b>0; b--)
> {//2
> if (dcn & BIT5) P1OUT |= SIN; else P1OUT &= ~SIN;
> dcn = dcn << 1;
> P1OUT |= SCLK;
> P1OUT &= ~SCLK;
> }//2
> }//1
>
> P1OUT |= XLAT;
> P1OUT &= ~XLAT;
>
> P1OUT &= ~VPRG;
>
> while (1)
> {//1a
> for (int n=16; n>0; n--)
> {//2a
> int gsn = gs[n-1];
> for (int b=12; b>0; b--)
> {//3a
> if (gsn & BITB) P1OUT |= SIN;
> else P1OUT &= ~SIN;
> gsn = gsn << 1;
> P1OUT |= SCLK;
> P1OUT &= ~SCLK;
> }//3a
> }//2a
>
> P1OUT |= XLAT;
> P1OUT &= ~XLAT;
>
> P1OUT &= ~BLANK;
>
> for (int p=4096; p>0; p--)
> {//2c
> P1OUT |= GSCLK;
> P1OUT &= ~GSCLK;
> }//2c
>
> P1OUT |= BLANK;
> }//1a
> }//0
>
> --- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@> wrote:
> >
> > I used the spi to put the data into the tlc5940 registers, I think it is getting transfered properly. The pin conections are included in the code.
> > At the moment the leds are just stuck into my proto board to test. I am not trying to show any particular patern, just trying to figure out how to get the chip to work. Ultimatly I hope to send data from a pc serial port with this program--
> > http://blogger.xs4all.nl/loosen/articles/408184.aspx
> > I have a uart to spi chip to handle the comunication with the pc.
> > Programming in assembly is not really an opton for me as I'm rubish at it. Here my current attempt at the program, with comments removed.
> >
> >
> >
> > #include <msp430x20x2.h>
> >
> > int main( void )
> >
> > {
> >
> >   WDTCTL = WDTPW + WDTHOLD;                
> >
> >   P1DIR |= 0xFF;                            
> >
> >   CCTL0 = CCIE;                              
> >
> >   volatile unsigned int FKSRCNT;                    
> >
> >   volatile unsigned int GSBLKCNT;                  
> >
> >   volatile unsigned int CONVERTED;        
> >
> >   volatile unsigned int PWAIT;              
> >
> >   volatile  int TESTGSDATA[16]={0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0};
> >
> >      
> >
> >   //These comments left in to show how I have the pins connected
> >
> >   P1OUT &= ~0x10;  //GSCLK    = P1.4 = low
> >
> >   P1OUT &= ~0x20;  //FAKESCLK = P1.5 = low
> >
> >   P1OUT &= ~0x08;  //DCPRG    = P1.3 = low
> >
> >   P1OUT |= 0x01;   //VPRG     = P1.0 = high
> >
> >   P1OUT &= ~0x02;  //XLAT     = P1.1 = low
> >
> >   P1OUT |= 0x04;   //BLANK    = P1.2 = high
> >
> >   P1OUT &= ~0x40;  //FAKESERIAL P1.6 = low
> >
> >   P1OUT &= ~0x08;//set dcprg low
> >
> >   P1OUT &= ~0x01;//set vprg low
> >
> >  FKSRCNT =0;
> >
> >   while (FKSRCNT !=192)
> >
> >   {
> >
> >    
> >
> >     P1OUT |= 0x20;       //FAKESCLK high
> >
> >     P1OUT &= ~0x20;     //FAKESCLK low
> >
> >     FKSRCNT = FKSRCNT + 1;
> >
> >   }
> >
> >   P1SEL |= 0x10;                            
> >
> >   USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE;
> >
> >   USICTL1 |= USICKPH;  
> >
> >   USICKCTL = USIDIV_0 + USISSEL_2;
> >
> >   USICTL0 &= ~USISWRST;                
> >
> >   CCTL0 = CCIE;                            
> >
> >   CCR0 = 4095;                
> >
> >   _BIS_SR(SCG1);              
> >
> >  while (1)
> >
> >  {
> >
> >     _BIS_SR(SCG1);
> >
> >    P1OUT |= 0x04;  
> >
> >    P1OUT |= 0x02;  
> >
> >    P1OUT &= ~0x02;  
> >
> >    GSBLKCNT = 0;
> >
> >    PWAIT = 0;
> >
> >    
> >
> >    P1OUT &= ~0x04;  
> >
> >    
> >
> >    TACTL = TASSEL_2 + ID_0 + MC_1;
> >
> >    _BIC_SR(SCG1);
> >
> >    while (GSBLKCNT !=15)
> >
> >    {
> >
> >      CONVERTED = TESTGSDATA[GSBLKCNT] << 4;
> >
> >      USISR = CONVERTED;                      
> >
> >      USICNT = USI16B | 12;
> >
> >      while (PWAIT != 20)
> >
> >        PWAIT = PWAIT + 1;
> >
> >      }
> >
> >      PWAIT = 0;
> >
> >      GSBLKCNT = GSBLKCNT +1;
> >
> >    }
> >
> >   _BIS_SR(LPM0_bits + GIE);                  
> >
> >  }
> >
> > }
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > #pragma vector=TIMERA0_VECTOR
> >
> > __interrupt void Timer_A (void)
> >
> > {
> >
> >    _BIS_SR(SCG1);              
> >
> >    TACTL = TASSEL_2 + ID_0 + MC_0;
> >
> >    //_BIC_SR(LPM0_bits );                
> >
> >    _BIC_SR_IRQ(LPM0_bits);                
> >
> >
> >
> > }
> >
>


Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

old_cow_yellow
If you replace the lines:

//for (int p=4096; p>0; p--)
//{//2c
//P1OUT |= GSCLK;
//P1OUT &= ~GSCLK;
//}//2c

by the lines:

__asm
(
" bis.b #0x01,&0x0026\n"
" mov.w #1363,R15\n"
" dec.w R15\n"
" jnz $-2\n"
" nop\n"
" bic.b #0x01,&0x0026"
);

You will not need to increase the clock speed

--- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@...> wrote:

>
> Ha, you make it look so simple.
> The code you posted works well, but I had to increase the clock speed.  It flashes horibly otherwise.
> Thanks.
> --- In [hidden email], "old_cow_yellow" <old_cow_yellow@> wrote:
> >
> > I do not think your code reflects what the data-sheet says. Do you have any other references?
> >
> > Anyway, I took a shoot in the dark and have the following:
> >
> > #include <msp430.h>
> >
> > #define VPRG  BIT0
> > #define XLAT  BIT1
> > #define BLANK BIT2
> > #define DCPRG BIT3
> > #define GSCLK BIT4
> > #define SCLK  BIT5
> > #define SIN   BIT6
> >
> > const char dc[16]=
> > {63,63,63,63, 63,63,63,63, 63,63,63,63, 63,63,63,63};
> >
> > const int gs[16]=
> > {0,4095,4095,4095, 4095,4095,4095,4095,
> > 4095,4095,4095,4095, 4095,4095,4095,0};
> >
> > void main (void)
> > {//0
> > WDTCTL = WDTPW | WDTHOLD;
> >
> > P1OUT = DCPRG | BLANK | VPRG;
> > P1DIR = 0xFF;
> >
> > for (int n=16; n>0; n--)
> > {//1
> > int dcn = dc[n-1];
> > for (int b=6; b>0; b--)
> > {//2
> > if (dcn & BIT5) P1OUT |= SIN; else P1OUT &= ~SIN;
> > dcn = dcn << 1;
> > P1OUT |= SCLK;
> > P1OUT &= ~SCLK;
> > }//2
> > }//1
> >
> > P1OUT |= XLAT;
> > P1OUT &= ~XLAT;
> >
> > P1OUT &= ~VPRG;
> >
> > while (1)
> > {//1a
> > for (int n=16; n>0; n--)
> > {//2a
> > int gsn = gs[n-1];
> > for (int b=12; b>0; b--)
> > {//3a
> > if (gsn & BITB) P1OUT |= SIN;
> > else P1OUT &= ~SIN;
> > gsn = gsn << 1;
> > P1OUT |= SCLK;
> > P1OUT &= ~SCLK;
> > }//3a
> > }//2a
> >
> > P1OUT |= XLAT;
> > P1OUT &= ~XLAT;
> >
> > P1OUT &= ~BLANK;
> >
> > for (int p=4096; p>0; p--)
> > {//2c
> > P1OUT |= GSCLK;
> > P1OUT &= ~GSCLK;
> > }//2c
> >
> > P1OUT |= BLANK;
> > }//1a
> > }//0
> >
> > --- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@> wrote:
> > >
> > > I used the spi to put the data into the tlc5940 registers, I think it is getting transfered properly. The pin conections are included in the code.
> > > At the moment the leds are just stuck into my proto board to test. I am not trying to show any particular patern, just trying to figure out how to get the chip to work. Ultimatly I hope to send data from a pc serial port with this program--
> > > http://blogger.xs4all.nl/loosen/articles/408184.aspx
> > > I have a uart to spi chip to handle the comunication with the pc.
> > > Programming in assembly is not really an opton for me as I'm rubish at it. Here my current attempt at the program, with comments removed.
> > >
> > >
> > >
> > > #include <msp430x20x2.h>
> > >
> > > int main( void )
> > >
> > > {
> > >
> > >   WDTCTL = WDTPW + WDTHOLD;                
> > >
> > >   P1DIR |= 0xFF;                            
> > >
> > >   CCTL0 = CCIE;                              
> > >
> > >   volatile unsigned int FKSRCNT;                    
> > >
> > >   volatile unsigned int GSBLKCNT;                  
> > >
> > >   volatile unsigned int CONVERTED;        
> > >
> > >   volatile unsigned int PWAIT;              
> > >
> > >   volatile  int TESTGSDATA[16]={0,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,4095,0};
> > >
> > >      
> > >
> > >   //These comments left in to show how I have the pins connected
> > >
> > >   P1OUT &= ~0x10;  //GSCLK    = P1.4 = low
> > >
> > >   P1OUT &= ~0x20;  //FAKESCLK = P1.5 = low
> > >
> > >   P1OUT &= ~0x08;  //DCPRG    = P1.3 = low
> > >
> > >   P1OUT |= 0x01;   //VPRG     = P1.0 = high
> > >
> > >   P1OUT &= ~0x02;  //XLAT     = P1.1 = low
> > >
> > >   P1OUT |= 0x04;   //BLANK    = P1.2 = high
> > >
> > >   P1OUT &= ~0x40;  //FAKESERIAL P1.6 = low
> > >
> > >   P1OUT &= ~0x08;//set dcprg low
> > >
> > >   P1OUT &= ~0x01;//set vprg low
> > >
> > >  FKSRCNT =0;
> > >
> > >   while (FKSRCNT !=192)
> > >
> > >   {
> > >
> > >    
> > >
> > >     P1OUT |= 0x20;       //FAKESCLK high
> > >
> > >     P1OUT &= ~0x20;     //FAKESCLK low
> > >
> > >     FKSRCNT = FKSRCNT + 1;
> > >
> > >   }
> > >
> > >   P1SEL |= 0x10;                            
> > >
> > >   USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE;
> > >
> > >   USICTL1 |= USICKPH;  
> > >
> > >   USICKCTL = USIDIV_0 + USISSEL_2;
> > >
> > >   USICTL0 &= ~USISWRST;                
> > >
> > >   CCTL0 = CCIE;                            
> > >
> > >   CCR0 = 4095;                
> > >
> > >   _BIS_SR(SCG1);              
> > >
> > >  while (1)
> > >
> > >  {
> > >
> > >     _BIS_SR(SCG1);
> > >
> > >    P1OUT |= 0x04;  
> > >
> > >    P1OUT |= 0x02;  
> > >
> > >    P1OUT &= ~0x02;  
> > >
> > >    GSBLKCNT = 0;
> > >
> > >    PWAIT = 0;
> > >
> > >    
> > >
> > >    P1OUT &= ~0x04;  
> > >
> > >    
> > >
> > >    TACTL = TASSEL_2 + ID_0 + MC_1;
> > >
> > >    _BIC_SR(SCG1);
> > >
> > >    while (GSBLKCNT !=15)
> > >
> > >    {
> > >
> > >      CONVERTED = TESTGSDATA[GSBLKCNT] << 4;
> > >
> > >      USISR = CONVERTED;                      
> > >
> > >      USICNT = USI16B | 12;
> > >
> > >      while (PWAIT != 20)
> > >
> > >        PWAIT = PWAIT + 1;
> > >
> > >      }
> > >
> > >      PWAIT = 0;
> > >
> > >      GSBLKCNT = GSBLKCNT +1;
> > >
> > >    }
> > >
> > >   _BIS_SR(LPM0_bits + GIE);                  
> > >
> > >  }
> > >
> > > }
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > >
> > > #pragma vector=TIMERA0_VECTOR
> > >
> > > __interrupt void Timer_A (void)
> > >
> > > {
> > >
> > >    _BIS_SR(SCG1);              
> > >
> > >    TACTL = TASSEL_2 + ID_0 + MC_0;
> > >
> > >    //_BIC_SR(LPM0_bits );                
> > >
> > >    _BIC_SR_IRQ(LPM0_bits);                
> > >
> > >
> > >
> > > }
> > >
> >
>


Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

bob_shaftenkluger
I haven't tested this yet, but I have been trying to figure out what the assembly means, and I came up with this-

__asm
(
" bis.b #0x01,&0x0026\n"
Bit set, #0x01 into 0x0026, the pin functon select register. have I misunderstood, or is this the wrong bit into the wrong register?
" mov.w #1363,R15\n"    
Moves 1363 to register 15,
" dec.w R15\n"          
Decrement R15
" jnz $-2\n"            
Jump if not zero, unsure about the "$-2" bit, but i guess it jumps back to the line above.
" nop\n"                
Do nothing
" bic.b #0x01,&0x0026"
Clears the bit set in the first line
);

So, it seems one of us, (Most likely me...) has got something horibly wrong. To me it looks like that code would switch on bit 1 of the p1sel register, wait for a while, then switch it off again. Perhaps its something to do with the "\n" at the end of some of the lines, I can't find out what that means. (Although I didn't look very hard, nearly bed time for me!) It would be good if you could give me a better explanaton.



--- In [hidden email], "old_cow_yellow" <old_cow_yellow@...> wrote:

>
> If you replace the lines:
>
> //for (int p=4096; p>0; p--)
> //{//2c
> //P1OUT |= GSCLK;
> //P1OUT &= ~GSCLK;
> //}//2c
>
> by the lines:
>
> __asm
> (
> " bis.b #0x01,&0x0026\n"
> " mov.w #1363,R15\n"
> " dec.w R15\n"
> " jnz $-2\n"
> " nop\n"
> " bic.b #0x01,&0x0026"
> );
>
> You will not need to increase the clock speed
>
>

Reply | Threaded
Open this post in threaded view
|

Specfic questions Re: tlc5940 programming problems.

old_cow_yellow
You got it right. But I made some mistakes. It should be:

__asm
(
" bis.b #0x10,&0x0026\n"
" mov.w #1363,R15\n"
" dec.w R15\n"
" jnz $-2\n"
" bic.b #0x10,&0x0026"
);

This puts SMCLK on P1.4, delay 4094 MCLK cycles and remove SMCLK from P1.4. Since SMCLK=MCLK, you get 4096 pulses at P1.4

(BTW, \n means new-line.)

--- In [hidden email], "bob_shaftenkluger" <bob_shaftenkluger@...> wrote:

>
> I haven't tested this yet, but I have been trying to figure out what the assembly means, and I came up with this-
>
> __asm
> (
> " bis.b #0x01,&0x0026\n"
> Bit set, #0x01 into 0x0026, the pin functon select register. have I misunderstood, or is this the wrong bit into the wrong register?
> " mov.w #1363,R15\n"    
> Moves 1363 to register 15,
> " dec.w R15\n"          
> Decrement R15
> " jnz $-2\n"            
> Jump if not zero, unsure about the "$-2" bit, but i guess it jumps back to the line above.
> " nop\n"                
> Do nothing
> " bic.b #0x01,&0x0026"
> Clears the bit set in the first line
> );
>
> So, it seems one of us, (Most likely me...) has got something horibly wrong. To me it looks like that code would switch on bit 1 of the p1sel register, wait for a while, then switch it off again. Perhaps its something to do with the "\n" at the end of some of the lines, I can't find out what that means. (Although I didn't look very hard, nearly bed time for me!) It would be good if you could give me a better explanaton.
>
>
>
> --- In [hidden email], "old_cow_yellow" <old_cow_yellow@> wrote:
> >
> > If you replace the lines:
> >
> > //for (int p=4096; p>0; p--)
> > //{//2c
> > //P1OUT |= GSCLK;
> > //P1OUT &= ~GSCLK;
> > //}//2c
> >
> > by the lines:
> >
> > __asm
> > (
> > " bis.b #0x01,&0x0026\n"
> > " mov.w #1363,R15\n"
> > " dec.w R15\n"
> > " jnz $-2\n"
> > " nop\n"
> > " bic.b #0x01,&0x0026"
> > );
> >
> > You will not need to increase the clock speed
> >
> >
>


Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

random intel dude
This post has NOT been accepted by the mailing list yet.
I think you forgot the "0x" in #0x1363 below (I added the "0x").  Unless the loop needs to be divided by an integer number of cycles (but your description doesn't seem to fit with this)

So I think this is correct:

__asm
(
" bis.b #0x10,&0x0026\n"
" mov.w #0x1363,R15\n"
" dec.w R15\n"
" jnz $-2\n"
" bic.b #0x10,&0x0026"
);
Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

random intel dude
This post has NOT been accepted by the mailing list yet.
BTW - Energia, with the loop (instead of the asm code), works just fine (no flicker).  Too bad I can't see the disassembly to see how Energia optimized the compile.  I never thought Energia would produce tighter code.
I tried putting "register" on the loop variable in the CCS version, but it didn't help (not sure if I got it correct though).
Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

random intel dude
This post has NOT been accepted by the mailing list yet.
Also, the energia version with the loop is MUCH brighter.  Maybe the SMCLK pulse that is used is not giving full length pulses?  But if the GSCLK is just edge triggered, it shouldn't matter.  But it is definitely dimmer on CCS running the same code.  (I added fade on and the full "on" is blinding on Energia. :-) )

Not sure why...
Reply | Threaded
Open this post in threaded view
|

Re: Specfic questions Re: tlc5940 programming problems.

random intel dude
This post has NOT been accepted by the mailing list yet.
I figured out why.  The CCS is defaulting my msp430g2452 to 1MHz!
I added this at near the top of main:

DCOCTL = CALDCO_16MHZ;// try changing clock speed
BCSCTL1 = CALBC1_16MHZ;  

And now it is brighter (not sure why), and also no flicker results when using the for-loop instead of the _asm.

Why is CCS defaulting my board to 1MHz?  Time to revisit all my projects with this in mind!
Still curious why the _asm results in a dimmer LED.