Chris Styles
/
EA_RotaryEncoder
This example positions a lit LED in the I2C LED array using the rotary encoder
Diff: PCA9532.cpp
- Revision:
- 0:498b9b4a7bb9
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9532.cpp Tue Mar 02 08:27:23 2010 +0000 @@ -0,0 +1,186 @@ +/* +PCA9532 +(c) 2009, cstyles +*/ + +#include "PCA9532.h" +#include "mbed.h" + +/* + Constructor, pin names for I2C and the I2C addrss of the device + */ + + +PCA9532::PCA9532(PinName scl, PinName sda, int addr) + : _i2c(scl, sda) { + + _addr = addr; + +} + + + + + +/* + force the LEDs on or off according to thier corresponding bits + in the vector + */ + +void PCA9532::write (int leds) { + + // cycle through the array + for (int i=0; i < 16; i++) { + + // if the ith bit is '1' + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_SET); + } + + else { + _rmw(i,PCA9532_MODE_CLEAR); + } + } +} + + + +/* + this is one hot encoding for the LED array + any bit set will have it's corresponding LED switched on + */ + +void PCA9532::set (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_SET); + } + } +} + + +void PCA9532::clear (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_CLEAR); + } + } +} + + +void PCA9532::pwm0 (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_PWM0); + } + } +} + + +void PCA9532::pwm1 (int leds) { + for (int i=0; i < 16; i++) { + if (leds & (0x1 << i)) { + _rmw(i,PCA9532_MODE_PWM1); + } + } +} + + +void PCA9532::duty0 (float d) { + +char duty = 0; + +if (d > 1.0) { duty = 255; } +else if ( d < 0.0 ) { duty = 0; } +else { duty = 256 * d; } + +_write(PCA9532_REG_PWM0,duty); + +} + + +void PCA9532::duty1 (float d) { + +char duty = 0; + +if (d > 1.0) { duty = 255; } +else if ( d < 0.0 ) { duty = 0; } +else { duty = 256 * d; } + +_write(PCA9532_REG_PWM1,duty); + +} + + + + + + + +/* + led is in the range 0-15 + mode is inthe range 0-3 + */ + +void PCA9532::_rmw(int led, int mode) { + + int reg = 0; + int offset = (led % 4); + + // makesure mode is within bounds + if ( (mode < 0) || (mode > 3) ) { + return; + } + + + // determine which register this is, + if (led < 4) { + reg = PCA9532_REG_LS0;} + + else if ( (led > 3) && (led < 8) ) { + reg = PCA9532_REG_LS1;} + + else if ( (led > 7) && (led < 12) ) { + reg = PCA9532_REG_LS2;} + + else if ( (led > 11) && (led < 16) ) { + reg = PCA9532_REG_LS3;} + + else { return; } + + // read the current status of the register + char regval = _read(reg); + + // clear the two bit slice at the calculated offset + regval &= ~(0x3 << (2 * offset)); + + // now OR in the mode, shifted by 2 8 offset + regval |= (mode << (2 * offset)); + + // write this back + + _write(reg,regval); + + return; +} + + +void PCA9532::_write(int reg, int data) { + char args[2]; + args[0] = reg; + args[1] = data; + _i2c.write(_addr,args,2); +} + + +int PCA9532::_read(int reg) { + char args[2]; + args[0] = reg; + _i2c.write(_addr,args,2); + return(args[1]); +} + + + + +