diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index f5f56cc835..430f7d5b2e 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -160,8 +160,8 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_ uint32_t* base = RTC_SLOW_MEM; #endif - //Start by clearing memory reserved with zeros, this will also will initialize the bss: - memset(base, 0, ULP_COPROC_RESERVE_MEM); + /* Clear only program size bytes to avoid clearing the shared memory */ + memset(base, 0, program_size_bytes); memcpy(base, program_binary, program_size_bytes); return ESP_OK; diff --git a/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h b/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h index 8d20d1f43c..e4965120a3 100644 --- a/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h +++ b/components/ulp/lp_core/lp_core/include/ulp_lp_core_interrupts.h @@ -55,6 +55,10 @@ void ulp_lp_core_intr_enable(void); */ void ulp_lp_core_intr_disable(void); +#if SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR +int ulp_lp_core_intr_set_handler(int intr_source, void (*handler)(void *arg), void *arg); +#endif + #ifdef __cplusplus } #endif diff --git a/components/ulp/lp_core/lp_core/lp_core_interrupt.c b/components/ulp/lp_core/lp_core/lp_core_interrupt.c index 66bcb86b01..05af9ce7b8 100644 --- a/components/ulp/lp_core/lp_core/lp_core_interrupt.c +++ b/components/ulp/lp_core/lp_core/lp_core_interrupt.c @@ -70,23 +70,40 @@ void __attribute__((weak, alias("ulp_lp_core_default_intr_handler"))) ulp_lp_cor #if SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR -static void* s_intr_handlers[] = { - ulp_lp_core_lp_io_intr_handler, - ulp_lp_core_lp_i2c_intr_handler, - ulp_lp_core_lp_uart_intr_handler, - ulp_lp_core_lp_timer_intr_handler, - 0, // Reserved / Unused - ulp_lp_core_lp_pmu_intr_handler, +typedef struct { + void (*handler)(void *arg); + void *arg; +} ulp_lp_core_intr_handler_t; + +static ulp_lp_core_intr_handler_t s_intr_handlers[] = { + {(void (*)(void *))ulp_lp_core_lp_io_intr_handler, NULL}, + {(void (*)(void *))ulp_lp_core_lp_i2c_intr_handler, NULL}, + {(void (*)(void *))ulp_lp_core_lp_uart_intr_handler, NULL}, + {(void (*)(void *))ulp_lp_core_lp_timer_intr_handler, NULL}, + {NULL, NULL}, // Reserved / Unused + {(void (*)(void *))ulp_lp_core_lp_pmu_intr_handler, NULL}, }; +int ulp_lp_core_intr_set_handler(int intr_source, void (*handler)(void *arg), void *arg) +{ + if (intr_source < 0 || intr_source >= sizeof(s_intr_handlers) / sizeof(s_intr_handlers[0])) { + return -1; + } + + s_intr_handlers[intr_source].handler = handler; + s_intr_handlers[intr_source].arg = arg; + + return 0; +} + void __attribute__((weak)) ulp_lp_core_intr_handler(void) { uint8_t intr_source = lp_core_ll_get_triggered_interrupt_srcs(); - for (int i = 0; i < sizeof(s_intr_handlers) / 4; i++) { + for (int i = 0; i < sizeof(s_intr_handlers) / sizeof(s_intr_handlers[0]); i++) { if (intr_source & (1 << i)) { - void (*handler)(void) = s_intr_handlers[i]; - if (handler) { - handler(); + ulp_lp_core_intr_handler_t *handler_entry = &s_intr_handlers[i]; + if (handler_entry->handler) { + handler_entry->handler(handler_entry->arg); } } }