当前位置:网站首页>[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

边栏推荐
- SVN完全备份svnadmin hotcopy
- [2. Basics of Delphi grammar] 2 Object Pascal data type
- LeetCode 1656. Design ordered flow
- C语言按行修改文件
- LeetCode13.罗马数字转整数(三种解法)
- How to promote cross department project collaboration | community essay solicitation
- [combinatorics] recursive equation (general solution structure of recursive equation with multiple roots | linear independent solution | general solution with multiple roots | solution example of recu
- What is your income level in the country?
- 大变局!全国房价,跌破万元大关
- LeetCode 1657. Determine whether the two strings are close
猜你喜欢
随机推荐
CC2530 common registers for watchdog
LeetCode 1656. Design ordered flow
27. Input 3 integers and output them in descending order. Pointer method is required.
Assembly instance analysis -- screen display in real mode
比亚迪、长城混动市场再“聚首”
Kindeditor editor upload image ultra wide automatic compression -php code
Free data | new library online | cnopendata complete data of China's insurance intermediary outlets
跨境电商:外贸企业做海外社媒营销的优势
Vs code plug-in korofileheader
Bcvp developer community 2022 exclusive peripheral first bullet
The most complete postman interface test tutorial in the whole network, API interface test
CC2530 common registers for port interrupts
The largest matrix (H) in a brush 143 monotone stack 84 histogram
设计电商秒杀
Answer to the homework assessment of advanced English reading (II) of the course examination of Fuzhou Normal University in February 2022
Static program analysis (I) -- Outline mind map and content introduction
Depth first search of graph
線程池:業務代碼最常用也最容易犯錯的組件
RF Analyze Demo搭建 Step by Step
深入理解 SQL 中的 Grouping Sets 语句








