Only update of BurstSPI-Library

Dependencies:   BurstSPI

Dependents:   WordClock TI_NEOPIXEL_SPI

Fork of PixelArray by Jacob Bramley

Files at this revision

API Documentation at this revision

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