Programming an array of NeoPixels using the GPDMA for maximum performance.

Dependencies:   MODDMA mbed

Files at this revision

API Documentation at this revision

Comitter:
tohu
Date:
Sat Dec 06 15:01:16 2014 +0000
Parent:
2:1f2f547a9991
Child:
4:f2ef03b37a66
Commit message:
Funkar ungef?r, det verkar som att den har problem med flera nollor efter varandra eller n?got...

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Sat Dec 06 12:19:28 2014 +0000
+++ b/main.cpp	Sat Dec 06 15:01:16 2014 +0000
@@ -9,7 +9,7 @@
 DigitalOut led4(LED4);
 
 
-#define IMAGE_SIZE 120
+#define IMAGE_SIZE 123
 
 // Set DAC output power mode.
 #define DAC_POWER_MODE  (1 << 16)
@@ -18,15 +18,54 @@
 // IMAGE AND RENDER BUFFER
 //
 
-// NOTE: BRG!!!!
+// TODO: WHY DOESN'T THE LAST BIT GET OK!?!?!?!?!?!
+
+// WHY DOES ALL 0,1,4,5,8,9,C,D GET DISPLACED??
+
+int foo = 0xcc;
+int bar = 0xee;
+
+#if 0
+uint8_t  smiley [IMAGE_SIZE] = {
+    0x0, 0x0, 0xFF, 0x0, 0x0, 0xDC, 0x0, 0x0, 0xBA, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0,0x0, 0x0, 0x3E, 0x0, 0x0, 0x1F,
+    0x0, 0x0, 0xFF, 0x0, 0x0, 0xDC, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x1F,
+    0x0, 0x0, 0xFF, 0x0, 0x0, 0xDC, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x1F,
+    0x0, 0x0, 0xFF, 0x0, 0x0, 0xDC, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x1F,
+    0x0, 0x0, 0xFF, 0x0, 0x0, 0xDC, 0x0, 0x0, 0xBA, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0xFF, 0xFF, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x1F,
+    0x0, 0x0, 0x0
+};
+#endif
+
+#if 1
+uint8_t  smiley [IMAGE_SIZE] = {
+    0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5,0x6, 0x6, 0x6, 0x7, 0x7, 0x7,
+    0x8, 0x8, 0x8, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0xb, 0xb, 0xb, 0xc, 0xc, 0xc, 0xd, 0xd, 0xd,0xe, 0xe, 0xe, 0xf, 0xf, 0xf,
+    0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17,
+    0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f,
+    0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27,
+    0x0, 0x0, 0x0
+};
+#endif
+
+#if 0
+uint8_t  smiley [IMAGE_SIZE] = {
+    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+    0x0, 0x0, 0x0
+};
 
 uint8_t  smiley [IMAGE_SIZE] = {
     0xFF,0x0,0x0,0xD9,0x0,0x0,0xBA,0x0,0x0,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x3E,0x0,0x0,0x1F,0x0,0x0,
     0xFF,0x0,0x0,0xD9,0x0,0x0,0x0,0xFF,0xFF,0x0,0x0,0x0,0x0,0xFF,0xFF,0x0,0x0,0x0,0x0,0xFF,0xFF,0x1F,0x0,0x0,
     0xFF,0x0,0x0,0xD9,0x0,0x0,0x0,0xFF,0xFF,0x0,0x0,0x0,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x1F,0x0,0x0,
     0xFF,0x0,0x0,0xD9,0x0,0x0,0x0,0xFF,0xFF,0x0,0x0,0x0,0x0,0xFF,0xFF,0x0,0x0,0x0,0x0,0xFF,0xFF,0x1F,0x0,0x0,
-    0xFF,0x0,0x0,0xD9,0x0,0x0,0xBA,0x0,0x0,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x3E,0x0,0x0,0x1F,0x0,0x0};
-
+    0xFF,0x0,0x0,0xD9,0x0,0x0,0xBA,0x0,0x0,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x0,0xFF,0xFF,0x3E,0x0,0x0,0x1F,0x0,0x0,
+    0x0, 0x0, 0x0
+};
+#endif
 
 uint8_t *renderBuffer;
 #if 0
@@ -50,9 +89,10 @@
 
 SPI spi(p11, NC, p13);
 
