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:
bikeNomad
Date:
Thu Jan 02 19:42:14 2014 +0000
Parent:
24:feb1dae0403a
Child:
26:ac5d0e18c7b6
Commit message:
added second light strip to demo.

Changed in this revision

WS2811.cpp 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
--- a/WS2811.cpp	Thu Jan 02 11:26:44 2014 +0000
+++ b/WS2811.cpp	Thu Jan 02 19:42:14 2014 +0000
@@ -54,15 +54,13 @@
 static const uint32_t tpm_p0_period = NSEC_TO_TICKS(CLK_NSEC / 3);
 static const uint32_t tpm_p1_period = NSEC_TO_TICKS(CLK_NSEC * 2 / 3);
 
-enum DMA_MUX_SRC
-{
+enum DMA_MUX_SRC {
     DMA_MUX_SRC_TPM0_CH_0     = 24,
     DMA_MUX_SRC_TPM0_CH_1,
     DMA_MUX_SRC_TPM0_Overflow = 54,
 };
 
-enum DMA_CHAN
-{
+enum DMA_CHAN {
     DMA_CHAN_START = 0,
     DMA_CHAN_0_LOW = 1,
     DMA_CHAN_1_LOW = 2,
@@ -86,8 +84,7 @@
 #define BITS_PER_RGB       24
 #define DMA_TRAILING_ZEROS 1
 
-static struct
-{
+static struct {
     uint32_t start_t1_low[ DMA_LEADING_ZEROS ];
     uint32_t dmaWords[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
     uint32_t trailing_zeros_1[ DMA_TRAILING_ZEROS ];
@@ -97,7 +94,7 @@
     uint32_t trailing_zeros_2[ DMA_TRAILING_ZEROS + 1 ];
 } dmaData WORD_ALIGNED;
 
-// class static 
+// class static
 bool WS2811::is_dma_done()
 {
     return dma_done;
@@ -148,11 +145,9 @@
 void WS2811::io_init()
 {
     uint32_t m = 1;
-    for (uint32_t i = 0; i < 32; i++)
-    {
+    for (uint32_t i = 0; i < 32; i++) {
         // set up each pin
-        if (m & enabledPins)
-        {
+        if (m & enabledPins) {
             IO_PORT->PCR[i] = PORT_PCR_MUX(1) // GPIO
                               | PORT_PCR_DSE_MASK; // high drive strength
         }
@@ -235,11 +230,13 @@
 // class static
 void WS2811::startDMA()
 {
+    hw_init();
+
     DMA_Type volatile * dma   = DMA0;
     TPM_Type volatile *tpm   = TPM0;
     uint32_t nBytes = sizeof(dmaData.start_t1_low)
-        + sizeof(dmaData.dmaWords)
-        + sizeof(dmaData.trailing_zeros_1);
+                      + sizeof(dmaData.dmaWords)
+                      + sizeof(dmaData.trailing_zeros_1);
 
     tpm->SC &= ~TPM_SC_CMOD_MASK; // disable internal clocking
     tpm->CNT = tpm_p0_period - 2 ;
@@ -267,20 +264,18 @@
     dma->DMA[DMA_CHAN_1_LOW].SAR     = (uint32_t)(void*)dmaData.start_t1_low; // set source address
     dma->DMA[DMA_CHAN_1_LOW].DSR_BCR = DMA_DSR_BCR_BCR_MASK & nBytes; // length of transfer in bytes
 
-    dma->DMA[DMA_CHAN_0_LOW].DAR 
-        = dma->DMA[DMA_CHAN_1_LOW].DAR 
-        = dma->DMA[DMA_CHAN_START].DAR 
+    dma->DMA[DMA_CHAN_0_LOW].DAR
+    = dma->DMA[DMA_CHAN_1_LOW].DAR
+      = dma->DMA[DMA_CHAN_START].DAR
         = (uint32_t)(void*)&IO_GPIO->PDOR;
 
     // wait until done
-    while (!is_dma_done())
-    {
+    while (!is_dma_done()) {
         __WFI();
     }
-    
+
     // ensure sufficient guard time
-    while (guardtime.read_us() < 50)
-    {
+    while (guardtime.read_us() < 50) {
         __NOP();
     }
 
@@ -324,8 +319,7 @@
 // class static
 void WS2811::writeByte(uint8_t byte, uint32_t mask, uint32_t *dest)
 {
-    for (uint8_t bm = 0x80; bm; bm >>= 1)
-    {
+    for (uint8_t bm = 0x80; bm; bm >>= 1) {
         // MSBit first
         if (byte & bm)
             *dest |= mask;
@@ -347,7 +341,7 @@
 
 #if DEBUG
     for (unsigned i = DMA_LEADING_ZEROS; i < DMA_LEADING_ZEROS + BITS_PER_RGB; i++)
-            dmaData.dmaWords[i] = DEBUG_MASK;
+        dmaData.dmaWords[i] = DEBUG_MASK;
 #else
     memset(dmaData.dmaWords, 0x00, sizeof(dmaData.dmaWords));
 #endif
@@ -355,18 +349,14 @@
 
 void WS2811::show()
 {
-    hw_init();
 
     uint16_t i, n = numPixels(); // 3 bytes per LED
     uint8_t *p = pixels;
 
-    for (i=0; i<n; i++ )
-    {
+    for (i=0; i<n; i++ ) {
         writePixel(i, p);
         p += 3;
     }
-
-    startDMA();
 }
 
 extern "C" void DMA0_IRQHandler()
@@ -375,20 +365,17 @@
     TPM_Type volatile *tpm   = TPM0;
 
     uint32_t db = dma->DMA[DMA_CHAN_START].DSR_BCR;
-    if (db & DMA_DSR_BCR_DONE_MASK)
-    {
+    if (db & DMA_DSR_BCR_DONE_MASK) {
         dma->DMA[DMA_CHAN_START].DSR_BCR = DMA_DSR_BCR_DONE_MASK;  // clear/reset DMA status
     }
 
     db = dma->DMA[DMA_CHAN_0_LOW].DSR_BCR;
-    if (db & DMA_DSR_BCR_DONE_MASK)
-    {
+    if (db & DMA_DSR_BCR_DONE_MASK) {
         dma->DMA[DMA_CHAN_0_LOW].DSR_BCR = DMA_DSR_BCR_DONE_MASK;  // clear/reset DMA status
     }
 
     db = dma->DMA[DMA_CHAN_1_LOW].DSR_BCR;
-    if (db & DMA_DSR_BCR_DONE_MASK)
-    {
+    if (db & DMA_DSR_BCR_DONE_MASK) {
         dma->DMA[DMA_CHAN_1_LOW].DSR_BCR = DMA_DSR_BCR_DONE_MASK; // clear/reset DMA status
         dma_done                         = true;
         tpm->SC &= ~TPM_SC_CMOD_MASK; // disable internal clocking
--- a/main.cpp	Thu Jan 02 11:26:44 2014 +0000
+++ b/main.cpp	Thu Jan 02 19:42:14 2014 +0000
@@ -5,6 +5,7 @@
 
 // per LED: 3 * 20 mA = 60mA max
 // 60 LEDs: 60 * 60mA = 3600 mA max
+// 120 LEDs: 7200 mA max
 unsigned const nLEDs = MAX_LEDS_PER_STRIP;
 
 // I/O pin usage
@@ -13,24 +14,26 @@
 // PTD2 data output
 // PTD3 debug output
 
-unsigned const DATA_OUT_PIN = 2; // PTD2
+unsigned const DATA_OUT_PIN1 = 2; // PTD2
+unsigned const DATA_OUT_PIN2 = 3; // PTD3
 
 Serial pc(USBTX, USBRX);
+Timer timeRunning;
 
 TSISensor touchSensor;
 Ticker touchTicker;
 float touchPercentage;
-float const minBrite = 0.1;
-float const maxBrite = 0.7;
+unsigned frames;
+
+float const minBrite = 0.2;
+float const maxBrite = 0.5;
 float brite;
 
 void readTouchSensor()
 {
     touchPercentage *= 0.9;
     touchPercentage += touchSensor.readPercentage() * 0.1;
-    brite = maxBrite * touchPercentage;
-    if (brite < minBrite)
-        brite = minBrite;
+    brite = minBrite + (maxBrite - minBrite) * touchPercentage;
 }
 
 // @brief sets different colors in each of the LEDs of a strip
@@ -62,28 +65,28 @@
 int main(void)
 {
     pc.baud(115200);
-    WS2811 lightStrip(nLEDs, DATA_OUT_PIN);
+    WS2811 lightStrip1(nLEDs, DATA_OUT_PIN1);
+    WS2811 lightStrip2(nLEDs, DATA_OUT_PIN2);
 
     touchTicker.attach(&readTouchSensor, 0.1);
-    lightStrip.begin();
+    lightStrip1.begin();
+    lightStrip2.begin();
 
     float rainbowPeriod = 1 * 1.0e6; // usec
     float sat = 1.0;
 
-    Timer timeRunning;
     timeRunning.start();
     bool printed = false;
-    unsigned frames = 0;
 
     uint8_t r =0;
     uint8_t g =0;
     uint8_t b =0;
     for (;;) {
-        if (r < 255)
+        if (r < 40)
             r++;
-        else if (g < 255)
+        else if (g < 40)
             g++;
-        else if (b < 255)
+        else if (b < 40)
             b++;
         else {
             unsigned running = timeRunning.read_us();
@@ -92,7 +95,10 @@
         }
 
         wait(0.1);
-        showSolidColor(lightStrip, r, g, b);
+        showSolidColor(lightStrip1, r, g, b);
+        showSolidColor(lightStrip2, r, g, b);
+        WS2811::startDMA();
+
         frames++;
     }
 
@@ -106,7 +112,10 @@
             pc.printf("%u frames in %u usec = %u frames / sec\r\n", frames, running, frames * 1000000 / running);
             printed = true;
         }
-        showRainbow(lightStrip, sat, brite, hueShift);
+        showRainbow(lightStrip1, sat, brite, hueShift);
+        showRainbow(lightStrip2, sat, brite, hueShift + 0.5);
+        WS2811::startDMA();
+
         frames ++;
     }
 }