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

Dependents:   PCA9955_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCA9955.cpp Source File

PCA9955.cpp

00001 /** PCA9955 constant current LED driver control library
00002  *
00003  *  @class   PCA9955
00004  *  @author  NXP Semiconductors Japan
00005  *  @version 0.5(15-Jun-2011) (publish 10-Aug-2012)
00006  *
00007  *  Copyright: 2011 NXP Semiconductors
00008  *  Released under the MIT License: http://mbed.org/license/mit
00009  *  This is a library that controls PCA9955 a constant current LED driver
00010  *  Example:
00011  *  @code
00012  *  #include    "mbed.h"
00013  *  #include    "PCA9955.h"
00014  *
00015  *  #define     MAX_IREF    0x20
00016  *
00017  *  PCA9955     led_driver( p28, p27, 0xC0 );  // making an instance of PCA9955
00018  *
00019  *  main()
00020  *  {
00021  *      char    v[ 16 ] = { 0xFF };
00022  *      int     sel;
00023  *
00024  *      srand( 0 );
00025  *
00026  *      led_driver  = 0xFFFF;
00027  *      led_driver.set_all_intensity( v );              //  PWM
00028  *      led_driver.set_all_intensity( MAX_IREF, true ); //  IREF
00029  *
00030  *      while ( 1 ) {
00031  *          for ( sel = 0; sel < 16; sel++ ) {
00032  *              v[ sel ]  = (char)((float)(v[ sel ]) * 0.8);
00033  *          }
00034  *
00035  *          v[ rand() % 16 ]  = 0xFF;
00036  *
00037  *          led_driver.set_all_intensity( v );              //  PWM
00038  *          wait( 0.05 );
00039  *      }
00040  *  }
00041  *  @endcode
00042  */
00043 
00044 #include    "mbed.h"
00045 #include    "PCA9955.h"
00046 
00047 PCA9955::PCA9955(
00048     PinName I2C_sda,
00049     PinName I2C_scl,
00050     char    I2C_address = PCA9955_ADDR
00051 ) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) {
00052 
00053     i2c.frequency( 400 * 1000 );
00054     write( init_array, sizeof( init_array[42] ) );
00055 }
00056 
00057 void PCA9955::set_single_individual_intensity( char port, char val, int iref ) {
00058     write( (command_reg)((iref ? IREF_REGISTER_START : PWM_REGISTER_START) + port), val );
00059 }
00060 
00061 void PCA9955::set_all_intensity( char *p, int iref ) {
00062     char    pwm[ PCA9955_N_OF_PORTS + 1 ] = { AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START) };
00063 
00064     for ( int i = 1; i <= PCA9955_N_OF_PORTS; i++ )
00065         pwm[ i ]    = *p++;
00066 
00067     write( pwm, PCA9955_N_OF_PORTS + 1 );
00068 }
00069 
00070 void PCA9955::set_all_intensity( char val, int iref ) {
00071     char    c[ PCA9955_N_OF_PORTS ];
00072 
00073     for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ )
00074         c[ i ]    = val;
00075 
00076     set_all_intensity( c, iref );
00077 }
00078 
00079 void PCA9955::get_all_intensity( char *p, int iref ) {
00080     read( (command_reg)(AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START)), p, PCA9955_N_OF_PORTS );
00081 }
00082 
00083 void PCA9955::operator=( int c ) {
00084     char    a[ 1 + (PCA9955_N_OF_PORTS / 4) ]  = { AUTO_INCREMENT | LEDOUT_REGISTER_START, 0x00, 0x00, 0x00, 0x00 };
00085     char    out_val = 0x2;
00086 
00087     for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ )
00088         a[ (i / 4) + 1 ]  |= (((c >> i) & 0x1) ? out_val : 0x0) << ((i % 4) << 1);
00089 
00090     write( a, sizeof( a ) );
00091 }
00092 
00093 unsigned short PCA9955::fault_test( void )
00094 {
00095     char    mode2_reg;
00096 
00097 #define     FAULTTEST   0x40
00098     
00099     mode2_reg   = read( MODE2 );
00100     mode2_reg   = 0;
00101     write( MODE2, mode2_reg | FAULTTEST );
00102     
00103     while ( read( MODE2 ) & FAULTTEST )
00104         ;
00105     
00106     return( ((unsigned short)(read( EFLAG1 )) << 8) | read( EFLAG0 ) );
00107 }
00108 
00109 void PCA9955::write( char *data, int length ) {
00110     i2c.write( i2c_addr, data, length );
00111 }
00112 
00113 void PCA9955::write( command_reg reg_addr, char data ) {
00114     char    c[2];
00115 
00116     c[0]    = reg_addr;
00117     c[1]    = data;
00118 
00119     i2c.write( i2c_addr, c, 2 );
00120 }
00121 
00122 void PCA9955::read( command_reg reg_addr, char *data, int length ) {
00123     i2c.write( i2c_addr, (char *)(&reg_addr), 1, true );
00124     i2c.read(  i2c_addr, data, length );
00125 }
00126 
00127 char PCA9955::read( command_reg reg_addr ) {
00128     i2c.write( i2c_addr, (char *)(&reg_addr), 1, true );
00129     i2c.read(  i2c_addr, (char *)(&reg_addr), 1 );
00130 
00131     return ( reg_addr );
00132 }
00133 
00134 char  PCA9955::init_array[] = {
00135     AUTO_INCREMENT | REGISTER_START,                //  Command
00136     0x00, 0x05,                                     //  MODE1, MODE2
00137     0xAA, 0xAA, 0xAA, 0xAA,                         //  LEDOUT[3:0]
00138     0x80, 0x00,                                     //  GRPPWM, GRPFREQ
00139     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  PWM[7:0]
00140     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  PWM[15:8]
00141     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, //  IREF[7:0]
00142     0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, //  IREF[15:8]
00143     0x08                                            //  OFFSET: 1uS offsets
00144 };
00145