summaryrefslogtreecommitdiff
path: root/peripheral/libupm/src/pca9685/pca9685.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'peripheral/libupm/src/pca9685/pca9685.hpp')
-rw-r--r--peripheral/libupm/src/pca9685/pca9685.hpp320
1 files changed, 320 insertions, 0 deletions
diff --git a/peripheral/libupm/src/pca9685/pca9685.hpp b/peripheral/libupm/src/pca9685/pca9685.hpp
new file mode 100644
index 0000000..d7b23cc
--- /dev/null
+++ b/peripheral/libupm/src/pca9685/pca9685.hpp
@@ -0,0 +1,320 @@
+/*
+ * Author: Jon Trulson <jtrulson@ics.com>
+ * Copyright (c) 2015 Intel Corporation.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include <string>
+#include <mraa/i2c.h>
+#include <mraa/gpio.h>
+
+#define PCA9685_I2C_BUS 0
+#define PCA9685_DEFAULT_I2C_ADDR 0x60
+// internal oscillator frequency
+#define PCA9685_INTERNAL_OSC 25000000.0
+
+// This is a 'special' LED number, used to refer to the ALL_LED registers
+// that affect all LED outputs at once.
+#define PCA9685_ALL_LED 0xff
+
+namespace upm {
+
+ /**
+ * @brief PCA9685 PWM Controller library
+ * @defgroup pca9685 libupm-pca9685
+ * @ingroup adafruit i2c led motor
+ */
+ /**
+ * @library pca9685
+ * @sensor pca9685
+ * @comname PCA9685 PWM Controller
+ * @type led motor
+ * @man adafruit
+ * @web http://www.adafruit.com/products/815
+ * @con i2c
+ *
+ * @brief API for the PCA9685 16-channel, 12-bit PWM LED Controller
+ *
+ * This controller is also used on the Adafruit* Motor Shield v2.3
+ * board to control up to 4 DC motors, 2 stepper motors, and 2 servo
+ * motors.
+ *
+ * This module was tested with the Adafruit Motor Shield v2.3
+ *
+ * @image html pca9685.jpg
+ * @snippet pca9685.cxx Interesting
+ */
+ class PCA9685 {
+ public:
+
+ /**
+ * PCA9685 registers
+ */
+ typedef enum { REG_MODE1 = 0x00,
+ REG_MODE2 = 0x01,
+ REG_I2C_SA1 = 0x02, // I2C subaddress 1
+ REG_I2C_SA2 = 0x03,
+ REG_I2C_SA3 = 0x04,
+ REG_ALLCALL = 0x05, // I2C all call address
+
+ // LED output PWM control
+ REG_LED0_ON_L = 0x06, // LED0 ON low byte
+ REG_LED0_ON_H = 0x07, // LED0 ON high byte
+ REG_LED0_OFF_L = 0x08, // LED0 OFF low byte
+ REG_LED0_OFF_H = 0x09, // LED0 OFF high byte
+ REG_LED1_ON_L = 0x0a,
+ REG_LED1_ON_H = 0x0b,
+ REG_LED1_OFF_L = 0x0c,
+ REG_LED1_OFF_H = 0x0d,
+ REG_LED2_ON_L = 0x0e,
+ REG_LED2_ON_H = 0x0f,
+ REG_LED2_OFF_L = 0x10,
+ REG_LED2_OFF_H = 0x11,
+ REG_LED3_ON_L = 0x12,
+ REG_LED3_ON_H = 0x13,
+ REG_LED3_OFF_L = 0x14,
+ REG_LED3_OFF_H = 0x15,
+ REG_LED4_ON_L = 0x16,
+ REG_LED4_ON_H = 0x17,
+ REG_LED4_OFF_L = 0x18,
+ REG_LED4_OFF_H = 0x19,
+ REG_LED5_ON_L = 0x1a,
+ REG_LED5_ON_H = 0x1b,
+ REG_LED5_OFF_L = 0x1c,
+ REG_LED5_OFF_H = 0x1d,
+ REG_LED6_ON_L = 0x1e,
+ REG_LED6_ON_H = 0x1f,
+ REG_LED6_OFF_L = 0x20,
+ REG_LED6_OFF_H = 0x21,
+ REG_LED7_ON_L = 0x22,
+ REG_LED7_ON_H = 0x23,
+ REG_LED7_OFF_L = 0x24,
+ REG_LED7_OFF_H = 0x25,
+ REG_LED8_ON_L = 0x26,
+ REG_LED8_ON_H = 0x27,
+ REG_LED8_OFF_L = 0x28,
+ REG_LED8_OFF_H = 0x29,
+ REG_LED9_ON_L = 0x2a,
+ REG_LED9_ON_H = 0x2b,
+ REG_LED9_OFF_L = 0x2c,
+ REG_LED9_OFF_H = 0x2d,
+ REG_LED10_ON_L = 0x2e,
+ REG_LED10_ON_H = 0x2f,
+ REG_LED10_OFF_L = 0x30,
+ REG_LED10_OFF_H = 0x31,
+ REG_LED11_ON_L = 0x32,
+ REG_LED11_ON_H = 0x33,
+ REG_LED11_OFF_L = 0x34,
+ REG_LED11_OFF_H = 0x35,
+ REG_LED12_ON_L = 0x36,
+ REG_LED12_ON_H = 0x37,
+ REG_LED12_OFF_L = 0x38,
+ REG_LED12_OFF_H = 0x39,
+ REG_LED13_ON_L = 0x3a,
+ REG_LED13_ON_H = 0x3b,
+ REG_LED13_OFF_L = 0x3c,
+ REG_LED13_OFF_H = 0x3d,
+ REG_LED14_ON_L = 0x3e,
+ REG_LED14_ON_H = 0x3f,
+ REG_LED14_OFF_L = 0x40,
+ REG_LED14_OFF_H = 0x41,
+ REG_LED15_ON_L = 0x42,
+ REG_LED15_ON_H = 0x43,
+ REG_LED15_OFF_L = 0x44,
+ REG_LED15_OFF_H = 0x45,
+ // 0x46-0xf9 reserved
+
+ REG_ALL_LED_ON_L = 0xfa, // write all LED ON L
+ REG_ALL_LED_ON_H = 0xfb, // write all LED ON H
+ REG_ALL_LED_OFF_L = 0xfc, // write all LED OFF L
+ REG_ALL_LED_OFF_H = 0xfd, // write all LED OFF H
+ REG_PRESCALE = 0xfe,
+ REG_TESTMODE = 0xff // don't use
+ } PCA9685_REG_T;
+
+ /**
+ * MODE1 bits
+ */
+ typedef enum { MODE1_ALL_CALL = 0x01, // all call status
+ MODE1_SUB3 = 0x02, // subcall 3 status
+ MODE1_SUB2 = 0x04, // subcall 2 status
+ MODE1_SUB1 = 0x08, // subcall 1 status
+ MODE1_SLEEP = 0x10, // sleep/normal mode
+ MODE1_AI = 0x20, // auto-increment enable
+ MODE1_EXTCLK = 0x40, // external clock enable
+ MODE1_RESTART = 0x80 // restart status
+ } PCA9685_MODE1_T;
+
+ /**
+ * MODE2 bits
+ */
+ typedef enum { MODE2_OUTNE0 = 0x01, // output driver enable bit 0
+ MODE2_OUTNE = 0x02, // output driver enable bit 1
+ MODE2_OUTDRV = 0x04, // output open-drain/totem pole
+ MODE2_OCH = 0x08, // output change on STOP or ACK
+ MODE2_INVRT = 0x10, // output logic state invert
+ MODE2_RESERVE0 = 0x20, // reserved
+ MODE2_RESERVE1 = 0x40, // reserved
+ MODE2_RESERVE2 = 0x80 // reserved
+ } PCA9685_MODE2_T;
+
+ /**
+ * PCA9685 constructor
+ *
+ * @param bus I2C bus to use
+ * @param address Address for this device
+ */
+ PCA9685(int bus, uint8_t address = PCA9685_DEFAULT_I2C_ADDR, bool raw = false);
+
+ /**
+ * PCA9685 destructor
+ */
+ ~PCA9685();
+
+ /**
+ * Writes a byte value into a register
+ *
+ * @param reg Register location to write into
+ * @param byte Byte to write
+ * @return True if successful
+ */
+ bool writeByte(uint8_t reg, uint8_t byte);
+
+ /**
+ * Writes a word value into a register. Note: the device must have the
+ * auto-increment bit set in the MODE1 register to work.
+ *
+ * @param reg Register location to write into
+ * @param word Word to write
+ * @return True if successful
+ */
+ bool writeWord(uint8_t reg, uint16_t word);
+
+ /**
+ * Reads a byte value from a register
+ *
+ * @param reg Register location to read from
+ * @return Value in a specified register
+ */
+ uint8_t readByte(uint8_t reg);
+
+ /**
+ * Reads a word value from a register. Note: the device must have the
+ * auto-increment bit set in the MODE1 register to work.
+ *
+ * @param reg Register location to read from
+ * @return Value in a specified register
+ */
+ uint16_t readWord(uint8_t reg);
+
+ /**
+ * Puts the device in or out of the sleep mode. The device is always
+ * in the sleep mode upon power-up.
+ *
+ * @param sleep True to put the device in the sleep mode, false to put out
+ * @return True if successful
+ */
+ bool setModeSleep(bool sleep);
+
+ /**
+ * Sets or clears the FULL ON bit for a given LED
+ *
+ * @param led LED number; valid values are 0-15, PCA9685_ALL_LED
+ * @param val True to set the bit, false to clear it
+ * @return True if successful
+ */
+ bool ledFullOn(uint8_t led, bool val);
+
+ /**
+ * Sets or clears the FULL OFF bit for a given LED. If the FULL ON
+ * bit is also set, FULL OFF has precedence.
+ *
+ * @param led LED number; valid values are 0-15, PCA9685_ALL_LED
+ * @param val True to set the bit, false to clear it
+ * @return True if successful
+ */
+ bool ledFullOff(uint8_t led, bool val);
+
+ /**
+ * Sets the 'LED on' time (0-4,095). See the PCA9685 datasheet for details.
+ *
+ * @param led LED number; valid values are 0-15, PCA9685_ALL_LED
+ * @param time 12-bit value at which point the LED turns on
+ * @return True if successful
+ */
+ bool ledOnTime(uint8_t led, uint16_t time);
+
+ /**
+ * Sets the 'LED off' time (0-4,095). See the PCA9685 datasheet for details.
+ *
+ * @param led LED number; valid values are 0-15, PCA9685_ALL_LED
+ * @param time 12-bit value at which point the LED turns off
+ * @return True if successful
+ */
+ bool ledOffTime(uint8_t led, uint16_t time);
+
+ /**
+ * Sets the prescale value. See the PCA9685 datasheet for
+ * details. The prescale can only be set when the device is in
+ * the sleep mode.
+ *
+ * @param prescale Prescale value
+ * @return True if successful
+ */
+ bool setPrescale(uint8_t prescale);
+
+ /**
+ * Sets the prescale value based on a desired frequency in Hz. The
+ * prescale can only be set when the device is in the sleep mode.
+ *
+ * @param hz Desired frequency in Hz
+ * @param oscFreq Oscillator frequency; default is 25 MHz
+ * @return True if successful
+ */
+ bool setPrescaleFromHz(float hz,
+ float oscFreq=PCA9685_INTERNAL_OSC);
+
+ /**
+ * Enables or disables the restart capability of the controller
+ *
+ * @param enabled True to enable, false to disable
+ * It is enabled by default.
+ */
+ void enableRestart(bool enabled) { m_restartEnabled = enabled; };
+
+ private:
+ /**
+ * Enables the I2C register auto-increment. This needs to be enabled
+ * for write/readWord() to work. The contructor enables this by
+ * default.
+ *
+ * @param ai True to enable, false otherwise
+ */
+ bool enableAutoIncrement(bool ai);
+
+ bool m_restartEnabled;
+ mraa_i2c_context m_i2c;
+ uint8_t m_addr;
+ };
+}
+
+