Simple 8x8 LED Matrix controller which interfaces with a Processing GUI over serial to display sketches

Dependencies:   Multi_WS2811 mbed

Fork of Multi_WS2811_test by Ned Konz

Files at this revision

API Documentation at this revision

Comitter:
heroic
Date:
Tue Jul 23 22:32:14 2013 +0000
Parent:
12:7ebd51549c04
Child:
14:c97261a9a282
Commit message:
Rework timing for constant execution time; do direct bitband writes for improved speed; change interrupt handling (turns out we can't have interrupts during an entire strip push, not just between bits).; ; Now works!

Changed in this revision

WS2811.cpp Show annotated file Show diff for this revision Revisions of this file
WS2811.h Show annotated file Show diff for this revision Revisions of this file
--- a/WS2811.cpp	Thu Apr 11 22:16:07 2013 +0000
+++ b/WS2811.cpp	Tue Jul 23 22:32:14 2013 +0000
@@ -27,6 +27,14 @@
     printf("ws2811:  1000 iters took %d usec.\n", i);
     bogocal = (1000 / (onewire_speed_multiplier * i * 4.2)); // iterations per bitcell (417 nsec)
     printf("ws2811:  calibrating to %d bogojiffies.\n", bogocal);
+    
+    data_mask = dat.get_mask();
+    clock_mask = clk.get_mask();
+    data_set = dat.get_set();
+    data_clr = dat.get_clr();
+    clock_set = clk.get_set();
+    clock_clr = clk.get_clr();
+    
 }
 
 /*
@@ -34,7 +42,7 @@
  */
  
 void WS2811::write(uint8_t byte) {
-    __disable_irq();
+    
     for (int i=0; i<8; i++) {
         if (byte & 0x80)
             writebit(1);
@@ -42,26 +50,26 @@
             writebit(0);
         byte <<= 1;
     }
-    __enable_irq();
 }
 
 inline void WS2811::celldelay(void) {
-    for (int i = 0; i<bogocal; i++)
+    for (volatile int i = 0; i<bogocal; i++)
         /* do nothing */ ;
 }
 
-void WS2811::writebit(bool bit) {
+inline void WS2811::writebit(bool bit) {
     // first cell is always 1
-    dat = 1;
+    (*data_set) = data_mask;
     celldelay();
     if (bit) {
+        (*clock_set) = data_mask; // dummy, we don't care but must take constant time
         celldelay();
     } else {
-        dat=0;
+        (*data_clr) = data_mask;
         celldelay();
     }
     // last cell is always 0
-    dat=0;
+    (*data_clr) = data_mask;
     celldelay();
 }
 
@@ -82,10 +90,11 @@
     uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
     while (guardtime.read_us() < 50)
         /* spin */;
+    __disable_irq();
     for (i=0; i<nl3; i++ ) {
         write(pixels[i]);
     }
-
+    __enable_irq();
     guardtime.reset();
 }
 
--- a/WS2811.h	Thu Apr 11 22:16:07 2013 +0000
+++ b/WS2811.h	Tue Jul 23 22:32:14 2013 +0000
@@ -37,6 +37,12 @@
  private:
   DigitalOut dat;
   DigitalOut clk;
+  __IO uint32_t *data_set;
+  __IO uint32_t *clock_set;
+  __IO uint32_t *data_clr;
+  __IO uint32_t *clock_clr;
+  uint32_t clock_mask;
+  uint32_t data_mask;
   void write(uint8_t byte);
   void writebit(bool bit);
   void celldelay(void);