mirror of
https://github.com/bbulkow/FastLED-idf.git
synced 2025-07-30 18:58:07 +02:00
Make the 4-wire LEDs compile.
Had to pull in far more of the Arduino HAL.
This commit is contained in:
88
README.md
88
README.md
@ -34,7 +34,7 @@ changing the duty cycle and brightness, it doesn't control color-controlled LEDs
|
||||
|
||||
Thus, we need FastLED.
|
||||
|
||||
# Use of ESP32 hardware
|
||||
# Use of ESP32 hardware for 3 wire LEDs
|
||||
|
||||
The ESP32 has an interesting module, called RMT. It's a module that's
|
||||
meant to make arbitrary waveforms on pins, without having to bang each pin at
|
||||
@ -60,6 +60,25 @@ I have not yet validated if this library correctly uses RMT.
|
||||
|
||||
No extra commands in `menuconfig` seem necessary.
|
||||
|
||||
# Four wire LEDs ( APA102 and similar )
|
||||
|
||||
Interestingly, four wire LEDs can't use the RMT interface, because
|
||||
the clock and data lines have to be controled together ( duh ),
|
||||
and the RMT interface doesn't do that. What does do that is the SPI
|
||||
interface, and I don't think I've wired that up.
|
||||
|
||||
There are two hardware SPI ports in the system, so that should be
|
||||
able to be enabled. I haven't tried that.
|
||||
|
||||
Since hardware banging is used ( that's the big ugly warning ),
|
||||
these LEDs are very likely far slower, and probably do not respond to parallelism
|
||||
the same way.
|
||||
|
||||
I have pulled in enough of the HAL for the APA102 code to compile,
|
||||
but I don't know if it works, since I don't have any four-wire LEDs
|
||||
around. Since it's very much a different code path, I'm not going to make
|
||||
promises until someone tries it.
|
||||
|
||||
# async mode
|
||||
|
||||
The right way to use a system like this is with some form of async mode, where the CPU
|
||||
@ -68,27 +87,15 @@ happening. This would allow much better multi-channel work, because the CPU coul
|
||||
one channel, then go off and fill the next channel, etc. For that, you'd have to use
|
||||
the LastLED async interfaces.
|
||||
|
||||
Why do you want to use multiple channels? Apply the FadeCandy algos. The reason the fadecandy
|
||||
is teh awesome is it applies "temporal anti-aliasing", which is to say, it always drives the
|
||||
LEDs at full speed, and when it's trying to display a certain color, it actually displays a blend
|
||||
of other colors. This allows far more resolution than the underlying LED hardware might be
|
||||
capable of.
|
||||
It turns out this all works just peachy, it's just that the FastLED interface is a little
|
||||
peculiar. If you see the THREADING document in this directory, you'll
|
||||
see that this port is enabling multi-channel mode when using 3-wire LEDs,
|
||||
which means you change all the pixels, and when you call FastLED.show(), they'll
|
||||
all bang on the RMT hardware, and use very little main CPU.
|
||||
|
||||
However, it means you need to drive lots of bytes all the time. The fadecandy appears to drive
|
||||
400Khz across its 64-led maximum strings _all the time_. If we did that with this system, one core
|
||||
would drive one string. Sure, we've got two cores, but that's not very fun.
|
||||
|
||||
With an async system, you can drive as many strings as you want in parallel, and let RMT loose.
|
||||
There are only 8 RMT channels, so you can at least get up to the capacity of a single FadeCandy.
|
||||
|
||||
Still - imagine the possibilities. If you're not applying temporal dithering, you can at least have
|
||||
a ton more parallel strings. Instead of being limited to about 1k LEDs saturating an entire core
|
||||
at 30fps with no "temporal dithering", you might be able to get upward of 4k or 8k ( to be measured ).
|
||||
|
||||
In order to do this in the happiest way, you'd like to use FastLED's coordination systems. You'd
|
||||
like an async call to complete using a C feature, to take mutexes because it might be interrupting
|
||||
with the scheduler, or to put a message on one of the message queues for service. Doing all
|
||||
that would be a major expansion of the FastLED interface and would diverge from the "published spec".
|
||||
It would be nicer if FastLED had some sort of Async mode, but that's not
|
||||
really the Arduino way, and this code is meant for arduino. Arduino doesn't
|
||||
have threads of control or message queues or anything like that.
|
||||
|
||||
# A bit about esp-idf
|
||||
|
||||
@ -131,6 +138,10 @@ simply changes the duty cycle on a pin using the RMT interface.
|
||||
It doesn't do pixel color control. It can be an example of using
|
||||
the RMT system, that's it.
|
||||
|
||||
There is an example of LED control, using the RMT interface directly.
|
||||
If you just want to it like that, without all the cool stuff in FastLED,
|
||||
be everyone's guest!
|
||||
|
||||
I did reach out to Espressif. I think they should include or have a FastLED port.
|
||||
In their forums, they said they don't intend to do anything like that.
|
||||
|
||||
@ -342,6 +353,8 @@ Note: what's up with registering the driver? I should, right? Make sure that's d
|
||||
menuconfig? Doen't seem to be. There are no settings anywhere in the menuconfig regarding
|
||||
gpio. Should probably look at the examples to see if I have to enable the ISR or something.
|
||||
|
||||
|
||||
|
||||
## using RMT vs I2S
|
||||
|
||||
Note to self: There is a define in the platforms area that lets a person choose.
|
||||
@ -389,10 +402,9 @@ After looking a bit, it doesn't seem unreasonable to remove all the memmoves and
|
||||
loops. It's been done in other places of the code. Otherwise, one could say "IF GCC8" or something
|
||||
similar, because I bet it really does matter on smaller systems. Maybe even on this one.
|
||||
|
||||
There is a menuconfig to turn off new warnings introduced from GCC6 to GCC8.
|
||||
|
||||
The other thing is to cast these to void, but ewww. Anyone who uses C++ on an embedded system
|
||||
should go whole hog.
|
||||
In the upstream code of FastLED, there is an introduction of a void * cast in these two places.
|
||||
That's the other way of doing it, and the code does "promise" that the classes in question
|
||||
can be memcpy'd. If someone re-ports the code, they could fix this.
|
||||
|
||||
## Don't use C
|
||||
|
||||
@ -400,8 +412,28 @@ Had a main.c , and FastLED.h includes nothing but C++. Therefore, all the source
|
||||
that include FastLED have to be using the C++ compiler, and ESP-IDF has the standard rules
|
||||
for using C for C and CPP for CPP because it's not like they are subsets or something.
|
||||
|
||||
## CXX_STUFF
|
||||
|
||||
There is some really scary code about guards. It is defined if ESP32,
|
||||
and seems to override the way the compiler executes a certain kind of guard.
|
||||
I've turned that off, because I think we should probably trust esp-idf to do the
|
||||
right and best thing for that
|
||||
|
||||
## pulled in too much of the hal
|
||||
|
||||
In order to get 4-wire LEDs compiling, it's necessary to pull in the HAL gpio.c .
|
||||
Just to get one lousy function - pinMode. I probably should
|
||||
have simply had the function call gpio_set_direction(), which is the esp_idf
|
||||
function, directly. If you have a 4-wire system, I left a breadcrumb in the
|
||||
fastpin_esp32 directory. If the alternate code works, then you can take the
|
||||
gpio.c out of the hal compile.
|
||||
|
||||
## message about no hardware SPI pins defined
|
||||
|
||||
This appears widely known to be a warning on ESP32 to go look and see if the RMT system
|
||||
is getting included. Do need to put in some printfs to see if RMT is enabled,
|
||||
and see if the async system works, which would be the cool part of RMT.
|
||||
It's true! There are no hardware SPI pins defined. SPI is used for 4-wire LEDs, where
|
||||
you have to synchronize the clock and data.
|
||||
|
||||
If you have 3-wire LEDs, you'll be using the RMT system, which is super fast anyway.
|
||||
|
||||
The upstream code doesn't seem to use SPI on ESP32 either, so that's just a big hairy
|
||||
todo, and don't worry overmuch.
|
@ -12,6 +12,7 @@ set(srcs
|
||||
"power_mgt.cpp"
|
||||
"wiring.cpp"
|
||||
"hal/esp32-hal-misc.c"
|
||||
"hal/esp32-hal-gpio.c"
|
||||
)
|
||||
|
||||
# everything needs the ESP32 flag, not sure why this won't work
|
||||
|
307
components/FastLED-idf/hal/esp32-hal-gpio.c
Normal file
307
components/FastLED-idf/hal/esp32-hal-gpio.c
Normal file
@ -0,0 +1,307 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "esp32-hal-gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
|
||||
const int8_t esp32_adc2gpio[20] = {36, 37, 38, 39, 32, 33, 34, 35, -1, -1, 4, 0, 2, 15, 13, 12, 14, 27, 25, 26};
|
||||
|
||||
// BB
|
||||
#define GPIO_PIN_COUNT 40
|
||||
|
||||
const DRAM_ATTR esp32_gpioMux_t esp32_gpioMux[GPIO_PIN_COUNT]={
|
||||
{0x44, 11, 11, 1},
|
||||
{0x88, -1, -1, -1},
|
||||
{0x40, 12, 12, 2},
|
||||
{0x84, -1, -1, -1},
|
||||
{0x48, 10, 10, 0},
|
||||
{0x6c, -1, -1, -1},
|
||||
{0x60, -1, -1, -1},
|
||||
{0x64, -1, -1, -1},
|
||||
{0x68, -1, -1, -1},
|
||||
{0x54, -1, -1, -1},
|
||||
{0x58, -1, -1, -1},
|
||||
{0x5c, -1, -1, -1},
|
||||
{0x34, 15, 15, 5},
|
||||
{0x38, 14, 14, 4},
|
||||
{0x30, 16, 16, 6},
|
||||
{0x3c, 13, 13, 3},
|
||||
{0x4c, -1, -1, -1},
|
||||
{0x50, -1, -1, -1},
|
||||
{0x70, -1, -1, -1},
|
||||
{0x74, -1, -1, -1},
|
||||
{0x78, -1, -1, -1},
|
||||
{0x7c, -1, -1, -1},
|
||||
{0x80, -1, -1, -1},
|
||||
{0x8c, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0x24, 6, 18, -1}, //DAC1
|
||||
{0x28, 7, 19, -1}, //DAC2
|
||||
{0x2c, 17, 17, 7},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0, -1, -1, -1},
|
||||
{0x1c, 9, 4, 8},
|
||||
{0x20, 8, 5, 9},
|
||||
{0x14, 4, 6, -1},
|
||||
{0x18, 5, 7, -1},
|
||||
{0x04, 0, 0, -1},
|
||||
{0x08, 1, 1, -1},
|
||||
{0x0c, 2, 2, -1},
|
||||
{0x10, 3, 3, -1}
|
||||
};
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
typedef void (*voidFuncPtrArg)(void*);
|
||||
typedef struct {
|
||||
voidFuncPtr fn;
|
||||
void* arg;
|
||||
bool functional;
|
||||
} InterruptHandle_t;
|
||||
static InterruptHandle_t __pinInterruptHandlers[GPIO_PIN_COUNT] = {0,};
|
||||
|
||||
#include "driver/rtc_io.h"
|
||||
|
||||
extern void IRAM_ATTR __pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
|
||||
if(!digitalPinIsValid(pin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t rtc_reg = rtc_gpio_desc[pin].reg;
|
||||
if(mode == ANALOG) {
|
||||
if(!rtc_reg) {
|
||||
return;//not rtc pin
|
||||
}
|
||||
//lock rtc
|
||||
uint32_t reg_val = ESP_REG(rtc_reg);
|
||||
if(reg_val & rtc_gpio_desc[pin].mux){
|
||||
return;//already in adc mode
|
||||
}
|
||||
reg_val &= ~(
|
||||
(RTC_IO_TOUCH_PAD1_FUN_SEL_V << rtc_gpio_desc[pin].func)
|
||||
|rtc_gpio_desc[pin].ie
|
||||
|rtc_gpio_desc[pin].pullup
|
||||
|rtc_gpio_desc[pin].pulldown);
|
||||
ESP_REG(RTC_GPIO_ENABLE_W1TC_REG) = (1 << (rtc_gpio_desc[pin].rtc_num + RTC_GPIO_ENABLE_W1TC_S));
|
||||
ESP_REG(rtc_reg) = reg_val | rtc_gpio_desc[pin].mux;
|
||||
//unlock rtc
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = ((uint32_t)2 << MCU_SEL_S) | ((uint32_t)2 << FUN_DRV_S) | FUN_IE;
|
||||
return;
|
||||
}
|
||||
|
||||
//RTC pins PULL settings
|
||||
if(rtc_reg) {
|
||||
//lock rtc
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].mux);
|
||||
if(mode & PULLUP) {
|
||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pullup) & ~(rtc_gpio_desc[pin].pulldown);
|
||||
} else if(mode & PULLDOWN) {
|
||||
ESP_REG(rtc_reg) = (ESP_REG(rtc_reg) | rtc_gpio_desc[pin].pulldown) & ~(rtc_gpio_desc[pin].pullup);
|
||||
} else {
|
||||
ESP_REG(rtc_reg) = ESP_REG(rtc_reg) & ~(rtc_gpio_desc[pin].pullup | rtc_gpio_desc[pin].pulldown);
|
||||
}
|
||||
//unlock rtc
|
||||
}
|
||||
|
||||
uint32_t pinFunction = 0, pinControl = 0;
|
||||
|
||||
//lock gpio
|
||||
if(mode & INPUT) {
|
||||
if(pin < 32) {
|
||||
GPIO.enable_w1tc = ((uint32_t)1 << pin);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
} else if(mode & OUTPUT) {
|
||||
if(pin > 33){
|
||||
//unlock gpio
|
||||
return;//pins above 33 can be only inputs
|
||||
} else if(pin < 32) {
|
||||
GPIO.enable_w1ts = ((uint32_t)1 << pin);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
|
||||
if(mode & PULLUP) {
|
||||
pinFunction |= FUN_PU;
|
||||
} else if(mode & PULLDOWN) {
|
||||
pinFunction |= FUN_PD;
|
||||
}
|
||||
|
||||
pinFunction |= ((uint32_t)2 << FUN_DRV_S);//what are the drivers?
|
||||
pinFunction |= FUN_IE;//input enable but required for output as well?
|
||||
|
||||
if(mode & (INPUT | OUTPUT)) {
|
||||
pinFunction |= ((uint32_t)2 << MCU_SEL_S);
|
||||
} else if(mode == SPECIAL) {
|
||||
pinFunction |= ((uint32_t)(((pin)==1||(pin)==3)?0:1) << MCU_SEL_S);
|
||||
} else {
|
||||
pinFunction |= ((uint32_t)(mode >> 5) << MCU_SEL_S);
|
||||
}
|
||||
|
||||
ESP_REG(DR_REG_IO_MUX_BASE + esp32_gpioMux[pin].reg) = pinFunction;
|
||||
|
||||
if(mode & OPEN_DRAIN) {
|
||||
pinControl = (1 << GPIO_PIN0_PAD_DRIVER_S);
|
||||
}
|
||||
|
||||
GPIO.pin[pin].val = pinControl;
|
||||
//unlock gpio
|
||||
}
|
||||
|
||||
extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
if(val) {
|
||||
if(pin < 32) {
|
||||
GPIO.out_w1ts = ((uint32_t)1 << pin);
|
||||
} else if(pin < 34) {
|
||||
GPIO.out1_w1ts.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
} else {
|
||||
if(pin < 32) {
|
||||
GPIO.out_w1tc = ((uint32_t)1 << pin);
|
||||
} else if(pin < 34) {
|
||||
GPIO.out1_w1tc.val = ((uint32_t)1 << (pin - 32));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int IRAM_ATTR __digitalRead(uint8_t pin)
|
||||
{
|
||||
if(pin < 32) {
|
||||
return (GPIO.in >> pin) & 0x1;
|
||||
} else if(pin < 40) {
|
||||
return (GPIO.in1.val >> (pin - 32)) & 0x1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static intr_handle_t gpio_intr_handle = NULL;
|
||||
|
||||
static void IRAM_ATTR __onPinInterrupt()
|
||||
{
|
||||
uint32_t gpio_intr_status_l=0;
|
||||
uint32_t gpio_intr_status_h=0;
|
||||
|
||||
gpio_intr_status_l = GPIO.status;
|
||||
gpio_intr_status_h = GPIO.status1.val;
|
||||
GPIO.status_w1tc = gpio_intr_status_l;//Clear intr for gpio0-gpio31
|
||||
GPIO.status1_w1tc.val = gpio_intr_status_h;//Clear intr for gpio32-39
|
||||
|
||||
uint8_t pin=0;
|
||||
if(gpio_intr_status_l) {
|
||||
do {
|
||||
if(gpio_intr_status_l & ((uint32_t)1 << pin)) {
|
||||
if(__pinInterruptHandlers[pin].fn) {
|
||||
if(__pinInterruptHandlers[pin].arg){
|
||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
||||
} else {
|
||||
__pinInterruptHandlers[pin].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(++pin<32);
|
||||
}
|
||||
if(gpio_intr_status_h) {
|
||||
pin=32;
|
||||
do {
|
||||
if(gpio_intr_status_h & ((uint32_t)1 << (pin - 32))) {
|
||||
if(__pinInterruptHandlers[pin].fn) {
|
||||
if(__pinInterruptHandlers[pin].arg){
|
||||
((voidFuncPtrArg)__pinInterruptHandlers[pin].fn)(__pinInterruptHandlers[pin].arg);
|
||||
} else {
|
||||
__pinInterruptHandlers[pin].fn();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(++pin<GPIO_PIN_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
extern void cleanupFunctional(void* arg);
|
||||
|
||||
extern void __attachInterruptFunctionalArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type, bool functional)
|
||||
{
|
||||
static bool interrupt_initialized = false;
|
||||
|
||||
if(!interrupt_initialized) {
|
||||
interrupt_initialized = true;
|
||||
esp_intr_alloc(ETS_GPIO_INTR_SOURCE, (int)ESP_INTR_FLAG_IRAM, __onPinInterrupt, NULL, &gpio_intr_handle);
|
||||
}
|
||||
|
||||
// if new attach without detach remove old info
|
||||
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||
{
|
||||
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||
}
|
||||
__pinInterruptHandlers[pin].fn = (voidFuncPtr)userFunc;
|
||||
__pinInterruptHandlers[pin].arg = arg;
|
||||
__pinInterruptHandlers[pin].functional = functional;
|
||||
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
if(esp_intr_get_cpu(gpio_intr_handle)) { //APP_CPU
|
||||
GPIO.pin[pin].int_ena = 1;
|
||||
} else { //PRO_CPU
|
||||
GPIO.pin[pin].int_ena = 4;
|
||||
}
|
||||
GPIO.pin[pin].int_type = intr_type;
|
||||
esp_intr_enable(gpio_intr_handle);
|
||||
}
|
||||
|
||||
extern void __attachInterruptArg(uint8_t pin, voidFuncPtrArg userFunc, void * arg, int intr_type)
|
||||
{
|
||||
__attachInterruptFunctionalArg(pin, userFunc, arg, intr_type, false);
|
||||
}
|
||||
|
||||
extern void __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int intr_type) {
|
||||
__attachInterruptFunctionalArg(pin, (voidFuncPtrArg)userFunc, NULL, intr_type, false);
|
||||
}
|
||||
|
||||
extern void __detachInterrupt(uint8_t pin)
|
||||
{
|
||||
esp_intr_disable(gpio_intr_handle);
|
||||
if (__pinInterruptHandlers[pin].functional && __pinInterruptHandlers[pin].arg)
|
||||
{
|
||||
cleanupFunctional(__pinInterruptHandlers[pin].arg);
|
||||
}
|
||||
__pinInterruptHandlers[pin].fn = NULL;
|
||||
__pinInterruptHandlers[pin].arg = NULL;
|
||||
__pinInterruptHandlers[pin].functional = false;
|
||||
|
||||
GPIO.pin[pin].int_ena = 0;
|
||||
GPIO.pin[pin].int_type = 0;
|
||||
esp_intr_enable(gpio_intr_handle);
|
||||
}
|
||||
|
||||
|
||||
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));
|
||||
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
|
||||
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
|
||||
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
|
||||
extern void attachInterruptArg(uint8_t pin, voidFuncPtrArg handler, void * arg, int mode) __attribute__ ((weak, alias("__attachInterruptArg")));
|
||||
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "esp32/rom/rtc.h"
|
||||
#include "esp_task_wdt.h"
|
||||
#include "esp32-hal.h"
|
||||
|
||||
|
@ -17,10 +17,10 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "esp32/rom/ets_sys.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_intr.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "esp32/rom/gpio.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
@ -17,6 +17,13 @@ public:
|
||||
typedef volatile uint32_t * port_ptr_t;
|
||||
typedef uint32_t port_t;
|
||||
|
||||
// BB
|
||||
// It could be better to to the following, then not have to pull in as
|
||||
// much of the hal:
|
||||
// inline static void setOutput() { gpio_set_direction(PIN, GPIO_MODE_OUTPUT); }
|
||||
// inline static void setInput() { gpio_set_direction(PIN, GPIO_MODE_INPUT); }
|
||||
|
||||
|
||||
inline static void setOutput() { pinMode(PIN, OUTPUT); }
|
||||
inline static void setInput() { pinMode(PIN, INPUT); }
|
||||
|
||||
|
@ -24,7 +24,8 @@ typedef unsigned long prog_uint32_t;
|
||||
# define INTERRUPT_THRESHOLD 0
|
||||
#endif
|
||||
|
||||
#define NEED_CXX_BITS
|
||||
// BB - I think I'm compiling in CXX in this project
|
||||
// #define NEED_CXX_BITS
|
||||
|
||||
// These can be overridden
|
||||
# define FASTLED_ESP32_RAW_PIN_ORDER
|
||||
|
@ -23,8 +23,8 @@ extern const TProgmemPalette16 IRAM_ATTR myRedWhiteBluePalette_p;
|
||||
#include "palettes.h"
|
||||
|
||||
#define NUM_LEDS 40
|
||||
#define DATA_PIN 18
|
||||
#define BRIGHTNESS 64
|
||||
#define DATA_PIN 13
|
||||
#define BRIGHTNESS 80
|
||||
#define LED_TYPE WS2811
|
||||
#define COLOR_ORDER RGB
|
||||
CRGB leds[NUM_LEDS];
|
||||
@ -100,9 +100,10 @@ CRGB colors[N_COLORS] = {
|
||||
void blinkLeds_simple(void *pvParameters){
|
||||
|
||||
while(1){
|
||||
printf("blink leds\n");
|
||||
|
||||
for (int j=0;j<N_COLORS;j++) {
|
||||
printf("blink leds\n");
|
||||
|
||||
for (int i=0;i<NUM_LEDS;i++) {
|
||||
leds[i] = colors[j];
|
||||
}
|
||||
@ -154,9 +155,13 @@ void blinkLeds_chase(void *pvParameters) {
|
||||
|
||||
void app_main() {
|
||||
printf(" entering app main, call add leds\n");
|
||||
// the WS2811 family uses the RMT driver
|
||||
FastLED.addLeds<LED_TYPE, DATA_PIN>(leds, NUM_LEDS);
|
||||
// this is a good test because it uses the GPIO ports
|
||||
//FastLED.addLeds<APA102, 13, 15>(leds, NUM_LEDS);
|
||||
|
||||
printf(" set max power\n");
|
||||
FastLED.setMaxPowerInVoltsAndMilliamps(5,1000);
|
||||
FastLED.setMaxPowerInVoltsAndMilliamps(5,2000);
|
||||
printf("create task for led blinking\n");
|
||||
xTaskCreatePinnedToCore(&blinkLeds_simple, "blinkLeds", 4000, NULL, 5, NULL, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user