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
Revision 13:1f65330abe92, committed 2013-07-23
- 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);
