Skip to content

Commit 056c404

Browse files
committed
Merge branch 'feature/mailbox' into 'master'
feat(mailbox): define and implement a mailbox API for the ESP32-P4 See merge request espressif/esp-idf!39925
2 parents 9fee9cc + 32bb32b commit 056c404

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2385
-291
lines changed

components/esp_hw_support/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ if(NOT non_os_build)
5757
if(CONFIG_SOC_MODEM_SUPPORT_ETM)
5858
list(APPEND srcs "modem/modem_etm.c")
5959
endif()
60+
if(CONFIG_SOC_PMU_SUPPORTED)
61+
list(APPEND srcs "pmu_share_hw.c")
62+
endif()
6063
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED)
6164
list(APPEND srcs "sleep_modem.c"
6265
"sleep_modes.c"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
/**
14+
* @brief Acquire PMU lock
15+
*
16+
* @note If any of the locks are taken, this API will wait until the lock is successfully acquired.
17+
*/
18+
void pmu_lock_acquire(void);
19+
20+
/**
21+
* @brief Release PMU lock
22+
*/
23+
void pmu_lock_release(void);
24+
25+
#ifdef __cplusplus
26+
}
27+
#endif
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/**
8+
* PMU is currently only used by the software mailbox, but it could be used by multiple components
9+
*/
10+
11+
#include <esp_types.h>
12+
#include "sdkconfig.h"
13+
#include "esp_private/critical_section.h"
14+
#include "esp_private/pmu_share_hw.h"
15+
16+
17+
DEFINE_CRIT_SECTION_LOCK_STATIC(s_pmu_lock);
18+
19+
void pmu_lock_acquire(void)
20+
{
21+
esp_os_enter_critical(&s_pmu_lock);
22+
}
23+
24+
25+
void pmu_lock_release(void)
26+
{
27+
esp_os_exit_critical(&s_pmu_lock);
28+
}

components/hal/esp32c5/include/hal/pmu_ll.h

Lines changed: 16 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
*/
@@ -522,6 +522,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
522522
hw->hp_ext.int_clr.reject = 1;
523523
}
524524

525+
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
526+
{
527+
hw->hp_ext.int_ena.sw = enable;
528+
}
529+
525530
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw)
526531
{
527532
return hw->wakeup.status0;
@@ -703,6 +708,16 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask)
703708
hw->lp_ext.int_clr.val = mask;
704709
}
705710

711+
FORCE_INLINE_ATTR void pmu_ll_lp_trigger_sw_intr(pmu_dev_t *hw)
712+
{
713+
hw->hp_lp_cpu_comm.lp_trigger_hp = 1;
714+
}
715+
716+
FORCE_INLINE_ATTR void pmu_ll_hp_trigger_sw_intr(pmu_dev_t *hw)
717+
{
718+
hw->hp_lp_cpu_comm.hp_trigger_lp = 1;
719+
}
720+
706721
FORCE_INLINE_ATTR void pmu_ll_lp_clear_sw_intr_status(pmu_dev_t *hw)
707722
{
708723
hw->lp_ext.int_clr.sw_trigger = 1;

components/hal/esp32c6/include/hal/pmu_ll.h

Lines changed: 16 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
*/
@@ -522,6 +522,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw)
522522
hw->hp_ext.int_clr.reject = 1;
523523
}
524524

525+
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
526+
{
527+
hw->hp_ext.int_ena.sw = enable;
528+
}
529+
525530
FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw)
526531
{
527532
return hw->wakeup.status0;
@@ -542,6 +547,16 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask)
542547
hw->lp_ext.int_clr.val = mask;
543548
}
544549

