From 81d45ba619c4c48ebbbf3b628392925068d94f94 Mon Sep 17 00:00:00 2001 From: HonestQiao Date: Wed, 24 Jun 2026 08:25:11 +0800 Subject: [PATCH 1/2] [bsp][imxrt1180-nxp-evk]add TIMER support --- .../cm33/applications/main.c | 58 +++++++++++++++++++ .../imxrt1180-nxp-evk/cm33/board/Kconfig | 14 +++++ .../imxrt1180-nxp-evk/cm33/board/SConscript | 4 ++ .../imxrt/imxrt1180-nxp-evk/cm7/board/Kconfig | 14 +++++ .../imxrt1180-nxp-evk/cm7/board/SConscript | 4 ++ .../imx/imxrt/libraries/drivers/drv_timer.c | 8 +-- .../imx/imxrt/libraries/drivers/drv_timer.h | 2 +- 7 files changed, 99 insertions(+), 5 deletions(-) diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c index db33aa290d8..8eaf838495d 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c @@ -14,10 +14,68 @@ #include #include +#ifdef BSP_USING_CLOCK_TIMER1 +static rt_err_t gpt1_timeout_cb(rt_device_t dev, rt_size_t size) +{ + rt_kprintf("gpt1 timeout, tick: %d\r\n", rt_tick_get()); + return RT_EOK; +} + +static void gpt1_sample_init(void) +{ + rt_device_t dev; + rt_clock_timer_mode_t mode; + rt_clock_timerval_t tv; + + dev = rt_device_find("gpt1"); + if (dev == RT_NULL) + { + rt_kprintf("gpt1 device not found\r\n"); + return; + } + + if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + rt_kprintf("gpt1 open failed\r\n"); + return; + } + + if (rt_device_set_rx_indicate(dev, gpt1_timeout_cb) != RT_EOK) + { + rt_kprintf("gpt1 set rx indicate failed\r\n"); + rt_device_close(dev); + return; + } + + mode = CLOCK_TIMER_MODE_PERIOD; + if (rt_device_control(dev, CLOCK_TIMER_CTRL_MODE_SET, &mode) != RT_EOK) + { + rt_kprintf("gpt1 mode set failed\r\n"); + rt_device_close(dev); + return; + } + + tv.sec = 1; + tv.usec = 0; + if (rt_device_write(dev, 0, &tv, sizeof(tv)) != sizeof(tv)) + { + rt_kprintf("gpt1 write failed\r\n"); + rt_device_close(dev); + return; + } + + rt_kprintf("gpt1 periodic timer started (1s)\r\n"); +} +#endif + int main(void) { rt_kprintf("MIMXRT1180_CM33 Hello_World\r\n"); +#ifdef BSP_USING_CLOCK_TIMER1 + gpt1_sample_init(); +#endif + while (1) { rt_thread_mdelay(500); diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/Kconfig b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/Kconfig index 12d8078d8c2..0c9f57d70c7 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/Kconfig +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/Kconfig @@ -138,6 +138,20 @@ menu "On-chip Peripheral Drivers" default n endif + menuconfig BSP_USING_CLOCK_TIMER + bool "Enable GPT" + default n + select RT_USING_CLOCK_TIME + if BSP_USING_CLOCK_TIMER + config BSP_USING_CLOCK_TIMER1 + bool "Enable GPT1" + default n + + config BSP_USING_CLOCK_TIMER2 + bool "Enable GPT2" + default n + endif + menuconfig BSP_USING_FLEXSPI bool "Enable FLEXSPI" default n diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/SConscript b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/SConscript index 0cfbe5a55b1..0c873a96107 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/SConscript +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/board/SConscript @@ -26,6 +26,10 @@ if rtconfig.PLATFORM in ['iccarm']: CPPDEFINES += ['NDEBUG'] # CPPDEFINES += ['FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE=1'] +if GetDepend(['BSP_USING_CLOCK_TIMER']): + src += ['../packages/nxp-imxrt-sdk-latest/MIMXRT1180/MIMXRT1189/drivers/fsl_gpt.c'] + CPPPATH += [cwd + '/../packages/nxp-imxrt-sdk-latest/MIMXRT1180/MIMXRT1189/drivers'] + group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES) Return('group') diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/Kconfig b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/Kconfig index 20b7ee52514..90ea8d58a23 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/Kconfig +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/Kconfig @@ -152,6 +152,20 @@ menu "On-chip Peripheral Drivers" bool "Enable FLEXSPI2" default n endif + + menuconfig BSP_USING_CLOCK_TIMER + bool "Enable GPT" + default n + select RT_USING_CLOCK_TIME + if BSP_USING_CLOCK_TIMER + config BSP_USING_CLOCK_TIMER1 + bool "Enable GPT1" + default n + + config BSP_USING_CLOCK_TIMER2 + bool "Enable GPT2" + default n + endif endmenu menu "Onboard Peripheral Drivers" diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/SConscript b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/SConscript index 81007a0eebc..454ccb04db4 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/SConscript +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/board/SConscript @@ -22,6 +22,10 @@ if rtconfig.PLATFORM in ['armcc', 'armclang']: if rtconfig.PLATFORM in ['iccarm']: CPPDEFINES += ['NDEBUG'] +if GetDepend(['BSP_USING_CLOCK_TIMER']): + src += ['../packages/nxp-imxrt-sdk-latest/MIMXRT1180/MIMXRT1189/drivers/fsl_gpt.c'] + CPPPATH += [cwd + '/../packages/nxp-imxrt-sdk-latest/MIMXRT1180/MIMXRT1189/drivers'] + group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES=CPPDEFINES) Return('group') diff --git a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c index 860c483e92f..24feac42bc5 100644 --- a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c +++ b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c @@ -29,10 +29,10 @@ /* Clock divider for PERCLK_CLK clock source */ #define EXAMPLE_GPT_CLOCK_DIVIDER_SELECT (5U) /* Get source clock for GPT driver (GPT prescaler = 6) */ -#ifdef SOC_IMXRT1170_SERIES +#if defined(SOC_IMXRT1170_SERIES) || defined(SOC_IMXRT1180_SERIES) #undef EXAMPLE_GPT_CLOCK_DIVIDER_SELECT #define EXAMPLE_GPT_CLOCK_DIVIDER_SELECT (2U) -// 1170 use this root directly, we have already divide this clk, can read it directly +// 1170/1180 use this root directly, we have already divide this clk, can read it directly #define EXAMPLE_GPT_CLK_FREQ (CLOCK_GetRootClockFreq(kCLOCK_Root_Gpt1)) #else #define EXAMPLE_GPT_CLK_FREQ (CLOCK_GetFreq(kCLOCK_IpgClk) / (EXAMPLE_GPT_CLOCK_DIVIDER_SELECT + 1U)) @@ -98,7 +98,7 @@ static void imxrt_clock_timer_init(rt_clock_timer_t *timer, rt_uint32_t state) if (state == 1) { - #ifdef SOC_IMXRT1170_SERIES + #if defined(SOC_IMXRT1170_SERIES) || defined(SOC_IMXRT1180_SERIES) #ifdef BSP_USING_CLOCK_TIMER1 /*Clock setting for GPT*/ CLOCK_SetRootClockMux(kCLOCK_Root_Gpt1, EXAMPLE_GPT_CLOCK_SOURCE_SELECT); @@ -198,7 +198,7 @@ int rt_hw_clock_timer_init(void) if (ret != RT_EOK) { - LOG_E("gpt1 register failed\n"); + LOG_E("gpt2 register failed\n"); } #endif diff --git a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.h b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.h index dc95a020b64..87775feb31b 100644 --- a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.h +++ b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.h @@ -14,7 +14,7 @@ #include #include -int rt_hw_wdt_init(void); +int rt_hw_clock_timer_init(void); #endif From dd5e61df7a2e2024245b506d64be7211078b4d8a Mon Sep 17 00:00:00 2001 From: HonestQiao Date: Wed, 24 Jun 2026 09:24:35 +0800 Subject: [PATCH 2/2] [bsp][imxrt1180-nxp-evk]update TIMER support --- .../cm33/applications/main.c | 14 ++-- .../imxrt1180-nxp-evk/cm7/applications/main.c | 64 ++++++++++++++++++ .../imx/imxrt/libraries/drivers/drv_timer.c | 67 +++++++++++++++++-- 3 files changed, 136 insertions(+), 9 deletions(-) diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c index 8eaf838495d..5d656ecdbd4 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm33/applications/main.c @@ -15,9 +15,15 @@ #include #ifdef BSP_USING_CLOCK_TIMER1 +static volatile rt_uint32_t gpt1_irq_count = 0; + static rt_err_t gpt1_timeout_cb(rt_device_t dev, rt_size_t size) { - rt_kprintf("gpt1 timeout, tick: %d\r\n", rt_tick_get()); + gpt1_irq_count++; + if (gpt1_irq_count % 1000 == 0) + { + rt_kprintf("gpt1 1ms x 1000, tick: %d, total irq: %d\r\n", rt_tick_get(), gpt1_irq_count); + } return RT_EOK; } @@ -55,8 +61,8 @@ static void gpt1_sample_init(void) return; } - tv.sec = 1; - tv.usec = 0; + tv.sec = 0; + tv.usec = 1000; if (rt_device_write(dev, 0, &tv, sizeof(tv)) != sizeof(tv)) { rt_kprintf("gpt1 write failed\r\n"); @@ -64,7 +70,7 @@ static void gpt1_sample_init(void) return; } - rt_kprintf("gpt1 periodic timer started (1s)\r\n"); + rt_kprintf("gpt1 periodic timer started (1ms)\r\n"); } #endif diff --git a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/applications/main.c b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/applications/main.c index 5c4b4373dfd..dc542bf6225 100644 --- a/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/applications/main.c +++ b/bsp/nxp/imx/imxrt/imxrt1180-nxp-evk/cm7/applications/main.c @@ -14,10 +14,74 @@ #include #include +#ifdef BSP_USING_CLOCK_TIMER1 +static volatile rt_uint32_t gpt1_irq_count = 0; + +static rt_err_t gpt1_timeout_cb(rt_device_t dev, rt_size_t size) +{ + gpt1_irq_count++; + if (gpt1_irq_count % 1000 == 0) + { + rt_kprintf("gpt1 1ms x 1000, tick: %d, total irq: %d\r\n", rt_tick_get(), gpt1_irq_count); + } + return RT_EOK; +} + +static void gpt1_sample_init(void) +{ + rt_device_t dev; + rt_clock_timer_mode_t mode; + rt_clock_timerval_t tv; + + dev = rt_device_find("gpt1"); + if (dev == RT_NULL) + { + rt_kprintf("gpt1 device not found\r\n"); + return; + } + + if (rt_device_open(dev, RT_DEVICE_OFLAG_RDWR) != RT_EOK) + { + rt_kprintf("gpt1 open failed\r\n"); + return; + } + + if (rt_device_set_rx_indicate(dev, gpt1_timeout_cb) != RT_EOK) + { + rt_kprintf("gpt1 set rx indicate failed\r\n"); + rt_device_close(dev); + return; + } + + mode = CLOCK_TIMER_MODE_PERIOD; + if (rt_device_control(dev, CLOCK_TIMER_CTRL_MODE_SET, &mode) != RT_EOK) + { + rt_kprintf("gpt1 mode set failed\r\n"); + rt_device_close(dev); + return; + } + + tv.sec = 0; + tv.usec = 1000; + if (rt_device_write(dev, 0, &tv, sizeof(tv)) != sizeof(tv)) + { + rt_kprintf("gpt1 write failed\r\n"); + rt_device_close(dev); + return; + } + + rt_kprintf("gpt1 periodic timer started (1ms)\r\n"); +} +#endif + int main(void) { rt_kprintf("MIMXRT1180_CM7 Hello_World\r\n"); +#ifdef BSP_USING_CLOCK_TIMER1 + gpt1_sample_init(); +#endif + while (1) { rt_thread_mdelay(500); diff --git a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c index 24feac42bc5..9e551a61e80 100644 --- a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c +++ b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c @@ -38,6 +38,17 @@ #define EXAMPLE_GPT_CLK_FREQ (CLOCK_GetFreq(kCLOCK_IpgClk) / (EXAMPLE_GPT_CLOCK_DIVIDER_SELECT + 1U)) #endif +/* The effective GPT input clock after root/prescaler configuration. + * 1170: 24 MHz root / 3 = 8 MHz; 1180: 240 MHz root / 3 = 80 MHz. */ +#if defined(SOC_IMXRT1180_SERIES) +#define IMXRT_GPT_MAXFREQ (80000000U) +#elif defined(SOC_IMXRT1170_SERIES) +#define IMXRT_GPT_MAXFREQ (8000000U) +#else +#define IMXRT_GPT_MAXFREQ (25000000U) +#endif +#define IMXRT_GPT_MINFREQ (1U) + static void NVIC_Configuration(void) { #ifdef BSP_USING_CLOCK_TIMER1 @@ -62,9 +73,36 @@ static rt_err_t imxrt_clock_timer_control(rt_clock_timer_t *timer, rt_uint32_t c case CLOCK_TIMER_CTRL_FREQ_SET: { uint32_t clk; + uint32_t freq; uint32_t pre; + + if (args == RT_NULL) + { + err = -RT_EEMPTY; + break; + } + + freq = *((uint32_t *)args); + if (freq == 0U) + { + err = -RT_EINVAL; + break; + } + clk = EXAMPLE_GPT_CLK_FREQ; - pre = clk / *((uint32_t *)args) - 1; + if (freq > clk) + { + err = -RT_EINVAL; + break; + } + + pre = clk / freq - 1U; + if (pre > 4095U) + { + err = -RT_EINVAL; + break; + } + GPT_SetClockDivider(clock_timer_dev, pre); } break; @@ -128,7 +166,16 @@ static rt_err_t imxrt_clock_timer_start(rt_clock_timer_t *timer, rt_uint32_t cnt RT_ASSERT(timer != RT_NULL); - clock_timer_dev->CR |= (mode != CLOCK_TIMER_MODE_PERIOD) ? GPT_CR_FRR_MASK : 0U; + if (mode == CLOCK_TIMER_MODE_PERIOD) + { + /* Restart mode: counter resets on output compare match, fixed interval */ + clock_timer_dev->CR &= ~GPT_CR_FRR_MASK; + } + else + { + /* Free-run mode: counter keeps running, one-shot match */ + clock_timer_dev->CR |= GPT_CR_FRR_MASK; + } GPT_SetOutputCompareValue(clock_timer_dev, kGPT_OutputCompare_Channel1, cnt); @@ -148,6 +195,7 @@ static void imxrt_clock_timer_stop(rt_clock_timer_t *timer) RT_ASSERT(timer != RT_NULL); + GPT_DisableInterrupts(clock_timer_dev, kGPT_OutputCompare1InterruptEnable); GPT_StopTimer(clock_timer_dev); } @@ -162,8 +210,8 @@ static const struct rt_clock_timer_ops imxrt_clock_timer_ops = static const struct rt_clock_timer_info imxrt_clock_timer_info = { - 25000000, /* the maximum count frequency can be set */ - 6103, /* the minimum count frequency can be set */ + IMXRT_GPT_MAXFREQ, /* the maximum count frequency can be set */ + IMXRT_GPT_MINFREQ, /* the minimum count frequency can be set */ 0xFFFFFFFF, CLOCK_TIMER_CNTMODE_UP, }; @@ -179,6 +227,7 @@ static rt_clock_timer_t GPT_timer2; int rt_hw_clock_timer_init(void) { int ret = RT_EOK; + int err = RT_EOK; #ifdef BSP_USING_CLOCK_TIMER1 GPT_timer1.info = &imxrt_clock_timer_info; @@ -188,6 +237,10 @@ int rt_hw_clock_timer_init(void) if (ret != RT_EOK) { LOG_E("gpt1 register failed\n"); + if (err == RT_EOK) + { + err = ret; + } } #endif @@ -199,10 +252,14 @@ int rt_hw_clock_timer_init(void) if (ret != RT_EOK) { LOG_E("gpt2 register failed\n"); + if (err == RT_EOK) + { + err = ret; + } } #endif - return ret; + return err; } #ifdef BSP_USING_CLOCK_TIMER1