/* This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ /* This library allows to control WS2812B LEDs * it uses timer 0 with interruts */ #include // Standard Integer Types #include // Standard IO facilities #include // General utilities #include // boolean type #include // AVR device-specific IO definitions #include // Interrupts #include "ws2812b.h" // WS2812B header /* has the WS2812B been initialized correctly */ bool initialized = false; /* the green, red, and blue (8 bits each) bit values for each LEDs */ uint8_t color_bits[3*8*WS2812B_NB_LEDS] = {0}; /* how much to shift for which channel */ uint8_t channel_shifts[WS2812B_NB_CHANNELS] = {0}; /* have the 50 us reset code timeout passed */ volatile bool reset_code = true; /* initialize */ bool ws2812b_init() { initialized = false; /* verify we are running with 16 MHz */ if (F_CPU != 16000000) { return initialized; // the code has been designed for 16 MHz } /* verify there are LEDs to use */ if (WS2812B_NB_LEDS==0) { return initialized; // there in no data to send } /* generate the channel shift depending on mask*/ uint8_t channel = 0; for (uint8_t shift=0; shift<8; shift++) { if ( (WS2812B_MASK>>shift)&0x01 ) { channel_shifts[channel++] = shift; } } /* verify the number of channels corresponds to the mask */ if (WS2812B_NB_CHANNELS!=channel) { return initialized; // the number of channels does not match the mask } WS2812B_DDR |= WS2812B_MASK; // set pins as output /* user timer 0 to time the reset code of 50 us */ TCCR0B |= (0<=WS2812B_NB_CHANNELS) { return false; } if (led>=WS2812B_NB_LEDS) { return false; } /* set color values * composition of 24bit data: G7..G0,R7..R0,B7..B0 * high bit is sent first * LEDs keep the first values and forward the next */ for (uint8_t i=0; i<8; i++) { uint8_t color_bit = 1<<(7-i); if (green&color_bit) { color_bits[8*3*led+i] |= (1<