Skip to content

Commit

Permalink
Merge (#411)
Browse files Browse the repository at this point in the history
* Fix Zero-Cross Dimmer for ESP32 with Core3 (arendst#19929)

* Fix Zero-Cross Dimmer for ESP32 with Core3

* Remove left-over

* Fix esp8266

* Berry ``debug.gcdebug()`` to enable GC debugging (arendst#19936)

---------

Co-authored-by: s-hadinger <[email protected]>
  • Loading branch information
Jason2866 and s-hadinger authored Nov 5, 2023
1 parent f969098 commit 1b50bda
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 69 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
## [13.2.0.2]
### Added
- Scripter TCP client (#19914)
- Berry ``debug.gcdebug()`` to enable GC debugging

### Breaking Changed

Expand All @@ -14,6 +15,7 @@ All notable changes to this project will be documented in this file.

### Fixed
- Scripter timer issue (#19914)
- Fix Zero-Cross Dimmer for ESP32 with Core3

### Removed

Expand Down
16 changes: 16 additions & 0 deletions lib/libesp32/berry/src/be_debuglib.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,19 @@ static int m_codedump(bvm *vm)
be_return_nil(vm);
}

static int m_gcdebug(bvm *vm) {
int argc = be_top(vm);
if (argc >= 1 && be_isbool(vm, 1)) {
if (be_tobool(vm, 1)) {
comp_set_gc_debug(vm);
} else {
comp_clear_gc_debug(vm);
}
}
be_pushbool(vm, comp_is_gc_debug(vm));
be_return(vm);
}

static int m_traceback(bvm *vm)
{
be_tracestack(vm);
Expand Down Expand Up @@ -223,6 +236,7 @@ be_native_module_attr_table(debug) {
be_native_module_function("varname", m_varname),
be_native_module_function("upvname", m_upvname)
#endif
be_native_module_function("gcdebug", m_gcdebug)
};

be_define_native_module(debug, NULL);
Expand All @@ -242,6 +256,8 @@ module debug (scope: global, depend: BE_USE_DEBUG_MODULE) {
allocs, func(m_allocs)
frees, func(m_frees)
reallocs, func(m_reallocs)
// GC debug mode
gcdebug, func(m_gcdebug)
}
@const_object_info_end */
#include "../generate/be_fixed_debug.h"
Expand Down
8 changes: 1 addition & 7 deletions lib/libesp32/berry/src/be_gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,15 +545,9 @@ static void reset_fixedlist(bvm *vm)

void be_gc_auto(bvm *vm)
{
#if BE_USE_DEBUG_GC
if (vm->gc.status & GC_PAUSE) { /* force gc each time it's possible */
if (vm->gc.status & GC_PAUSE && (BE_USE_DEBUG_GC || vm->gc.usage > vm->gc.threshold || comp_is_gc_debug(vm))) {
be_gc_collect(vm);
}
#else
if (vm->gc.status & GC_PAUSE && vm->gc.usage > vm->gc.threshold) {
be_gc_collect(vm);
}
#endif
}

size_t be_gc_memcount(bvm *vm)
Expand Down
6 changes: 3 additions & 3 deletions lib/libesp32/berry/src/be_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ BERRY_API void* be_realloc(bvm *vm, void *ptr, size_t old_size, size_t new_size)
vm->counter_mem_free++;
#endif
if (ptr == NULL) { return NULL; } /* safeguard */
#if BE_USE_DEBUG_GC
memset(ptr, 0xFF, old_size); /* fill the structure with invalid pointers */
#endif
if (BE_USE_DEBUG_GC || comp_is_gc_debug(vm)) {
memset(ptr, 0xFF, old_size); /* fill the structure with invalid pointers */
}
free_from_pool(vm, ptr, old_size);
break; /* early exit */
}
Expand Down
12 changes: 6 additions & 6 deletions lib/libesp32/berry/src/be_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ void be_gcstrtab(bvm *vm)
}
}
}
#if BE_USE_DEBUG_GC == 0
if (tab->count < size >> 2 && size > 8) {
resize(vm, size >> 1);
if (BE_USE_DEBUG_GC || comp_is_gc_debug(vm)) {
resize(vm, tab->count + 4);
} else {
if (tab->count < size >> 2 && size > 8) {
resize(vm, size >> 1);
}
}
#else
resize(vm, tab->count + 4);
#endif
}

uint32_t be_strhash(const bstring *s)
Expand Down
15 changes: 10 additions & 5 deletions lib/libesp32/berry/src/be_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@
#define comp_set_named_gbl(vm) ((vm)->compopt |= (1<<COMP_NAMED_GBL))
#define comp_clear_named_gbl(vm) ((vm)->compopt &= ~(1<<COMP_NAMED_GBL))

#define comp_is_strict(vm) ((vm)->compopt & (1<<COMP_STRICT))
#define comp_set_strict(vm) ((vm)->compopt |= (1<<COMP_STRICT))
#define comp_clear_strict(vm) ((vm)->compopt &= ~(1<<COMP_STRICT))
#define comp_is_strict(vm) ((vm)->compopt & (1<<COMP_STRICT))
#define comp_set_strict(vm) ((vm)->compopt |= (1<<COMP_STRICT))
#define comp_clear_strict(vm) ((vm)->compopt &= ~(1<<COMP_STRICT))

#define comp_is_gc_debug(vm) ((vm)->compopt & (1<<COMP_GC_DEBUG))
#define comp_set_gc_debug(vm) ((vm)->compopt |= (1<<COMP_GC_DEBUG))
#define comp_clear_gc_debug(vm) ((vm)->compopt &= ~(1<<COMP_GC_DEBUG))

/* Compilation options */
typedef enum {
COMP_NAMED_GBL = 0x00, /* compile with named globals */
COMP_STRICT = 0x01, /* compile with named globals */
COMP_NAMED_GBL = 0x00, /* compile with named globals */
COMP_STRICT = 0x01, /* compile with named globals */
COMP_GC_DEBUG = 0x02, /* compile with gc debug */
} compoptmask;

typedef struct {
Expand Down
2 changes: 1 addition & 1 deletion tasmota/include/tasmota_configurations_ESP32.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@

// -- Optional modules ----------------------------
#undef USE_SHUTTER // Disable Shutter support for up to 4 shutter with different motortypes (+6k code)
#undef USE_AC_ZERO_CROSS_DIMMER // API for timers has changed with IDF 5.x
#define USE_AC_ZERO_CROSS_DIMMER // Enable support for AC_ZERO_CROSS_DIMMER

#define USE_I2S
#define USE_SPI
Expand Down
111 changes: 64 additions & 47 deletions tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@

#define XDRV_68 68


#if !defined(ESP32) || (ESP_IDF_VERSION_MAJOR < 5) // temporarily disable for IDF 5.0

static const uint8_t TRIGGER_PERIOD = 75;

#define ZCDIMMERSET_SHOW 1
Expand Down Expand Up @@ -64,7 +61,7 @@ void (* const ZCDimmerCommand[])(void) PROGMEM = {
&CmndZCDimmerSet//,&CmndZCGateEnableTime
};

void IRAM_ATTR ACDimmerZeroCross(uint32_t time) {
extern "C" void IRAM_ATTR ACDimmerZeroCross(uint32_t time) {
ac_zero_cross_dimmer.dimmer_in_use = false;
ac_zero_cross_dimmer.cycle_time_us = time - ac_zero_cross_dimmer.crossed_zero_at;
ac_zero_cross_dimmer.crossed_zero_at = time;
Expand All @@ -76,12 +73,6 @@ void IRAM_ATTR ACDimmerZeroCross(uint32_t time) {
}
}

uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() {
//ACDimmerTimer_intr();
ACDimmerTimer_intr();
return ac_zero_cross_dimmer.actual_tigger_Period * 80;
}

void ACDimmerInit()
{
for (uint8_t i = 0 ; i < 5; i++) {
Expand All @@ -90,40 +81,7 @@ void ACDimmerInit()
}
}

void ACDimmerInterruptDisable(bool disable)
{
AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer enabled: %d"),!disable);
ac_zero_cross_dimmer.timer_iterrupt_started = !disable;
if (disable) {
//stop the interrupt
#ifdef ESP32
if (dimmer_timer != nullptr) {
timerAlarmDisable(dimmer_timer);
}
#endif
} else {
for (uint8_t i = 0 ; i < MAX_PWMS; i++) {
if (Pin(GPIO_PWM1, i) != -1) {
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer Pin %d set"),Pin(GPIO_PWM1, i));
}
}
#ifdef ESP32
if (dimmer_timer == nullptr) {
// 80 Divider -> 1 count=1µs
dimmer_timer = timerBegin(0, 80, true);
timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr, true);
// For ESP32, we can't use dynamic interval calculation because the timerX functions
// are not callable from ISR (placed in flash storage).
// Here we just use an interrupt firing every 75 µs.
timerAlarmWrite(dimmer_timer, TRIGGER_PERIOD , true);
}
timerAlarmEnable(dimmer_timer);
#endif
}
}

void IRAM_ATTR ACDimmerTimer_intr() {
extern "C" void IRAM_ATTR ACDimmerTimer_intr() {

uint32_t time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at;
// If no ZC signal received yet.
Expand Down Expand Up @@ -165,6 +123,62 @@ void IRAM_ATTR ACDimmerTimer_intr() {
}
}

#ifdef ESP8266
extern "C" uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() {
ACDimmerTimer_intr();
return ac_zero_cross_dimmer.actual_tigger_Period * 80;
}
#endif // ESP8266

void ACDimmerInterruptDisable(bool disable)
{
AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer enabled: %d"),!disable);
ac_zero_cross_dimmer.timer_iterrupt_started = !disable;
if (disable) {
//stop the interrupt
#ifdef ESP32
if (dimmer_timer != nullptr) {
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) )
timerStop(dimmer_timer);
#else // ESP_ARDUINO_VERSION_MAJOR >= 3
timerAlarmDisable(dimmer_timer);
#endif // ESP_ARDUINO_VERSION_MAJOR >= 3
}
#endif
} else {
for (uint8_t i = 0 ; i < MAX_PWMS; i++) {
if (Pin(GPIO_PWM1, i) != -1) {
pinMode(Pin(GPIO_PWM1, i), OUTPUT);
AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer Pin %d set"),Pin(GPIO_PWM1, i));
}
}
#ifdef ESP32
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) )
if (dimmer_timer == nullptr) {
dimmer_timer = timerBegin(1000000); // 1 MHz
timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr);
// For ESP32, we can't use dynamic interval calculation because the timerX functions
// are not callable from ISR (placed in flash storage).
// Here we just use an interrupt firing every 75 µs.
timerAlarm(dimmer_timer, TRIGGER_PERIOD, true, 0);
}
timerStart(dimmer_timer);
#else // ESP_ARDUINO_VERSION_MAJOR >= 3
if (dimmer_timer == nullptr) {
// 80 Divider -> 1 count=1µs
dimmer_timer = timerBegin(0, 80, true);
timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr, true);
// For ESP32, we can't use dynamic interval calculation because the timerX functions
// are not callable from ISR (placed in flash storage).
// Here we just use an interrupt firing every 75 µs.
timerAlarmWrite(dimmer_timer, TRIGGER_PERIOD , true);
}
timerAlarmEnable(dimmer_timer);
#endif // ESP_ARDUINO_VERSION_MAJOR >= 3
#endif
}
}

