Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: PCA9685.h
- Revision:
- 1:6e7731f14aac
- Parent:
- 0:1527da6e7c05
- Child:
- 2:fa75aff130cc
diff -r 1527da6e7c05 -r 6e7731f14aac PCA9685.h
--- a/PCA9685.h Tue Nov 07 14:17:54 2017 +0000
+++ b/PCA9685.h Tue Nov 07 14:28:19 2017 +0000
@@ -0,0 +1,421 @@
+/**
+ * @brief PCA9685.h
+ * @details 16-channel, 12-bit PWM Fm+ I2C-bus LED controller.
+ * Header file.
+ *
+ *
+ * @return NA
+ *
+ * @author Manuel Caballero
+ * @date 31/October/2017
+ * @version 31/October/2017 The ORIGIN
+ * @pre NaN.
+ * @warning NaN
+ * @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
+ */
+#ifndef PCA9685_H
+#define PCA9685_H
+
+#include "mbed.h"
+
+
+/**
+ Example:
+
+[todo]
+*/
+
+
+/*!
+ Library for the PCA9685 16-channel, 12-bit PWM Fm+ I2C-bus LED controller.
+*/
+class PCA9685
+{
+public:
+ /**
+ * @brief DEFAULT ADDRESSES. NOTE: There are a maximum of 64 possible programmable addresses using the 6 hardware
+ * address pins. Two of these addresses, Software Reset and LED All Call, cannot be used
+ * because their default power-up state is ON, leaving a maximum of 62 addresses. Using
+ * other reserved addresses, as well as any other subcall address, will reduce the total
+ * number of possible addresses even further.
+ *
+ * To access to a certain address just use the following method: PCA9685_ADDRESS_0 + Counter_Address
+ * Ex:
+ * PCA9685_ADDRESS_0 + 1 = 0x40 + 1 = 0x41 ( 0b1000001 )
+ * PCA9685_ADDRESS_0 + 10 = 0x40 + 10 = 0x4A ( 0b1001010 )
+ * and so on...
+ */
+ typedef enum {
+ PCA9685_ADDRESS_0 = ( 0x40 << 1 ) /*!< A5 A4 A3 A2 A1 A0: 000 000 */
+ } PCA9685_address_t;
+
+
+// REGISTERS
+ /**
+ * @brief REGISTER DEFINITIONS
+ */
+ typedef enum {
+ MODE1 = 0x00, /*!< Mode register 1 */
+ MODE2 = 0x01, /*!< Mode register 2 */
+ SUBADR1 = 0x02, /*!< I2C-bus subaddress 1 */
+ SUBADR2 = 0x03, /*!< I2C-bus subaddress 2 */
+ SUBADR3 = 0x04, /*!< I2C-bus subaddress 3 */
+ ALLCALLADR = 0x05, /*!< LED All Call I2C-bus address */
+ LED0_ON_L = 0x06, /*!< LED0 output and brightness control byte 0 */
+ LED0_ON_H = 0x07, /*!< LED0 output and brightness control byte 1 */
+ LED0_OFF_L = 0x08, /*!< LED0 output and brightness control byte 2 */
+ LED0_OFF_H = 0x09, /*!< LED0 output and brightness control byte 3 */
+ LED1_ON_L = 0x0A, /*!< LED1 output and brightness control byte 0 */
+ LED1_ON_H = 0x0B, /*!< LED1 output and brightness control byte 1 */
+ LED1_OFF_L = 0x0C, /*!< LED1 output and brightness control byte 2 */
+ LED1_OFF_H = 0x0D, /*!< LED1 output and brightness control byte 3 */
+ LED2_ON_L = 0x0E, /*!< LED2 output and brightness control byte 0 */
+ LED2_ON_H = 0x0F, /*!< LED2 output and brightness control byte 1 */
+ LED2_OFF_L = 0x10, /*!< LED2 output and brightness control byte 2 */
+ LED2_OFF_H = 0x11, /*!< LED2 output and brightness control byte 3 */
+ LED3_ON_L = 0x12, /*!< LED3 output and brightness control byte 0 */
+ LED3_ON_H = 0x13, /*!< LED3 output and brightness control byte 1 */
+ LED3_OFF_L = 0x14, /*!< LED3 output and brightness control byte 2 */
+ LED3_OFF_H = 0x15, /*!< LED3 output and brightness control byte 3 */
+ LED4_ON_L = 0x16, /*!< LED4 output and brightness control byte 0 */
+ LED4_ON_H = 0x17, /*!< LED4 output and brightness control byte 1 */
+ LED4_OFF_L = 0x18, /*!< LED4 output and brightness control byte 2 */
+ LED4_OFF_H = 0x19, /*!< LED4 output and brightness control byte 3 */
+ LED5_ON_L = 0x1A, /*!< LED5 output and brightness control byte 0 */
+ LED5_ON_H = 0x1B, /*!< LED5 output and brightness control byte 1 */
+ LED5_OFF_L = 0x1C, /*!< LED5 output and brightness control byte 2 */
+ LED5_OFF_H = 0x1D, /*!< LED5 output and brightness control byte 3 */
+ LED6_ON_L = 0x1E, /*!< LED6 output and brightness control byte 0 */
+ LED6_ON_H = 0x1F, /*!< LED6 output and brightness control byte 1 */
+ LED6_OFF_L = 0x20, /*!< LED6 output and brightness control byte 2 */
+ LED6_OFF_H = 0x21, /*!< LED6 output and brightness control byte 3 */
+ LED7_ON_L = 0x22, /*!< LED7 output and brightness control byte 0 */
+ LED7_ON_H = 0x23, /*!< LED7 output and brightness control byte 1 */
+ LED7_OFF_L = 0x24, /*!< LED7 output and brightness control byte 2 */
+ LED7_OFF_H = 0x25, /*!< LED7 output and brightness control byte 3 */
+ LED8_ON_L = 0x26, /*!< LED8 output and brightness control byte 0 */
+ LED8_ON_H = 0x27, /*!< LED8 output and brightness control byte 1 */
+ LED8_OFF_L = 0x28, /*!< LED8 output and brightness control byte 2 */
+ LED8_OFF_H = 0x29, /*!< LED8 output and brightness control byte 3 */
+ LED9_ON_L = 0x2A, /*!< LED9 output and brightness control byte 0 */
+ LED9_ON_H = 0x2B, /*!< LED9 output and brightness control byte 1 */
+ LED9_OFF_L = 0x2C, /*!< LED9 output and brightness control byte 2 */
+ LED9_OFF_H = 0x2D, /*!< LED9 output and brightness control byte 3 */
+ LED10_ON_L = 0x2E, /*!< LED10 output and brightness control byte 0 */
+ LED10_ON_H = 0x2F, /*!< LED10 output and brightness control byte 1 */
+ LED10_OFF_L = 0x30, /*!< LED10 output and brightness control byte 2 */
+ LED10_OFF_H = 0x31, /*!< LED10 output and brightness control byte 3 */
+ LED11_ON_L = 0x32, /*!< LED11 output and brightness control byte 0 */
+ LED11_ON_H = 0x33, /*!< LED11 output and brightness control byte 1 */
+ LED11_OFF_L = 0x34, /*!< LED11 output and brightness control byte 2 */
+ LED11_OFF_H = 0x35, /*!< LED11 output and brightness control byte 3 */
+ LED12_ON_L = 0x36, /*!< LED12 output and brightness control byte 0 */
+ LED12_ON_H = 0x37, /*!< LED12 output and brightness control byte 1 */
+ LED12_OFF_L = 0x38, /*!< LED12 output and brightness control byte 2 */
+ LED12_OFF_H = 0x39, /*!< LED12 output and brightness control byte 3 */
+ LED13_ON_L = 0x3A, /*!< LED13 output and brightness control byte 0 */
+ LED13_ON_H = 0x3B, /*!< LED13 output and brightness control byte 1 */
+ LED13_OFF_L = 0x3C, /*!< LED13 output and brightness control byte 2 */
+ LED13_OFF_H = 0x3D, /*!< LED13 output and brightness control byte 3 */
+ LED14_ON_L = 0x3E, /*!< LED14 output and brightness control byte 0 */
+ LED14_ON_H = 0x3F, /*!< LED14 output and brightness control byte 1 */
+ LED14_OFF_L = 0x40, /*!< LED14 output and brightness control byte 2 */
+ LED14_OFF_H = 0x41, /*!< LED14 output and brightness control byte 3 */
+ LED15_ON_L = 0x42, /*!< LED15 output and brightness control byte 0 */
+ LED15_ON_H = 0x43, /*!< LED15 output and brightness control byte 1 */
+ LED15_OFF_L = 0x44, /*!< LED15 output and brightness control byte 2 */
+ LED15_OFF_H = 0x45, /*!< LED15 output and brightness control byte 3 */
+ ALL_LED_ON_L = 0xFA, /*!< load all the LEDn_ON registers, byte 0 */
+ ALL_LED_ON_H = 0xFB, /*!< load all the LEDn_ON registers, byte 1 */
+ ALL_LED_OFF_L = 0xFC, /*!< load all the LEDn_OFF registers, byte 0 */
+ ALL_LED_OFF_H = 0xFD, /*!< load all the LEDn_OFF registers, byte 1 */
+ PRE_SCALE = 0xFE, /*!< prescaler for PWM output frequency */
+ TESTMODE = 0xFF /*!< defines the test mode to be entered */
+ } PCA9685_registers_t;
+
+
+
+// LED Sub Call I2C-bus addresses
+ /**
+ * @brief SUBADDRESS. NOTE: At power-up, Sub Call I2C-bus addresses are disabled. PCA9685 does not send an
+ * ACK when E2h (R/W = 0) or E3h (R/W = 1), E4h (R/W = 0) or E5h (R/W = 1), or
+ * E8h (R/W = 0) or E9h (R/W = 1) is sent by the master.
+ */
+ typedef enum {
+ SUBADR1_REG = ( 0xE2 << 1 ), /*!< Subaddress 1 */
+ SUBADR2_REG = ( 0xE4 << 1 ), /*!< Subaddress 2 */
+ SUBADR3_REG = ( 0xE8 << 1 ) /*!< Subaddress 3 */
+ } PCA9685_subaddresses_t;
+
+
+
+
+// Software Reset I2C-bus address
+ /**
+ * @brief SWRST. NOTE: The Software Reset address (SWRST Call) must be used with
+ * R/#W = logic 0. If R/#W = logic 1, the PCA9685 does not acknowledge the SWRST.
+ */
+ typedef enum {
+ GENERAL_CALL_ADDRESS = ( 0x00 << 1 ), /*!< Software reset */
+ SWRST = ( 0x06 << 1 ) /*!< Software reset */
+ } PCA9685_software_reset_t;
+
+
+
+
+// MODE REGISTER 1, MODE1
+ /**
+ * @brief RESTART
+ */
+ typedef enum {
+ MODE1_RESTART_MASK = ( 1 << 7 ), /*!< RESTART bit mask */
+ MODE1_RESTART_ENABLED = ( 1 << 7 ), /*!< Restart enabled */
+ MODE1_RESTART_DISABLED = ( 0 << 7 ) /*!< Restart disabled ( default ) */
+ } PCA9685_mode1_restart_t;
+
+
+ /**
+ * @brief EXTCLK
+ */
+ typedef enum {
+ MODE1_EXTCLK_MASK = ( 1 << 6 ), /*!< EXTCLK bit mask */
+ MODE1_EXTCLK_ENABLED = ( 1 << 6 ), /*!< Use EXTERNAL clock */
+ MODE1_EXTCLK_DISABLED = ( 0 << 6 ) /*!< Use INTERNAL clock ( default ) */
+ } PCA9685_mode1_extclk_t;
+
+
+ /**
+ * @brief AI
+ */
+ typedef enum {
+ MODE1_AI_MASK = ( 1 << 5 ), /*!< AI bit mask */
+ MODE1_AI_ENABLED = ( 1 << 5 ), /*!< Auto-Increment enabled */
+ MODE1_AI_DISABLED = ( 0 << 5 ) /*!< Auto-Increment disabled ( default ) */
+ } PCA9685_mode1_ai_t;
+
+
+ /**
+ * @brief SLEEP
+ */
+ typedef enum {
+ MODE1_SLEEP_MASK = ( 1 << 4 ), /*!< SLEEP bit mask */
+ MODE1_SLEEP_ENABLED = ( 1 << 4 ), /*!< Low power mode. Oscillator off ( default ) */
+ MODE1_SLEEP_DISABLED = ( 0 << 4 ) /*!< Normal mode */
+ } PCA9685_mode1_sleep_t;
+
+
+ /**
+ * @brief SUB1
+ */
+ typedef enum {
+ MODE1_SUB1_MASK = ( 1 << 3 ), /*!< SUB1 bit mask */
+ MODE1_SUB1_ENABLED = ( 1 << 3 ), /*!< PCA9685 responds to I2C-bus subaddress 1 */
+ MODE1_SUB1_DISABLED = ( 0 << 3 ) /*!< PCA9685 does not respond to I2C-bus subaddress 1 ( default ) */
+ } PCA9685_mode1_sub1_t;
+
+
+ /**
+ * @brief SUB2
+ */
+ typedef enum {
+ MODE1_SUB2_MASK = ( 1 << 2 ), /*!< SUB2 bit mask */
+ MODE1_SUB2_ENABLED = ( 1 << 2 ), /*!< PCA9685 responds to I2C-bus subaddress 2 */
+ MODE1_SUB2_DISABLED = ( 0 << 2 ) /*!< PCA9685 does not respond to I2C-bus subaddress 2 ( default ) */
+ } PCA9685_mode1_sub2_t;
+
+
+ /**
+ * @brief SUB3
+ */
+ typedef enum {
+ MODE1_SUB3_MASK = ( 1 << 1 ), /*!< SUB1 bit mask */
+ MODE1_SUB3_ENABLED = ( 1 << 1 ), /*!< PCA9685 responds to I2C-bus subaddress 3 */
+ MODE1_SUB3_DISABLED = ( 0 << 1 ) /*!< PCA9685 does not respond to I2C-bus subaddress 3 ( default ) */
+ } PCA9685_mode1_sub3_t;
+
+
+ /**
+ * @brief ALLCALL
+ */
+ typedef enum {
+ MODE1_ALLCALL_MASK = ( 1 << 0 ), /*!< ALLCALL bit mask */
+ MODE1_ALLCALL_ENABLED = ( 1 << 0 ), /*!< PCA9685 responds to LED All Call I2C-bus address ( default ) */
+ MODE1_ALLCALL_DISABLED = ( 0 << 0 ) /*!< PCA9685 does not respond to LED All Call I2C-bus address */
+ } PCA9685_mode1_allcall_t;
+
+
+
+// MODE REGISTER 2, MODE2
+ /**
+ * @brief INVRT
+ */
+ typedef enum {
+ MODE2_INVRT_MASK = ( 1 << 4 ), /*!< INVRT bit mask */
+ MODE2_INVRT_ENABLED = ( 1 << 4 ), /*!< Output logic state inverted. Value to use when no external driver used. Applicable when OE = 0 */
+ MODE2_INVRT_DISABLED = ( 0 << 4 ) /*!< Output logic state not inverted. Value to use when external driver used. Applicable when OE = 0. ( default ) */
+ } PCA9685_mode2_invrt_t;
+
+
+ /**
+ * @brief OCH
+ */
+ typedef enum {
+ MODE2_OCH_MASK = ( 1 << 3 ), /*!< ALLCALL bit mask */
+ MODE2_OCH_OUTPUT_CHANGE_STOP_CMD = ( 0 << 3 ), /*!< Outputs change on STOP command ( default ) */
+ MODE2_OCH_OUTPUT_CHANGE_ACK_CMD = ( 1 << 3 ) /*!< Outputs change on ACK */
+ } PCA9685_mode2_och_t;
+
+
+ /**
+ * @brief OUTDRV
+ */
+ typedef enum {
+ MODE2_OUTDRV_MASK = ( 1 << 2 ), /*!< OUTDRV bit mask */
+ MODE2_OUTDRV_TOTEM_POLE_STRUCTURE = ( 1 << 2 ), /*!< The 16 LEDn outputs are configured with a totem pole structure ( default ) */
+ MODE2_OUTDRV_OPEN_DRAIN_STRUCTURE = ( 0 << 2 ) /*!< The 16 LEDn outputs are configured with an open-drain structure */
+ } PCA9685_mode2_outdrv_t;
+
+
+ /**
+ * @brief OUTNE
+ */
+ typedef enum {
+ MODE2_OUTNE_MASK = ( 3 << 0 ), /*!< OUTNE bit mask */
+ MODE2_OUTNE_LEDn_LOW = ( 0 << 0 ), /*!< When #OE = 1 (output drivers not enabled), LEDn = 0 ( default ) */
+ MODE2_OUTNE_LEDn_HIGH = ( 1 << 0 ), /*!< When #OE = 1 (output drivers not enabled): LEDn = 1 when OUTDRV = 1
+ LEDn = high-impedance when OUTDRV = 0 (same as OUTNE[1:0] = 10) */
+ MODE2_OUTNE_LEDn_HIGH_IMPEDANCE = ( 2 << 0 ) /*!< When #OE = 1 (output drivers not enabled), LEDn = high-impedance */
+ } PCA9685_mode2_outne_t;
+
+
+
+
+ /**
+ * @brief INTERNAL CONSTANTS
+ */
+ typedef enum {
+ PCA9685_INTERNAL_CLOCK = 25000000, /*!< Internal clock frequency */
+ PCA9685_ADC_STEPS = 4096 /*!< ADC 12-bits */
+ } PCA9685_internal_parameters_t;
+
+
+ typedef enum {
+ PCA9685_LED0 = 0x00, /*!< LED0 channel */
+ PCA9685_LED1 = 0x01, /*!< LED1 channel */
+ PCA9685_LED2 = 0x02, /*!< LED2 channel */
+ PCA9685_LED3 = 0x03, /*!< LED3 channel */
+ PCA9685_LED4 = 0x04, /*!< LED4 channel */
+ PCA9685_LED5 = 0x05, /*!< LED5 channel */
+ PCA9685_LED6 = 0x06, /*!< LED6 channel */
+ PCA9685_LED7 = 0x07, /*!< LED7 channel */
+ PCA9685_LED8 = 0x08, /*!< LED8 channel */
+ PCA9685_LED9 = 0x09, /*!< LED9 channel */
+ PCA9685_LED10 = 0x0A, /*!< LED10 channel */
+ PCA9685_LED11 = 0x0B, /*!< LED11 channel */
+ PCA9685_LED12 = 0x0C, /*!< LED12 channel */
+ PCA9685_LED13 = 0x0D, /*!< LED13 channel */
+ PCA9685_LED14 = 0x0E, /*!< LED14 channel */
+ PCA9685_LED15 = 0x0F /*!< LED15 channel */
+ } PCA9685_led_channel_t;
+
+
+
+
+
+ /**
+ * @brief INTERNAL CONSTANTS
+ */
+ typedef enum {
+ PCA9685_SUCCESS = 0,
+ PCA9685_FAILURE = 1,
+ I2C_SUCCESS = 0 /*!< I2C communication was fine */
+ } PCA9685_status_t;
+
+
+
+
+ /** Create an PCA9685 object connected to the specified I2C pins.
+ *
+ * @param sda I2C data pin
+ * @param scl I2C clock pin
+ * @param addr I2C slave address
+ * @param freq I2C frequency in Hz.
+ */
+ PCA9685 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq );
+
+ /** Delete PCA9685 object.
+ */
+ ~PCA9685();
+
+ /** It resets the device by software.
+ */
+ PCA9685_status_t PCA9685_SoftReset ( void );
+
+ /** It configures the mode of the device: Sleep or Normal operation mode.
+ */
+ PCA9685_status_t PCA9685_SetMode ( PCA9685_mode1_sleep_t myMode );
+
+ /** It configures a new PWM frequency.
+ */
+ PCA9685_status_t PCA9685_SetPWM_Freq ( float myNewFrequency );
+
+ /** It configures a new PWM duty cycle on a given LED.
+ */
+ PCA9685_status_t PCA9685_SetPWM_DutyCycle ( PCA9685_led_channel_t myLEDchannel, uint8_t myDelay, uint8_t myPWM_DutyCycle );
+
+ /** It configures a new PWM duty cycle on all LEDs.
+ */
+ PCA9685_status_t PCA9685_SetPWM_DutyCycle_AllLEDs ( uint8_t myDelay, uint8_t myPWM_DutyCycle );
+
+ /** It sets the LEDn ON.
+ */
+ PCA9685_status_t PCA9685_SetLED_ON ( PCA9685_led_channel_t myLEDchannel );
+
+ /** It sets the LEDn OFF.
+ */
+ PCA9685_status_t PCA9685_SetLED_OFF ( PCA9685_led_channel_t myLEDchannel );
+
+ /** It sets All LEDs ON.
+ */
+ PCA9685_status_t PCA9685_SetAllLED_ON ( void );
+
+ /** It sets All LEDs OFF.
+ */
+ PCA9685_status_t PCA9685_SetAllLED_OFF ( void );
+
+ /** It sets SUB1 mode.
+ */
+ PCA9685_status_t PCA9685_SetSUB1 ( PCA9685_mode1_sub1_t mySUB1_mode );
+
+ /** It sets SUB2 mode.
+ */
+ PCA9685_status_t PCA9685_SetSUB2 ( PCA9685_mode1_sub2_t mySUB2_mode );
+
+ /** It sets SUB3 mode.
+ */
+ PCA9685_status_t PCA9685_SetSUB3 ( PCA9685_mode1_sub3_t mySUB3_mode );
+
+ /** It sets ALLCALL mode.
+ */
+ PCA9685_status_t PCA9685_SetALLCALL ( PCA9685_mode1_allcall_t myALLCALL_mode );
+
+ /** It sets INVERT mode.
+ */
+ PCA9685_status_t PCA9685_SetINVERT ( PCA9685_mode2_invrt_t myINVERT_mode );
+
+ /** It sets OCH mode.
+ */
+ PCA9685_status_t PCA9685_SetOCH ( PCA9685_mode2_och_t myOCH_mode );
+
+ /** It sets OUTDRV mode.
+ */
+ PCA9685_status_t PCA9685_SetOUTDRV ( PCA9685_mode2_outdrv_t myOUTDRV_mode );
+
+
+
+private:
+ I2C i2c;
+ uint32_t PCA9685_Addr;
+};
+
+#endif