-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[novosns][ns800][drivers] 增加 TIM 硬件定时器支持 #11395
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,230 @@ | ||
| /* | ||
| * Copyright (c) 2006-2025, RT-Thread Development Team | ||
| * | ||
| * SPDX-License-Identifier: Apache-2.0 | ||
| * Author: oxlm | ||
| */ | ||
|
|
||
| #include <board.h> | ||
| #include <rtthread.h> | ||
| #include <rtdevice.h> | ||
| #include "drv_config.h" | ||
|
|
||
| #ifdef BSP_USING_TIM | ||
|
|
||
| struct ns800_clock_timer | ||
| { | ||
| rt_clock_timer_t timer; | ||
| void *instance; | ||
| IRQn_Type irqno; | ||
| void (*irq_handler)(void); | ||
| char *name; | ||
| rt_clock_timer_mode_t mode; | ||
| }; | ||
|
|
||
|
|
||
| enum | ||
| { | ||
| #ifdef BSP_USING_TIM1 | ||
| TIM1_INDEX, | ||
| #endif | ||
| #ifdef BSP_USING_TIM2 | ||
| TIM2_INDEX, | ||
| #endif | ||
| }; | ||
|
|
||
|
|
||
| #ifdef BSP_USING_TIM1 | ||
| void TIM1_IRQHandler(void); | ||
| #endif | ||
| #ifdef BSP_USING_TIM2 | ||
| void TIM2_IRQHandler(void); | ||
| #endif | ||
|
|
||
| static struct ns800_clock_timer ns800_timers[] = | ||
| { | ||
| #ifdef BSP_USING_TIM1 | ||
| {.instance = TIM1, .irqno = TIM1_IRQn, .irq_handler = TIM1_IRQHandler, .name = "timer1"}, | ||
| #endif | ||
| #ifdef BSP_USING_TIM2 | ||
| {.instance = TIM2, .irqno = TIM2_IRQn, .irq_handler = TIM2_IRQHandler, .name = "timer2"}, | ||
| #endif | ||
| }; | ||
|
|
||
| #define NS800_TIMER_NUM (sizeof(ns800_timers) / sizeof(ns800_timers[0])) | ||
|
|
||
|
Comment on lines
+50
to
+61
|
||
| static void ns800_clock_timer_isr(void *param) | ||
| { | ||
| rt_interrupt_enter(); | ||
|
|
||
| struct ns800_clock_timer *tim = (struct ns800_clock_timer *)param; | ||
|
|
||
| TIM_TypeDef *htim = (TIM_TypeDef *)tim->instance; | ||
| if (TIM_getFlags(htim, TIM_FLAG_UPDATE)) | ||
| { | ||
| TIM_clearFlags(htim, TIM_FLAG_UPDATE); | ||
| rt_clock_timer_isr(&tim->timer); | ||
|
|
||
| if (tim->mode == CLOCK_TIMER_MODE_ONESHOT) | ||
| TIM_disableCounter(htim); | ||
| } | ||
|
|
||
| rt_interrupt_leave(); | ||
| __DSB(); | ||
| } | ||
|
|
||
|
|
||
| #ifdef BSP_USING_TIM1 | ||
| void TIM1_IRQHandler(void) { ns800_clock_timer_isr(&ns800_timers[TIM1_INDEX]); } | ||
| #endif | ||
| #ifdef BSP_USING_TIM2 | ||
| void TIM2_IRQHandler(void) { ns800_clock_timer_isr(&ns800_timers[TIM2_INDEX]); } | ||
| #endif | ||
|
|
||
| static void ns800_clock_timer_init(rt_clock_timer_t *timer, rt_uint32_t state) | ||
| { | ||
| struct ns800_clock_timer *tim = (struct ns800_clock_timer *)timer->parent.user_data; | ||
|
|
||
| __IO uint32_t cfg = | ||
| TIM_PWMMODE_ONEPOINT | | ||
| TIM_CLOCKDIVISION_DIV1 | | ||
| TIM_AUTORELOADPRELOAD_ENABLE | | ||
| TIM_COUNTERMODE_UP | | ||
| TIM_ONEPULSEMODE_REPETITIVE; | ||
|
|
||
| TIM_configTimeBase((TIM_TypeDef *)tim->instance, 200-1, 100-1, cfg); | ||
| TIM_clearFlags((TIM_TypeDef *)tim->instance, TIM_FLAG_UPDATE); | ||
| TIM_enableInterruptSource((TIM_TypeDef *)tim->instance, TIM_IT_UPDATE); | ||
|
oxlm marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| static rt_err_t ns800_clock_timer_start(rt_clock_timer_t *timer, rt_uint32_t cnt, rt_clock_timer_mode_t mode) | ||
| { | ||
| struct ns800_clock_timer *tim = (struct ns800_clock_timer *)timer->parent.user_data; | ||
| tim->mode = mode; | ||
|
|
||
| TIM_TypeDef *htim = (TIM_TypeDef *)tim->instance; | ||
|
|
||
| if (cnt > 0xFFFF) cnt = 0xFFFF; | ||
| TIM_setAutoReload(htim, cnt-1); | ||
| TIM_setCounter(htim, 0); | ||
| TIM_enableCounter(htim); | ||
| return RT_EOK; | ||
| } | ||
|
|
||
| static void ns800_clock_timer_stop(rt_clock_timer_t *timer) | ||
| { | ||
| struct ns800_clock_timer *tim = (struct ns800_clock_timer *)timer->parent.user_data; | ||
|
|
||
| TIM_disableCounter((TIM_TypeDef *)tim->instance); | ||
| } | ||
|
|
||
| static rt_uint32_t ns800_clock_timer_count_get(rt_clock_timer_t *timer) | ||
| { | ||
| struct ns800_clock_timer *tim = (struct ns800_clock_timer *)timer->parent.user_data; | ||
|
|
||
| return TIM_getCounter((TIM_TypeDef *)tim->instance); | ||
| } | ||
|
|
||
| static rt_err_t __set_timerx_freq(rt_clock_timer_t *timer, uint32_t freq) | ||
| { | ||
| #define TIM_SRC_CLK 200000000UL | ||
| struct ns800_clock_timer *tim = timer->parent.user_data; | ||
|
|
||
| rt_uint32_t psc = (TIM_SRC_CLK / freq ) - 1; | ||
| TIM_setPrescaler(tim->instance, psc); | ||
|
|
||
| return RT_EOK; | ||
| } | ||
|
|
||
| static rt_err_t ns800_clock_timer_control(rt_clock_timer_t *timer, rt_uint32_t cmd, void *args) | ||
| { | ||
| rt_err_t err = RT_EOK; | ||
| rt_int32_t freq; | ||
|
|
||
| switch (cmd) | ||
| { | ||
| case CLOCK_TIMER_CTRL_FREQ_SET: | ||
| freq = *(rt_uint32_t *)args; | ||
| __set_timerx_freq(timer, freq); | ||
| break; | ||
|
oxlm marked this conversation as resolved.
Outdated
|
||
| break; | ||
| case CLOCK_TIMER_CTRL_INFO_GET: | ||
| *(struct rt_clock_timer_info*)args = *timer->info; | ||
| err = RT_EOK; | ||
| break; | ||
|
|
||
| case CLOCK_TIMER_CTRL_MODE_SET: | ||
| timer->mode = *(rt_uint32_t *)args; | ||
| break; | ||
|
|
||
| case CLOCK_TIMER_CTRL_STOP: | ||
| ns800_clock_timer_stop(timer); | ||
| break; | ||
| } | ||
| return err; | ||
| } | ||
|
|
||
|
|
||
| static const struct rt_clock_timer_info ns800_clock_timer_info[] = | ||
| { | ||
| #ifdef BSP_USING_TIM1 | ||
| { | ||
| .maxfreq = 200000000UL, | ||
| .minfreq = 1UL, | ||
| .maxcnt = 0xFFFF, | ||
| .cntmode = CLOCK_TIMER_CNTMODE_UP, | ||
| }, | ||
| #endif | ||
| #ifdef BSP_USING_TIM2 | ||
| { | ||
| .maxfreq = 200000000UL, | ||
| .minfreq = 1UL, | ||
| .maxcnt = 0xFFFF, | ||
| .cntmode = CLOCK_TIMER_CNTMODE_UP, | ||
| }, | ||
| #endif | ||
| }; | ||
|
|
||
|
|
||
| static const struct rt_clock_timer_ops ns800_clock_timer_ops = | ||
| { | ||
| .init = ns800_clock_timer_init, | ||
| .start = ns800_clock_timer_start, | ||
| .stop = ns800_clock_timer_stop, | ||
| .count_get = ns800_clock_timer_count_get, | ||
| .control = ns800_clock_timer_control, | ||
| }; | ||
|
|
||
| int rt_hw_clock_timer_init(void) | ||
| { | ||
| if (NS800_TIMER_NUM == 0) | ||
| return RT_EOK; | ||
|
|
||
| uint8_t i; | ||
| IRQn_Type last_irq = (IRQn_Type)0; | ||
|
|
||
| for (i = 0; i < NS800_TIMER_NUM; i++) | ||
| { | ||
| ns800_timers[i].timer.info = &ns800_clock_timer_info[i]; | ||
| ns800_timers[i].timer.ops = &ns800_clock_timer_ops; | ||
|
|
||
| rt_clock_timer_register(&ns800_timers[i].timer, | ||
| ns800_timers[i].name, | ||
| &ns800_timers[i]); | ||
|
|
||
| if (ns800_timers[i].irqno != last_irq) | ||
| { | ||
| Interrupt_register(ns800_timers[i].irqno, ns800_timers[i].irq_handler); | ||
| Interrupt_enable(ns800_timers[i].irqno); | ||
| last_irq = ns800_timers[i].irqno; | ||
| } | ||
|
|
||
| rt_kprintf("[%s] register ok\n", ns800_timers[i].name); | ||
| } | ||
|
oxlm marked this conversation as resolved.
Outdated
|
||
|
|
||
| return RT_EOK; | ||
| } | ||
|
|
||
| INIT_DEVICE_EXPORT(rt_hw_clock_timer_init); | ||
|
|
||
| #endif /* BSP_USING_TIM */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,12 +31,6 @@ if os.path.isdir(arch_dir): | |
| src += Glob("arch/%s/*.c" % rtconfig.ARCH) | ||
|
|
||
| CPPPATH = [cwd, os.path.join(cwd, '..', 'include')] | ||
| LOCAL_CCFLAGS = '' | ||
| if rtconfig.PLATFORM in ['gcc', 'armclang']: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 为啥要删除这块内容?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 可以看这个 https://club.rt-thread.org/ask/question/a618d48ddf478ce3.html ,不删除的话,打开clock time宏生成的工程直接编译报错
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 感觉是你工具链的问题,更新成新版本的ac6工具链试试 |
||
| LOCAL_CCFLAGS += ' -std=gnu99' | ||
| elif rtconfig.PLATFORM in ['armcc']: | ||
| LOCAL_CCFLAGS += ' --c99 --gnu' | ||
|
|
||
| group = DefineGroup('DeviceDrivers', src, depend=[''], CPPPATH=CPPPATH, LOCAL_CCFLAGS=LOCAL_CCFLAGS) | ||
| group = DefineGroup('DeviceDrivers', src, depend=[''], CPPPATH=CPPPATH) | ||
|
|
||
| Return('group') | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
注释请参考RT-Thread代码规范:https://github.com/RT-Thread/rt-thread/blob/master/documentation/7.contribution/coding_style_cn.md#4%E6%96%87%E4%BB%B6%E5%A4%B4%E6%B3%A8%E9%87%8A