Jump to content
Sign in to follow this  
H3rv3

TLS3008 RGB Leds on Launchpad

Recommended Posts

I bought some addressable RGB Leds from Dealextreme and instead of the expected WS2801 chip, they came with TLS3008 drivers (8bit control for each colour, single wire, different protocol from WS2811 too).

It took some time with the osciloscope to get the timing right but this now works perfect. This is in C rahter than assembly but I can get a decent update rate. I do not work with the full 50 Leds as there is not enough RAM in the chip I use (2231) but I tried looping the code to work with the full length, that worked ok except on one set of Leds which was sometimes lagging, I think that this is due to the extra time used by the loop when returning. If all the RGB data is in a table there should be no issue. I will check this when I have a better chip.

I am making a kind of light organ - vu meter mix with a short string of 6  Leds and the update on the audio is faster than I need.

This is compiled with IAR.

Any comments and improvements welcome!

 

H3rv3

 

// TLS3008 based 6 RGB LEDs string test application for MSP430
// Based on DonJuanito99 for arduino
//THIS IS THE WORKING CODE

// includes
#include  "msp430g2231.h"
#include "intrinsics.h"

// defines
#define PULSEUS1 33  // Manchester half period in clock cycles (2.5us) to 1
#define PULSEUS0 22  // Manchester half period in clock cycles (2.5us) to 0
#define PULSEUS2 9   // used for end of command last 0 delay
#define EOSYNCDELAYMS 50750 // Pause duration at end of SYNC frame (3.5ms)
#define EORESETMS 29000 // Pause duration at end of RESET frame (2ms)
#define EOFDELAYMS 5000 // Pause duration at end of each frame (of 50 LEDs RGB data) (0.35ms)
#define UP 0x00
#define DOWN 0x01
#define HOLD 0x02

// variables
//all reds
//unsigned char RGBTable [18]={0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00,0xFF,0x00,0x00};
//one color each
//unsigned char RGBTable [18]={0xFF,0x00,0x00,0x0F,0x00,0x0F,0x00,0x00,0xFF,0x00,0x0F,0x0F,0x00,0xff,0x00,0x0f,0x0F,0x00};
//all off
unsigned char RGBTable [18];
int i;
int bc;
char led_red = 1;
char led_green = 255;
char led_blue = 1;
char red = UP;
char blue = HOLD;
char green = DOWN;

// routines
void reset(void); // sends reset frame
void sync(void); // sends sync frame
void frame_start(void); // sends emty data frame (last bit, out of procedure delay)
void updateRGB (void); // sends the data to the leds
void bitc(char); // bit sending procedure to send commands
void bitd(char); // bit sending procedure to send data
   
void main(void)
 {
//pin setup output and 0
P1DIR |= BIT0;
P1OUT &= ~BIT0;
//Stop watchdog timer  
WDTCTL = WDTPW + WDTHOLD; 
//Set clock at 16MHz
DCOCTL = DCO0 + DCO1;
BCSCTL1 = RSEL0 + RSEL1 + RSEL2 + RSEL3;
//Disable interupts
__disable_interrupt();

// initialising strings       
reset();
sync();
reset();
sync();
reset();
sync();

     
while(1)
{

//  reset(); // not required in this loop, consider regular reset
//  sync();  // not required in this loop, consider regular re-sync
    // send the data to the string
    updateRGB();
     // the code below is just for the show
    while (P1IN & BIT3)
     {}

//fade logic
switch (red){
case UP: ++led_red;
if (led_red == 255) {red = DOWN; green = HOLD; blue = UP; led_green=0;}
break;
case DOWN: --led_red;
if (led_red == 0) {red = HOLD;}
break;
case HOLD: break;
}//end switch
switch (blue){
case UP:  ++led_blue;
if (led_blue == 255) {blue = DOWN; green = UP; red = HOLD;led_red=0;}
break;
case DOWN: --led_blue;
if (led_blue == 0) {blue = HOLD;}
break;
case HOLD: break;
}//end switch
switch (green){
case UP: ++led_green;
if (led_green == 255) {green = DOWN; red = UP; blue = HOLD;led_blue=0;}
break;
case DOWN: --led_green;
if (led_green == 0) {green = HOLD;}
break;
case HOLD: break;
}//end switch
RGBTable [0]=led_red;
RGBTable [1]=led_green;
RGBTable [2]=led_blue;

RGBTable [3]=led_blue;
RGBTable [4]=led_green;
RGBTable [5]=led_red;

RGBTable [6]=led_red;
RGBTable [7]=led_blue;
RGBTable [8]=led_green;

RGBTable [9]=led_blue;
RGBTable [10]=led_red;
RGBTable [11]=led_green;

RGBTable [12]=led_green;
RGBTable [13]=led_blue;
RGBTable [14]=led_red;

RGBTable [15]=led_green;
RGBTable [16]=led_red;
RGBTable [17]=led_blue;

} //end while
} // end main()

