i2c RGBW led driver push/pull or opendrain output
Fork of PCA9633 by
Diff: PCA9633.cpp
- 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