ws2812b sample firmware.
Dependencies: BurstSPI
Dependents: mbed_ws2812b mbed_ws2812b
Fork of PixelArray by
neopixel.h
00001 #ifndef NEOPIXEL_H 00002 #define NEOPIXEL_H 00003 00004 #include <stdint.h> 00005 #include "mbed.h" 00006 #include "BurstSPI.h" 00007 00008 namespace neopixel 00009 { 00010 00011 /** Represent the value of a single pixel. 00012 * 00013 * Each channel uses the full 8 bits: 0x00 is fully off and 0xff is fully on. 00014 */ 00015 struct Pixel { 00016 uint8_t red; 00017 uint8_t green; 00018 uint8_t blue; 00019 }; 00020 00021 /** Control the byte order used by the connected pixels. 00022 * 00023 * The vast majority of NeoPixels use a GRB byte order, so this is the default. 00024 * A few use a RGB byte order. 00025 * 00026 * In principle, the WS281x controllers could be connected with _any_ byte 00027 * ordering, but only GRB and RGB are supported at the moment. 00028 */ 00029 enum ByteOrder { 00030 BYTE_ORDER_GRB, 00031 BYTE_ORDER_RGB, 00032 }; 00033 00034 /** Set the protocol mode. 00035 * 00036 * The protocol is named after the clock, as though WS8211 supports only the 00037 * 400kHz clock, WS8212 supports both. 00038 */ 00039 enum Protocol { 00040 PROTOCOL_800KHZ, 00041 PROTOCOL_400KHZ, 00042 }; 00043 00044 typedef void (*PixelGenerator)(Pixel* out, uint32_t index, uintptr_t extra); 00045 00046 /** Control an array or chain of NeoPixel-compatible RGB LEDs. 00047 * 00048 * "NeoPixel" is Adafruit's name for WS2812- and WS2811-based addressable RGB 00049 * LEDs. This library should work with any WS2811- or WS2812-based devices, as 00050 * long as they support the fast-mode (800kHz) interface. 00051 * 00052 * Most example code uses bit-banging to generate the timed signal precisely. 00053 * This library uses an SPI peripheral instead. The main advantage of this is 00054 * that the chip can service interrupts and the like without disrupting the 00055 * signal (as long as the interrupts don't take _too_ long). The main 00056 * disadvantage is that it requires the use of an SPI peripheral. 00057 * 00058 * @note SPI peripherals will tend to leave the output pin ('MOSI') floating 00059 * after a packet is sent. This will confuse the connected pixels, which expect 00060 * the line to be driven low when idle. One way to fix this is to add a 10k 00061 * resistor between 'MOSI' and ground so that it drops to '0' when not driven. 00062 * Another method is to enable the on-chip pull-down resistor on the output pin. 00063 * However, the mbed API only exposes this function through the DigitalIn and 00064 * DigitalInOut classes. If you want to use the on-chip pull-down, you'll have 00065 * to temporarily connect a DigitalIn peripheral _before_ creating instantiating 00066 * the PixelArray. 00067 * 00068 * @code 00069 * // Sample generator: Cycle through each colour combination, increasing the 00070 * // brightness each time. `extra` is used as an iteration counter. 00071 * void generate(neopixel::Pixel * out, uint32_t index, uintptr_t extra) { 00072 * uint32_t brightness = (index + extra) >> 3; 00073 * out->red = ((index + extra) & 0x1) ? brightness : 0; 00074 * out->green = ((index + extra) & 0x2) ? brightness : 0; 00075 * out->blue = ((index + extra) & 0x4) ? brightness : 0; 00076 * } 00077 * 00078 * int main() { 00079 * // Create a temporary DigitalIn so we can configure the pull-down resistor. 00080 * // (The mbed API doesn't provide any other way to do this.) 00081 * // An alternative is to connect an external pull-down resistor. 00082 * DigitalIn(p5, PullDown); 00083 * 00084 * // The pixel array control class. 00085 * neopixel::PixelArray array(p5); 00086 * 00087 * uint32_t offset = 0; 00088 * while (1) { 00089 * array.update(generate, 100, offset++); 00090 * wait_ms(250); 00091 * } 00092 * } 00093 * @endcode 00094 */ 00095 class PixelArray 00096 { 00097 public: 00098 /** Initialize a PixelArray. 00099 * 00100 * @param out Output (SPI MOSI) pin. 00101 * @param byte_order The order in which to transmit colour channels. 00102 */ 00103 PixelArray(PinName out, 00104 ByteOrder byte_order = BYTE_ORDER_GRB, 00105 Protocol protocol = PROTOCOL_800KHZ); 00106 00107 /** Update the pixel display from a buffer. 00108 * 00109 * This update method is good in the following situations: 00110 * - You want to make incremental changes to a fixed frame pattern. 00111 * - The frame is hard (or impossible) to generate procedurally. 00112 * - The frame requires a lot of time to generate. 00113 * 00114 * @param buffer Pixel data to be written. 00115 * @param length The number of pixels to write. 00116 * 00117 * buffer[0] is written to the pixel nearest the mbed. 00118 * buffer[length-1] is written to the pixel furthest from the mbed. 00119 */ 00120 void update(Pixel buffer[], uint32_t length); 00121 00122 /** Update a pixel chain using the callback to generate the value for each 00123 * pixel. 00124 * 00125 * This update method is good in the following situations: 00126 * - You have a lot of pixels to drive and don't have enough RAM to buffer 00127 * them all. 00128 * - You want to display a frame pattern that can be generated procedurally 00129 * generated without intensive processing. 00130 * 00131 * @param generator A callback which is called to generate a value for each 00132 * pixel on demand. This function must be fairly fast: if it takes more 00133 * than about 8-9us, the interface will reset and the display will be 00134 * corrupted. The exact time limits will vary between WS281x variants. As a 00135 * rough guide, an LPC1768 at 96MHz can (conservatively) execute about 750 00136 * instructions in that time. 00137 * 00138 * @param length The number of pixels to write. 00139 * 00140 * @param extra An arbitrary value to pass into the generator function. For 00141 * example, this is a good way to pass an animation time index to the 00142 * generator function. 00143 */ 00144 void update(PixelGenerator generator, uint32_t length, uintptr_t extra); 00145 00146 private: 00147 BurstSPI spi_; 00148 ByteOrder byte_order_; 00149 Protocol protocol_; 00150 00151 static int const latch_time_us_ = 50; 00152 00153 void send_pixel(Pixel& pixel); 00154 }; 00155 00156 } 00157 00158 #endif
Generated on Sun Jul 17 2022 12:50:52 by 1.7.2