i2c RGBW led driver push/pull or opendrain output

Fork of PCA9633 by Mederic Melard

PCA9633.cpp

Committer:
mederic
Date:
2018-06-20
Revision:
0:39b243509a43
Child:
1:f95d80e0f84a

File content as of revision 0:39b243509a43:

#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
}