// led.ch.txt (ver 8/11/18) ws2812 rgb led driver /* ledRGB.h */ #ifndef _ledRGB_h #define _ledRGB_h #ifdef CONFIG_RGB_LED void ledRGBInit(void); void ledRGBTask(void); void ledSetColor(U8 r, U8 g, U8 b); #else /* CONFIG_RGB_LED */ #define ledRGBInit() #define ledRGBTask() #define ledSetColor(r,g,b) #endif /* CONFIG_RGB_LED */ #endif /* _ledRGB_h */ /* ledRGB.c */ #include #include "compiler_defs.h" #include "processor.h" #include "config.h" #include "main.h" #include "ledRGB.h" // 150 + 350 + 300 + 150 + 300 = 1250 #define BIT(color) P3_0 = 0, \ P3_0 = (color & 0x80), \ P3_0 = (color & 0x80), \ P3_0 = 1, \ color = color << 1 #ifdef CONFIG_RGB_LED // use P3_0 C8051F381 24MHz to form bit one/zero timing void ledRGB(U8 red, U8 grn, U8 blu) { // bits inverted bit savedEA; // ws2812 rgb spec timing (+- 150) // /350\900/ /200\1050/ /500\750/ // 350 550+350 200 850+200 500 550+500 // // 2 4 2 // ___|___|____| |___ // ___/ 1 \__0__\___/___ // 350 550 350 1.25 uSec // // 2 4 2 // 250 600 250 1.10 uSec // 450 500 450 1.40 uSec // 3 3 3 // twiddle code produces 0.133 uSec per bit timing // (1,1,0,0,0,0,0,0,0) 250 + 950 min // one (1,1,1,0,0,0,0,0,0) 400 + 800 // zero (1,1,1,1,1,1,0,0,0) 800 + 400 // (1,1,1,1,1,1,1,0,0) 950 + 250 min // for led in grn red blu // color order // for msb thru lsb // and bit order savedEA = EA; EA = 0; BIT(grn); // msb BIT(grn); BIT(grn); BIT(grn); // 654 BIT(grn); BIT(grn); BIT(grn); // 321 BIT(grn); // lsb BIT(red); // msb BIT(red); BIT(red); BIT(red); // 654 BIT(red); BIT(red); BIT(red); // 321 BIT(red); // lsb BIT(blu); // msb BIT(blu); BIT(blu); BIT(blu); // 654 BIT(blu); BIT(blu); BIT(blu); // 321 BIT(blu); // lsb EA = savedEA; } static struct { enum {idleLS, enableLS} state; U8 red; U8 grn; U8 blu; U8 updateReq; } xdata rgb; void ledRGBInit(void) { memset(&rgb, 0, sizeof(rgb)); rgb.updateReq = 0; rgb.red = 0xff; rgb.grn = 0xff; rgb.blu = 0xff; rgb.state = idleLS; } void ledSetColor(U8 r, U8 g, U8 b) { rgb.red = r; rgb.grn = g; rgb.blu = b; rgb.updateReq = 1; } void ledRGBTask(void) { switch (rgb.state) { case idleLS: if (rgb.updateReq) { // initiate led color change rgb.state = enableLS; } break; case enableLS: // bit bang ws2812 rgb led ledRGB(rgb.red,rgb.grn,rgb.blu); rgb.state = idleLS; break; } } #endif /* CONFIG_RGB_LED */