Skip to content

Commit

Permalink
Merge pull request #13 from hoffmannjan/master
Browse files Browse the repository at this point in the history
transactional SPI
  • Loading branch information
ladyada authored Apr 4, 2019
2 parents eeabab2 + a415c9c commit 9ac3b80
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 41 deletions.
123 changes: 87 additions & 36 deletions Adafruit_TLC59711.cpp
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
/***************************************************
/***************************************************
This is a library for our Adafruit 12-channel PWM/LED driver
Pick one up today in the adafruit shop!
------> http://www.adafruit.com/products/1455
Two SPI Pins are required to send data: clock and data pin.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/


#include <Adafruit_TLC59711.h>
#include <SPI.h>

SPISettings SPI_SETTINGS(500000, MSBFIRST, SPI_MODE0);

/*!
* @brief Instantiates a new Adafruit_TLC59711 class
* @param n
Expand All @@ -32,9 +33,9 @@ Adafruit_TLC59711::Adafruit_TLC59711(uint8_t n, uint8_t c, uint8_t d) {
_clk = c;
_dat = d;

BCr = BCg = BCb = 0x7F;
BCr = BCg = BCb = 0x7F; // default 100% brigthness

pwmbuffer = (uint16_t *)calloc(2, 12*n);
pwmbuffer = (uint16_t *)calloc(2, 12 * n);
}

/*!
Expand All @@ -50,33 +51,26 @@ Adafruit_TLC59711::Adafruit_TLC59711(uint8_t n, SPIClass *theSPI) {
_dat = -1;
_spi = theSPI;

_spi->setBitOrder(MSBFIRST);
#ifdef __arm__
_spi->setClockDivider(42);
#else
_spi->setClockDivider(SPI_CLOCK_DIV8);
#endif
_spi->setDataMode(SPI_MODE0);
BCr = BCg = BCb = 0x7F;
BCr = BCg = BCb = 0x7F; // default 100% brigthness

pwmbuffer = (uint16_t *)calloc(2, 12*n);
pwmbuffer = (uint16_t *)calloc(2, 12 * n);
}

/*!
* @brief Write data throught SPI at MSB
* @param d
* data
*/
void Adafruit_TLC59711::spiwriteMSB(uint8_t d) {
void Adafruit_TLC59711::spiwriteMSB(uint8_t d) {
if (_clk >= 0) {
uint32_t b = 0x80;
// b <<= (bits-1);
for (; b!=0; b>>=1) {
for (; b != 0; b >>= 1) {
digitalWrite(_clk, LOW);
if (d & b)
digitalWrite(_dat, HIGH);
if (d & b)
digitalWrite(_dat, HIGH);
else
digitalWrite(_dat, LOW);
digitalWrite(_dat, LOW);
digitalWrite(_clk, HIGH);
}
} else {
Expand All @@ -88,13 +82,17 @@ void Adafruit_TLC59711::spiwriteMSB(uint8_t d) {
* @brief Writes PWM buffer to board
*/
void Adafruit_TLC59711::write() {
if (_clk < 0) {
_spi->beginTransaction(SPI_SETTINGS);
}

uint32_t command;

// Magic word for write
command = 0x25;

command <<= 5;
//OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 0 -> 0x16
// OUTTMG = 1, EXTGCK = 0, TMGRST = 1, DSPRPT = 1, BLANK = 0 -> 0x16
command |= 0x16;

command <<= 7;
Expand All @@ -107,29 +105,29 @@ void Adafruit_TLC59711::write() {
command |= BCb;

noInterrupts();
for (uint8_t n=0; n<numdrivers; n++) {
for (uint8_t n = 0; n < numdrivers; n++) {
spiwriteMSB(command >> 24);
spiwriteMSB(command >> 16);
spiwriteMSB(command >> 8);
spiwriteMSB(command);

// 12 channels per TLC59711
for (int8_t c=11; c >= 0 ; c--) {
for (int8_t c = 11; c >= 0; c--) {
// 16 bits per channel, send MSB first
spiwriteMSB(pwmbuffer[n*12+c]>>8);
spiwriteMSB(pwmbuffer[n*12+c]);
spiwriteMSB(pwmbuffer[n * 12 + c] >> 8);
spiwriteMSB(pwmbuffer[n * 12 + c]);
}
}

if (_clk >= 0)
delayMicroseconds(200);
else
delayMicroseconds(2);
_spi->endTransaction();

interrupts();
}



/*!
* @brief Set PWM value on selected channel
* @param chan
Expand All @@ -138,12 +136,13 @@ void Adafruit_TLC59711::write() {
* pwm value
*/
void Adafruit_TLC59711::setPWM(uint8_t chan, uint16_t pwm) {
if (chan > 12*numdrivers) return;
pwmbuffer[chan] = pwm;
if (chan > 12 * numdrivers)
return;
pwmbuffer[chan] = pwm;
}

/*!
* @brief Set RGB value for selected LED
* @brief Set RGB value for selected LED
* @param lednum
* selected LED number that for which value will be set
* @param r
Expand All @@ -153,18 +152,70 @@ void Adafruit_TLC59711::setPWM(uint8_t chan, uint16_t pwm) {
* @param b
* blue value
*/
void Adafruit_TLC59711::setLED(uint8_t lednum, uint16_t r, uint16_t g, uint16_t b) {
setPWM(lednum*3, r);
setPWM(lednum*3+1, g);
setPWM(lednum*3+2, b);
void Adafruit_TLC59711::setLED(uint8_t lednum, uint16_t r, uint16_t g,
uint16_t b) {
setPWM(lednum * 3, r);
setPWM(lednum * 3 + 1, g);
setPWM(lednum * 3 + 2, b);
}

/*!
* @brief Set the brightness of LED channels to same value
* @param BC
* Brightness Control value
*/
void Adafruit_TLC59711::simpleSetBrightness(uint8_t BC) {
if (BC > 127) {
BC = 127; // maximum possible value since BC can only be 7 bit
} else if (BC < 0) {
BC = 0;
}

BCr = BCg = BCb = BC;
}

/*!
* @brief Set the brightness of LED channels to specific value
* @param bcr
* Brightness Control Red value
* @param bcg
* Brightness Control Green value
* @param bcb
* Brightness Control Blue value
*/
void Adafruit_TLC59711::setBrightness(uint8_t bcr, uint8_t bcg, uint8_t bcb) {
if (bcr > 127) {
bcr = 127; // maximum possible value since BC can only be 7 bit
} else if (bcr < 0) {
bcr = 0;
}

BCr = bcr;

if (bcg > 127) {
bcg = 127; // maximum possible value since BC can only be 7 bit
} else if (bcg < 0) {
bcg = 0;
}

BCg = bcg;

if (bcb > 127) {
bcb = 127; // maximum possible value since BC can only be 7 bit
} else if (bcb < 0) {
bcb = 0;
}

BCb = bcb;
}

/*!
* @brief Begins SPI connection if there is not empty PWM buffer
* @return If successful returns true, otherwise false
*/
boolean Adafruit_TLC59711::begin() {
if (!pwmbuffer) return false;
if (!pwmbuffer)
return false;

if (_clk >= 0) {
pinMode(_clk, OUTPUT);
Expand Down
8 changes: 4 additions & 4 deletions Adafruit_TLC59711.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* TLC59711 Senor
*/
class Adafruit_TLC59711 {
public:
public:
Adafruit_TLC59711(uint8_t n, uint8_t c, uint8_t d);
Adafruit_TLC59711(uint8_t n, SPIClass *theSPI = &SPI);

Expand All @@ -40,15 +40,15 @@ class Adafruit_TLC59711 {
void setLED(uint8_t lednum, uint16_t r, uint16_t g, uint16_t b);
void write();
void spiwriteMSB(uint8_t d);
void setBrightness(uint8_t bcr, uint8_t bcg, uint8_t bcb);
void simpleSetBrightness(uint8_t BC);

private:
private:
uint16_t *pwmbuffer;

uint8_t BCr, BCg, BCb;
int8_t numdrivers, _clk, _dat;
SPIClass *_spi;

};


#endif
15 changes: 14 additions & 1 deletion examples/tlc59711test/tlc59711test.ino
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void loop() {
colorWipe(0, 0, 65535, 100); // "Blue" (depending on your LED wiring)
delay(200);

rainbowCycle(5);
increaseBrightness();
}


Expand Down Expand Up @@ -83,3 +83,16 @@ void Wheel(uint8_t ledn, uint16_t WheelPos) {
tlc.setLED(ledn, 0, 3*WheelPos, 65535 - 3*WheelPos);
}
}

//All RGB Channels on full colour
//Cycles trough all brightness settings from 0 up to 127
void increaseBrightness(){
for(uint16_t i=0; i<8*NUM_TLC59711; i++) {
tlc.setLED(i, 65535, 65535, 65535);
}
for(int i = 0; i < 128; i++){
tlc.simpleSetBrightness(i);
tlc.write();
delay(1000);
}
}

0 comments on commit 9ac3b80

Please sign in to comment.