Library for using the TLC5940 as a servo controller.

Dependencies:   FastPWM

Dependents:   TLC5940ServoTest

TLC5940Servo.cpp

Committer:
dudanian
Date:
2014-10-21
Revision:
0:9fc434ff7a03
Child:
2:1d2251574d35

File content as of revision 0:9fc434ff7a03:

#include "TLC5940Servo.h"

TLC5940Servo::TLC5940Servo(PinName MOSI, PinName SCLK, PinName XLAT, PinName BLANK, 
        PinName GSCLK, const int number) : number(number), spi(MOSI, NC, SCLK), gsclk(GSCLK),
                                           blank(BLANK), xlat(XLAT), newData(false), need_xlat(false)
{   
    // Configure SPI to 12 bits and SPI_SPEED
    spi.format(12, 0);
    spi.frequency(SPI_SPEED);
    
    // Set output pin states
    xlat = 0;
    blank = 1;
    
    // Call the reset function every 4096 PWM outputs
    reset_ticker.attach_us(this, &TLC5940Servo::reset, (1000000.0/GSCLK_SPEED) * 4096.0);
    
    // Configure FastPWM output for GSCLK frequency at 50% duty cycle
    gsclk.period_us(1000000.0/GSCLK_SPEED);
    gsclk.write(.5);

    // Create a data buffer to store the current Servo states
    dataBuffer = new int[16 * number]();
}

TLC5940Servo::~TLC5940Servo()
{
    // Delete the buffer
    delete[] dataBuffer;
}


int& TLC5940Servo::operator[](int index)
{
    // Return the start of the correct data chunk
    newData = true;
    return dataBuffer[index];
}

void TLC5940Servo::reset()
{
    gsclk.write(0); // turn off gsclk
    blank = 1; // start reset
    
    // latch data if new data was written
    if (need_xlat) {
        xlat = 1;
        xlat = 0;
        
        need_xlat = false;
    }
    
    blank = 0; // turn off reset
    gsclk.write(.5); // restart gsclk

    if (newData) {
        
        // Send GS data backwards - this makes the GS_buffer[0] index correspond to OUT0 
        for (int i = (16 * number) - 1; i >= 0; i--)
        {
            // Get the lower 12 bits of the buffer and send
            spi.write(dataBuffer[i] & 0xFFF);
        }
        
        // Latch after current GS data is done being displayed
        need_xlat = true;
        
        // No new data to send (we just sent it!)
        newData = false;
    }
}