当前位置:网站首页>[RT thread] construction and use of --hwtimer of NXP rt10xx device driver framework
[RT thread] construction and use of --hwtimer of NXP rt10xx device driver framework
2022-07-03 17:11:00 【L_ seventeen】
hwtimer For our commonly used hardware timers , The following will be used gpt The timer realizes the construction of device driver
Preparation before development
- Hardware platform :nxp rt10xx Single chip microcomputer
- IDE: Keil
1.Kconfig Modifications and menuconfig To configure
stay Env Environmental Science menuconfig in RT-Thread Components->Device Drivers The device driver defaults to n, So it needs to be turned on

First in Kconfig Add the following statement to , And then in Env Environmental Science menuconfig in Hardware Drivers Config->On-Chip Peripheral Drivers, Then select and specify as needed HWTIMER, Peripherals used by the author GPT1 namely :HWTIMER1

2. Engineering additions HWTIMER Drive framework and BSP Driver interface
Device drive frame :hwtimer.c BSP Interface :drv_hwtimer.c fsl_gpt.c

3. Add or modify drv_hwtimer.c
The author consulted the document , The driver is relatively perfect , The author changed the clock source , Use osc 24M As a clock source , In addition, some redundant configurations have been deleted
struct rt_hwtimer_ops
{
void (*init)(struct rt_hwtimer_device *timer, rt_uint32_t state);
rt_err_t (*start)(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
void (*stop)(struct rt_hwtimer_device *timer);
rt_uint32_t (*count_get)(struct rt_hwtimer_device *timer);
rt_err_t (*control)(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args);
};
static const struct rt_hwtimer_ops imxrt_hwtimer_ops =
{
.init = imxrt_hwtimer_init,
.start = imxrt_hwtimer_start,
.stop = imxrt_hwtimer_stop,
.count_get = imxrt_hwtimer_count_get,
.control = imxrt_hwtimer_control,
};
int rt_hw_hwtimer_init(void)
{
int ret = RT_EOK;
#ifdef BSP_USING_HWTIMER1
GPT_timer1.info = &imxrt_hwtimer_info;
GPT_timer1.ops = &imxrt_hwtimer_ops;
ret = rt_device_hwtimer_register(&GPT_timer1, "gpt1", GPT1);
if (ret != RT_EOK)
{
LOG_E("gpt1 register failed\n");
}
#endif
#ifdef BSP_USING_HWTIMER2
GPT_timer2.info = &imxrt_hwtimer_info;
GPT_timer2.ops = &imxrt_hwtimer_ops;
ret = rt_device_hwtimer_register(&GPT_timer2, "gpt2", GPT2);
if (ret != RT_EOK)
{
LOG_E("gpt1 register failed\n");
}
#endif
return ret;
}
Clock source selection and interrupt priority are the places that the author changed , All the codes are pasted here
#define GPT_CLK_FREQ CLOCK_GetFreq(kCLOCK_OscClk)
#define SAI_ISR_PRE (14U)
static void NVIC_Configuration(void)
{
#ifdef BSP_USING_HWTIMER1
NVIC_SetPriority(GPT1_IRQn,SAI_ISR_PRE);
EnableIRQ(GPT1_IRQn);
#endif
#ifdef BSP_USING_HWTIMER2
NVIC_SetPriority(GPT2_IRQn,SAI_ISR_PRE);
EnableIRQ(GPT2_IRQn);
#endif
}
static rt_err_t imxrt_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
{
rt_err_t err = RT_EOK;
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
switch (cmd)
{
case HWTIMER_CTRL_FREQ_SET:
{
uint32_t clk;
uint32_t pre;
clk = GPT_CLK_FREQ;
pre = clk / *((uint32_t *)args);
GPT_SetClockDivider(hwtimer_dev, pre);
}
break;
default:
err = -RT_ENOSYS;
break;
}
return err;
}
static rt_uint32_t imxrt_hwtimer_count_get(rt_hwtimer_t *timer)
{
rt_uint32_t CurrentTimer_Count;
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
CurrentTimer_Count = GPT_GetCurrentTimerCount(hwtimer_dev);
return CurrentTimer_Count;
}
static void imxrt_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
{
GPT_Type *hwtimer_dev;
gpt_config_t gptConfig;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
if (state == 1)
{
/* Initialize GPT module by default config */
GPT_GetDefaultConfig(&gptConfig);
gptConfig.clockSource = kGPT_ClockSource_Osc; // Select peripheral clock
gptConfig.divider = 24; // Set the frequency division coefficient 24M/24 = 1M
GPT_Init(hwtimer_dev, &gptConfig);
}
}
static rt_err_t imxrt_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
{
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
hwtimer_dev->CR |= (mode != HWTIMER_MODE_PERIOD) ? GPT_CR_FRR_MASK : 0U;
GPT_SetOutputCompareValue(hwtimer_dev, kGPT_OutputCompare_Channel1, cnt);
GPT_EnableInterrupts(hwtimer_dev, kGPT_OutputCompare1InterruptEnable);
NVIC_Configuration();
GPT_StartTimer(hwtimer_dev);
return RT_EOK;
}
static void imxrt_hwtimer_stop(rt_hwtimer_t *timer)
{
GPT_Type *hwtimer_dev;
hwtimer_dev = (GPT_Type *)timer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
GPT_StopTimer(hwtimer_dev);
}
4. Build application layer demo
Turn on timer , Check whether the time accuracy ok
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------ Includes */
#include <rtthread.h>
#include <rtdevice.h>
/*------------------------------------------------------------------------------------------------------------------ Macros */
#define HWTIMER_DEVICE_NAME "gpt1" /* Hardware timer device name */
/*------------------------------------------------------------------------------------------------------------------ Variables */
/*------------------------------------------------------------------------------------------------------------------ Functions */
/* Timer timeout callback function */
static rt_err_t timer_callback(rt_device_t dev, rt_size_t size)
{
rt_kprintf("this is hwtimer timeout callback fucntion!\n");
rt_kprintf("tick is :%d !\n", rt_tick_get());
return 0;
}
int xAPP_HwTimerInit(void)
{
rt_err_t ret = RT_EOK;
rt_hwtimerval_t timeout_s; /* Timer timeout value */
rt_device_t hw_dev = RT_NULL; /* Timer device handle */
rt_hwtimer_mode_t mode; /* timer mode */
rt_uint32_t freq = 100000; /* Counting frequency */
hw_dev = rt_device_find(HWTIMER_DEVICE_NAME);
if (hw_dev == RT_NULL)
{
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEVICE_NAME);
return RT_ERROR;
}
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
if (ret != RT_EOK)
{
rt_kprintf("open %s device failed!\n", HWTIMER_DEVICE_NAME);
return ret;
}
/* Set the timeout callback function */
rt_device_set_rx_indicate(hw_dev, timer_callback);
/* Set the counting frequency ( If this item is not set , The default is 1Mhz or Minimum count frequency supported ) */
rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);
mode = HWTIMER_MODE_PERIOD;
ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
if (ret != RT_EOK)
{
rt_kprintf("set mode failed! ret is :%d\n", ret);
return ret;
}
/* Set the timer timeout value to 5s And start the timer */
timeout_s.sec = 5; /* second */
timeout_s.usec = 0; /* Microsecond */
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
{
rt_kprintf("set timeout value failed\n");
return RT_ERROR;
}
/* Time delay 3200ms */
rt_thread_mdelay(3200);
rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
rt_kprintf("Read: Sec = %d, Usec = %d\n", timeout_s.sec, timeout_s.usec);
return ret;
}
/****************************************************END OF FILE*****************************************************/

