Using the I2C LED driver on the Embedded Artists baseboard to control the LEDS.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
chris
Date:
Tue Mar 02 07:40:02 2010 +0000
Commit message:

Changed in this revision

PCA9532.cpp Show annotated file Show diff for this revision Revisions of this file
PCA9532.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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