PCA9955 16 channel current drive(sink) LED driver sample code

Dependencies:   mbed PCA9955

What is this?

This is a demo application code to operate the PCA9955.
The PCA9955 is a 16-channel Fm+ I2C-bus 57 mA constant current LED driver with independent current control for each channels.

/media/uploads/nxp_ip/_scaled_dsc_0374.jpg

/media/uploads/nxp_ip/pca9955-block.png

Datasheet is available in next URL.
http://www.nxp.com/documents/data_sheet/PCA9952_PCA9955.pdf

/media/uploads/nxp_ip/pca9955-application.png

Chip details

The PCA9952 and PCA9955 are I2C-bus controlled 16-channel constant current LED driver optimized for dimming and blinking 57 mA Red/Green/Blue/Amber (RGBA) LEDs in amusement products. Each LED output has its own 8-bit resolution (256 steps) fixed frequency individual PWM controller that operates at 31.25 kHz with a duty cycle that is adjustable from 0 % to 99.6 % to allow the LED to be set to a specific brightness value. An additional 8-bit resolution (256 steps) group PWM controller has both a fixed frequency of 122 Hz and an adjustable frequency between 15 Hz to once every 16.8 seconds with a duty cycle that is adjustable from 0 % to 99.6 % that is used to either dim or blink all LEDs with the same value.

Each LED output can be off, on (no PWM control), set at its individual PWM controller value or at both individual and group PWM controller values. The PCA9952 and PCA9955 operate with a supply voltage range of 3 V to 5.5 V and the constant current sink LED outputs allow up to 40 V for the LED supply. The output peak current is adjustable with an 8-bit linear DAC from 225 μA to 57 mA.

These devices have built-in open, short load and overtemperature detection circuitry. The error information from the corresponding register can be read via the I2C-bus. Additionally, a thermal shutdown feature protects the device when internal junction temperature exceeds the limit allowed for the process.

The PCA9952 and PCA9955 devices have Fast-mode Plus (Fm+) I2C-bus interface. Fm+ devices offer higher frequency (up to 1 MHz) or more densely populated bus operation (up to 4000 pF).

The PCA9952 is identical to PCA9955 except for the following differences:

  • The PCA9952 has only 3 hardware address pins compared to 4 on PCA9955.
  • The PCA9952 has an output enable pin (OE) and the PCA9955 does not.

The active LOW output enable input pin (OE), available only on PCA9952, blinks all the LED outputs and can be used to externally PWM the outputs, which is useful when multiple devices need to be dimmed or blinked together without using software control.

Software programmable LED Group and three Sub Call I2C-bus addresses allow all or defined groups of PCA9952/55 devices to respond to a common I2C-bus address, allowing for example, all red LEDs to be turned on or off at the same time or marquee chasing effect, thus minimizing I2C-bus commands. On power-up, PCA9952/55 will have a unique Sub Call address to identify it as a 16-channel LED driver. This allows mixing of devices with different channel widths. Four hardware address pins on PCA9955 allow up to 16 devices on the same bus. In the case of PCA9952, three hardware address pins allow up to 8 devices on the same bus.

The Software Reset (SWRST) function allows the master to perform a reset of the PCA9952/55 through the I2C-bus, identical to the Power-On Reset (POR) that initializes the registers to their default state causing the output current switches to be OFF (LED off). This allows an easy and quick way to reconfigure all device registers to the same condition.

