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..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 @@ -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_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/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/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..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