Compare commits

...

1 commit

Author SHA1 Message Date
Phillip Burgess
2907b65133 Trying some faster-bitplanes stuff, not quite right, may need to use different periph. 2023-07-21 17:47:15 -07:00
3 changed files with 42 additions and 7 deletions

View file

@ -20,6 +20,8 @@
#if defined(ESP32) || \ #if defined(ESP32) || \
defined(ESP_PLATFORM) // *All* ESP32 variants (OG, S2, S3, etc.) defined(ESP_PLATFORM) // *All* ESP32 variants (OG, S2, S3, etc.)
extern volatile uint8_t bitz;
#include "esp_idf_version.h" #include "esp_idf_version.h"
// NOTE: there is some intentional repetition in the macros and functions // NOTE: there is some intentional repetition in the macros and functions
@ -58,6 +60,7 @@ static hw_timer_t *_PM_esp32timer = NULL;
#define _PM_TIMER_DEFAULT &_PM_esp32timer #define _PM_TIMER_DEFAULT &_PM_esp32timer
extern IRAM_ATTR void _PM_row_handler(Protomatter_core *core); // In core.c extern IRAM_ATTR void _PM_row_handler(Protomatter_core *core); // In core.c
extern IRAM_ATTR void _PM_OE_off(Protomatter_core *core);
// Timer interrupt handler. This, _PM_row_handler() and any functions // Timer interrupt handler. This, _PM_row_handler() and any functions
// called by _PM_row_handler() should all have the IRAM_ATTR attribute // called by _PM_row_handler() should all have the IRAM_ATTR attribute
@ -65,7 +68,13 @@ extern IRAM_ATTR void _PM_row_handler(Protomatter_core *core); // In core.c
// callback invoked by the real ISR (in arduino-esp32's esp32-hal-timer.c) // callback invoked by the real ISR (in arduino-esp32's esp32-hal-timer.c)
// which takes care of interrupt status bits & such. // which takes care of interrupt status bits & such.
IRAM_ATTR static void _PM_esp32timerCallback(void) { IRAM_ATTR static void _PM_esp32timerCallback(void) {
_PM_row_handler(_PM_protoPtr); // In core.c bitz |= 2;
if (bitz == 3) {
_PM_row_handler(_PM_protoPtr); // In core.c
} else {
_PM_OE_off(_PM_protoPtr);
_PM_timerStop(_PM_protoPtr);
}
} }
// Set timer period, initialize count value to zero, enable timer. // Set timer period, initialize count value to zero, enable timer.

View file

