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:43:30 2012 +0000
Revision:
1:7e06b1057ca9
Parent:
0:c4e84914b494
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 1:7e06b1057ca9 6 * revision 1.0 15-June-2011 / 10-Aug-2012
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 1:7e06b1057ca9 18 PCA9955 led_driver( p28, p27, 0xC0 ); // SDA, SCL, I2C_slave_sddress
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_0( void );
nxp_ip 0:c4e84914b494 23 void demo_1( void );
nxp_ip 0:c4e84914b494 24 void demo_2( void );
nxp_ip 1:7e06b1057ca9 25 void demo_FF( void );
nxp_ip 0:c4e84914b494 26
nxp_ip 0:c4e84914b494 27 I2C i2c( p28, p27 );
nxp_ip 0:c4e84914b494 28
nxp_ip 0:c4e84914b494 29 main() {
nxp_ip 0:c4e84914b494 30
nxp_ip 0:c4e84914b494 31 while ( 1 ) {
nxp_ip 0:c4e84914b494 32 demo_2();
nxp_ip 1:7e06b1057ca9 33 demo_0();
nxp_ip 1:7e06b1057ca9 34 demo_1();
nxp_ip 1:7e06b1057ca9 35 //demo_FF();
nxp_ip 0:c4e84914b494 36 }
nxp_ip 0:c4e84914b494 37 }
nxp_ip 0:c4e84914b494 38
nxp_ip 0:c4e84914b494 39 void demo_0( void ) {
nxp_ip 0:c4e84914b494 40 int i;
nxp_ip 0:c4e84914b494 41
nxp_ip 0:c4e84914b494 42 srand( 0xFF00 );
nxp_ip 0:c4e84914b494 43
nxp_ip 0:c4e84914b494 44 led_driver = 0x0000;
nxp_ip 0:c4e84914b494 45 led_driver.set_all_intensity( 0xFF ); // PWM
nxp_ip 0:c4e84914b494 46 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 47
nxp_ip 0:c4e84914b494 48 for ( i = 0; i < 128; i++ ) {
nxp_ip 0:c4e84914b494 49 led_driver = 0x0001 << (rand() % 16);
nxp_ip 0:c4e84914b494 50 wait( 0.05 );
nxp_ip 0:c4e84914b494 51 }
nxp_ip 0:c4e84914b494 52 }
nxp_ip 0:c4e84914b494 53
nxp_ip 0:c4e84914b494 54 void demo_1( void ) {
nxp_ip 0:c4e84914b494 55 char v[ 16 ] = { 0xFF };
nxp_ip 0:c4e84914b494 56 int sel;
nxp_ip 0:c4e84914b494 57 int i;
nxp_ip 0:c4e84914b494 58
nxp_ip 0:c4e84914b494 59 srand( 0xFF00 );
nxp_ip 0:c4e84914b494 60
nxp_ip 0:c4e84914b494 61 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 62 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 63 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 64
nxp_ip 0:c4e84914b494 65 for ( i = 0; i < 256; i++ ) {
nxp_ip 0:c4e84914b494 66 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 67 v[ sel ] = (char)((float)(v[ sel ]) * 0.8);
nxp_ip 0:c4e84914b494 68 }
nxp_ip 0:c4e84914b494 69
nxp_ip 0:c4e84914b494 70 v[ rand() % 16 ] = 0xFF;
nxp_ip 0:c4e84914b494 71
nxp_ip 0:c4e84914b494 72 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 73 wait( 0.05 );
nxp_ip 0:c4e84914b494 74 }
nxp_ip 0:c4e84914b494 75 }
nxp_ip 0:c4e84914b494 76
nxp_ip 0:c4e84914b494 77 void demo_2( void ) {
nxp_ip 0:c4e84914b494 78 int demo_loop;
nxp_ip 0:c4e84914b494 79 char intensity[ 3 ];
nxp_ip 0:c4e84914b494 80 char pwms[ 16 ];
nxp_ip 0:c4e84914b494 81 int color;
nxp_ip 0:c4e84914b494 82 int sel;
nxp_ip 0:c4e84914b494 83 int i;
nxp_ip 0:c4e84914b494 84
nxp_ip 0:c4e84914b494 85 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 86 led_driver.set_all_intensity( (char)0x00 ); // PWM
nxp_ip 0:c4e84914b494 87 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 88
nxp_ip 0:c4e84914b494 89 for ( demo_loop = 0; demo_loop < 10; demo_loop++ ) {
nxp_ip 0:c4e84914b494 90 for ( i = 0; i < 100; i++ ) {
nxp_ip 0:c4e84914b494 91 for ( color = 0; color < 3; color++ ) {
nxp_ip 0:c4e84914b494 92 intensity[ color ] = (char)(pow(sin( (((float)i * PI) / (float)LOOP) + (color * (PI / 3.0))), 4) * 0xFF);
nxp_ip 0:c4e84914b494 93 }
nxp_ip 0:c4e84914b494 94 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 95 pwms[ sel ] = intensity[ sel % 3 ];
nxp_ip 0:c4e84914b494 96 led_driver.set_all_intensity( pwms );
nxp_ip 0:c4e84914b494 97 }
nxp_ip 0:c4e84914b494 98 wait( (float)CYCLE / (float)LOOP );
nxp_ip 0:c4e84914b494 99 }
nxp_ip 0:c4e84914b494 100 }
nxp_ip 0:c4e84914b494 101 }
nxp_ip 0:c4e84914b494 102
nxp_ip 1:7e06b1057ca9 103 void demo_FF( void ) {
nxp_ip 1:7e06b1057ca9 104 unsigned short flags;
nxp_ip 1:7e06b1057ca9 105 unsigned int i;
nxp_ip 1:7e06b1057ca9 106
nxp_ip 1:7e06b1057ca9 107 syncpin = 1;
nxp_ip 1:7e06b1057ca9 108
nxp_ip 1:7e06b1057ca9 109 led_driver = 0xFFFF;
nxp_ip 1:7e06b1057ca9 110 led_driver.set_all_intensity( 0x7F ); // PWM
nxp_ip 1:7e06b1057ca9 111
nxp_ip 1:7e06b1057ca9 112 printf( "\r\n\r\nFAULTTEST\r\n" );
nxp_ip 1:7e06b1057ca9 113
nxp_ip 1:7e06b1057ca9 114 while ( 1 ) {
nxp_ip 1:7e06b1057ca9 115 for ( i = 0; i < 256; i++ ) {
nxp_ip 1:7e06b1057ca9 116 led_driver.set_all_intensity( (char)i, true ); // IREF
nxp_ip 1:7e06b1057ca9 117 syncpin = 0;
nxp_ip 1:7e06b1057ca9 118 flags = led_driver.fault_test();
nxp_ip 1:7e06b1057ca9 119 syncpin = 1;
nxp_ip 1:7e06b1057ca9 120
nxp_ip 1:7e06b1057ca9 121 // printf( "IREF=0x%02X : flags = 0x%04X\r\n", i, flags );
nxp_ip 1:7e06b1057ca9 122 printf( "IREF=0x%02X : flags = 0x%04X\r", i, flags );
nxp_ip 1:7e06b1057ca9 123 //wait_ms( 100 );
nxp_ip 1:7e06b1057ca9 124 }
nxp_ip 1:7e06b1057ca9 125 }
nxp_ip 1:7e06b1057ca9 126 }
nxp_ip 1:7e06b1057ca9 127
nxp_ip 0:c4e84914b494 128 #if 0
nxp_ip 0:c4e84914b494 129 main() {
nxp_ip 0:c4e84914b494 130 char v[ 16 ] = { 0xFF };
nxp_ip 0:c4e84914b494 131 int sel;
nxp_ip 0:c4e84914b494 132
nxp_ip 0:c4e84914b494 133 srand( 0 );
nxp_ip 0:c4e84914b494 134
nxp_ip 0:c4e84914b494 135 led_driver = 0xFFFF;
nxp_ip 0:c4e84914b494 136 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 137 led_driver.set_all_intensity( MAX_IREF, true ); // IREF
nxp_ip 0:c4e84914b494 138
nxp_ip 0:c4e84914b494 139 while ( 1 ) {
nxp_ip 0:c4e84914b494 140 for ( sel = 0; sel < 16; sel++ ) {
nxp_ip 0:c4e84914b494 141 v[ sel ] = (char)((float)(v[ sel ]) * 0.8);
nxp_ip 0:c4e84914b494 142 }
nxp_ip 0:c4e84914b494 143
nxp_ip 0:c4e84914b494 144 v[ rand() % 16 ] = 0xFF;
nxp_ip 0:c4e84914b494 145
nxp_ip 0:c4e84914b494 146 led_driver.set_all_intensity( v ); // PWM
nxp_ip 0:c4e84914b494 147 wait( 0.05 );
nxp_ip 0:c4e84914b494 148 }
nxp_ip 0:c4e84914b494 149 }
nxp_ip 0:c4e84914b494 150 #endif