550+
FORCE_INLINE_ATTR void pmu_ll_lp_trigger_sw_intr(pmu_dev_t *hw)
551+
{
552+
hw->hp_lp_cpu_comm.lp_trigger_hp = 1;
553+
}
554+
555+
FORCE_INLINE_ATTR void pmu_ll_hp_trigger_sw_intr(pmu_dev_t *hw)
556+
{
557+
hw->hp_lp_cpu_comm.hp_trigger_lp = 1;
558+
}
559+
545560
FORCE_INLINE_ATTR void pmu_ll_lp_clear_sw_intr_status(pmu_dev_t *hw)
546561
{
547562
hw->lp_ext.int_clr.sw_trigger = 1;
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// The LL layer for ESP32-P4 LP Mailbox register operations
8+
9+
#pragma once
10+
11+
#include <stdlib.h>
12+
#include <stdbool.h>
13+
#include "soc/soc.h"
14+
#include "soc/lp_mailbox_struct.h"
15+
#include "soc/lp_mailbox_reg.h"
16+
#include "hal/misc.h"
17+
#include "esp_attr.h"
18+
19+
#define LP_MAILBOX_LL_MSG_COUNT 16U
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
25+
26+
/**
27+
* @brief Get a message (32-bit value) from the LP mailbox.
28+
*
29+
* @param dev Pointer to the LP mailbox device structure.
30+
* @param index Index of the message to retrieve (must be less than LP_MAILBOX_LL_MSG_COUNT).
31+
*
32+
* @return The 32-bit message value at the specified index, or 0 if the index is out of range.
33+
*/
34+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_message(lp_mb_dev_t *dev, int index)
35+
{
36+
if (index < LP_MAILBOX_LL_MSG_COUNT) {
37+
return (&dev->message_0.val)[index];
38+
}
39+
return 0;
40+
}
41+
42+
/**
43+
* @brief Set a message in the LP mailbox.
44+
*
45+
* @note Writing a message in the mailbox will set the corresponding message's intr_raw bit for
46+
* both the LP and HP registers, regardless of the writer!
47+
*
48+
* @param dev Pointer to the LP mailbox device structure.
49+
* @param index Index of the message to set (must be less than LP_MAILBOX_LL_MSG_COUNT).
50+
* @param val Message (32-bit value) to write to the specified message index.
51+
*/
52+
FORCE_INLINE_ATTR void lp_mailbox_ll_set_message(lp_mb_dev_t *dev, int index, uint32_t val)
53+
{
54+
if (index < LP_MAILBOX_LL_MSG_COUNT) {
55+
(&dev->message_0.val)[index] = val;
56+
}
57+
}
58+
59+
/**
60+
* @brief Get the raw status of the LP core interrupt register.
61+
*
62+
* @param dev Pointer to the LP mailbox device structure.
63+
*
64+
* @return Raw interrupt status value.
65+
*/
66+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_lp_intr_raw(lp_mb_dev_t *dev)
67+
{
68+
return dev->lp_int_raw.val;
69+
}
70+
71+
/**
72+
* @brief Clear LP core interrupt register bits.
73+
*
74+
* @param dev Pointer to the LP mailbox device structure.
75+
* @param mask Bitmask of interrupts to clear, bit `i` represents message `i`.
76+
*/
77+
FORCE_INLINE_ATTR void lp_mailbox_ll_lp_intr_clear(lp_mb_dev_t *dev, uint32_t mask)
78+
{
79+
dev->lp_int_clr.val = mask;
80+
}
81+
82+
/**
83+
* @brief Get the LP core interrupt register status.
84+
*
85+
* @param dev Pointer to the LP mailbox device structure.
86+
*
87+
* @return Interrupt status value.
88+
*/
89+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_status(lp_mb_dev_t *dev)
90+
{
91+
return dev->lp_int_st.val;
92+
}
93+
94+
/**
95+
* @brief Enable mailbox interrupts by mask for the LP core.
96+
*
97+
* @param dev Pointer to the LP mailbox device structure.
98+
* @param mask Bitmask of interrupts to enable, bit `i` represents message `i`.
99+
*
100+
* @return Updated interrupt enable register value.
101+
*/
102+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_enable_mask(lp_mb_dev_t *dev, uint32_t mask)
103+
{
104+
dev->lp_int_ena.val |= mask;
105+
return dev->lp_int_ena.val;
106+
}
107+
108+
/**
109+
* @brief Disable LP core mailbox interrupts by mask.
110+
*
111+
* @param dev Pointer to the LP mailbox device structure.
112+
* @param mask Bitmask of interrupts to disable, bit `i` represents message `i`.
113+
*
114+
* @return Updated interrupt enable register value.
115+
*/
116+
117+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_lp_intr_disable_mask(lp_mb_dev_t *dev, uint32_t mask)
118+
{
119+
dev->lp_int_ena.val &= ~mask;
120+
return dev->lp_int_ena.val;
121+
}
122+
123+
/**
124+
* @brief Get the raw status of the HP core interrupt register.
125+
*
126+
* @param dev Pointer to the LP mailbox device structure.
127+
*
128+
* @return Raw interrupt status value.
129+
*/
130+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_get_hp_intr_raw(lp_mb_dev_t *dev)
131+
{
132+
return dev->hp_int_raw.val;
133+
}
134+
135+
/**
136+
* @brief Clear HP core interrupt register bits.
137+
*
138+
* @param dev Pointer to the LP mailbox device structure.
139+
* @param mask Bitmask of interrupts to clear, bit `i` represents message `i`.
140+
*/
141+
FORCE_INLINE_ATTR void lp_mailbox_ll_hp_intr_clear(lp_mb_dev_t *dev, uint32_t mask)
142+
{
143+
dev->hp_int_clr.val = mask;
144+
}
145+
146+
/**
147+
* @brief Get the HP core interrupt register status.
148+
*
149+
* @param dev Pointer to the LP mailbox device structure.
150+
*
151+
* @return Interrupt status value.
152+
*/
153+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_status(lp_mb_dev_t *dev)
154+
{
155+
return dev->hp_int_st.val;
156+
}
157+
158+
/**
159+
* @brief Enable mailbox interrupts by mask for the HP core.
160+
*
161+
* @param dev Pointer to the LP mailbox device structure.
162+
* @param mask Bitmask of interrupts to enable, bit `i` represents message `i`.
163+
*
164+
* @return Updated interrupt enable register value.
165+
*/
166+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_enable_mask(lp_mb_dev_t *dev, uint32_t mask)
167+
{
168+
dev->hp_int_ena.val |= mask;
169+
return dev->hp_int_ena.val;
170+
}
171+
172+
/**
173+
* @brief Disable HP core mailbox interrupts by mask.
174+
*
175+
* @param dev Pointer to the LP mailbox device structure.
176+
* @param mask Bitmask of interrupts to disable, bit `i` represents message `i`.
177+
*
178+
* @return Updated interrupt enable register value.
179+
*/
180+
FORCE_INLINE_ATTR uint32_t lp_mailbox_ll_hp_intr_disable_mask(lp_mb_dev_t *dev, uint32_t mask)
181+
{
182+
dev->hp_int_ena.val &= ~mask;
183+
return dev->hp_int_ena.val;
184+
}
185+
186+
#ifdef __cplusplus
187+
}
188+
#endif

