i2c RGBW led driver push/pull or opendrain output

Fork of PCA9633 by Mederic Melard

Revision:
0:39b243509a43
Child:
1:f95d80e0f84a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCA9633.cpp	Wed Jun 20 12:56:31 2018 +0000
@@ -0,0 +1,108 @@
+#include "PCA9633.h"
+#include <math.h>
+
+//***********************************/************************************
+//                              Constant                                //
+//***********************************/************************************
+#define PCA9633_ADD_SWRST   0x03 // Software Reset Call Address
+#define PCA9633_REG_SWRST   0xa5 // Software Reset register
+#define PCA9633_VAL_SWRST   0x5a // Software Reset register
+
+// Register addr (with auto increment)
+#define PCA9633_REG_MODE1   0x80  // Mode register 1
+#define PCA9633_REG_MODE2   0x81  // Mode register 2
+#define PCA9633_REG_PWM0    0x82  // brightness control LED0
+#define PCA9633_REG_GRPPWM  0x86  // group duty cycle control
+#define PCA9633_REG_GRPFREQ 0x87  // group frequency
+#define PCA9633_REG_LEDOUT  0x88  // LED output state
+
+//PCA9633 MODE2 register bit
+#define PCA9633_BIT_DMBLNK  0x05
+#define PCA9633_BIT_INVRT   0x04
+#define PCA9633_BIT_OUTDRV  0x02
+
+//***********************************/************************************
+//                         Constructors                                 //
+//***********************************/************************************
+PCA9633::PCA9633(I2C *i2c, char addr, bool invert, bool openDrain):_i2c(i2c){
+    _addr = addr<<1;
+    softReset();
+    _buf[0] = PCA9633_REG_MODE1;
+    _buf[1] = 0;
+    /*  SLEEP=0 Normal Mode
+        SUB1 =0 PCA9633 does not respond to I2C-bus subaddress 1.
+        SUB2 =0 PCA9633 does not respond to I2C-bus subaddress 2.
+        SUB3 =0 PCA9633 does not respond to I2C-bus subaddress 3.
+        ALLCAL =0 PCA9633 does not respond to LED All Call I2C-bus address.*/
+    _i2c->write(_addr,_buf,2);
+    config(invert, openDrain);
+}
+
+
+void PCA9633::config(bool invert, bool openDrain){
+    _buf[0] = PCA9633_REG_MODE2;
+    _buf[1] = (invert<<PCA9633_BIT_INVRT ) | (openDrain<<PCA9633_BIT_OUTDRV);
+    _i2c->write(_addr,_buf,2);
+}
+
+void PCA9633::softReset(void){
+    _buf[0] = PCA9633_REG_SWRST;
+    _buf[1] = PCA9633_VAL_SWRST;
+    _i2c->write(PCA9633_ADD_SWRST,_buf,2); 
+}
+
+void PCA9633::pwm(char bright, char pos){
+    _buf[0] = PCA9633_REG_PWM0;
+    _buf[1] = bright;_buf[2] = bright;_buf[3] = bright;_buf[4] = bright;
+    char len = 5;  
+    if(pos<PCA9633::ALL){
+        len=2;
+        _buf[0]+=pos;
+    }
+    _i2c->write(_addr,_buf,len);
+}
+
+void PCA9633::dim(char val){
+     _buf[0] = PCA9633_REG_MODE2;
+     _buf[1] = 0;
+     _i2c->write(_addr,_buf,1);          //cmd to read mode2 
+     _i2c->read(_addr, _buf+1,1);      //stock in buf[1]
+     _buf[1] &= ~(1<<PCA9633_BIT_DMBLNK); //set dimming in mode2
+     _i2c->write(_addr,_buf,2);          //write mode2
+     
+     _buf[0] = PCA9633_REG_GRPPWM;
+     _buf[1] = val;
+     _i2c->write(_addr,_buf,2);          //dimming
+}
+
+void PCA9633::blink(char duty, float period){
+    char buf[3] = {PCA9633_REG_MODE2,0};
+    _i2c->write(_addr,buf,1);          //cmd to read mode2 
+    _i2c->read(_addr, &buf[1],1);      //stock in buf[1]
+    buf[1] |= (1<<PCA9633_BIT_DMBLNK); //set blink in mode2
+    _i2c->write(_addr,buf,2);          //write mode2
+    
+    buf[0] = PCA9633_REG_GRPPWM;
+    buf[1] = duty;
+    buf[2] = char(rint((period*24.0)-1));
+    _i2c->write(_addr,buf,3);
+    
+}
+
+void PCA9633::ledout(char state, char pos){
+    char buf[5] = {PCA9633_REG_LEDOUT,0};
+    _i2c->write(_addr,buf,1);          //cmd to read ledout 
+    _i2c->read(_addr, &buf[1],1);      //stock in buf[1]
+     
+    if(pos<PCA9633::ALL){
+        buf[1] &= ~(0x03<<(pos*2)); // erase 2 state bit of selected position
+        buf[1] |= (state<<(pos*2)); // set state at position
+    }
+    else{
+        for(int i=0;i<PCA9633::ALL;i++){
+            buf[1] &= ~(0x03<<(i*2)); // erase 2 state bit of selected position
+            buf[1] |= (state<<(i*2)); // set state at position  
+        }
+    }
+    _i2c->write(_addr,buf,2);          //write LEDOUT
+}
\ No newline at end of file