Add up ,gpt Conversion method :
The clock source is 24M, Division coefficient 0xEF + 1 = 240, The available clock is :100000Hz,COMP:0x7A120 namely :500000
500000/100000=5s therefore 5s Break once

边栏推荐
- CC2530 common registers for watchdog
- One brush 148 force deduction hot question-5 longest palindrome substring (m)
- How to promote cross department project collaboration | community essay solicitation
- Thread pool: the most common and error prone component of business code
- Great changes! National housing prices fell below the 10000 yuan mark
- [combinatorics] recursive equation (example 1 of recursive equation | list recursive equation)
- 【RT-Thread】nxp rt10xx 设备驱动框架之--hwtimer搭建和使用
- Luogu: p1155 [noip2008 improvement group] double stack sorting (bipartite graph, simulation)
- LeetCode 1658. Minimum operand to reduce x to 0
- Network security web penetration technology
猜你喜欢

kubernetes资源对象介绍及常用命令(三)

MySQL Basics

Build your own website (23)

设计电商秒杀
![Luogu: p1155 [noip2008 improvement group] double stack sorting (bipartite graph, simulation)](/img/be/4ef38f711e7319a2cc83db2bee3a07.jpg)
Luogu: p1155 [noip2008 improvement group] double stack sorting (bipartite graph, simulation)

Meituan side: why does thread crash not cause JVM crash

聊聊接口优化的几个方法

ucore概述

How do large consumer enterprises make digital transformation?

New features of C 10
随机推荐
CC2530 common registers for crystal oscillator settings
Life is still confused? Maybe these subscription numbers have the answers you need!
IL Runtime
跨境电商:外贸企业做海外社媒营销的优势
Talk about several methods of interface optimization
[combinatorial mathematics] recursive equation (example of recursive equation 2 Hanoi Tower | example of recursive equation 3 insertion sequencing)
免费数据 | 新库上线 | CnOpenData中国保险中介机构网点全集数据
LeetCode 1657. Determine whether the two strings are close
Redis: operation commands for list type data
UCORE overview
Kotlin learning quick start (7) -- wonderful use of expansion
Take you to API development by hand
One brush 142 monotone stack next larger element II (m)
CC2530 common registers for serial communication
Kindeditor editor upload image ultra wide automatic compression -php code
Atom QT 16_ audiorecorder
線程池:業務代碼最常用也最容易犯錯的組件
Fast Ethernet and Gigabit Ethernet: what's the difference?
BYD and great wall hybrid market "get together" again
绝对定位时元素水平垂直居中