PCA9955 16 channel current drive(sink) LED driver class library
PCA9955.cpp@0:2e6f5ac1b29b, 2012-08-10 (annotated)
- Committer:
- nxp_ip
- Date:
- Fri Aug 10 01:39:02 2012 +0000
- Revision:
- 0:2e6f5ac1b29b
PCA9955 sample code
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nxp_ip | 0:2e6f5ac1b29b | 1 | /** PCA9955 constant current LED driver control library |
nxp_ip | 0:2e6f5ac1b29b | 2 | * |
nxp_ip | 0:2e6f5ac1b29b | 3 | * @class PCA9955 |
nxp_ip | 0:2e6f5ac1b29b | 4 | * @author NXP Semiconductors Japan |
nxp_ip | 0:2e6f5ac1b29b | 5 | * @version 0.5(15-Jun-2011) (publish 10-Aug-2012) |
nxp_ip | 0:2e6f5ac1b29b | 6 | * |
nxp_ip | 0:2e6f5ac1b29b | 7 | * Copyright: 2011 NXP Semiconductors |
nxp_ip | 0:2e6f5ac1b29b | 8 | * Released under the MIT License: http://mbed.org/license/mit |
nxp_ip | 0:2e6f5ac1b29b | 9 | * This is a library that controls PCA9955 a constant current LED driver |
nxp_ip | 0:2e6f5ac1b29b | 10 | * Example: |
nxp_ip | 0:2e6f5ac1b29b | 11 | * @code |
nxp_ip | 0:2e6f5ac1b29b | 12 | * #include "mbed.h" |
nxp_ip | 0:2e6f5ac1b29b | 13 | * #include "PCA9955.h" |
nxp_ip | 0:2e6f5ac1b29b | 14 | * |
nxp_ip | 0:2e6f5ac1b29b | 15 | * #define MAX_IREF 0x20 |
nxp_ip | 0:2e6f5ac1b29b | 16 | * |
nxp_ip | 0:2e6f5ac1b29b | 17 | * PCA9955 led_driver( p28, p27, 0xC0 ); // making an instance of PCA9955 |
nxp_ip | 0:2e6f5ac1b29b | 18 | * |
nxp_ip | 0:2e6f5ac1b29b | 19 | * main() |
nxp_ip | 0:2e6f5ac1b29b | 20 | * { |
nxp_ip | 0:2e6f5ac1b29b | 21 | * char v[ 16 ] = { 0xFF }; |
nxp_ip | 0:2e6f5ac1b29b | 22 | * int sel; |
nxp_ip | 0:2e6f5ac1b29b | 23 | * |
nxp_ip | 0:2e6f5ac1b29b | 24 | * srand( 0 ); |
nxp_ip | 0:2e6f5ac1b29b | 25 | * |
nxp_ip | 0:2e6f5ac1b29b | 26 | * led_driver = 0xFFFF; |
nxp_ip | 0:2e6f5ac1b29b | 27 | * led_driver.set_all_intensity( v ); // PWM |
nxp_ip | 0:2e6f5ac1b29b | 28 | * led_driver.set_all_intensity( MAX_IREF, true ); // IREF |
nxp_ip | 0:2e6f5ac1b29b | 29 | * |
nxp_ip | 0:2e6f5ac1b29b | 30 | * while ( 1 ) { |
nxp_ip | 0:2e6f5ac1b29b | 31 | * for ( sel = 0; sel < 16; sel++ ) { |
nxp_ip | 0:2e6f5ac1b29b | 32 | * v[ sel ] = (char)((float)(v[ sel ]) * 0.8); |
nxp_ip | 0:2e6f5ac1b29b | 33 | * } |
nxp_ip | 0:2e6f5ac1b29b | 34 | * |
nxp_ip | 0:2e6f5ac1b29b | 35 | * v[ rand() % 16 ] = 0xFF; |
nxp_ip | 0:2e6f5ac1b29b | 36 | * |
nxp_ip | 0:2e6f5ac1b29b | 37 | * led_driver.set_all_intensity( v ); // PWM |
nxp_ip | 0:2e6f5ac1b29b | 38 | * wait( 0.05 ); |
nxp_ip | 0:2e6f5ac1b29b | 39 | * } |
nxp_ip | 0:2e6f5ac1b29b | 40 | * } |
nxp_ip | 0:2e6f5ac1b29b | 41 | * @endcode |
nxp_ip | 0:2e6f5ac1b29b | 42 | */ |
nxp_ip | 0:2e6f5ac1b29b | 43 | |
nxp_ip | 0:2e6f5ac1b29b | 44 | #include "mbed.h" |
nxp_ip | 0:2e6f5ac1b29b | 45 | #include "PCA9955.h" |
nxp_ip | 0:2e6f5ac1b29b | 46 | |
nxp_ip | 0:2e6f5ac1b29b | 47 | PCA9955::PCA9955( |
nxp_ip | 0:2e6f5ac1b29b | 48 | PinName I2C_sda, |
nxp_ip | 0:2e6f5ac1b29b | 49 | PinName I2C_scl, |
nxp_ip | 0:2e6f5ac1b29b | 50 | char I2C_address = PCA9955_ADDR |
nxp_ip | 0:2e6f5ac1b29b | 51 | ) : i2c( I2C_sda, I2C_scl ), i2c_addr( I2C_address ) { |
nxp_ip | 0:2e6f5ac1b29b | 52 | |
nxp_ip | 0:2e6f5ac1b29b | 53 | i2c.frequency( 400 * 1000 ); |
nxp_ip | 0:2e6f5ac1b29b | 54 | write( init_array, sizeof( init_array[42] ) ); |
nxp_ip | 0:2e6f5ac1b29b | 55 | } |
nxp_ip | 0:2e6f5ac1b29b | 56 | |
nxp_ip | 0:2e6f5ac1b29b | 57 | void PCA9955::set_single_individual_intensity( char port, char val, int iref ) { |
nxp_ip | 0:2e6f5ac1b29b | 58 | write( (command_reg)((iref ? IREF_REGISTER_START : PWM_REGISTER_START) + port), val ); |
nxp_ip | 0:2e6f5ac1b29b | 59 | } |
nxp_ip | 0:2e6f5ac1b29b | 60 | |
nxp_ip | 0:2e6f5ac1b29b | 61 | void PCA9955::set_all_intensity( char *p, int iref ) { |
nxp_ip | 0:2e6f5ac1b29b | 62 | char pwm[ PCA9955_N_OF_PORTS + 1 ] = { AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START) }; |
nxp_ip | 0:2e6f5ac1b29b | 63 | |
nxp_ip | 0:2e6f5ac1b29b | 64 | for ( int i = 1; i <= PCA9955_N_OF_PORTS; i++ ) |
nxp_ip | 0:2e6f5ac1b29b | 65 | pwm[ i ] = *p++; |
nxp_ip | 0:2e6f5ac1b29b | 66 | |
nxp_ip | 0:2e6f5ac1b29b | 67 | write( pwm, PCA9955_N_OF_PORTS + 1 ); |
nxp_ip | 0:2e6f5ac1b29b | 68 | } |
nxp_ip | 0:2e6f5ac1b29b | 69 | |
nxp_ip | 0:2e6f5ac1b29b | 70 | void PCA9955::set_all_intensity( char val, int iref ) { |
nxp_ip | 0:2e6f5ac1b29b | 71 | char c[ PCA9955_N_OF_PORTS ]; |
nxp_ip | 0:2e6f5ac1b29b | 72 | |
nxp_ip | 0:2e6f5ac1b29b | 73 | for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ ) |
nxp_ip | 0:2e6f5ac1b29b | 74 | c[ i ] = val; |
nxp_ip | 0:2e6f5ac1b29b | 75 | |
nxp_ip | 0:2e6f5ac1b29b | 76 | set_all_intensity( c, iref ); |
nxp_ip | 0:2e6f5ac1b29b | 77 | } |
nxp_ip | 0:2e6f5ac1b29b | 78 | |
nxp_ip | 0:2e6f5ac1b29b | 79 | void PCA9955::get_all_intensity( char *p, int iref ) { |
nxp_ip | 0:2e6f5ac1b29b | 80 | read( (command_reg)(AUTO_INCREMENT | (iref ? IREF_REGISTER_START : PWM_REGISTER_START)), p, PCA9955_N_OF_PORTS ); |
nxp_ip | 0:2e6f5ac1b29b | 81 | } |
nxp_ip | 0:2e6f5ac1b29b | 82 | |
nxp_ip | 0:2e6f5ac1b29b | 83 | void PCA9955::operator=( int c ) { |
nxp_ip | 0:2e6f5ac1b29b | 84 | char a[ 1 + (PCA9955_N_OF_PORTS / 4) ] = { AUTO_INCREMENT | LEDOUT_REGISTER_START, 0x00, 0x00, 0x00, 0x00 }; |
nxp_ip | 0:2e6f5ac1b29b | 85 | char out_val = 0x2; |
nxp_ip | 0:2e6f5ac1b29b | 86 | |
nxp_ip | 0:2e6f5ac1b29b | 87 | for ( int i = 0; i < PCA9955_N_OF_PORTS; i++ ) |
nxp_ip | 0:2e6f5ac1b29b | 88 | a[ (i / 4) + 1 ] |= (((c >> i) & 0x1) ? out_val : 0x0) << ((i % 4) << 1); |
nxp_ip | 0:2e6f5ac1b29b | 89 | |
nxp_ip | 0:2e6f5ac1b29b | 90 | write( a, sizeof( a ) ); |
nxp_ip | 0:2e6f5ac1b29b | 91 | } |
nxp_ip | 0:2e6f5ac1b29b | 92 | |
nxp_ip | 0:2e6f5ac1b29b | 93 | unsigned short PCA9955::fault_test( void ) |
nxp_ip | 0:2e6f5ac1b29b | 94 | { |
nxp_ip | 0:2e6f5ac1b29b | 95 | char mode2_reg; |
nxp_ip | 0:2e6f5ac1b29b | 96 | |
nxp_ip | 0:2e6f5ac1b29b | 97 | #define FAULTTEST 0x40 |
nxp_ip | 0:2e6f5ac1b29b | 98 | |
nxp_ip | 0:2e6f5ac1b29b | 99 | mode2_reg = read( MODE2 ); |
nxp_ip | 0:2e6f5ac1b29b | 100 | mode2_reg = 0; |
nxp_ip | 0:2e6f5ac1b29b | 101 | write( MODE2, mode2_reg | FAULTTEST ); |
nxp_ip | 0:2e6f5ac1b29b | 102 | |
nxp_ip | 0:2e6f5ac1b29b | 103 | while ( read( MODE2 ) & FAULTTEST ) |
nxp_ip | 0:2e6f5ac1b29b | 104 | ; |
nxp_ip | 0:2e6f5ac1b29b | 105 | |
nxp_ip | 0:2e6f5ac1b29b | 106 | return( ((unsigned short)(read( EFLAG1 )) << 8) | read( EFLAG0 ) ); |
nxp_ip | 0:2e6f5ac1b29b | 107 | } |
nxp_ip | 0:2e6f5ac1b29b | 108 | |
nxp_ip | 0:2e6f5ac1b29b | 109 | void PCA9955::write( char *data, int length ) { |
nxp_ip | 0:2e6f5ac1b29b | 110 | i2c.write( i2c_addr, data, length ); |
nxp_ip | 0:2e6f5ac1b29b | 111 | } |
nxp_ip | 0:2e6f5ac1b29b | 112 | |
nxp_ip | 0:2e6f5ac1b29b | 113 | void PCA9955::write( command_reg reg_addr, char data ) { |
nxp_ip | 0:2e6f5ac1b29b | 114 | char c[2]; |
nxp_ip | 0:2e6f5ac1b29b | 115 | |
nxp_ip | 0:2e6f5ac1b29b | 116 | c[0] = reg_addr; |
nxp_ip | 0:2e6f5ac1b29b | 117 | c[1] = data; |
nxp_ip | 0:2e6f5ac1b29b | 118 | |
nxp_ip | 0:2e6f5ac1b29b | 119 | i2c.write( i2c_addr, c, 2 ); |
nxp_ip | 0:2e6f5ac1b29b | 120 | } |
nxp_ip | 0:2e6f5ac1b29b | 121 | |
nxp_ip | 0:2e6f5ac1b29b | 122 | void PCA9955::read( command_reg reg_addr, char *data, int length ) { |
nxp_ip | 0:2e6f5ac1b29b | 123 | i2c.write( i2c_addr, (char *)(®_addr), 1, true ); |
nxp_ip | 0:2e6f5ac1b29b | 124 | i2c.read( i2c_addr, data, length ); |
nxp_ip | 0:2e6f5ac1b29b | 125 | } |
nxp_ip | 0:2e6f5ac1b29b | 126 | |
nxp_ip | 0:2e6f5ac1b29b | 127 | char PCA9955::read( command_reg reg_addr ) { |
nxp_ip | 0:2e6f5ac1b29b | 128 | i2c.write( i2c_addr, (char *)(®_addr), 1, true ); |
nxp_ip | 0:2e6f5ac1b29b | 129 | i2c.read( i2c_addr, (char *)(®_addr), 1 ); |
nxp_ip | 0:2e6f5ac1b29b | 130 | |
nxp_ip | 0:2e6f5ac1b29b | 131 | return ( reg_addr ); |
nxp_ip | 0:2e6f5ac1b29b | 132 | } |
nxp_ip | 0:2e6f5ac1b29b | 133 | |
nxp_ip | 0:2e6f5ac1b29b | 134 | char PCA9955::init_array[] = { |
nxp_ip | 0:2e6f5ac1b29b | 135 | AUTO_INCREMENT | REGISTER_START, // Command |
nxp_ip | 0:2e6f5ac1b29b | 136 | 0x00, 0x05, // MODE1, MODE2 |
nxp_ip | 0:2e6f5ac1b29b | 137 | 0xAA, 0xAA, 0xAA, 0xAA, // LEDOUT[3:0] |
nxp_ip | 0:2e6f5ac1b29b | 138 | 0x80, 0x00, // GRPPWM, GRPFREQ |
nxp_ip | 0:2e6f5ac1b29b | 139 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PWM[7:0] |
nxp_ip | 0:2e6f5ac1b29b | 140 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // PWM[15:8] |
nxp_ip | 0:2e6f5ac1b29b | 141 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // IREF[7:0] |
nxp_ip | 0:2e6f5ac1b29b | 142 | 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // IREF[15:8] |
nxp_ip | 0:2e6f5ac1b29b | 143 | 0x08 // OFFSET: 1uS offsets |
nxp_ip | 0:2e6f5ac1b29b | 144 | }; |
nxp_ip | 0:2e6f5ac1b29b | 145 |