drivers: timer: move initialization setup to drivers
The weak symbol sys_clock_driver_init has been removed, therefore moving the init responsability to the drivers themselves. As a result, the init function has now been made static on all drivers and moved to the bottom, following the convention used in other areas. Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
parent
7b1349cfe6
commit
b1ced75386
|
@ -160,31 +160,6 @@ void timer0_nrf_isr(void *arg)
|
|||
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : (dticks > 0));
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* FIXME switch to 1 MHz once this is fixed in QEMU */
|
||||
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_2MHz);
|
||||
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
|
||||
|
||||
IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0);
|
||||
irq_enable(TIMER0_IRQn);
|
||||
|
||||
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
|
||||
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
set_comparator(counter() + CYC_PER_TICK);
|
||||
}
|
||||
|
||||
event_clear();
|
||||
NVIC_ClearPendingIRQ(TIMER0_IRQn);
|
||||
int_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -255,3 +230,31 @@ uint32_t sys_clock_cycle_get_32(void)
|
|||
k_spin_unlock(&lock, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* FIXME switch to 1 MHz once this is fixed in QEMU */
|
||||
nrf_timer_frequency_set(TIMER, NRF_TIMER_FREQ_2MHz);
|
||||
nrf_timer_bit_width_set(TIMER, NRF_TIMER_BIT_WIDTH_32);
|
||||
|
||||
IRQ_CONNECT(TIMER0_IRQn, 1, timer0_nrf_isr, 0, 0);
|
||||
irq_enable(TIMER0_IRQn);
|
||||
|
||||
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_CLEAR);
|
||||
nrf_timer_task_trigger(TIMER, NRF_TIMER_TASK_START);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
set_comparator(counter() + CYC_PER_TICK);
|
||||
}
|
||||
|
||||
event_clear();
|
||||
NVIC_ClearPendingIRQ(TIMER0_IRQn);
|
||||
int_enable();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -42,24 +42,6 @@ static void timer_irq_handler(const void *unused)
|
|||
wrapped_announce(_sys_idle_elapsed_ticks);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE,
|
||||
k_ticks_to_cyc_floor32(1) & 0xFFFF);
|
||||
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE,
|
||||
(k_ticks_to_cyc_floor32(1) >> 16) & 0xFFFF);
|
||||
|
||||
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0);
|
||||
irq_enable(TIMER_0_IRQ);
|
||||
|
||||
alt_avalon_timer_sc_init((void *)TIMER_0_BASE, 0,
|
||||
TIMER_0_IRQ, k_ticks_to_cyc_floor32(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
/* Per the Altera Embedded IP Peripherals guide, you cannot
|
||||
|
@ -85,3 +67,24 @@ uint32_t sys_clock_elapsed(void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE,
|
||||
k_ticks_to_cyc_floor32(1) & 0xFFFF);
|
||||
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE,
|
||||
(k_ticks_to_cyc_floor32(1) >> 16) & 0xFFFF);
|
||||
|
||||
IRQ_CONNECT(TIMER_0_IRQ, 0, timer_irq_handler, NULL, 0);
|
||||
irq_enable(TIMER_0_IRQ);
|
||||
|
||||
alt_avalon_timer_sc_init((void *)TIMER_0_BASE, 0,
|
||||
TIMER_0_IRQ, k_ticks_to_cyc_floor32(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -213,7 +214,7 @@ uint32_t sys_clock_cycle_get_32(void)
|
|||
|
||||
#endif
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
|
@ -240,3 +241,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Copyright (c) 2021 Intel Corporation
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -154,7 +155,7 @@ static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *
|
|||
: "a"(*eax), "c"(*ecx));
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
#ifdef CONFIG_ASSERT
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
@ -200,3 +201,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -267,50 +267,6 @@ static void timer_int_handler(const void *unused)
|
|||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize and enable the system clock
|
||||
*
|
||||
* This routine is used to program the ARCv2 timer to deliver interrupts at the
|
||||
* rate specified via the CYC_PER_TICK.
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* ensure that the timer will not generate interrupts */
|
||||
timer0_control_register_set(0);
|
||||
|
||||
#if SMP_TIMER_DRIVER
|
||||
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
|
||||
timer_int_handler, NULL, 0);
|
||||
|
||||
timer0_limit_register_set(CYC_PER_TICK - 1);
|
||||
last_time = z_arc_connect_gfrc_read();
|
||||
start_time = last_time;
|
||||
#else
|
||||
last_load = CYC_PER_TICK;
|
||||
overflow_cycles = 0;
|
||||
announced_cycles = 0;
|
||||
|
||||
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
|
||||
timer_int_handler, NULL, 0);
|
||||
|
||||
timer0_limit_register_set(last_load - 1);
|
||||
#endif
|
||||
timer0_count_register_set(0);
|
||||
timer0_control_register_set(_ARC_V2_TMR_CTRL_NH | _ARC_V2_TMR_CTRL_IE);
|
||||
|
||||
/* everything has been configured: safe to enable the interrupt */
|
||||
|
||||
irq_enable(IRQ_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
/* If the kernel allows us to miss tick announcements in idle,
|
||||
|
@ -459,3 +415,49 @@ void smp_timer_init(void)
|
|||
irq_enable(IRQ_TIMER0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize and enable the system clock
|
||||
*
|
||||
* This routine is used to program the ARCv2 timer to deliver interrupts at the
|
||||
* rate specified via the CYC_PER_TICK.
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* ensure that the timer will not generate interrupts */
|
||||
timer0_control_register_set(0);
|
||||
|
||||
#if SMP_TIMER_DRIVER
|
||||
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
|
||||
timer_int_handler, NULL, 0);
|
||||
|
||||
timer0_limit_register_set(CYC_PER_TICK - 1);
|
||||
last_time = z_arc_connect_gfrc_read();
|
||||
start_time = last_time;
|
||||
#else
|
||||
last_load = CYC_PER_TICK;
|
||||
overflow_cycles = 0;
|
||||
announced_cycles = 0;
|
||||
|
||||
IRQ_CONNECT(IRQ_TIMER0, CONFIG_ARCV2_TIMER_IRQ_PRIORITY,
|
||||
timer_int_handler, NULL, 0);
|
||||
|
||||
timer0_limit_register_set(last_load - 1);
|
||||
#endif
|
||||
timer0_count_register_set(0);
|
||||
timer0_control_register_set(_ARC_V2_TMR_CTRL_NH | _ARC_V2_TMR_CTRL_IE);
|
||||
|
||||
/* everything has been configured: safe to enable the interrupt */
|
||||
|
||||
irq_enable(IRQ_TIMER0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/arm_arch_timer.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
|
@ -85,21 +85,6 @@ static void arm_arch_timer_compare_isr(const void *arg)
|
|||
sys_clock_announce(delta_ticks);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(ARM_ARCH_TIMER_IRQ, ARM_ARCH_TIMER_PRIO,
|
||||
arm_arch_timer_compare_isr, NULL, ARM_ARCH_TIMER_FLAGS);
|
||||
arm_arch_timer_init();
|
||||
arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
|
||||
arm_arch_timer_enable(true);
|
||||
irq_enable(ARM_ARCH_TIMER_IRQ);
|
||||
arm_arch_timer_set_irq_mask(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
#if defined(CONFIG_TICKLESS_KERNEL)
|
||||
|
@ -192,3 +177,21 @@ void smp_timer_init(void)
|
|||
arm_arch_timer_set_irq_mask(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(ARM_ARCH_TIMER_IRQ, ARM_ARCH_TIMER_PRIO,
|
||||
arm_arch_timer_compare_isr, NULL, ARM_ARCH_TIMER_FLAGS);
|
||||
arm_arch_timer_init();
|
||||
arm_arch_timer_set_compare(arm_arch_timer_count() + CYC_PER_TICK);
|
||||
arm_arch_timer_enable(true);
|
||||
irq_enable(ARM_ARCH_TIMER_IRQ);
|
||||
arm_arch_timer_set_irq_mask(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -118,18 +118,6 @@ static void compare_isr(const void *arg)
|
|||
sys_clock_announce(dticks);
|
||||
}
|
||||
|
||||
/* Runs on core 0 only */
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
uint64_t curr = count();
|
||||
|
||||
IRQ_CONNECT(TIMER_IRQ, 0, compare_isr, 0, 0);
|
||||
set_compare(curr + CYC_PER_TICK);
|
||||
last_count = curr;
|
||||
irq_enable(TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -195,3 +183,18 @@ void smp_timer_init(void)
|
|||
CAVS_INTCTRL[arch_curr_cpu()->id].l2.clear = CAVS_L2_DWCT0;
|
||||
irq_enable(TIMER_IRQ);
|
||||
}
|
||||
|
||||
/* Runs on core 0 only */
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
uint64_t curr = count();
|
||||
|
||||
IRQ_CONNECT(TIMER_IRQ, 0, compare_isr, 0, 0);
|
||||
set_compare(curr + CYC_PER_TICK);
|
||||
last_count = curr;
|
||||
irq_enable(TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* the comparator value set is reached.
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
|
@ -183,24 +184,6 @@ static void startDevice(void)
|
|||
irq_unlock(key);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
rtc_last = 0U;
|
||||
|
||||
initDevice();
|
||||
startDevice();
|
||||
|
||||
/* Enable RTC interrupt. */
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
rtc_isr, 0, 0);
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -247,3 +230,24 @@ uint64_t sys_clock_cycle_get_64(void)
|
|||
{
|
||||
return AONRTCCurrent64BitValueGet() / RTC_COUNTS_PER_CYCLE;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
rtc_last = 0U;
|
||||
|
||||
initDevice();
|
||||
startDevice();
|
||||
|
||||
/* Enable RTC interrupt. */
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
rtc_isr, 0, 0);
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -149,21 +150,6 @@ void sys_clock_isr(void *arg)
|
|||
z_arm_int_exit();
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET);
|
||||
last_load = CYC_PER_TICK - 1;
|
||||
overflow_cyc = 0U;
|
||||
SysTick->LOAD = last_load;
|
||||
SysTick->VAL = 0; /* resets timer to last_load */
|
||||
SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_CLKSOURCE_Msk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
/* Fast CPUs and a 24 bit counter mean that even idle systems
|
||||
|
@ -279,3 +265,21 @@ void sys_clock_disable(void)
|
|||
{
|
||||
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
NVIC_SetPriority(SysTick_IRQn, _IRQ_PRIO_OFFSET);
|
||||
last_load = CYC_PER_TICK - 1;
|
||||
overflow_cyc = 0U;
|
||||
SysTick->LOAD = last_load;
|
||||
SysTick->VAL = 0; /* resets timer to last_load */
|
||||
SysTick->CTRL |= (SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_CLKSOURCE_Msk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -67,26 +67,6 @@ static void sys_timer_isr(const void *arg)
|
|||
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
esp_intr_alloc(DT_IRQN(DT_NODELABEL(systimer0)),
|
||||
0,
|
||||
sys_timer_isr,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
systimer_hal_init();
|
||||
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
|
||||
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
|
||||
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
|
||||
last_count = systimer_alarm();
|
||||
set_systimer_alarm(last_count + CYC_PER_TICK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -139,3 +119,26 @@ uint64_t sys_clock_cycle_get_64(void)
|
|||
{
|
||||
return systimer_alarm();
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
esp_intr_alloc(DT_IRQN(DT_NODELABEL(systimer0)),
|
||||
0,
|
||||
sys_timer_isr,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
systimer_hal_init();
|
||||
systimer_hal_connect_alarm_counter(SYSTIMER_ALARM_0, SYSTIMER_COUNTER_1);
|
||||
systimer_hal_enable_counter(SYSTIMER_COUNTER_1);
|
||||
systimer_hal_counter_can_stall_by_cpu(SYSTIMER_COUNTER_1, 0, true);
|
||||
last_count = systimer_alarm();
|
||||
set_systimer_alarm(last_count + CYC_PER_TICK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#define DT_DRV_COMPAT intel_hpet
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -316,56 +317,6 @@ static void config_timer0(unsigned int irq)
|
|||
hpet_timer_conf_set(val);
|
||||
}
|
||||
|
||||
__boot_func
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
extern int z_clock_hw_cycles_per_sec;
|
||||
uint32_t hz, reg;
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(hz);
|
||||
ARG_UNUSED(z_clock_hw_cycles_per_sec);
|
||||
|
||||
DEVICE_MMIO_TOPLEVEL_MAP(hpet_regs, K_MEM_CACHE_NONE);
|
||||
|
||||
#if DT_INST_IRQ_HAS_CELL(0, sense)
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
hpet_isr, 0, DT_INST_IRQ(0, sense));
|
||||
#else
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
hpet_isr, 0, 0);
|
||||
#endif
|
||||
config_timer0(DT_INST_IRQN(0));
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME
|
||||
hz = (uint32_t)(HPET_COUNTER_CLK_PERIOD / hpet_counter_clk_period_get());
|
||||
z_clock_hw_cycles_per_sec = hz;
|
||||
cyc_per_tick = hz / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
|
||||
#endif
|
||||
|
||||
/* Note: we set the legacy routing bit, because otherwise
|
||||
* nothing in Zephyr disables the PIT which then fires
|
||||
* interrupts into the same IRQ. But that means we're then
|
||||
* forced to use IRQ2 contra the way the kconfig IRQ selection
|
||||
* is supposed to work. Should fix this.
|
||||
*/
|
||||
reg = hpet_gconf_get();
|
||||
reg |= GCONF_LR | GCONF_ENABLE;
|
||||
hpet_gconf_set(reg);
|
||||
|
||||
last_count = hpet_counter_get();
|
||||
if (cyc_per_tick >= HPET_CMP_MIN_DELAY) {
|
||||
hpet_timer_comparator_set(last_count + cyc_per_tick);
|
||||
} else {
|
||||
hpet_timer_comparator_set(last_count + HPET_CMP_MIN_DELAY);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__boot_func
|
||||
void smp_timer_init(void)
|
||||
{
|
||||
|
@ -453,3 +404,56 @@ void sys_clock_idle_exit(void)
|
|||
reg |= GCONF_ENABLE;
|
||||
hpet_gconf_set(reg);
|
||||
}
|
||||
|
||||
__boot_func
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
extern int z_clock_hw_cycles_per_sec;
|
||||
uint32_t hz, reg;
|
||||
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(hz);
|
||||
ARG_UNUSED(z_clock_hw_cycles_per_sec);
|
||||
|
||||
DEVICE_MMIO_TOPLEVEL_MAP(hpet_regs, K_MEM_CACHE_NONE);
|
||||
|
||||
#if DT_INST_IRQ_HAS_CELL(0, sense)
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
hpet_isr, 0, DT_INST_IRQ(0, sense));
|
||||
#else
|
||||
IRQ_CONNECT(DT_INST_IRQN(0),
|
||||
DT_INST_IRQ(0, priority),
|
||||
hpet_isr, 0, 0);
|
||||
#endif
|
||||
config_timer0(DT_INST_IRQN(0));
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
#ifdef CONFIG_TIMER_READS_ITS_FREQUENCY_AT_RUNTIME
|
||||
hz = (uint32_t)(HPET_COUNTER_CLK_PERIOD / hpet_counter_clk_period_get());
|
||||
z_clock_hw_cycles_per_sec = hz;
|
||||
cyc_per_tick = hz / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
|
||||
#endif
|
||||
|
||||
/* Note: we set the legacy routing bit, because otherwise
|
||||
* nothing in Zephyr disables the PIT which then fires
|
||||
* interrupts into the same IRQ. But that means we're then
|
||||
* forced to use IRQ2 contra the way the kconfig IRQ selection
|
||||
* is supposed to work. Should fix this.
|
||||
*/
|
||||
reg = hpet_gconf_get();
|
||||
reg |= GCONF_LR | GCONF_ENABLE;
|
||||
hpet_gconf_set(reg);
|
||||
|
||||
last_count = hpet_counter_get();
|
||||
if (cyc_per_tick >= HPET_CMP_MIN_DELAY) {
|
||||
hpet_timer_comparator_set(last_count + cyc_per_tick);
|
||||
} else {
|
||||
hpet_timer_comparator_set(last_count + HPET_CMP_MIN_DELAY);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT ite_it8xxx2_timer
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <dt-bindings/interrupt-controller/ite-intc.h>
|
||||
#include <soc.h>
|
||||
|
@ -331,7 +332,7 @@ static int timer_init(enum ext_timer_idx ext_timer,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
@ -372,3 +373,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT gaisler_gptimer
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
|
||||
|
@ -101,7 +102,7 @@ static void init_downcounter(volatile struct gptimer_timer_regs *tmr)
|
|||
tmr->ctrl = GPTIMER_CTRL_LD | GPTIMER_CTRL_RS | GPTIMER_CTRL_EN;
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
const int timer_interrupt = get_timer_irq();
|
||||
|
@ -127,3 +128,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
irq_enable(timer_interrupt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -72,7 +72,7 @@ uint32_t sys_clock_elapsed(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
IRQ_CONNECT(TIMER_IRQ, DT_INST_IRQ(0, priority),
|
||||
|
@ -94,3 +94,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT microchip_xec_rtos_timer
|
||||
|
||||
#include <device.h>
|
||||
#include <devicetree.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
|
@ -366,7 +367,37 @@ void sys_clock_disable(void)
|
|||
TIMER_REGS->CTRL = 0U;
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
|
||||
|
||||
/*
|
||||
* We implement custom busy wait using a MEC1501 basic timer running on
|
||||
* the 48MHz clock domain. This code is here for future power management
|
||||
* save/restore of the timer context.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 32-bit basic timer 0 configured for 1MHz count up, auto-reload,
|
||||
* and no interrupt generation.
|
||||
*/
|
||||
void arch_busy_wait(uint32_t usec_to_wait)
|
||||
{
|
||||
if (usec_to_wait == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t start = BTMR32_0_REGS->CNT;
|
||||
|
||||
for (;;) {
|
||||
uint32_t curr = BTMR32_0_REGS->CNT;
|
||||
|
||||
if ((curr - start) >= usec_to_wait) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
|
@ -413,32 +444,5 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_HAS_CUSTOM_BUSY_WAIT
|
||||
|
||||
/*
|
||||
* We implement custom busy wait using a MEC1501 basic timer running on
|
||||
* the 48MHz clock domain. This code is here for future power management
|
||||
* save/restore of the timer context.
|
||||
*/
|
||||
|
||||
/*
|
||||
* 32-bit basic timer 0 configured for 1MHz count up, auto-reload,
|
||||
* and no interrupt generation.
|
||||
*/
|
||||
void arch_busy_wait(uint32_t usec_to_wait)
|
||||
{
|
||||
if (usec_to_wait == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t start = BTMR32_0_REGS->CNT;
|
||||
|
||||
for (;;) {
|
||||
uint32_t curr = BTMR32_0_REGS->CNT;
|
||||
|
||||
if ((curr - start) >= usec_to_wait) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT nxp_kinetis_lptmr
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <fsl_lptmr.h>
|
||||
|
||||
|
@ -91,7 +92,7 @@ static void mcux_lptmr_timer_isr(void *arg)
|
|||
LPTMR_ClearStatusFlags(LPTMR_BASE, kLPTMR_TimerCompareFlag);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
lptmr_config_t config;
|
||||
|
||||
|
@ -120,3 +121,6 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT nxp_os_timer
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -50,30 +51,6 @@ void mcux_lpc_ostick_isr(void *arg)
|
|||
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *device)
|
||||
{
|
||||
ARG_UNUSED(device);
|
||||
|
||||
/* Configure event timer's ISR */
|
||||
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
|
||||
mcux_lpc_ostick_isr, NULL, 0);
|
||||
|
||||
base = (OSTIMER_Type *)DT_INST_REG_ADDR(0);
|
||||
|
||||
EnableDeepSleepIRQ(DT_INST_IRQN(0));
|
||||
|
||||
/* Initialize the OS timer, setting clock configuration. */
|
||||
OSTIMER_Init(base);
|
||||
|
||||
last_count = OSTIMER_GetCurrentTimerValue(base);
|
||||
OSTIMER_SetMatchValue(base, last_count + CYC_PER_TICK, NULL);
|
||||
|
||||
/* Enable event timer interrupt */
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -132,3 +109,30 @@ uint64_t sys_clock_cycle_get_64(void)
|
|||
{
|
||||
return OSTIMER_GetCurrentTimerValue(base);
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *device)
|
||||
{
|
||||
ARG_UNUSED(device);
|
||||
|
||||
/* Configure event timer's ISR */
|
||||
IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority),
|
||||
mcux_lpc_ostick_isr, NULL, 0);
|
||||
|
||||
base = (OSTIMER_Type *)DT_INST_REG_ADDR(0);
|
||||
|
||||
EnableDeepSleepIRQ(DT_INST_IRQN(0));
|
||||
|
||||
/* Initialize the OS timer, setting clock configuration. */
|
||||
OSTIMER_Init(base);
|
||||
|
||||
last_count = OSTIMER_GetCurrentTimerValue(base);
|
||||
OSTIMER_SetMatchValue(base, last_count + CYC_PER_TICK, NULL);
|
||||
|
||||
/* Enable event timer interrupt */
|
||||
irq_enable(DT_INST_IRQN(0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -60,26 +60,6 @@ void np_timer_isr_test_hook(const void *arg)
|
|||
np_timer_isr(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Initialize system timer driver
|
||||
*
|
||||
* Enable the hw timer, setting its tick period, and setup its interrupt
|
||||
*/
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
tick_period = 1000000ul / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
|
||||
|
||||
last_tick_time = hwm_get_time();
|
||||
hwtimer_enable(tick_period);
|
||||
|
||||
IRQ_CONNECT(TIMER_TICK_IRQ, 1, np_timer_isr, 0, 0);
|
||||
irq_enable(TIMER_TICK_IRQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set system clock timeout
|
||||
*
|
||||
|
@ -143,3 +123,26 @@ void sys_clock_disable(void)
|
|||
hwtimer_set_silent_ticks(INT64_MAX);
|
||||
}
|
||||
#endif /* CONFIG_SYSTEM_CLOCK_DISABLE */
|
||||
|
||||
/*
|
||||
* @brief Initialize system timer driver
|
||||
*
|
||||
* Enable the hw timer, setting its tick period, and setup its interrupt
|
||||
*/
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
tick_period = 1000000ul / CONFIG_SYS_CLOCK_TICKS_PER_SEC;
|
||||
|
||||
last_tick_time = hwm_get_time();
|
||||
hwtimer_enable(tick_period);
|
||||
|
||||
IRQ_CONNECT(TIMER_TICK_IRQ, 1, np_timer_isr, 0, 0);
|
||||
irq_enable(TIMER_TICK_IRQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* "sleep/deep sleep" power state if CONFIG_PM is enabled.
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/clock_control/nrf_clock_control.h>
|
||||
|
@ -311,46 +312,6 @@ void z_nrf_rtc_timer_chan_free(int32_t chan)
|
|||
atomic_or(&alloc_mask, BIT(chan));
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
static const enum nrf_lfclk_start_mode mode =
|
||||
IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) ?
|
||||
CLOCK_CONTROL_NRF_LF_START_NOWAIT :
|
||||
(IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) ?
|
||||
CLOCK_CONTROL_NRF_LF_START_AVAILABLE :
|
||||
CLOCK_CONTROL_NRF_LF_START_STABLE);
|
||||
|
||||
/* TODO: replace with counter driver to access RTC */
|
||||
nrf_rtc_prescaler_set(RTC, 0);
|
||||
for (int32_t chan = 0; chan < CHAN_COUNT; chan++) {
|
||||
nrf_rtc_int_enable(RTC, RTC_CHANNEL_INT_MASK(chan));
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(RTC_IRQn);
|
||||
|
||||
IRQ_CONNECT(RTC_IRQn, DT_IRQ(DT_NODELABEL(RTC_LABEL), priority),
|
||||
rtc_nrf_isr, 0, 0);
|
||||
irq_enable(RTC_IRQn);
|
||||
|
||||
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR);
|
||||
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START);
|
||||
|
||||
int_mask = BIT_MASK(CHAN_COUNT);
|
||||
if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT) {
|
||||
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << 1;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
compare_set(0, counter() + CYC_PER_TICK,
|
||||
sys_clock_timeout_handler, NULL);
|
||||
}
|
||||
|
||||
z_nrf_clock_control_lf_on(mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -409,3 +370,46 @@ uint32_t sys_clock_cycle_get_32(void)
|
|||
k_spin_unlock(&lock, key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
static const enum nrf_lfclk_start_mode mode =
|
||||
IS_ENABLED(CONFIG_SYSTEM_CLOCK_NO_WAIT) ?
|
||||
CLOCK_CONTROL_NRF_LF_START_NOWAIT :
|
||||
(IS_ENABLED(CONFIG_SYSTEM_CLOCK_WAIT_FOR_AVAILABILITY) ?
|
||||
CLOCK_CONTROL_NRF_LF_START_AVAILABLE :
|
||||
CLOCK_CONTROL_NRF_LF_START_STABLE);
|
||||
|
||||
/* TODO: replace with counter driver to access RTC */
|
||||
nrf_rtc_prescaler_set(RTC, 0);
|
||||
for (int32_t chan = 0; chan < CHAN_COUNT; chan++) {
|
||||
nrf_rtc_int_enable(RTC, RTC_CHANNEL_INT_MASK(chan));
|
||||
}
|
||||
|
||||
NVIC_ClearPendingIRQ(RTC_IRQn);
|
||||
|
||||
IRQ_CONNECT(RTC_IRQn, DT_IRQ(DT_NODELABEL(RTC_LABEL), priority),
|
||||
rtc_nrf_isr, 0, 0);
|
||||
irq_enable(RTC_IRQn);
|
||||
|
||||
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR);
|
||||
nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START);
|
||||
|
||||
int_mask = BIT_MASK(CHAN_COUNT);
|
||||
if (CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT) {
|
||||
alloc_mask = BIT_MASK(EXT_CHAN_COUNT) << 1;
|
||||
}
|
||||
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
compare_set(0, counter() + CYC_PER_TICK,
|
||||
sys_clock_timeout_handler, NULL);
|
||||
}
|
||||
|
||||
z_nrf_clock_control_lf_on(mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <drivers/clock_control.h>
|
||||
|
@ -66,13 +67,24 @@ static void cmt_isr(void *arg)
|
|||
sys_clock_announce(1);
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
/* Always return 0 for tickful operation */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
return sys_read32(TIMER_BASE_ADDR + CMCNT1_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize both channels at same frequency,
|
||||
* Set the first one to generates interrupt at CYCLES_PER_TICK.
|
||||
* The second one is used for cycles count, the match value is set
|
||||
* at max uint32_t.
|
||||
*/
|
||||
int sys_clock_driver_init(const struct device *device)
|
||||
static int sys_clock_driver_init(const struct device *device)
|
||||
{
|
||||
const struct device *clk;
|
||||
uint32_t reg_val;
|
||||
|
@ -140,13 +152,5 @@ int sys_clock_driver_init(const struct device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
/* Always return 0 for tickful operation */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
return sys_read32(TIMER_BASE_ADDR + CMCNT1_OFFSET);
|
||||
}
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -79,17 +80,6 @@ static void timer_isr(const void *arg)
|
|||
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0);
|
||||
last_count = mtime();
|
||||
set_mtimecmp(last_count + CYC_PER_TICK);
|
||||
irq_enable(RISCV_MACHINE_TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -152,3 +142,17 @@ uint64_t sys_clock_cycle_get_64(void)
|
|||
{
|
||||
return mtime();
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0);
|
||||
last_count = mtime();
|
||||
set_mtimecmp(last_count + CYC_PER_TICK);
|
||||
irq_enable(RISCV_MACHINE_TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT openisa_rv32m1_lptmr
|
||||
|
||||
#include <device.h>
|
||||
#include <zephyr.h>
|
||||
#include <sys/util.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
|
@ -53,7 +54,20 @@ static void lptmr_irq_handler(const struct device *unused)
|
|||
sys_clock_announce(1); /* Poke the scheduler. */
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *unused)
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
return cycle_count + SYSTEM_TIMER_INSTANCE->CNR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we're not tickless, this is identically zero.
|
||||
*/
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *unused)
|
||||
{
|
||||
uint32_t csr, psr, sircdiv; /* LPTMR registers */
|
||||
|
||||
|
@ -131,15 +145,5 @@ int sys_clock_driver_init(const struct device *unused)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
return cycle_count + SYSTEM_TIMER_INSTANCE->CNR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since we're not tickless, this is identically zero.
|
||||
*/
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
* generate an interrupt every tick.
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/clock_control.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
|
@ -175,7 +176,71 @@ static void rtc_isr(const void *arg)
|
|||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
|
||||
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
|
||||
ticks = CLAMP(ticks - 1, 0, (int32_t) MAX_TICKS);
|
||||
|
||||
/* Compute number of RTC cycles until the next timeout. */
|
||||
uint32_t count = rtc_count();
|
||||
uint32_t timeout = ticks * CYCLES_PER_TICK + count % CYCLES_PER_TICK;
|
||||
|
||||
/* Round to the nearest tick boundary. */
|
||||
timeout = (timeout + CYCLES_PER_TICK - 1) / CYCLES_PER_TICK
|
||||
* CYCLES_PER_TICK;
|
||||
|
||||
if (timeout < TICK_THRESHOLD) {
|
||||
timeout += CYCLES_PER_TICK;
|
||||
}
|
||||
|
||||
rtc_sync();
|
||||
RTC0->COMP[0].reg = count + timeout;
|
||||
|
||||
#else /* !CONFIG_TICKLESS_KERNEL */
|
||||
|
||||
if (ticks == K_TICKS_FOREVER) {
|
||||
/* Disable comparator for K_TICKS_FOREVER and other negative
|
||||
* values.
|
||||
*/
|
||||
rtc_timeout = rtc_counter;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ticks < 1) {
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
/* Avoid race condition between reading counter and ISR incrementing
|
||||
* it.
|
||||
*/
|
||||
int key = irq_lock();
|
||||
|
||||
rtc_timeout = rtc_counter + ticks;
|
||||
irq_unlock(key);
|
||||
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
return (rtc_count() - rtc_last) / CYCLES_PER_TICK;
|
||||
#else
|
||||
return rtc_counter - rtc_last;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
/* Just return the absolute value of RTC cycle counter. */
|
||||
return rtc_count();
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
|
@ -252,66 +317,5 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
|
||||
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
|
||||
ticks = CLAMP(ticks - 1, 0, (int32_t) MAX_TICKS);
|
||||
|
||||
/* Compute number of RTC cycles until the next timeout. */
|
||||
uint32_t count = rtc_count();
|
||||
uint32_t timeout = ticks * CYCLES_PER_TICK + count % CYCLES_PER_TICK;
|
||||
|
||||
/* Round to the nearest tick boundary. */
|
||||
timeout = (timeout + CYCLES_PER_TICK - 1) / CYCLES_PER_TICK
|
||||
* CYCLES_PER_TICK;
|
||||
|
||||
if (timeout < TICK_THRESHOLD) {
|
||||
timeout += CYCLES_PER_TICK;
|
||||
}
|
||||
|
||||
rtc_sync();
|
||||
RTC0->COMP[0].reg = count + timeout;
|
||||
|
||||
#else /* !CONFIG_TICKLESS_KERNEL */
|
||||
|
||||
if (ticks == K_TICKS_FOREVER) {
|
||||
/* Disable comparator for K_TICKS_FOREVER and other negative
|
||||
* values.
|
||||
*/
|
||||
rtc_timeout = rtc_counter;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ticks < 1) {
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
/* Avoid race condition between reading counter and ISR incrementing
|
||||
* it.
|
||||
*/
|
||||
int key = irq_lock();
|
||||
|
||||
rtc_timeout = rtc_counter + ticks;
|
||||
irq_unlock(key);
|
||||
|
||||
#endif /* CONFIG_TICKLESS_KERNEL */
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
return (rtc_count() - rtc_last) / CYCLES_PER_TICK;
|
||||
#else
|
||||
return rtc_counter - rtc_last;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
/* Just return the absolute value of RTC cycle counter. */
|
||||
return rtc_count();
|
||||
}
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <stm32_ll_lptim.h>
|
||||
#include <stm32_ll_bus.h>
|
||||
|
@ -78,141 +79,6 @@ static void lptim_irq_handler(const struct device *unused)
|
|||
}
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* enable LPTIM clock source */
|
||||
#if defined(LL_APB1_GRP1_PERIPH_LPTIM1)
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
#elif defined(LL_APB3_GRP1_PERIPH_LPTIM1)
|
||||
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_LPTIM1);
|
||||
LL_SRDAMR_GRP1_EnableAutonomousClock(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_LPTIM_CLOCK_LSI)
|
||||
/* enable LSI clock */
|
||||
#ifdef CONFIG_SOC_SERIES_STM32WBX
|
||||
LL_RCC_LSI1_Enable();
|
||||
while (!LL_RCC_LSI1_IsReady()) {
|
||||
#else
|
||||
LL_RCC_LSI_Enable();
|
||||
while (!LL_RCC_LSI_IsReady()) {
|
||||
#endif /* CONFIG_SOC_SERIES_STM32WBX */
|
||||
/* Wait for LSI ready */
|
||||
}
|
||||
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);
|
||||
|
||||
#else /* CONFIG_STM32_LPTIM_CLOCK_LSI */
|
||||
#if defined(LL_APB1_GRP1_PERIPH_PWR)
|
||||
/* Enable the power interface clock */
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
|
||||
#endif /* LL_APB1_GRP1_PERIPH_PWR */
|
||||
|
||||
/* enable backup domain */
|
||||
LL_PWR_EnableBkUpAccess();
|
||||
|
||||
/* enable LSE clock */
|
||||
LL_RCC_LSE_DisableBypass();
|
||||
LL_RCC_LSE_Enable();
|
||||
while (!LL_RCC_LSE_IsReady()) {
|
||||
/* Wait for LSE ready */
|
||||
}
|
||||
#ifdef RCC_BDCR_LSESYSEN
|
||||
LL_RCC_LSE_EnablePropagation();
|
||||
#endif /* RCC_BDCR_LSESYSEN */
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
|
||||
|
||||
#endif /* CONFIG_STM32_LPTIM_CLOCK_LSI */
|
||||
|
||||
/* Clear the event flag and possible pending interrupt */
|
||||
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(lptim1)),
|
||||
DT_IRQ(DT_NODELABEL(lptim1), priority),
|
||||
lptim_irq_handler, 0, 0);
|
||||
irq_enable(DT_IRQN(DT_NODELABEL(lptim1)));
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32WLX
|
||||
/* Enable the LPTIM1 wakeup EXTI line */
|
||||
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_29);
|
||||
#endif
|
||||
|
||||
/* configure the LPTIM1 counter */
|
||||
LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
|
||||
/* configure the LPTIM1 prescaler with 1 */
|
||||
LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV1);
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
LL_LPTIM_OC_SetPolarity(LPTIM1, LL_LPTIM_CHANNEL_CH1,
|
||||
LL_LPTIM_OUTPUT_POLARITY_REGULAR);
|
||||
#else
|
||||
LL_LPTIM_SetPolarity(LPTIM1, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
|
||||
#endif
|
||||
LL_LPTIM_SetUpdateMode(LPTIM1, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
|
||||
LL_LPTIM_SetCounterMode(LPTIM1, LL_LPTIM_COUNTER_MODE_INTERNAL);
|
||||
LL_LPTIM_DisableTimeout(LPTIM1);
|
||||
/* counting start is initiated by software */
|
||||
LL_LPTIM_TrigSw(LPTIM1);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
/* Enable the LPTIM1 before proceeding with configuration */
|
||||
LL_LPTIM_Enable(LPTIM1);
|
||||
|
||||
LL_LPTIM_DisableIT_CC1(LPTIM1);
|
||||
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
|
||||
}
|
||||
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
|
||||
LL_LPTIM_ClearFLAG_CC1(LPTIM1);
|
||||
#else
|
||||
/* LPTIM1 interrupt set-up before enabling */
|
||||
/* no Compare match Interrupt */
|
||||
LL_LPTIM_DisableIT_CMPM(LPTIM1);
|
||||
LL_LPTIM_ClearFLAG_CMPM(LPTIM1);
|
||||
#endif
|
||||
|
||||
/* Autoreload match Interrupt */
|
||||
LL_LPTIM_EnableIT_ARRM(LPTIM1);
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
|
||||
}
|
||||
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
|
||||
#endif
|
||||
LL_LPTIM_ClearFLAG_ARRM(LPTIM1);
|
||||
/* ARROK bit validates the write operation to ARR register */
|
||||
LL_LPTIM_ClearFlag_ARROK(LPTIM1);
|
||||
|
||||
accumulated_lptim_cnt = 0;
|
||||
|
||||
#ifndef CONFIG_SOC_SERIES_STM32U5X
|
||||
/* Enable the LPTIM1 counter */
|
||||
LL_LPTIM_Enable(LPTIM1);
|
||||
#endif
|
||||
|
||||
/* Set the Autoreload value once the timer is enabled */
|
||||
if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
/* LPTIM1 is triggered on a LPTIM_TIMEBASE period */
|
||||
LL_LPTIM_SetAutoReload(LPTIM1, LPTIM_TIMEBASE);
|
||||
|
||||
} else {
|
||||
/* LPTIM1 is triggered on a Tick period */
|
||||
LL_LPTIM_SetAutoReload(LPTIM1, COUNT_PER_TICK - 1);
|
||||
}
|
||||
|
||||
/* Start the LPTIM counter in continuous mode */
|
||||
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
/* stop LPTIM1 during DEBUG */
|
||||
#if defined(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP)
|
||||
LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP);
|
||||
#elif defined(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP)
|
||||
LL_DBGMCU_APB3_GRP1_FreezePeriph(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t z_clock_lptim_getcounter(void)
|
||||
{
|
||||
uint32_t lp_time;
|
||||
|
@ -374,3 +240,141 @@ uint32_t sys_clock_cycle_get_32(void)
|
|||
/* convert in hw cycles (keeping 32bit value) */
|
||||
return (uint32_t)(ret);
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* enable LPTIM clock source */
|
||||
#if defined(LL_APB1_GRP1_PERIPH_LPTIM1)
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
#elif defined(LL_APB3_GRP1_PERIPH_LPTIM1)
|
||||
LL_APB3_GRP1_EnableClock(LL_APB3_GRP1_PERIPH_LPTIM1);
|
||||
LL_SRDAMR_GRP1_EnableAutonomousClock(LL_SRDAMR_GRP1_PERIPH_LPTIM1AMEN);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32_LPTIM_CLOCK_LSI)
|
||||
/* enable LSI clock */
|
||||
#ifdef CONFIG_SOC_SERIES_STM32WBX
|
||||
LL_RCC_LSI1_Enable();
|
||||
while (!LL_RCC_LSI1_IsReady()) {
|
||||
#else
|
||||
LL_RCC_LSI_Enable();
|
||||
while (!LL_RCC_LSI_IsReady()) {
|
||||
#endif /* CONFIG_SOC_SERIES_STM32WBX */
|
||||
/* Wait for LSI ready */
|
||||
}
|
||||
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSI);
|
||||
|
||||
#else /* CONFIG_STM32_LPTIM_CLOCK_LSI */
|
||||
#if defined(LL_APB1_GRP1_PERIPH_PWR)
|
||||
/* Enable the power interface clock */
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
|
||||
#endif /* LL_APB1_GRP1_PERIPH_PWR */
|
||||
|
||||
/* enable backup domain */
|
||||
LL_PWR_EnableBkUpAccess();
|
||||
|
||||
/* enable LSE clock */
|
||||
LL_RCC_LSE_DisableBypass();
|
||||
LL_RCC_LSE_Enable();
|
||||
while (!LL_RCC_LSE_IsReady()) {
|
||||
/* Wait for LSE ready */
|
||||
}
|
||||
#ifdef RCC_BDCR_LSESYSEN
|
||||
LL_RCC_LSE_EnablePropagation();
|
||||
#endif /* RCC_BDCR_LSESYSEN */
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
|
||||
|
||||
#endif /* CONFIG_STM32_LPTIM_CLOCK_LSI */
|
||||
|
||||
/* Clear the event flag and possible pending interrupt */
|
||||
IRQ_CONNECT(DT_IRQN(DT_NODELABEL(lptim1)),
|
||||
DT_IRQ(DT_NODELABEL(lptim1), priority),
|
||||
lptim_irq_handler, 0, 0);
|
||||
irq_enable(DT_IRQN(DT_NODELABEL(lptim1)));
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32WLX
|
||||
/* Enable the LPTIM1 wakeup EXTI line */
|
||||
LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_29);
|
||||
#endif
|
||||
|
||||
/* configure the LPTIM1 counter */
|
||||
LL_LPTIM_SetClockSource(LPTIM1, LL_LPTIM_CLK_SOURCE_INTERNAL);
|
||||
/* configure the LPTIM1 prescaler with 1 */
|
||||
LL_LPTIM_SetPrescaler(LPTIM1, LL_LPTIM_PRESCALER_DIV1);
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
LL_LPTIM_OC_SetPolarity(LPTIM1, LL_LPTIM_CHANNEL_CH1,
|
||||
LL_LPTIM_OUTPUT_POLARITY_REGULAR);
|
||||
#else
|
||||
LL_LPTIM_SetPolarity(LPTIM1, LL_LPTIM_OUTPUT_POLARITY_REGULAR);
|
||||
#endif
|
||||
LL_LPTIM_SetUpdateMode(LPTIM1, LL_LPTIM_UPDATE_MODE_IMMEDIATE);
|
||||
LL_LPTIM_SetCounterMode(LPTIM1, LL_LPTIM_COUNTER_MODE_INTERNAL);
|
||||
LL_LPTIM_DisableTimeout(LPTIM1);
|
||||
/* counting start is initiated by software */
|
||||
LL_LPTIM_TrigSw(LPTIM1);
|
||||
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
/* Enable the LPTIM1 before proceeding with configuration */
|
||||
LL_LPTIM_Enable(LPTIM1);
|
||||
|
||||
LL_LPTIM_DisableIT_CC1(LPTIM1);
|
||||
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
|
||||
}
|
||||
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
|
||||
LL_LPTIM_ClearFLAG_CC1(LPTIM1);
|
||||
#else
|
||||
/* LPTIM1 interrupt set-up before enabling */
|
||||
/* no Compare match Interrupt */
|
||||
LL_LPTIM_DisableIT_CMPM(LPTIM1);
|
||||
LL_LPTIM_ClearFLAG_CMPM(LPTIM1);
|
||||
#endif
|
||||
|
||||
/* Autoreload match Interrupt */
|
||||
LL_LPTIM_EnableIT_ARRM(LPTIM1);
|
||||
#ifdef CONFIG_SOC_SERIES_STM32U5X
|
||||
while (LL_LPTIM_IsActiveFlag_DIEROK(LPTIM1) == 0) {
|
||||
}
|
||||
LL_LPTIM_ClearFlag_DIEROK(LPTIM1);
|
||||
#endif
|
||||
LL_LPTIM_ClearFLAG_ARRM(LPTIM1);
|
||||
/* ARROK bit validates the write operation to ARR register */
|
||||
LL_LPTIM_ClearFlag_ARROK(LPTIM1);
|
||||
|
||||
accumulated_lptim_cnt = 0;
|
||||
|
||||
#ifndef CONFIG_SOC_SERIES_STM32U5X
|
||||
/* Enable the LPTIM1 counter */
|
||||
LL_LPTIM_Enable(LPTIM1);
|
||||
#endif
|
||||
|
||||
/* Set the Autoreload value once the timer is enabled */
|
||||
if (IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
/* LPTIM1 is triggered on a LPTIM_TIMEBASE period */
|
||||
LL_LPTIM_SetAutoReload(LPTIM1, LPTIM_TIMEBASE);
|
||||
|
||||
} else {
|
||||
/* LPTIM1 is triggered on a Tick period */
|
||||
LL_LPTIM_SetAutoReload(LPTIM1, COUNT_PER_TICK - 1);
|
||||
}
|
||||
|
||||
/* Start the LPTIM counter in continuous mode */
|
||||
LL_LPTIM_StartCounter(LPTIM1, LL_LPTIM_OPERATING_MODE_CONTINUOUS);
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
/* stop LPTIM1 during DEBUG */
|
||||
#if defined(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP)
|
||||
LL_DBGMCU_APB1_GRP1_FreezePeriph(LL_DBGMCU_APB1_GRP1_LPTIM1_STOP);
|
||||
#elif defined(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP)
|
||||
LL_DBGMCU_APB3_GRP1_FreezePeriph(LL_DBGMCU_APB3_GRP1_LPTIM1_STOP);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -23,13 +23,6 @@ void __weak sys_clock_isr(void *arg)
|
|||
__ASSERT_NO_MSG(false);
|
||||
}
|
||||
|
||||
int __weak sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __weak sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
}
|
||||
|
@ -41,6 +34,3 @@ void __weak sys_clock_idle_exit(void)
|
|||
void __weak sys_clock_disable(void)
|
||||
{
|
||||
}
|
||||
|
||||
SYS_DEVICE_DEFINE("sys_clock", sys_clock_driver_init,
|
||||
PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#define DT_DRV_COMPAT xlnx_ttcps
|
||||
|
||||
#include <device.h>
|
||||
#include <soc.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include "xlnx_psttc_timer_priv.h"
|
||||
|
@ -96,7 +97,50 @@ static void ttc_isr(const void *arg)
|
|||
sys_clock_announce(ticks);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
uint32_t cycles;
|
||||
uint32_t next_cycles;
|
||||
|
||||
/* Read counter value */
|
||||
cycles = read_count();
|
||||
|
||||
/* Calculate timeout counter value */
|
||||
if (ticks == K_TICKS_FOREVER) {
|
||||
next_cycles = cycles + CYCLES_NEXT_MAX;
|
||||
} else {
|
||||
next_cycles = cycles + ((uint32_t)ticks * CYCLES_PER_TICK);
|
||||
}
|
||||
|
||||
/* Set match value for the next interrupt */
|
||||
update_match(cycles, next_cycles);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
uint32_t cycles;
|
||||
|
||||
/* Read counter value */
|
||||
cycles = read_count();
|
||||
|
||||
/* Return the number of ticks since last announcement */
|
||||
return (cycles - last_cycles) / CYCLES_PER_TICK;
|
||||
#else
|
||||
/* Always return 0 for tickful operation */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
/* Return the current counter value */
|
||||
return read_count();
|
||||
}
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
uint32_t reg_val;
|
||||
ARG_UNUSED(dev);
|
||||
|
@ -153,45 +197,5 @@ int sys_clock_driver_init(const struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
uint32_t cycles;
|
||||
uint32_t next_cycles;
|
||||
|
||||
/* Read counter value */
|
||||
cycles = read_count();
|
||||
|
||||
/* Calculate timeout counter value */
|
||||
if (ticks == K_TICKS_FOREVER) {
|
||||
next_cycles = cycles + CYCLES_NEXT_MAX;
|
||||
} else {
|
||||
next_cycles = cycles + ((uint32_t)ticks * CYCLES_PER_TICK);
|
||||
}
|
||||
|
||||
/* Set match value for the next interrupt */
|
||||
update_match(cycles, next_cycles);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_elapsed(void)
|
||||
{
|
||||
#ifdef CONFIG_TICKLESS_KERNEL
|
||||
uint32_t cycles;
|
||||
|
||||
/* Read counter value */
|
||||
cycles = read_count();
|
||||
|
||||
/* Return the number of ticks since last announcement */
|
||||
return (cycles - last_cycles) / CYCLES_PER_TICK;
|
||||
#else
|
||||
/* Always return 0 for tickful operation */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t sys_clock_cycle_get_32(void)
|
||||
{
|
||||
/* Return the current counter value */
|
||||
return read_count();
|
||||
}
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <device.h>
|
||||
#include <drivers/timer/system_timer.h>
|
||||
#include <sys_clock.h>
|
||||
#include <spinlock.h>
|
||||
|
@ -56,16 +57,6 @@ static void ccompare_isr(const void *arg)
|
|||
sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1);
|
||||
}
|
||||
|
||||
int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(TIMER_IRQ, 0, ccompare_isr, 0, 0);
|
||||
set_ccompare(ccount() + CYC_PER_TICK);
|
||||
irq_enable(TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sys_clock_set_timeout(int32_t ticks, bool idle)
|
||||
{
|
||||
ARG_UNUSED(idle);
|
||||
|
@ -122,3 +113,16 @@ void smp_timer_init(void)
|
|||
irq_enable(TIMER_IRQ);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sys_clock_driver_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
IRQ_CONNECT(TIMER_IRQ, 0, ccompare_isr, 0, 0);
|
||||
set_ccompare(ccount() + CYC_PER_TICK);
|
||||
irq_enable(TIMER_IRQ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2,
|
||||
CONFIG_SYSTEM_CLOCK_INIT_PRIORITY);
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
#define ZEPHYR_INCLUDE_DRIVERS_SYSTEM_TIMER_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <device.h>
|
||||
#include <stdbool.h>
|
||||
#include <zephyr/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -29,15 +28,6 @@ extern "C" {
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize system clock driver
|
||||
*
|
||||
* The system clock is a Zephyr device created globally. This is its
|
||||
* initialization callback. It is a weak symbol that will be
|
||||
* implemented as a noop if undefined in the clock driver.
|
||||
*/
|
||||
extern int sys_clock_driver_init(const struct device *dev);
|
||||
|
||||
/**
|
||||
* @brief Set system clock timeout
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue