Only update of BurstSPI-Library
Dependents: WordClock TI_NEOPIXEL_SPI
Fork of PixelArray by
neopixel-spi.cpp@0:38eeab21a162, 2014-07-24 (annotated)
- Committer:
- JacobBramley
- Date:
- Thu Jul 24 12:19:20 2014 +0000
- Revision:
- 0:38eeab21a162
- Child:
- 1:adbbe3e9f2c5
Basic (untested) NeoPixel driver.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JacobBramley | 0:38eeab21a162 | 1 | #include <stdint.h> |
JacobBramley | 0:38eeab21a162 | 2 | #include "mbed.h" |
JacobBramley | 0:38eeab21a162 | 3 | #include "neopixel-spi.h" |
JacobBramley | 0:38eeab21a162 | 4 | |
JacobBramley | 0:38eeab21a162 | 5 | namespace neopixel { |
JacobBramley | 0:38eeab21a162 | 6 | |
JacobBramley | 0:38eeab21a162 | 7 | Array::Array(PinName out) : spi_(out, NC, NC) { |
JacobBramley | 0:38eeab21a162 | 8 | // TODO: WS2811 has a different timing specification. |
JacobBramley | 0:38eeab21a162 | 9 | |
JacobBramley | 0:38eeab21a162 | 10 | // WS2812 bit timings: |
JacobBramley | 0:38eeab21a162 | 11 | // '0': ----________ mark: 0.40us, space: 0.85us |
JacobBramley | 0:38eeab21a162 | 12 | // '1': --------____ mark: 0.80us, space: 0.45us |
JacobBramley | 0:38eeab21a162 | 13 | // The period is 1.25us, giving a basic frequency of 800kHz. |
JacobBramley | 0:38eeab21a162 | 14 | // Using three SPI bits per NeoPixel bit, we need an API frequency of 2.4MHz. |
JacobBramley | 0:38eeab21a162 | 15 | // '0': 100 mark: 0.42us, space: 0.83us |
JacobBramley | 0:38eeab21a162 | 16 | // '1': 110 mark: 0.83us, space: 0.42us |
JacobBramley | 0:38eeab21a162 | 17 | // These timings are well within the +/-150ns tolerance specified by WS2812. |
JacobBramley | 0:38eeab21a162 | 18 | |
JacobBramley | 0:38eeab21a162 | 19 | spi_.frequency(2400000); |
JacobBramley | 0:38eeab21a162 | 20 | spi_.format(12); // Send four NeoPixel bits in each packet. |
JacobBramley | 0:38eeab21a162 | 21 | } |
JacobBramley | 0:38eeab21a162 | 22 | |
JacobBramley | 0:38eeab21a162 | 23 | static void SendFourBits(BurstSPI& spi, uint32_t bits) { |
JacobBramley | 0:38eeab21a162 | 24 | static int const pattern_width = 3; |
JacobBramley | 0:38eeab21a162 | 25 | uint32_t word = 04444; // 0b100100100100 |
JacobBramley | 0:38eeab21a162 | 26 | |
JacobBramley | 0:38eeab21a162 | 27 | for (int i = 0; i < 4; i++) { |
JacobBramley | 0:38eeab21a162 | 28 | word |= ((bits >> 3) & 1) << (pattern_width * i + 1); |
JacobBramley | 0:38eeab21a162 | 29 | } |
JacobBramley | 0:38eeab21a162 | 30 | |
JacobBramley | 0:38eeab21a162 | 31 | spi.fastWrite(word); |
JacobBramley | 0:38eeab21a162 | 32 | } |
JacobBramley | 0:38eeab21a162 | 33 | |
JacobBramley | 0:38eeab21a162 | 34 | void Array::Update(Pixel buffer[], size_t length) { |
JacobBramley | 0:38eeab21a162 | 35 | // Pixels are sent as follows: |
JacobBramley | 0:38eeab21a162 | 36 | // - The first transmitted pixel is the pixel closest to the transmitter. |
JacobBramley | 0:38eeab21a162 | 37 | // - The most significant bit is always sent first. |
JacobBramley | 0:38eeab21a162 | 38 | // - Green is sent first, then red, then blue. |
JacobBramley | 0:38eeab21a162 | 39 | // |
JacobBramley | 0:38eeab21a162 | 40 | // g7,g6,g5,g4,g3,g2,g1,g0,r7,r6,r5,r4,r3,r2,r1,r0,b7,b6,b5,b4,b3,b2,b1,b0 |
JacobBramley | 0:38eeab21a162 | 41 | // \ / |
JacobBramley | 0:38eeab21a162 | 42 | // \___________________________________________________________________/ |
JacobBramley | 0:38eeab21a162 | 43 | // | |
JacobBramley | 0:38eeab21a162 | 44 | // GRB,GRB,GRB,GRB,... |
JacobBramley | 0:38eeab21a162 | 45 | |
JacobBramley | 0:38eeab21a162 | 46 | for (size_t i = 0; i < length; i++) { |
JacobBramley | 0:38eeab21a162 | 47 | SendFourBits(spi_, (buffer[i].green >> 4) & 0xf); |
JacobBramley | 0:38eeab21a162 | 48 | SendFourBits(spi_, (buffer[i].green >> 0) & 0xf); |
JacobBramley | 0:38eeab21a162 | 49 | SendFourBits(spi_, (buffer[i].red >> 4) & 0xf); |
JacobBramley | 0:38eeab21a162 | 50 | SendFourBits(spi_, (buffer[i].red >> 0) & 0xf); |
JacobBramley | 0:38eeab21a162 | 51 | SendFourBits(spi_, (buffer[i].blue >> 4) & 0xf); |
JacobBramley | 0:38eeab21a162 | 52 | SendFourBits(spi_, (buffer[i].blue >> 0) & 0xf); |
JacobBramley | 0:38eeab21a162 | 53 | } |
JacobBramley | 0:38eeab21a162 | 54 | spi_.clearRX(); |
JacobBramley | 0:38eeab21a162 | 55 | |
JacobBramley | 0:38eeab21a162 | 56 | wait_us(50); |
JacobBramley | 0:38eeab21a162 | 57 | } |
JacobBramley | 0:38eeab21a162 | 58 | |
JacobBramley | 0:38eeab21a162 | 59 | } |