void updateRGB(void) // send the RGBTable data to the string
{
     frame_start(); // prepare to send data
    __delay_cycles (PULSEUS0-4); 
     for(i=0;i<18;i++) // Repeat for 6 leds * 3 data blocks
       {  
         // Start tag (= 0 bit)
          P1OUT &= ~BIT0;    // set to 0
          __delay_cycles(PULSEUS1);
          P1OUT |= BIT0;     //set to 1 
          __delay_cycles(4);
          for (bc=0x80;bc!=0;bc>>=1) bitd( RGBTable[i] & bc ); // send the 8 data bits
          __delay_cycles (6); 
       }         
      P1OUT &= ~BIT0;
      __delay_cycles (EOFDELAYMS);
     //pass value from chip to LED (=send a complete frame start)
     frame_start();
     __delay_cycles (PULSEUS1-3);     
     P1OUT &= ~BIT0; // write a low
      __delay_cycles (EOFDELAYMS);
}      
      

void bitd(char 
 {
   if (b==0){
      P1OUT &= ~BIT0;    // set to 0
      __delay_cycles(PULSEUS1);
      P1OUT |= BIT0;     //set to 1
      __delay_cycles (4);
   }
   else{
      P1OUT |= BIT0;     // set to 1
      __delay_cycles(PULSEUS1);
      P1OUT &= ~BIT0;   //set to 0
      __delay_cycles (4);
    }
 }

void bitc(char 
 {
   if (b==0){
      P1OUT &= ~BIT0;    // set to 0
      __delay_cycles(PULSEUS1);
      P1OUT |= BIT0;     //set to 1
      __delay_cycles (PULSEUS0);
   }
   else{
      P1OUT |= BIT0;     // set to 1
      __delay_cycles(PULSEUS1);
      P1OUT &= ~BIT0;   //set to 0
      __delay_cycles (PULSEUS0);
    }
 }
 
 void sync()
 {
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);

    bitc(0);
    bitc(0);
    bitc(0);
    bitc(1);
    
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    bitc(0);
    __delay_cycles (PULSEUS2);      // additional delay on last 0
    P1OUT &= ~BIT0;                 // now set to 0
    __delay_cycles (EOSYNCDELAYMS); // end of sync frame delay

 }
 void reset()
 {
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);

    bitc(0);
    bitc(1);
    bitc(0);
    bitc(0);
    __delay_cycles (PULSEUS2);  // additional delay on last 0
    P1OUT &= ~BIT0;             // now set to 0
    __delay_cycles (EORESETMS); // end of reset frame delay

 }

 void frame_start()
 {
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);
    bitc(1);

    bitc(0);
    bitc(0);
    bitc(1);
    P1OUT &= ~BIT0;     
    __delay_cycles(PULSEUS1+9);
    P1OUT |= BIT0;     //set to 1
    // last 0 bit has no delay (delay will be set outside due to procedure return delays) 
 }

 

Share this post


Link to post
Share on other sites

Are PULSEUS0,1,2 really different values, or are they different to compensate for the other code you're running? If the second is the case, I'd really recommend you to use a timer to output these values. scrap that, with these speeds, there is no way a timer could be set fast enough; too much execution overhead.

The code seems very similar to manchester encoding, maybe there's a library to do that for you. If you're using an MSP with USI or USCI built in, you could even use those to transmit the data (send bits 10 for a 1 or 01 for a 0)

Share this post


Link to post
Share on other sites

That was sku 111682, unfortunately now sold out :-(

Thanks. I had one I bought from DX for testing, but it turns out mine is a SKU 14965, which is a totally different kind of beast. :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...