Need help trying to interface to STP1612PW05 LED driver

27 Jan 2012

Hi there,

I am trying to interface to this 16 bit LED driver from ST ( http://www.st.com/internet/analog/product/215262.jsp ). It interfaces via SPI but the problem is that to send configuration data to it I need to have one of its pins high for a certain number of bits (yes, bits...). I am not sure how to do that with the current SPI library and I can't seem to find another way. Please refer to page 14 of the data sheet ( http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00237442.pdf ) to gain further understanding of what I mean... Any insight on this would be greatly appreciated.

Regards, Kartik

27 Jan 2012

If config is a one off, then I'd bit bash SPI For that frame, But if it is more frequent, then I think you can actuality Have a FOUR bit SPI frame ?

So you would send 4 bit frame, toggle pin, send 12 bit frame.

Will look at data sheet a little later, just to make sure.

Ceri

27 Jan 2012

If it is fig. 7, then. This is 16 bit packets, Therefore, a pulse afterwards should be OK. Have a look for TLC9540, In the cool book ? It is amazingly similar.

Ceri

27 Jan 2012

You mean the TLC5940? I did but its only 12 bit. I am using this to drive servos. Ok, so a 4 bit packet should work, how do I know that the SPI library sends the most significant bit first? Also which "mode" of SPI do I need to use with this? My guess is "mode 0"...

Thanks again for taking the time to help me.

Regards, Kartik

27 Jan 2012

Ceri, What do you mean by bit bashing the SPI? Yes the configuration is a one off thing in the beginning of the program. Although in the data sheet fig. 6 shows that the LE needs to go high at the 6th or 7th bit all the way to the 16th bit then low.

27 Jan 2012

CS = 0
Data = 1
Clock = 1
Clock = 0
 ....
....
.....
....
Le = 1
Data ...
Clock...
Clock
.....
....
....
....
Le = 0
Ce = 1

You simply toggle the bits manual, You could put it in a loop, in a subroutine.

27 Jan 2012

So this is what I did and still a no go.

#include "mbed.h"


PwmOut pwclk (p21);
DigitalOut mosi (p5);
DigitalOut le (p6);
DigitalOut clk (p7);
unsigned short servo_pos [16] = {0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF};
unsigned short config = 0xFAAF;

void servo_init (unsigned short config);
void servo_write (unsigned short servo_pos []);

int main()
{
    le = 0;
    clk = 0;
    mosi = 0;
     
    LPC_PWM1->TCR = (1 << 1);               // Reset counter, disable PWM
    LPC_SC->PCLKSEL0 &= ~(0x3 << 12);  
    LPC_SC->PCLKSEL0 |= (1 << 12);          // Set peripheral clock divider to /1, i.e. system clock
    LPC_PWM1->MR0 = 29;                     // Match Register 0 is shared period counter for all PWM1
    LPC_PWM1->MR6 = 14;                      // Pin 21 is PWM output 6, so Match Register 6
    LPC_PWM1->LER |= 1;                     // Start updating at next period start
    LPC_PWM1->TCR = (1 << 0) || (1 << 3);   // Enable counter and PWM
    
    servo_init (config);
    
    while (1)
    {
        servo_write (servo_pos);
    }
}

void servo_init (unsigned short config)
{
    clk = 0;
    for (int i = 0; i < 16; i++)
    {
        clk = 0;
        if (i >= 6 && i < 16)
            le = 1;
        else
            le = 0;
        
        if (config & 0x8000)
            mosi = 1;
        else
            mosi = 0;
        config = config << 1;
        clk = 1;
    }
    le = 0;
}

void servo_write (unsigned short servo_pos [])
{
    unsigned int byte = 0;
    le = 0;
    clk = 0;
    for (int k = 15; k >= 0; k--)
    {
        byte = servo_pos [k];
        for (int i = 0; i < 16; i++)
        {
            clk = 0;
            if (byte & 0x8000)
                mosi = 1;
            else
                mosi = 0;
            byte = byte << 1;
            clk = 1;
        }
    }
    le = 1;
    le = 0;
}
28 Jan 2012

Alright... everything is solved and working correctly. Thanks for your help!

#include "mbed.h"


PwmOut pwclk (p21);
DigitalOut mosi (p5);
DigitalOut le (p6);
DigitalOut clk (p7);
unsigned short servo_pos [16] = {60620, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF};
unsigned short config = 0xFAAF;

void servo_init (unsigned short config);
void servo_write (unsigned short servo_pos []);

int main()
{
    le = 0;
    clk = 0;
    mosi = 0;
     
    LPC_PWM1->TCR = (1 << 1);               // Reset counter, disable PWM
    LPC_SC->PCLKSEL0 &= ~(0x3 << 12);  
    LPC_SC->PCLKSEL0 |= (1 << 12);          // Set peripheral clock divider to /1, i.e. system clock
    LPC_PWM1->MR0 = 29;                     // Match Register 0 is shared period counter for all PWM1
    LPC_PWM1->MR6 = 14;                      // Pin 21 is PWM output 6, so Match Register 6
    LPC_PWM1->LER |= 1;                     // Start updating at next period start
    LPC_PWM1->TCR = (1 << 0) || (1 << 3);   // Enable counter and PWM
    
    servo_init (config);
    
    while (1)
    {
        servo_write (servo_pos);
    }
}

void servo_init (unsigned short config)
{
    clk = 0;
    for (int i = 0; i < 16; i++)
    {
        clk = 0;
        mosi = 0;
        if (i >= 5 && i < 16)
            le = 1;
        else
            le = 0;
        
        if (config & 0x8000)
            mosi = 1;
        else
            mosi = 0;
        config = config << 1;
        clk = 1;
    }
    mosi = 0;
    clk = 0;
    le = 0;
}

void servo_write (unsigned short servo_pos [])
{
    unsigned int byte = 0;
    le = 0;
    clk = 0;
    for (int k = 15; k >= 0; k--)
    {
        byte = servo_pos [k];
        for (int i = 0; i < 16; i++)
        {
            clk = 0;
            mosi = 0;
            if (k == 0 && i >= 13)
                le = 1;
            else
                le = 0;
            if (byte & 0x8000)
                mosi = 1;
            else
                mosi = 0;
            byte = byte << 1;
            
            clk = 1;            
        }
    }
    mosi = 0;
    clk = 0;
    le = 0;
}