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

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?

UserRevisionLine numberNew contents of line
mcm 1:6e7731f14aac 1 /**
mcm 1:6e7731f14aac 2 * @brief PCA9685.h
mcm 1:6e7731f14aac 3 * @details 16-channel, 12-bit PWM Fm+ I2C-bus LED controller.
mcm 1:6e7731f14aac 4 * Header file.
mcm 1:6e7731f14aac 5 *
mcm 1:6e7731f14aac 6 *
mcm 1:6e7731f14aac 7 * @return NA
mcm 1:6e7731f14aac 8 *
mcm 1:6e7731f14aac 9 * @author Manuel Caballero
mcm 1:6e7731f14aac 10 * @date 31/October/2017
mcm 1:6e7731f14aac 11 * @version 31/October/2017 The ORIGIN
mcm 1:6e7731f14aac 12 * @pre NaN.
mcm 1:6e7731f14aac 13 * @warning NaN
mcm 1:6e7731f14aac 14 * @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
mcm 1:6e7731f14aac 15 */
mcm 1:6e7731f14aac 16 #ifndef PCA9685_H
mcm 1:6e7731f14aac 17 #define PCA9685_H
mcm 1:6e7731f14aac 18
mcm 1:6e7731f14aac 19 #include "mbed.h"
mcm 1:6e7731f14aac 20
mcm 1:6e7731f14aac 21
mcm 1:6e7731f14aac 22 /**
mcm 1:6e7731f14aac 23 Example:
mcm 1:6e7731f14aac 24
mcm 3:f69f4e2c35b6 25 #include "mbed.h"
mcm 3:f69f4e2c35b6 26 #include "PCA9685.h"
mcm 3:f69f4e2c35b6 27
mcm 3:f69f4e2c35b6 28 PCA9685 myPWMSensor ( I2C_SDA, I2C_SCL, PCA9685::PCA9685_ADDRESS_0, 400000 );
mcm 3:f69f4e2c35b6 29
mcm 3:f69f4e2c35b6 30
mcm 3:f69f4e2c35b6 31 Ticker newPWMOutput;
mcm 3:f69f4e2c35b6 32 DigitalOut myled(LED1);
mcm 3:f69f4e2c35b6 33
mcm 3:f69f4e2c35b6 34 PCA9685::PCA9685_status_t aux;
mcm 3:f69f4e2c35b6 35 uint8_t myState = 0;
mcm 3:f69f4e2c35b6 36
mcm 3:f69f4e2c35b6 37
mcm 3:f69f4e2c35b6 38 void changeDATA ( void )
mcm 3:f69f4e2c35b6 39 {
mcm 3:f69f4e2c35b6 40 myState++;
mcm 3:f69f4e2c35b6 41 }
mcm 3:f69f4e2c35b6 42
mcm 3:f69f4e2c35b6 43
mcm 3:f69f4e2c35b6 44 int main()
mcm 3:f69f4e2c35b6 45 {
mcm 3:f69f4e2c35b6 46 // Reset the device
mcm 3:f69f4e2c35b6 47 aux = myPWMSensor.PCA9685_SoftReset ();
mcm 3:f69f4e2c35b6 48 wait_us ( 5 );
mcm 3:f69f4e2c35b6 49
mcm 3:f69f4e2c35b6 50 // Configure the PWM frequency and wake up the device
mcm 3:f69f4e2c35b6 51 aux = myPWMSensor.PCA9685_SetPWM_Freq ( 1000 ); // PWM frequency: 1kHz
mcm 3:f69f4e2c35b6 52 aux = myPWMSensor.PCA9685_SetMode ( PCA9685::MODE1_SLEEP_DISABLED );
mcm 3:f69f4e2c35b6 53
mcm 3:f69f4e2c35b6 54
mcm 3:f69f4e2c35b6 55 newPWMOutput.attach( &changeDATA, 1 ); // the address of the function to be attached ( changeDATA ) and the interval ( 1s )
mcm 3:f69f4e2c35b6 56
mcm 3:f69f4e2c35b6 57 // Let the callbacks take care of everything
mcm 3:f69f4e2c35b6 58 while(1) {
mcm 3:f69f4e2c35b6 59 sleep();
mcm 3:f69f4e2c35b6 60
mcm 3:f69f4e2c35b6 61 myled = 1;
mcm 3:f69f4e2c35b6 62
mcm 3:f69f4e2c35b6 63 switch ( myState ) {
mcm 3:f69f4e2c35b6 64 default:
mcm 3:f69f4e2c35b6 65 case 0:
mcm 3:f69f4e2c35b6 66 // All LEDs: Delay Time = 1% | PWM duty cycle = 99%
mcm 3:f69f4e2c35b6 67 aux = myPWMSensor.PCA9685_SetPWM_DutyCycle_AllLEDs ( 0, 99 );
mcm 3:f69f4e2c35b6 68
mcm 3:f69f4e2c35b6 69 myState = 1;
mcm 3:f69f4e2c35b6 70 break;
mcm 3:f69f4e2c35b6 71
mcm 3:f69f4e2c35b6 72 case 1:
mcm 3:f69f4e2c35b6 73 // All LEDs: Delay Time = 100% | PWM duty cycle = 1%
mcm 3:f69f4e2c35b6 74 aux = myPWMSensor.PCA9685_SetPWM_DutyCycle_AllLEDs ( 100, 1 );
mcm 3:f69f4e2c35b6 75
mcm 3:f69f4e2c35b6 76 myState = 2;
mcm 3:f69f4e2c35b6 77 break;
mcm 3:f69f4e2c35b6 78
mcm 3:f69f4e2c35b6 79 case 2:
mcm 3:f69f4e2c35b6 80 // LED1: Delay Time = 10% | PWM duty cycle = 30%
mcm 3:f69f4e2c35b6 81 aux = myPWMSensor.PCA9685_SetPWM_DutyCycle ( PCA9685::PCA9685_LED1, 10, 30 );
mcm 3:f69f4e2c35b6 82
mcm 3:f69f4e2c35b6 83 myState = 0;
mcm 3:f69f4e2c35b6 84 break;
mcm 3:f69f4e2c35b6 85 }
mcm 3:f69f4e2c35b6 86
mcm 3:f69f4e2c35b6 87 myled = 0;
mcm 3:f69f4e2c35b6 88 }
mcm 3:f69f4e2c35b6 89 }
mcm 1:6e7731f14aac 90 */
mcm 1:6e7731f14aac 91
mcm 1:6e7731f14aac 92
mcm 1:6e7731f14aac 93 /*!
mcm 1:6e7731f14aac 94 Library for the PCA9685 16-channel, 12-bit PWM Fm+ I2C-bus LED controller.
mcm 1:6e7731f14aac 95 */
mcm 1:6e7731f14aac 96 class PCA9685
mcm 1:6e7731f14aac 97 {
mcm 1:6e7731f14aac 98 public:
mcm 1:6e7731f14aac 99 /**
mcm 1:6e7731f14aac 100 * @brief DEFAULT ADDRESSES. NOTE: There are a maximum of 64 possible programmable addresses using the 6 hardware
mcm 1:6e7731f14aac 101 * address pins. Two of these addresses, Software Reset and LED All Call, cannot be used
mcm 1:6e7731f14aac 102 * because their default power-up state is ON, leaving a maximum of 62 addresses. Using
mcm 1:6e7731f14aac 103 * other reserved addresses, as well as any other subcall address, will reduce the total
mcm 1:6e7731f14aac 104 * number of possible addresses even further.
mcm 1:6e7731f14aac 105 *
mcm 1:6e7731f14aac 106 * To access to a certain address just use the following method: PCA9685_ADDRESS_0 + Counter_Address
mcm 1:6e7731f14aac 107 * Ex:
mcm 1:6e7731f14aac 108 * PCA9685_ADDRESS_0 + 1 = 0x40 + 1 = 0x41 ( 0b1000001 )
mcm 1:6e7731f14aac 109 * PCA9685_ADDRESS_0 + 10 = 0x40 + 10 = 0x4A ( 0b1001010 )
mcm 1:6e7731f14aac 110 * and so on...
mcm 1:6e7731f14aac 111 */
mcm 1:6e7731f14aac 112 typedef enum {
mcm 1:6e7731f14aac 113 PCA9685_ADDRESS_0 = ( 0x40 << 1 ) /*!< A5 A4 A3 A2 A1 A0: 000 000 */
mcm 1:6e7731f14aac 114 } PCA9685_address_t;
mcm 1:6e7731f14aac 115
mcm 1:6e7731f14aac 116
mcm 1:6e7731f14aac 117 // REGISTERS
mcm 1:6e7731f14aac 118 /**
mcm 1:6e7731f14aac 119 * @brief REGISTER DEFINITIONS
mcm 1:6e7731f14aac 120 */
mcm 1:6e7731f14aac 121 typedef enum {
mcm 1:6e7731f14aac 122 MODE1 = 0x00, /*!< Mode register 1 */
mcm 1:6e7731f14aac 123 MODE2 = 0x01, /*!< Mode register 2 */
mcm 1:6e7731f14aac 124 SUBADR1 = 0x02, /*!< I2C-bus subaddress 1 */
mcm 1:6e7731f14aac 125 SUBADR2 = 0x03, /*!< I2C-bus subaddress 2 */
mcm 1:6e7731f14aac 126 SUBADR3 = 0x04, /*!< I2C-bus subaddress 3 */
mcm 1:6e7731f14aac 127 ALLCALLADR = 0x05, /*!< LED All Call I2C-bus address */
mcm 1:6e7731f14aac 128 LED0_ON_L = 0x06, /*!< LED0 output and brightness control byte 0 */
mcm 1:6e7731f14aac 129 LED0_ON_H = 0x07, /*!< LED0 output and brightness control byte 1 */
mcm 1:6e7731f14aac 130 LED0_OFF_L = 0x08, /*!< LED0 output and brightness control byte 2 */
mcm 1:6e7731f14aac 131 LED0_OFF_H = 0x09, /*!< LED0 output and brightness control byte 3 */
mcm 1:6e7731f14aac 132 LED1_ON_L = 0x0A, /*!< LED1 output and brightness control byte 0 */
mcm 1:6e7731f14aac 133 LED1_ON_H = 0x0B, /*!< LED1 output and brightness control byte 1 */
mcm 1:6e7731f14aac 134 LED1_OFF_L = 0x0C, /*!< LED1 output and brightness control byte 2 */
mcm 1:6e7731f14aac 135 LED1_OFF_H = 0x0D, /*!< LED1 output and brightness control byte 3 */
mcm 1:6e7731f14aac 136 LED2_ON_L = 0x0E, /*!< LED2 output and brightness control byte 0 */
mcm 1:6e7731f14aac 137 LED2_ON_H = 0x0F, /*!< LED2 output and brightness control byte 1 */
mcm 1:6e7731f14aac 138 LED2_OFF_L = 0x10, /*!< LED2 output and brightness control byte 2 */
mcm 1:6e7731f14aac 139 LED2_OFF_H = 0x11, /*!< LED2 output and brightness control byte 3 */
mcm 1:6e7731f14aac 140 LED3_ON_L = 0x12, /*!< LED3 output and brightness control byte 0 */
mcm 1:6e7731f14aac 141 LED3_ON_H = 0x13, /*!< LED3 output and brightness control byte 1 */
mcm 1:6e7731f14aac 142 LED3_OFF_L = 0x14, /*!< LED3 output and brightness control byte 2 */
mcm 1:6e7731f14aac 143 LED3_OFF_H = 0x15, /*!< LED3 output and brightness control byte 3 */
mcm 1:6e7731f14aac 144 LED4_ON_L = 0x16, /*!< LED4 output and brightness control byte 0 */
mcm 1:6e7731f14aac 145 LED4_ON_H = 0x17, /*!< LED4 output and brightness control byte 1 */
mcm 1:6e7731f14aac 146 LED4_OFF_L = 0x18, /*!< LED4 output and brightness control byte 2 */
mcm 1:6e7731f14aac 147 LED4_OFF_H = 0x19, /*!< LED4 output and brightness control byte 3 */
mcm 1:6e7731f14aac 148 LED5_ON_L = 0x1A, /*!< LED5 output and brightness control byte 0 */
mcm 1:6e7731f14aac 149 LED5_ON_H = 0x1B, /*!< LED5 output and brightness control byte 1 */
mcm 1:6e7731f14aac 150 LED5_OFF_L = 0x1C, /*!< LED5 output and brightness control byte 2 */
mcm 1:6e7731f14aac 151 LED5_OFF_H = 0x1D, /*!< LED5 output and brightness control byte 3 */
mcm 1:6e7731f14aac 152 LED6_ON_L = 0x1E, /*!< LED6 output and brightness control byte 0 */
mcm 1:6e7731f14aac 153 LED6_ON_H = 0x1F, /*!< LED6 output and brightness control byte 1 */
mcm 1:6e7731f14aac 154 LED6_OFF_L = 0x20, /*!< LED6 output and brightness control byte 2 */
mcm 1:6e7731f14aac 155 LED6_OFF_H = 0x21, /*!< LED6 output and brightness control byte 3 */
mcm 1:6e7731f14aac 156 LED7_ON_L = 0x22, /*!< LED7 output and brightness control byte 0 */
mcm 1:6e7731f14aac 157 LED7_ON_H = 0x23, /*!< LED7 output and brightness control byte 1 */
mcm 1:6e7731f14aac 158 LED7_OFF_L = 0x24, /*!< LED7 output and brightness control byte 2 */
mcm 1:6e7731f14aac 159 LED7_OFF_H = 0x25, /*!< LED7 output and brightness control byte 3 */
mcm 1:6e7731f14aac 160 LED8_ON_L = 0x26, /*!< LED8 output and brightness control byte 0 */
mcm 1:6e7731f14aac 161 LED8_ON_H = 0x27, /*!< LED8 output and brightness control byte 1 */
mcm 1:6e7731f14aac 162 LED8_OFF_L = 0x28, /*!< LED8 output and brightness control byte 2 */
mcm 1:6e7731f14aac 163 LED8_OFF_H = 0x29, /*!< LED8 output and brightness control byte 3 */
mcm 1:6e7731f14aac 164 LED9_ON_L = 0x2A, /*!< LED9 output and brightness control byte 0 */
mcm 1:6e7731f14aac 165 LED9_ON_H = 0x2B, /*!< LED9 output and brightness control byte 1 */
mcm 1:6e7731f14aac 166 LED9_OFF_L = 0x2C, /*!< LED9 output and brightness control byte 2 */
mcm 1:6e7731f14aac 167 LED9_OFF_H = 0x2D, /*!< LED9 output and brightness control byte 3 */
mcm 1:6e7731f14aac 168 LED10_ON_L = 0x2E, /*!< LED10 output and brightness control byte 0 */
mcm 1:6e7731f14aac 169 LED10_ON_H = 0x2F, /*!< LED10 output and brightness control byte 1 */
mcm 1:6e7731f14aac 170 LED10_OFF_L = 0x30, /*!< LED10 output and brightness control byte 2 */
mcm 1:6e7731f14aac 171 LED10_OFF_H = 0x31, /*!< LED10 output and brightness control byte 3 */
mcm 1:6e7731f14aac 172 LED11_ON_L = 0x32, /*!< LED11 output and brightness control byte 0 */
mcm 1:6e7731f14aac 173 LED11_ON_H = 0x33, /*!< LED11 output and brightness control byte 1 */
mcm 1:6e7731f14aac 174 LED11_OFF_L = 0x34, /*!< LED11 output and brightness control byte 2 */
mcm 1:6e7731f14aac 175 LED11_OFF_H = 0x35, /*!< LED11 output and brightness control byte 3 */
mcm 1:6e7731f14aac 176 LED12_ON_L = 0x36, /*!< LED12 output and brightness control byte 0 */
mcm 1:6e7731f14aac 177 LED12_ON_H = 0x37, /*!< LED12 output and brightness control byte 1 */
mcm 1:6e7731f14aac 178 LED12_OFF_L = 0x38, /*!< LED12 output and brightness control byte 2 */
mcm 1:6e7731f14aac 179 LED12_OFF_H = 0x39, /*!< LED12 output and brightness control byte 3 */
mcm 1:6e7731f14aac 180 LED13_ON_L = 0x3A, /*!< LED13 output and brightness control byte 0 */
mcm 1:6e7731f14aac 181 LED13_ON_H = 0x3B, /*!< LED13 output and brightness control byte 1 */
mcm 1:6e7731f14aac 182 LED13_OFF_L = 0x3C, /*!< LED13 output and brightness control byte 2 */
mcm 1:6e7731f14aac 183 LED13_OFF_H = 0x3D, /*!< LED13 output and brightness control byte 3 */
mcm 1:6e7731f14aac 184 LED14_ON_L = 0x3E, /*!< LED14 output and brightness control byte 0 */
mcm 1:6e7731f14aac 185 LED14_ON_H = 0x3F, /*!< LED14 output and brightness control byte 1 */
mcm 1:6e7731f14aac 186 LED14_OFF_L = 0x40, /*!< LED14 output and brightness control byte 2 */
mcm 1:6e7731f14aac 187 LED14_OFF_H = 0x41, /*!< LED14 output and brightness control byte 3 */
mcm 1:6e7731f14aac 188 LED15_ON_L = 0x42, /*!< LED15 output and brightness control byte 0 */
mcm 1:6e7731f14aac 189 LED15_ON_H = 0x43, /*!< LED15 output and brightness control byte 1 */
mcm 1:6e7731f14aac 190 LED15_OFF_L = 0x44, /*!< LED15 output and brightness control byte 2 */
mcm 1:6e7731f14aac 191 LED15_OFF_H = 0x45, /*!< LED15 output and brightness control byte 3 */
mcm 1:6e7731f14aac 192 ALL_LED_ON_L = 0xFA, /*!< load all the LEDn_ON registers, byte 0 */
mcm 1:6e7731f14aac 193 ALL_LED_ON_H = 0xFB, /*!< load all the LEDn_ON registers, byte 1 */
mcm 1:6e7731f14aac 194 ALL_LED_OFF_L = 0xFC, /*!< load all the LEDn_OFF registers, byte 0 */
mcm 1:6e7731f14aac 195 ALL_LED_OFF_H = 0xFD, /*!< load all the LEDn_OFF registers, byte 1 */
mcm 1:6e7731f14aac 196 PRE_SCALE = 0xFE, /*!< prescaler for PWM output frequency */
mcm 1:6e7731f14aac 197 TESTMODE = 0xFF /*!< defines the test mode to be entered */
mcm 1:6e7731f14aac 198 } PCA9685_registers_t;
mcm 1:6e7731f14aac 199
mcm 1:6e7731f14aac 200
mcm 1:6e7731f14aac 201
mcm 1:6e7731f14aac 202 // LED Sub Call I2C-bus addresses
mcm 1:6e7731f14aac 203 /**
mcm 1:6e7731f14aac 204 * @brief SUBADDRESS. NOTE: At power-up, Sub Call I2C-bus addresses are disabled. PCA9685 does not send an
mcm 1:6e7731f14aac 205 * ACK when E2h (R/W = 0) or E3h (R/W = 1), E4h (R/W = 0) or E5h (R/W = 1), or
mcm 1:6e7731f14aac 206 * E8h (R/W = 0) or E9h (R/W = 1) is sent by the master.
mcm 1:6e7731f14aac 207 */
mcm 1:6e7731f14aac 208 typedef enum {
mcm 1:6e7731f14aac 209 SUBADR1_REG = ( 0xE2 << 1 ), /*!< Subaddress 1 */
mcm 1:6e7731f14aac 210 SUBADR2_REG = ( 0xE4 << 1 ), /*!< Subaddress 2 */
mcm 1:6e7731f14aac 211 SUBADR3_REG = ( 0xE8 << 1 ) /*!< Subaddress 3 */
mcm 1:6e7731f14aac 212 } PCA9685_subaddresses_t;
mcm 1:6e7731f14aac 213
mcm 1:6e7731f14aac 214
mcm 1:6e7731f14aac 215
mcm 1:6e7731f14aac 216
mcm 1:6e7731f14aac 217 // Software Reset I2C-bus address
mcm 1:6e7731f14aac 218 /**
mcm 1:6e7731f14aac 219 * @brief SWRST. NOTE: The Software Reset address (SWRST Call) must be used with
mcm 1:6e7731f14aac 220 * R/#W = logic 0. If R/#W = logic 1, the PCA9685 does not acknowledge the SWRST.
mcm 1:6e7731f14aac 221 */
mcm 1:6e7731f14aac 222 typedef enum {
mcm 1:6e7731f14aac 223 GENERAL_CALL_ADDRESS = ( 0x00 << 1 ), /*!< Software reset */
mcm 3:f69f4e2c35b6 224 SWRST = 0x06 /*!< Software reset */
mcm 1:6e7731f14aac 225 } PCA9685_software_reset_t;
mcm 1:6e7731f14aac 226
mcm 1:6e7731f14aac 227
mcm 1:6e7731f14aac 228
mcm 1:6e7731f14aac 229
mcm 1:6e7731f14aac 230 // MODE REGISTER 1, MODE1
mcm 1:6e7731f14aac 231 /**
mcm 1:6e7731f14aac 232 * @brief RESTART
mcm 1:6e7731f14aac 233 */
mcm 1:6e7731f14aac 234 typedef enum {
mcm 1:6e7731f14aac 235 MODE1_RESTART_MASK = ( 1 << 7 ), /*!< RESTART bit mask */
mcm 1:6e7731f14aac 236 MODE1_RESTART_ENABLED = ( 1 << 7 ), /*!< Restart enabled */
mcm 1:6e7731f14aac 237 MODE1_RESTART_DISABLED = ( 0 << 7 ) /*!< Restart disabled ( default ) */
mcm 1:6e7731f14aac 238 } PCA9685_mode1_restart_t;
mcm 1:6e7731f14aac 239
mcm 1:6e7731f14aac 240
mcm 1:6e7731f14aac 241 /**
mcm 1:6e7731f14aac 242 * @brief EXTCLK
mcm 1:6e7731f14aac 243 */
mcm 1:6e7731f14aac 244 typedef enum {
mcm 1:6e7731f14aac 245 MODE1_EXTCLK_MASK = ( 1 << 6 ), /*!< EXTCLK bit mask */
mcm 1:6e7731f14aac 246 MODE1_EXTCLK_ENABLED = ( 1 << 6 ), /*!< Use EXTERNAL clock */
mcm 1:6e7731f14aac 247 MODE1_EXTCLK_DISABLED = ( 0 << 6 ) /*!< Use INTERNAL clock ( default ) */
mcm 1:6e7731f14aac 248 } PCA9685_mode1_extclk_t;
mcm 1:6e7731f14aac 249
mcm 1:6e7731f14aac 250
mcm 1:6e7731f14aac 251 /**
mcm 1:6e7731f14aac 252 * @brief AI
mcm 1:6e7731f14aac 253 */
mcm 1:6e7731f14aac 254 typedef enum {
mcm 1:6e7731f14aac 255 MODE1_AI_MASK = ( 1 << 5 ), /*!< AI bit mask */
mcm 1:6e7731f14aac 256 MODE1_AI_ENABLED = ( 1 << 5 ), /*!< Auto-Increment enabled */
mcm 1:6e7731f14aac 257 MODE1_AI_DISABLED = ( 0 << 5 ) /*!< Auto-Increment disabled ( default ) */
mcm 1:6e7731f14aac 258 } PCA9685_mode1_ai_t;
mcm 1:6e7731f14aac 259
mcm 1:6e7731f14aac 260
mcm 1:6e7731f14aac 261 /**
mcm 1:6e7731f14aac 262 * @brief SLEEP
mcm 1:6e7731f14aac 263 */
mcm 1:6e7731f14aac 264 typedef enum {
mcm 1:6e7731f14aac 265 MODE1_SLEEP_MASK = ( 1 << 4 ), /*!< SLEEP bit mask */
mcm 1:6e7731f14aac 266 MODE1_SLEEP_ENABLED = ( 1 << 4 ), /*!< Low power mode. Oscillator off ( default ) */
mcm 1:6e7731f14aac 267 MODE1_SLEEP_DISABLED = ( 0 << 4 ) /*!< Normal mode */
mcm 1:6e7731f14aac 268 } PCA9685_mode1_sleep_t;
mcm 1:6e7731f14aac 269
mcm 1:6e7731f14aac 270
mcm 1:6e7731f14aac 271 /**
mcm 1:6e7731f14aac 272 * @brief SUB1
mcm 1:6e7731f14aac 273 */
mcm 1:6e7731f14aac 274 typedef enum {
mcm 1:6e7731f14aac 275 MODE1_SUB1_MASK = ( 1 << 3 ), /*!< SUB1 bit mask */
mcm 1:6e7731f14aac 276 MODE1_SUB1_ENABLED = ( 1 << 3 ), /*!< PCA9685 responds to I2C-bus subaddress 1 */
mcm 1:6e7731f14aac 277 MODE1_SUB1_DISABLED = ( 0 << 3 ) /*!< PCA9685 does not respond to I2C-bus subaddress 1 ( default ) */
mcm 1:6e7731f14aac 278 } PCA9685_mode1_sub1_t;
mcm 1:6e7731f14aac 279
mcm 1:6e7731f14aac 280
mcm 1:6e7731f14aac 281 /**
mcm 1:6e7731f14aac 282 * @brief SUB2
mcm 1:6e7731f14aac 283 */
mcm 1:6e7731f14aac 284 typedef enum {
mcm 1:6e7731f14aac 285 MODE1_SUB2_MASK = ( 1 << 2 ), /*!< SUB2 bit mask */
mcm 1:6e7731f14aac 286 MODE1_SUB2_ENABLED = ( 1 << 2 ), /*!< PCA9685 responds to I2C-bus subaddress 2 */
mcm 1:6e7731f14aac 287 MODE1_SUB2_DISABLED = ( 0 << 2 ) /*!< PCA9685 does not respond to I2C-bus subaddress 2 ( default ) */
mcm 1:6e7731f14aac 288 } PCA9685_mode1_sub2_t;
mcm 1:6e7731f14aac 289
mcm 1:6e7731f14aac 290
mcm 1:6e7731f14aac 291 /**
mcm 1:6e7731f14aac 292 * @brief SUB3
mcm 1:6e7731f14aac 293 */
mcm 1:6e7731f14aac 294 typedef enum {
mcm 1:6e7731f14aac 295 MODE1_SUB3_MASK = ( 1 << 1 ), /*!< SUB1 bit mask */
mcm 1:6e7731f14aac 296 MODE1_SUB3_ENABLED = ( 1 << 1 ), /*!< PCA9685 responds to I2C-bus subaddress 3 */
mcm 1:6e7731f14aac 297 MODE1_SUB3_DISABLED = ( 0 << 1 ) /*!< PCA9685 does not respond to I2C-bus subaddress 3 ( default ) */
mcm 1:6e7731f14aac 298 } PCA9685_mode1_sub3_t;
mcm 1:6e7731f14aac 299
mcm 1:6e7731f14aac 300
mcm 1:6e7731f14aac 301 /**
mcm 1:6e7731f14aac 302 * @brief ALLCALL
mcm 1:6e7731f14aac 303 */
mcm 1:6e7731f14aac 304 typedef enum {
mcm 1:6e7731f14aac 305 MODE1_ALLCALL_MASK = ( 1 << 0 ), /*!< ALLCALL bit mask */
mcm 1:6e7731f14aac 306 MODE1_ALLCALL_ENABLED = ( 1 << 0 ), /*!< PCA9685 responds to LED All Call I2C-bus address ( default ) */
mcm 1:6e7731f14aac 307 MODE1_ALLCALL_DISABLED = ( 0 << 0 ) /*!< PCA9685 does not respond to LED All Call I2C-bus address */
mcm 1:6e7731f14aac 308 } PCA9685_mode1_allcall_t;
mcm 1:6e7731f14aac 309
mcm 1:6e7731f14aac 310
mcm 1:6e7731f14aac 311
mcm 1:6e7731f14aac 312 // MODE REGISTER 2, MODE2
mcm 1:6e7731f14aac 313 /**
mcm 1:6e7731f14aac 314 * @brief INVRT
mcm 1:6e7731f14aac 315 */
mcm 1:6e7731f14aac 316 typedef enum {
mcm 1:6e7731f14aac 317 MODE2_INVRT_MASK = ( 1 << 4 ), /*!< INVRT bit mask */
mcm 1:6e7731f14aac 318 MODE2_INVRT_ENABLED = ( 1 << 4 ), /*!< Output logic state inverted. Value to use when no external driver used. Applicable when OE = 0 */
mcm 1:6e7731f14aac 319 MODE2_INVRT_DISABLED = ( 0 << 4 ) /*!< Output logic state not inverted. Value to use when external driver used. Applicable when OE = 0. ( default ) */
mcm 1:6e7731f14aac 320 } PCA9685_mode2_invrt_t;
mcm 1:6e7731f14aac 321
mcm 1:6e7731f14aac 322
mcm 1:6e7731f14aac 323 /**
mcm 1:6e7731f14aac 324 * @brief OCH
mcm 1:6e7731f14aac 325 */
mcm 1:6e7731f14aac 326 typedef enum {
mcm 1:6e7731f14aac 327 MODE2_OCH_MASK = ( 1 << 3 ), /*!< ALLCALL bit mask */
mcm 1:6e7731f14aac 328 MODE2_OCH_OUTPUT_CHANGE_STOP_CMD = ( 0 << 3 ), /*!< Outputs change on STOP command ( default ) */
mcm 1:6e7731f14aac 329 MODE2_OCH_OUTPUT_CHANGE_ACK_CMD = ( 1 << 3 ) /*!< Outputs change on ACK */
mcm 1:6e7731f14aac 330 } PCA9685_mode2_och_t;
mcm 1:6e7731f14aac 331
mcm 1:6e7731f14aac 332
mcm 1:6e7731f14aac 333 /**
mcm 1:6e7731f14aac 334 * @brief OUTDRV
mcm 1:6e7731f14aac 335 */
mcm 1:6e7731f14aac 336 typedef enum {
mcm 1:6e7731f14aac 337 MODE2_OUTDRV_MASK = ( 1 << 2 ), /*!< OUTDRV bit mask */
mcm 1:6e7731f14aac 338 MODE2_OUTDRV_TOTEM_POLE_STRUCTURE = ( 1 << 2 ), /*!< The 16 LEDn outputs are configured with a totem pole structure ( default ) */
mcm 1:6e7731f14aac 339 MODE2_OUTDRV_OPEN_DRAIN_STRUCTURE = ( 0 << 2 ) /*!< The 16 LEDn outputs are configured with an open-drain structure */
mcm 1:6e7731f14aac 340 } PCA9685_mode2_outdrv_t;
mcm 1:6e7731f14aac 341
mcm 1:6e7731f14aac 342
mcm 1:6e7731f14aac 343 /**
mcm 1:6e7731f14aac 344 * @brief OUTNE
mcm 1:6e7731f14aac 345 */
mcm 1:6e7731f14aac 346 typedef enum {
mcm 1:6e7731f14aac 347 MODE2_OUTNE_MASK = ( 3 << 0 ), /*!< OUTNE bit mask */
mcm 1:6e7731f14aac 348 MODE2_OUTNE_LEDn_LOW = ( 0 << 0 ), /*!< When #OE = 1 (output drivers not enabled), LEDn = 0 ( default ) */
mcm 1:6e7731f14aac 349 MODE2_OUTNE_LEDn_HIGH = ( 1 << 0 ), /*!< When #OE = 1 (output drivers not enabled): LEDn = 1 when OUTDRV = 1
mcm 1:6e7731f14aac 350 LEDn = high-impedance when OUTDRV = 0 (same as OUTNE[1:0] = 10) */
mcm 1:6e7731f14aac 351 MODE2_OUTNE_LEDn_HIGH_IMPEDANCE = ( 2 << 0 ) /*!< When #OE = 1 (output drivers not enabled), LEDn = high-impedance */
mcm 1:6e7731f14aac 352 } PCA9685_mode2_outne_t;
mcm 1:6e7731f14aac 353
mcm 1:6e7731f14aac 354
mcm 1:6e7731f14aac 355
mcm 1:6e7731f14aac 356
mcm 1:6e7731f14aac 357 /**
mcm 1:6e7731f14aac 358 * @brief INTERNAL CONSTANTS
mcm 1:6e7731f14aac 359 */
mcm 1:6e7731f14aac 360 typedef enum {
mcm 1:6e7731f14aac 361 PCA9685_INTERNAL_CLOCK = 25000000, /*!< Internal clock frequency */
mcm 1:6e7731f14aac 362 PCA9685_ADC_STEPS = 4096 /*!< ADC 12-bits */
mcm 1:6e7731f14aac 363 } PCA9685_internal_parameters_t;
mcm 1:6e7731f14aac 364
mcm 1:6e7731f14aac 365
mcm 1:6e7731f14aac 366 typedef enum {
mcm 1:6e7731f14aac 367 PCA9685_LED0 = 0x00, /*!< LED0 channel */
mcm 1:6e7731f14aac 368 PCA9685_LED1 = 0x01, /*!< LED1 channel */
mcm 1:6e7731f14aac 369 PCA9685_LED2 = 0x02, /*!< LED2 channel */
mcm 1:6e7731f14aac 370 PCA9685_LED3 = 0x03, /*!< LED3 channel */
mcm 1:6e7731f14aac 371 PCA9685_LED4 = 0x04, /*!< LED4 channel */
mcm 1:6e7731f14aac 372 PCA9685_LED5 = 0x05, /*!< LED5 channel */
mcm 1:6e7731f14aac 373 PCA9685_LED6 = 0x06, /*!< LED6 channel */
mcm 1:6e7731f14aac 374 PCA9685_LED7 = 0x07, /*!< LED7 channel */
mcm 1:6e7731f14aac 375 PCA9685_LED8 = 0x08, /*!< LED8 channel */
mcm 1:6e7731f14aac 376 PCA9685_LED9 = 0x09, /*!< LED9 channel */
mcm 1:6e7731f14aac 377 PCA9685_LED10 = 0x0A, /*!< LED10 channel */
mcm 1:6e7731f14aac 378 PCA9685_LED11 = 0x0B, /*!< LED11 channel */
mcm 1:6e7731f14aac 379 PCA9685_LED12 = 0x0C, /*!< LED12 channel */
mcm 1:6e7731f14aac 380 PCA9685_LED13 = 0x0D, /*!< LED13 channel */
mcm 1:6e7731f14aac 381 PCA9685_LED14 = 0x0E, /*!< LED14 channel */
mcm 1:6e7731f14aac 382 PCA9685_LED15 = 0x0F /*!< LED15 channel */
mcm 1:6e7731f14aac 383 } PCA9685_led_channel_t;
mcm 1:6e7731f14aac 384
mcm 1:6e7731f14aac 385
mcm 1:6e7731f14aac 386
mcm 1:6e7731f14aac 387
mcm 1:6e7731f14aac 388
mcm 1:6e7731f14aac 389 /**
mcm 1:6e7731f14aac 390 * @brief INTERNAL CONSTANTS
mcm 1:6e7731f14aac 391 */
mcm 1:6e7731f14aac 392 typedef enum {
mcm 1:6e7731f14aac 393 PCA9685_SUCCESS = 0,
mcm 1:6e7731f14aac 394 PCA9685_FAILURE = 1,
mcm 1:6e7731f14aac 395 I2C_SUCCESS = 0 /*!< I2C communication was fine */
mcm 1:6e7731f14aac 396 } PCA9685_status_t;
mcm 1:6e7731f14aac 397
mcm 1:6e7731f14aac 398
mcm 2:fa75aff130cc 399 // MACRO: round function
mcm 2:fa75aff130cc 400 #define _MYROUND( x ) ({ \
mcm 2:fa75aff130cc 401 uint32_t aux_pre; \
mcm 2:fa75aff130cc 402 float aux_x; \
mcm 2:fa75aff130cc 403 \
mcm 2:fa75aff130cc 404 aux_x = (x); \
mcm 2:fa75aff130cc 405 aux_pre = (x); \
mcm 2:fa75aff130cc 406 aux_x -= aux_pre; \
mcm 2:fa75aff130cc 407 aux_x *= 10; \
mcm 2:fa75aff130cc 408 \
mcm 2:fa75aff130cc 409 if ( aux_x >= 5 ) \
mcm 2:fa75aff130cc 410 aux_pre++; \
mcm 2:fa75aff130cc 411 \
mcm 2:fa75aff130cc 412 aux_pre; \
mcm 2:fa75aff130cc 413 })
mcm 2:fa75aff130cc 414
mcm 2:fa75aff130cc 415
mcm 2:fa75aff130cc 416
mcm 1:6e7731f14aac 417
mcm 1:6e7731f14aac 418
mcm 1:6e7731f14aac 419 /** Create an PCA9685 object connected to the specified I2C pins.
mcm 1:6e7731f14aac 420 *
mcm 1:6e7731f14aac 421 * @param sda I2C data pin
mcm 1:6e7731f14aac 422 * @param scl I2C clock pin
mcm 1:6e7731f14aac 423 * @param addr I2C slave address
mcm 1:6e7731f14aac 424 * @param freq I2C frequency in Hz.
mcm 1:6e7731f14aac 425 */
mcm 1:6e7731f14aac 426 PCA9685 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq );
mcm 1:6e7731f14aac 427
mcm 1:6e7731f14aac 428 /** Delete PCA9685 object.
mcm 1:6e7731f14aac 429 */
mcm 1:6e7731f14aac 430 ~PCA9685();
mcm 1:6e7731f14aac 431
mcm 1:6e7731f14aac 432 /** It resets the device by software.
mcm 1:6e7731f14aac 433 */
mcm 1:6e7731f14aac 434 PCA9685_status_t PCA9685_SoftReset ( void );
mcm 1:6e7731f14aac 435
mcm 1:6e7731f14aac 436 /** It configures the mode of the device: Sleep or Normal operation mode.
mcm 1:6e7731f14aac 437 */
mcm 1:6e7731f14aac 438 PCA9685_status_t PCA9685_SetMode ( PCA9685_mode1_sleep_t myMode );
mcm 1:6e7731f14aac 439
mcm 1:6e7731f14aac 440 /** It configures a new PWM frequency.
mcm 1:6e7731f14aac 441 */
mcm 1:6e7731f14aac 442 PCA9685_status_t PCA9685_SetPWM_Freq ( float myNewFrequency );
mcm 1:6e7731f14aac 443
mcm 1:6e7731f14aac 444 /** It configures a new PWM duty cycle on a given LED.
mcm 1:6e7731f14aac 445 */
mcm 1:6e7731f14aac 446 PCA9685_status_t PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t myLEDchannel, uint8_t myDelay, uint8_t myPWM_DutyCycle );
mcm 1:6e7731f14aac 447
mcm 1:6e7731f14aac 448 /** It configures a new PWM duty cycle on all LEDs.
mcm 1:6e7731f14aac 449 */
mcm 1:6e7731f14aac 450 PCA9685_status_t PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t myDelay, uint8_t myPWM_DutyCycle );
mcm 1:6e7731f14aac 451
mcm 1:6e7731f14aac 452 /** It sets the LEDn ON.
mcm 1:6e7731f14aac 453 */
mcm 1:6e7731f14aac 454 PCA9685_status_t PCA9685_SetLED_ON ( PCA9685_led_channel_t myLEDchannel );
mcm 1:6e7731f14aac 455
mcm 1:6e7731f14aac 456 /** It sets the LEDn OFF.
mcm 1:6e7731f14aac 457 */
mcm 1:6e7731f14aac 458 PCA9685_status_t PCA9685_SetLED_OFF ( PCA9685_led_channel_t myLEDchannel );
mcm 1:6e7731f14aac 459
mcm 1:6e7731f14aac 460 /** It sets All LEDs ON.
mcm 1:6e7731f14aac 461 */
mcm 1:6e7731f14aac 462 PCA9685_status_t PCA9685_SetAllLED_ON ( void );
mcm 1:6e7731f14aac 463
mcm 1:6e7731f14aac 464 /** It sets All LEDs OFF.
mcm 1:6e7731f14aac 465 */
mcm 1:6e7731f14aac 466 PCA9685_status_t PCA9685_SetAllLED_OFF ( void );
mcm 1:6e7731f14aac 467
mcm 1:6e7731f14aac 468 /** It sets SUB1 mode.
mcm 1:6e7731f14aac 469 */
mcm 1:6e7731f14aac 470 PCA9685_status_t PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t mySUB1_mode );
mcm 1:6e7731f14aac 471
mcm 1:6e7731f14aac 472 /** It sets SUB2 mode.
mcm 1:6e7731f14aac 473 */
mcm 1:6e7731f14aac 474 PCA9685_status_t PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t mySUB2_mode );
mcm 1:6e7731f14aac 475
mcm 1:6e7731f14aac 476 /** It sets SUB3 mode.
mcm 1:6e7731f14aac 477 */
mcm 1:6e7731f14aac 478 PCA9685_status_t PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t mySUB3_mode );
mcm 1:6e7731f14aac 479
mcm 1:6e7731f14aac 480 /** It sets ALLCALL mode.
mcm 1:6e7731f14aac 481 */
mcm 1:6e7731f14aac 482 PCA9685_status_t PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t myALLCALL_mode );
mcm 1:6e7731f14aac 483
mcm 1:6e7731f14aac 484 /** It sets INVERT mode.
mcm 1:6e7731f14aac 485 */
mcm 1:6e7731f14aac 486 PCA9685_status_t PCA9685_SetINVERT ( PCA9685_mode2_invrt_t myINVERT_mode );
mcm 1:6e7731f14aac 487
mcm 1:6e7731f14aac 488 /** It sets OCH mode.
mcm 1:6e7731f14aac 489 */
mcm 1:6e7731f14aac 490 PCA9685_status_t PCA9685_SetOCH ( PCA9685_mode2_och_t myOCH_mode );
mcm 1:6e7731f14aac 491
mcm 1:6e7731f14aac 492 /** It sets OUTDRV mode.
mcm 1:6e7731f14aac 493 */
mcm 1:6e7731f14aac 494 PCA9685_status_t PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t myOUTDRV_mode );
mcm 1:6e7731f14aac 495
mcm 1:6e7731f14aac 496
mcm 1:6e7731f14aac 497
mcm 1:6e7731f14aac 498 private:
mcm 1:6e7731f14aac 499 I2C i2c;
mcm 1:6e7731f14aac 500 uint32_t PCA9685_Addr;
mcm 1:6e7731f14aac 501 };
mcm 1:6e7731f14aac 502
mcm 1:6e7731f14aac 503 #endif