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.
Dependents: PCA9955_HelloWorld
PCA9955.h
- Committer:
- neilt6
- Date:
- 2013-11-07
- Revision:
- 1:016f916c5579
- Parent:
- 0:7b3cbb5a53b8
- Child:
- 2:9d866639b32b
File content as of revision 1:016f916c5579:
/* PCA9952/55 Driver Library
* Copyright (c) 2013 Neil Thiessen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef PCA9955_H
#define PCA9955_H
#include "mbed.h"
/** PCA9952/55 class.
* Used for controlling a PCA9952/55 constant current LED driver connected via I2C.
*
* Example:
* @code
* #include "mbed.h"
* #include "PCA9955.h"
*
* //Create an PCA9955 object at the default address (ADDRESS_0)
* PCA9955 driver(p28, p27);
*
* int main()
* {
* //Try to open the PCA9955
* if (driver.open()) {
* printf("Device detected!\n");
*
* //Reset the device
* //NOTE: This might reset other I2C devices as well!
* driver.reset();
*
* //Set all the output states to PWM mode
* driver.allOutputStates(PCA9955::OUTPUT_PWM);
*
* //Set the all of the output currents to maximum
* driver.allOutputCurrents(1.0);
*
* while (1) {
* //Generate a breathing effect on all of the outputs
* for (float i = 0.0f; i < 360.0f; i += 0.1f) {
* driver.allOutputDuties(0.5 * (sinf(i * 3.14159265f / 180.0f) + 1));
* }
* }
* } else {
* error("Device not detected!\n");
* }
* }
* @endcode
*/
class PCA9955
{
public:
/** Represents the different I2C address possibilities for the PCA9952/55
*/
enum Address {
ADDRESS_0 = (0x60 << 1), /**< A[3:0] pins = 0000 */
ADDRESS_1 = (0x61 << 1), /**< A[3:0] pins = 0001 */
ADDRESS_2 = (0x62 << 1), /**< A[3:0] pins = 0010 */
ADDRESS_3 = (0x63 << 1), /**< A[3:0] pins = 0011 */
ADDRESS_4 = (0x64 << 1), /**< A[3:0] pins = 0100 */
ADDRESS_5 = (0x65 << 1), /**< A[3:0] pins = 0101 */
ADDRESS_6 = (0x66 << 1), /**< A[3:0] pins = 0110 */
ADDRESS_7 = (0x67 << 1), /**< A[3:0] pins = 0111 */
ADDRESS_8 = (0x68 << 1), /**< A[3:0] pins = 1000 (not available on PCA9952) */
ADDRESS_9 = (0x69 << 1), /**< A[3:0] pins = 1001 (not available on PCA9952) */
ADDRESS_10 = (0x6A << 1), /**< A[3:0] pins = 1010 (not available on PCA9952) */
ADDRESS_11 = (0x6B << 1), /**< A[3:0] pins = 1011 (not available on PCA9952) */
ADDRESS_12 = (0x6C << 1), /**< A[3:0] pins = 1100 (not available on PCA9952) */
ADDRESS_13 = (0x6D << 1), /**< A[3:0] pins = 1101 (not available on PCA9952) */
ADDRESS_14 = (0x6E << 1), /**< A[3:0] pins = 1110 (not available on PCA9952) */
ADDRESS_15 = (0x6F << 1) /**< A[3:0] pins = 1111 (not available on PCA9952) */
};
/** Represents the different outputs of the PCA9952/55
*/
enum Output {
OUTPUT_0 = 0, /**< LED output 0 */
OUTPUT_1 = 1, /**< LED output 1 */
OUTPUT_2 = 2, /**< LED output 2 */
OUTPUT_3 = 3, /**< LED output 3 */
OUTPUT_4 = 4, /**< LED output 4 */
OUTPUT_5 = 5, /**< LED output 5 */
OUTPUT_6 = 6, /**< LED output 6 */
OUTPUT_7 = 7, /**< LED output 7 */
OUTPUT_8 = 8, /**< LED output 8 */
OUTPUT_9 = 9, /**< LED output 9 */
OUTPUT_10 = 10, /**< LED output 10 */
OUTPUT_11 = 11, /**< LED output 11 */
OUTPUT_12 = 12, /**< LED output 12 */
OUTPUT_13 = 13, /**< LED output 13 */
OUTPUT_14 = 14, /**< LED output 14 */
OUTPUT_15 = 15 /**< LED output 15 */
};
/** Represents the power mode of the PCA9952/55
*/
enum PowerMode {
POWER_NORMAL, /**< Oscillator is enabled */
POWER_SHUTDOWN /**< Oscillator is disabled */
};
/** Represents the output change mode of the PCA9952/55
*/
enum OutputChangeMode {
OUTPUT_CHANGE_ON_STOP, /**< Outputs change on STOP command */
OUTPUT_CHANGE_ON_ACK /**< Outputs change on ACK */
};
/** Represents the group control mode of the PCA9952/55
*/
enum GroupMode {
GROUP_DIMMING, /**< Group control = dimming */
GROUP_BLINKING /**< group control = blinking */
};
/** Represents the individual driver output states of the PCA9952/55
*/
enum OutputState {
OUTPUT_OFF, /**< LED driver x is off (default power-up state) */
OUTPUT_ON, /**< LED driver x is fully on (individual brightness and group dimming/blinking not controlled) */
OUTPUT_PWM, /**< LED driver x individual brightness can be controlled through its PWMx register */
OUTPUT_PWM_GRPPWM /**< LED driver x individual brightness and group dimming/blinking can be controlled through its PWMx register and the GRPPWM registers */
};
/** Represents the fault test flags for the PCA9952/55
*/
enum FaultFlags {
FAULT_OUTPUT_0 = (1 << 0), /**< LED output 0 is either open or shorted */
FAULT_OUTPUT_1 = (1 << 1), /**< LED output 1 is either open or shorted */
FAULT_OUTPUT_2 = (1 << 2), /**< LED output 2 is either open or shorted */
FAULT_OUTPUT_3 = (1 << 3), /**< LED output 3 is either open or shorted */
FAULT_OUTPUT_4 = (1 << 4), /**< LED output 4 is either open or shorted */
FAULT_OUTPUT_5 = (1 << 5), /**< LED output 5 is either open or shorted */
FAULT_OUTPUT_6 = (1 << 6), /**< LED output 6 is either open or shorted */
FAULT_OUTPUT_7 = (1 << 7), /**< LED output 7 is either open or shorted */
FAULT_OUTPUT_8 = (1 << 8), /**< LED output 8 is either open or shorted */
FAULT_OUTPUT_9 = (1 << 9), /**< LED output 9 is either open or shorted */
FAULT_OUTPUT_10 = (1 << 10), /**< LED output 10 is either open or shorted */
FAULT_OUTPUT_11 = (1 << 11), /**< LED output 11 is either open or shorted */
FAULT_OUTPUT_12 = (1 << 12), /**< LED output 12 is either open or shorted */
FAULT_OUTPUT_13 = (1 << 13), /**< LED output 13 is either open or shorted */
FAULT_OUTPUT_14 = (1 << 14), /**< LED output 14 is either open or shorted */
FAULT_OUTPUT_15 = (1 << 15) /**< LED output 15 is either open or shorted */
};
/** Create a PCA9952/55 object connected to the specified I2C pins with the specified I2C slave address
*
* @param sda The I2C data pin.
* @param scl The I2C clock pin.
* @param addr The I2C slave address (defaults to ADDRESS_0).
*/
PCA9955(PinName sda, PinName scl, Address addr = ADDRESS_0);
/** Probe for the PCA9952/55 and configure Auto-Increment if present
*
* @returns
* 'true' if the device exists on the bus,
* 'false' if the device doesn't exist on the bus.
*/
bool open();
/** Issue an SWRST call to reset the PCA9952/55
* @warning This might reset other I2C devices as well!
*/
void reset();
/** Determine whether the LED All Call address is enabled on the PCA9952/55
*
* @returns Whether or not the LED All Call address is enabled.
*/
bool allCallEnabled();
/** Set whether the LED All Call address is enabled on the PCA9952/55
*
* @param enabled Whether or not the LED All Call address is enabled.
*/
void allCallEnabled(bool enabled);
/** Determine whether subaddress 3 is enabled on the PCA9952/55
*
* @returns Whether or not subaddress 3 is enabled.
*/
bool subCall3Enabled();
/** Set whether subaddress 3 is enabled on the PCA9952/55
*
* @param enabled Whether or not subaddress 3 is enabled.
*/
void subCall3Enabled(bool enabled);
/** Determine whether subaddress 2 is enabled on the PCA9952/55
*
* @returns Whether or not subaddress 2 is enabled.
*/
bool subCall2Enabled();
/** Set whether subaddress 2 is enabled on the PCA9952/55
*
* @param enabled Whether or not subaddress 2 is enabled.
*/
void subCall2Enabled(bool enabled);
/** Determine whether subaddress 1 is enabled on the PCA9952/55
*
* @returns Whether or not subaddress 1 is enabled.
*/
bool subCall1Enabled();
/** Set whether subaddress 1 is enabled on the PCA9952/55
*
* @param enabled Whether or not subaddress 1 is enabled.
*/
void subCall1Enabled(bool enabled);
/** Get the current power mode of the PCA9952/55
*
* @returns The current power mode as a PowerMode enum.
*/
PCA9955::PowerMode powerMode();
/** Set the power mode of the PCA9952/55
*
* @param mode The new power mode as a PowerMode enum.
*/
void powerMode(PowerMode mode);
/** Get the current output change mode of the PCA9952/55
*
* @returns The current output change mode as an OutputChangeMode enum.
*/
PCA9955::OutputChangeMode outputChangeMode();
/** Set the output change mode of the PCA9952/55
*
* @param mode The new output change mode as an OutputChangeMode enum.
*/
void outputChangeMode(OutputChangeMode mode);
/** Get the current group control mode of the PCA9952/55
*
* @returns The current group control mode as a GroupMode enum.
*/
PCA9955::GroupMode groupMode();
/** Set the group control mode of the PCA9952/55
*
* @param mode The new group control mode as a GroupMode enum.
*/
void groupMode(GroupMode mode);
/** Determine whether or not the PCA9952/55 is overheating
*
* @returns
* 'true' if the device is currently disabled due to overheating,
* 'false' if the device is functioning normally.
*/
bool overTemp();
/** Get the specified output's state
*
* @param output The output to check.
*
* @returns The output's current state as an OutputState enum.
*/
PCA9955::OutputState outputState(Output output);
/** Set the specified output's state
*
* @param output The output to change.
* @param state The new output state as an OutputState enum.
*/
void outputState(Output output, OutputState state);
/** Get the current group control duty cycle of the PCA9952/55 in percent
*
* @returns The current group control duty cycle as a float (0.0 to 1.0).
*/
float groupDuty();
/** Set the group control duty cycle of the PCA9952/55 in percent
*
* @param duty The new group control duty cycle as a float (0.0 to 1.0).
*/
void groupDuty(float duty);
/** Get the current group control duty cycle of the PCA9952/55
*
* @returns The current group control duty cycle as an unsigned char (0 to 255).
*/
char groupDuty_char();
/** Set the group control duty cycle of the PCA9952/55
*
* @param duty The new group control duty cycle as an unsigned char (0 to 255).
*/
void groupDuty_char(char duty);
/** Get the current group control blink period of the PCA9952/55 in seconds
*
* @returns The current group control blink period in seconds (0.067 to 16.8).
*/
float groupBlinkPeriod();
/** Set the current group control blink period of the PCA9952/55 in seconds
*
* @param period The new group control blink period in seconds (0.067 to 16.8).
*/
void groupBlinkPeriod(float period);
/** Get the current group control blink period of the PCA9952/55
*
* @returns The current group control blink period as an unsigned char (0 to 255).
*/
char groupBlinkPeriod_char();
/** Set the current group control blink period of the PCA9952/55
*
* @param period The new group control blink period as an unsigned char (0 to 255).
*/
void groupBlinkPeriod_char(char period);
/** Get the specified output's duty cycle in percent
*
* @param output The output to check.
*
* @returns The output's current duty cycle as a float (0.0 to 1.0).
*/
float outputDuty(Output output);
/** Set the specified output's duty cycle in percent
*
* @param output The output to change.
* @param duty The new output duty cycle as a float (0.0 to 1.0).
*/
void outputDuty(Output output, float duty);
/** Get the specified output's duty cycle
*
* @param output The output to check.
*
* @returns The output's current duty cycle as an unsigned char (0 to 255).
*/
char outputDuty_char(Output output);
/** Set the specified output's duty cycle
*
* @param output The output to change.
* @param duty The new output duty cycle as an unsigned char (0 to 255).
*/
void outputDuty_char(Output output, char duty);
/** Get the specified output's current reference in percent
*
* @param output The output to check.
*
* @returns The output's current reference as a float (0.0 to 1.0).
*/
float outputCurrent(Output output);
/** Set the specified output's current reference in percent
*
* @param output The output to change.
* @param iref The new output current reference as a float (0.0 to 1.0).
*/
void outputCurrent(Output output, float iref);
/** Get the specified output's current reference
*
* @param output The output to check.
*
* @returns The output's current reference as an unsigned char (0 to 255).
*/
char outputCurrent_char(Output output);
/** Set the specified output's current reference
*
* @param output The output to change.
* @param iref The new output current reference as an unsigned char (0 to 255).
*/
void outputCurrent_char(Output output, char iref);
/** Get the turn-on delay between LEDn outputs
*
* @returns The turn-on delay between LEDn outputs in clocks (0 to 15 - 125ns per clock).
*/
char outputDelay();
/** Set the specified output's current reference
*
* @param clocks The turn-on delay between LEDn outputs in clocks (0 to 15 - 125ns per clock).
*/
void outputDelay(char clocks);
/** Get subaddress 1
*
* @returns The current I2C subaddress 1.
*/
char subCall1Addr();
/** Set subaddress 1
*
* @param addr The new I2C subaddress 1.
*/
void subCall1Addr(char addr);
/** Get subaddress 2
*
* @returns The current I2C subaddress 2.
*/
char subCall2Addr();
/** Set subaddress 2
*
* @param addr The new I2C subaddress 2.
*/
void subCall2Addr(char addr);
/** Get subaddress 3
*
* @returns The current I2C subaddress 3.
*/
char subCall3Addr();
/** Set subaddress 3
*
* @param addr The new I2C subaddress 3.
*/
void subCall3Addr(char addr);
/** Get the LED All Call address
*
* @returns The current LED All Call address.
*/
char allCallAddr();
/** Set the LED All Call address
*
* @param addr The new LED All Call address.
*/
void allCallAddr(char addr);
/** Set all of the output states to the same state
*
* @param state The new output state for all outputs.
*/
void allOutputStates(OutputState state);
/** Read all of the output duty cycles into an array as percents
*
* @param duties Pointer to any array for 16 duty cycles as floats (0.0 to 1.0).
*/
void getOutputDuties(float* duties);
/** Set all of the output duty cycles to the same value in percent
*
* @param duty The new duty cycle for all outputs as a float (0.0 to 1.0).
*/
void allOutputDuties(float duty);
/** Set all of the output duty cycles from an array of percents
*
* @param duties Pointer to any array of 16 duty cycles as floats (0.0 to 1.0).
*/
void allOutputDuties(float* duties);
/** Read all of the output duty cycles into an array
*
* @param duties Pointer to any array for 16 duty cycles as unsigned chars (0 to 255).
*/
void getOutputDuties_char(char* duties);
/** Set all of the output duty cycles to the same value
*
* @param duty The new duty cycle for all outputs as an unsigned char (0 to 255).
*/
void allOutputDuties_char(char duty);
/** Set all of the output duty cycles from an array
*
* @param duties Pointer to any array of 16 duty cycles as unsigned chars (0 to 255).
*/
void allOutputDuties_char(char* duties);
/** Read all of the output current references into an array as percents
*
* @param irefs Pointer to any array for 16 current references as floats (0.0 to 1.0).
*/
void getOutputCurrents(float* irefs);
/** Set all of the output current references to the same value in percent
*
* @param iref The new current reference for all outputs as a float (0.0 to 1.0).
*/
void allOutputCurrents(float iref);
/** Set all of the output current references from an array of percents
*
* @param irefs Pointer to any array of 16 current references as floats (0.0 to 1.0).
*/
void allOutputCurrents(float* irefs);
/** Read all of the output current references into an array
*
* @param irefs Pointer to any array for 16 current references as unsigned chars (0 to 255).
*/
void getOutputCurrents_char(char* irefs);
/** Set all of the output current references to the same value
*
* @param iref The new current reference for all outputs as an unsigned char (0 to 255).
*/
void allOutputCurrents_char(char iref);
/** Set all of the output current references from an array
*
* @param irefs Pointer to any array of 16 current references as unsigned chars (0 to 255).
*/
void allOutputCurrents_char(char* irefs);
/** Perform a fault test on all enabled outputs
*
* @returns The fault test flags as FaultFlags enum values OR'd together.
*/
unsigned short faultTest();
#ifdef MBED_OPERATORS
/** A shorthand for allOutputDuties()
*
* @param value The new duty cycle for all outputs as a float (0.0 to 1.0).
*/
PCA9955& operator=(float value);
#endif
private:
//I2C register addresses
enum Register {
REG_MODE1 = 0x00,
REG_MODE2 = 0x01,
REG_LEDOUT0 = 0x02,
REG_LEDOUT1 = 0x03,
REG_LEDOUT2 = 0x04,
REG_LEDOUT3 = 0x05,
REG_GRPPWM = 0x08,
REG_GRPFREQ = 0x09,
REG_PWM0 = 0x0A,
REG_PWM1 = 0x0B,
REG_PWM2 = 0x0C,
REG_PWM3 = 0x0D,
REG_PWM4 = 0x0E,
REG_PWM5 = 0x0F,
REG_PWM6 = 0x10,
REG_PWM7 = 0x11,
REG_PWM8 = 0x12,
REG_PWM9 = 0x13,
REG_PWM10 = 0x14,
REG_PWM11 = 0x15,
REG_PWM12 = 0x16,
REG_PWM13 = 0x17,
REG_PWM14 = 0x18,
REG_PWM15 = 0x19,
REG_IREF0 = 0x22,
REG_IREF1 = 0x23,
REG_IREF2 = 0x24,
REG_IREF3 = 0x25,
REG_IREF4 = 0x26,
REG_IREF5 = 0x27,
REG_IREF6 = 0x28,
REG_IREF7 = 0x29,
REG_IREF8 = 0x2A,
REG_IREF9 = 0x2B,
REG_IREF10 = 0x2C,
REG_IREF11 = 0x2D,
REG_IREF12 = 0x2E,
REG_IREF13 = 0x2F,
REG_IREF14 = 0x30,
REG_IREF15 = 0x31,
REG_OFFSET = 0x3A,
REG_SUBADR1 = 0x3B,
REG_SUBADR2 = 0x3C,
REG_SUBADR3 = 0x3D,
REG_ALLCALLADR = 0x3E,
REG_RESERVED1 = 0x3F,
REG_RESERVED2 = 0x40,
REG_RESERVED3 = 0x41,
REG_PWMALL = 0x42,
REG_IREFALL = 0x43,
REG_EFLAG0 = 0x44,
REG_EFLAG1 = 0x45,
REG_AUTO_INC = 0x80
};
//Member variables
I2C m_I2C;
const int m_ADDR;
//Internal functions
char read(char reg);
void write(char reg, char data);
void readMulti(char startReg, char* data, int length);
void writeMulti(char* data, int length);
};
#endif
PCA9952/55 16-channel LED driver