Skip to content

Commit f54c09e

Browse files
committed
Merge branch 'feat/esp_hal_timg' into 'master'
feat(timg): graduate the hal driver into a single component Closes IDF-14095 See merge request espressif/esp-idf!42202
2 parents 33321e5 + 71cb24c commit f54c09e

File tree

85 files changed

+1117
-787
lines changed

Some content is hidden

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

85 files changed

+1117
-787
lines changed

components/bootloader_support/src/bootloader_utility.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "soc/rtc.h"
2525
#include "soc/efuse_periph.h"
2626
#include "soc/rtc_periph.h"
27-
#include "soc/timer_periph.h"
2827
#include "hal/mmu_hal.h"
2928
#include "hal/mmu_ll.h"
3029
#include "hal/cache_types.h"

components/esp_driver_gptimer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ if(CONFIG_SOC_TIMER_SUPPORT_ETM)
1414
list(APPEND srcs "src/gptimer_etm.c")
1515
endif()
1616

17-
set(requires esp_pm)
17+
set(requires esp_pm esp_hal_timg)
1818

1919
idf_component_register(SRCS ${srcs}
2020
INCLUDE_DIRS ${public_include}

components/esp_driver_gptimer/linker.lf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ entries:
1212
gptimer: gptimer_stop (noflash)
1313

1414
[mapping:gptimer_hal]
15-
archive: libhal.a
15+
archive: libesp_hal_timg.a
1616
entries:
1717
if GPTIMER_ISR_HANDLER_IN_IRAM = y:
1818
timer_hal: timer_hal_capture_and_get_counter_value (noflash)

components/esp_driver_gptimer/src/gptimer_common.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ gptimer_group_t *gptimer_acquire_group_handle(int group_id)
5050
// we need to increase/decrease the reference count before enable/disable/reset the peripheral
5151
PERIPH_RCC_ACQUIRE_ATOMIC(soc_timg_gptimer_signals[group_id][0].parent_module, ref_count) {
5252
if (ref_count == 0) {
53-
timer_ll_enable_bus_clock(group_id, true);
54-
timer_ll_reset_register(group_id);
53+
timg_ll_enable_bus_clock(group_id, true);
54+
timg_ll_reset_register(group_id);
5555
}
5656
}
5757
ESP_LOGD(TAG, "new group (%d) @%p", group_id, group);
@@ -78,7 +78,7 @@ void gptimer_release_group_handle(gptimer_group_t *group)
7878
// disable bus clock for the timer group
7979
PERIPH_RCC_RELEASE_ATOMIC(soc_timg_gptimer_signals[group_id][0].parent_module, ref_count) {
8080
if (ref_count == 0) {
81-
timer_ll_enable_bus_clock(group_id, false);
81+
timg_ll_enable_bus_clock(group_id, false);
8282
}
8383
}
8484
free(group);

components/esp_driver_gptimer/test_apps/.build-test-rules.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ components/esp_driver_gptimer/test_apps/gptimer:
55
- if: SOC_GPTIMER_SUPPORTED != 1
66
depends_components:
77
- esp_driver_gptimer
8+
- esp_hal_timg
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
idf_build_get_property(target IDF_TARGET)
2+
if(${target} STREQUAL "linux")
3+
return() # This component is not supported by the POSIX/Linux simulator
4+
endif()
5+
6+
set(srcs)
7+
set(public_include "include" "${target}/include")
8+
9+
if(CONFIG_SOC_GPTIMER_SUPPORTED)
10+
list(APPEND srcs "timer_hal.c" "${target}/timer_periph.c")
11+
endif()
12+
13+
idf_component_register(SRCS ${srcs}
14+
INCLUDE_DIRS ${public_include}
15+
REQUIRES soc hal)

components/esp_hal_timg/README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# ESP Hardware Abstraction Layer for Timer Groups (`esp_hal_timg`)
2+
3+
⚠️ **Notice**: This HAL component is under active development. API stability and backward-compatibility between versions are not guaranteed at this time.
4+
5+
## Overview
6+
7+
The `esp_hal_timg` component provides a **Hardware Abstraction Layer** for the General Purpose Timer peripherals across all ESP-IDF supported targets. It serves as a foundation for the higher-level timer drivers, offering a consistent interface to interact with timer hardware while hiding the complexities of chip-specific implementations.
8+
9+
## Architecture
10+
11+
The HAL architecture consists of two primary layers:
12+
13+
1. **HAL Layer (Upper)**: Defines the operational sequences and data structures required to interact with timer peripherals, including:
14+
- Initialization and deinitialization
15+
- Timer control operations (start, stop, reload)
16+
- Alarm and event handling
17+
- Counter operations
18+
19+
2. **Low-Level Layer (Bottom)**: Acts as a translation layer between the HAL and the register definitions in the `soc` component, handling:
20+
- Register access abstractions
21+
- Chip-specific register configurations
22+
- Hardware feature compatibility
23+
24+
## Features
25+
26+
- Unified timer interface across all ESP chip families
27+
- Support for different timer counting modes (up/down)
28+
- Alarm functionality with configurable triggers
29+
- Auto-reload capability
30+
- ETM (Event Task Matrix) integration on supported chips
31+
- Multiple clock source options
32+
33+
## Usage
34+
35+
This component is primarily used by ESP-IDF peripheral drivers such as `esp_driver_gptimer`. It is also utilized by system components like `esp_timer`.
36+
37+
For advanced developers implementing custom timer solutions, the HAL functions can be used directly. However, please note that the interfaces provided by this component are internal to ESP-IDF and are subject to change.
38+
39+
## Dependencies
40+
41+
- `soc`: Provides chip-specific register definitions
42+
- `hal`: Core hardware abstraction utilities and macros
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <stdbool.h>
10+
#include "hal/assert.h"
11+
#include "hal/misc.h"
12+
#include "hal/timg_ll.h"
13+
#include "soc/timer_group_struct.h"
14+
#include "soc/dport_reg.h"
15+
16+
#ifdef __cplusplus
17+
extern "C" {
18+
#endif
19+
20+
// Get timer group register base address with giving group number
21+
#define LACT_LL_GET_HW(group_id) ((group_id == 0) ? (&TIMERG0) : (&TIMERG1))
22+
23+
/**
24+
* @brief Set clock prescale for LACT timer
25+
*
26+
* @param hw Timer Group register base address
27+
* @param divider Prescale value (0 and 1 are not valid)
28+
*/
29+
__attribute__((always_inline))
30+
static inline void lact_ll_set_clock_prescale(timg_dev_t *hw, uint32_t divider)
31+
{
32+
HAL_ASSERT(divider >= 2);
33+
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->lactconfig, lact_divider, divider);
34+
}
35+
36+
#ifdef __cplusplus
37+
}
38+
#endif