components/hal/esp32p4/include/hal/pmu_ll.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw)
493493
hw->wakeup.cntl4.slp_reject_cause_clr = 1;
494494
}
495495

496+
FORCE_INLINE_ATTR void pmu_ll_hp_enable_sw_intr(pmu_dev_t *hw, bool enable)
497+
{
498+
hw->hp_ext.int_ena.sw = enable;
499+
}
500+
496501
FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_wakeup(pmu_dev_t *hw)
497502
{
498503
return (hw->hp_ext.int_raw.wakeup == 1);
@@ -503,6 +508,16 @@ FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_reject(pmu_dev_t *hw)
503508
return (hw->hp_ext.int_raw.reject == 1);
504509
}
505510

511+
FORCE_INLINE_ATTR void pmu_ll_lp_trigger_sw_intr(pmu_dev_t *hw)
512+
{
513+
hw->hp_lp_cpu_comm.lp_trigger_hp = 1;
514+
}
515+
516+
FORCE_INLINE_ATTR void pmu_ll_hp_trigger_sw_intr(pmu_dev_t *hw)
517+
{
518+
hw->hp_lp_cpu_comm.hp_trigger_lp = 1;
519+
}
520+
506521
FORCE_INLINE_ATTR void pmu_ll_hp_clear_sw_intr_status(pmu_dev_t *hw)
507522
{
508523
hw->hp_ext.int_clr.sw = 1;

components/soc/esp32p4/include/soc/Kconfig.soc_caps.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ config SOC_LP_VAD_SUPPORTED
283283
bool
284284
default y
285285

286+
config SOC_LP_MAILBOX_SUPPORTED
287+
bool
288+
default y
289+
286290
config SOC_SPIRAM_SUPPORTED
287291
bool
288292
default y

components/soc/esp32p4/include/soc/soc_caps.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#define SOC_LP_SPI_SUPPORTED 1
9494
#define SOC_LP_ADC_SUPPORTED 1
9595
#define SOC_LP_VAD_SUPPORTED 1
96+
#define SOC_LP_MAILBOX_SUPPORTED 1
9697
#define SOC_SPIRAM_SUPPORTED 1
9798
#define SOC_PSRAM_DMA_CAPABLE 1
9899
#define SOC_SDMMC_HOST_SUPPORTED 1

components/soc/esp32p4/ld/esp32p4.peripherals.ld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ PROVIDE ( LP_AON_CLKRST = 0x50111000 );
7676
PROVIDE ( EFUSE = 0x5012D000 );
7777
PROVIDE ( LPPERI = 0x50120000 );
7878
PROVIDE ( LP_TIMER = 0x50112000 );
79+
PROVIDE ( LP_MAILBOX = 0x50118000 );
7980
PROVIDE ( LP_UART = 0x50121000 );
8081
PROVIDE ( LP_I2C = 0x50122000 );
8182
PROVIDE ( LP_SPI = 0x50123000 );

0 commit comments

Comments
 (0)