Difference between revisions of "TLC59711"

From Steak Wiki
Jump to navigationJump to search
(Created page with "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...")
 
Line 31: Line 31:
  
 
Example Code:
 
Example Code:
 +
<pre>
 +
// 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");               
 +
                }
 +
}
 +
 +
</pre>
 +
I also have prefetch disabled. See https://microchipdeveloper.com/32bit:mz-cache-disable
 +
 +
todo: test code
  
 
==References==
 
==References==

Revision as of 15:37, 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.

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

Example Code:

// 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

todo: test code

References