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/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/libraries/drivers/drv_timer.c b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c index 860c483e92f..9e551a61e80 100644 --- a/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c +++ b/bsp/nxp/imx/imxrt/libraries/drivers/drv_timer.c @@ -29,15 +29,26 @@ /* 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)) #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; @@ -98,7 +136,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); @@ -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 @@ -198,11 +251,15 @@ int rt_hw_clock_timer_init(void) if (ret != RT_EOK) { - LOG_E("gpt1 register failed\n"); + LOG_E("gpt2 register failed\n"); + if (err == RT_EOK) + { + err = ret; + } } #endif - return ret; + return err; } #ifdef BSP_USING_CLOCK_TIMER1 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