Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: PCA9956A_Hello pca9956b_two_demoboards PCA9955A_Gradation_control PCA9955A_Gradation_control ... more
PCA9955A.h
00001 /** PCA9955A constant current LED driver 00002 * 00003 * An operation sample of PCA9955A 16-channel Fm+ I2C-bus 57mA/20V constant current LED driver. 00004 * mbed accesses PCA9955A registers via I2C. 00005 * 00006 * @class PCA9955A 00007 * @author Akifumi (Tedd) OKANO, NXP Semiconductors 00008 * @version 0.6 00009 * @date 19-Mar-2015 (minor fix on 17-Jun-2022) 00010 * 00011 * Released under the Apache 2 license 00012 * 00013 * About PCA9955A: 00014 * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_led_display_control/PCA9955ATW.html 00015 */ 00016 00017 #ifndef MBED_PCA9955A 00018 #define MBED_PCA9955A 00019 00020 #include "mbed.h" 00021 #include "PCA995xA.h" 00022 #include "LedPwmOutCC.h" 00023 00024 /** PCA9955A class 00025 * 00026 * This is a driver code for the PCA9955A 16-channel Fm+ I2C-bus 57mA/20V constant current LED driver. 00027 * This class provides interface for PCA9955A operation and accessing its registers. 00028 * Detail information is available on next URL. 00029 * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_led_display_control/PCA9955ATW.html 00030 * 00031 * Next sample code shows operation based on low-level-API (operated by just device instane) 00032 * 00033 * Example: 00034 * @code 00035 * // PCA9955A operation sample using its device instance 00036 * 00037 * #include "mbed.h" 00038 * #include "PCA9955A.h" 00039 * PCA9955A led_cntlr( p28, p27, 0x02 ); // SDA, SCL, Slave_address(option) 00040 * 00041 * int main() 00042 * { 00043 * led_cntlr.current( ALLPORTS, 1.0 ); // Set all ports output current 100% 00044 * 00045 * while(1) { 00046 * for ( int port = 0; port < led_cntlr.number_of_ports(); port++ ) { 00047 * for ( int i = 1; i <= 100; i++ ) { 00048 * led_cntlr.pwm( port, (float)i / 100.0 ); 00049 * wait( 0.01 ); 00050 * } 00051 * } 00052 * led_cntlr.pwm( ALLPORTS, 0.0 ); 00053 * } 00054 * } 00055 * @endcode 00056 * 00057 * The high-level-API:LedPwmOutCC is also available. 00058 * It can be used like next sample code. 00059 * 00060 * @code 00061 * // PCA9955A operation sample using high-level-API 00062 * 00063 * #include "mbed.h" 00064 * #include "PCA9955A.h" 00065 * 00066 * PCA9955A led_cntlr( p28, p27, 0x02 ); // SDA, SCL, Slave_address(option) 00067 * LedPwmOutCC led0( led_cntlr, L0 ); // Instance for LED0 pin 00068 * LedPwmOutCC led1( led_cntlr, L1 ); // Instance for LED1 pin 00069 * LedPwmOutCC led2( led_cntlr, L2 ); // Instance for LED2 pin 00070 * 00071 * int main() 00072 * { 00073 * led0.current( 0.5 ); // LED0 pin current output setting to 50% 00074 * led1.current( 0.5 ); // LED1 pin current output setting to 50% 00075 * led2.current( 0.5 ); // LED2 pin current output setting to 50% 00076 * 00077 * while(1) { 00078 * 00079 * for ( float p = 1.0; p >= 0.0; p -= 0.01 ) { 00080 * led0 = p; // Set LED0 output PWM dutycycle as 'p' 00081 * wait( 0.01 ); 00082 * } 00083 * 00084 * for ( float p = 1.0; p >= 0.0; p -= 0.01 ) { 00085 * led1 = p; // Set LED1 output PWM dutycycle as 'p' 00086 * wait( 0.01 ); 00087 * } 00088 * 00089 * for ( float p = 1.0; p >= 0.0; p -= 0.01 ) { 00090 * led2 = p; // Set LED2 output PWM dutycycle as 'p' 00091 * wait( 0.01 ); 00092 * } 00093 * } 00094 * } 00095 * @endcode 00096 */ 00097 class PCA9955A : public PCA995xA 00098 { 00099 public: 00100 00101 #if DOXYGEN_ONLY 00102 /** PCA9955A pin names high-level API i.e. LedPwmOutCC */ 00103 typedef enum { 00104 L0, /**< LED0 pin */ 00105 L1, /**< LED1 pin */ 00106 L2, /**< LED2 pin */ 00107 L3, /**< LED3 pin */ 00108 L4, /**< LED4 pin */ 00109 L5, /**< LED5 pin */ 00110 L6, /**< LED6 pin */ 00111 L7, /**< LED7 pin */ 00112 L8, /**< LED8 pin */ 00113 L9, /**< LED9 pin */ 00114 L10, /**< LED10 pin */ 00115 L11, /**< LED11 pin */ 00116 L12, /**< LED12 pin */ 00117 L13, /**< LED13 pin */ 00118 L14, /**< LED14 pin */ 00119 L15, /**< LED15 pin */ 00120 L_NC = ~0x0L /**< for when the pin is left no-connection */ 00121 } LedPinName; 00122 #endif // DOXYGEN_ONLY 00123 00124 /** Name of the PCA9955A registers (for direct register access) */ 00125 enum command_reg { 00126 MODE1 = 0x00, /**< MODE1 register */ 00127 MODE2, /**< MODE2 register */ 00128 LEDOUT0, /**< LEDOUT0 register */ 00129 LEDOUT1, /**< LEDOUT1 register */ 00130 LEDOUT2, /**< LEDOUT2 register */ 00131 LEDOUT3, /**< LEDOUT3 register */ 00132 GRPPWM = 0x06, /**< GRPPWM register */ 00133 GRPFREQ, /**< GRPFREQ register */ 00134 PWM0, /**< PWM0 register */ 00135 PWM1, /**< PWM1 register */ 00136 PWM2, /**< PWM2 register */ 00137 PWM3, /**< PWM3 register */ 00138 PWM4, /**< PWM4 register */ 00139 PWM5, /**< PWM5 register */ 00140 PWM6, /**< PWM6 register */ 00141 PWM7, /**< PWM7 register */ 00142 PWM8, /**< PWM8 register */ 00143 PWM9, /**< PWM9 register */ 00144 PWM10, /**< PWM10 register */ 00145 PWM11, /**< PWM11 register */ 00146 PWM12, /**< PWM12 register */ 00147 PWM13, /**< PWM13 register */ 00148 PWM14, /**< PWM14 register */ 00149 PWM15, /**< PWM15 register */ 00150 IREF0, /**< IREF0 register */ 00151 IREF1, /**< IREF1 register */ 00152 IREF2, /**< IREF2 register */ 00153 IREF3, /**< IREF3 register */ 00154 IREF4, /**< IREF4 register */ 00155 IREF5, /**< IREF5 register */ 00156 IREF6, /**< IREF6 register */ 00157 IREF7, /**< IREF7 register */ 00158 IREF8, /**< IREF8 register */ 00159 IREF9, /**< IREF9 register */ 00160 IREF10, /**< IREF10 register */ 00161 IREF11, /**< IREF11 register */ 00162 IREF12, /**< IREF12 register */ 00163 IREF13, /**< IREF13 register */ 00164 IREF14, /**< IREF14 register */ 00165 IREF15, /**< IREF15 register */ 00166 RAMP_RATE_GRP0, /**< RAMP_RATE_GRP0 register */ 00167 STEP_TIME_GRP0, /**< STEP_TIME_GRP0 register */ 00168 HOLD_CNTL_GRP0, /**< HOLD_CNTL_GRP0 register */ 00169 IREF_GRP0, /**< IREF_GRP0 register */ 00170 RAMP_RATE_GRP1, /**< RAMP_RATE_GRP1 register */ 00171 STEP_TIME_GRP1, /**< STEP_TIME_GRP1 register */ 00172 HOLD_CNTL_GRP1, /**< HOLD_CNTL_GRP1 register */ 00173 IREF_GRP1, /**< IREF_GRP1 register */ 00174 RAMP_RATE_GRP2, /**< RAMP_RATE_GRP2 register */ 00175 STEP_TIME_GRP2, /**< STEP_TIME_GRP2 register */ 00176 HOLD_CNTL_GRP2, /**< HOLD_CNTL_GRP2 register */ 00177 IREF_GRP2, /**< IREF_GRP2 register */ 00178 RAMP_RATE_GRP3, /**< RAMP_RATE_GRP3 register */ 00179 STEP_TIME_GRP3, /**< STEP_TIME_GRP3 register */ 00180 HOLD_CNTL_GRP3, /**< HOLD_CNTL_GRP3 register */ 00181 IREF_GRP3, /**< IREF_GRP3 register */ 00182 GRAD_MODE_SEL0 = 0x38, /**< GRAD_MODE_SEL0 register */ 00183 GRAD_MODE_SEL1, /**< GRAD_MODE_SEL1 register */ 00184 GRAD_GRP_SEL0, /**< GRAD_GRP_SEL0 register */ 00185 GRAD_GRP_SEL1, /**< GRAD_GRP_SEL1 register */ 00186 GRAD_GRP_SEL2, /**< GRAD_GRP_SEL2 register */ 00187 GRAD_GRP_SEL3, /**< GRAD_GRP_SEL3 register */ 00188 GRAD_CNTL, /**< GRAD_CNTL register */ 00189 OFFSET = 0x3F, /**< OFFSET register */ 00190 SUBADR1, /**< SUBADR1 register */ 00191 SUBADR2, /**< SUBADR2 register */ 00192 SUBADR3, /**< SUBADR3 register */ 00193 ALLCALLADR, /**< ALLCALLADR register */ 00194 PWMALL, /**< PWMALL register */ 00195 IREFALL, /**< IREFALL register */ 00196 EFLAG0, /**< EFLAG0 register */ 00197 EFLAG1, /**< EFLAG1 register */ 00198 00199 REGISTER_START = MODE1, 00200 LEDOUT_REGISTER_START = LEDOUT0, 00201 PWM_REGISTER_START = PWM0, 00202 IREF_REGISTER_START = IREF0, 00203 GRAD_GROUP_OFFSET = RAMP_RATE_GRP1 - RAMP_RATE_GRP0 00204 }; 00205 00206 /** Create a PCA9955A instance connected to specified I2C pins with specified address 00207 * 00208 * @param i2c_sda I2C-bus SDA pin 00209 * @param i2c_sda I2C-bus SCL pin 00210 * @param i2c_address (option) I2C-bus address (default: 0xC0) 00211 */ 00212 PCA9955A( PinName i2c_sda, PinName i2c_scl, char i2c_address = PCA995xA::DEFAULT_I2C_ADDR ); 00213 00214 /** Create a PCA9955A instance connected to specified I2C pins with specified address 00215 * 00216 * @param i2c_obj I2C object (instance) 00217 * @param i2c_address (option) I2C-bus address (default: 0xC0) 00218 */ 00219 PCA9955A( I2C &i2c_obj, char i2c_address = PCA995xA::DEFAULT_I2C_ADDR ); 00220 00221 /** Destractor 00222 * 00223 */ 00224 virtual ~PCA9955A(); 00225 00226 /** Returns the number of output ports 00227 * 00228 * @returns 00229 * The number of output ports 00230 */ 00231 virtual int number_of_ports( void ); 00232 00233 #if DOXYGEN_ONLY 00234 /** Set the output duty-cycle, specified as a percentage (float) 00235 * 00236 * @param port Selecting output port 00237 * 'ALLPORTS' can be used to set all port duty-cycle same value. 00238 * @param v A floating-point value representing the output duty-cycle, 00239 * specified as a percentage. The value should lie between 00240 * 0.0f (representing on 0%) and 1.0f (representing on 100%). 00241 * Values outside this range will have undefined behavior. 00242 */ 00243 void pwm( int port, float v ); 00244 00245 /** Set all output port duty-cycle, specified as a percentage (array of float) 00246 * 00247 * @param vp Aray to floating-point values representing the output duty-cycle, 00248 * specified as a percentage. The value should lie between 00249 * 0.0f (representing on 0%) and 1.0f (representing on 100%). 00250 * 00251 * @note 00252 * The aray should have length of 16 00253 */ 00254 void pwm( float *vp ); 00255 00256 /** Set the output current, specified as a percentage (float) 00257 * 00258 * @param port Selecting output port 00259 * 'ALLPORTS' can be used to set all port current same value. 00260 * @param v A floating-point value representing the output current, 00261 * specified as a percentage. The value should lie between 00262 * 0.0f (representing on 0%) and 1.0f (representing on 100%). 00263 * Values outside this range will have undefined behavior. 00264 */ 00265 void current( int port, float vp ); 00266 00267 /** Set all output port curent, specified as a percentage (array of float) 00268 * 00269 * @param vp Aray to floating-point values representing the output current, 00270 * specified as a percentage. The value should lie between 00271 * 0.0f (representing on 0%) and 1.0f (representing on 100%). 00272 * 00273 * @note 00274 * The aray should have length of 16 00275 */ 00276 void current( float *vP ); 00277 00278 /** Register write (single byte) : Low level access to device register 00279 * 00280 * @param reg_addr Register address 00281 * @param data Value for setting into the register 00282 */ 00283 void write( char reg_addr, char data ); 00284 00285 /** Register write (multiple bytes) : Low level access to device register 00286 * 00287 * @param data Pointer to an array. First 1 byte should be the writing start register address 00288 * @param length Length of data 00289 */ 00290 void write( char *data, int length ); 00291 00292 /** Register read (single byte) : Low level access to device register 00293 * 00294 * @param reg_addr Register address 00295 * @return Read value from register 00296 */ 00297 char read( char reg_addr ); 00298 00299 /** Register write (multiple bytes) : Low level access to device register 00300 * 00301 * @param reg_addr Register address 00302 * @param data Pointer to an array. The values are stored in this array. 00303 * @param length Length of data 00304 */ 00305 void read( char reg_addr, char *data, int length ); 00306 #endif 00307 00308 /** Gradation control setting 00309 * 00310 * Auto calculation and register setting API for gradation control. 00311 * User can set the gradation by specifying cycle, hold-ON/OFF time and ramp-up/down enabling. 00312 * All register values are calcurated automatically to have fine gradation setting. 00313 * In this routine, the IREF (current) setting is fixed to maximum (i.e. 0xFF) 00314 * 00315 * @param group Group selector 00316 * @param cycle Ramp rate register (RAMP_RATE_GRPn) value 00317 * @param flag_on Holding time for ON can be selected from available constants. 00318 * Those are 0, 0.25, 0.5, 0.75, 1, 2, 4 and 6 seconds. 00319 * Use one of next words: HOLD_0_00_SEC, HOLD_0_25_SEC, HOLD_0_50_SEC, HOLD_0_75_SEC, HOLD_1_00_SEC, HOLD_2_00_SEC, HOLD_4_00_SEC or HOLD_6_00_SEC 00320 * @param flag_off Holding time for OFF can be selected from available constants. 00321 * Those are 0, 0.25, 0.5, 0.75, 1, 2, 4 and 6 seconds. 00322 * Use one of next words: HOLD_0_00_SEC, HOLD_0_25_SEC, HOLD_0_50_SEC, HOLD_0_75_SEC, HOLD_1_00_SEC, HOLD_2_00_SEC, HOLD_4_00_SEC or HOLD_6_00_SEC 00323 * @param ramp_flag Choose one from next words : NO_RAMP, RAMP_UP_ONLY, RAMP_DOWN_ONLY or RAMP_UP_DOWN 00324 * 00325 * @return calculated actual time for one cycle (in seconds) 00326 * 00327 * @see gradation_setting() 00328 */ 00329 float gradation_ramp_setting( char group, float cycle, char flag_on, char flag_off, int ramp_flag ); 00330 00331 /** Gradation control: Port assignment to group 00332 * 00333 * Each ports which is going to use in gradation control should be assigned to group. 00334 * This function help to assign the port to 1 of 4 groups. 00335 * 00336 * @param group Target group 00337 * @param port A output port which is being assigned to the target group 00338 */ 00339 void gradation_group_setting( char group, char port ); 00340 00341 /** Gradation control: Start 00342 * 00343 * @param group Group selector 00344 * @param continuous_flag (option) Set false for one-shot operation 00345 */ 00346 void gradation_start( char group, char continuous_flag = true ); 00347 00348 /** Gradation control: Stop 00349 * 00350 */ 00351 void gradation_stop( void ); 00352 00353 00354 /** Gradation control: Clear all group assignments 00355 * 00356 * Set all output port operation to no-gradation control 00357 * 00358 */ 00359 void gradation_group_clear( void ); 00360 00361 /** Setting gradation control registers (low level setting API) 00362 * 00363 * @param group Group selector 00364 * @param ramp_rate Ramp rate register (RAMP_RATE_GRPn) value 00365 * @param step_time Step time register (STEP_TIME_GRPn) value 00366 * @param hold_cntl Hold control register (HOLD_CNTL_GRPn) value 00367 * @param iref IREF (current setting) register (IREF_GRPn) value 00368 * 00369 * @see gradation_ramp_setting() 00370 */ 00371 void gradation_setting( int group, char ramp_rate, char step_time, char hold_cntl, char iref ); 00372 00373 /** Setting gradation register dump (for debugging) 00374 * 00375 */ 00376 void dump_gradation_registers( void ); 00377 00378 private: 00379 void initialize( void ); 00380 virtual char pwm_register_access( int port ); 00381 virtual char current_register_access( int port ); 00382 00383 void group_selector( short g0, short g1, short g2, short g3 ); 00384 00385 const int n_of_ports; 00386 static char gradation_group[]; 00387 } 00388 ; 00389 00390 /** Constants for Gradation control */ 00391 enum GradationControlConstants { 00392 CONTINUOUS = 1, 00393 NOGROUP = 0xFF 00394 }; 00395 00396 /** Flags for Gradation control (Ramp selector) */ 00397 enum GradationControlRampSelector { 00398 NO_RAMP = 0x0, 00399 RAMP_UP_ONLY, 00400 RAMP_DOWN_ONLY, 00401 RAMP_UP_DOWN 00402 }; 00403 00404 /** Flags for Gradation control (Hold time selector) */ 00405 enum GradationControlHoldTimeSelector { 00406 HOLD_0_00_SEC = 0x0, 00407 HOLD_0_25_SEC, 00408 HOLD_0_50_SEC, 00409 HOLD_0_75_SEC, 00410 HOLD_1_00_SEC, 00411 HOLD_2_00_SEC, 00412 HOLD_4_00_SEC, 00413 HOLD_6_00_SEC 00414 }; 00415 00416 #endif // MBED_PCA9955A
Generated on Wed Jul 13 2022 08:07:57 by
