Tomas Hübner
/
DMANeoPixel
Programming an array of NeoPixels using the GPDMA for maximum performance.
Revision 3:96f4cc4c5984, committed 2014-12-06
- 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();