+Timer dmaTimer;
+
 int main()
 {
-    
     // Setup the serial port to print out results.
     pc.baud(115200);
 
@@ -66,8 +106,8 @@
     // Set up the image to render
     copyImageToRender(smiley, renderBuffer, IMAGE_SIZE);
 
-    spi.format(16);
-    spi.frequency(2800000);
+    spi.format(8); // spi.format(8,0) har fungerat!!
+    spi.frequency(3300000); // 3200000 har fungerat!!!
 
 #if 0
     // SET SPI OUTPUT PINS
@@ -90,12 +130,12 @@
     ->attach_err    ( &ERR_callback )
     ;
     LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
-    
-    #if 0
+
+#if 0
     // Set up SSP0 (SPI)
     //LPC_GPDMA->DMACSoftSReq = 0xC;
     //NVIC_EnableIRQ(DMA_IRQn);
-      
+
     // SET THE CLOCK AND POWER THE SSP0 UP
     LPC_SC->PCLKSEL0 &= ~(2<<10); // PCLK_SSP0 = CCLK/2 (96MHz)
     LPC_SSP0->CPSR = 10; // CPSDVSR = 10 (9600kHz)
@@ -103,41 +143,50 @@
     LPC_SSP0->CR0 =  (3<<8) | 7;  // SCR = 1 (2400kHz), CPOL = low, SPI frame format, 8 bits per frame
     // Start the transfer
     LPC_SSP0->DMACR |= 3; // TX/RXDMAE - enable transmit FIFO for DMA
-    
+
     if(!dma.Prepare(dmaConfig)) {
         error("Failed to prepare dma configuration!");
     }
-    
+
     LPC_SSP0->CR1 = 2; // Enable the SSP0
-    
-    #else
-    
+
+#else
+
     if(!dma.Prepare(dmaConfig)) {
         error("Failed to prepare dma configuration!");
     }
-    
+
+    dmaTimer.start();
+
     dma.Enable(dmaConfig);
-    
-    #endif
-    
+
+#endif
+
     while(1) {
 
-        if(!flgCompleted)
-        {
+        if(!flgCompleted) {
             led1 = !led1;
-        }
-        else
-        {
+        } else {
+            pc.printf("Time spend in dma: %d us\n", dmaTimer.read_us());
+
+
             led2 = !led2;
         }
-        if(flgFailed)
-        {
-            wait(0.1);            
+        if(flgFailed) {
+            wait(0.1);
             led2 = !led2;
         }
 
+        uint8_t in[2] = { 0x99, 0x33 };
+        uint8_t out[8];
+
+        copyImageToRender(in, out, 2);
+
+        pc.printf("RENDER white: %02x %02x %02x %02x\n", out[0],out[1],out[2],out[3]);
+        pc.printf("RENDER black: %02x %02x %02x %02x\n", out[4],out[5],out[6],out[7]);
+
         wait(1);
-        led4 = !led4;     
+        led4 = !led4;
     }
 }
 
@@ -147,21 +196,23 @@
     // TODO: FIX THIS UP!!!!
     // DISMANTLE THE SSP0 (SPI)
     //
-    
+
     LPC_SSP0->CR1 = 0; // Diable the SSP0    ?
-    
+
     // Just show sending buffer0 complete.
-    led3 = !led3; 
-        
+    led3 = !led3;
+
     // Get configuration pointer.
     MODDMA_Config *config = dma.getConfig();
-    
+
     // Finish the DMA cycle by shutting down the channel.
     dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
     dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-     
+
+    dmaTimer.stop();
+
     flgCompleted = true;
-    
+
     // Clear DMA IRQ flags.
     if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
     if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
@@ -170,7 +221,7 @@
 void ERR_callback(void)
 {
     error("Something failed!!!!");
-    
+
     flgFailed = true;
 }
 
@@ -186,17 +237,31 @@
 
         outIndex = i*4;
 
+        // 11001100
+        buffer[outIndex] = 0xCC | image[i]&128>>2 | image[i]&64>>5;
+
+        // 11001100
+        buffer[outIndex+1] = 0xCC | image[i]&32 | image[i]&16>>3;
+
+        // 11001100
+        buffer[outIndex+2] = 0xCC |image[i]&8<<2 | image[i]&4>>1;
+
+        // 11001100
+        buffer[outIndex+3] = 0xCC |image[i]&2<<4 | image[i]&1<<1;
+
+#if 0
         // 10001000
         buffer[outIndex++] = 0x88 | image[i]&128>>1 | image[i]&64>>4;
 
         // 10001000
-        buffer[outIndex++] = 0x88 | image[i]&32>>3 | image[i]&16>>2;
+        buffer[outIndex++] = 0x88 | image[i]&32<<1 | image[i]&16>>2;
 
         // 10001000
-        buffer[outIndex++] = 0x88 |image[i]&8<<4 | image[i]&4;
+        buffer[outIndex++] = 0x88 |image[i]&8<<3 | image[i]&4;
 
         // 10001000
-        buffer[outIndex++] = 0x88 |image[i]&2<<6 | image[i]&1<<2;
+        buffer[outIndex] = 0x88 |image[i]&2<<5 | image[i]&1<<2;
+#endif
     }
 
     timer.stop();