| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /*
- * Copyright (c) 2006-2023, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2023-04-01 wcx1024979076 first version
- */
- #include "drv_hwtimer.h"
- #include <rtthread.h>
- #include <rtdevice.h>
- #ifdef BSP_USING_HWTIMER
- #define DBG_LEVEL DBG_LOG
- #include <rtdbg.h>
- #define LOG_TAG "DRV.HWTIMER"
- typedef struct _gptimer
- {
- const char *name;
- rt_hwtimer_t timer;
- struct bflb_device_s *bflb_timer;
- } _gptimer_t;
- static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state);
- static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
- static void _hwtimer_stop(rt_hwtimer_t *timer);
- static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer);
- static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
- static void _hwtmr_isr(_gptimer_t *gptmr);
- static const struct rt_hwtimer_ops _hwtimer_ops = {
- .init = _hwtimer_init,
- .start = _hwtimer_start,
- .stop = _hwtimer_stop,
- .count_get = _hwtimer_count_get,
- .control = _hwtimer_control
- };
- static const struct rt_hwtimer_info _hwtimer_info = {
- .maxfreq = 1000000UL,
- .minfreq = 1000000UL,
- .maxcnt = 0xFFFFFFFFUL,
- .cntmode = HWTIMER_MODE_PERIOD
- };
- #ifdef BSP_USING_TIMER0
- static _gptimer_t timer0 = {.name = "timer0"};
- #endif /* BSP_USING_TIMER0 */
- #ifdef BSP_USING_TIMER1
- static _gptimer_t timer1 = {.name = "timer1" };
- #endif /* BSP_USING_TIMER1 */
- static _gptimer_t *s_gptimers[] = {
- #ifdef BSP_USING_TIMER0
- &timer0,
- #endif /* BSP_USING_TIMER0 */
- #ifdef BSP_USING_TIMER1
- &timer1,
- #endif /* BSP_USING_TIMER1 */
- };
- #ifdef BSP_USING_TIMER0
- void timer0_isr(int irq, void *arg)
- {
- _hwtmr_isr(&timer0);
- }
- #endif /* BSP_USING_TIMER0 */
- #ifdef BSP_USING_TIMER1
- void timer1_isr(int irq, void *arg)
- {
- _hwtmr_isr(&timer1);
- }
- #endif /* BSP_USING_TIMER1 */
- static void _hwtmr_isr(_gptimer_t *timer)
- {
- bool hwtmr_stat = bflb_timer_get_compint_status(timer->bflb_timer, TIMER_COMP_ID_0);
- if (hwtmr_stat)
- {
- rt_device_hwtimer_isr(&timer->timer);
- bflb_timer_compint_clear(timer->bflb_timer, TIMER_COMP_ID_0);
- }
- }
- static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
- {
- _gptimer_t *_gptmr = (_gptimer_t*)timer->parent.user_data;
- struct bflb_timer_config_s cfg;
- cfg.counter_mode = TIMER_COUNTER_MODE_PROLOAD;
- cfg.clock_source = TIMER_CLKSRC_XTAL;
- cfg.clock_div = 40;
- cfg.trigger_comp_id = TIMER_COMP_ID_0;
- cfg.comp0_val = 0;
- cfg.comp1_val = 0;
- cfg.comp2_val = 0;
- cfg.preload_val = 0;
- bflb_timer_init(_gptmr->bflb_timer, &cfg);
- }
- static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
- {
- _gptimer_t *_gptmr = (_gptimer_t*) timer->parent.user_data;
- struct bflb_timer_config_s cfg;
- if(mode == HWTIMER_MODE_ONESHOT)
- cfg.counter_mode = TIMER_COUNTER_MODE_UP;
- else
- cfg.counter_mode = TIMER_COUNTER_MODE_PROLOAD;
- cfg.clock_source = TIMER_CLKSRC_XTAL;
- cfg.clock_div = 40;
- cfg.trigger_comp_id = TIMER_COMP_ID_0;
- cfg.comp0_val = cnt;
- cfg.comp1_val = cnt;
- cfg.comp2_val = cnt;
- cfg.preload_val = 0;
- bflb_timer_init(_gptmr->bflb_timer, &cfg);
- bflb_irq_enable(_gptmr->bflb_timer->irq_num);
- bflb_timer_start(_gptmr->bflb_timer);
- return RT_EOK;
- }
- static void _hwtimer_stop(rt_hwtimer_t *timer)
- {
- _gptimer_t *_gptmr = (_gptimer_t*)timer->parent.user_data;
- bflb_timer_stop(_gptmr->bflb_timer);
- }
- static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer)
- {
- _gptimer_t *_gptmr = (_gptimer_t*)timer->parent.user_data;
- rt_uint32_t current_cnt = bflb_timer_get_countervalue(_gptmr->bflb_timer);
- return current_cnt;
- }
- static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
- {
- rt_err_t err = RT_EOK;
- _gptimer_t *_gptmr = (_gptimer_t*) timer->parent.user_data;
- switch (cmd)
- {
- case HWTIMER_CTRL_FREQ_SET:
- err = -RT_ERROR;
- break;
- case HWTIMER_CTRL_INFO_GET:
- *(rt_hwtimer_t*)args = _gptmr->timer;
- break;
- case HWTIMER_CTRL_MODE_SET:
- _gptmr->timer.mode = *(rt_uint32_t*)args;
- break;
- case HWTIMER_CTRL_STOP:
- bflb_timer_stop(_gptmr->bflb_timer);
- break;
- }
- return err;
- }
- int rt_hw_hwtimer_init(void)
- {
- int ret = RT_EOK;
- for (uint32_t i = 0; i < sizeof(s_gptimers) / sizeof(s_gptimers[0]); i++)
- {
- s_gptimers[i]->timer.info = &_hwtimer_info;
- s_gptimers[i]->timer.ops = &_hwtimer_ops;
- s_gptimers[i]->bflb_timer = bflb_device_get_by_name(s_gptimers[i]->name);
- ret = rt_device_hwtimer_register(&s_gptimers[i]->timer, s_gptimers[i]->name, s_gptimers[i]);
- if (ret != RT_EOK)
- {
- LOG_E("%s register failed", s_gptimers[i]->name);
- }
- }
- #ifdef BSP_USING_TIMER0
- bflb_irq_attach(bflb_device_get_by_name("timer0")->irq_num, timer0_isr, NULL);
- #endif /* BSP_USING_TIMER0 */
- #ifdef BSP_USING_TIMER1
- bflb_irq_attach(bflb_device_get_by_name("timer1")->irq_num, timer1_isr, NULL);
- #endif /* BSP_USING_TIMER1 */
- return ret;
- }
- INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
- #endif /* BSP_USING_HWTIMER */
|