16-channel, 12-bit PWM Fm I2C-bus LED controller

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCA9685.cpp Source File

PCA9685.cpp

00001 /**
00002  * @brief       PCA9685.h
00003  * @details     16-channel, 12-bit PWM Fm+ I2C-bus LED controller.
00004  *              Functions file.
00005  *
00006  *
00007  * @return      NA
00008  *
00009  * @author      Manuel Caballero
00010  * @date        7/November/2017
00011  * @version     7/November/2017    The ORIGIN
00012  * @pre         NaN.
00013  * @warning     NaN
00014  * @pre         This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
00015  */
00016 
00017 #include "PCA9685.h"
00018 
00019 
00020 PCA9685::PCA9685 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq )
00021     : i2c          ( sda, scl )
00022     , PCA9685_Addr ( addr )
00023 {
00024     i2c.frequency( freq );
00025 }
00026 
00027 
00028 PCA9685::~PCA9685()
00029 {
00030 }
00031 
00032 
00033 
00034 /**
00035  * @brief       PCA9685_SoftReset ( void )
00036  *
00037  * @details     It performs a software reset.
00038  *
00039  * @param[in]    NaN.
00040  *
00041  * @param[out]   NaN.
00042  *
00043  *
00044  * @return       Status of PCA9685_SoftReset.
00045  *
00046  *
00047  * @author      Manuel Caballero
00048  * @date        7/November/2017
00049  * @version     7/November/2017     The ORIGIN
00050  * @pre         The device will be ready to be addressed again within
00051  *              the specified bus free time ( t_BUF ).
00052  * @warning     NaN.
00053  */
00054 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SoftReset   ( void )
00055 {
00056     char         cmd   =   SWRST ;
00057     uint32_t     aux;
00058 
00059 
00060 
00061     aux = i2c.write ( GENERAL_CALL_ADDRESS , &cmd, 1, false );
00062 
00063 
00064 
00065     if ( aux == I2C_SUCCESS  )
00066         return   PCA9685_SUCCESS;
00067     else
00068         return   PCA9685_FAILURE;
00069 }
00070 
00071 
00072 
00073 
00074 /**
00075  * @brief       PCA9685_SetMode ( PCA9685_mode1_sleep_t )
00076  *
00077  * @details     It configures the device in Low power mode or in Normal operation
00078  *              mode.
00079  *
00080  * @param[in]    myMode:            Sleep or Normal mode.
00081  *
00082  * @param[out]   NaN.
00083  *
00084  *
00085  * @return       Status of PCA9685_SetMode.
00086  *
00087  *
00088  * @author      Manuel Caballero
00089  * @date        7/November/2017
00090  * @version     7/November/2017     The ORIGIN
00091  * @pre         NaN.
00092  * @warning     NaN.
00093  */
00094 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetMode   ( PCA9685_mode1_sleep_t myMode )
00095 {
00096     char     cmd[]   =   { MODE1 , 0 };
00097     uint32_t aux;
00098 
00099 
00100     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00101     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00102     cmd[1]  &=  ~MODE1_SLEEP_MASK ;
00103     cmd[1]  |=   myMode;
00104 
00105 
00106     aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00107 
00108 
00109 
00110     if ( aux == I2C_SUCCESS  )
00111         return   PCA9685_SUCCESS;
00112     else
00113         return   PCA9685_FAILURE;
00114 }
00115 
00116 
00117 
00118 
00119 /**
00120  * @brief       PCA9685_SetPWM_Freq ( float )
00121  *
00122  * @details     It sets a new PWM frequency.
00123  *
00124  * @param[in]    myNewFrequency:    New PWM frequency.
00125  *
00126  * @param[out]   NaN.
00127  *
00128  *
00129  * @return       Status of PCA9685_SetPWM_Freq.
00130  *
00131  *
00132  * @author      Manuel Caballero
00133  * @date        7/November/2017
00134  * @version     7/November/2017     The ORIGIN
00135  * @pre         This library can ONLY work with the internal clock, otherwise
00136  *              PCA9685_INTERNAL_CLOCK must be changed in the header file.
00137  * @warning     NaN.
00138  */
00139 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetPWM_Freq ( float myNewFrequency )
00140 {
00141     char     cmd[]       =   { MODE1 , 0 };
00142     char     prev_mode1  =   0;
00143     uint32_t aux;
00144 
00145 
00146     // The maximum PWM frequency is 1526 Hz and the minimum PWM frequency is 24 Hz.
00147     if ( ( myNewFrequency < 24 ) || ( myNewFrequency > 1526 ) )
00148         return   PCA9685_FAILURE;
00149 
00150 
00151     // The device MUST be in SLEEP mode
00152     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00153     aux      =   i2c.read  ( PCA9685_Addr, &prev_mode1, 1 );
00154     cmd[1]   =   ( prev_mode1 | MODE1_SLEEP_ENABLED  );
00155     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00156 
00157 
00158     // Calculate the new PWM frequency
00159     if ( myNewFrequency == 24 )
00160         cmd[1]   =   255;
00161     else
00162         cmd[1]   =   _MYROUND ( ( PCA9685_INTERNAL_CLOCK  / ( PCA9685_ADC_STEPS  * myNewFrequency ) ) - 1 );
00163 
00164 
00165     cmd[0]   =   PRE_SCALE ;
00166     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00167 
00168 
00169     // Restore the device's mode
00170     cmd[0]   =   MODE1 ;
00171     cmd[1]   =   prev_mode1;
00172     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00173 
00174 
00175 
00176 
00177     if ( aux == I2C_SUCCESS  )
00178         return   PCA9685_SUCCESS;
00179     else
00180         return   PCA9685_FAILURE;
00181 }
00182 
00183 
00184 
00185 
00186 /**
00187  * @brief       PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t , uint8_t , uint8_t )
00188  *
00189  * @details     It sets a new PWM duty cycle on the given LED ( channel ).
00190  *
00191  * @param[in]    myLEDchannel:      Chosen LED ( channel ).
00192  * @param[in]    myDelay:           PWM delay.
00193  * @param[in]    myPWM_DutyCycle:   PWM duty cycle.
00194  *
00195  * @param[out]   NaN.
00196  *
00197  *
00198  * @return       Status of PCA9685_SetPWM_DutyCycle.
00199  *
00200  *
00201  * @author      Manuel Caballero
00202  * @date        7/November/2017
00203  * @version     7/November/2017     The ORIGIN
00204  * @pre         Datasheet p.17 ( Example 1 and Example 2).
00205  * @warning     NaN.
00206  */
00207 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t  myLEDchannel, uint8_t myDelay, uint8_t myPWM_DutyCycle )
00208 {
00209     char     cmd[]       =   { 0, 0 };
00210     uint32_t myAux       =   0;
00211     uint32_t aux;
00212 
00213 
00214     // The range is from 0% up to 100%.
00215     if ( ( myDelay > 100 ) || ( myPWM_DutyCycle > 100 ) )
00216         return   PCA9685_FAILURE;
00217 
00218 
00219     // Delay time cannot be 0%
00220     if ( myDelay == 0 )
00221         myDelay  =   1;
00222 
00223 
00224     // DELAY TIME: LEDn_ON_L + LEDn_ON_H
00225     myAux   =   _MYROUND ( ( myDelay / 100.0 ) * PCA9685_ADC_STEPS  ) - 1;
00226 
00227     // LEDn_ON_L
00228     cmd[0]  =   LED0_ON_L  + ( myLEDchannel << 2 );
00229     cmd[1]  =   ( myAux & 0xFF );
00230 
00231     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00232 
00233     // LEDn_ON_H
00234     cmd[0]  =   LED0_ON_H  + ( myLEDchannel << 2 );
00235 
00236     if ( myPWM_DutyCycle == 100 )
00237         cmd[1]  =   0x10;                                   // LEDn full ON
00238     else
00239         cmd[1]  =   ( ( myAux >> 8 ) & 0xFF );
00240 
00241     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00242 
00243 
00244 
00245     // LED OFF TIME: LEDn_OFF_L + LEDn_OFF_H
00246     myAux  +=    _MYROUND ( ( myPWM_DutyCycle / 100.0 ) * PCA9685_ADC_STEPS  );
00247 
00248     if ( ( myDelay + myPWM_DutyCycle ) <= 100 )
00249         myAux--;
00250     else
00251         myAux    =   ( myAux - 4096 );
00252 
00253 
00254     // LEDn_OFF_L
00255     cmd[0]  =   LED0_OFF_L  + ( myLEDchannel << 2 );
00256     cmd[1]  =   ( myAux & 0xFF );
00257 
00258     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00259 
00260     // LEDn_OFF_H
00261     cmd[0]  =   LED0_OFF_H  + ( myLEDchannel << 2 );
00262 
00263     if ( myPWM_DutyCycle == 0 )
00264         cmd[1]  =   0x10;                                   // LEDn full OFF
00265     else
00266         cmd[1]  =   ( ( myAux >> 8 ) & 0xFF );
00267 
00268     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00269 
00270 
00271 
00272 
00273 
00274     if ( aux == I2C_SUCCESS  )
00275         return   PCA9685_SUCCESS;
00276     else
00277         return   PCA9685_FAILURE;
00278 }
00279 
00280 
00281 
00282 
00283 /**
00284  * @brief       PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t , uint8_t )
00285  *
00286  * @details     It sets a new PWM duty cycle on all LEDs ( all channels ).
00287  *
00288  * @param[in]    myDelay:           PWM delay.
00289  * @param[in]    myPWM_DutyCycle:   PWM duty cycle.
00290  *
00291  * @param[out]   NaN.
00292  *
00293  *
00294  * @return       Status of PCA9685_SetPWM_DutyCycle_AllLEDs.
00295  *
00296  *
00297  * @author      Manuel Caballero
00298  * @date        7/November/2017
00299  * @version     7/November/2017     The ORIGIN
00300  * @pre         Datasheet p.17 ( Example 1 and Example 2).
00301  * @warning     NaN.
00302  */
00303 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t myDelay, uint8_t myPWM_DutyCycle )
00304 {
00305     char      cmd[]       =   { 0, 0 };
00306     uint32_t  myAux       =   0;
00307     uint32_t  aux;
00308 
00309 
00310     // The range is from 0% up to 100%.
00311     if ( ( myDelay > 100 ) || ( myPWM_DutyCycle > 100 ) )
00312         return   PCA9685_FAILURE;
00313 
00314 
00315     // Delay time cannot be 0%
00316     if ( myDelay == 0 )
00317         myDelay  =   1;
00318 
00319 
00320     // DELAY TIME: LEDs_ON_L + LEDs_ON_H
00321     myAux   =   _MYROUND ( ( myDelay / 100.0 ) * PCA9685_ADC_STEPS  ) - 1;
00322 
00323     // LEDs_ON_L
00324     cmd[0]  =   ALL_LED_ON_L ;
00325     cmd[1]  =   ( myAux & 0xFF );
00326 
00327     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00328 
00329     // LEDs_ON_H
00330     cmd[0]  =   ALL_LED_ON_H ;
00331 
00332     if ( myPWM_DutyCycle == 100 )
00333         cmd[1]  =   0x10;                                   // All LEDs full ON
00334     else
00335         cmd[1]  =   ( ( myAux >> 8 ) & 0xFF );
00336 
00337     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00338 
00339 
00340 
00341     // LED OFF TIME: LEDs_OFF_L + LEDs_OFF_H
00342     myAux  +=    _MYROUND ( ( myPWM_DutyCycle / 100.0 ) * PCA9685_ADC_STEPS  );
00343 
00344     if ( ( myDelay + myPWM_DutyCycle ) <= 100 )
00345         myAux--;
00346     else
00347         myAux    =   ( myAux - 4096 );
00348 
00349 
00350     // LEDs_OFF_L
00351     cmd[0]  =   ALL_LED_OFF_L ;
00352     cmd[1]  =   ( myAux & 0xFF );
00353 
00354     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00355 
00356     // LEDs_OFF_H
00357     cmd[0]  =   ALL_LED_OFF_H ;
00358 
00359     if ( myPWM_DutyCycle == 0 )
00360         cmd[1]  =   0x10;                                   // All LEDs full OFF
00361     else
00362         cmd[1]  =   ( ( myAux >> 8 ) & 0xFF );
00363 
00364     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00365 
00366 
00367 
00368 
00369 
00370     if ( aux == I2C_SUCCESS  )
00371         return   PCA9685_SUCCESS;
00372     else
00373         return   PCA9685_FAILURE;
00374 }
00375 
00376 
00377 
00378 /**
00379  * @brief       PCA9685_SetLED_ON ( PCA9685_led_channel_t )
00380  *
00381  * @details     It sets LEDn ON.
00382  *
00383  * @param[in]    myLEDchannel:      Chosen LED ( channel ).
00384  *
00385  * @param[out]   NaN.
00386  *
00387  *
00388  * @return       Status of PCA9685_SetLED_ON.
00389  *
00390  *
00391  * @author      Manuel Caballero
00392  * @date        7/November/2017
00393  * @version     7/November/2017     The ORIGIN
00394  * @pre         Update on ACK requires all 4 PWM channel registers to be loaded before outputs will
00395  *              change on the last ACK.
00396  * @warning     NaN.
00397  */
00398 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetLED_ON ( PCA9685_led_channel_t  myLEDchannel )
00399 {
00400     char     cmd[]       =   { 0, 0 };
00401     uint32_t aux;
00402 
00403 
00404 
00405     // LEDn_ON_L
00406     cmd[0]  =   LED0_ON_L  + ( myLEDchannel << 2 );
00407     cmd[1]  =   0x00;                                       // Dummy value
00408 
00409     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00410 
00411     // LEDn_ON_H
00412     cmd[0]  =   LED0_ON_H  + ( myLEDchannel << 2 );
00413     cmd[1]  =   0x10;                                       // LEDn full ON
00414 
00415     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00416 
00417 
00418 
00419     // LEDn_OFF_L
00420     cmd[0]  =   LED0_OFF_L  + ( myLEDchannel << 2 );
00421     cmd[1]  =   0x00;                                       // Dummy value
00422 
00423     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00424 
00425     // LEDn_OFF_H
00426     cmd[0]  =   LED0_OFF_H  + ( myLEDchannel << 2 );
00427     cmd[1]  =   0x00;                                       // LEDn full OFF
00428 
00429     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00430 
00431 
00432 
00433 
00434 
00435     if ( aux == I2C_SUCCESS  )
00436         return   PCA9685_SUCCESS;
00437     else
00438         return   PCA9685_FAILURE;
00439 }
00440 
00441 
00442 
00443 
00444 /**
00445  * @brief       PCA9685_SetLED_OFF ( PCA9685_led_channel_t )
00446  *
00447  * @details     It sets LEDn OFF.
00448  *
00449  * @param[in]    myLEDchannel:      Chosen LED ( channel ).
00450  *
00451  * @param[out]   NaN.
00452  *
00453  *
00454  * @return       Status of PCA9685_SetLED_OFF.
00455  *
00456  *
00457  * @author      Manuel Caballero
00458  * @date        7/November/2017
00459  * @version     7/November/2017     The ORIGIN
00460  * @pre         Update on ACK requires all 4 PWM channel registers to be loaded before outputs will
00461  *              change on the last ACK.
00462  * @warning     NaN.
00463  */
00464 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetLED_OFF ( PCA9685_led_channel_t  myLEDchannel )
00465 {
00466     char     cmd[]       =   { 0, 0 };
00467     uint32_t aux;
00468 
00469 
00470 
00471     // LEDn_ON_L
00472     cmd[0]  =   LED0_ON_L  + ( myLEDchannel << 2 );
00473     cmd[1]  =   0x00;                                       // Dummy value
00474 
00475     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00476 
00477     // LEDn_ON_H
00478     cmd[0]  =   LED0_ON_H  + ( myLEDchannel << 2 );
00479     cmd[1]  =   0x00;                                       // Dummy value
00480 
00481     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00482 
00483 
00484 
00485     // LEDn_OFF_L
00486     cmd[0]  =   LED0_OFF_L  + ( myLEDchannel << 2 );
00487     cmd[1]  =   0x00;                                       // Dummy value
00488 
00489     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00490 
00491     // LEDn_OFF_H
00492     cmd[0]  =   LED0_OFF_H  + ( myLEDchannel << 2 );
00493     cmd[1]  =   0x10;                                       // LEDn full OFF
00494 
00495     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00496 
00497 
00498 
00499 
00500 
00501     if ( aux == I2C_SUCCESS  )
00502         return   PCA9685_SUCCESS;
00503     else
00504         return   PCA9685_FAILURE;
00505 }
00506 
00507 
00508 
00509 
00510 /**
00511  * @brief       PCA9685_SetAllLED_ON ( void )
00512  *
00513  * @details     It sets All LEDs ON.
00514  *
00515  * @param[in]    NaN.
00516  *
00517  * @param[out]   NaN.
00518  *
00519  *
00520  * @return       Status of PCA9685_SetAllLED_ON.
00521  *
00522  *
00523  * @author      Manuel Caballero
00524  * @date        7/November/2017
00525  * @version     7/November/2017     The ORIGIN
00526  * @pre         Update on ACK requires all 4 PWM channel registers to be loaded before outputs will
00527  *              change on the last ACK.
00528  * @warning     NaN.
00529  */
00530 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetAllLED_ON ( void )
00531 {
00532     char     cmd[]       =   { 0, 0 };
00533     uint32_t aux;
00534 
00535 
00536 
00537     // LEDs_ON_L
00538     cmd[0]  =   ALL_LED_ON_L ;
00539     cmd[1]  =   0x00;                                       // Dummy value
00540 
00541     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00542 
00543     // LEDs_ON_H
00544     cmd[0]  =   ALL_LED_ON_H ;
00545     cmd[1]  =   0x10;                                       // All LEDs full ON
00546 
00547     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00548 
00549 
00550 
00551     // LEDs_OFF_L
00552     cmd[0]  =   ALL_LED_OFF_L ;
00553     cmd[1]  =   0x00;                                       // Dummy value
00554 
00555     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00556 
00557     // LEDs_OFF_H
00558     cmd[0]  =   ALL_LED_OFF_H ;
00559     cmd[1]  =   0x00;                                       // Dummy value
00560 
00561     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00562 
00563 
00564 
00565 
00566 
00567     if ( aux == I2C_SUCCESS  )
00568         return   PCA9685_SUCCESS;
00569     else
00570         return   PCA9685_FAILURE;
00571 }
00572 
00573 
00574 
00575 
00576 /**
00577  * @brief       PCA9685_SetAllLED_OFF ( void )
00578  *
00579  * @details     It sets All LEDs OFF.
00580  *
00581  * @param[in]    NaN.
00582  *
00583  * @param[out]   NaN.
00584  *
00585  *
00586  * @return       Status of PCA9685_SetAllLED_OFF.
00587  *
00588  *
00589  * @author      Manuel Caballero
00590  * @date        7/November/2017
00591  * @version     7/November/2017     The ORIGIN
00592  * @pre         Update on ACK requires all 4 PWM channel registers to be loaded before outputs will
00593  *              change on the last ACK.
00594  * @warning     NaN.
00595  */
00596 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetAllLED_OFF ( void )
00597 {
00598     char     cmd[]       =   { 0, 0 };
00599     uint32_t aux;
00600 
00601 
00602 
00603     // LEDs_ON_L
00604     cmd[0]  =   ALL_LED_ON_L ;
00605     cmd[1]  =   0x00;                                       // Dummy value
00606 
00607     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00608 
00609     // LEDs_ON_H
00610     cmd[0]  =   ALL_LED_ON_H ;
00611     cmd[1]  =   0x00;                                       // Dummy value
00612 
00613     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00614 
00615 
00616 
00617     // LEDs_OFF_L
00618     cmd[0]  =   ALL_LED_OFF_L ;
00619     cmd[1]  =   0x00;                                       // Dummy value
00620 
00621     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00622 
00623     // LEDs_OFF_H
00624     cmd[0]  =   ALL_LED_OFF_H ;
00625     cmd[1]  =   0x10;                                       // All LEDs full OFF
00626 
00627     aux     =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00628 
00629 
00630 
00631 
00632 
00633     if ( aux == I2C_SUCCESS  )
00634         return   PCA9685_SUCCESS;
00635     else
00636         return   PCA9685_FAILURE;
00637 }
00638 
00639 
00640 
00641 
00642 /**
00643  * @brief       PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t )
00644  *
00645  * @details     The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 1.
00646  *
00647  * @param[in]    mySUB1_mode:       SUB1 Enabled/Disabled.
00648  *
00649  * @param[out]   NaN.
00650  *
00651  *
00652  * @return       Status of PCA9685_SetSUB1.
00653  *
00654  *
00655  * @author      Manuel Caballero
00656  * @date        7/November/2017
00657  * @version     7/November/2017     The ORIGIN
00658  * @pre         NaN.
00659  * @warning     NaN.
00660  */
00661 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t mySUB1_mode )
00662 {
00663     char     cmd[]       =   { MODE1 , 0 };
00664     uint32_t aux;
00665 
00666 
00667     // Mask SUB1 and update its value
00668     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00669     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00670     cmd[1]  &=   ~MODE1_SUB1_MASK ;
00671     cmd[1]  |=   mySUB1_mode;
00672     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00673 
00674 
00675 
00676 
00677 
00678     if ( aux == I2C_SUCCESS  )
00679         return   PCA9685_SUCCESS;
00680     else
00681         return   PCA9685_FAILURE;
00682 }
00683 
00684 
00685 
00686 
00687 /**
00688  * @brief       PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t )
00689  *
00690  * @details     The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 2.
00691  *
00692  * @param[in]    mySUB2_mode:       SUB2 Enabled/Disabled.
00693  *
00694  * @param[out]   NaN.
00695  *
00696  *
00697  * @return       Status of PCA9685_SetSUB2.
00698  *
00699  *
00700  * @author      Manuel Caballero
00701  * @date        7/November/2017
00702  * @version     7/November/2017     The ORIGIN
00703  * @pre         NaN.
00704  * @warning     NaN.
00705  */
00706 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t mySUB2_mode )
00707 {
00708     char     cmd[]       =   { MODE1 , 0 };
00709     uint32_t aux;
00710 
00711 
00712     // Mask SUB2 and update its value
00713     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00714     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00715     cmd[1]  &=   ~MODE1_SUB2_MASK ;
00716     cmd[1]  |=   mySUB2_mode;
00717     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00718 
00719 
00720 
00721 
00722 
00723     if ( aux == I2C_SUCCESS  )
00724         return   PCA9685_SUCCESS;
00725     else
00726         return   PCA9685_FAILURE;
00727 }
00728 
00729 
00730 
00731 
00732 /**
00733  * @brief       PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t )
00734  *
00735  * @details     The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 3.
00736  *
00737  * @param[in]    mySUB3_mode:       SUB3 Enabled/Disabled.
00738  *
00739  * @param[out]   NaN.
00740  *
00741  *
00742  * @return       Status of PCA9685_SetSUB3.
00743  *
00744  *
00745  * @author      Manuel Caballero
00746  * @date        7/November/2017
00747  * @version     7/November/2017     The ORIGIN
00748  * @pre         NaN.
00749  * @warning     NaN.
00750  */
00751 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t mySUB3_mode )
00752 {
00753     char     cmd[]       =   { MODE1 , 0 };
00754     uint32_t aux;
00755 
00756 
00757     // Mask SUB3 and update its value
00758     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00759     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00760     cmd[1]  &=   ~MODE1_SUB3_MASK ;
00761     cmd[1]  |=   mySUB3_mode;
00762     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00763 
00764 
00765 
00766 
00767 
00768     if ( aux == I2C_SUCCESS  )
00769         return   PCA9685_SUCCESS;
00770     else
00771         return   PCA9685_FAILURE;
00772 }
00773 
00774 
00775 
00776 
00777 /**
00778  * @brief       PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t )
00779  *
00780  * @details     The device responds ( Enabled ) or not ( Disabled ) to LED All Call I2C-bus address.
00781  *
00782  * @param[in]    myALLCALL_mode:    ALLCALL Enabled/Disabled.
00783  *
00784  * @param[out]   NaN.
00785  *
00786  *
00787  * @return       Status of PCA9685_SetALLCALL.
00788  *
00789  *
00790  * @author      Manuel Caballero
00791  * @date        7/November/2017
00792  * @version     7/November/2017     The ORIGIN
00793  * @pre         NaN.
00794  * @warning     NaN.
00795  */
00796 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t myALLCALL_mode )
00797 {
00798     char     cmd[]       =   { MODE1 , 0 };
00799     uint32_t aux;
00800 
00801 
00802     // Mask SUB3 and update its value
00803     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00804     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00805     cmd[1]  &=   ~MODE1_ALLCALL_MASK ;
00806     cmd[1]  |=   myALLCALL_mode;
00807     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00808 
00809 
00810 
00811 
00812 
00813     if ( aux == I2C_SUCCESS  )
00814         return   PCA9685_SUCCESS;
00815     else
00816         return   PCA9685_FAILURE;
00817 }
00818 
00819 
00820 
00821 
00822 /**
00823  * @brief       PCA9685_SetINVERT ( PCA9685_mode2_invrt_t )
00824  *
00825  * @details     Output logic state inverted ( Enabled ) or not ( Disabled ). Value to use
00826  *              when external driver used. Applicable when #OE = 0
00827  *
00828  * @param[in]    myINVERT_mode:     INVERT Enabled/Disabled.
00829  *
00830  * @param[out]   NaN.
00831  *
00832  *
00833  * @return       Status of PCA9685_SetINVERT.
00834  *
00835  *
00836  * @author      Manuel Caballero
00837  * @date        7/November/2017
00838  * @version     7/November/2017     The ORIGIN
00839  * @pre         NaN.
00840  * @warning     NaN.
00841  */
00842 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetINVERT ( PCA9685_mode2_invrt_t myINVERT_mode )
00843 {
00844     char     cmd[]       =   { MODE2 , 0 };
00845     uint32_t aux;
00846 
00847 
00848     // Mask SUB3 and update its value
00849     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00850     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00851     cmd[1]  &=   ~MODE2_INVRT_MASK ;
00852     cmd[1]  |=   myINVERT_mode;
00853     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00854 
00855 
00856 
00857 
00858 
00859     if ( aux == I2C_SUCCESS  )
00860         return   PCA9685_SUCCESS;
00861     else
00862         return   PCA9685_FAILURE;
00863 }
00864 
00865 
00866 
00867 
00868 /**
00869  * @brief       PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t )
00870  *
00871  * @details     It sets the 16 LEDn as open-drain or totem pole structure.
00872  *
00873  * @param[in]    myOUTDRV_mode:     OUTDRV mode.
00874  *
00875  * @param[out]   NaN.
00876  *
00877  *
00878  * @return       Status of PCA9685_SetOUTDRV.
00879  *
00880  *
00881  * @author      Manuel Caballero
00882  * @date        7/November/2017
00883  * @version     7/November/2017     The ORIGIN
00884  * @pre         NaN.
00885  * @warning     NaN.
00886  */
00887 PCA9685::PCA9685_status_t  PCA9685::PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t myOUTDRV_mode )
00888 {
00889     char     cmd[]       =   { MODE2 , 0 };
00890     uint32_t aux;
00891 
00892 
00893     // Mask SUB3 and update its value
00894     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], 1, true );
00895     aux      =   i2c.read  ( PCA9685_Addr, &cmd[1], 1 );
00896     cmd[1]  &=   ~MODE2_OUTDRV_MASK ;
00897     cmd[1]  |=   myOUTDRV_mode;
00898     aux      =   i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false );
00899 
00900 
00901 
00902 
00903 
00904     if ( aux == I2C_SUCCESS  )
00905         return   PCA9685_SUCCESS;
00906     else
00907         return   PCA9685_FAILURE;
00908 }