TLC59711
From Steak Wiki
Jump to navigationJump to searchThe 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
References
|