2019-07-15 02:21:36 -04:00
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// The LL layer for Timer Group register operations.
// Note that most of the register operations in this layer are non-atomic operations.
# pragma once
# ifdef __cplusplus
extern " C " {
# endif
2019-07-15 02:21:36 -04:00
# include <stdlib.h>
2021-08-23 02:03:23 -04:00
# include "hal/misc.h"
2021-05-18 22:53:21 -04:00
# include "hal/assert.h"
2019-07-15 02:21:36 -04:00
# include "hal/timer_types.h"
# include "soc/timer_periph.h"
2021-08-23 02:03:23 -04:00
# include "soc/timer_group_struct.h"
2019-07-15 02:21:36 -04:00
2019-07-24 21:52:36 -04:00
_Static_assert ( TIMER_INTR_T0 = = TIMG_T0_INT_CLR , " Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t " ) ;
_Static_assert ( TIMER_INTR_T1 = = TIMG_T1_INT_CLR , " Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t " ) ;
_Static_assert ( TIMER_INTR_WDT = = TIMG_WDT_INT_CLR , " Add mapping to LL interrupt handling, since it's no longer naturally compatible with the timer_intr_t " ) ;
2019-07-15 02:21:36 -04:00
// Get timer group instance with giving group number
# define TIMER_LL_GET_HW(num) ((num == 0) ? (&TIMERG0) : (&TIMERG1))
2019-07-24 21:52:36 -04:00
/**
2019-07-15 02:21:36 -04:00
* @ brief Set timer clock prescale value
2019-07-24 21:52:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
2019-07-15 02:21:36 -04:00
* @ param timer_num The timer number
2020-04-10 04:23:19 -04:00
* @ param divider Prescale value ( 0 and 1 are not valid )
2019-07-24 21:52:36 -04:00
*
* @ return None
*/
2020-04-10 04:23:19 -04:00
static inline void timer_ll_set_divider ( timg_dev_t * hw , timer_idx_t timer_num , uint32_t divider )
2019-07-24 21:52:36 -04:00
{
2021-05-18 22:53:21 -04:00
HAL_ASSERT ( divider > = 2 & & divider < = 65536 ) ;
2021-02-01 01:17:10 -05:00
if ( divider > = 65536 ) {
2020-04-10 04:23:19 -04:00
divider = 0 ;
}
2019-07-15 02:21:36 -04:00
int timer_en = hw - > hw_timer [ timer_num ] . config . enable ;
hw - > hw_timer [ timer_num ] . config . enable = 0 ;
2021-08-23 02:03:23 -04:00
HAL_FORCE_MODIFY_U32_REG_FIELD ( hw - > hw_timer [ timer_num ] . config , divider , divider ) ;
2019-07-15 02:21:36 -04:00
hw - > hw_timer [ timer_num ] . config . enable = timer_en ;
2019-07-24 21:52:36 -04:00
}
/**
2019-07-15 02:21:36 -04:00
* @ brief Get timer clock prescale value
2019-07-24 21:52:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
2019-07-15 02:21:36 -04:00
* @ param timer_num The timer number
* @ param divider Pointer to accept the prescale value
2019-07-24 21:52:36 -04:00
*
* @ return None
*/
2020-04-10 04:23:19 -04:00
static inline void timer_ll_get_divider ( timg_dev_t * hw , timer_idx_t timer_num , uint32_t * divider )
2019-07-24 21:52:36 -04:00
{
2021-08-23 02:03:23 -04:00
uint32_t d = HAL_FORCE_READ_U32_REG_FIELD ( hw - > hw_timer [ timer_num ] . config , divider ) ;
2020-04-10 04:23:19 -04:00
if ( d = = 0 ) {
d = 65536 ;
} else if ( d = = 1 ) {
d = 2 ;
}
* divider = d ;
2019-07-24 21:52:36 -04:00
}
/**
2019-07-15 02:21:36 -04:00
* @ brief Load counter value into time - base counter
2019-07-24 21:52:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
2019-07-15 02:21:36 -04:00
* @ param timer_num The timer number
* @ param load_val Counter value
2019-07-24 21:52:36 -04:00
*
2019-07-15 02:21:36 -04:00
* @ return None
2019-07-24 21:52:36 -04:00
*/
2019-07-15 02:21:36 -04:00
static inline void timer_ll_set_counter_value ( timg_dev_t * hw , timer_idx_t timer_num , uint64_t load_val )
2019-07-24 21:52:36 -04:00
{
2019-07-15 02:21:36 -04:00
hw - > hw_timer [ timer_num ] . load_high = ( uint32_t ) ( load_val > > 32 ) ;
hw - > hw_timer [ timer_num ] . load_low = ( uint32_t ) load_val ;
hw - > hw_timer [ timer_num ] . reload = 1 ;
2019-07-24 21:52:36 -04:00
}
/**
2019-07-15 02:21:36 -04:00
* @ brief Get counter value from time - base counter
2019-07-24 21:52:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
2019-07-15 02:21:36 -04:00
* @ param timer_num The timer number
* @ param timer_val Pointer to accept the counter value
2019-07-24 21:52:36 -04:00
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
FORCE_INLINE_ATTR void timer_ll_get_counter_value ( timg_dev_t * hw , timer_idx_t timer_num , uint64_t * timer_val )
2019-07-24 21:52:36 -04:00
{
2019-07-15 02:21:36 -04:00
hw - > hw_timer [ timer_num ] . update = 1 ;
2020-11-11 06:54:04 -05:00
while ( hw - > hw_timer [ timer_num ] . update ) { }
2019-07-15 02:21:36 -04:00
* timer_val = ( ( uint64_t ) hw - > hw_timer [ timer_num ] . cnt_high < < 32 ) | ( hw - > hw_timer [ timer_num ] . cnt_low ) ;
2019-07-24 21:52:36 -04:00
}
2019-07-15 02:21:36 -04:00
/**
2019-07-15 02:21:36 -04:00
* @ brief Set counter mode , include increment mode and decrement mode .
2019-07-15 02:21:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
2019-07-15 02:21:36 -04:00
* @ param increase_en True to increment mode , fasle to decrement mode
2019-07-15 02:21:36 -04:00
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
static inline void timer_ll_set_counter_increase ( timg_dev_t * hw , timer_idx_t timer_num , bool increase_en )
2019-07-15 02:21:36 -04:00
{
2019-07-15 02:21:36 -04:00
hw - > hw_timer [ timer_num ] . config . increase = increase_en ;
}
/**
* @ brief Get counter mode , include increment mode and decrement mode .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return
* - true Increment mode
* - false Decrement mode
*/
static inline bool timer_ll_get_counter_increase ( timg_dev_t * hw , timer_idx_t timer_num )
{
return hw - > hw_timer [ timer_num ] . config . increase ;
2019-07-15 02:21:36 -04:00
}
/**
* @ brief Set counter status , enable or disable counter .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
2019-07-15 02:21:36 -04:00
* @ param counter_en True to enable counter , false to disable counter
2019-07-15 02:21:36 -04:00
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
FORCE_INLINE_ATTR void timer_ll_set_counter_enable ( timg_dev_t * hw , timer_idx_t timer_num , bool counter_en )
2019-07-15 02:21:36 -04:00
{
hw - > hw_timer [ timer_num ] . config . enable = counter_en ;
}
/**
2019-07-15 02:21:36 -04:00
* @ brief Get counter status .
2019-07-15 02:21:36 -04:00
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
2019-07-15 02:21:36 -04:00
*
* @ return
* - true Enable counter
* - false Disable conuter
*/
static inline bool timer_ll_get_counter_enable ( timg_dev_t * hw , timer_idx_t timer_num )
{
return hw - > hw_timer [ timer_num ] . config . enable ;
}
/**
* @ brief Set auto reload mode .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
* @ param auto_reload_en True to enable auto reload mode , flase to disable auto reload mode
2019-07-15 02:21:36 -04:00
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
static inline void timer_ll_set_auto_reload ( timg_dev_t * hw , timer_idx_t timer_num , bool auto_reload_en )
{
hw - > hw_timer [ timer_num ] . config . autoreload = auto_reload_en ;
}
/**
* @ brief Get auto reload mode .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return
* - true Enable auto reload mode
* - false Disable auto reload mode
*/
FORCE_INLINE_ATTR bool timer_ll_get_auto_reload ( timg_dev_t * hw , timer_idx_t timer_num )
2019-07-15 02:21:36 -04:00
{
return hw - > hw_timer [ timer_num ] . config . autoreload ;
}
/**
* @ brief Set the counter value to trigger the alarm .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
* @ param alarm_value Counter value to trigger the alarm
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
FORCE_INLINE_ATTR void timer_ll_set_alarm_value ( timg_dev_t * hw , timer_idx_t timer_num , uint64_t alarm_value )
2019-07-15 02:21:36 -04:00
{
hw - > hw_timer [ timer_num ] . alarm_high = ( uint32_t ) ( alarm_value > > 32 ) ;
hw - > hw_timer [ timer_num ] . alarm_low = ( uint32_t ) alarm_value ;
}
/**
* @ brief Get the counter value to trigger the alarm .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
* @ param alarm_value Pointer to accept the counter value to trigger the alarm
*
* @ return None
*/
static inline void timer_ll_get_alarm_value ( timg_dev_t * hw , timer_idx_t timer_num , uint64_t * alarm_value )
{
* alarm_value = ( ( uint64_t ) hw - > hw_timer [ timer_num ] . alarm_high < < 32 ) | ( hw - > hw_timer [ timer_num ] . alarm_low ) ;
}
/**
* @ brief Set the alarm status , enable or disable the alarm .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
2019-07-15 02:21:36 -04:00
* @ param alarm_en True to enable alarm , false to disable alarm
2019-07-15 02:21:36 -04:00
*
* @ return None
*/
2019-07-15 02:21:36 -04:00
FORCE_INLINE_ATTR void timer_ll_set_alarm_enable ( timg_dev_t * hw , timer_idx_t timer_num , bool alarm_en )
2019-07-15 02:21:36 -04:00
{
hw - > hw_timer [ timer_num ] . config . alarm_en = alarm_en ;
}
/**
* @ brief Get the alarm status .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
2019-07-15 02:21:36 -04:00
*
* @ return
* - true Enable alarm
* - false Disable alarm
*/
static inline bool timer_ll_get_alarm_enable ( timg_dev_t * hw , timer_idx_t timer_num )
{
return hw - > hw_timer [ timer_num ] . config . alarm_en ;
}
/**
* @ brief Enable timer interrupt .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_enable ( timg_dev_t * hw , timer_idx_t timer_num )
{
hw - > int_ena . val | = BIT ( timer_num ) ;
2020-04-10 04:23:19 -04:00
hw - > hw_timer [ timer_num ] . config . level_int_en = 1 ;
2019-07-15 02:21:36 -04:00
}
/**
* @ brief Disable timer interrupt .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return None
*/
FORCE_INLINE_ATTR void timer_ll_intr_disable ( timg_dev_t * hw , timer_idx_t timer_num )
{
hw - > int_ena . val & = ( ~ BIT ( timer_num ) ) ;
2020-04-10 04:23:19 -04:00
hw - > hw_timer [ timer_num ] . config . level_int_en = 0 ;
2019-07-15 02:21:36 -04:00
}
/**
* @ brief Disable timer interrupt .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return None
*/
FORCE_INLINE_ATTR void timer_ll_clear_intr_status ( timg_dev_t * hw , timer_idx_t timer_num )
{
hw - > int_clr_timers . val | = BIT ( timer_num ) ;
}
/**
* @ brief Get interrupt status .
*
* @ param hw Beginning address of the peripheral registers .
* @ param intr_status Interrupt status
*
* @ return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_status ( timg_dev_t * hw , uint32_t * intr_status )
{
2020-10-13 23:46:30 -04:00
* intr_status = hw - > int_st_timers . val & 0x03 ;
2019-07-15 02:21:36 -04:00
}
2019-11-25 01:47:19 -05:00
/**
* @ brief Get interrupt raw status .
*
* @ param group_num Timer group number , 0 for TIMERG0 or 1 for TIMERG1
* @ param intr_raw_status Interrupt raw status
*
* @ return None
*/
FORCE_INLINE_ATTR void timer_ll_get_intr_raw_status ( timer_group_t group_num , uint32_t * intr_raw_status )
{
timg_dev_t * hw = TIMER_LL_GET_HW ( group_num ) ;
2020-10-13 23:46:30 -04:00
* intr_raw_status = hw - > int_raw . val & 0x03 ;
2019-11-25 01:47:19 -05:00
}
2019-07-15 02:21:36 -04:00
/**
* @ brief Set the level interrupt status , enable or disable the level interrupt .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
* @ param level_int_en True to enable level interrupt , false to disable level interrupt
*
* @ return None
*/
static inline void timer_ll_set_level_int_enable ( timg_dev_t * hw , timer_idx_t timer_num , bool level_int_en )
{
hw - > hw_timer [ timer_num ] . config . level_int_en = level_int_en ;
}
/**
* @ brief Get the level interrupt status .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return
* - true Enable level interrupt
* - false Disable level interrupt
*/
static inline bool timer_ll_get_level_int_enable ( timg_dev_t * hw , timer_idx_t timer_num )
{
return hw - > hw_timer [ timer_num ] . config . level_int_en ;
}
/**
* @ brief Set the edge interrupt status , enable or disable the edge interrupt .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
* @ param edge_int_en True to enable edge interrupt , false to disable edge interrupt
*
* @ return None
*/
static inline void timer_ll_set_edge_int_enable ( timg_dev_t * hw , timer_idx_t timer_num , bool edge_int_en )
{
hw - > hw_timer [ timer_num ] . config . edge_int_en = edge_int_en ;
}
/**
* @ brief Get the edge interrupt status .
*
* @ param hw Beginning address of the peripheral registers .
* @ param timer_num The timer number
*
* @ return
* - true Enable edge interrupt
* - false Disable edge interrupt
*/
static inline bool timer_ll_get_edge_int_enable ( timg_dev_t * hw , timer_idx_t timer_num )
{
return hw - > hw_timer [ timer_num ] . config . edge_int_en ;
}
/**
* @ brief Get interrupt status register address .
*
* @ param hw Beginning address of the peripheral registers .
2019-07-15 02:21:36 -04:00
*
2020-04-10 04:23:19 -04:00
* @ return Interrupt status register address
2019-07-15 02:21:36 -04:00
*/
2020-04-10 04:23:19 -04:00
static inline uint32_t timer_ll_get_intr_status_reg ( timg_dev_t * hw )
{
return ( uint32_t ) & ( hw - > int_st_timers . val ) ;
}
static inline uint32_t timer_ll_get_intr_mask_bit ( timg_dev_t * hw , timer_idx_t timer_num )
2019-07-15 02:21:36 -04:00
{
2020-04-10 04:23:19 -04:00
return ( 1U < < timer_num ) ;
2019-07-15 02:21:36 -04:00
}
# ifdef __cplusplus
}
# endif