当前位置:网站首页>[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 serial communication
- 绝对定位时元素水平垂直居中
- Squid 服务启动脚本
- [combinatorial mathematics] recursive equation (example of recursive equation 2 Hanoi Tower | example of recursive equation 3 insertion sequencing)
- Design e-commerce spike
- How to promote cross department project collaboration | community essay solicitation
- [combinatorics] recursive equation (example of solving recursive equation without multiple roots | complete process of solving recursive equation without multiple roots)
- PHP online confusion encryption tutorial sharing + basically no solution
- kubernetes资源对象介绍及常用命令(三)
- Hands on in-depth learning notes (XIV) 3.7 Simple implementation of softmax regression
猜你喜欢

Mysql database DDL and DML

静态程序分析(一)—— 大纲思维导图与内容介绍

Take you to API development by hand

Free data | new library online | cnopendata complete data of China's insurance intermediary outlets

CC2530 common registers for port initialization

美团一面:为什么线程崩溃崩溃不会导致 JVM 崩溃

Pools de Threads: les composants les plus courants et les plus sujets aux erreurs du Code d'affaires

Network security web penetration technology

kubernetes资源对象介绍及常用命令(五)-(NFS&PV&PVC)

建立自己的网站(23)
随机推荐
2021 ICPC regional competition (Shanghai) g.edge groups (tree DP)
One brush 146 force buckle hot question-3 longest substring without repeated characters (m)
Javescript variable declaration -- VaR, let, const
On Lagrange interpolation and its application
How to judge the region of an IP through C?
Free data | new library online | cnopendata complete data of China's insurance intermediary outlets
[combinatorics] recursive equation (the relationship theorem between the solution of the recursive equation and the characteristic root | the linear property theorem of the solution of the recursive e
[2. Basics of Delphi grammar] 2 Object Pascal data type
C language string practice
匯編實例解析--實模式下屏幕顯示
C language string inversion
[2. Basics of Delphi grammar] 1 Identifiers and reserved words
PHP online confusion encryption tutorial sharing + basically no solution
Build your own website (23)
一位普通程序员一天工作清单
SWM32系列教程4-端口映射及串口应用
[combinatorics] recursive equation (constant coefficient linear homogeneous recursive equation | constant coefficient, linear, homogeneous concept description | constant coefficient linear homogeneous
Apache service suspended asynchronous acceptex failed
How to delete a specific line from a text file using the SED command?
MySQL user management