/* * Copyright (c) 2019 Winner Microelectronics Co., Ltd. * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-11-19 fanwenl 1st version */ #include #include #include "wm_type_def.h" #include "wm_timer.h" #include "drv_hw_timer.h" #ifdef BSP_USING_HWTIMER struct wm_timer_Type { enum tls_timer_unit unit; enum tls_timer_id id; }; static void wm_timer_init(rt_hwtimer_t *timer, rt_uint32_t state) { struct tls_timer_cfg timer_cfg; struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data; timer_cfg.unit = wm_timer->unit; timer_cfg.timeout = 0xFFFFFFFF; timer_cfg.is_repeat = 0; timer_cfg.callback = NULL; timer_cfg.arg = NULL; if (state == 1) { tls_timer_create(&timer_cfg, wm_timer->id); } else if (state == 0) { tls_timer_destroy(wm_timer->id); } } static rt_err_t wm_timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) { struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data; uint8_t m; tls_timer_change(wm_timer->id, t); m = (opmode == HWTIMER_MODE_ONESHOT) ? 0 : 1; tls_timer_set_mode(wm_timer->id, m); tls_timer_start(wm_timer->id); return RT_EOK; } static void wm_timer_stop(rt_hwtimer_t *timer) { struct wm_timer_Type *wm_timer = (struct wm_timer_Type *)timer->parent.user_data; tls_timer_stop(wm_timer->id); } static rt_uint32_t wm_timer_get(rt_hwtimer_t *timer) { return 0; } static rt_err_t wm_timer_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_ENOSYS; } if ( *(rt_uint32_t*)arg == 1000000) { return RT_EOK; } else { return -RT_ENOSYS; } } static const struct rt_hwtimer_info _info = { 1000000, /* the maximum count frequency can be set */ 1000000, /* the minimum count frequency can be set */ 0xFFFFFFFF, /* the maximum counter value */ HWTIMER_CNTMODE_DW, /* Increment or Decreasing count mode */ }; static const struct rt_hwtimer_ops _ops = { wm_timer_init, wm_timer_start, wm_timer_stop, wm_timer_get, wm_timer_ctrl, }; #ifdef USING_HW_TIMER1 static rt_hwtimer_t _timer1; static struct wm_timer_Type wm_timer1; #endif #ifdef USING_HW_TIMER2 static rt_hwtimer_t _timer2; static struct wm_timer_Type wm_timer2; #endif #ifdef USING_HW_TIMER3 static rt_hwtimer_t _timer3; static struct wm_timer_Type wm_timer3; #endif #ifdef USING_HW_TIMER4 static rt_hwtimer_t _timer4; static struct wm_timer_Type wm_timer4; #endif #ifdef USING_HW_TIMER5 static rt_hwtimer_t _timer5; static struct wm_timer_Type wm_timer5; #endif int wm_hw_timer_init(void) { #ifdef USING_HW_TIMER1 wm_timer1.id = TLS_TIMER_ID_1; wm_timer1.unit = TLS_TIMER_UNIT_US; _timer1.info = &_info; _timer1.ops = &_ops; rt_device_hwtimer_register(&_timer1, "timer1", &wm_timer1); #endif #ifdef USING_HW_TIMER2 wm_timer2.id = TLS_TIMER_ID_2; wm_timer2.unit = TLS_TIMER_UNIT_US; _timer2.info = &_info; _timer2.ops = &_ops; rt_device_hwtimer_register(&_timer2, "timer2", &wm_timer2); #endif #ifdef USING_HW_TIMER3 wm_timer3.id = TLS_TIMER_ID_3; wm_timer3.unit = TLS_TIMER_UNIT_US; _timer3.info = &_info; _timer3.ops = &_ops; rt_device_hwtimer_register(&_timer3, "timer3", &wm_timer3); #endif #ifdef USING_HW_TIMER4 wm_timer4.id = TLS_TIMER_ID_4; wm_timer4.unit = TLS_TIMER_UNIT_US; _timer4.info = &_info; _timer4.ops = &_ops; rt_device_hwtimer_register(&_timer4, "timer4", &wm_timer4); #endif #ifdef USING_HW_TIMER5 wm_timer5.id = TLS_TIMER_ID_5; wm_timer5.unit = TLS_TIMER_UNIT_US; _timer5.info = &_info; _timer5.ops = &_ops; rt_device_hwtimer_register(&_timer5, "timer5", &wm_timer5); #endif return 0; } INIT_BOARD_EXPORT(wm_hw_timer_init); void TIM1_IRQHandler(void) { timer_clear_irq(1); #ifdef USING_HW_TIMER1 rt_device_hwtimer_isr(&_timer1); #endif } void TIM2_IRQHandler(void) { timer_clear_irq(2); #ifdef USING_HW_TIMER2 rt_device_hwtimer_isr(&_timer2); #endif } void TIM3_IRQHandler(void) { timer_clear_irq(3); #ifdef USING_HW_TIMER3 rt_device_hwtimer_isr(&_timer3); #endif } void TIM4_IRQHandler(void) { timer_clear_irq(4); #ifdef USING_HW_TIMER4 rt_device_hwtimer_isr(&_timer4); #endif } void TIM5_IRQHandler(void) { timer_clear_irq(5); #ifdef USING_HW_TIMER5 rt_device_hwtimer_isr(&_timer5); #endif } #endif /* BSP_USING_HWTIMER */