16-channel, 12-bit PWM Fm I2C-bus LED controller
PCA9685.cpp@3:f69f4e2c35b6, 2017-11-07 (annotated)
- Committer:
- mcm
- Date:
- Tue Nov 07 17:09:04 2017 +0000
- Revision:
- 3:f69f4e2c35b6
- Parent:
- 2:fa75aff130cc
The library was completed and tested, it works as expected.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mcm | 2:fa75aff130cc | 1 | /** |
mcm | 2:fa75aff130cc | 2 | * @brief PCA9685.h |
mcm | 2:fa75aff130cc | 3 | * @details 16-channel, 12-bit PWM Fm+ I2C-bus LED controller. |
mcm | 2:fa75aff130cc | 4 | * Functions file. |
mcm | 2:fa75aff130cc | 5 | * |
mcm | 2:fa75aff130cc | 6 | * |
mcm | 2:fa75aff130cc | 7 | * @return NA |
mcm | 2:fa75aff130cc | 8 | * |
mcm | 2:fa75aff130cc | 9 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 10 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 11 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 12 | * @pre NaN. |
mcm | 2:fa75aff130cc | 13 | * @warning NaN |
mcm | 2:fa75aff130cc | 14 | * @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ). |
mcm | 2:fa75aff130cc | 15 | */ |
mcm | 2:fa75aff130cc | 16 | |
mcm | 2:fa75aff130cc | 17 | #include "PCA9685.h" |
mcm | 2:fa75aff130cc | 18 | |
mcm | 2:fa75aff130cc | 19 | |
mcm | 2:fa75aff130cc | 20 | PCA9685::PCA9685 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq ) |
mcm | 2:fa75aff130cc | 21 | : i2c ( sda, scl ) |
mcm | 2:fa75aff130cc | 22 | , PCA9685_Addr ( addr ) |
mcm | 2:fa75aff130cc | 23 | { |
mcm | 2:fa75aff130cc | 24 | i2c.frequency( freq ); |
mcm | 2:fa75aff130cc | 25 | } |
mcm | 2:fa75aff130cc | 26 | |
mcm | 2:fa75aff130cc | 27 | |
mcm | 2:fa75aff130cc | 28 | PCA9685::~PCA9685() |
mcm | 2:fa75aff130cc | 29 | { |
mcm | 2:fa75aff130cc | 30 | } |
mcm | 2:fa75aff130cc | 31 | |
mcm | 2:fa75aff130cc | 32 | |
mcm | 2:fa75aff130cc | 33 | |
mcm | 2:fa75aff130cc | 34 | /** |
mcm | 2:fa75aff130cc | 35 | * @brief PCA9685_SoftReset ( void ) |
mcm | 2:fa75aff130cc | 36 | * |
mcm | 2:fa75aff130cc | 37 | * @details It performs a software reset. |
mcm | 2:fa75aff130cc | 38 | * |
mcm | 2:fa75aff130cc | 39 | * @param[in] NaN. |
mcm | 2:fa75aff130cc | 40 | * |
mcm | 2:fa75aff130cc | 41 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 42 | * |
mcm | 2:fa75aff130cc | 43 | * |
mcm | 2:fa75aff130cc | 44 | * @return Status of PCA9685_SoftReset. |
mcm | 2:fa75aff130cc | 45 | * |
mcm | 2:fa75aff130cc | 46 | * |
mcm | 2:fa75aff130cc | 47 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 48 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 49 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 50 | * @pre The device will be ready to be addressed again within |
mcm | 2:fa75aff130cc | 51 | * the specified bus free time ( t_BUF ). |
mcm | 2:fa75aff130cc | 52 | * @warning NaN. |
mcm | 2:fa75aff130cc | 53 | */ |
mcm | 2:fa75aff130cc | 54 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SoftReset ( void ) |
mcm | 2:fa75aff130cc | 55 | { |
mcm | 2:fa75aff130cc | 56 | char cmd = SWRST; |
mcm | 2:fa75aff130cc | 57 | uint32_t aux; |
mcm | 2:fa75aff130cc | 58 | |
mcm | 2:fa75aff130cc | 59 | |
mcm | 2:fa75aff130cc | 60 | |
mcm | 2:fa75aff130cc | 61 | aux = i2c.write ( GENERAL_CALL_ADDRESS, &cmd, 1, false ); |
mcm | 2:fa75aff130cc | 62 | |
mcm | 2:fa75aff130cc | 63 | |
mcm | 2:fa75aff130cc | 64 | |
mcm | 2:fa75aff130cc | 65 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 66 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 67 | else |
mcm | 2:fa75aff130cc | 68 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 69 | } |
mcm | 2:fa75aff130cc | 70 | |
mcm | 2:fa75aff130cc | 71 | |
mcm | 2:fa75aff130cc | 72 | |
mcm | 2:fa75aff130cc | 73 | |
mcm | 2:fa75aff130cc | 74 | /** |
mcm | 2:fa75aff130cc | 75 | * @brief PCA9685_SetMode ( PCA9685_mode1_sleep_t ) |
mcm | 2:fa75aff130cc | 76 | * |
mcm | 2:fa75aff130cc | 77 | * @details It configures the device in Low power mode or in Normal operation |
mcm | 2:fa75aff130cc | 78 | * mode. |
mcm | 2:fa75aff130cc | 79 | * |
mcm | 2:fa75aff130cc | 80 | * @param[in] myMode: Sleep or Normal mode. |
mcm | 2:fa75aff130cc | 81 | * |
mcm | 2:fa75aff130cc | 82 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 83 | * |
mcm | 2:fa75aff130cc | 84 | * |
mcm | 2:fa75aff130cc | 85 | * @return Status of PCA9685_SetMode. |
mcm | 2:fa75aff130cc | 86 | * |
mcm | 2:fa75aff130cc | 87 | * |
mcm | 2:fa75aff130cc | 88 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 89 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 90 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 91 | * @pre NaN. |
mcm | 2:fa75aff130cc | 92 | * @warning NaN. |
mcm | 2:fa75aff130cc | 93 | */ |
mcm | 2:fa75aff130cc | 94 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetMode ( PCA9685_mode1_sleep_t myMode ) |
mcm | 2:fa75aff130cc | 95 | { |
mcm | 2:fa75aff130cc | 96 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 97 | uint32_t aux; |
mcm | 2:fa75aff130cc | 98 | |
mcm | 2:fa75aff130cc | 99 | |
mcm | 2:fa75aff130cc | 100 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 101 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 102 | cmd[1] &= ~MODE1_SLEEP_MASK; |
mcm | 2:fa75aff130cc | 103 | cmd[1] |= myMode; |
mcm | 2:fa75aff130cc | 104 | |
mcm | 2:fa75aff130cc | 105 | |
mcm | 2:fa75aff130cc | 106 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 107 | |
mcm | 2:fa75aff130cc | 108 | |
mcm | 2:fa75aff130cc | 109 | |
mcm | 2:fa75aff130cc | 110 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 111 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 112 | else |
mcm | 2:fa75aff130cc | 113 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 114 | } |
mcm | 2:fa75aff130cc | 115 | |
mcm | 2:fa75aff130cc | 116 | |
mcm | 2:fa75aff130cc | 117 | |
mcm | 2:fa75aff130cc | 118 | |
mcm | 2:fa75aff130cc | 119 | /** |
mcm | 2:fa75aff130cc | 120 | * @brief PCA9685_SetPWM_Freq ( float ) |
mcm | 2:fa75aff130cc | 121 | * |
mcm | 2:fa75aff130cc | 122 | * @details It sets a new PWM frequency. |
mcm | 2:fa75aff130cc | 123 | * |
mcm | 2:fa75aff130cc | 124 | * @param[in] myNewFrequency: New PWM frequency. |
mcm | 2:fa75aff130cc | 125 | * |
mcm | 2:fa75aff130cc | 126 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 127 | * |
mcm | 2:fa75aff130cc | 128 | * |
mcm | 2:fa75aff130cc | 129 | * @return Status of PCA9685_SetPWM_Freq. |
mcm | 2:fa75aff130cc | 130 | * |
mcm | 2:fa75aff130cc | 131 | * |
mcm | 2:fa75aff130cc | 132 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 133 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 134 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 135 | * @pre This library can ONLY work with the internal clock, otherwise |
mcm | 2:fa75aff130cc | 136 | * PCA9685_INTERNAL_CLOCK must be changed in the header file. |
mcm | 2:fa75aff130cc | 137 | * @warning NaN. |
mcm | 2:fa75aff130cc | 138 | */ |
mcm | 2:fa75aff130cc | 139 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetPWM_Freq ( float myNewFrequency ) |
mcm | 2:fa75aff130cc | 140 | { |
mcm | 2:fa75aff130cc | 141 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 142 | char prev_mode1 = 0; |
mcm | 2:fa75aff130cc | 143 | uint32_t aux; |
mcm | 2:fa75aff130cc | 144 | |
mcm | 2:fa75aff130cc | 145 | |
mcm | 2:fa75aff130cc | 146 | // The maximum PWM frequency is 1526 Hz and the minimum PWM frequency is 24 Hz. |
mcm | 2:fa75aff130cc | 147 | if ( ( myNewFrequency < 24 ) || ( myNewFrequency > 1526 ) ) |
mcm | 2:fa75aff130cc | 148 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 149 | |
mcm | 2:fa75aff130cc | 150 | |
mcm | 2:fa75aff130cc | 151 | // The device MUST be in SLEEP mode |
mcm | 2:fa75aff130cc | 152 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 153 | aux = i2c.read ( PCA9685_Addr, &prev_mode1, 1 ); |
mcm | 2:fa75aff130cc | 154 | cmd[1] = ( prev_mode1 | MODE1_SLEEP_ENABLED ); |
mcm | 2:fa75aff130cc | 155 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 156 | |
mcm | 2:fa75aff130cc | 157 | |
mcm | 2:fa75aff130cc | 158 | // Calculate the new PWM frequency |
mcm | 2:fa75aff130cc | 159 | if ( myNewFrequency == 24 ) |
mcm | 2:fa75aff130cc | 160 | cmd[1] = 255; |
mcm | 2:fa75aff130cc | 161 | else |
mcm | 2:fa75aff130cc | 162 | cmd[1] = _MYROUND ( ( PCA9685_INTERNAL_CLOCK / ( PCA9685_ADC_STEPS * myNewFrequency ) ) - 1 ); |
mcm | 2:fa75aff130cc | 163 | |
mcm | 2:fa75aff130cc | 164 | |
mcm | 2:fa75aff130cc | 165 | cmd[0] = PRE_SCALE; |
mcm | 2:fa75aff130cc | 166 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 167 | |
mcm | 2:fa75aff130cc | 168 | |
mcm | 2:fa75aff130cc | 169 | // Restore the device's mode |
mcm | 2:fa75aff130cc | 170 | cmd[0] = MODE1; |
mcm | 2:fa75aff130cc | 171 | cmd[1] = prev_mode1; |
mcm | 2:fa75aff130cc | 172 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 173 | |
mcm | 2:fa75aff130cc | 174 | |
mcm | 2:fa75aff130cc | 175 | |
mcm | 2:fa75aff130cc | 176 | |
mcm | 2:fa75aff130cc | 177 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 178 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 179 | else |
mcm | 2:fa75aff130cc | 180 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 181 | } |
mcm | 2:fa75aff130cc | 182 | |
mcm | 2:fa75aff130cc | 183 | |
mcm | 2:fa75aff130cc | 184 | |
mcm | 2:fa75aff130cc | 185 | |
mcm | 2:fa75aff130cc | 186 | /** |
mcm | 2:fa75aff130cc | 187 | * @brief PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t , uint8_t , uint8_t ) |
mcm | 2:fa75aff130cc | 188 | * |
mcm | 2:fa75aff130cc | 189 | * @details It sets a new PWM duty cycle on the given LED ( channel ). |
mcm | 2:fa75aff130cc | 190 | * |
mcm | 2:fa75aff130cc | 191 | * @param[in] myLEDchannel: Chosen LED ( channel ). |
mcm | 2:fa75aff130cc | 192 | * @param[in] myDelay: PWM delay. |
mcm | 2:fa75aff130cc | 193 | * @param[in] myPWM_DutyCycle: PWM duty cycle. |
mcm | 2:fa75aff130cc | 194 | * |
mcm | 2:fa75aff130cc | 195 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 196 | * |
mcm | 2:fa75aff130cc | 197 | * |
mcm | 2:fa75aff130cc | 198 | * @return Status of PCA9685_SetPWM_DutyCycle. |
mcm | 2:fa75aff130cc | 199 | * |
mcm | 2:fa75aff130cc | 200 | * |
mcm | 2:fa75aff130cc | 201 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 202 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 203 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 204 | * @pre Datasheet p.17 ( Example 1 and Example 2). |
mcm | 2:fa75aff130cc | 205 | * @warning NaN. |
mcm | 2:fa75aff130cc | 206 | */ |
mcm | 2:fa75aff130cc | 207 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t myLEDchannel, uint8_t myDelay, uint8_t myPWM_DutyCycle ) |
mcm | 2:fa75aff130cc | 208 | { |
mcm | 2:fa75aff130cc | 209 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 210 | uint32_t myAux = 0; |
mcm | 2:fa75aff130cc | 211 | uint32_t aux; |
mcm | 2:fa75aff130cc | 212 | |
mcm | 2:fa75aff130cc | 213 | |
mcm | 2:fa75aff130cc | 214 | // The range is from 0% up to 100%. |
mcm | 2:fa75aff130cc | 215 | if ( ( myDelay > 100 ) || ( myPWM_DutyCycle > 100 ) ) |
mcm | 2:fa75aff130cc | 216 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 217 | |
mcm | 2:fa75aff130cc | 218 | |
mcm | 2:fa75aff130cc | 219 | // Delay time cannot be 0% |
mcm | 2:fa75aff130cc | 220 | if ( myDelay == 0 ) |
mcm | 2:fa75aff130cc | 221 | myDelay = 1; |
mcm | 2:fa75aff130cc | 222 | |
mcm | 2:fa75aff130cc | 223 | |
mcm | 2:fa75aff130cc | 224 | // DELAY TIME: LEDn_ON_L + LEDn_ON_H |
mcm | 2:fa75aff130cc | 225 | myAux = _MYROUND ( ( myDelay / 100.0 ) * PCA9685_ADC_STEPS ) - 1; |
mcm | 2:fa75aff130cc | 226 | |
mcm | 2:fa75aff130cc | 227 | // LEDn_ON_L |
mcm | 2:fa75aff130cc | 228 | cmd[0] = LED0_ON_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 229 | cmd[1] = ( myAux & 0xFF ); |
mcm | 2:fa75aff130cc | 230 | |
mcm | 2:fa75aff130cc | 231 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 232 | |
mcm | 2:fa75aff130cc | 233 | // LEDn_ON_H |
mcm | 2:fa75aff130cc | 234 | cmd[0] = LED0_ON_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 235 | |
mcm | 2:fa75aff130cc | 236 | if ( myPWM_DutyCycle == 100 ) |
mcm | 2:fa75aff130cc | 237 | cmd[1] = 0x10; // LEDn full ON |
mcm | 2:fa75aff130cc | 238 | else |
mcm | 2:fa75aff130cc | 239 | cmd[1] = ( ( myAux >> 8 ) & 0xFF ); |
mcm | 2:fa75aff130cc | 240 | |
mcm | 2:fa75aff130cc | 241 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 242 | |
mcm | 2:fa75aff130cc | 243 | |
mcm | 2:fa75aff130cc | 244 | |
mcm | 2:fa75aff130cc | 245 | // LED OFF TIME: LEDn_OFF_L + LEDn_OFF_H |
mcm | 2:fa75aff130cc | 246 | myAux += _MYROUND ( ( myPWM_DutyCycle / 100.0 ) * PCA9685_ADC_STEPS ); |
mcm | 2:fa75aff130cc | 247 | |
mcm | 2:fa75aff130cc | 248 | if ( ( myDelay + myPWM_DutyCycle ) <= 100 ) |
mcm | 2:fa75aff130cc | 249 | myAux--; |
mcm | 2:fa75aff130cc | 250 | else |
mcm | 2:fa75aff130cc | 251 | myAux = ( myAux - 4096 ); |
mcm | 2:fa75aff130cc | 252 | |
mcm | 2:fa75aff130cc | 253 | |
mcm | 2:fa75aff130cc | 254 | // LEDn_OFF_L |
mcm | 2:fa75aff130cc | 255 | cmd[0] = LED0_OFF_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 256 | cmd[1] = ( myAux & 0xFF ); |
mcm | 2:fa75aff130cc | 257 | |
mcm | 2:fa75aff130cc | 258 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 259 | |
mcm | 2:fa75aff130cc | 260 | // LEDn_OFF_H |
mcm | 2:fa75aff130cc | 261 | cmd[0] = LED0_OFF_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 262 | |
mcm | 2:fa75aff130cc | 263 | if ( myPWM_DutyCycle == 0 ) |
mcm | 2:fa75aff130cc | 264 | cmd[1] = 0x10; // LEDn full OFF |
mcm | 2:fa75aff130cc | 265 | else |
mcm | 2:fa75aff130cc | 266 | cmd[1] = ( ( myAux >> 8 ) & 0xFF ); |
mcm | 2:fa75aff130cc | 267 | |
mcm | 2:fa75aff130cc | 268 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 269 | |
mcm | 2:fa75aff130cc | 270 | |
mcm | 2:fa75aff130cc | 271 | |
mcm | 2:fa75aff130cc | 272 | |
mcm | 2:fa75aff130cc | 273 | |
mcm | 2:fa75aff130cc | 274 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 275 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 276 | else |
mcm | 2:fa75aff130cc | 277 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 278 | } |
mcm | 2:fa75aff130cc | 279 | |
mcm | 2:fa75aff130cc | 280 | |
mcm | 2:fa75aff130cc | 281 | |
mcm | 2:fa75aff130cc | 282 | |
mcm | 2:fa75aff130cc | 283 | /** |
mcm | 2:fa75aff130cc | 284 | * @brief PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t , uint8_t ) |
mcm | 2:fa75aff130cc | 285 | * |
mcm | 2:fa75aff130cc | 286 | * @details It sets a new PWM duty cycle on all LEDs ( all channels ). |
mcm | 2:fa75aff130cc | 287 | * |
mcm | 2:fa75aff130cc | 288 | * @param[in] myDelay: PWM delay. |
mcm | 2:fa75aff130cc | 289 | * @param[in] myPWM_DutyCycle: PWM duty cycle. |
mcm | 2:fa75aff130cc | 290 | * |
mcm | 2:fa75aff130cc | 291 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 292 | * |
mcm | 2:fa75aff130cc | 293 | * |
mcm | 2:fa75aff130cc | 294 | * @return Status of PCA9685_SetPWM_DutyCycle_AllLEDs. |
mcm | 2:fa75aff130cc | 295 | * |
mcm | 2:fa75aff130cc | 296 | * |
mcm | 2:fa75aff130cc | 297 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 298 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 299 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 300 | * @pre Datasheet p.17 ( Example 1 and Example 2). |
mcm | 2:fa75aff130cc | 301 | * @warning NaN. |
mcm | 2:fa75aff130cc | 302 | */ |
mcm | 2:fa75aff130cc | 303 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t myDelay, uint8_t myPWM_DutyCycle ) |
mcm | 2:fa75aff130cc | 304 | { |
mcm | 2:fa75aff130cc | 305 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 306 | uint32_t myAux = 0; |
mcm | 2:fa75aff130cc | 307 | uint32_t aux; |
mcm | 2:fa75aff130cc | 308 | |
mcm | 2:fa75aff130cc | 309 | |
mcm | 2:fa75aff130cc | 310 | // The range is from 0% up to 100%. |
mcm | 2:fa75aff130cc | 311 | if ( ( myDelay > 100 ) || ( myPWM_DutyCycle > 100 ) ) |
mcm | 2:fa75aff130cc | 312 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 313 | |
mcm | 2:fa75aff130cc | 314 | |
mcm | 2:fa75aff130cc | 315 | // Delay time cannot be 0% |
mcm | 2:fa75aff130cc | 316 | if ( myDelay == 0 ) |
mcm | 2:fa75aff130cc | 317 | myDelay = 1; |
mcm | 2:fa75aff130cc | 318 | |
mcm | 2:fa75aff130cc | 319 | |
mcm | 2:fa75aff130cc | 320 | // DELAY TIME: LEDs_ON_L + LEDs_ON_H |
mcm | 2:fa75aff130cc | 321 | myAux = _MYROUND ( ( myDelay / 100.0 ) * PCA9685_ADC_STEPS ) - 1; |
mcm | 2:fa75aff130cc | 322 | |
mcm | 2:fa75aff130cc | 323 | // LEDs_ON_L |
mcm | 2:fa75aff130cc | 324 | cmd[0] = ALL_LED_ON_L; |
mcm | 2:fa75aff130cc | 325 | cmd[1] = ( myAux & 0xFF ); |
mcm | 2:fa75aff130cc | 326 | |
mcm | 2:fa75aff130cc | 327 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 328 | |
mcm | 2:fa75aff130cc | 329 | // LEDs_ON_H |
mcm | 2:fa75aff130cc | 330 | cmd[0] = ALL_LED_ON_H; |
mcm | 2:fa75aff130cc | 331 | |
mcm | 2:fa75aff130cc | 332 | if ( myPWM_DutyCycle == 100 ) |
mcm | 2:fa75aff130cc | 333 | cmd[1] = 0x10; // All LEDs full ON |
mcm | 2:fa75aff130cc | 334 | else |
mcm | 2:fa75aff130cc | 335 | cmd[1] = ( ( myAux >> 8 ) & 0xFF ); |
mcm | 2:fa75aff130cc | 336 | |
mcm | 2:fa75aff130cc | 337 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 338 | |
mcm | 2:fa75aff130cc | 339 | |
mcm | 2:fa75aff130cc | 340 | |
mcm | 2:fa75aff130cc | 341 | // LED OFF TIME: LEDs_OFF_L + LEDs_OFF_H |
mcm | 2:fa75aff130cc | 342 | myAux += _MYROUND ( ( myPWM_DutyCycle / 100.0 ) * PCA9685_ADC_STEPS ); |
mcm | 2:fa75aff130cc | 343 | |
mcm | 2:fa75aff130cc | 344 | if ( ( myDelay + myPWM_DutyCycle ) <= 100 ) |
mcm | 2:fa75aff130cc | 345 | myAux--; |
mcm | 2:fa75aff130cc | 346 | else |
mcm | 2:fa75aff130cc | 347 | myAux = ( myAux - 4096 ); |
mcm | 2:fa75aff130cc | 348 | |
mcm | 2:fa75aff130cc | 349 | |
mcm | 2:fa75aff130cc | 350 | // LEDs_OFF_L |
mcm | 2:fa75aff130cc | 351 | cmd[0] = ALL_LED_OFF_L; |
mcm | 2:fa75aff130cc | 352 | cmd[1] = ( myAux & 0xFF ); |
mcm | 2:fa75aff130cc | 353 | |
mcm | 2:fa75aff130cc | 354 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 355 | |
mcm | 2:fa75aff130cc | 356 | // LEDs_OFF_H |
mcm | 2:fa75aff130cc | 357 | cmd[0] = ALL_LED_OFF_H; |
mcm | 2:fa75aff130cc | 358 | |
mcm | 2:fa75aff130cc | 359 | if ( myPWM_DutyCycle == 0 ) |
mcm | 2:fa75aff130cc | 360 | cmd[1] = 0x10; // All LEDs full OFF |
mcm | 2:fa75aff130cc | 361 | else |
mcm | 2:fa75aff130cc | 362 | cmd[1] = ( ( myAux >> 8 ) & 0xFF ); |
mcm | 2:fa75aff130cc | 363 | |
mcm | 2:fa75aff130cc | 364 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 365 | |
mcm | 2:fa75aff130cc | 366 | |
mcm | 2:fa75aff130cc | 367 | |
mcm | 2:fa75aff130cc | 368 | |
mcm | 2:fa75aff130cc | 369 | |
mcm | 2:fa75aff130cc | 370 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 371 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 372 | else |
mcm | 2:fa75aff130cc | 373 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 374 | } |
mcm | 2:fa75aff130cc | 375 | |
mcm | 2:fa75aff130cc | 376 | |
mcm | 2:fa75aff130cc | 377 | |
mcm | 2:fa75aff130cc | 378 | /** |
mcm | 2:fa75aff130cc | 379 | * @brief PCA9685_SetLED_ON ( PCA9685_led_channel_t ) |
mcm | 2:fa75aff130cc | 380 | * |
mcm | 2:fa75aff130cc | 381 | * @details It sets LEDn ON. |
mcm | 2:fa75aff130cc | 382 | * |
mcm | 2:fa75aff130cc | 383 | * @param[in] myLEDchannel: Chosen LED ( channel ). |
mcm | 2:fa75aff130cc | 384 | * |
mcm | 2:fa75aff130cc | 385 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 386 | * |
mcm | 2:fa75aff130cc | 387 | * |
mcm | 2:fa75aff130cc | 388 | * @return Status of PCA9685_SetLED_ON. |
mcm | 2:fa75aff130cc | 389 | * |
mcm | 2:fa75aff130cc | 390 | * |
mcm | 2:fa75aff130cc | 391 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 392 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 393 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 394 | * @pre Update on ACK requires all 4 PWM channel registers to be loaded before outputs will |
mcm | 2:fa75aff130cc | 395 | * change on the last ACK. |
mcm | 2:fa75aff130cc | 396 | * @warning NaN. |
mcm | 2:fa75aff130cc | 397 | */ |
mcm | 2:fa75aff130cc | 398 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetLED_ON ( PCA9685_led_channel_t myLEDchannel ) |
mcm | 2:fa75aff130cc | 399 | { |
mcm | 2:fa75aff130cc | 400 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 401 | uint32_t aux; |
mcm | 2:fa75aff130cc | 402 | |
mcm | 2:fa75aff130cc | 403 | |
mcm | 2:fa75aff130cc | 404 | |
mcm | 2:fa75aff130cc | 405 | // LEDn_ON_L |
mcm | 2:fa75aff130cc | 406 | cmd[0] = LED0_ON_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 407 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 408 | |
mcm | 2:fa75aff130cc | 409 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 410 | |
mcm | 2:fa75aff130cc | 411 | // LEDn_ON_H |
mcm | 2:fa75aff130cc | 412 | cmd[0] = LED0_ON_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 413 | cmd[1] = 0x10; // LEDn full ON |
mcm | 2:fa75aff130cc | 414 | |
mcm | 2:fa75aff130cc | 415 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 416 | |
mcm | 2:fa75aff130cc | 417 | |
mcm | 2:fa75aff130cc | 418 | |
mcm | 2:fa75aff130cc | 419 | // LEDn_OFF_L |
mcm | 2:fa75aff130cc | 420 | cmd[0] = LED0_OFF_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 421 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 422 | |
mcm | 2:fa75aff130cc | 423 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 424 | |
mcm | 2:fa75aff130cc | 425 | // LEDn_OFF_H |
mcm | 2:fa75aff130cc | 426 | cmd[0] = LED0_OFF_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 427 | cmd[1] = 0x00; // LEDn full OFF |
mcm | 2:fa75aff130cc | 428 | |
mcm | 2:fa75aff130cc | 429 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 430 | |
mcm | 2:fa75aff130cc | 431 | |
mcm | 2:fa75aff130cc | 432 | |
mcm | 2:fa75aff130cc | 433 | |
mcm | 2:fa75aff130cc | 434 | |
mcm | 2:fa75aff130cc | 435 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 436 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 437 | else |
mcm | 2:fa75aff130cc | 438 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 439 | } |
mcm | 2:fa75aff130cc | 440 | |
mcm | 2:fa75aff130cc | 441 | |
mcm | 2:fa75aff130cc | 442 | |
mcm | 2:fa75aff130cc | 443 | |
mcm | 2:fa75aff130cc | 444 | /** |
mcm | 2:fa75aff130cc | 445 | * @brief PCA9685_SetLED_OFF ( PCA9685_led_channel_t ) |
mcm | 2:fa75aff130cc | 446 | * |
mcm | 2:fa75aff130cc | 447 | * @details It sets LEDn OFF. |
mcm | 2:fa75aff130cc | 448 | * |
mcm | 2:fa75aff130cc | 449 | * @param[in] myLEDchannel: Chosen LED ( channel ). |
mcm | 2:fa75aff130cc | 450 | * |
mcm | 2:fa75aff130cc | 451 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 452 | * |
mcm | 2:fa75aff130cc | 453 | * |
mcm | 2:fa75aff130cc | 454 | * @return Status of PCA9685_SetLED_OFF. |
mcm | 2:fa75aff130cc | 455 | * |
mcm | 2:fa75aff130cc | 456 | * |
mcm | 2:fa75aff130cc | 457 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 458 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 459 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 460 | * @pre Update on ACK requires all 4 PWM channel registers to be loaded before outputs will |
mcm | 2:fa75aff130cc | 461 | * change on the last ACK. |
mcm | 2:fa75aff130cc | 462 | * @warning NaN. |
mcm | 2:fa75aff130cc | 463 | */ |
mcm | 2:fa75aff130cc | 464 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetLED_OFF ( PCA9685_led_channel_t myLEDchannel ) |
mcm | 2:fa75aff130cc | 465 | { |
mcm | 2:fa75aff130cc | 466 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 467 | uint32_t aux; |
mcm | 2:fa75aff130cc | 468 | |
mcm | 2:fa75aff130cc | 469 | |
mcm | 2:fa75aff130cc | 470 | |
mcm | 2:fa75aff130cc | 471 | // LEDn_ON_L |
mcm | 2:fa75aff130cc | 472 | cmd[0] = LED0_ON_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 473 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 474 | |
mcm | 2:fa75aff130cc | 475 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 476 | |
mcm | 2:fa75aff130cc | 477 | // LEDn_ON_H |
mcm | 2:fa75aff130cc | 478 | cmd[0] = LED0_ON_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 479 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 480 | |
mcm | 2:fa75aff130cc | 481 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 482 | |
mcm | 2:fa75aff130cc | 483 | |
mcm | 2:fa75aff130cc | 484 | |
mcm | 2:fa75aff130cc | 485 | // LEDn_OFF_L |
mcm | 2:fa75aff130cc | 486 | cmd[0] = LED0_OFF_L + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 487 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 488 | |
mcm | 2:fa75aff130cc | 489 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 490 | |
mcm | 2:fa75aff130cc | 491 | // LEDn_OFF_H |
mcm | 2:fa75aff130cc | 492 | cmd[0] = LED0_OFF_H + ( myLEDchannel << 2 ); |
mcm | 2:fa75aff130cc | 493 | cmd[1] = 0x10; // LEDn full OFF |
mcm | 2:fa75aff130cc | 494 | |
mcm | 2:fa75aff130cc | 495 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 496 | |
mcm | 2:fa75aff130cc | 497 | |
mcm | 2:fa75aff130cc | 498 | |
mcm | 2:fa75aff130cc | 499 | |
mcm | 2:fa75aff130cc | 500 | |
mcm | 2:fa75aff130cc | 501 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 502 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 503 | else |
mcm | 2:fa75aff130cc | 504 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 505 | } |
mcm | 2:fa75aff130cc | 506 | |
mcm | 2:fa75aff130cc | 507 | |
mcm | 2:fa75aff130cc | 508 | |
mcm | 2:fa75aff130cc | 509 | |
mcm | 2:fa75aff130cc | 510 | /** |
mcm | 2:fa75aff130cc | 511 | * @brief PCA9685_SetAllLED_ON ( void ) |
mcm | 2:fa75aff130cc | 512 | * |
mcm | 2:fa75aff130cc | 513 | * @details It sets All LEDs ON. |
mcm | 2:fa75aff130cc | 514 | * |
mcm | 2:fa75aff130cc | 515 | * @param[in] NaN. |
mcm | 2:fa75aff130cc | 516 | * |
mcm | 2:fa75aff130cc | 517 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 518 | * |
mcm | 2:fa75aff130cc | 519 | * |
mcm | 2:fa75aff130cc | 520 | * @return Status of PCA9685_SetAllLED_ON. |
mcm | 2:fa75aff130cc | 521 | * |
mcm | 2:fa75aff130cc | 522 | * |
mcm | 2:fa75aff130cc | 523 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 524 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 525 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 526 | * @pre Update on ACK requires all 4 PWM channel registers to be loaded before outputs will |
mcm | 2:fa75aff130cc | 527 | * change on the last ACK. |
mcm | 2:fa75aff130cc | 528 | * @warning NaN. |
mcm | 2:fa75aff130cc | 529 | */ |
mcm | 2:fa75aff130cc | 530 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetAllLED_ON ( void ) |
mcm | 2:fa75aff130cc | 531 | { |
mcm | 2:fa75aff130cc | 532 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 533 | uint32_t aux; |
mcm | 2:fa75aff130cc | 534 | |
mcm | 2:fa75aff130cc | 535 | |
mcm | 2:fa75aff130cc | 536 | |
mcm | 2:fa75aff130cc | 537 | // LEDs_ON_L |
mcm | 2:fa75aff130cc | 538 | cmd[0] = ALL_LED_ON_L; |
mcm | 2:fa75aff130cc | 539 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 540 | |
mcm | 2:fa75aff130cc | 541 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 542 | |
mcm | 2:fa75aff130cc | 543 | // LEDs_ON_H |
mcm | 2:fa75aff130cc | 544 | cmd[0] = ALL_LED_ON_H; |
mcm | 2:fa75aff130cc | 545 | cmd[1] = 0x10; // All LEDs full ON |
mcm | 2:fa75aff130cc | 546 | |
mcm | 2:fa75aff130cc | 547 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 548 | |
mcm | 2:fa75aff130cc | 549 | |
mcm | 2:fa75aff130cc | 550 | |
mcm | 2:fa75aff130cc | 551 | // LEDs_OFF_L |
mcm | 2:fa75aff130cc | 552 | cmd[0] = ALL_LED_OFF_L; |
mcm | 2:fa75aff130cc | 553 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 554 | |
mcm | 2:fa75aff130cc | 555 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 556 | |
mcm | 2:fa75aff130cc | 557 | // LEDs_OFF_H |
mcm | 2:fa75aff130cc | 558 | cmd[0] = ALL_LED_OFF_H; |
mcm | 2:fa75aff130cc | 559 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 560 | |
mcm | 2:fa75aff130cc | 561 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 562 | |
mcm | 2:fa75aff130cc | 563 | |
mcm | 2:fa75aff130cc | 564 | |
mcm | 2:fa75aff130cc | 565 | |
mcm | 2:fa75aff130cc | 566 | |
mcm | 2:fa75aff130cc | 567 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 568 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 569 | else |
mcm | 2:fa75aff130cc | 570 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 571 | } |
mcm | 2:fa75aff130cc | 572 | |
mcm | 2:fa75aff130cc | 573 | |
mcm | 2:fa75aff130cc | 574 | |
mcm | 2:fa75aff130cc | 575 | |
mcm | 2:fa75aff130cc | 576 | /** |
mcm | 2:fa75aff130cc | 577 | * @brief PCA9685_SetAllLED_OFF ( void ) |
mcm | 2:fa75aff130cc | 578 | * |
mcm | 2:fa75aff130cc | 579 | * @details It sets All LEDs OFF. |
mcm | 2:fa75aff130cc | 580 | * |
mcm | 2:fa75aff130cc | 581 | * @param[in] NaN. |
mcm | 2:fa75aff130cc | 582 | * |
mcm | 2:fa75aff130cc | 583 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 584 | * |
mcm | 2:fa75aff130cc | 585 | * |
mcm | 2:fa75aff130cc | 586 | * @return Status of PCA9685_SetAllLED_OFF. |
mcm | 2:fa75aff130cc | 587 | * |
mcm | 2:fa75aff130cc | 588 | * |
mcm | 2:fa75aff130cc | 589 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 590 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 591 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 592 | * @pre Update on ACK requires all 4 PWM channel registers to be loaded before outputs will |
mcm | 2:fa75aff130cc | 593 | * change on the last ACK. |
mcm | 2:fa75aff130cc | 594 | * @warning NaN. |
mcm | 2:fa75aff130cc | 595 | */ |
mcm | 2:fa75aff130cc | 596 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetAllLED_OFF ( void ) |
mcm | 2:fa75aff130cc | 597 | { |
mcm | 2:fa75aff130cc | 598 | char cmd[] = { 0, 0 }; |
mcm | 2:fa75aff130cc | 599 | uint32_t aux; |
mcm | 2:fa75aff130cc | 600 | |
mcm | 2:fa75aff130cc | 601 | |
mcm | 2:fa75aff130cc | 602 | |
mcm | 2:fa75aff130cc | 603 | // LEDs_ON_L |
mcm | 2:fa75aff130cc | 604 | cmd[0] = ALL_LED_ON_L; |
mcm | 2:fa75aff130cc | 605 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 606 | |
mcm | 2:fa75aff130cc | 607 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 608 | |
mcm | 2:fa75aff130cc | 609 | // LEDs_ON_H |
mcm | 2:fa75aff130cc | 610 | cmd[0] = ALL_LED_ON_H; |
mcm | 2:fa75aff130cc | 611 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 612 | |
mcm | 2:fa75aff130cc | 613 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 614 | |
mcm | 2:fa75aff130cc | 615 | |
mcm | 2:fa75aff130cc | 616 | |
mcm | 2:fa75aff130cc | 617 | // LEDs_OFF_L |
mcm | 2:fa75aff130cc | 618 | cmd[0] = ALL_LED_OFF_L; |
mcm | 2:fa75aff130cc | 619 | cmd[1] = 0x00; // Dummy value |
mcm | 2:fa75aff130cc | 620 | |
mcm | 2:fa75aff130cc | 621 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 622 | |
mcm | 2:fa75aff130cc | 623 | // LEDs_OFF_H |
mcm | 2:fa75aff130cc | 624 | cmd[0] = ALL_LED_OFF_H; |
mcm | 2:fa75aff130cc | 625 | cmd[1] = 0x10; // All LEDs full OFF |
mcm | 2:fa75aff130cc | 626 | |
mcm | 2:fa75aff130cc | 627 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 628 | |
mcm | 2:fa75aff130cc | 629 | |
mcm | 2:fa75aff130cc | 630 | |
mcm | 2:fa75aff130cc | 631 | |
mcm | 2:fa75aff130cc | 632 | |
mcm | 2:fa75aff130cc | 633 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 634 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 635 | else |
mcm | 2:fa75aff130cc | 636 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 637 | } |
mcm | 2:fa75aff130cc | 638 | |
mcm | 2:fa75aff130cc | 639 | |
mcm | 2:fa75aff130cc | 640 | |
mcm | 2:fa75aff130cc | 641 | |
mcm | 2:fa75aff130cc | 642 | /** |
mcm | 2:fa75aff130cc | 643 | * @brief PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t ) |
mcm | 2:fa75aff130cc | 644 | * |
mcm | 2:fa75aff130cc | 645 | * @details The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 1. |
mcm | 2:fa75aff130cc | 646 | * |
mcm | 2:fa75aff130cc | 647 | * @param[in] mySUB1_mode: SUB1 Enabled/Disabled. |
mcm | 2:fa75aff130cc | 648 | * |
mcm | 2:fa75aff130cc | 649 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 650 | * |
mcm | 2:fa75aff130cc | 651 | * |
mcm | 2:fa75aff130cc | 652 | * @return Status of PCA9685_SetSUB1. |
mcm | 2:fa75aff130cc | 653 | * |
mcm | 2:fa75aff130cc | 654 | * |
mcm | 2:fa75aff130cc | 655 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 656 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 657 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 658 | * @pre NaN. |
mcm | 2:fa75aff130cc | 659 | * @warning NaN. |
mcm | 2:fa75aff130cc | 660 | */ |
mcm | 2:fa75aff130cc | 661 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t mySUB1_mode ) |
mcm | 2:fa75aff130cc | 662 | { |
mcm | 2:fa75aff130cc | 663 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 664 | uint32_t aux; |
mcm | 2:fa75aff130cc | 665 | |
mcm | 2:fa75aff130cc | 666 | |
mcm | 2:fa75aff130cc | 667 | // Mask SUB1 and update its value |
mcm | 2:fa75aff130cc | 668 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 669 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 670 | cmd[1] &= ~MODE1_SUB1_MASK; |
mcm | 2:fa75aff130cc | 671 | cmd[1] |= mySUB1_mode; |
mcm | 2:fa75aff130cc | 672 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 673 | |
mcm | 2:fa75aff130cc | 674 | |
mcm | 2:fa75aff130cc | 675 | |
mcm | 2:fa75aff130cc | 676 | |
mcm | 2:fa75aff130cc | 677 | |
mcm | 2:fa75aff130cc | 678 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 679 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 680 | else |
mcm | 2:fa75aff130cc | 681 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 682 | } |
mcm | 2:fa75aff130cc | 683 | |
mcm | 2:fa75aff130cc | 684 | |
mcm | 2:fa75aff130cc | 685 | |
mcm | 2:fa75aff130cc | 686 | |
mcm | 2:fa75aff130cc | 687 | /** |
mcm | 2:fa75aff130cc | 688 | * @brief PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t ) |
mcm | 2:fa75aff130cc | 689 | * |
mcm | 2:fa75aff130cc | 690 | * @details The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 2. |
mcm | 2:fa75aff130cc | 691 | * |
mcm | 2:fa75aff130cc | 692 | * @param[in] mySUB2_mode: SUB2 Enabled/Disabled. |
mcm | 2:fa75aff130cc | 693 | * |
mcm | 2:fa75aff130cc | 694 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 695 | * |
mcm | 2:fa75aff130cc | 696 | * |
mcm | 2:fa75aff130cc | 697 | * @return Status of PCA9685_SetSUB2. |
mcm | 2:fa75aff130cc | 698 | * |
mcm | 2:fa75aff130cc | 699 | * |
mcm | 2:fa75aff130cc | 700 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 701 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 702 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 703 | * @pre NaN. |
mcm | 2:fa75aff130cc | 704 | * @warning NaN. |
mcm | 2:fa75aff130cc | 705 | */ |
mcm | 2:fa75aff130cc | 706 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t mySUB2_mode ) |
mcm | 2:fa75aff130cc | 707 | { |
mcm | 2:fa75aff130cc | 708 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 709 | uint32_t aux; |
mcm | 2:fa75aff130cc | 710 | |
mcm | 2:fa75aff130cc | 711 | |
mcm | 2:fa75aff130cc | 712 | // Mask SUB2 and update its value |
mcm | 2:fa75aff130cc | 713 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 714 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 715 | cmd[1] &= ~MODE1_SUB2_MASK; |
mcm | 2:fa75aff130cc | 716 | cmd[1] |= mySUB2_mode; |
mcm | 2:fa75aff130cc | 717 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 718 | |
mcm | 2:fa75aff130cc | 719 | |
mcm | 2:fa75aff130cc | 720 | |
mcm | 2:fa75aff130cc | 721 | |
mcm | 2:fa75aff130cc | 722 | |
mcm | 2:fa75aff130cc | 723 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 724 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 725 | else |
mcm | 2:fa75aff130cc | 726 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 727 | } |
mcm | 2:fa75aff130cc | 728 | |
mcm | 2:fa75aff130cc | 729 | |
mcm | 2:fa75aff130cc | 730 | |
mcm | 2:fa75aff130cc | 731 | |
mcm | 2:fa75aff130cc | 732 | /** |
mcm | 2:fa75aff130cc | 733 | * @brief PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t ) |
mcm | 2:fa75aff130cc | 734 | * |
mcm | 2:fa75aff130cc | 735 | * @details The device responds ( Enabled ) or not ( Disabled ) to I2C-bus subaddress 3. |
mcm | 2:fa75aff130cc | 736 | * |
mcm | 2:fa75aff130cc | 737 | * @param[in] mySUB3_mode: SUB3 Enabled/Disabled. |
mcm | 2:fa75aff130cc | 738 | * |
mcm | 2:fa75aff130cc | 739 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 740 | * |
mcm | 2:fa75aff130cc | 741 | * |
mcm | 2:fa75aff130cc | 742 | * @return Status of PCA9685_SetSUB3. |
mcm | 2:fa75aff130cc | 743 | * |
mcm | 2:fa75aff130cc | 744 | * |
mcm | 2:fa75aff130cc | 745 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 746 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 747 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 748 | * @pre NaN. |
mcm | 2:fa75aff130cc | 749 | * @warning NaN. |
mcm | 2:fa75aff130cc | 750 | */ |
mcm | 2:fa75aff130cc | 751 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t mySUB3_mode ) |
mcm | 2:fa75aff130cc | 752 | { |
mcm | 2:fa75aff130cc | 753 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 754 | uint32_t aux; |
mcm | 2:fa75aff130cc | 755 | |
mcm | 2:fa75aff130cc | 756 | |
mcm | 2:fa75aff130cc | 757 | // Mask SUB3 and update its value |
mcm | 2:fa75aff130cc | 758 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 759 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 760 | cmd[1] &= ~MODE1_SUB3_MASK; |
mcm | 2:fa75aff130cc | 761 | cmd[1] |= mySUB3_mode; |
mcm | 2:fa75aff130cc | 762 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 763 | |
mcm | 2:fa75aff130cc | 764 | |
mcm | 2:fa75aff130cc | 765 | |
mcm | 2:fa75aff130cc | 766 | |
mcm | 2:fa75aff130cc | 767 | |
mcm | 2:fa75aff130cc | 768 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 769 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 770 | else |
mcm | 2:fa75aff130cc | 771 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 772 | } |
mcm | 2:fa75aff130cc | 773 | |
mcm | 2:fa75aff130cc | 774 | |
mcm | 2:fa75aff130cc | 775 | |
mcm | 2:fa75aff130cc | 776 | |
mcm | 2:fa75aff130cc | 777 | /** |
mcm | 2:fa75aff130cc | 778 | * @brief PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t ) |
mcm | 2:fa75aff130cc | 779 | * |
mcm | 2:fa75aff130cc | 780 | * @details The device responds ( Enabled ) or not ( Disabled ) to LED All Call I2C-bus address. |
mcm | 2:fa75aff130cc | 781 | * |
mcm | 2:fa75aff130cc | 782 | * @param[in] myALLCALL_mode: ALLCALL Enabled/Disabled. |
mcm | 2:fa75aff130cc | 783 | * |
mcm | 2:fa75aff130cc | 784 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 785 | * |
mcm | 2:fa75aff130cc | 786 | * |
mcm | 2:fa75aff130cc | 787 | * @return Status of PCA9685_SetALLCALL. |
mcm | 2:fa75aff130cc | 788 | * |
mcm | 2:fa75aff130cc | 789 | * |
mcm | 2:fa75aff130cc | 790 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 791 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 792 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 793 | * @pre NaN. |
mcm | 2:fa75aff130cc | 794 | * @warning NaN. |
mcm | 2:fa75aff130cc | 795 | */ |
mcm | 2:fa75aff130cc | 796 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t myALLCALL_mode ) |
mcm | 2:fa75aff130cc | 797 | { |
mcm | 2:fa75aff130cc | 798 | char cmd[] = { MODE1, 0 }; |
mcm | 2:fa75aff130cc | 799 | uint32_t aux; |
mcm | 2:fa75aff130cc | 800 | |
mcm | 2:fa75aff130cc | 801 | |
mcm | 2:fa75aff130cc | 802 | // Mask SUB3 and update its value |
mcm | 2:fa75aff130cc | 803 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 804 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 805 | cmd[1] &= ~MODE1_ALLCALL_MASK; |
mcm | 2:fa75aff130cc | 806 | cmd[1] |= myALLCALL_mode; |
mcm | 2:fa75aff130cc | 807 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 808 | |
mcm | 2:fa75aff130cc | 809 | |
mcm | 2:fa75aff130cc | 810 | |
mcm | 2:fa75aff130cc | 811 | |
mcm | 2:fa75aff130cc | 812 | |
mcm | 2:fa75aff130cc | 813 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 814 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 815 | else |
mcm | 2:fa75aff130cc | 816 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 817 | } |
mcm | 2:fa75aff130cc | 818 | |
mcm | 2:fa75aff130cc | 819 | |
mcm | 2:fa75aff130cc | 820 | |
mcm | 2:fa75aff130cc | 821 | |
mcm | 2:fa75aff130cc | 822 | /** |
mcm | 2:fa75aff130cc | 823 | * @brief PCA9685_SetINVERT ( PCA9685_mode2_invrt_t ) |
mcm | 2:fa75aff130cc | 824 | * |
mcm | 2:fa75aff130cc | 825 | * @details Output logic state inverted ( Enabled ) or not ( Disabled ). Value to use |
mcm | 2:fa75aff130cc | 826 | * when external driver used. Applicable when #OE = 0 |
mcm | 2:fa75aff130cc | 827 | * |
mcm | 2:fa75aff130cc | 828 | * @param[in] myINVERT_mode: INVERT Enabled/Disabled. |
mcm | 2:fa75aff130cc | 829 | * |
mcm | 2:fa75aff130cc | 830 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 831 | * |
mcm | 2:fa75aff130cc | 832 | * |
mcm | 2:fa75aff130cc | 833 | * @return Status of PCA9685_SetINVERT. |
mcm | 2:fa75aff130cc | 834 | * |
mcm | 2:fa75aff130cc | 835 | * |
mcm | 2:fa75aff130cc | 836 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 837 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 838 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 839 | * @pre NaN. |
mcm | 2:fa75aff130cc | 840 | * @warning NaN. |
mcm | 2:fa75aff130cc | 841 | */ |
mcm | 2:fa75aff130cc | 842 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetINVERT ( PCA9685_mode2_invrt_t myINVERT_mode ) |
mcm | 2:fa75aff130cc | 843 | { |
mcm | 2:fa75aff130cc | 844 | char cmd[] = { MODE2, 0 }; |
mcm | 2:fa75aff130cc | 845 | uint32_t aux; |
mcm | 2:fa75aff130cc | 846 | |
mcm | 2:fa75aff130cc | 847 | |
mcm | 2:fa75aff130cc | 848 | // Mask SUB3 and update its value |
mcm | 2:fa75aff130cc | 849 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 850 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 851 | cmd[1] &= ~MODE2_INVRT_MASK; |
mcm | 2:fa75aff130cc | 852 | cmd[1] |= myINVERT_mode; |
mcm | 2:fa75aff130cc | 853 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 854 | |
mcm | 2:fa75aff130cc | 855 | |
mcm | 2:fa75aff130cc | 856 | |
mcm | 2:fa75aff130cc | 857 | |
mcm | 2:fa75aff130cc | 858 | |
mcm | 2:fa75aff130cc | 859 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 860 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 861 | else |
mcm | 2:fa75aff130cc | 862 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 863 | } |
mcm | 2:fa75aff130cc | 864 | |
mcm | 2:fa75aff130cc | 865 | |
mcm | 2:fa75aff130cc | 866 | |
mcm | 2:fa75aff130cc | 867 | |
mcm | 2:fa75aff130cc | 868 | /** |
mcm | 2:fa75aff130cc | 869 | * @brief PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t ) |
mcm | 2:fa75aff130cc | 870 | * |
mcm | 2:fa75aff130cc | 871 | * @details It sets the 16 LEDn as open-drain or totem pole structure. |
mcm | 2:fa75aff130cc | 872 | * |
mcm | 2:fa75aff130cc | 873 | * @param[in] myOUTDRV_mode: OUTDRV mode. |
mcm | 2:fa75aff130cc | 874 | * |
mcm | 2:fa75aff130cc | 875 | * @param[out] NaN. |
mcm | 2:fa75aff130cc | 876 | * |
mcm | 2:fa75aff130cc | 877 | * |
mcm | 2:fa75aff130cc | 878 | * @return Status of PCA9685_SetOUTDRV. |
mcm | 2:fa75aff130cc | 879 | * |
mcm | 2:fa75aff130cc | 880 | * |
mcm | 2:fa75aff130cc | 881 | * @author Manuel Caballero |
mcm | 2:fa75aff130cc | 882 | * @date 7/November/2017 |
mcm | 2:fa75aff130cc | 883 | * @version 7/November/2017 The ORIGIN |
mcm | 2:fa75aff130cc | 884 | * @pre NaN. |
mcm | 2:fa75aff130cc | 885 | * @warning NaN. |
mcm | 2:fa75aff130cc | 886 | */ |
mcm | 2:fa75aff130cc | 887 | PCA9685::PCA9685_status_t PCA9685::PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t myOUTDRV_mode ) |
mcm | 2:fa75aff130cc | 888 | { |
mcm | 2:fa75aff130cc | 889 | char cmd[] = { MODE2, 0 }; |
mcm | 2:fa75aff130cc | 890 | uint32_t aux; |
mcm | 2:fa75aff130cc | 891 | |
mcm | 2:fa75aff130cc | 892 | |
mcm | 2:fa75aff130cc | 893 | // Mask SUB3 and update its value |
mcm | 2:fa75aff130cc | 894 | aux = i2c.write ( PCA9685_Addr, &cmd[0], 1, true ); |
mcm | 2:fa75aff130cc | 895 | aux = i2c.read ( PCA9685_Addr, &cmd[1], 1 ); |
mcm | 2:fa75aff130cc | 896 | cmd[1] &= ~MODE2_OUTDRV_MASK; |
mcm | 2:fa75aff130cc | 897 | cmd[1] |= myOUTDRV_mode; |
mcm | 2:fa75aff130cc | 898 | aux = i2c.write ( PCA9685_Addr, &cmd[0], sizeof( cmd )/sizeof( cmd[0] ), false ); |
mcm | 2:fa75aff130cc | 899 | |
mcm | 2:fa75aff130cc | 900 | |
mcm | 2:fa75aff130cc | 901 | |
mcm | 2:fa75aff130cc | 902 | |
mcm | 2:fa75aff130cc | 903 | |
mcm | 2:fa75aff130cc | 904 | if ( aux == I2C_SUCCESS ) |
mcm | 2:fa75aff130cc | 905 | return PCA9685_SUCCESS; |
mcm | 2:fa75aff130cc | 906 | else |
mcm | 2:fa75aff130cc | 907 | return PCA9685_FAILURE; |
mcm | 2:fa75aff130cc | 908 | } |