Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
RT-Thread
rt-thread
提交
84111766
R
rt-thread
项目概览
RT-Thread
/
rt-thread
8 个月 前同步成功
通知
750
Star
8909
Fork
4735
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
84111766
编写于
9月 08, 2021
作者:
C
charlown
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[bsp/wch/arm/Libraries/ch32_drivers]: support ch32f10x hwtimer.
[bsp/wch/arm/ch32f103c8-core]: add hwtimer1~4.
上级
7aa4dfec
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
637 addition
and
0 deletion
+637
-0
bsp/wch/arm/Libraries/ch32_drivers/SConscript
bsp/wch/arm/Libraries/ch32_drivers/SConscript
+3
-0
bsp/wch/arm/Libraries/ch32_drivers/drv_hwtimer_ch32f10x.c
bsp/wch/arm/Libraries/ch32_drivers/drv_hwtimer_ch32f10x.c
+372
-0
bsp/wch/arm/ch32f103c8-core/board/Kconfig
bsp/wch/arm/ch32f103c8-core/board/Kconfig
+168
-0
bsp/wch/arm/ch32f103c8-core/board/board.c
bsp/wch/arm/ch32f103c8-core/board/board.c
+91
-0
bsp/wch/arm/ch32f103c8-core/board/board.h
bsp/wch/arm/ch32f103c8-core/board/board.h
+3
-0
未找到文件。
bsp/wch/arm/Libraries/ch32_drivers/SConscript
浏览文件 @
84111766
...
...
@@ -29,6 +29,9 @@ if GetDepend('SOC_ARM_SERIES_CH32F103'):
if
GetDepend
([
'RT_USING_WDT'
,
'BSP_USING_IWDT'
]):
src
+=
[
'drv_iwdt_ch32f10x.c'
]
if
GetDepend
([
'RT_USING_HWTIMER'
,
'BSP_USING_HWTIMER'
]):
src
+=
[
'drv_hwtimer_ch32f10x.c'
]
src
+=
[
'drv_common.c'
]
path
=
[
cwd
]
...
...
bsp/wch/arm/Libraries/ch32_drivers/drv_hwtimer_ch32f10x.c
0 → 100644
浏览文件 @
84111766
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-10 charlown first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#ifdef BSP_USING_HWTIMER
#define LOG_TAG "drv.hwtimer"
#include <drv_log.h>
struct
hwtimer_device
{
struct
rt_hwtimer_device
parent
;
TIM_TypeDef
*
periph
;
IRQn_Type
irqn
;
char
*
name
;
};
#ifdef BSP_USING_TIM1_HWTIMER
struct
hwtimer_device
hwtimer_device1
=
{
.
periph
=
TIM1
,
.
irqn
=
TIM1_UP_IRQn
,
.
name
=
"timer1"
};
#endif
#ifdef BSP_USING_TIM2_HWTIMER
struct
hwtimer_device
hwtimer_device2
=
{
.
periph
=
TIM2
,
.
irqn
=
TIM2_IRQn
,
.
name
=
"timer2"
};
#endif
#ifdef BSP_USING_TIM3_HWTIMER
struct
hwtimer_device
hwtimer_device3
=
{
.
periph
=
TIM3
,
.
irqn
=
TIM3_IRQn
,
.
name
=
"timer3"
};
#endif
#ifdef BSP_USING_TIM4_HWTIMER
struct
hwtimer_device
hwtimer_device4
=
{
.
periph
=
TIM4
,
.
irqn
=
TIM4_IRQn
,
.
name
=
"timer4"
};
#endif
static
void
ch32f1_hwtimer_init
(
struct
rt_hwtimer_device
*
device
,
rt_uint32_t
state
)
{
struct
hwtimer_device
*
hwtimer_dev
;
struct
rt_hwtimer_info
*
hwtimer_info
;
rt_uint32_t
clk
=
0
;
rt_uint16_t
prescaler_value
=
0
;
TIM_TimeBaseInitTypeDef
TIM_TimeBaseInitType
;
NVIC_InitTypeDef
NVIC_InitStructure
;
RT_ASSERT
(
device
!=
RT_NULL
);
hwtimer_dev
=
(
struct
hwtimer_device
*
)
device
;
if
(
state
)
{
ch32f1_hwtimer_clock_init
(
hwtimer_dev
->
periph
);
hwtimer_info
=
ch32f1_hwtimer_info_config_get
(
hwtimer_dev
->
periph
);
clk
=
ch32f1_hwtimer_clock_get
(
hwtimer_dev
->
periph
);
prescaler_value
=
(
rt_uint16_t
)(
clk
/
hwtimer_info
->
minfreq
)
-
1
;
/*
* set interrupt callback one or each time need total time =
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
*/
TIM_TimeBaseInitType
.
TIM_Period
=
hwtimer_info
->
maxcnt
-
1
;
TIM_TimeBaseInitType
.
TIM_Prescaler
=
prescaler_value
;
TIM_TimeBaseInitType
.
TIM_ClockDivision
=
TIM_CKD_DIV1
;
TIM_TimeBaseInitType
.
TIM_RepetitionCounter
=
0
;
if
(
hwtimer_info
==
RT_NULL
)
{
TIM_TimeBaseInitType
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
}
else
{
if
(
hwtimer_info
->
cntmode
==
HWTIMER_CNTMODE_UP
)
{
TIM_TimeBaseInitType
.
TIM_CounterMode
=
TIM_CounterMode_Up
;
}
else
{
TIM_TimeBaseInitType
.
TIM_CounterMode
=
TIM_CounterMode_Down
;
}
}
TIM_TimeBaseInit
(
hwtimer_dev
->
periph
,
&
TIM_TimeBaseInitType
);
NVIC_InitStructure
.
NVIC_IRQChannel
=
hwtimer_dev
->
irqn
;
NVIC_InitStructure
.
NVIC_IRQChannelPreemptionPriority
=
2
;
NVIC_InitStructure
.
NVIC_IRQChannelSubPriority
=
0
;
NVIC_InitStructure
.
NVIC_IRQChannelCmd
=
ENABLE
;
NVIC_Init
(
&
NVIC_InitStructure
);
TIM_ITConfig
(
hwtimer_dev
->
periph
,
TIM_IT_Update
,
ENABLE
);
TIM_ClearITPendingBit
(
hwtimer_dev
->
periph
,
TIM_IT_Update
);
LOG_D
(
"%s init success"
,
hwtimer_dev
->
name
);
}
}
static
rt_err_t
ch32f1_hwtimer_start
(
struct
rt_hwtimer_device
*
device
,
rt_uint32_t
cnt
,
rt_hwtimer_mode_t
mode
)
{
struct
hwtimer_device
*
hwtimer_dev
;
RT_ASSERT
(
device
!=
RT_NULL
);
hwtimer_dev
=
(
struct
hwtimer_device
*
)
device
;
/*
* interrupt callback one or each time need total time =
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
*/
TIM_SetCounter
(
hwtimer_dev
->
periph
,
0
);
TIM_SetAutoreload
(
hwtimer_dev
->
periph
,
cnt
-
1
);
if
(
mode
==
HWTIMER_MODE_ONESHOT
)
{
TIM_SelectOnePulseMode
(
hwtimer_dev
->
periph
,
TIM_OPMode_Single
);
}
else
{
TIM_SelectOnePulseMode
(
hwtimer_dev
->
periph
,
TIM_OPMode_Repetitive
);
}
TIM_Cmd
(
hwtimer_dev
->
periph
,
ENABLE
);
LOG_D
(
"%s start, cnt = %d"
,
hwtimer_dev
->
name
,
cnt
);
return
RT_EOK
;
}
static
void
ch32f1_hwtimer_stop
(
struct
rt_hwtimer_device
*
device
)
{
struct
hwtimer_device
*
hwtimer_dev
;
RT_ASSERT
(
device
!=
RT_NULL
);
hwtimer_dev
=
(
struct
hwtimer_device
*
)
device
;
TIM_Cmd
(
hwtimer_dev
->
periph
,
DISABLE
);
TIM_SetCounter
(
hwtimer_dev
->
periph
,
0
);
}
static
rt_uint32_t
ch32f1_hwtimer_counter_get
(
struct
rt_hwtimer_device
*
device
)
{
struct
hwtimer_device
*
hwtimer_dev
;
RT_ASSERT
(
device
!=
RT_NULL
);
hwtimer_dev
=
(
struct
hwtimer_device
*
)
device
;
return
hwtimer_dev
->
periph
->
CNT
;
}
static
rt_err_t
ch32f1_hwtimer_control
(
struct
rt_hwtimer_device
*
device
,
rt_uint32_t
cmd
,
void
*
arg
)
{
struct
hwtimer_device
*
hwtimer_dev
;
rt_err_t
result
=
RT_EOK
;
RT_ASSERT
(
device
!=
RT_NULL
);
hwtimer_dev
=
(
struct
hwtimer_device
*
)
device
;
switch
(
cmd
)
{
case
HWTIMER_CTRL_FREQ_SET
:
{
rt_uint32_t
freq
=
0
;
rt_uint32_t
clk
=
0
;
rt_uint16_t
prescaler_value
=
0
;
/*
*set interrupt callback one or each time need total time =
* (cnt + 1) * (1 / (clk/(prescaler_value + 1) ) )
*/
if
(
arg
!=
RT_NULL
)
{
freq
=
*
((
rt_uint32_t
*
)
arg
);
clk
=
ch32f1_hwtimer_clock_get
(
hwtimer_dev
->
periph
);
prescaler_value
=
(
rt_uint16_t
)(
clk
/
freq
)
-
1
;
TIM_PrescalerConfig
(
hwtimer_dev
->
periph
,
prescaler_value
,
TIM_PSCReloadMode_Immediate
);
}
else
{
result
=
RT_EINVAL
;
}
}
break
;
default:
result
=
RT_ENOSYS
;
break
;
}
return
result
;
}
static
const
struct
rt_hwtimer_ops
hwtimer_ops
=
{
.
init
=
ch32f1_hwtimer_init
,
.
start
=
ch32f1_hwtimer_start
,
.
stop
=
ch32f1_hwtimer_stop
,
.
count_get
=
ch32f1_hwtimer_counter_get
,
.
control
=
ch32f1_hwtimer_control
,
};
static
int
rt_hw_hwtimer_init
(
void
)
{
rt_err_t
ret
;
struct
rt_hwtimer_info
*
hwtimer_info
;
#ifdef BSP_USING_TIM1_HWTIMER
hwtimer_info
=
ch32f1_hwtimer_info_config_get
(
hwtimer_device1
.
periph
);
hwtimer_device1
.
parent
.
info
=
hwtimer_info
;
hwtimer_device1
.
parent
.
ops
=
&
hwtimer_ops
;
ret
=
rt_device_hwtimer_register
(
&
hwtimer_device1
.
parent
,
hwtimer_device1
.
name
,
RT_NULL
);
if
(
ret
==
RT_EOK
)
{
LOG_D
(
"hwtimer: %s register success."
,
hwtimer_device1
.
name
);
}
else
{
LOG_D
(
"hwtimer: %s register failed."
,
hwtimer_device1
.
name
);
}
#endif
#ifdef BSP_USING_TIM2_HWTIMER
hwtimer_info
=
ch32f1_hwtimer_info_config_get
(
hwtimer_device2
.
periph
);
hwtimer_device2
.
parent
.
info
=
hwtimer_info
;
hwtimer_device2
.
parent
.
ops
=
&
hwtimer_ops
;
ret
=
rt_device_hwtimer_register
(
&
hwtimer_device2
.
parent
,
hwtimer_device2
.
name
,
RT_NULL
);
if
(
ret
==
RT_EOK
)
{
LOG_D
(
"hwtimer: %s register success."
,
hwtimer_device2
.
name
);
}
else
{
LOG_D
(
"hwtimer: %s register failed."
,
hwtimer_device2
.
name
);
}
#endif
#ifdef BSP_USING_TIM3_HWTIMER
hwtimer_info
=
ch32f1_hwtimer_info_config_get
(
hwtimer_device3
.
periph
);
hwtimer_device3
.
parent
.
info
=
hwtimer_info
;
hwtimer_device3
.
parent
.
ops
=
&
hwtimer_ops
;
ret
=
rt_device_hwtimer_register
(
&
hwtimer_device3
.
parent
,
hwtimer_device3
.
name
,
RT_NULL
);
if
(
ret
==
RT_EOK
)
{
LOG_D
(
"hwtimer: %s register success."
,
hwtimer_device3
.
name
);
}
else
{
LOG_D
(
"hwtimer: %s register failed."
,
hwtimer_device3
.
name
);
}
#endif
#ifdef BSP_USING_TIM4_HWTIMER
hwtimer_info
=
ch32f1_hwtimer_info_config_get
(
hwtimer_device4
.
periph
);
hwtimer_device4
.
parent
.
info
=
hwtimer_info
;
hwtimer_device4
.
parent
.
ops
=
&
hwtimer_ops
;
ret
=
rt_device_hwtimer_register
(
&
hwtimer_device4
.
parent
,
hwtimer_device4
.
name
,
RT_NULL
);
if
(
ret
==
RT_EOK
)
{
LOG_D
(
"hwtimer: %s register success."
,
hwtimer_device4
.
name
);
}
else
{
LOG_D
(
"hwtimer: %s register failed."
,
hwtimer_device4
.
name
);
}
#endif
return
RT_EOK
;
}
INIT_DEVICE_EXPORT
(
rt_hw_hwtimer_init
);
#ifdef BSP_USING_TIM1_HWTIMER
void
TIM1_UP_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
hwtimer_device1
.
periph
,
TIM_IT_Update
)
==
SET
)
{
TIM_ClearITPendingBit
(
hwtimer_device1
.
periph
,
TIM_IT_Update
);
rt_device_hwtimer_isr
(
&
hwtimer_device1
.
parent
);
}
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
#ifdef BSP_USING_TIM2_HWTIMER
void
TIM2_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
hwtimer_device2
.
periph
,
TIM_IT_Update
)
==
SET
)
{
TIM_ClearITPendingBit
(
hwtimer_device2
.
periph
,
TIM_IT_Update
);
rt_device_hwtimer_isr
(
&
hwtimer_device2
.
parent
);
}
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
#ifdef BSP_USING_TIM3_HWTIMER
void
TIM3_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
hwtimer_device3
.
periph
,
TIM_IT_Update
)
==
SET
)
{
TIM_ClearITPendingBit
(
hwtimer_device3
.
periph
,
TIM_IT_Update
);
rt_device_hwtimer_isr
(
&
hwtimer_device3
.
parent
);
}
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
#ifdef BSP_USING_TIM4_HWTIMER
void
TIM4_IRQHandler
(
void
)
{
/* enter interrupt */
rt_interrupt_enter
();
if
(
TIM_GetITStatus
(
hwtimer_device4
.
periph
,
TIM_IT_Update
)
==
SET
)
{
TIM_ClearITPendingBit
(
hwtimer_device4
.
periph
,
TIM_IT_Update
);
rt_device_hwtimer_isr
(
&
hwtimer_device4
.
parent
);
}
/* leave interrupt */
rt_interrupt_leave
();
}
#endif
#endif
/* BSP_USING_HWTIMER */
bsp/wch/arm/ch32f103c8-core/board/Kconfig
浏览文件 @
84111766
...
...
@@ -80,6 +80,174 @@ config LSI_VALUE
int
default 40000
config BSP_USING_TIM
bool "using TIMx"
default n
if BSP_USING_TIM
config BSP_USING_HWTIMER
bool
select RT_USING_HWTIMER
default n
config BSP_USING_PWM
bool
select RT_USING_PWM
default n
config BSP_USING_TIM1
bool "using TIM1"
default n
if BSP_USING_TIM1
choice
prompt "using TIM1 as hwtimer or pwm mode"
default BSP_USING_TIM1_HWTIMER
config BSP_USING_TIM1_HWTIMER
bool "using TIM1 as hwtimer mode"
select BSP_USING_HWTIMER
config BSP_USING_TIM1_PWM
bool "using TIM1 as pwm mode"
select BSP_USING_PWM
endchoice
if BSP_USING_TIM1_PWM
config BSP_USING_TIM1_PWM_CH1
bool "using TIM1 channel 1 as pwm"
default n
config BSP_USING_TIM1_PWM_CH2
bool "using TIM1 channel 2 as pwm"
default n
config BSP_USING_TIM1_PWM_CH3
bool "using TIM1 channel 3 as pwm"
config BSP_USING_TIM1_PWM_CH4
bool "using TIM1 channel 4 as pwm"
endif
endif
config BSP_USING_TIM2
bool "using TIM2"
default n
if BSP_USING_TIM2
choice
prompt "using TIM2 as hwtimer or pwm mode"
default BSP_USING_TIM2_HWTIMER
config BSP_USING_TIM2_HWTIMER
bool "using TIM2 as hwtimer mode"
select BSP_USING_HWTIMER
config BSP_USING_TIM2_PWM
bool "using TIM2 as pwm mode"
select BSP_USING_PWM
endchoice
if BSP_USING_TIM2_PWM
config BSP_USING_TIM2_PWM_CH1
bool "using TIM2 channel 1 as pwm"
default n
config BSP_USING_TIM2_PWM_CH2
bool "using TIM2 channel 2 as pwm"
default n
config BSP_USING_TIM2_PWM_CH3
bool "using TIM2 channel 3 as pwm"
config BSP_USING_TIM2_PWM_CH4
bool "using TIM2 channel 4 as pwm"
endif
endif
config BSP_USING_TIM3
bool "using TIM3"
default n
if BSP_USING_TIM3
choice
prompt "using TIM3 as hwtimer or pwm mode"
default BSP_USING_TIM3_HWTIMER
config BSP_USING_TIM3_HWTIMER
bool "using TIM3 as hwtimer mode"
select BSP_USING_HWTIMER
config BSP_USING_TIM3_PWM
bool "using TIM3 as pwm mode"
select BSP_USING_PWM
endchoice
if BSP_USING_TIM3_PWM
config BSP_USING_TIM3_PWM_CH1
bool "using TIM3 channel 1 as pwm"
default n
config BSP_USING_TIM3_PWM_CH2
bool "using TIM3 channel 2 as pwm"
default n
config BSP_USING_TIM3_PWM_CH3
bool "using TIM3 channel 3 as pwm"
config BSP_USING_TIM3_PWM_CH4
bool "using TIM3 channel 4 as pwm"
endif
endif
config BSP_USING_TIM4
bool "using TIM4"
default n
if BSP_USING_TIM4
choice
prompt "using TIM4 as hwtimer or pwm mode"
default BSP_USING_TIM4_HWTIMER
config BSP_USING_TIM4_HWTIMER
bool "using TIM4 as hwtimer mode"
select BSP_USING_HWTIMER
config BSP_USING_TIM4_PWM
bool "using TIM4 as pwm mode"
select BSP_USING_PWM
endchoice
if BSP_USING_TIM4_PWM
config BSP_USING_TIM4_PWM_CH1
bool "using TIM4 channel 1 as pwm"
default n
config BSP_USING_TIM4_PWM_CH2
bool "using TIM4 channel 2 as pwm"
default n
config BSP_USING_TIM4_PWM_CH3
bool "using TIM4 channel 3 as pwm"
config BSP_USING_TIM4_PWM_CH4
bool "using TIM4 channel 4 as pwm"
endif
endif
endif
endmenu
menu "Onboard Peripheral Drivers"
...
...
bsp/wch/arm/ch32f103c8-core/board/board.c
浏览文件 @
84111766
...
...
@@ -200,4 +200,95 @@ void ch32f1_i2c_config(I2C_TypeDef *i2cx)
}
}
void
ch32f1_hwtimer_clock_init
(
TIM_TypeDef
*
timx
)
{
if
(
timx
==
TIM1
)
{
RCC_APB2PeriphClockCmd
(
RCC_APB2Periph_TIM1
,
ENABLE
);
}
if
(
timx
==
TIM2
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM2
,
ENABLE
);
}
if
(
timx
==
TIM3
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM3
,
ENABLE
);
}
if
(
timx
==
TIM4
)
{
RCC_APB1PeriphClockCmd
(
RCC_APB1Periph_TIM4
,
ENABLE
);
}
}
rt_uint32_t
ch32f1_hwtimer_clock_get
(
TIM_TypeDef
*
timx
)
{
RCC_ClocksTypeDef
RCC_Clocks
;
RCC_GetClocksFreq
(
&
RCC_Clocks
);
/*tim1~4 all in HCLK*/
return
RCC_Clocks
.
HCLK_Frequency
;
}
struct
rt_hwtimer_info
hwtimer_info1
=
{
.
maxfreq
=
1000000
,
.
minfreq
=
2000
,
.
maxcnt
=
0xFFFF
,
.
cntmode
=
HWTIMER_CNTMODE_UP
,
};
struct
rt_hwtimer_info
hwtimer_info2
=
{
.
maxfreq
=
1000000
,
.
minfreq
=
2000
,
.
maxcnt
=
0xFFFF
,
.
cntmode
=
HWTIMER_CNTMODE_UP
,
};
struct
rt_hwtimer_info
hwtimer_info3
=
{
.
maxfreq
=
1000000
,
.
minfreq
=
2000
,
.
maxcnt
=
0xFFFF
,
.
cntmode
=
HWTIMER_CNTMODE_UP
,
};
struct
rt_hwtimer_info
hwtimer_info4
=
{
.
maxfreq
=
1000000
,
.
minfreq
=
2000
,
.
maxcnt
=
0xFFFF
,
.
cntmode
=
HWTIMER_CNTMODE_UP
,
};
struct
rt_hwtimer_info
*
ch32f1_hwtimer_info_config_get
(
TIM_TypeDef
*
timx
)
{
struct
rt_hwtimer_info
*
info
=
RT_NULL
;
if
(
timx
==
TIM1
)
{
info
=
&
hwtimer_info1
;
}
else
if
(
timx
==
TIM2
)
{
info
=
&
hwtimer_info2
;
}
else
if
(
timx
==
TIM3
)
{
info
=
&
hwtimer_info3
;
}
else
if
(
timx
==
TIM4
)
{
info
=
&
hwtimer_info4
;
}
return
info
;
}
bsp/wch/arm/ch32f103c8-core/board/board.h
浏览文件 @
84111766
...
...
@@ -50,6 +50,9 @@ void ch32f1_spi_clock_and_io_init(SPI_TypeDef* spix);
rt_uint32_t
ch32f1_spi_clock_get
(
SPI_TypeDef
*
spix
);
void
ch32f1_i2c_clock_and_io_init
(
I2C_TypeDef
*
i2cx
);
void
ch32f1_i2c_config
(
I2C_TypeDef
*
i2cx
);
void
ch32f1_hwtimer_clock_init
(
TIM_TypeDef
*
timx
);
rt_uint32_t
ch32f1_hwtimer_clock_get
(
TIM_TypeDef
*
timx
);
struct
rt_hwtimer_info
*
ch32f1_hwtimer_info_config_get
(
TIM_TypeDef
*
timx
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录