Chris Styles
/
EA_LEDS
Using the I2C LED driver on the Embedded Artists baseboard to control the LEDS.
Revision 0:5d07670e5b83, committed 2010-03-02
- Comitter:
- chris
- Date:
- Tue Mar 02 07:40:02 2010 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 5d07670e5b83 PCA9532.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9532.cpp Tue Mar 02 07:40:02 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]); +} + + + + +
diff -r 000000000000 -r 5d07670e5b83 PCA9532.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCA9532.h Tue Mar 02 07:40:02 2010 +0000 @@ -0,0 +1,64 @@ +/* PCA9532 + * (c) 2009, cstyles + */ + +#ifndef PCA9532_H +#define PCA9532_H + +#include "mbed.h" + +// register names +#define PCA9532_REG_INPUT0 0 +#define PCA9532_REG_INPUT1 1 +#define PCA9532_REG_PSC0 2 +#define PCA9532_REG_PWM0 3 +#define PCA9532_REG_PSC1 4 +#define PCA9532_REG_PWM1 5 +#define PCA9532_REG_LS0 6 +#define PCA9532_REG_LS1 7 +#define PCA9532_REG_LS2 8 +#define PCA9532_REG_LS3 9 + +#define PCA9532_MODE_CLEAR 0 +#define PCA9532_MODE_SET 1 +#define PCA9532_MODE_PWM0 2 +#define PCA9532_MODE_PWM1 3 + + + + + +class PCA9532 { + +public: + + PCA9532(PinName sda, PinName scl, int addr); + + void write (int leds); + + void set (int leds); + void clear (int leds); + void pwm0 (int leds); + void pwm1 (int leds); + + void duty0 (float d); + void duty1 (float d); + + void period0 (float t); + void period1 (float t); + +protected: + + void _write(int reg, int data); + int _read(int reg); + + void _rmw(int led, int mode); + + int _addr; + + I2C _i2c; + +}; + + +#endif
diff -r 000000000000 -r 5d07670e5b83 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Mar 02 07:40:02 2010 +0000 @@ -0,0 +1,50 @@ +#include "mbed.h" +#include "PCA9532.h" + +DigitalOut myled(LED1); + +PCA9532 leds (p28,p27,0xc0); + +int main() { + + +// set leds 15-12 to PWM1 channel +leds.pwm1(0xf000); + +// set leds 11-8 to PWM0 channel +leds.pwm0(0x0f00); + +// set leds 7-4 to "off" +leds.clear(0x00f0); + +// set leds 7-4 to "on" +leds.set(0xf); + + +while (1) { + + for (float i = 0.0 ; i < 1.0 ; i+=0.01) { + leds.duty0(i); // PWM0 brighter + leds.duty1(1.0-i); // PWM1 dimmer + wait (0.01); + } + + leds.clear(0xf); // Toggle LEDS + leds.set(0x00f0); + + for (float i = 1.0 ; i > 0.0 ; i-=0.01) { + leds.duty0(i); // PWM0 dimmer + leds.duty1(1.0-i); // PWM1 brighter + + wait (0.01); + } + + leds.clear(0x00f0); // Toggle LEDS + leds.set(0x000f); + + + +} + +} +
diff -r 000000000000 -r 5d07670e5b83 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Mar 02 07:40:02 2010 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0