Pouziti RMT periferie pro ESP32
This commit is contained in:
parent
44de7d5d15
commit
3bbb76672a
@ -1,11 +1,25 @@
|
|||||||
// Ovladani signalizacni chytre LED diody
|
// Ovladani signalizacni chytre LED diody
|
||||||
#include "wsLED.h"
|
#include "wsLED.h"
|
||||||
//#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
//# include "esp_task.h"
|
//# include "esp_task.h"
|
||||||
//#endif
|
// https://github.com/JSchaenzle/ESP32-NeoPixel-WS2812-RMT/blob/master/ws2812_control.c
|
||||||
|
# include <driver/rmt.h>
|
||||||
|
# include <set>
|
||||||
|
# ifndef LED_RMT_TX_CHANNEL
|
||||||
|
# define LED_RMT_TX_CHANNEL RMT_CHANNEL_0
|
||||||
|
# endif
|
||||||
|
# define BITS_PER_LED_CMD 24
|
||||||
|
# define LED_BUFFER_ITEMS ((1 * BITS_PER_LED_CMD))
|
||||||
|
// These values are determined by measuring pulse timing with logic analyzer and adjusting to match datasheet.
|
||||||
|
# define T0H 14 // 0 bit high time
|
||||||
|
# define T1H 52 // 1 bit high time
|
||||||
|
# define TL 52 // low time for either bit
|
||||||
|
#endif
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
// due to linker overriding the ICACHE_RAM_ATTR for cpp files, these methods are
|
// 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
|
// 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);
|
extern "C" void ICACHE_RAM_ATTR send_pixels_800(uint8_t* pixel, size_t count, uint8_t pin);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define countof(a) (sizeof(a) / sizeof(a[0]))
|
#define countof(a) (sizeof(a) / sizeof(a[0]))
|
||||||
|
|
||||||
@ -35,16 +49,20 @@ void wsLED::show(void)
|
|||||||
while (!canShow())
|
while (!canShow())
|
||||||
__asm__ volatile ("nop");
|
__asm__ volatile ("nop");
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
// uint32_t volatile register ilevel = XTOS_DISABLE_ALL_INTERRUPTS;
|
rmt_item32_t led_data_buffer[LED_BUFFER_ITEMS];
|
||||||
portENTER_CRITICAL(&_mux);
|
|
||||||
|
uint32_t bits_to_send = ((uint32_t)color[0] << 16) | ((uint32_t)color[1] << 8) | (uint32_t)color[2];
|
||||||
|
uint32_t mask = 1 << (BITS_PER_LED_CMD - 1);
|
||||||
|
for (uint32_t bit = 0; bit < BITS_PER_LED_CMD; bit++) {
|
||||||
|
uint32_t bit_is_set = bits_to_send & mask;
|
||||||
|
led_data_buffer[bit] = bit_is_set ? (rmt_item32_t) {{{T1H, 1, TL, 0}}} : (rmt_item32_t) {{{T0H, 1, TL, 0}}};
|
||||||
|
mask >>= 1;
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(rmt_write_items(LED_RMT_TX_CHANNEL, led_data_buffer, LED_BUFFER_ITEMS, false));
|
||||||
|
ESP_ERROR_CHECK(rmt_wait_tx_done(LED_RMT_TX_CHANNEL, portMAX_DELAY));
|
||||||
#else
|
#else
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
#endif
|
|
||||||
send_pixels_800(color, 1, _pin);
|
send_pixels_800(color, 1, _pin);
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
|
||||||
// XTOS_RESTORE_INTLEVEL(ilevel);
|
|
||||||
portEXIT_CRITICAL(&_mux);
|
|
||||||
#else
|
|
||||||
interrupts();
|
interrupts();
|
||||||
#endif
|
#endif
|
||||||
_endtime = micros();
|
_endtime = micros();
|
||||||
@ -61,7 +79,26 @@ wsLED::wsLED(int pin, int order)
|
|||||||
void wsLED::begin(void)
|
void wsLED::begin(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_ESP8266)
|
||||||
pinMode(_pin, OUTPUT);
|
pinMode(_pin, OUTPUT);
|
||||||
|
#endif
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
// TODO: mozna nejak zkusit najit volny RMT kanal?
|
||||||
|
rmt_config_t config;
|
||||||
|
|
||||||
|
config.rmt_mode = RMT_MODE_TX;
|
||||||
|
config.channel = LED_RMT_TX_CHANNEL;
|
||||||
|
config.gpio_num = (gpio_num_t)_pin;
|
||||||
|
config.mem_block_num = 3;
|
||||||
|
config.tx_config.loop_en = false;
|
||||||
|
config.tx_config.carrier_en = false;
|
||||||
|
config.tx_config.idle_output_en = true;
|
||||||
|
config.tx_config.idle_level = RMT_IDLE_LEVEL_LOW;
|
||||||
|
config.clk_div = 2;
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(rmt_config(&config));
|
||||||
|
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
|
||||||
|
#endif
|
||||||
_color[0] = _color[1] = _color[2] = 0;
|
_color[0] = _color[1] = _color[2] = 0;
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
@ -146,3 +183,5 @@ void wsLED::setOrder(int neworder)
|
|||||||
|
|
||||||
_order = neworder;
|
_order = neworder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,6 +131,9 @@ protected:
|
|||||||
LED_PATTERN,
|
LED_PATTERN,
|
||||||
} _ledState; // stav LEDky (blika, dycha, ...)
|
} _ledState; // stav LEDky (blika, dycha, ...)
|
||||||
int _subState; // pomocny stav/index v poli dychani
|
int _subState; // pomocny stav/index v poli dychani
|
||||||
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
|
int _rmtChannel;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool canShow(void);
|
bool canShow(void);
|
||||||
void show(void);
|
void show(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user