WS2812 LED driver

Dependents:   WS2812-Example WS2812-Example WS2812-Example

Committer:
fastestoffer
Date:
Wed Nov 18 14:00:44 2015 +0000
Revision:
0:f1e39d76fbca
Initial commit of WS2812 LED driver

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fastestoffer 0:f1e39d76fbca 1 #include "WS2812.h"
fastestoffer 0:f1e39d76fbca 2
fastestoffer 0:f1e39d76fbca 3 #define WS2812_ONE (3<<2)
fastestoffer 0:f1e39d76fbca 4 #define WS2812_ZERO (1<<3)
fastestoffer 0:f1e39d76fbca 5
fastestoffer 0:f1e39d76fbca 6 typedef struct {
fastestoffer 0:f1e39d76fbca 7 uint8_t g[4];
fastestoffer 0:f1e39d76fbca 8 uint8_t r[4];
fastestoffer 0:f1e39d76fbca 9 uint8_t b[4];
fastestoffer 0:f1e39d76fbca 10 } led_pixel_wire_data;
fastestoffer 0:f1e39d76fbca 11
fastestoffer 0:f1e39d76fbca 12 WS2812::WS2812(SPI &spi, event_callback_t led_update_strip_finished):
fastestoffer 0:f1e39d76fbca 13 _spi(spi),
fastestoffer 0:f1e39d76fbca 14 _led_data_size(WS2812_LED_NUM_LEDS*12 + WS2812_LED_NUM_RESET_BYTES),
fastestoffer 0:f1e39d76fbca 15 _led_update_strip_finished(led_update_strip_finished)
fastestoffer 0:f1e39d76fbca 16 {
fastestoffer 0:f1e39d76fbca 17 //Setup SPI for WS2812
fastestoffer 0:f1e39d76fbca 18 _spi.format(8,0);
fastestoffer 0:f1e39d76fbca 19 _spi.frequency(3000000);
fastestoffer 0:f1e39d76fbca 20 _spi.set_dma_usage(DMA_USAGE_ALWAYS);
fastestoffer 0:f1e39d76fbca 21
fastestoffer 0:f1e39d76fbca 22 //Initialize led data buffer to zero
fastestoffer 0:f1e39d76fbca 23 memset(_led_data, 0, _led_data_size);
fastestoffer 0:f1e39d76fbca 24 }
fastestoffer 0:f1e39d76fbca 25
fastestoffer 0:f1e39d76fbca 26 void WS2812::update_strip() {
fastestoffer 0:f1e39d76fbca 27 //Initiate transfer of led data buffer through SPI
fastestoffer 0:f1e39d76fbca 28 this->_spi.transfer(this->_led_data, this->_led_data_size, (uint8_t *)NULL, 0, this->_led_update_strip_finished);
fastestoffer 0:f1e39d76fbca 29 }
fastestoffer 0:f1e39d76fbca 30
fastestoffer 0:f1e39d76fbca 31 //Write same color to all leds
fastestoffer 0:f1e39d76fbca 32 void WS2812::set_all(Color *c) {
fastestoffer 0:f1e39d76fbca 33 for(int i=0; i<WS2812_LED_NUM_LEDS; i++)
fastestoffer 0:f1e39d76fbca 34 {
fastestoffer 0:f1e39d76fbca 35 this->set_led(i, c);
fastestoffer 0:f1e39d76fbca 36 }
fastestoffer 0:f1e39d76fbca 37 }
fastestoffer 0:f1e39d76fbca 38
fastestoffer 0:f1e39d76fbca 39 //Write color to led_number (a single led on the strip)
fastestoffer 0:f1e39d76fbca 40 //led_number range is [0,WS2812_LED_NUM_LEDS - 1]
fastestoffer 0:f1e39d76fbca 41 void WS2812::set_led(int led_number, Color *c)
fastestoffer 0:f1e39d76fbca 42 {
fastestoffer 0:f1e39d76fbca 43 uint8_t *ledptr;
fastestoffer 0:f1e39d76fbca 44 uint32_t offset;
fastestoffer 0:f1e39d76fbca 45 led_pixel_wire_data *led_pixel_data_ptr;
fastestoffer 0:f1e39d76fbca 46
fastestoffer 0:f1e39d76fbca 47 offset = led_number * 12;
fastestoffer 0:f1e39d76fbca 48 ledptr = &(this->_led_data[offset]);
fastestoffer 0:f1e39d76fbca 49 led_pixel_data_ptr = (led_pixel_wire_data*)ledptr;
fastestoffer 0:f1e39d76fbca 50
fastestoffer 0:f1e39d76fbca 51 /*************** GREEN value first (see datasheet) **********************/
fastestoffer 0:f1e39d76fbca 52 _write_color_to_memory(led_pixel_data_ptr->g, c->g);
fastestoffer 0:f1e39d76fbca 53
fastestoffer 0:f1e39d76fbca 54 /*************** RED value second (see datasheet) ***********************/
fastestoffer 0:f1e39d76fbca 55 _write_color_to_memory(led_pixel_data_ptr->r, c->r);
fastestoffer 0:f1e39d76fbca 56
fastestoffer 0:f1e39d76fbca 57 /*************** BLUE value last (see datasheet) ************************/
fastestoffer 0:f1e39d76fbca 58 _write_color_to_memory(led_pixel_data_ptr->b, c->b);
fastestoffer 0:f1e39d76fbca 59
fastestoffer 0:f1e39d76fbca 60 }
fastestoffer 0:f1e39d76fbca 61
fastestoffer 0:f1e39d76fbca 62 //Write one channel of the color (R, G or B) to its in-memory representation
fastestoffer 0:f1e39d76fbca 63 void WS2812::_write_color_to_memory(uint8_t tuple[], uint8_t color_value)
fastestoffer 0:f1e39d76fbca 64 {
fastestoffer 0:f1e39d76fbca 65 uint8_t byte = 0, nibble = 0, bitval = 0;
fastestoffer 0:f1e39d76fbca 66
fastestoffer 0:f1e39d76fbca 67 /* For each bit in the color value, convert it to a corresponding one or a zero in-memory value */
fastestoffer 0:f1e39d76fbca 68 for(byte = 0; byte < 4; byte++) {
fastestoffer 0:f1e39d76fbca 69 tuple[3-byte] = 0;
fastestoffer 0:f1e39d76fbca 70 for(nibble = 0; nibble < 2; nibble++) {
fastestoffer 0:f1e39d76fbca 71 bitval = (color_value >> ((byte*2)+nibble)) & 0x1;
fastestoffer 0:f1e39d76fbca 72 bitval = bitval ? WS2812_ONE : WS2812_ZERO;
fastestoffer 0:f1e39d76fbca 73
fastestoffer 0:f1e39d76fbca 74 tuple[3-byte] |= bitval << (nibble*4);
fastestoffer 0:f1e39d76fbca 75 }
fastestoffer 0:f1e39d76fbca 76 }
fastestoffer 0:f1e39d76fbca 77 }