PCA9955 16 channel current drive(sink) LED driver class library

Dependents:   PCA9955_Hello

Files at this revision

API Documentation at this revision

Comitter:
nxp_ip
Date:
Fri Aug 10 01:39:02 2012 +0000
Commit message:
PCA9955 sample code

Changed in this revision

PCA9955.cpp Show annotated file Show diff for this revision Revisions of this file
PCA9955.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 2e6f5ac1b29b PCA9955.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9955.cpp	Fri Aug 10 01:39:02 2012 +0000
@@ -0,0 +1,145 @@
+/** PCA9955 constant current LED driver control library
+ *
+ *  @class   PCA9955
+ *  @author  NXP Semiconductors Japan
+ *  @version 0.5(15-Jun-2011) (publish 10-Aug-2012)
+ *
+ *  Copyright: 2011 NXP Semiconductors
+ *  Released under the MIT License: http://mbed.org/license/mit
+ *  This is a library that controls PCA9955 a constant current LED driver
+ *  Example:
+ *  @code
+ *  #include    "mbed.h"
+ *  #include    "PCA9955.h"
+ *
+ *  #define     MAX_IREF    0x20
+ *
+ *  PCA9955     led_driver( p28, p27, 0xC0 );  // making an instance of PCA9955
+ *
+ *  main()
+ *  {
+ *      char    v[ 16 ] = { 0xFF };
+ *      int     sel;
+ *
+ *      srand( 0 );
+ *
+ *      led_driver  = 0xFFFF;
+ *      led_driver.set_all_intensity( v );              //  PWM
+ *      led_driver.set_all_intensity( MAX_IREF, true ); //  IREF
+ *
+ *      while ( 1 ) {
+ *          for ( sel = 0; sel < 16; sel++ ) {
+ *              v[ sel ]  = (char)((float)(v[ sel ]) * 0.8);
+ *          }
+ *
+ *          v[ rand() % 16 ]  = 0xFF;
+ *
+ *          led_driver.set_all_intensity( v );              //  PWM
+ *          wait( 0.05 );
+ *      }
+ *  }
+ *  @endcode
+ */
+
+#include    "mbed.h"
+#include    "PCA9955.h"
+
+PCA9955::PCA9955(
+    PinName I2C_sda,
+    PinName I2C_scl,
+    char    I2C_address = PCA9955_ADDR
+) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) {
+
+    i2c.frequency( 400 * 1000 );
+    write( init_array, sizeof( init_array[42] ) );
+}
+
+void PCA9955::set_single_individual_intensity( char port, char val, int iref ) {
+    write( (command_reg)((iref ? IREF_REGISTER_START : PWM_REGISTER_START) + port), val );
+}
+
+void PCA9955::set_all_intensity( char *p, int iref ) {
+    char    pwm[ PCA9955_N_OF_PORTS + 1 ] = { AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START) };
+
+    for ( int i = 1; i <= PCA9955_N_OF_PORTS; i++ )
+        pwm[ i ]    = *p++;
+
+    write( pwm, PCA9955_N_OF_PORTS + 1 );
+}
+
+void PCA9955::set_all_intensity( char val, int iref ) {
+    char    c[ PCA9955_N_OF_PORTS ];
+
+    for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ )
+        c[ i ]    = val;
+
+    set_all_intensity( c, iref );
+}
+
+void PCA9955::get_all_intensity( char *p, int iref ) {
+    read( (command_reg)(AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START)), p, PCA9955_N_OF_PORTS );
+}
+
+void PCA9955::operator=( int c ) {
+    char    a[ 1 + (PCA9955_N_OF_PORTS / 4) ]  = { AUTO_INCREMENT | LEDOUT_REGISTER_START, 0x00, 0x00, 0x00, 0x00 };
+    char    out_val = 0x2;
+
+    for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ )
+        a[ (i / 4) + 1 ]  |= (((c >> i) & 0x1) ? out_val : 0x0) << ((i % 4) << 1);
+
+    write( a, sizeof( a ) );
+}
+
+unsigned short PCA9955::fault_test( void )
+{
+    char    mode2_reg;
+
+#define     FAULTTEST   0x40
+    
+    mode2_reg   = read( MODE2 );
+    mode2_reg   = 0;
+    write( MODE2, mode2_reg | FAULTTEST );
+    
+    while ( read( MODE2 ) & FAULTTEST )
+        ;
+    
+    return( ((unsigned short)(read( EFLAG1 )) << 8) | read( EFLAG0 ) );
+}
+
+void PCA9955::write( char *data, int length ) {
+    i2c.write( i2c_addr, data, length );
+}
+
+void PCA9955::write( command_reg reg_addr, char data ) {
+    char    c[2];
+
+    c[0]    = reg_addr;
+    c[1]    = data;
+
+    i2c.write( i2c_addr, c, 2 );
+}
+
+void PCA9955::read( command_reg reg_addr, char *data, int length ) {
+    i2c.write( i2c_addr, (char *)(&reg_addr), 1, true );
+    i2c.read(  i2c_addr, data, length );
+}
+
+char PCA9955::read( command_reg reg_addr ) {
+    i2c.write( i2c_addr, (char *)(&reg_addr), 1, true );
+    i2c.read(  i2c_addr, (char *)(&reg_addr), 1 );
+
+    return ( reg_addr );
+}
+
+char  PCA9955::init_array[] = {
+    AUTO_INCREMENT | REGISTER_START,                //  Command
+    0x00, 0x05,                                     //  MODE1, MODE2
+    0xAA, 0xAA, 0xAA, 0xAA,                         //  LEDOUT[3:0]
+    0x80, 0x00,                                     //  GRPPWM, GRPFREQ
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  PWM[7:0]
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  PWM[15:8]
+    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, //  IREF[7:0]
+    0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, //  IREF[15:8]
+    0x08                                            //  OFFSET: 1uS offsets
+};
+
diff -r 000000000000 -r 2e6f5ac1b29b PCA9955.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9955.h	Fri Aug 10 01:39:02 2012 +0000
@@ -0,0 +1,161 @@
+/** PCA9955 constant current LED driver control library
+ *
+ *  @class   PCA9955
+ *  @author  NXP Semiconductors Japan
+ *  @version 0.5(15-Jun-2011) (publish 10-Aug-2012)
+ *
+ *  Copyright: 2011 NXP Semiconductors
+ *  Released under the MIT License: http://mbed.org/license/mit
+ *  This is a library that controls PCA9955 a constant current LED driver
+ *  Example:
+ *  @code
+ *  #include    "mbed.h"
+ *  #include    "PCA9955.h"
+ *
+ *  #define     MAX_IREF    0x20
+ *
+ *  PCA9955     led_driver( p28, p27, 0xC0 );  // making an instance of PCA9955
+ *
+ *  main()
+ *  {
+ *      char    v[ 16 ] = { 0xFF };
+ *      int     sel;
+ *
+ *      srand( 0 );
+ *
+ *      led_driver  = 0xFFFF;
+ *      led_driver.set_all_intensity( v );              //  PWM
+ *      led_driver.set_all_intensity( MAX_IREF, true ); //  IREF
+ *
+ *      while ( 1 ) {
+ *          for ( sel = 0; sel < 16; sel++ ) {
+ *              v[ sel ]  = (char)((float)(v[ sel ]) * 0.8);
+ *          }
+ *
+ *          v[ rand() % 16 ]  = 0xFF;
+ *
+ *          led_driver.set_all_intensity( v );              //  PWM
+ *          wait( 0.05 );
+ *      }
+ *  }
+ *  @endcode
+ */
+
+#ifndef     MBED_PCA9955
+#define     MBED_PCA9955
+
+#include    "mbed.h"
+
+//  PCA9955 I2C address
+
+#if 0
+#define     PCA9955_ADDR            0xC0
+
+#define     PCA9955_INIT_PWM        0xFF
+#define     PCA9955_N_OF_PORTS      16
+
+#define     AUTO_INCREMENT           0x80
+#define     REGISTER_START           0x00
+#define     LEDOUT_REGISTER_START    0x02
+#define     PWM_REGISTER_START       0x0A
+#define     IREF_REGISTER_START      0x22
+#endif
+
+class PCA9955 {
+public:
+    PCA9955( PinName I2C_sda, PinName I2C_scl, char I2C_address );
+    void set_single_individual_intensity( char port, char val, int iref = false );
+    void set_all_intensity( char *p, int iref = false );
+    void set_all_intensity( char val, int iref = false );
+    void get_all_intensity( char *p, int iref = false );
+    void operator=( int c );
+    unsigned short fault_test( void );
+
+private:
+
+    enum {
+        PCA9955_ADDR            = 0xC0,
+    };
+
+    enum {
+        PCA9955_INIT_PWM        = 0xFF,
+        PCA9955_N_OF_PORTS      = 16,
+    };
+
+    typedef enum {
+        MODE1   = 0x00,
+        MODE2,
+        LEDOUT0,
+        LEDOUT1,
+        LEDOUT2,
+        LEDOUT3,
+        GRPPWM  = 0x08,
+        GRPFREQ,
+        PWM0    = 0x0A,
+        PWM1,
+        PWM2,
+        PWM3,
+        PWM4,
+        PWM5,
+        PWM6,
+        PWM7,
+        PWM8,
+        PWM9,
+        PWM10,
+        PWM11,
+        PWM12,
+        PWM13,
+        PWM14,
+        PWM15,
+        IREF0   = 0x22,
+        IREF1,
+        IREF2,
+        IREF3,
+        IREF4,
+        IREF5,
+        IREF6,
+        IREF7,
+        IREF8,
+        IREF9,
+        IREF10,
+        IREF11,
+        IREF12,
+        IREF13,
+        IREF14,
+        IREF15,
+        OFFSET  = 0x3A,
+        SUBADR1,
+        SUBADR2,
+        SUBADR3,
+        ALLCALLADR,
+        RESERVED1,
+        RESERVED2,
+        RESERVED3,
+        PWMALL,
+        IREFALL,
+        EFLAG0,
+        EFLAG1,
+
+        REGISTER_START          = MODE1,
+        LEDOUT_REGISTER_START   = LEDOUT0,
+        PWM_REGISTER_START      = PWM0,
+        IREF_REGISTER_START     = IREF0,
+    }
+    command_reg;
+
+    enum {
+        AUTO_INCREMENT          = 0x80,
+    };
+
+
+    I2C         i2c;
+    char        i2c_addr;
+    static char init_array[];
+    void        write( char *data, int length );
+    void        write( command_reg reg_addr, char data );
+    void        read( command_reg reg_addr, char *data, int length );
+    char        read( command_reg reg_addr );
+}
+;
+
+#endif  //  MBED_PCA9955