Only update of BurstSPI-Library
Dependents: WordClock TI_NEOPIXEL_SPI
Fork of PixelArray by
Revision 0:38eeab21a162, committed 2014-07-24
- Comitter:
- JacobBramley
- Date:
- Thu Jul 24 12:19:20 2014 +0000
- Child:
- 1:adbbe3e9f2c5
- Commit message:
- Basic (untested) NeoPixel driver.
Changed in this revision
neopixel-spi.cpp | Show annotated file Show diff for this revision Revisions of this file |
neopixel-spi.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neopixel-spi.cpp Thu Jul 24 12:19:20 2014 +0000 @@ -0,0 +1,59 @@ +#include <stdint.h> +#include "mbed.h" +#include "neopixel-spi.h" + +namespace neopixel { + +Array::Array(PinName out) : spi_(out, NC, NC) { + // TODO: WS2811 has a different timing specification. + + // WS2812 bit timings: + // '0': ----________ mark: 0.40us, space: 0.85us + // '1': --------____ mark: 0.80us, space: 0.45us + // The period is 1.25us, giving a basic frequency of 800kHz. + // Using three SPI bits per NeoPixel bit, we need an API frequency of 2.4MHz. + // '0': 100 mark: 0.42us, space: 0.83us + // '1': 110 mark: 0.83us, space: 0.42us + // These timings are well within the +/-150ns tolerance specified by WS2812. + + spi_.frequency(2400000); + spi_.format(12); // Send four NeoPixel bits in each packet. +} + +static void SendFourBits(BurstSPI& spi, uint32_t bits) { + static int const pattern_width = 3; + uint32_t word = 04444; // 0b100100100100 + + for (int i = 0; i < 4; i++) { + word |= ((bits >> 3) & 1) << (pattern_width * i + 1); + } + + spi.fastWrite(word); +} + +void Array::Update(Pixel buffer[], size_t length) { + // Pixels are sent as follows: + // - The first transmitted pixel is the pixel closest to the transmitter. + // - The most significant bit is always sent first. + // - Green is sent first, then red, then blue. + // + // g7,g6,g5,g4,g3,g2,g1,g0,r7,r6,r5,r4,r3,r2,r1,r0,b7,b6,b5,b4,b3,b2,b1,b0 + // \ / + // \___________________________________________________________________/ + // | + // GRB,GRB,GRB,GRB,... + + for (size_t i = 0; i < length; i++) { + SendFourBits(spi_, (buffer[i].green >> 4) & 0xf); + SendFourBits(spi_, (buffer[i].green >> 0) & 0xf); + SendFourBits(spi_, (buffer[i].red >> 4) & 0xf); + SendFourBits(spi_, (buffer[i].red >> 0) & 0xf); + SendFourBits(spi_, (buffer[i].blue >> 4) & 0xf); + SendFourBits(spi_, (buffer[i].blue >> 0) & 0xf); + } + spi_.clearRX(); + + wait_us(50); +} + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neopixel-spi.h Thu Jul 24 12:19:20 2014 +0000 @@ -0,0 +1,29 @@ +#ifndef NEOPIXEL_SPI +#define NEOPIXEL_SPI + +#include <stdint.h> +#include "mbed.h" +#include "BurstSPI.h" + +namespace neopixel { + +struct Pixel { + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +// Drive a chain of NeoPixels. The 'count' parameter specifies the length of the chain. +class Array { + public: + Array(PinName out); + + void Update(Pixel buffer[], size_t length); + + private: + BurstSPI spi_; +}; + +} + +#endif \ No newline at end of file