components/hal/esp32/include/hal/timer_ll.h renamed to components/esp_hal_timg/esp32/include/hal/timer_ll.h

Lines changed: 5 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
// Attention: Timer Group has 3 independent functions: General Purpose Timer, Watchdog Timer and Clock calibration.
8-
// This Low Level driver only serve the General Purpose Timer function.
9-
107
#pragma once
118

129
#include <stdbool.h>
1310
#include "esp_attr.h"
1411
#include "hal/assert.h"
1512
#include "hal/misc.h"
1613
#include "hal/timer_types.h"
14+
#include "hal/timg_ll.h"
1715
#include "soc/timer_group_struct.h"
1816
#include "soc/dport_reg.h"
1917

@@ -30,61 +28,6 @@ extern "C" {
3028
// Support APB as function clock
3129
#define TIMER_LL_FUNC_CLOCK_SUPPORT_APB 1
3230

33-
/**
34-
* @brief Enable the bus clock for timer group module
35-
*
36-
* @param group_id Group ID
37-
* @param enable true to enable, false to disable
38-
*/
39-
static inline void _timer_ll_enable_bus_clock(int group_id, bool enable)
40-
{
41-
uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
42-
if (group_id == 0) {
43-
reg_val &= ~DPORT_TIMERGROUP_CLK_EN;
44-
reg_val |= enable << 13;
45-
} else {
46-
reg_val &= ~DPORT_TIMERGROUP1_CLK_EN;
47-
reg_val |= enable << 15;
48-
}
49-
DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val);
50-
}
51-
52-
/// use a macro to wrap the function, force the caller to use it in a critical section
53-
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
54-
#define timer_ll_enable_bus_clock(...) do { \
55-
(void)__DECLARE_RCC_RC_ATOMIC_ENV; \
56-
_timer_ll_enable_bus_clock(__VA_ARGS__); \
57-
} while(0)
58-
59-
/**
60-
* @brief Reset the timer group module
61-
*
62-
* @note After reset the register, the "flash boot protection" will be enabled again.
63-
* FLash boot protection is not used anymore after system boot up.
64-
* This function will disable it by default in order to prevent the system from being reset unexpectedly.
65-
*
66-
* @param group_id Group ID
67-
*/
68-
static inline void _timer_ll_reset_register(int group_id)
69-
{
70-
if (group_id == 0) {
71-
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
72-
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
73-
TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
74-
} else {
75-
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
76-
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
77-
TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
78-
}
79-
}
80-
81-
/// use a macro to wrap the function, force the caller to use it in a critical section
82-
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
83-
#define timer_ll_reset_register(...) do { \
84-
(void)__DECLARE_RCC_RC_ATOMIC_ENV; \
85-
_timer_ll_reset_register(__VA_ARGS__); \
86-
} while(0)
87-
8831
/**
8932
* @brief Set clock source for timer
9033
*
@@ -233,8 +176,8 @@ static inline uint64_t timer_ll_get_counter_value(timg_dev_t *hw, uint32_t timer
233176
__attribute__((always_inline))
234177
static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num, uint64_t alarm_value)
235178
{
236-
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t) (alarm_value >> 32);
237-
hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t) alarm_value;
179+
hw->hw_timer[timer_num].alarmhi.tx_alarm_hi = (uint32_t)(alarm_value >> 32);
180+
hw->hw_timer[timer_num].alarmlo.tx_alarm_lo = (uint32_t)alarm_value;
238181
}
239182

240183
/**
@@ -247,8 +190,8 @@ static inline void timer_ll_set_alarm_value(timg_dev_t *hw, uint32_t timer_num,
247190
__attribute__((always_inline))
248191
static inline void timer_ll_set_reload_value(timg_dev_t *hw, uint32_t timer_num, uint64_t load_val)
249192
{
250-
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t) (load_val >> 32);
251-
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t) load_val;
193+
hw->hw_timer[timer_num].loadhi.tx_load_hi = (uint32_t)(load_val >> 32);
194+
hw->hw_timer[timer_num].loadlo.tx_load_lo = (uint32_t)load_val;
252195
}
253196

254197
/**
@@ -343,19 +286,6 @@ static inline volatile void *timer_ll_get_intr_status_reg(timg_dev_t *hw)
343286
return &hw->int_st_timers.val;
344287
}
345288

346-
/**
347-
* @brief Set clock prescale for LACT timer
348-
*
349-
* @param hw Timer Group register base address
350-
* @param timer_num Timer number in the group
351-
* @param divider Prescale value (0 and 1 are not valid)
352-
*/
353-
FORCE_INLINE_ATTR void timer_ll_set_lact_clock_prescale(timg_dev_t *hw, uint32_t divider)
354-
{
355-
HAL_ASSERT(divider>=2);
356-
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->lactconfig, lact_divider, divider);
357-
}
358-
359289
#ifdef __cplusplus
360290
}
361291
#endif
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
// Attention: Timer Group has 3 independent functions: General Purpose Timer, Watchdog Timer and Clock calibration.
8+
9+
#pragma once
10+
11+
#include <stdbool.h>
12+
#include "hal/assert.h"
13+
#include "hal/misc.h"
14+
#include "soc/timer_group_struct.h"
15+
#include "soc/dport_reg.h"
16+
17+
#ifdef __cplusplus
18+
extern "C" {
19+
#endif
20+
21+
/**
22+
* @brief Enable the bus clock for timer group module
23+
*
24+
* @param group_id Group ID
25+
* @param enable true to enable, false to disable
26+
*/
27+
static inline void _timg_ll_enable_bus_clock(int group_id, bool enable)
28+
{
29+
uint32_t reg_val = DPORT_READ_PERI_REG(DPORT_PERIP_CLK_EN_REG);
30+
if (group_id == 0) {
31+
reg_val &= ~DPORT_TIMERGROUP_CLK_EN;
32+
reg_val |= enable << 13;
33+
} else {
34+
reg_val &= ~DPORT_TIMERGROUP1_CLK_EN;
35+
reg_val |= enable << 15;
36+
}
37+
DPORT_WRITE_PERI_REG(DPORT_PERIP_CLK_EN_REG, reg_val);
38+
}
39+
40+
/// use a macro to wrap the function, force the caller to use it in a critical section
41+
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
42+
#define timg_ll_enable_bus_clock(...) do { \
43+
(void)__DECLARE_RCC_RC_ATOMIC_ENV; \
44+
_timg_ll_enable_bus_clock(__VA_ARGS__); \
45+
} while(0)
46+
47+
/**
48+
* @brief Reset the timer group module
49+
*
50+
* @note After reset the register, the "flash boot protection" will be enabled again.
51+
* FLash boot protection is not used anymore after system boot up.
52+
* This function will disable it by default in order to prevent the system from being reset unexpectedly.
53+
*
54+
* @param group_id Group ID
55+
*/
56+
static inline void _timg_ll_reset_register(int group_id)
57+
{
58+
if (group_id == 0) {
59+
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
60+
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
61+
TIMERG0.wdtconfig0.wdt_flashboot_mod_en = 0;
62+
} else {
63+
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
64+
DPORT_WRITE_PERI_REG(DPORT_PERIP_RST_EN_REG, 0);
65+
TIMERG1.wdtconfig0.wdt_flashboot_mod_en = 0;
66+
}
67+
}
68+
69+
/// use a macro to wrap the function, force the caller to use it in a critical section
70+
/// the critical section needs to declare the __DECLARE_RCC_RC_ATOMIC_ENV variable in advance
71+
#define timg_ll_reset_register(...) do { \
72+
(void)__DECLARE_RCC_RC_ATOMIC_ENV; \
73+
_timg_ll_reset_register(__VA_ARGS__); \
74+
} while(0)
75+
76+
#ifdef __cplusplus
77+
}
78+
#endif

0 commit comments

Comments
 (0)