Committer:
nxp_ip
Date:
Fri Aug 10 01:39:20 2012 +0000
Revision:
0:c4e84914b494
Child:
1:7e06b1057ca9
PCA9955 sample code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nxp_ip 0:c4e84914b494 1 /*
nxp_ip 0:c4e84914b494 2 * PCA9955 (I2C 16 channel LED driver) demo application
nxp_ip 0:c4e84914b494 3 *
nxp_ip 0:c4e84914b494 4 * Released under the MIT License: http://mbed.org/license/mit
nxp_ip 0:c4e84914b494 5 *
nxp_ip 0:c4e84914b494 6 * revision 1.0 15-June-2011
nxp_ip 0:c4e84914b494 7 */
nxp_ip 0:c4e84914b494 8
nxp_ip 0:c4e84914b494 9 #include "mbed.h"
nxp_ip 0:c4e84914b494 10 #include "PCA9955.h"
nxp_ip 0:c4e84914b494 11
nxp_ip 0:c4e84914b494 12 #define MAX_IREF 0x20
nxp_ip 0:c4e84914b494 13
nxp_ip 0:c4e84914b494 14 #define PI 3.14159265
nxp_ip 0:c4e84914b494 15 #define LOOP 100
nxp_ip 0:c4e84914b494 16 #define CYCLE 1.0
nxp_ip 0:c4e84914b494 17
nxp_ip 0:c4e84914b494 18 PCA9955 led_driver( p28, p27, 0xC0 ); // making an instance of PCA9955
nxp_ip 0:c4e84914b494 19
nxp_ip 0:c4e84914b494 20 DigitalOut syncpin( p21 );
nxp_ip 0:c4e84914b494 21
nxp_ip 0:c4e84914b494 22 void demo_FF( void );
nxp_ip 0:c4e84914b494 23 void demo_0( void );
nxp_ip 0:c4e84914b494 24 void demo_00( void );
nxp_ip 0:c4e84914b494 25 void demo_1( void );
nxp_ip 0:c4e84914b494 26 void demo_2( void );
nxp_ip 0:c4e84914b494 27
nxp_ip 0:c4e84914b494 28 I2C i2c( p28, p27 );
nxp_ip 0:c4e84914b494 29
nxp_ip 0:c4e84914b494 30 main() {
nxp_ip 0:c4e84914b494 31
nxp_ip 0:c4e84914b494 32 char v0[] = { 0x3B, 0x22 };
nxp_ip 0:c4e84914b494 33 char v1[] = { 0x3B, 0x20 };
nxp_ip 0:c4e84914b494 34
nxp_ip 0:c4e84914b494 35 i2c.write( 0xC0, v0, 2 );
nxp_ip 0:c4e84914b494 36 i2c.write( 0xC2, v1, 2 );
nxp_ip 0:c4e84914b494 37
nxp_ip 0:c4e84914b494 38 while ( 1 ) {
nxp_ip 0:c4e84914b494 39 //demo_FF();
nxp_ip 0:c4e84914b494 40 demo_2();
nxp_ip 0:c4e84914b494 41 //demo_0();
nxp_ip 0:c4e84914b494 42 //demo_1();
nxp_ip 0:c4e84914b494 43 }
nxp_ip 0:c4e84914b494 44 }
nxp_ip 0:c4e84914b494 45
nxp_ip 0:c4e84914b494 46 void demo_FF( void ) {
nxp_ip 0:c4e84914b494 47 unsigned short flags;
nxp_ip 0:c4e84914b494 48 unsigned int i;
nxp_ip 0:c4e84914b494 49
nxp_ip 0:c4e84914b494 50 syncpin = 1;
nxp_ip 0:c4e84914b494 51
nxp_ip 0:c4e84914b494 52 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 53 led_driver.set_all_intensity( 0x7F ); // PWM
nxp_ip 0:c4e84914b494 54
nxp_ip 0:c4e84914b494 55 printf( "\r\n\r\nFAULTTEST\r\n" );
nxp_ip 0:c4e84914b494 56
nxp_ip 0:c4e84914b494 57 while ( 1 ) {
nxp_ip 0:c4e84914b494 58 for ( i = 0; i < 256; i++ ) {
nxp_ip 0:c4e84914b494 59 led_driver.set_all_intensity( (char)i, true ); // IREF
nxp_ip 0:c4e84914b494 60 syncpin = 0;
nxp_ip 0:c4e84914b494 61 flags = led_driver.fault_test();
nxp_ip 0:c4e84914b494 62 syncpin = 1;
nxp_ip 0:c4e84914b494 63
nxp_ip 0:c4e84914b494 64 // printf( "IREF=0x%02X : flags = 0x%04X\r\n", i, flags );
nxp_ip 0:c4e84914b494 65 printf( "IREF=0x%02X : flags = 0x%04X\r", i, flags );
nxp_ip 0:c4e84914b494 66 //wait_ms( 100 );
nxp_ip 0:c4e84914b494 67 }
nxp_ip 0:c4e84914b494 68 }
nxp_ip 0:c4e84914b494 69 }
nxp_ip 0:c4e84914b494 70
nxp_ip 0:c4e84914b494 71 void demo_0( void ) {
nxp_ip 0:c4e84914b494 72 int i;
nxp_ip 0:c4e84914b494 73
nxp_ip 0:c4e84914b494 74 srand( 0xFF00 );
nxp_ip 0:c4e84914b494 75
nxp_ip 0:c4e84914b494 76 led_driver = 0x0000;
nxp_ip 0:c4e84914b494 77 led_driver.set_all_intensity( 0xFF ); // PWM
nxp_ip 0:c4e84914b494 78 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 79
nxp_ip 0:c4e84914b494 80 for ( i = 0; i < 128; i++ ) {
nxp_ip 0:c4e84914b494 81 led_driver = 0x0001 << (rand() % 16);
nxp_ip 0:c4e84914b494 82 wait( 0.05 );
nxp_ip 0:c4e84914b494 83 }
nxp_ip 0:c4e84914b494 84 }
nxp_ip 0:c4e84914b494 85
nxp_ip 0:c4e84914b494 86 void demo_00( void ) {
nxp_ip 0:c4e84914b494 87 int i;
nxp_ip 0:c4e84914b494 88
nxp_ip 0:c4e84914b494 89 srand( 0xFF00 );
nxp_ip 0:c4e84914b494 90
nxp_ip 0:c4e84914b494 91 led_driver = 0x0000;
nxp_ip 0:c4e84914b494 92 led_driver.set_all_intensity( 0xFF ); // PWM
nxp_ip 0:c4e84914b494 93 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 94
nxp_ip 0:c4e84914b494 95 for ( i = 0; i < 128; i++ ) {
nxp_ip 0:c4e84914b494 96 led_driver = rand() & 0xFFFF;
nxp_ip 0:c4e84914b494 97 wait( 0.05 );
nxp_ip 0:c4e84914b494 98 }
nxp_ip 0:c4e84914b494 99 }
nxp_ip 0:c4e84914b494 100
nxp_ip 0:c4e84914b494 101 void demo_1( void ) {
nxp_ip 0:c4e84914b494 102 char v[ 16 ] = { 0xFF };
nxp_ip 0:c4e84914b494 103 int sel;
nxp_ip 0:c4e84914b494 104 int i;
nxp_ip 0:c4e84914b494 105
nxp_ip 0:c4e84914b494 106 srand( 0xFF00 );
nxp_ip 0:c4e84914b494 107
nxp_ip 0:c4e84914b494 108 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 109 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 110 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 111
nxp_ip 0:c4e84914b494 112 for ( i = 0; i < 256; i++ ) {
nxp_ip 0:c4e84914b494 113 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 114 v[ sel ] = (char)((float)(v[ sel ]) * 0.8);
nxp_ip 0:c4e84914b494 115 }
nxp_ip 0:c4e84914b494 116
nxp_ip 0:c4e84914b494 117 v[ rand() % 16 ] = 0xFF;
nxp_ip 0:c4e84914b494 118
nxp_ip 0:c4e84914b494 119 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 120 wait( 0.05 );
nxp_ip 0:c4e84914b494 121 }
nxp_ip 0:c4e84914b494 122 }
nxp_ip 0:c4e84914b494 123
nxp_ip 0:c4e84914b494 124 void demo_2( void ) {
nxp_ip 0:c4e84914b494 125 int demo_loop;
nxp_ip 0:c4e84914b494 126 char intensity[ 3 ];
nxp_ip 0:c4e84914b494 127 char pwms[ 16 ];
nxp_ip 0:c4e84914b494 128 int color;
nxp_ip 0:c4e84914b494 129 int sel;
nxp_ip 0:c4e84914b494 130 int i;
nxp_ip 0:c4e84914b494 131
nxp_ip 0:c4e84914b494 132 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 133 led_driver.set_all_intensity( (char)0x00 ); // PWM
nxp_ip 0:c4e84914b494 134 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 135
nxp_ip 0:c4e84914b494 136 for ( demo_loop = 0; demo_loop < 10; demo_loop++ ) {
nxp_ip 0:c4e84914b494 137 for ( i = 0; i < 100; i++ ) {
nxp_ip 0:c4e84914b494 138 for ( color = 0; color < 3; color++ ) {
nxp_ip 0:c4e84914b494 139 intensity[ color ] = (char)(pow(sin( (((float)i * PI) / (float)LOOP) + (color * (PI / 3.0))), 4) * 0xFF);
nxp_ip 0:c4e84914b494 140 }
nxp_ip 0:c4e84914b494 141 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 142 pwms[ sel ] = intensity[ sel % 3 ];
nxp_ip 0:c4e84914b494 143 led_driver.set_all_intensity( pwms );
nxp_ip 0:c4e84914b494 144 }
nxp_ip 0:c4e84914b494 145 wait( (float)CYCLE / (float)LOOP );
nxp_ip 0:c4e84914b494 146 }
nxp_ip 0:c4e84914b494 147 }
nxp_ip 0:c4e84914b494 148 }
nxp_ip 0:c4e84914b494 149
nxp_ip 0:c4e84914b494 150 #if 0
nxp_ip 0:c4e84914b494 151 main() {
nxp_ip 0:c4e84914b494 152 char v[ 16 ] = { 0xFF };
nxp_ip 0:c4e84914b494 153 int sel;
nxp_ip 0:c4e84914b494 154
nxp_ip 0:c4e84914b494 155 srand( 0 );
nxp_ip 0:c4e84914b494 156
nxp_ip 0:c4e84914b494 157 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 158 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 159 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 160
nxp_ip 0:c4e84914b494 161 while ( 1 ) {
nxp_ip 0:c4e84914b494 162 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 163 v[ sel ] = (char)((float)(v[ sel ]) * 0.8);
nxp_ip 0:c4e84914b494 164 }
nxp_ip 0:c4e84914b494 165
nxp_ip 0:c4e84914b494 166 v[ rand() % 16 ] = 0xFF;
nxp_ip 0:c4e84914b494 167
nxp_ip 0:c4e84914b494 168 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 169 wait( 0.05 );
nxp_ip 0:c4e84914b494 170 }
nxp_ip 0:c4e84914b494 171 }
nxp_ip 0:c4e84914b494 172 #endif