This library allows control of the TLC5940 PWM driver IC. It supports both normal operation and controlling multiplexed displays.

Dependencies:   FastPWM

Dependents:   TLC5940LEDtreiber

Committer:
Spencer
Date:
Sun May 26 05:04:29 2013 +0000
Revision:
3:e5ed5650eb15
Parent:
2:69e40ccf506f
A few more bug fixes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Spencer 0:be9399a34b15 1 #include "TLC5940.h"
Spencer 0:be9399a34b15 2
Spencer 0:be9399a34b15 3 TLC5940::TLC5940(PinName SCLK, PinName MOSI, PinName GSCLK, PinName BLANK,
Spencer 0:be9399a34b15 4 PinName XLAT, PinName DCPRG, PinName VPRG, const int number) : number(number),
Spencer 0:be9399a34b15 5 spi(MOSI, NC, SCLK),
Spencer 0:be9399a34b15 6 gsclk(GSCLK),
Spencer 0:be9399a34b15 7 blank(BLANK),
Spencer 0:be9399a34b15 8 xlat(XLAT),
Spencer 0:be9399a34b15 9 dcprg(DCPRG),
Spencer 0:be9399a34b15 10 vprg(VPRG),
Spencer 0:be9399a34b15 11 newGSData(false),
Spencer 0:be9399a34b15 12 newDCData(false),
Spencer 0:be9399a34b15 13 need_xlat(false)
Spencer 0:be9399a34b15 14 {
Spencer 0:be9399a34b15 15 // Configure SPI to 12 bits and SPI_SPEED
Spencer 0:be9399a34b15 16 spi.format(12, 0);
Spencer 0:be9399a34b15 17 spi.frequency(SPI_SPEED);
Spencer 0:be9399a34b15 18
Spencer 0:be9399a34b15 19 // Set output pin states
Spencer 0:be9399a34b15 20 dcprg = 0;
Spencer 0:be9399a34b15 21 vprg = 0;
Spencer 0:be9399a34b15 22 xlat = 0;
Spencer 0:be9399a34b15 23 blank = 1;
Spencer 0:be9399a34b15 24
Spencer 0:be9399a34b15 25 // Call the reset function every 4096 PWM outputs
Spencer 0:be9399a34b15 26 reset_ticker.attach_us(this, &TLC5940::reset, (1000000.0/GSCLK_SPEED) * 4096.0);
Spencer 0:be9399a34b15 27
Spencer 0:be9399a34b15 28 // Configure FastPWM output for GSCLK frequency at 50% duty cycle
Spencer 2:69e40ccf506f 29 gsclk.period_us(1000000.0/(GSCLK_SPEED * 1.05));
Spencer 0:be9399a34b15 30 gsclk.write(.5);
Spencer 0:be9399a34b15 31 }
Spencer 0:be9399a34b15 32
Spencer 0:be9399a34b15 33 void TLC5940::setNewGSData(unsigned short* data)
Spencer 0:be9399a34b15 34 {
Spencer 0:be9399a34b15 35 gsBuffer = data;
Spencer 0:be9399a34b15 36
Spencer 0:be9399a34b15 37 // Tell reset function that new GS data has been given
Spencer 0:be9399a34b15 38 newGSData = true;
Spencer 0:be9399a34b15 39 }
Spencer 0:be9399a34b15 40
Spencer 0:be9399a34b15 41 void TLC5940::setNewDCData(unsigned char* data)
Spencer 0:be9399a34b15 42 {
Spencer 0:be9399a34b15 43 dcBuffer = data;
Spencer 0:be9399a34b15 44
Spencer 0:be9399a34b15 45 // Tell reset function that new DC data has been given
Spencer 0:be9399a34b15 46 newDCData = true;
Spencer 0:be9399a34b15 47 }
Spencer 0:be9399a34b15 48
Spencer 0:be9399a34b15 49 void TLC5940::reset()
Spencer 0:be9399a34b15 50 {
Spencer 2:69e40ccf506f 51 gsclk.write(0);
Spencer 0:be9399a34b15 52 // Turn off LEDs
Spencer 0:be9399a34b15 53 blank = 1;
Spencer 0:be9399a34b15 54
Spencer 2:69e40ccf506f 55 // Virtual function that allows the next data chunk to be set after every GSCLK cycle
Spencer 2:69e40ccf506f 56 // Useful for setting the next frame when multiplexing (e.g. LED matrices)
Spencer 2:69e40ccf506f 57 setNextData();
Spencer 2:69e40ccf506f 58
Spencer 0:be9399a34b15 59 // Latch in data from previous cycle if needed
Spencer 0:be9399a34b15 60 if (need_xlat)
Spencer 0:be9399a34b15 61 {
Spencer 0:be9399a34b15 62 // Latch
Spencer 0:be9399a34b15 63 xlat = 1;
Spencer 0:be9399a34b15 64 xlat = 0;
Spencer 0:be9399a34b15 65
Spencer 0:be9399a34b15 66 // Don't need to latch again
Spencer 0:be9399a34b15 67 need_xlat = false;
Spencer 0:be9399a34b15 68 }
Spencer 0:be9399a34b15 69
Spencer 0:be9399a34b15 70 // Reset the screen so that it is updating while data is being sent
Spencer 0:be9399a34b15 71 blank = 0;
Spencer 2:69e40ccf506f 72 gsclk.write(.5);
Spencer 0:be9399a34b15 73
Spencer 0:be9399a34b15 74 // Do we have new DC data to send?
Spencer 0:be9399a34b15 75 if (newDCData)
Spencer 0:be9399a34b15 76 {
Spencer 0:be9399a34b15 77 // Set TLC5940 to accpet DC data
Spencer 0:be9399a34b15 78 vprg = 1;
Spencer 0:be9399a34b15 79
Spencer 0:be9399a34b15 80 // Get DC data from registers instead of EEPROM (since we are sending data to the registers now)
Spencer 0:be9399a34b15 81 dcprg = 1;
Spencer 0:be9399a34b15 82
Spencer 0:be9399a34b15 83 // Send DC data backwards - this makes the DC_buffer[0] index correspond to OUT0
Spencer 0:be9399a34b15 84 for (int i = (16 * number) - 1; i >= 0; i--)
Spencer 0:be9399a34b15 85 {
Spencer 0:be9399a34b15 86 // Assemble a 12 bit packet from two 6 bit chunks
Spencer 0:be9399a34b15 87 spi.write(((dcBuffer[i] & 0x3F) << 6) | (dcBuffer[i-1] & 0x3F));
Spencer 0:be9399a34b15 88 i--;
Spencer 0:be9399a34b15 89 }
Spencer 0:be9399a34b15 90
Spencer 0:be9399a34b15 91 // Latch
Spencer 0:be9399a34b15 92 xlat = 1;
Spencer 0:be9399a34b15 93 xlat = 0;
Spencer 0:be9399a34b15 94
Spencer 0:be9399a34b15 95 // No new data to send (we just sent it!)
Spencer 0:be9399a34b15 96 newDCData = false;
Spencer 0:be9399a34b15 97 }
Spencer 0:be9399a34b15 98
Spencer 0:be9399a34b15 99 // Do we have new GS data to send?
Spencer 0:be9399a34b15 100 if (newGSData)
Spencer 0:be9399a34b15 101 {
Spencer 0:be9399a34b15 102 // Set TLC5940 to accept GS data
Spencer 0:be9399a34b15 103 vprg = 0;
Spencer 0:be9399a34b15 104
Spencer 0:be9399a34b15 105 // Send GS data backwards - this makes the GS_buffer[0] index correspond to OUT0
Spencer 0:be9399a34b15 106 for (int i = (16 * number) - 1; i >= 0; i--)
Spencer 0:be9399a34b15 107 {
Spencer 0:be9399a34b15 108 // Get the lower 12 bits of the buffer and send
Spencer 0:be9399a34b15 109 spi.write(gsBuffer[i] & 0xFFF);
Spencer 0:be9399a34b15 110 }
Spencer 0:be9399a34b15 111
Spencer 0:be9399a34b15 112 // Latch after current GS data is done being displayed
Spencer 0:be9399a34b15 113 need_xlat = true;
Spencer 0:be9399a34b15 114
Spencer 0:be9399a34b15 115 // No new data to send (we just sent it!)
Spencer 0:be9399a34b15 116 newGSData = false;
Spencer 0:be9399a34b15 117 }
Spencer 0:be9399a34b15 118 }