void ACDimmerControllTrigger(void) {
#ifdef ESP32
if (ac_zero_cross_dimmer.timer_iterrupt_started != ac_zero_cross_dimmer.dimmer_in_use) {
Expand Down Expand Up @@ -204,10 +218,15 @@ void ACDimmerLogging(void)
bool alarmEnabled = false;
uint32_t timercounter = ac_zero_cross_dimmer.intr_counter;

#ifdef ESP32
#ifdef ESP32
if (dimmer_timer != nullptr) {
#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) )
alarmEnabled = true; // we assume it's started, there is no API to check whether it's running
timercounter = (uint32_t)timerRead(dimmer_timer);
#else // ESP_ARDUINO_VERSION_MAJOR >= 3
alarmEnabled = timerAlarmEnabled(dimmer_timer);
timercounter = (uint32_t)timerRead(dimmer_timer);
#endif // ESP_ARDUINO_VERSION_MAJOR >= 3
}
#endif

Expand Down Expand Up @@ -302,6 +321,4 @@ bool Xdrv68(uint32_t function)
return result;
}

#endif // !enabled(ESP32) || (ESP_IDF_VERSION_MAJOR < 5)

#endif // USE_AC_ZERO_CROSS_DIMMER

0 comments on commit 1b50bda

Please sign in to comment.