rt-thread/bsp/raspberry-pi/raspi3-64/driver/drv_timer.c

160 lines
3.7 KiB
C
Raw Normal View History

2020-01-10 10:38:21 +08:00
/*
* Copyright (c) 2006-2019, 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"
2020-02-28 17:49:50 +08:00
#include "interrupt.h"
#include "raspi.h"
2020-01-10 10:38:21 +08:00
2020-02-28 17:49:50 +08:00
#ifdef BSP_USING_SYSTIMER
static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state)
2020-01-10 10:38:21 +08:00
{
if (state == 0)
hwtimer->ops->stop(hwtimer);
}
2020-02-28 17:49:50 +08:00
static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
2020-01-10 10:38:21 +08:00
{
rt_err_t result = RT_EOK;
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
int timer_id = timer->timer_id;
2020-02-28 17:49:50 +08:00
2020-01-10 10:38:21 +08:00
if (mode == HWTIMER_MODE_PERIOD)
timer->cnt = cnt;
else
timer->cnt = 0;
2020-02-28 17:49:50 +08:00
__sync_synchronize();
2020-01-10 10:38:21 +08:00
if (timer_id == 1)
{
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
2020-01-10 10:38:21 +08:00
STIMER_C1 = STIMER_CLO + cnt;
}
else if (timer_id == 3)
{
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
2020-01-10 10:38:21 +08:00
STIMER_C3 = STIMER_CLO + cnt;
}
else
result = -RT_ERROR;
2020-02-28 17:49:50 +08:00
__sync_synchronize();
2020-01-10 10:38:21 +08:00
return result;
}
2020-02-28 17:49:50 +08:00
static void raspi_systimer_stop(rt_hwtimer_t *hwtimer)
2020-01-10 10:38:21 +08:00
{
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
int timer_id = timer->timer_id;
if (timer_id == 1)
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1);
2020-01-10 10:38:21 +08:00
else if (timer_id == 3)
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3);
2020-01-10 10:38:21 +08:00
}
2020-02-28 17:49:50 +08:00
static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
2020-01-10 10:38:21 +08:00
{
/* 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)
{
2020-02-28 17:49:50 +08:00
2020-01-10 10:38:21 +08:00
rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param;
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
2020-02-28 17:49:50 +08:00
2020-01-10 10:38:21 +08:00
int timer_id = timer->timer_id;
2020-02-28 17:49:50 +08:00
__sync_synchronize();
2020-01-10 10:38:21 +08:00
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;
}
2020-02-28 17:49:50 +08:00
__sync_synchronize();
2020-01-10 10:38:21 +08:00
rt_device_hwtimer_isr(hwtimer);
}
2020-02-28 17:49:50 +08:00
#ifdef RT_USING_SYSTIMER1
2020-01-10 10:38:21 +08:00
static struct rt_hwtimer_device _hwtimer1;
2020-02-28 17:49:50 +08:00
static rt_systimer_t _systimer1;
#endif
#ifdef RT_USING_SYSTIMER3
2020-01-10 10:38:21 +08:00
static struct rt_hwtimer_device _hwtimer3;
2020-02-28 17:49:50 +08:00
static rt_systimer_t _systimer3;
#endif
const static struct rt_hwtimer_ops systimer_ops =
{
raspi_systimer_init,
raspi_systimer_start,
raspi_systimer_stop,
RT_NULL,
raspi_systimer_ctrl
};
2020-01-10 10:38:21 +08:00
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) */
};
2020-02-28 17:49:50 +08:00
#endif
2020-01-10 10:38:21 +08:00
int rt_hw_systimer_init(void)
{
2020-02-28 17:49:50 +08:00
#ifdef BSP_USING_SYSTIMER
2020-01-10 10:38:21 +08:00
#ifdef RT_USING_SYSTIMER1
_systimer1.timer_id =1;
_hwtimer1.ops = &systimer_ops;
_hwtimer1.info = &_info;
rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1);
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1");
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
2020-01-10 10:38:21 +08:00
#endif
#ifdef RT_USING_SYSTIMER3
_systimer3.timer_id =3;
_hwtimer3.ops = &systimer_ops;
_hwtimer3.info = &_info;
rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3);
2020-02-28 17:49:50 +08:00
rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3");
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
#endif
2020-01-10 10:38:21 +08:00
#endif
return 0;
}
2020-02-28 17:49:50 +08:00
INIT_DEVICE_EXPORT(rt_hw_systimer_init);