Skip to content

Commit 692512c

Browse files
Merge branch 'contrib/github_pr_15717' into 'master'
feat(ulp): LP Timer interrupt support (GitHub PR) Closes IDFGH-15026 See merge request espressif/esp-idf!38613
2 parents 382121b + 954d129 commit 692512c

File tree

15 files changed

+222
-1
lines changed

15 files changed

+222
-1
lines changed

components/hal/esp32c5/include/hal/lp_timer_ll.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uin
7373
dev->lp_int_clr.val = mask;
7474
}
7575

76+
FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, bool enable)
77+
{
78+
dev->lp_int_ena.main_timer_lp_int_ena = enable;
79+
}
80+
7681
#ifdef __cplusplus
7782
}
7883
#endif

components/hal/esp32c6/include/hal/lp_timer_ll.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -73,6 +73,11 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uin
7373
dev->lp_int_clr.val = mask;
7474
}
7575

76+
FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, bool enable)
77+
{
78+
dev->lp_int_en.alarm = enable;
79+
}
80+
7681
#ifdef __cplusplus
7782
}
7883
#endif

components/hal/esp32c61/include/hal/lp_timer_ll.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uin
7373
dev->lp_int_clr.val = mask;
7474
}
7575

76+
FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, bool enable)
77+
{
78+
dev->lp_int_ena.main_timer_lp_int_ena = enable;
79+
}
80+
7681
#ifdef __cplusplus
7782
}
7883
#endif

components/hal/esp32h2/include/hal/lp_timer_ll.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_overflow_intr_status(lp_timer_dev_t *de
5757
dev->int_clr.overflow = 1;
5858
}
5959

60+
FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, bool enable)
61+
{
62+
dev->lp_int_en.alarm = enable;
63+
}
64+
6065
#ifdef __cplusplus
6166
}
6267
#endif

components/hal/esp32p4/include/hal/lp_timer_ll.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ FORCE_INLINE_ATTR void lp_timer_ll_clear_lp_intsts_mask(lp_timer_dev_t *dev, uin
7373
dev->lp_int_clr.val = mask;
7474
}
7575

76+
FORCE_INLINE_ATTR void lp_timer_ll_lp_alarm_intr_enable(lp_timer_dev_t *dev, bool enable)
77+
{
78+
dev->lp_int_ena.main_timer_lp_int_ena = enable;
79+
}
80+
7681
#ifdef __cplusplus
7782
}
7883
#endif

components/ulp/lp_core/lp_core/include/ulp_lp_core_utils.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,20 @@ void ulp_lp_core_sw_intr_enable(bool enable);
104104
*/
105105
void ulp_lp_core_sw_intr_clear(void);
106106

107+
#if SOC_LP_TIMER_SUPPORTED
108+
/**
109+
* @brief Enable the LP Timer interrupt
110+
*
111+
*/
112+
void ulp_lp_core_lp_timer_intr_enable(bool enable);
113+
114+
/**
115+
* @brief Clear the interrupt status for the LP Timer interrupt
116+
*
117+
*/
118+
void ulp_lp_core_lp_timer_intr_clear(void);
119+
#endif
120+
107121
/**
108122
* @brief Puts the CPU into a wait state until an interrupt is triggered
109123
*

components/ulp/lp_core/lp_core/lp_core_utils.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,18 @@ void ulp_lp_core_sw_intr_clear(void)
191191
pmu_ll_lp_clear_sw_intr_status(&PMU);
192192
}
193193

194+
#if SOC_LP_TIMER_SUPPORTED
195+
void ulp_lp_core_lp_timer_intr_enable(bool enable)
196+
{
197+
lp_timer_ll_lp_alarm_intr_enable(&LP_TIMER, enable);
198+
}
199+
200+
void ulp_lp_core_lp_timer_intr_clear(void)
201+
{
202+
lp_timer_ll_clear_lp_alarm_intr_status(&LP_TIMER);
203+
}
204+
#endif
205+
194206
void ulp_lp_core_wait_for_intr(void)
195207
{
196208
asm volatile("wfi");

examples/system/.build-test-rules.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,12 @@ examples/system/ulp/lp_core/lp_spi:
334334
depends_components:
335335
- ulp
336336

337+
examples/system/ulp/lp_core/lp_timer_interrupt:
338+
disable:
339+
- if: (SOC_LP_CORE_SUPPORTED != 1) or (SOC_LP_TIMER_SUPPORTED != 1)
340+
depends_components:
341+
- ulp
342+
337343
examples/system/ulp/lp_core/lp_touch:
338344
enable:
339345
- if: SOC_TOUCH_SENSOR_SUPPORTED == 1 and (SOC_DEEP_SLEEP_SUPPORTED == 1 and SOC_LP_CORE_SUPPORTED == 1)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# For more information about build system see
2+
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
3+
# The following five lines of boilerplate have to be in your project's
4+
# CMakeLists in this exact order for cmake to work correctly
5+
cmake_minimum_required(VERSION 3.16)
6+
7+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
8+
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
9+
# idf_build_set_property(MINIMAL_BUILD ON)
10+
project(interrupts)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-P4 |
2+
| ----------------- | -------- | -------- | -------- |
3+
4+
# LP-Core example with interrupt triggered from LP Timer
5+
6+
This example demonstrates how to program the ULP coprocessor to receive an interrupt triggered by the LP Timer
7+
8+
ULP program written in C can be found across `lp_core/main.c`. The build system compiles and links this program, converts it into binary format, and embeds it into the .rodata section of the ESP-IDF application.
9+
10+
At runtime, the application running inside the main CPU loads ULP program into the `RTC_SLOW_MEM` memory region using `ulp_lp_core_load_binary` function. The main code then configures the ULP and starts the coprocessor by using `ulp_lp_core_run`. Once the ULP program is started, it runs continuously, waiting for interrupts. The main program will periodically trigger interrupts on the LP-Core.
11+
12+
The main core will continuously read a counter of interrupts received as reported by the LP-Core.
13+
14+
## Example output
15+
16+
```
17+
LP core loaded with firmware and running successfully
18+
Interrupt count: 6
19+
```

0 commit comments

Comments
 (0)