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.
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 }
Generated on Wed Jul 13 2022 01:54:44 by