@ -79,7 +79,8 @@ IRAM_ATTR inline uint32_t _PM_timerGetCount(Protomatter_core *core) {
// slightly different length of time, but duty cycle scales with this so it's // slightly different length of time, but duty cycle scales with this so it's
// perceptually consistent; don't see bright or dark rows. // perceptually consistent; don't see bright or dark rows.
#define _PM_minMinPeriod (200 + (uint32_t)core->chainBits * 2) //#define _PM_minMinPeriod (200 + (uint32_t)core->chainBits * 2)
#define _PM_minMinPeriod 40
#if (ESP_IDF_VERSION_MAJOR == 5) #if (ESP_IDF_VERSION_MAJOR == 5)
#include <esp_private/periph_ctrl.h> #include <esp_private/periph_ctrl.h>
@ -129,6 +130,7 @@ static void pinmux(int8_t pin, uint8_t signal) {
} }
#if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------ #if defined(ARDUINO) // COMPILING FOR ARDUINO ------------------------------
// LCD_CAM requires a complete replacement of the "blast" functions in order // LCD_CAM requires a complete replacement of the "blast" functions in order
// to use the DMA-based peripheral. // to use the DMA-based peripheral.
#define _PM_CUSTOM_BLAST // Disable blast_*() functions in core.c #define _PM_CUSTOM_BLAST // Disable blast_*() functions in core.c
@ -160,6 +162,19 @@ IRAM_ATTR static void blast_byte(Protomatter_core *core, uint8_t *data) {
// See notes near top of this file for what's done with this info. // See notes near top of this file for what's done with this info.
} }
volatile uint32_t bloop = 0;
extern volatile uint8_t bitz;
extern IRAM_ATTR void _PM_OE_off(Protomatter_core *core);
IRAM_ATTR static bool dma_callback(gdma_channel_handle_t dma_chan,
gdma_event_data_t *event_data, void *user_data) {
bitz |= 1; // DMA xfer has finished
if (bitz == 3)
_PM_row_handler(_PM_protoPtr); // In core.c
bloop++;
return true;
}
void _PM_timerInit(Protomatter_core *core) { void _PM_timerInit(Protomatter_core *core) {
// On S3, initialize the LCD_CAM peripheral and DMA. // On S3, initialize the LCD_CAM peripheral and DMA.
@ -247,9 +262,11 @@ void _PM_timerInit(Protomatter_core *core) {
gdma_set_transfer_ability(dma_chan, &ability); gdma_set_transfer_ability(dma_chan, &ability);
gdma_start(dma_chan, (intptr_t)&desc); gdma_start(dma_chan, (intptr_t)&desc);
// Enable TRANS_DONE interrupt. Note that we do NOT require nor install // Enable DMA transfer callback
// an interrupt service routine, but DO need to enable the TRANS_DONE gdma_tx_event_callbacks_t tx_cbs = {
// flag to make the LCD DMA transfer work. .on_trans_eof = dma_callback
};
gdma_register_tx_event_callbacks(dma_chan, &tx_cbs, NULL);
LCD_CAM.lc_dma_int_ena.val |= LCD_LL_EVENT_TRANS_DONE & 0x03; LCD_CAM.lc_dma_int_ena.val |= LCD_LL_EVENT_TRANS_DONE & 0x03;
_PM_esp32commonTimerInit(core); // In esp32-common.h _PM_esp32commonTimerInit(core); // In esp32-common.h

View file

@ -341,6 +341,7 @@ ProtomatterStatus _PM_begin(Protomatter_core *core) {
uint32_t minPeriodPerFrame = _PM_timerFreq / _PM_MAX_REFRESH_HZ; uint32_t minPeriodPerFrame = _PM_timerFreq / _PM_MAX_REFRESH_HZ;
uint32_t minPeriodPerLine = minPeriodPerFrame / core->numRowPairs; uint32_t minPeriodPerLine = minPeriodPerFrame / core->numRowPairs;
core->minPeriod = minPeriodPerLine / ((1 << core->numPlanes) - 1); core->minPeriod = minPeriodPerLine / ((1 << core->numPlanes) - 1);
core->minPeriod = _PM_minMinPeriod;
if (core->minPeriod < _PM_minMinPeriod) { if (core->minPeriod < _PM_minMinPeriod) {
core->minPeriod = _PM_minMinPeriod; core->minPeriod = _PM_minMinPeriod;
} }
@ -487,6 +488,13 @@ void _PM_deallocate(Protomatter_core *core) {
} }
} }
volatile uint8_t bitz = 3;
IRAM_ATTR void _PM_OE_off(Protomatter_core *core) {
_PM_clearReg(core->oe);
_PM_setReg(core->oe); // Disable LED output
}
// ISR function (in arch.h) calls this function which it extern'd. // ISR function (in arch.h) calls this function which it extern'd.
// Profuse apologies for the ESP32-specific IRAM_ATTR here -- the goal was // Profuse apologies for the ESP32-specific IRAM_ATTR here -- the goal was
// for all architecture-specific detauls to be in arch.h -- but the need // for all architecture-specific detauls to be in arch.h -- but the need
@ -497,6 +505,7 @@ void _PM_deallocate(Protomatter_core *core) {
// specific section of arch.h. Sorry. :/ // specific section of arch.h. Sorry. :/
// Any functions called by this function should also be IRAM_ATTR'd. // Any functions called by this function should also be IRAM_ATTR'd.
IRAM_ATTR void _PM_row_handler(Protomatter_core *core) { IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
bitz = 0;
_PM_setReg(core->oe); // Disable LED output _PM_setReg(core->oe); // Disable LED output
@ -577,7 +586,7 @@ IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
// Set timer and enable LED output for data loaded on PRIOR pass: // Set timer and enable LED output for data loaded on PRIOR pass:
_PM_timerStart(core, core->bitZeroPeriod << prevPlane); _PM_timerStart(core, core->bitZeroPeriod << prevPlane);
_PM_delayMicroseconds(1); // Appease Teensy4 // _PM_delayMicroseconds(1); // Appease Teensy4
_PM_clearReg(core->oe); // Enable LED output _PM_clearReg(core->oe); // Enable LED output
uint32_t elementsPerLine = uint32_t elementsPerLine =
@ -610,7 +619,7 @@ IRAM_ATTR void _PM_row_handler(Protomatter_core *core) {
// Timer is still running and counting up at this point. // Timer is still running and counting up at this point.
uint32_t elapsed = _PM_timerGetCount(core); uint32_t elapsed = _PM_timerGetCount(core);
// Nudge the plane-zero time up or down (filtering to avoid jitter) // Nudge the plane-zero time up or down (filtering to avoid jitter)
core->bitZeroPeriod = ((core->bitZeroPeriod * 7) + elapsed + 4) / 8; // core->bitZeroPeriod = ((core->bitZeroPeriod * 7) + elapsed + 4) / 8;
// But don't allow it to drop below the minimum period calculated during // But don't allow it to drop below the minimum period calculated during
// begin(), that's a hard limit and would just waste cycles. // begin(), that's a hard limit and would just waste cycles.
if (core->bitZeroPeriod < core->minPeriod) { if (core->bitZeroPeriod < core->minPeriod) {