Difference between revisions of "TLC59711"
From Steak Wiki
Jump to navigationJump to search| Line 1: | Line 1: | ||
| − | The TLC59711 by Texas Instruments is a 16 bit 12 channel LED driver. It has a 224 bit stream required for each chip. The stream has 32 bits of configuration data (config + 21 brightness), and 192 bits for the LEDs. | + | The TLC59711 by Texas Instruments is a 16 bit 12 channel LED driver. It has a 224 bit stream required for each chip. The stream has 32 bits of configuration data (config + 21 brightness), and 192 bits for the LEDs. It is programmed via SPI. |
| + | |||
| + | ==Usage== | ||
| + | There is an Adafruit reference library which can be used Adafruit_TLC59711. Note that this library uses bit banging. The data sheet is also helpful. | ||
==Example Code== | ==Example Code== | ||
| Line 6: | Line 9: | ||
The SPI clock (SCK) polarity (parameter clock_idle) | The SPI clock (SCK) polarity (parameter clock_idle) | ||
The SPI data out transmit edge (parameter edge) | The SPI data out transmit edge (parameter edge) | ||
| − | |||
The SPI "Modes" | The SPI "Modes" | ||
SPI knows 4 "standard" modes, reflecting the SCK's polarity (CPOL) and the SCK's phase (CPHA). | SPI knows 4 "standard" modes, reflecting the SCK's polarity (CPOL) and the SCK's phase (CPHA). | ||
| − | |||
The definition is: | The definition is: | ||
SPI Mode CPOL CPHA | SPI Mode CPOL CPHA | ||
| Line 16: | Line 17: | ||
2 (or 1,0) 1 0 | 2 (or 1,0) 1 0 | ||
3 (or 1,1) 1 1 | 3 (or 1,1) 1 1 | ||
| − | |||
The meaning is: | The meaning is: | ||
| − | |||
CPOL: | CPOL: | ||
0 = Clock Idle low level | 0 = Clock Idle low level | ||
| Line 25: | Line 24: | ||
0 = SDO transmit edge (*) active to idle | 0 = SDO transmit edge (*) active to idle | ||
1 = SDO transmit edge idle to active | 1 = SDO transmit edge idle to active | ||
| − | |||
| − | |||
(*): the transmit edge is the clock edge at which the SDO level changes | (*): the transmit edge is the clock edge at which the SDO level changes | ||
Ref: http://www.rosseeld.be/DRO/PIC/SPI_Timing.htm | Ref: http://www.rosseeld.be/DRO/PIC/SPI_Timing.htm | ||
| − | + | ===main.c=== | |
<pre> | <pre> | ||
// DEVCFG3 | // DEVCFG3 | ||
| Line 186: | Line 183: | ||
</pre> | </pre> | ||
I also have prefetch disabled. See https://microchipdeveloper.com/32bit:mz-cache-disable | I also have prefetch disabled. See https://microchipdeveloper.com/32bit:mz-cache-disable | ||
| + | |||
| + | The example code should alternately blink one, then another LED. | ||
todo: test code | todo: test code | ||
==References== | ==References== | ||
Revision as of 15:42, 13 December 2019
The TLC59711 by Texas Instruments is a 16 bit 12 channel LED driver. It has a 224 bit stream required for each chip. The stream has 32 bits of configuration data (config + 21 brightness), and 192 bits for the LEDs. It is programmed via SPI.
Usage
There is an Adafruit reference library which can be used Adafruit_TLC59711. Note that this library uses bit banging. The data sheet is also helpful.
Example Code
This code runs on an Olimex PIC32-HMZ144 development board. Note that SPI mode 3 must be used. The SPI mode refers to whether bits are
The SPI clock (SCK) polarity (parameter clock_idle) The SPI data out transmit edge (parameter edge) The SPI "Modes" SPI knows 4 "standard" modes, reflecting the SCK's polarity (CPOL) and the SCK's phase (CPHA). The definition is: SPI Mode CPOL CPHA 0 (or 0,0) 0 0 1 (or 0,1) 0 1 2 (or 1,0) 1 0 3 (or 1,1) 1 1 The meaning is: CPOL: 0 = Clock Idle low level 1 = Clock Idle high level CPHA: 0 = SDO transmit edge (*) active to idle 1 = SDO transmit edge idle to active (*): the transmit edge is the clock edge at which the SDO level changes
Ref: http://www.rosseeld.be/DRO/PIC/SPI_Timing.htm
main.c
// DEVCFG3
// USERID = No Setting
#pragma config FMIIEN = OFF // Ethernet RMII/MII Enable (MII Enabled)
#pragma config FETHIO = OFF // Ethernet I/O Pin Select (Default Ethernet I/O)
#pragma config PGL1WAY = OFF // Permission Group Lock One Way Configuration (Allow only one reconfiguration)
#pragma config PMDL1WAY = ON // Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = ON // Peripheral Pin Select Configuration (Allow only one reconfiguration)
#pragma config FUSBIDIO = OFF // USB USBID Selection (Controlled by the USB Module)
#pragma config POSCMOD = HS
#pragma config FNOSC = SPLL
#pragma config FPLLICLK= PLL_POSC
#pragma config FPLLIDIV= DIV_2 // 6MHz
#pragma config FPLLRNG = RANGE_5_10_MHZ
#pragma config FPLLMULT= MUL_66 // 396MHz
#pragma config FPLLODIV= DIV_2 // 198MHz
#define SYSFREQ (198000000L)
#pragma config UPLLFSEL = FREQ_24MHZ // USB PLL Input Frequency Selection (USB PLL input is 24 MHz)
#pragma config UPLLEN = OFF
#pragma config DMTINTV = WIN_127_128 // DMT Count Window Interval (Window/Interval value is 127/128 counter value)
#pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
#pragma config WDTSPGM = STOP // Watchdog Timer Stop During Flash Programming (WDT stops during Flash programming)
#pragma config WINDIS = NORMAL // Watchdog Timer Window Mode (Watchdog Timer is in non-Window mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Enabled)
#pragma config FWDTWINSZ = WINSZ_25 // Watchdog Timer Window Size (Window size is 25%)
#pragma config DMTCNT = DMT31 // Deadman Timer Count Selection (2^31 (2147483648))
#pragma config FDMTEN = OFF // Deadman Timer Enable (Deadman Timer is enabled)
// DEVCFG0
#pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
#pragma config JTAGEN = OFF // JTAG Enable (JTAG Port Enabled)
#pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (Communicate on PGEC2/PGED2)
#pragma config TRCEN = OFF // Trace Enable (Trace features in the CPU are enabled)
#pragma config BOOTISA = MIPS32 // Boot ISA Selection (Boot code and Exception code is MIPS32)
#pragma config FECCCON = OFF_UNLOCKED // Dynamic Flash ECC Configuration (ECC and Dynamic ECC are disabled (ECCCON bits are writable))
#pragma config FSLEEP = OFF // Flash Sleep Mode (Flash is powered down when the device is in Sleep mode)
#pragma config DBGPER = PG_ALL // Debug Mode CPU Access Permission (Allow CPU access to all permission regions)
#pragma config EJTAGBEN = NORMAL // EJTAG Boot (Normal EJTAG functionality)
// DEVCP0
#pragma config CP = OFF // Code Protect (Protection Disabled)
//TLC5971
//0x25 b100101
//0x16 b10110
//17 x 3 bits high (brightness)
//16 x 3 bits colour
unsigned char __attribute__((coherent))testTI[28] = {0b10010110, //25, then half of 16
0b11011111, //some of 16 (3 bits), and start of brightness (5 bits for brightness)
0xFF,0xFF,//end brightness
//for color, 16 bits each
0,0,0,0,0,0,0,0, //color data for 12 channels
0,0,0,0,0,0,0,0, //
0,0,0,0,0,0,0xFF,0xFF};// channels 0 are here
//224 / 8 == 28. 4 bytes for config/brightness. 24 bytes for colour.
unsigned char __attribute__((coherent))testTI2[28] = {0b10010110,
0b11011111,
0xFF,0xFF,
0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,
0,0,0xFF,0xFF,0,0,0,0};
void configurePorts (void){
AD1CON1 = 0; // disable ADC
//SPI Ports
//UEXT / RD15 SCK6, AN33, RPD15, RD15
SPI6CONCLR = _SPI6CON_ON_MASK;
ANSELD = 0;
ANSELDCLR = _ANSELD_ANSD15_MASK;
TRISDbits.TRISD15 = 0; //output
RPD15Rbits.RPD15R = 0b0101; //assign SDO1 to RPD15
//RPD15R; SPI6CON
}
void configureSPI(void){
IEC3bits.SPI1EIE = 0; //disable interrupts
IEC3bits.SPI1RXIE = 0;
IEC3bits.SPI1TXIE = 0;
IEC3bits.SPI1EIE = 0; //enable general error flag (all three get flagged, in practice)
IEC3bits.SPI1RXIE = 0;
//SPI Priority for Interrupts
IPC27bits.SPI1TXIP = 6; //priority
IPC27bits.SPI1TXIS = 2;
IPC27bits.SPI1RXIP = 7; //priority
IPC27bits.SPI1RXIS = 3;
rData = SPI1BUF;
//enable SPI
SPI1CONbits.ON = 0; //stop & reset module
SPI1BUF = 0; //clear buffer (rx/tx)
SPI1STATbits.SPIROV = 0; //clear rx overflow
SPI1CONbits.MSTEN = 1; //master (not slave mode)
SPI1CONbits.ON = 1; //enable SPI
//Adafruit website (see led docs) remarks spi mode 3 needed so...
SPI1CONbits.CKP = 1;
SPI1CONbits.SMP = 1;//sample phase (clock "phase" to sample)
SPI1CONbits.CKE = 0;
//REQUIRED
}
//non dma spi
void SPITransmit(void){
int receivebin[150];
int number = 0;
while (number < 28){
//transmit
SPI1BUF = testTI[number];
//receive
while(SPI1STATbits.SPIRBE); //wait for buffer
receivebin[number] = SPI1BUF; // goes to /dev/null
number++;
}
}//SPI1STAT//SPI1BUF
//non dma spi
void SPITransmit2(void){ //Yes, I know this is a duplicate. Just testing.
int receivebin[150];
int number = 0;
while (number < 28){
//transmit
SPI1BUF = testTI2[number];
//receive
while(SPI1STATbits.SPIRBE); //wait for buffer
receivebin[number] = SPI1BUF; // goes to /dev/null
number++;
}
}//SPI1STAT//SPI1BUF//SPI1CON
main(){
configurePorts();
configureSPI();
int cat = 0;
while(1){
SPITransmit();
for(cat = 0;cat<400000;cat++){
asm("nop");
}
SPITransmit2();
for(cat = 0;cat<400000;cat++){
asm("nop");
}
}
I also have prefetch disabled. See https://microchipdeveloper.com/32bit:mz-cache-disable
The example code should alternately blink one, then another LED.
todo: test code