A feature complete driver for the PCA9952/55 LED driver from NXP.
Dependents: PCA9955_HelloWorld
Diff: PCA9955.h
- Revision:
- 0:7b3cbb5a53b8
- Child:
- 1:016f916c5579
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9955.h Tue Nov 05 21:16:25 2013 +0000 @@ -0,0 +1,558 @@ +/* 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 indicate whether it is present on the bus + * + * @returns + * 'true' if the device exists on the bus, + * 'false' if the device doesn't exist on the bus. + */ + bool open(void); + + /** Issue an SWRST call to reset the PCA9952/55 + * @warning This might reset other I2C devices as well! + */ + void reset(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** 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(void); + + /** Set the LED All Call address + * + * @param addr The new LED All Call address. + */ + void allCallAddr(char addr); + + /** Set all of the output states at once + * + * @param state The new output state for all outputs. + */ + void allOutputStates(OutputState state); + + /** Set all of the output duties at once 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 duties at once + * + * @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 current references at once 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 at once + * + * @param iref The new current reference for all outputs as an unsigned char (0 to 255). + */ + void allOutputCurrents_char(char iref); + + /** Perform a fault test on all enabled outputs + * + * @returns The fault test flags as FaultFlags enum values OR'd together. + */ + unsigned short faultTest(void); + +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; + int m_Addr; + + //Internal functions + char read(char reg); + void readMulti(char startReg, char* data, int length); + void write(char reg, char data); + void writeMulti(char* data, int length); +}; + +#endif