Tasmota/lib/lib_basic/TasmotaLED/src/TasmotaLEDPusher.h
s-hadinger db0287e566
Replace NeoPixelBus with TasmotaLED on ESP32x (#22556)
* Replace NeoPixelBus with TasmotaLED on ESP32x

* update changelog
2024-11-27 22:11:57 +01:00

162 lines
5.2 KiB
C++

/*
TasmotaLEDPusher.h - Abstract class for Leds pusher (RMT, SPI, I2S...)
Copyright (C) 2024 Stephan Hadinger
This library 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __TASMOTALEDPUSHER_H__
#define __TASMOTALEDPUSHER_H__
#include <Arduino.h>
// Below are flags to enable of disable each hardware support: RMT, I2S, SPI
// By default, only enable RMT support, and SPI is used as fallback if no protocol works
//
// Use de defines below:
// #define TASMOTALED_HARDWARE_RMT 0/1
// #define TASMOTALED_HARDWARE_I2S 0/1
// #define TASMOTALED_HARDWARE_SPI 0/1
//
#ifndef TASMOTALED_HARDWARE_RMT
#define TASMOTALED_HARDWARE_RMT 1
#endif
#ifndef TASMOTALED_HARDWARE_I2S
#define TASMOTALED_HARDWARE_I2S 0
#endif
#ifndef TASMOTALED_HARDWARE_SPI
#define TASMOTALED_HARDWARE_SPI 0
#endif
// Disable any hardware if not supported by the SOC
#if TASMOTALED_HARDWARE_RMT && !defined(SOC_RMT_SUPPORTED)
#undef TASMOTALED_HARDWARE_RMT
#define TASMOTALED_HARDWARE_RMT 0
#endif
#if TASMOTALED_HARDWARE_I2S && !defined(SOC_I2S_SUPPORTED)
#undef TASMOTALED_HARDWARE_I2S
#define TASMOTALED_HARDWARE_I2S 0
#endif
#if TASMOTALED_HARDWARE_SPI && !defined(SOC_GPSPI_SUPPORTED)
#undef TASMOTALED_HARDWARE_SPI
#define TASMOTALED_HARDWARE_SPI 0
#endif
// if no protocol is defined, use SPI as fallback
#if !TASMOTALED_HARDWARE_RMT && !TASMOTALED_HARDWARE_I2S && !TASMOTALED_HARDWARE_SPI
#undef TASMOTALED_HARDWARE_SPI
#define TASMOTALED_HARDWARE_SPI 1
#endif
// Timing structure for LEDS - in nanoseconds
// It is passed by TasmotaLed to the pushers
typedef struct TasmotaLED_Timing {
uint16_t T0H, T0L, T1H, T1L;
uint32_t Reset;
} TasmotaLED_Timing;
/*******************************************************************************************\
* class TasmotaLEDPusher
*
* This is an virtual abstract class for Leds pusher (RMT, SPI, I2S...)
*
* Below are interfaces for current implementations
\*******************************************************************************************/
class TasmotaLEDPusher {
public:
TasmotaLEDPusher() : _pixel_count(0), _pixel_size(0), _led_timing(nullptr) {};
virtual ~TasmotaLEDPusher() {};
virtual bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) {
_pixel_count = pixel_count;
_pixel_size = pixel_size;
_led_timing = led_timing;
return true;
}
virtual bool Push(uint8_t *buf) = 0;
virtual bool CanShow(void) = 0;
static uint32_t ResolveHardware(uint32_t hw); // convert to the appropriate hardware acceleration based on capacities of the SOC
static TasmotaLEDPusher * Create(uint32_t hw, int8_t gpio); // create instance for the provided type, or nullptr if failed
protected:
uint16_t _pixel_count;
uint16_t _pixel_size;
const TasmotaLED_Timing * _led_timing;
};
/*******************************************************************************************\
* class TasmotaLEDPusherRMT
*
* Implementation based on RMT driver
\*******************************************************************************************/
#if TASMOTALED_HARDWARE_RMT
#include "driver/rmt_tx.h"
class TasmotaLEDPusherRMT : public TasmotaLEDPusher {
public:
TasmotaLEDPusherRMT(int8_t pin) : _pin(pin) {};
~TasmotaLEDPusherRMT();
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
bool Push(uint8_t *buf) override;
bool CanShow(void) override;
protected:
int8_t _pin;
rmt_transmit_config_t _tx_config = {};
rmt_channel_handle_t _channel = nullptr;;
rmt_encoder_handle_t _led_encoder = nullptr;
};
#endif // TASMOTALED_HARDWARE_RMT
/*******************************************************************************************\
* class TasmotaLEDPusherSPI
*
* Implementation based on SPI driver, mandatory for C2
\*******************************************************************************************/
#if TASMOTALED_HARDWARE_SPI
#include <driver/spi_master.h>
typedef struct led_strip_spi_obj_t {
uint8_t * pixel_buf;
uint16_t strip_len;
uint8_t bytes_per_pixel;
spi_host_device_t spi_host;
spi_device_handle_t spi_device;
spi_transaction_t tx_conf; // transaction in process if any
} led_strip_spi_obj;
class TasmotaLEDPusherSPI : public TasmotaLEDPusher {
public:
TasmotaLEDPusherSPI(int8_t pin) : _pin(pin), _spi_strip({}) {};
~TasmotaLEDPusherSPI();
bool Begin(uint16_t pixel_count, uint16_t pixel_size, const TasmotaLED_Timing * led_timing) override;
bool Push(uint8_t *buf) override;
bool CanShow(void) override;
protected:
int8_t _pin;
struct led_strip_spi_obj_t _spi_strip;
};
#endif // TASMOTALED_HARDWARE_SPI
#endif // __TASMOTALEDPUSHER_H__