A feature complete driver for the PCA9952/55 LED driver from NXP.
Dependents: PCA9955_HelloWorld
PCA9955.h
- Committer:
- neilt6
- Date:
- 2013-11-08
- Revision:
- 4:6ca7ab31c5fb
- Parent:
- 3:84571acc16a1
- Child:
- 5:7ad949955db8
File content as of revision 4:6ca7ab31c5fb:
/* 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 a PCA9955 object using the LED All Call address * PCA9955 driver(p28, p27, PCA9955::ADDRESS_ALL); * * 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 of the output states to PWM mode * driver.allOutputStates(PCA9955::OUTPUT_PWM); * * //Set 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 = 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) */ ADDRESS_ALL = (0x70 << 1), /**< The default LED All Call address */ ADDRESS_SUB = (0x76 << 1) /**< The default subaddress for 16-channel LED drivers */ }; /** 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); /** Create a PCA9952/55 object connected to the specified I2C pins with a custom I2C slave address * * @param sda The I2C data pin. * @param scl The I2C clock pin. * @param addr The custom I2C slave address (a modified subaddress or LED All Call address). */ PCA9955(PinName sda, PinName scl, int addr); /** 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