From f64a92220fac388f4621eb45fc5d35d5253dea9c Mon Sep 17 00:00:00 2001 From: James Fowkes Date: Wed, 28 Apr 2021 09:45:18 +0100 Subject: [PATCH 1/3] Add OUTDRV control --- src/PCA9633.cpp | 14 ++++++++++++++ src/PCA9633.h | 13 ++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/PCA9633.cpp b/src/PCA9633.cpp index 58c3eaa..790d2c3 100644 --- a/src/PCA9633.cpp +++ b/src/PCA9633.cpp @@ -133,6 +133,20 @@ void PCA9633::setLdrStateAll(uint8_t state) { writeReg(REG_LEDOUT, newReg); } +void PCA9633::setDrvState(uint8_t state) { + + uint8_t prevReg = readReg(REG_MODE2); + uint8_t newReg; + + // first clear both bits of drv + newReg = prevReg & ~(0b11 << BIT_OUTDRV); + + // second set new state to specified drv + newReg |= (state << BIT_OUTDRV); + + writeReg(REG_MODE2, newReg); +} + void PCA9633::setAutoIncrement(uint8_t option) { uint8_t newReg; diff --git a/src/PCA9633.h b/src/PCA9633.h index 4802075..3bef450 100644 --- a/src/PCA9633.h +++ b/src/PCA9633.h @@ -195,7 +195,9 @@ */ #define BIT_LDR0 0 - +// LED driver output type, OUTDRV (page 11, MODE2 register table) +#define OUTDRV_OPEN_DRAIN 0 +#define OUTDRV_TOTEM_POLE 1 // LED driver output state, LEDOUT (page 14, below table 13) @@ -385,6 +387,15 @@ class PCA9633 { */ void setRGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w); + /** + * Set the global driver output type for a given channel. There are two types: + * - OUTDRV_OPEN_DRAIN + * - OUTDRV_TOTEM_POLE + * + * @param state One of the two possible states + */ + void setDrvState(uint8_t state); + /** * Set the LED driver output state for a given channel. There are four states: * - LDR_STATE_OFF From fe514b21772358016c1fad988ee30c7ac919c95b Mon Sep 17 00:00:00 2001 From: James Fowkes Date: Tue, 22 Jun 2021 17:24:51 +0100 Subject: [PATCH 2/3] Add invert control. --- src/PCA9633.cpp | 17 +++++++++++++++++ src/PCA9633.h | 27 ++++++++++++++++----------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/PCA9633.cpp b/src/PCA9633.cpp index 790d2c3..60e6dca 100644 --- a/src/PCA9633.cpp +++ b/src/PCA9633.cpp @@ -147,6 +147,23 @@ void PCA9633::setDrvState(uint8_t state) { writeReg(REG_MODE2, newReg); } +void PCA9633::setInvertState(bool invert) { + + uint8_t prevReg = readReg(REG_MODE2); + uint8_t newReg; + + if (invert) + { + newReg = prevReg | (1 << BIT_INVRT); + } + else + { + newReg = prevReg & ~(1 << BIT_INVRT); + } + + writeReg(REG_MODE2, newReg); +} + void PCA9633::setAutoIncrement(uint8_t option) { uint8_t newReg; diff --git a/src/PCA9633.h b/src/PCA9633.h index 3bef450..35e2646 100644 --- a/src/PCA9633.h +++ b/src/PCA9633.h @@ -396,6 +396,13 @@ class PCA9633 { */ void setDrvState(uint8_t state); + /** + * Set the invert state. Defaults to non-inverting + * + * @param invert True to set the invert bit, false to clear it + */ + void setInvertState(bool invert); + /** * Set the LED driver output state for a given channel. There are four states: * - LDR_STATE_OFF @@ -440,17 +447,6 @@ class PCA9633 { */ void setGroupControlMode(uint8_t mode); - -private: - - /** - * Write data to a register. - * - * @param registerAddress Register address to write to - * @param data Data to write - */ - void writeReg(uint8_t registerAddress, uint8_t data); - /** * Read data from a register. * @@ -460,6 +456,15 @@ class PCA9633 { * @return -1 if no byte was available to be read */ uint8_t readReg(uint8_t registerAddress); +private: + + /** + * Write data to a register. + * + * @param registerAddress Register address to write to + * @param data Data to write + */ + void writeReg(uint8_t registerAddress, uint8_t data); /** * I2C address of device. From b3ca81ca69bc679457a64b3f3f230ee7e4cb3b9d Mon Sep 17 00:00:00 2001 From: James Fowkes Date: Wed, 4 Aug 2021 16:20:54 +0100 Subject: [PATCH 3/3] Change setInvertState to use state input as per other functions. Add function to header. --- src/PCA9633.cpp | 15 ++++++--------- src/PCA9633.h | 21 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/PCA9633.cpp b/src/PCA9633.cpp index ada6df2..61582de 100644 --- a/src/PCA9633.cpp +++ b/src/PCA9633.cpp @@ -147,19 +147,16 @@ void PCA9633::setDrvState(uint8_t state) { writeReg(REG_MODE2, newReg); } -void PCA9633::setInvertState(bool invert) { +void PCA9633::setInvertState(uint8_t invert) { uint8_t prevReg = readReg(REG_MODE2); uint8_t newReg; - if (invert) - { - newReg = prevReg | (1 << BIT_INVRT); - } - else - { - newReg = prevReg & ~(1 << BIT_INVRT); - } + // first clear the INVRT bit + newReg = prevReg & ~(1 << BIT_INVRT); + + // second set new state to specified invrt + newReg |= (state << BIT_INVRT); writeReg(REG_MODE2, newReg); } diff --git a/src/PCA9633.h b/src/PCA9633.h index dd2fc92..3674b5d 100644 --- a/src/PCA9633.h +++ b/src/PCA9633.h @@ -207,6 +207,18 @@ */ #define OUTDRV_TOTEM_POLE 1 +// LED driver invert mode, INVRT (page 12, table 9, MODE2 register table, also see section 7.7) + +/** + * The 4 LED outputs are configured with non-inverting outputs + */ +#define INVERT_OFF 0 + +/** + * The 4 LED outputs are configured with inverting outputs + */ +#define INVERT_ON 1 + // LED driver output state, LEDOUT (page 14, below table 13) /** @@ -404,6 +416,15 @@ class PCA9633 { */ void setDrvState(uint8_t state); + /** + * Set the global output invert mode. There are two types: + * - INVERT_OFF + * - INVERT_ON + * + * @param state One of the two possible states + */ + void setInvertState(uint8_t state); + /** * Set the LED driver output state for a given channel. There are four states: * - LDR_STATE_OFF