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

Dependents:   PCA9955_Hello

Revision:
0:2e6f5ac1b29b
--- /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
+};
+