PCA9955 16 channel current drive(sink) LED driver class library
PCA9955.cpp
- Committer:
- nxp_ip
- Date:
- 2012-08-10
- Revision:
- 0:2e6f5ac1b29b
File content as of revision 0:2e6f5ac1b29b:
/** 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 *)(®_addr), 1, true ); i2c.read( i2c_addr, data, length ); } char PCA9955::read( command_reg reg_addr ) { i2c.write( i2c_addr, (char *)(®_addr), 1, true ); i2c.read( i2c_addr, (char *)(®_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 };