16-channel, 12-bit PWM Fm I2C-bus LED controller
Embed:
(wiki syntax)
Show/hide line numbers
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 Sun Jul 17 2022 17:06:29 by 1.7.2