/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2019-07-29 zdzn first version */ #include "drv_timer.h" #ifdef BSP_USING_SYSTIMER static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state) { if (state == 0) hwtimer->ops->stop(hwtimer); } static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode) { rt_err_t result = RT_EOK; rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; int timer_id = timer->timer_id; if (mode == HWTIMER_MODE_PERIOD) timer->cnt = cnt; else timer->cnt = 0; __sync_synchronize(); if (timer_id == 1) { rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1); STIMER_C1 = STIMER_CLO + cnt; } else if (timer_id == 3) { rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3); STIMER_C3 = STIMER_CLO + cnt; } else result = -RT_ERROR; __sync_synchronize(); return result; } static void raspi_systimer_stop(rt_hwtimer_t *hwtimer) { rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; int timer_id = timer->timer_id; if (timer_id == 1) rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1); else if (timer_id == 3) rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3); } static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) { /* The frequency value is an immutable value. */ if (cmd == HWTIMER_CTRL_FREQ_SET) { return RT_EOK; } else { return -RT_ENOSYS; } } void rt_device_systimer_isr(int vector, void *param) { rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param; rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data; RT_ASSERT(timer != RT_NULL); int timer_id = timer->timer_id; __sync_synchronize(); if (timer_id == 1) { STIMER_CS = 0x2; STIMER_C1 = STIMER_CLO + timer->cnt; } else if (timer_id == 3) { STIMER_CS = 0x8; STIMER_C3 = STIMER_CLO + timer->cnt; } __sync_synchronize(); rt_device_hwtimer_isr(hwtimer); } static struct rt_hwtimer_device _hwtimer1; static struct rt_hwtimer_device _hwtimer3; static rt_systimer_t _systimer1; static rt_systimer_t _systimer3; const static struct rt_hwtimer_ops systimer_ops = { raspi_systimer_init, raspi_systimer_start, raspi_systimer_stop, RT_NULL, raspi_systimer_ctrl }; static const struct rt_hwtimer_info _info = { 1000000, /* the maxinum count frequency can be set */ 1000000, /* the maxinum count frequency can be set */ 0xFFFFFFFF, /* the maximum counter value */ HWTIMER_CNTMODE_UP /* count mode (inc/dec) */ }; #endif int rt_hw_systimer_init(void) { #ifdef BSP_USING_SYSTIMER #ifdef RT_USING_SYSTIMER1 _systimer1.timer_id =1; _hwtimer1.ops = &systimer_ops; _hwtimer1.info = &_info; rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1); rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1"); rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1); #endif #ifdef RT_USING_SYSTIMER3 _systimer3.timer_id =3; _hwtimer3.ops = &systimer_ops; _hwtimer3.info = &_info; rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3); rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3"); rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3); #endif #endif return 0; } INIT_DEVICE_EXPORT(rt_hw_systimer_init);