InetrfaceProducts NXP / PCA995xA

Dependencies:   CompLedDvrCC

Dependents:   PCA9956A_Hello pca9956b_two_demoboards PCA9955A_Gradation_control PCA9955A_Gradation_control ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCA9955A.h Source File

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