Kenji Arai / WS2812

Dependents:   WS2812_out_of_specification_demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WS2812.cpp Source File

WS2812.cpp

00001 /*
00002     Modified by Kenji Arai / JH1PJL
00003         March 20th, 2020
00004  */
00005 
00006 #include "WS2812.h"
00007 
00008 WS2812::WS2812(PinName mosi, PinName miso, PinName sclk, int size)
00009     : __spi(mosi, miso, sclk)
00010 {
00011     __size = size;
00012     __spi.format(SPIBPF,0);
00013     __spi.frequency(SPICLK);
00014      __mode = OFF;      // 0=off,1=use global,2=per pixel
00015      __br = 0xFF;       // set global Brightness to full
00016 }
00017 
00018 WS2812::~WS2812 () {;}
00019 
00020 void WS2812::write(int buf[])
00021 {
00022     // for each of the data points in the buffer
00023     for (int i = 0; i < __size ; i++) {
00024         __write(buf[i]);
00025     }
00026 }
00027 
00028 void WS2812::write_offsets(int buf[], int r_offset, int g_offset, int b_offset)
00029 {
00030     // for each of the data points in the buffer
00031     for (int i = 0; i < __size ; i++) {
00032         int color_one = 0x0;
00033         // index and extract color fields from IIRRGGBB buf[]
00034         // 0 = blue, 1 = green, 2 = red, 3 = brightness
00035         color_one |= (buf[(i+b_offset)%__size] & 0x000000ff);
00036         color_one |= (buf[(i+g_offset)%__size] & 0x0000ff00);
00037         color_one |= (buf[(i+r_offset)%__size] & 0x00ff0000);
00038         color_one |= (buf[i] & 0xff000000);
00039         __write(color_one);
00040     }
00041 }
00042 
00043 void WS2812::setAll(int color)
00044 {
00045     int color_one = ( __br << 24) | color;
00046     // for each of the data points in the buffer
00047     for (int i = 0; i < __size ; i++) {
00048         __write(color_one);
00049     }
00050 }
00051 
00052 void WS2812::set_brightness_mode(BrightnessControl mode)
00053 {
00054      __mode = mode;
00055 }
00056 
00057 void WS2812::set_brightness(unsigned char br)
00058 {
00059      __br = br;
00060 }
00061 
00062 void WS2812::__write(int color)
00063 {
00064     // Input format(color)  :   GGRRBB
00065     // Output format(agrb)  : IIRRGGBB
00066     unsigned char agrb[4];
00067     unsigned char sf;           // scaling factor for  II
00068     // extract color fields from incoming
00069     // 0 = blue, 1 = red, 2 = green, 3 = brightness
00070     agrb[0] = (unsigned char)color;
00071     agrb[1] = (unsigned char)((color & 0x00ff0000) >> 16);
00072     agrb[2] = (unsigned char)((color & 0x0000ff00) >>  8);
00073     agrb[3] = (unsigned char)((color & 0xff000000) >> 24);
00074     // set and intensity scaling factor (global, per pixel, none = Max)
00075     if ( __mode == GLOBAL) {
00076         sf =  __br;
00077     } else if ( __mode == PER_PIXEL) {
00078         sf = agrb[3];
00079     } else {
00080         sf = 0xff;
00081     }
00082     // Input format(agrb[4])  : IIRRGGBB
00083     // Output format(agrb[3]) : RR*II, GG*II, BB*II
00084     // Apply the scaling factor to each on the color components
00085     for (int clr = 2; clr >= 0; clr--) {
00086         agrb[clr] = (agrb[clr] * sf) >> 8;
00087     }
00088     // For each color component G,R,B
00089     // shift out the data 7..0, writing a SPI frame per bit
00090     // green=2,red=1,blue=0,
00091     char bit_ptn[8] = {1, 2, 4, 8, 16, 32, 64, 128};
00092     for (int32_t clr = 2; clr >= 0; clr--) {
00093         unsigned char dt = agrb[clr];
00094         for (int32_t bit = 7 ; bit >= 0 ; bit--) {
00095             if (dt & bit_ptn[bit]) {
00096                 __spi.write(WS1);
00097             } else {
00098                 __spi.write(WS0);
00099             }
00100             // debug purpose
00101             //wait_us(30);
00102         }
00103     }
00104 }