Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bsp/novosns/ns800/libraries/HAL_Drivers/drivers/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ if GetDepend('BSP_USING_CAN'):
if GetDepend('BSP_USING_ECAP'):
src += ['drv_ecap.c']

if GetDepend('BSP_USING_TIM'):
src += ['drv_timer.c']

group = DefineGroup('HAL_Drivers', src, depend = [''], CPPPATH = path)

Return('group')
274 changes: 274 additions & 0 deletions bsp/novosns/ns800/libraries/HAL_Drivers/drivers/drv_timer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,274 @@
/*
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分已修改

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* 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"
#include "tim.h"
#include "rcc.h"

#ifdef BSP_USING_TIM

#define DRV_DEBUG
#define LOG_TAG "drv.timer"
#include <drv_log.h>

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 +51 to +62
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;
TIM_TypeDef *htim = (TIM_TypeDef *)tim->instance;

if(state)
{
__IO uint32_t cfg =
TIM_PWMMODE_ONEPOINT |
TIM_CLOCKDIVISION_DIV1 |
TIM_AUTORELOADPRELOAD_ENABLE |
TIM_COUNTERMODE_UP |
TIM_ONEPULSEMODE_REPETITIVE;

TIM_configTimeBase(htim, 200-1, 100-1, cfg);
TIM_clearFlags(htim, TIM_FLAG_UPDATE);
TIM_enableInterruptSource(htim, TIM_IT_UPDATE);
}
else
{
TIM_disableInterruptSource(htim, TIM_IT_UPDATE);
TIM_disableCounter(htim);
}
}

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 uint32_t __get_timer_src_clk(TIM_TypeDef *htim)
{
if (htim == TIM1)
{
uint32_t pclk = RCC_getPclk2Frequency();
return (RCC_getApb2ClkDiv() == RCC_APB2_4_HCLK_DIV1) ? pclk : (pclk << 1);
}
else if (htim == TIM2)
{
uint32_t pclk = RCC_getPclk2Frequency();
return (RCC_getApb2ClkDiv() == RCC_APB2_4_HCLK_DIV1) ? pclk : (pclk << 1);
}

return 0;
}

static rt_err_t __set_timerx_freq(rt_clock_timer_t *timer, uint32_t freq)
{
struct ns800_clock_timer *tim = timer->parent.user_data;
TIM_TypeDef *htim = (TIM_TypeDef *)tim->instance;
uint32_t timer_clk;
uint32_t psc;

if (freq == 0)
{
return -RT_ERROR;
}

timer_clk = __get_timer_src_clk(htim);
if (timer_clk == 0)
{
LOG_E("timer %s does not use internal RCC clock source or clock query failed", tim->name);
return -RT_ERROR;
}

psc = (timer_clk / freq) - 1;
TIM_setPrescaler(htim, 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;
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)
{
rt_err_t ret = RT_EOK;

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;

ret = rt_clock_timer_register(&ns800_timers[i].timer,
ns800_timers[i].name,
&ns800_timers[i]);

if ((ret == RT_EOK) && (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;
}
}

return RT_EOK;
}

INIT_DEVICE_EXPORT(rt_hw_clock_timer_init);

#endif /* BSP_USING_TIM */
19 changes: 19 additions & 0 deletions bsp/novosns/ns800/ns800rt7p65-nssinepad/board/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,23 @@ menu "On-chip Peripheral Drivers"

endif

menuconfig BSP_USING_TIM
bool "Enable TIM (Hardware Timer)"
select RT_USING_CLOCK_TIME
default n
help
Enable hardware timer TIM driver

if BSP_USING_TIM
menu "TIM Timer Configuration"
config BSP_USING_TIM1
bool "Enable TIM1"
default n
config BSP_USING_TIM2
bool "Enable TIM2"
default n
endmenu

endif

endmenu
8 changes: 1 addition & 7 deletions components/drivers/clock_time/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -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']:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥要删除这块内容?

Copy link
Copy Markdown
Contributor

@ShaquilleLiu ShaquilleLiu May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以看这个 https://club.rt-thread.org/ask/question/a618d48ddf478ce3.html ,不删除的话,打开clock time宏生成的工程直接编译报错

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感觉是你工具链的问题,更新成新版本的ac6工具链试试

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

问题就在这,其实我编译器是keil 5.39,打开生成的工程看配置,已经显示编译器用的是AC6,也就是clang,不是armcc了。然后这几天尝试把这块还原,采用不动bsp以外的部分的方式解决,发现把copilot的免费额度烧的差不多了都没找到解决方案,甚至连根本原因都没找到。

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分已还原,原因是ns800的rtconfig.py在keil下默认选择的是armcc,所以clock time编译选项跑到另一边,实际我本地keil版本比较新,使用的是armclang,导致编译时报错。因此只还原clock time部分,rtconfig.py部分先不动,因为实际使用armcc编译器的keil应该是能编译过的 @Rbb666

rtconfig.py里面的字段其实并没有实际作用,scons --target=mdk5 命令是基于template.uvprojx 生成的,也就是template.uvprojx里面配置的是ac5/ac6。

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以在其他的BSP下面,使用MDK+AC6去验证下是否会出现一样的问题

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看了下n32和nxp,py脚本写的是armcc,模板工程选择的是AC5。倒是renesas有不少配置成了AC6,同时py脚本也选到了armclang。再鉴于ns800模板工程选择AC5编译会有一堆报错,基本上就确定了要改py脚本了。帮忙看看这么改是否可行

rtconfig.py这个脚本里面的platform虽然说不能直接指定keil用哪个编译器,但是会让工程生成时选择不同的配置信息,这就是问题的根源。
@Rbb666

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我的理解是当选择是keil时,platform不是从template工程中的配置设置的,而是强制指定的(关键这个指定也不会让生成的工程切换到platform指定的编译器上),两边存在不同步的风险。

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

详见: #11430

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')
Loading