Ulozeni kodu
This commit is contained in:
parent
fbc32db3fd
commit
69a5b37616
104
src/NeoPixelesp8266.c
Normal file
104
src/NeoPixelesp8266.c
Normal file
@ -0,0 +1,104 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
NeoPixel library helper functions for Esp8266 and Esp32.
|
||||
|
||||
Written by Michael C. Miller.
|
||||
|
||||
I invest time and resources providing this open source code,
|
||||
please support me by dontating (see https://github.com/Makuna/NeoPixelBus)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
This file is part of the Makuna/NeoPixelBus library.
|
||||
|
||||
NeoPixelBus is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
NeoPixelBus 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with NeoPixel. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
#include <Arduino.h>
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
#include <eagle_soc.h>
|
||||
#endif
|
||||
|
||||
// ESP32 doesn't define ICACHE_RAM_ATTR
|
||||
#ifndef ICACHE_RAM_ATTR
|
||||
#define ICACHE_RAM_ATTR IRAM_ATTR
|
||||
#endif
|
||||
|
||||
inline uint32_t _getCycleCount()
|
||||
{
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
//#define CYCLES_800_T0H (F_CPU / 2500000) // 0.4us
|
||||
//#define CYCLES_800_T1H (F_CPU / 1250000) // 0.8us
|
||||
//#define CYCLES_800 (F_CPU / 800000) // 1.25us per bit
|
||||
#define CYCLES_800_T0H (F_CPU / 2600000) // 0.4us
|
||||
#define CYCLES_800_T1H (F_CPU / 1350000) // 0.8us
|
||||
#define CYCLES_800 (F_CPU / 900000) // 1.25us per bit
|
||||
|
||||
void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixels, size_t count, uint8_t pin)
|
||||
{
|
||||
const uint32_t pinRegister = _BV(pin);
|
||||
uint8_t mask;
|
||||
uint8_t subpix;
|
||||
uint32_t cyclesStart;
|
||||
uint8_t *end = pixels + (3 * count);
|
||||
|
||||
// trigger emediately
|
||||
cyclesStart = _getCycleCount() - CYCLES_800;
|
||||
do
|
||||
{
|
||||
subpix = *pixels++;
|
||||
for (mask = 0x80; mask != 0; mask >>= 1)
|
||||
{
|
||||
// do the checks here while we are waiting on time to pass
|
||||
uint32_t cyclesBit = ((subpix & mask)) ? CYCLES_800_T1H : CYCLES_800_T0H;
|
||||
uint32_t cyclesNext = cyclesStart;
|
||||
|
||||
// after we have done as much work as needed for this next bit
|
||||
// now wait for the HIGH
|
||||
do
|
||||
{
|
||||
// cache and use this count so we don't incur another
|
||||
// instruction before we turn the bit high
|
||||
cyclesStart = _getCycleCount();
|
||||
} while ((cyclesStart - cyclesNext) < CYCLES_800);
|
||||
|
||||
// set high
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
GPIO.out_w1ts = pinRegister;
|
||||
#else
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinRegister);
|
||||
#endif
|
||||
|
||||
// wait for the LOW
|
||||
do
|
||||
{
|
||||
cyclesNext = _getCycleCount();
|
||||
} while ((cyclesNext - cyclesStart) < cyclesBit);
|
||||
|
||||
// set low
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
GPIO.out_w1tc = pinRegister;
|
||||
#else
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinRegister);
|
||||
#endif
|
||||
}
|
||||
} while (pixels < end);
|
||||
}
|
||||
|
||||
#endif
|
145
src/wsLED.cpp
Normal file
145
src/wsLED.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
// Ovladani signalizacni chytre LED diody
|
||||
#include "wsLED.h"
|
||||
// due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are
|
||||
// moved into a C file so the attribute will be applied correctly
|
||||
extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixel, size_t count, uint8_t pin);
|
||||
|
||||
#define countof(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
static const uint16_t LB[] PROGMEM = {
|
||||
0x201 , 0x202 , 0x103 , 0x104 , 0x105 , 0x106 , 0x107 , 0x109 , 0x10a , 0x10c , 0x10e , 0x110 , 0x112 , 0x114 , 0x116 , 0x119 , 0x11c , 0x11e , 0x122 , 0x125 , 0x128 , 0x12c , 0x130 , 0x134,
|
||||
0x139 , 0x13d , 0x142 , 0x147 , 0x14d , 0x152 , 0x158 , 0x15e , 0x165 , 0x16b , 0x172 , 0x179 , 0x180 , 0x187 , 0x18e , 0x196 , 0x19d , 0x1a5 , 0x1ac , 0x1b3 , 0x1bb , 0x1c2 , 0x1c9 , 0x1cf,
|
||||
0x1d6 , 0x1dc , 0x1e2 , 0x1e7 , 0x1ec , 0x1f0 , 0x1f4 , 0x1f7 , 0x1fa , 0x1fc , 0x1fd , 0x3fe , 0x1fd , 0x1fb , 0x1f8 , 0x1f5 , 0x1f2 , 0x1ed , 0x1e9 , 0x1e4 , 0x1de , 0x1d8 , 0x1d2 , 0x1cb,
|
||||
0x1c4 , 0x1bd , 0x1b6 , 0x1af , 0x1a7 , 0x1a0 , 0x198 , 0x191 , 0x18a , 0x182 , 0x17b , 0x174 , 0x16d , 0x167 , 0x161 , 0x15a , 0x154 , 0x14f , 0x149 , 0x144 , 0x13f , 0x13a , 0x136 , 0x131,
|
||||
0x12d , 0x12a , 0x126 , 0x123 , 0x11f , 0x11c , 0x11a , 0x117 , 0x115 , 0x112 , 0x110 , 0x10e , 0x10c , 0x10b , 0x109 , 0x108 , 0x107 , 0x105 , 0x104 , 0x203 , 0x102 , 0x201 , 0x2a00
|
||||
};
|
||||
|
||||
inline bool wsLED::canShow(void)
|
||||
{
|
||||
|
||||
return (micros() - _endtime) >= 50L;
|
||||
}
|
||||
|
||||
void wsLED::show(void)
|
||||
{
|
||||
uint8_t color[3];
|
||||
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
// https://github.com/FastLED/FastLED/wiki/FastLED-Color-Correction
|
||||
uint16_t c = (uint16_t)_color[i] * (1 + (uint16_t)_scale);
|
||||
color[i] = (uint8_t)(c >> 8);
|
||||
}
|
||||
while (!canShow())
|
||||
__asm__ volatile ("nop");
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
uint32_t volatile register ilevel = XTOS_DISABLE_ALL_INTERRUPTS;
|
||||
#else
|
||||
noInterrupts();
|
||||
//cli();
|
||||
#endif
|
||||
send_pixels_800(color, 1, _pin);
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
XTOS_RESTORE_INTLEVEL(ilevel);
|
||||
#else
|
||||
interrupts();
|
||||
//sei();
|
||||
#endif
|
||||
_endtime = micros();
|
||||
}
|
||||
|
||||
|
||||
wsLED::wsLED(int pin, int order)
|
||||
{
|
||||
|
||||
_pin = pin;
|
||||
_order = order;
|
||||
}
|
||||
|
||||
void wsLED::begin(void)
|
||||
{
|
||||
|
||||
pinMode(_pin, OUTPUT);
|
||||
_color[0] = _color[1] = _color[2] = 0;
|
||||
show();
|
||||
}
|
||||
|
||||
void wsLED::setColor(LEDRGB &color)
|
||||
{
|
||||
|
||||
_color[(_order >> 6) & 7] = color.r;
|
||||
_color[(_order >> 3) & 7] = color.g;
|
||||
_color[_order & 7] = color.b;
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR wsLED::rtLed(void)
|
||||
{
|
||||
|
||||
switch (_ledState) {
|
||||
case LED_BLINK:
|
||||
_scale = 0xff;
|
||||
if (_subState) {
|
||||
_subState = 0;
|
||||
setColor(_color2);
|
||||
} else {
|
||||
_subState = 1;
|
||||
setColor(_color1);
|
||||
}
|
||||
show();
|
||||
break;
|
||||
|
||||
|
||||
case LED_BREATH: {
|
||||
++_subState;
|
||||
_subState %= countof(LB);
|
||||
uint16_t val = pgm_read_word(&LB[_subState]);
|
||||
_scale = (uint8_t)val;
|
||||
show();
|
||||
val >>= 8;
|
||||
_handler.attach_ms(30ul * val, lh, this);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
_handler.attach_ms(300, lh, this); // jen pomale casovani
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR wsLED::lh(wsLED *ptr)
|
||||
{
|
||||
|
||||
wsLED *pled = ptr;
|
||||
pled->rtLed();
|
||||
}
|
||||
|
||||
void wsLED::setColors(LEDRGB color1, LEDRGB color2)
|
||||
{
|
||||
|
||||
_color1 = color1;
|
||||
_color2 = color2;
|
||||
}
|
||||
|
||||
void wsLED::blink(int speed)
|
||||
{
|
||||
|
||||
_handler.detach();
|
||||
_ledState = LED_BLINK;
|
||||
_subState = 1;
|
||||
_handler.attach_ms(300, lh, this);
|
||||
}
|
||||
|
||||
void wsLED::breath(void)
|
||||
{
|
||||
|
||||
_handler.detach();
|
||||
_ledState = LED_BREATH;
|
||||
_subState = 0;
|
||||
setColor(_color1);
|
||||
_handler.attach_ms(1, lh, this);
|
||||
}
|
||||
|
||||
void wsLED::setOrder(int neworder)
|
||||
{
|
||||
|
||||
_order = neworder;
|
||||
}
|
151
src/wsLED.h
Normal file
151
src/wsLED.h
Normal file
@ -0,0 +1,151 @@
|
||||
// Ovladani RGB WS2812 LED diody pro signalizacni ucely
|
||||
/**The MIT License (MIT)
|
||||
Copyright (c) 2017,2020 by Pavel Brychta
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
See more at http://www.xpablo.cz
|
||||
*/
|
||||
|
||||
#ifndef __WSLED_H__
|
||||
#define __WSLED_H__
|
||||
#include <Arduino.h>
|
||||
#include <Ticker.h>
|
||||
|
||||
struct LEDRGB {
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
uint8_t r;
|
||||
uint8_t red;
|
||||
};
|
||||
union {
|
||||
uint8_t g;
|
||||
uint8_t green;
|
||||
};
|
||||
union {
|
||||
uint8_t b;
|
||||
uint8_t blue;
|
||||
};
|
||||
};
|
||||
uint8_t raw[3];
|
||||
};
|
||||
|
||||
// Array access operator to index into the crgb object
|
||||
inline uint8_t& operator[] (uint8_t x) __attribute__((always_inline))
|
||||
{
|
||||
return raw[x];
|
||||
}
|
||||
|
||||
// Array access operator to index into the crgb object
|
||||
inline const uint8_t& operator[] (uint8_t x) const __attribute__((always_inline))
|
||||
{
|
||||
return raw[x];
|
||||
}
|
||||
|
||||
// default values are UNINITIALIZED
|
||||
inline LEDRGB() __attribute__((always_inline))
|
||||
{
|
||||
}
|
||||
|
||||
// allow construction from R, G, B
|
||||
inline LEDRGB( uint8_t ir, uint8_t ig, uint8_t ib) __attribute__((always_inline))
|
||||
: r(ir), g(ig), b(ib)
|
||||
{
|
||||
}
|
||||
|
||||
// allow construction from 32-bit (really 24-bit) bit 0xRRGGBB color code
|
||||
inline LEDRGB( uint32_t colorcode) __attribute__((always_inline))
|
||||
: r((colorcode >> 16) & 0xFF), g((colorcode >> 8) & 0xFF), b((colorcode >> 0) & 0xFF)
|
||||
{
|
||||
}
|
||||
|
||||
// allow copy construction
|
||||
inline LEDRGB(const LEDRGB& rhs) __attribute__((always_inline))
|
||||
{
|
||||
r = rhs.r;
|
||||
g = rhs.g;
|
||||
b = rhs.b;
|
||||
}
|
||||
|
||||
// allow assignment from one RGB struct to another
|
||||
inline LEDRGB& operator= (const LEDRGB& rhs) __attribute__((always_inline))
|
||||
{
|
||||
r = rhs.r;
|
||||
g = rhs.g;
|
||||
b = rhs.b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// allow assignment from 32-bit (really 24-bit) 0xRRGGBB color code
|
||||
inline LEDRGB& operator= (const uint32_t colorcode) __attribute__((always_inline))
|
||||
{
|
||||
r = (colorcode >> 16) & 0xFF;
|
||||
g = (colorcode >> 8) & 0xFF;
|
||||
b = (colorcode >> 0) & 0xFF;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// allow assignment from R, G, and B
|
||||
inline LEDRGB& setRGB (uint8_t nr, uint8_t ng, uint8_t nb) __attribute__((always_inline))
|
||||
{
|
||||
r = nr;
|
||||
g = ng;
|
||||
b = nb;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
enum ColorOrder {
|
||||
RGB = 0012,
|
||||
GRB = 0102
|
||||
};
|
||||
|
||||
class wsLED
|
||||
{
|
||||
protected:
|
||||
int _pin; // pin, na kterem je LED pripojena
|
||||
LEDRGB _color1;
|
||||
LEDRGB _color2;
|
||||
int _order; // ColorOrder
|
||||
uint32_t _endtime;
|
||||
uint8_t _scale;
|
||||
uint8_t _color[3];
|
||||
Ticker _handler;
|
||||
enum {
|
||||
LED_STOP = 0,
|
||||
LED_BLINK,
|
||||
LED_BREATH,
|
||||
LED_PATTERN,
|
||||
} _ledState; // stav LEDky (blika, dycha, ...)
|
||||
int _subState; // pomocny stav/index v poli dychani
|
||||
|
||||
bool canShow(void);
|
||||
void show(void);
|
||||
void setColor(LEDRGB &color);
|
||||
|
||||
public:
|
||||
wsLED(int pin, int order = RGB);
|
||||
void begin(void);
|
||||
static void lh(wsLED *ptr);
|
||||
void rtLed(void); // vykonna metoda
|
||||
void setColors(LEDRGB color1, LEDRGB color2 = LEDRGB(0, 0, 0));
|
||||
void blink(int speed = 300);
|
||||
void breath(void);
|
||||
void setOrder(int neworder);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user