This example positions a lit LED in the I2C LED array using the rotary encoder

Dependencies:   mbed

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]);
+}
+
+
+
+
+