Christmas DMA core tweaks
Bring back support to change the I2S_NUM_X as a define. Attempt to reduce buffer swap flicker with some additional checks.
This commit is contained in:
parent
229b0d874c
commit
4f5fcf0399
6 changed files with 115 additions and 69 deletions
|
@ -419,7 +419,7 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg)
|
||||||
Serial.println(F("Performing I2S setup:"));
|
Serial.println(F("Performing I2S setup:"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i2s_parallel_config_t cfg = {
|
i2s_parallel_config_t dma_cfg = {
|
||||||
.gpio_bus={_cfg.gpio.r1, _cfg.gpio.g1, _cfg.gpio.b1, _cfg.gpio.r2, _cfg.gpio.g2, _cfg.gpio.b2, _cfg.gpio.lat, _cfg.gpio.oe, _cfg.gpio.a, _cfg.gpio.b, _cfg.gpio.c, _cfg.gpio.d, _cfg.gpio.e, -1, -1, -1},
|
.gpio_bus={_cfg.gpio.r1, _cfg.gpio.g1, _cfg.gpio.b1, _cfg.gpio.r2, _cfg.gpio.g2, _cfg.gpio.b2, _cfg.gpio.lat, _cfg.gpio.oe, _cfg.gpio.a, _cfg.gpio.b, _cfg.gpio.c, _cfg.gpio.d, _cfg.gpio.e, -1, -1, -1},
|
||||||
.gpio_clk=_cfg.gpio.clk,
|
.gpio_clk=_cfg.gpio.clk,
|
||||||
.sample_rate=_cfg.i2sspeed,
|
.sample_rate=_cfg.i2sspeed,
|
||||||
|
@ -428,18 +428,16 @@ void MatrixPanel_I2S_DMA::configureDMA(const HUB75_I2S_CFG& _cfg)
|
||||||
.lldesc_a=dmadesc_a,
|
.lldesc_a=dmadesc_a,
|
||||||
.desccount_b=desccount,
|
.desccount_b=desccount,
|
||||||
.lldesc_b=dmadesc_b,
|
.lldesc_b=dmadesc_b,
|
||||||
.clkphase=_cfg.clkphase
|
.clkphase=_cfg.clkphase,
|
||||||
|
.int_ena_out_eof=_cfg.double_buff
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup I2S
|
// Setup I2S
|
||||||
i2s_parallel_driver_install(I2S_NUM_0, &cfg);
|
i2s_parallel_driver_install(ESP32_I2S_DEVICE, &dma_cfg);
|
||||||
//i2s_parallel_setup_without_malloc(&I2S1, &cfg);
|
i2s_parallel_send_dma(ESP32_I2S_DEVICE, &dmadesc_a[0]);
|
||||||
|
|
||||||
// Start DMA Output
|
|
||||||
i2s_parallel_send_dma(I2S_NUM_0, &dmadesc_a[0]);
|
|
||||||
|
|
||||||
#if SERIAL_DEBUG
|
#if SERIAL_DEBUG
|
||||||
Serial.println(F("configureDMA(): DMA setup completed on I2S_NUM_0."));
|
Serial.println(F("configureDMA(): DMA setup completed on ESP32_I2S_DEVICE."));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // end initMatrixDMABuff
|
} // end initMatrixDMABuff
|
||||||
|
|
|
@ -129,9 +129,10 @@
|
||||||
|
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
/* Definitions below should NOT be ever changed without rewriting library logic */
|
/* Definitions below should NOT be ever changed without rewriting library logic */
|
||||||
#define ESP32_I2S_DMA_MODE I2S_PARALLEL_WIDTH_16 // From esp32_i2s_parallel_v2.h = 16 bits in parallel
|
#define ESP32_I2S_DMA_MODE I2S_PARALLEL_WIDTH_16 // From esp32_i2s_parallel_v2.h = 16 bits in parallel
|
||||||
#define ESP32_I2S_DMA_STORAGE_TYPE uint16_t // DMA output of one uint16_t at a time.
|
#define ESP32_I2S_DMA_STORAGE_TYPE uint16_t // DMA output of one uint16_t at a time.
|
||||||
#define CLKS_DURING_LATCH 0 // Not (yet) used.
|
#define CLKS_DURING_LATCH 0 // Not (yet) used.
|
||||||
|
#define ESP32_I2S_DEVICE I2S_NUM_1
|
||||||
|
|
||||||
// Panel Upper half RGB (numbering according to order in DMA gpio_bus configuration)
|
// Panel Upper half RGB (numbering according to order in DMA gpio_bus configuration)
|
||||||
#define BITS_RGB1_OFFSET 0 // Start point of RGB_X1 bits
|
#define BITS_RGB1_OFFSET 0 // Start point of RGB_X1 bits
|
||||||
|
@ -316,7 +317,7 @@ struct HUB75_I2S_CFG {
|
||||||
LAT_PIN_DEFAULT, OE_PIN_DEFAULT, CLK_PIN_DEFAULT },
|
LAT_PIN_DEFAULT, OE_PIN_DEFAULT, CLK_PIN_DEFAULT },
|
||||||
shift_driver _drv = SHIFTREG,
|
shift_driver _drv = SHIFTREG,
|
||||||
bool _dbuff = false,
|
bool _dbuff = false,
|
||||||
clk_speed _i2sspeed = HZ_20M,
|
clk_speed _i2sspeed = HZ_10M,
|
||||||
uint8_t _latblk = 1, // Anything > 1 seems to cause artefacts on ICS panels
|
uint8_t _latblk = 1, // Anything > 1 seems to cause artefacts on ICS panels
|
||||||
bool _clockphase = true,
|
bool _clockphase = true,
|
||||||
uint8_t _min_refresh_rate = 85
|
uint8_t _min_refresh_rate = 85
|
||||||
|
@ -525,15 +526,23 @@ class MatrixPanel_I2S_DMA {
|
||||||
Serial.printf_P(PSTR("Set back buffer to: %d\n"), back_buffer_id);
|
Serial.printf_P(PSTR("Set back buffer to: %d\n"), back_buffer_id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i2s_parallel_flip_to_buffer(I2S_NUM_0, back_buffer_id);
|
i2s_parallel_set_previous_buffer_not_free();
|
||||||
|
|
||||||
// Wait before we allow any writing to the buffer. Stop flicker.
|
// Wait before we allow any writing to the buffer. Stop flicker.
|
||||||
while(i2s_parallel_is_previous_buffer_free() == false) { }
|
while(i2s_parallel_is_previous_buffer_free() == false) { }
|
||||||
|
|
||||||
|
i2s_parallel_flip_to_buffer(ESP32_I2S_DEVICE, back_buffer_id);
|
||||||
// Flip to other buffer as the backbuffer.
|
// Flip to other buffer as the backbuffer.
|
||||||
// i.e. Graphic changes happen to this buffer, but aren't displayed until flipDMABuffer() is called again.
|
// i.e. Graphic changes happen to this buffer, but aren't displayed until flipDMABuffer() is called again.
|
||||||
back_buffer_id ^= 1;
|
back_buffer_id ^= 1;
|
||||||
|
|
||||||
|
i2s_parallel_set_previous_buffer_not_free();
|
||||||
|
// Wait before we allow any writing to the buffer. Stop flicker.
|
||||||
|
while(i2s_parallel_is_previous_buffer_free() == false) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setPanelBrightness(int b)
|
inline void setPanelBrightness(int b)
|
||||||
|
@ -585,7 +594,7 @@ class MatrixPanel_I2S_DMA {
|
||||||
*/
|
*/
|
||||||
void stopDMAoutput() {
|
void stopDMAoutput() {
|
||||||
resetbuffers();
|
resetbuffers();
|
||||||
i2s_parallel_stop_dma(I2S_NUM_0);
|
i2s_parallel_stop_dma(ESP32_I2S_DEVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
// Header
|
// Header
|
||||||
#include "esp32_i2s_parallel_dma.h"
|
#include "esp32_i2s_parallel_dma.h"
|
||||||
|
#include "esp32_i2s_parallel_mcu_def.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -25,22 +26,28 @@
|
||||||
#include <soc/gpio_sig_map.h>
|
#include <soc/gpio_sig_map.h>
|
||||||
|
|
||||||
// For I2S state management.
|
// For I2S state management.
|
||||||
static i2s_parallel_state_t *i2s_state = NULL;
|
static i2s_parallel_state_t *i2s_state = NULL;
|
||||||
|
|
||||||
// ESP32-S2,S3,C3 only has IS20
|
// ESP32-S2,S3,C3 only has IS20
|
||||||
// Original ESP32 has two I2S's, but we'll stick with the lowest common denominator.
|
// Original ESP32 has two I2S's, but we'll stick with the lowest common denominator.
|
||||||
static i2s_dev_t* I2S = &I2S0; // Device to use for this library, change if you want.
|
|
||||||
|
#ifdef ESP32_ORIG
|
||||||
|
static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0, &I2S1};
|
||||||
|
#else
|
||||||
|
static i2s_dev_t* I2S[I2S_NUM_MAX] = {&I2S0};
|
||||||
|
#endif
|
||||||
|
|
||||||
callback shiftCompleteCallback;
|
callback shiftCompleteCallback;
|
||||||
void setShiftCompleteCallback(callback f) {
|
void setShiftCompleteCallback(callback f) {
|
||||||
shiftCompleteCallback = f;
|
shiftCompleteCallback = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool previousBufferFree = true;
|
volatile int previousBufferOutputLoopCount = 0;
|
||||||
|
volatile bool previousBufferFree = true;
|
||||||
|
|
||||||
static void IRAM_ATTR irq_hndlr(void* arg) { // if we use I2S1 (default)
|
static void IRAM_ATTR irq_hndlr(void* arg) { // if we use I2S1 (default)
|
||||||
|
|
||||||
#ifdef ESP_ORIG
|
#ifdef ESP32_ORIG
|
||||||
|
|
||||||
if ( (*(i2s_port_t*)arg) == I2S_NUM_1 ) { // https://www.bogotobogo.com/cplusplus/pointers2_voidpointers_arrays.php
|
if ( (*(i2s_port_t*)arg) == I2S_NUM_1 ) { // https://www.bogotobogo.com/cplusplus/pointers2_voidpointers_arrays.php
|
||||||
//For I2S1
|
//For I2S1
|
||||||
|
@ -51,16 +58,24 @@ static void IRAM_ATTR irq_hndlr(void* arg) { // if we use I2S1 (default)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// Other ESP32 MCU's only have one I2S
|
// Other ESP32 MCU's only have one I2S
|
||||||
SET_PERI_REG_BITS(I2S_INT_CLR_REG(0), I2S_OUT_EOF_INT_CLR_V, 1, I2S_OUT_EOF_INT_CLR_S);
|
SET_PERI_REG_BITS(I2S_INT_CLR_REG(0), I2S_OUT_EOF_INT_CLR_V, 1, I2S_OUT_EOF_INT_CLR_S);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
|
if ( previousBufferOutputLoopCount == 1)
|
||||||
|
{
|
||||||
|
// at this point, the previously active buffer is free, go ahead and write to it
|
||||||
|
previousBufferFree = true;
|
||||||
|
////previousBufferOutputLoopCount = 0;
|
||||||
|
//i2s_parallel_set_previous_buffer_not_free();
|
||||||
|
}
|
||||||
|
else { previousBufferOutputLoopCount++; }
|
||||||
|
*/
|
||||||
|
previousBufferFree = true;
|
||||||
|
|
||||||
// at this point, the previously active buffer is free, go ahead and write to it
|
// if(shiftCompleteCallback) // we've defined a callback function ?
|
||||||
previousBufferFree = true;
|
// shiftCompleteCallback();
|
||||||
|
|
||||||
if(shiftCompleteCallback) // we've defined a callback function ?
|
|
||||||
shiftCompleteCallback();
|
|
||||||
|
|
||||||
} // end irq_hndlr
|
} // end irq_hndlr
|
||||||
|
|
||||||
|
@ -155,7 +170,7 @@ void link_dma_desc(volatile lldesc_t *dmadesc, volatile lldesc_t *prevdmadesc, v
|
||||||
|
|
||||||
esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* conf) {
|
esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* conf) {
|
||||||
|
|
||||||
port = I2S_NUM_0; /// override.
|
//port = I2S_NUM_0; /// override.
|
||||||
|
|
||||||
if(port < I2S_NUM_0 || port >= I2S_NUM_MAX) {
|
if(port < I2S_NUM_0 || port >= I2S_NUM_MAX) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
|
@ -176,7 +191,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
int irq_source;
|
int irq_source;
|
||||||
|
|
||||||
// Initialize I2S0 peripheral
|
// Initialize I2S0 peripheral
|
||||||
//if (port == I2S_NUM_0) {
|
if (port == I2S_NUM_0) {
|
||||||
periph_module_reset(PERIPH_I2S0_MODULE);
|
periph_module_reset(PERIPH_I2S0_MODULE);
|
||||||
periph_module_enable(PERIPH_I2S0_MODULE);
|
periph_module_enable(PERIPH_I2S0_MODULE);
|
||||||
iomux_clock = I2S0O_WS_OUT_IDX;
|
iomux_clock = I2S0O_WS_OUT_IDX;
|
||||||
|
@ -193,8 +208,12 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
case I2S_PARALLEL_WIDTH_MAX:
|
case I2S_PARALLEL_WIDTH_MAX:
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
/*
|
}
|
||||||
} else {
|
#ifdef ESP32_ORIG
|
||||||
|
// Can't compile if I2S1 if it doesn't exist with that hardware's IDF....
|
||||||
|
else {
|
||||||
|
// I2S = &I2S1;
|
||||||
|
|
||||||
periph_module_reset(PERIPH_I2S1_MODULE);
|
periph_module_reset(PERIPH_I2S1_MODULE);
|
||||||
periph_module_enable(PERIPH_I2S1_MODULE);
|
periph_module_enable(PERIPH_I2S1_MODULE);
|
||||||
iomux_clock = I2S1O_WS_OUT_IDX;
|
iomux_clock = I2S1O_WS_OUT_IDX;
|
||||||
|
@ -212,12 +231,14 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
#endif
|
||||||
|
|
||||||
// Setup GPIOs
|
// Setup GPIOs
|
||||||
int bus_width = get_bus_width(conf->sample_width);
|
int bus_width = get_bus_width(conf->sample_width);
|
||||||
|
|
||||||
// Setup I2S peripheral
|
// Setup I2S peripheral
|
||||||
i2s_dev_t* dev = I2S;
|
i2s_dev_t* dev = I2S[port];
|
||||||
|
//dev_reset(dev);
|
||||||
|
|
||||||
|
|
||||||
// Setup GPIO's
|
// Setup GPIO's
|
||||||
|
@ -245,7 +266,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
|
|
||||||
#ifdef ESP32_SXXX
|
#ifdef ESP32_SXXX
|
||||||
dev->clkm_conf.clk_sel = 2; // esp32-s2 only
|
dev->clkm_conf.clk_sel = 2; // esp32-s2 only
|
||||||
dev->clkm_conf.clk_en = 1;
|
dev->clkm_conf.clk_en = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ESP32_ORIG
|
#ifdef ESP32_ORIG
|
||||||
|
@ -329,26 +350,28 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
state->dmadesc_b = conf->lldesc_b;
|
state->dmadesc_b = conf->lldesc_b;
|
||||||
state->i2s_interrupt_port_arg = port; // need to keep this somewhere in static memory for the ISR
|
state->i2s_interrupt_port_arg = port; // need to keep this somewhere in static memory for the ISR
|
||||||
|
|
||||||
// Get ISR setup
|
|
||||||
esp_err_t err = esp_intr_alloc(irq_source,
|
|
||||||
(int)(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1),
|
|
||||||
irq_hndlr,
|
|
||||||
&state->i2s_interrupt_port_arg, NULL);
|
|
||||||
|
|
||||||
if(err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dev->timing.val = 0;
|
dev->timing.val = 0;
|
||||||
|
|
||||||
|
// We using the double buffering switch logic?
|
||||||
|
if (conf->int_ena_out_eof)
|
||||||
|
{
|
||||||
|
// Get ISR setup
|
||||||
|
esp_err_t err = esp_intr_alloc(irq_source,
|
||||||
|
(int)(ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_LEVEL1),
|
||||||
|
irq_hndlr,
|
||||||
|
&state->i2s_interrupt_port_arg, NULL);
|
||||||
|
|
||||||
// Setup interrupt handler which is focussed only on the (page 322 of Tech. Ref. Manual)
|
if(err) {
|
||||||
// "I2S_OUT_EOF_INT: Triggered when rxlink has finished sending a packet"
|
return err;
|
||||||
// ... whatever the hell that is supposed to mean... One massive linked list.
|
}
|
||||||
dev->int_ena.out_eof = 1;
|
|
||||||
|
|
||||||
|
|
||||||
|
// Setup interrupt handler which is focussed only on the (page 322 of Tech. Ref. Manual)
|
||||||
|
// "I2S_OUT_EOF_INT: Triggered when rxlink has finished sending a packet"
|
||||||
|
// ... whatever the hell that is supposed to mean... One massive linked list? So all pixels in the chain?
|
||||||
|
dev->int_ena.out_eof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +380,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2s_dev_t* dev = I2S;
|
i2s_dev_t* dev = I2S[port];
|
||||||
|
|
||||||
// Stop all ongoing DMA operations
|
// Stop all ongoing DMA operations
|
||||||
dev->out_link.stop = 1;
|
dev->out_link.stop = 1;
|
||||||
|
@ -373,7 +396,7 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
i2s_dev_t* dev = I2S;
|
i2s_dev_t* dev = I2S[port];
|
||||||
|
|
||||||
|
|
||||||
// Configure DMA burst mode
|
// Configure DMA burst mode
|
||||||
|
@ -390,16 +413,23 @@ esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* co
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
i2s_dev_t* i2s_parallel_get_dev(i2s_port_t port) {
|
i2s_dev_t* i2s_parallel_get_dev(i2s_port_t port) {
|
||||||
if(port < I2S_NUM_0 || port >= I2S_NUM_MAX) {
|
if(port < I2S_NUM_0 || port >= I2S_NUM_MAX) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return I2S; // HARCODE THIS TO RETURN &I2S0
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#ifdef ESP32_ORIG
|
||||||
|
if (port == I2S_NUM_1)
|
||||||
|
return &I2S1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return I2S0; // HARCODE THIS TO RETURN &I2S0
|
||||||
|
}
|
||||||
|
*/
|
||||||
// Double buffering flipping
|
// Double buffering flipping
|
||||||
// Flip to a buffer: 0 for bufa, 1 for bufb
|
// Flip to a buffer: 0 for bufa, 1 for bufb
|
||||||
|
// dmadesc_a and dmadesc_b point to the same memory if double buffering isn't enabled.
|
||||||
void i2s_parallel_flip_to_buffer(i2s_port_t port, int buffer_id) {
|
void i2s_parallel_flip_to_buffer(i2s_port_t port, int buffer_id) {
|
||||||
|
|
||||||
if (i2s_state == NULL) {
|
if (i2s_state == NULL) {
|
||||||
|
@ -418,9 +448,16 @@ void i2s_parallel_flip_to_buffer(i2s_port_t port, int buffer_id) {
|
||||||
i2s_state->dmadesc_b[i2s_state->desccount_b-1].qe.stqe_next = active_dma_chain;
|
i2s_state->dmadesc_b[i2s_state->desccount_b-1].qe.stqe_next = active_dma_chain;
|
||||||
|
|
||||||
// we're still shifting out the buffer, so it shouldn't be written to yet.
|
// we're still shifting out the buffer, so it shouldn't be written to yet.
|
||||||
previousBufferFree = false;
|
//previousBufferFree = false;
|
||||||
|
i2s_parallel_set_previous_buffer_not_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool i2s_parallel_is_previous_buffer_free() {
|
bool i2s_parallel_is_previous_buffer_free() {
|
||||||
return previousBufferFree;
|
return previousBufferFree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void i2s_parallel_set_previous_buffer_not_free() {
|
||||||
|
previousBufferFree = false;
|
||||||
|
previousBufferOutputLoopCount = 0;
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ typedef struct {
|
||||||
int desccount_b; // only used with double buffering
|
int desccount_b; // only used with double buffering
|
||||||
lldesc_t * lldesc_b; // only used with double buffering
|
lldesc_t * lldesc_b; // only used with double buffering
|
||||||
bool clkphase; // Clock signal phase
|
bool clkphase; // Clock signal phase
|
||||||
|
bool int_ena_out_eof; // Do we raise an interrupt every time the DMA output loops? Don't do this unless we're doing double buffering!
|
||||||
} i2s_parallel_config_t;
|
} i2s_parallel_config_t;
|
||||||
|
|
||||||
static inline int i2s_parallel_get_memory_width(i2s_port_t port, i2s_parallel_cfg_bits_t width) {
|
static inline int i2s_parallel_get_memory_width(i2s_port_t port, i2s_parallel_cfg_bits_t width) {
|
||||||
|
@ -72,7 +73,7 @@ void link_dma_desc(volatile lldesc_t *dmadesc, volatile lldesc_t *prevdmadesc, v
|
||||||
esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* conf);
|
esp_err_t i2s_parallel_driver_install(i2s_port_t port, i2s_parallel_config_t* conf);
|
||||||
esp_err_t i2s_parallel_send_dma(i2s_port_t port, lldesc_t* dma_descriptor);
|
esp_err_t i2s_parallel_send_dma(i2s_port_t port, lldesc_t* dma_descriptor);
|
||||||
esp_err_t i2s_parallel_stop_dma(i2s_port_t port);
|
esp_err_t i2s_parallel_stop_dma(i2s_port_t port);
|
||||||
i2s_dev_t* i2s_parallel_get_dev(i2s_port_t port);
|
//i2s_dev_t* i2s_parallel_get_dev(i2s_port_t port);
|
||||||
|
|
||||||
// For frame buffer flipping / double buffering
|
// For frame buffer flipping / double buffering
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -83,6 +84,7 @@ typedef struct {
|
||||||
|
|
||||||
void i2s_parallel_flip_to_buffer(i2s_port_t port, int bufid);
|
void i2s_parallel_flip_to_buffer(i2s_port_t port, int bufid);
|
||||||
bool i2s_parallel_is_previous_buffer_free();
|
bool i2s_parallel_is_previous_buffer_free();
|
||||||
|
void i2s_parallel_set_previous_buffer_not_free();
|
||||||
|
|
||||||
// Callback function for when whole length of DMA chain has been sent out.
|
// Callback function for when whole length of DMA chain has been sent out.
|
||||||
typedef void (*callback)(void);
|
typedef void (*callback)(void);
|
||||||
|
|
|
@ -143,11 +143,11 @@ uint8_t wheelval = 0;
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
// animate by going through the colour wheel for the first two lines
|
// animate by going through the colour wheel for the first two lines
|
||||||
//drawText(wheelval);
|
drawText(wheelval);
|
||||||
//wheelval +=1;
|
wheelval +=1;
|
||||||
|
|
||||||
//delay(20);
|
|
||||||
|
|
||||||
|
delay(20);
|
||||||
|
/*
|
||||||
drawText(0);
|
drawText(0);
|
||||||
delay(2000);
|
delay(2000);
|
||||||
dma_display->clearScreen();
|
dma_display->clearScreen();
|
||||||
|
@ -161,5 +161,6 @@ void loop() {
|
||||||
delay(2000);
|
delay(2000);
|
||||||
dma_display->fillScreen(myWHITE);
|
dma_display->fillScreen(myWHITE);
|
||||||
dma_display->clearScreen();
|
dma_display->clearScreen();
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|BitmapIcons |Simple example of how to display a bitmap image to the display. |
|
|BitmapIcons |Simple example of how to display a bitmap image to the display. |
|
||||||
|ChainedPanels |Popular example on how to use the 'VirtualDisplay' class to chain multiple LED Matrix Panels to form a much bigger display! Refer to the README within this example's folder! |
|
|ChainedPanels |Popular example on how to use the 'VirtualDisplay' class to chain multiple LED Matrix Panels to form a much bigger display! Refer to the README within this example's folder! |
|
||||||
|ChainedPanelsAuroraDemo |As above, but showing a large trippy plasma animation. |
|
|ChainedPanelsAuroraDemo |As above, but showing a large trippy plasma animation. |
|
||||||
|Smooth Double Buffer |Example of using a back-buffer (double buffering). Not useful in 99.9% of use-cases of this library. Uses double the SRAM as well. |
|
|One_Quarter_1_4_ScanPanel |Using this library with a 32w x 16h 1/4 Scan LED Matrix Panel. Custom co-ordinate remapping logic required. |
|
||||||
|One_Quarter_1_4_ScanPanel |Using this library with a 32w x 16h 1/4 Scan LED Matrix Panel. Custom co-ordinate remapping logic required. |
|
|One_Eighth_1_8_ScanPanel |Using this library with a 64w x 32h 1/8 Scan LED Matrix Panel. Custom co-ordinate remapping logic required.
|
||||||
|One_Eighth_1_8_ScanPanel |Using this library with a 64w x 32h 1/8 Scan LED Matrix Panel. Custom co-ordinate remapping logic required.
|
|
||||||
|PIO_TestPatterns |Non-Arduino example of how to display basic shapes. |
|
|PIO_TestPatterns |Non-Arduino example of how to display basic shapes. |
|
||||||
|
|
Loading…
Reference in a new issue