From 4ed6032e076d9dd87adb1d191a429470ba251a1b Mon Sep 17 00:00:00 2001 From: diskwu <27161916@qq.com> Date: Sat, 12 Mar 2022 21:37:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A1=AC=E4=BB=B6=E5=AE=9A?= =?UTF-8?q?=E6=97=B6=E5=99=A8=E9=A9=B1=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/imx6ull-artpi-smart/drivers/Kconfig | 15 + bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.c | 335 +++++++++++ bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.h | 20 + .../sdk/devices/MCIMX6Y2/drivers/fsl_gpt.c | 114 ++++ .../sdk/devices/MCIMX6Y2/drivers/fsl_gpt.h | 529 ++++++++++++++++++ .../sdk/devices/MCIMX6Y2/system_MCIMX6Y2.c | 10 + 6 files changed, 1023 insertions(+) create mode 100644 bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.c create mode 100644 bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.h create mode 100644 bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.c create mode 100644 bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.h diff --git a/bsp/imx6ull-artpi-smart/drivers/Kconfig b/bsp/imx6ull-artpi-smart/drivers/Kconfig index 54a8bfa955..72435c2f7b 100644 --- a/bsp/imx6ull-artpi-smart/drivers/Kconfig +++ b/bsp/imx6ull-artpi-smart/drivers/Kconfig @@ -191,6 +191,21 @@ menu "Select ADC Driver" endif endmenu +menu "Select hwTimer Driver" + config BSP_USING_HWTIMER + bool "Enable hwTimer" + select RT_USING_HWTIMER + default n + if BSP_USING_HWTIMER + config BSP_USING_HWTIMER1 + bool "Enable HWTIMER GPT1" + default n + config BSP_USING_HWTIMER2 + bool "Enable HWTIMER GPT2" + default n + endif +endmenu + menu "Select WDT Driver" if RT_USING_WDT config RT_USING_WDT1 diff --git a/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.c b/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.c new file mode 100644 index 0000000000..87019044ee --- /dev/null +++ b/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * +* Change Logs: +* Date Author Notes +* 2018-04-17 WangBing the first version. +* 2019-04-22 tyustli add imxrt series support +* +*/ +#include + +#ifdef BSP_USING_HWTIMER + +#define LOG_TAG "drv.hwtimer" +#include + +#include +#include "drv_hwtimer.h" +#include +#include +#include "fsl_gpt.h" + +/* Select IPG Clock as PERCLK_CLK clock source */ +#define EXAMPLE_GPT_CLOCK_SOURCE_SELECT (0U) +/* Clock divider for PERCLK_CLK clock source */ +#define EXAMPLE_GPT_CLOCK_DIVIDER_SELECT (5U) +/* Get source clock for GPT driver (GPT prescaler = 6) */ +#define EXAMPLE_GPT_CLK_FREQ (CLOCK_GetFreq(kCLOCK_IpgClk) / (EXAMPLE_GPT_CLOCK_DIVIDER_SELECT + 1U)) + +#ifdef BSP_USING_HWTIMER1 +void GPT1_IRQHandler(void); +static rt_hwtimer_t GPT_timer1; +GPT_Type *gpt1_base; +#endif + +#ifdef BSP_USING_HWTIMER2 +void GPT2_IRQHandler(void); +static rt_hwtimer_t GPT_timer2; +GPT_Type *gpt2_base; +#endif + +static void NVIC_Configuration(void) +{ +#ifdef BSP_USING_HWTIMER1 + rt_hw_interrupt_install(GPT1_IRQn, (rt_isr_handler_t)GPT1_IRQHandler, NULL,"GPT1"); + rt_hw_interrupt_umask(GPT1_IRQn); +#endif + +#ifdef BSP_USING_HWTIMER2 + rt_hw_interrupt_install(GPT2_IRQn, (rt_isr_handler_t)GPT2_IRQHandler, NULL,"GPT2"); + rt_hw_interrupt_umask(GPT2_IRQn); +#endif +} + +static rt_err_t imx6ull_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 = EXAMPLE_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 imx6ull_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 imx6ull_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) + { + /*Clock setting for GPT*/ + CLOCK_SetMux(kCLOCK_PerclkMux, EXAMPLE_GPT_CLOCK_SOURCE_SELECT); + CLOCK_SetDiv(kCLOCK_PerclkDiv, EXAMPLE_GPT_CLOCK_DIVIDER_SELECT); + + /* Initialize GPT module by default config */ + GPT_GetDefaultConfig(&gptConfig); + } +} + +static rt_err_t imx6ull_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 imx6ull_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); +} + +static const struct rt_hwtimer_ops imx6ull_hwtimer_ops = +{ + .init = imx6ull_hwtimer_init, + .start = imx6ull_hwtimer_start, + .stop = imx6ull_hwtimer_stop, + .count_get = imx6ull_hwtimer_count_get, + .control = imx6ull_hwtimer_control, +}; + +static const struct rt_hwtimer_info imx6ull_hwtimer_info = +{ + 25000000, /* the maximum count frequency can be set */ + 6103, /* the minimum count frequency can be set */ + 0xFFFFFFFF, + HWTIMER_CNTMODE_UP, +}; + +int rt_hw_hwtimer_init(void) +{ + int ret = RT_EOK; + +#ifdef BSP_USING_HWTIMER1 + GPT_timer1.info = &imx6ull_hwtimer_info; + GPT_timer1.ops = &imx6ull_hwtimer_ops; + gpt1_base = (GPT_Type *)rt_ioremap((void*)GPT1, 0x1000); + + ret = rt_device_hwtimer_register(&GPT_timer1, "gpt1", gpt1_base); + + if (ret != RT_EOK) + { + LOG_E("gpt1 register failed\n"); + } +#endif + +#ifdef BSP_USING_HWTIMER2 + GPT_timer2.info = &imx6ull_hwtimer_info; + GPT_timer2.ops = &imx6ull_hwtimer_ops; + gpt2_base = (GPT_Type *)rt_ioremap((void*)GPT2, 0x1000); + + ret = rt_device_hwtimer_register(&GPT_timer2, "gpt2", gpt2_base); + + if (ret != RT_EOK) + { + LOG_E("gpt2 register failed\n"); + } +#endif + + return ret; +} + +#ifdef BSP_USING_HWTIMER1 +void GPT1_IRQHandler(void) +{ + if (GPT_GetStatusFlags(gpt1_base, kGPT_OutputCompare1Flag) != 0) + { + GPT_ClearStatusFlags(gpt1_base, kGPT_OutputCompare1Flag); + rt_device_hwtimer_isr(&GPT_timer1); + } + + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U) + __DSB(); +#endif +} + +/* 定时器超时回调函数 */ +static rt_err_t timeout_cb1(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; +} +#endif /*BSP_USING_HWTIMER1*/ + +#ifdef BSP_USING_HWTIMER2 +void GPT2_IRQHandler(void) +{ + if (GPT_GetStatusFlags(gpt2_base, kGPT_OutputCompare1Flag) != 0) + { + GPT_ClearStatusFlags(gpt2_base, kGPT_OutputCompare1Flag); + rt_device_hwtimer_isr(&GPT_timer2); + } + + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F, Cortex-M7, Cortex-M7F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U || __CORTEX_M == 7U) + __DSB(); +#endif +} +/* 定时器超时回调函数 */ +static rt_err_t timeout_cb2(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; +} + +#endif /*BSP_USING_HWTIMER2*/ + +INIT_DEVICE_EXPORT(rt_hw_hwtimer_init); + +int set_hwtimer_default(void) +{ + int result = 0; + rt_hwtimer_mode_t mode; /* 定时器模式 */ + rt_hwtimerval_t timeout_s; /* 定时器超时值 */ + +#ifdef BSP_USING_HWTIMER1 + rt_device_t device; + device = rt_device_find("gpt1"); + if (!device) + { + result = -RT_EIO; + goto _exit; + } + result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR); + if (result != RT_EOK) + { + rt_kprintf("open %s device failed!\n", "gpt1"); + return result; + } + + /* 设置超时回调函数 */ + rt_device_set_rx_indicate(device, timeout_cb1); + + /* 设置模式为周期性定时器 */ + mode = HWTIMER_MODE_PERIOD; + result = rt_device_control(device, HWTIMER_CTRL_MODE_SET, &mode); + if (result != RT_EOK) + { + rt_kprintf("set mode failed! ret is :%d\n", result); + return result; + } + + /* 设置定时器超时值为5s并启动定时器 */ + timeout_s.sec = 0; /* 秒 */ + timeout_s.usec = 500*1000; /* 微秒 */ + + if (rt_device_write(device, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)) + { + rt_kprintf("set timeout value failed\n"); + return RT_ERROR; + } + +#endif +#ifdef BSP_USING_HWTIMER2 + rt_device_t device2; + device2 = rt_device_find("gpt2"); + if (!device2) + { + result = -RT_EIO; + goto _exit; + } + result = rt_device_open(device2, RT_DEVICE_OFLAG_RDWR); + if (result != RT_EOK) + { + rt_kprintf("open %s device failed!\n", "gpt2"); + return result; + } + + /* 设置超时回调函数 */ + rt_device_set_rx_indicate(device2, timeout_cb2); + + /* 设置模式为周期性定时器 */ + mode = HWTIMER_MODE_PERIOD; + result = rt_device_control(device2, HWTIMER_CTRL_MODE_SET, &mode); + if (result != RT_EOK) + { + rt_kprintf("set mode failed! ret is :%d\n", result); + return result; + } + + /* 设置定时器超时值为5s并启动定时器 */ + timeout_s.sec = 1; /* 秒 */ + timeout_s.usec = 0; /* 微秒 */ + + if (rt_device_write(device2, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s)) + { + rt_kprintf("set timeout value failed\n"); + return RT_ERROR; + } +#endif + +_exit: + return result; + +} +INIT_APP_EXPORT(set_hwtimer_default); + +#endif /* BSP_USING_HWTIMER */ diff --git a/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.h b/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.h new file mode 100644 index 0000000000..be0aca27f0 --- /dev/null +++ b/bsp/imx6ull-artpi-smart/drivers/drv_hwtimer.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * +* Change Logs: +* Date Author Notes +* 2018-04-17 WangBing the first version. +*/ + +#ifndef DRV_HWTIMER_H__ +#define DRV_HWTIMER_H__ + +#include +#include + +int rt_hw_wdt_init(void); + +#endif + diff --git a/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.c b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.c new file mode 100644 index 0000000000..2857a80276 --- /dev/null +++ b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpt.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to GPT bases for each instance. */ +static GPT_Type *const s_gptBases[] = GPT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to GPT clocks for each instance. */ +static const clock_ip_name_t s_gptClocks[] = GPT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t GPT_GetInstance(GPT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0U; instance < ARRAY_SIZE(s_gptBases); instance++) + { + if (s_gptBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_gptBases)); + + return instance; +} + +void GPT_Init(GPT_Type *base, const gpt_config_t *initConfig) +{ + assert(initConfig); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the GPT clock*/ + CLOCK_EnableClock(s_gptClocks[GPT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + base->CR = 0U; + + GPT_SoftwareReset(base); + + base->CR = + (initConfig->enableFreeRun ? GPT_CR_FRR_MASK : 0U) | (initConfig->enableRunInWait ? GPT_CR_WAITEN_MASK : 0U) | + (initConfig->enableRunInStop ? GPT_CR_STOPEN_MASK : 0U) | + (initConfig->enableRunInDoze ? GPT_CR_DOZEEN_MASK : 0U) | + (initConfig->enableRunInDbg ? GPT_CR_DBGEN_MASK : 0U) | (initConfig->enableMode ? GPT_CR_ENMOD_MASK : 0U); + + GPT_SetClockSource(base, initConfig->clockSource); + GPT_SetClockDivider(base, initConfig->divider); +} + +void GPT_Deinit(GPT_Type *base) +{ + /* Disable GPT timers */ + base->CR = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the GPT clock*/ + CLOCK_DisableClock(s_gptClocks[GPT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void GPT_GetDefaultConfig(gpt_config_t *config) +{ + assert(config); + + config->clockSource = kGPT_ClockSource_Periph; + config->divider = 1U; + config->enableRunInStop = true; + config->enableRunInWait = true; + config->enableRunInDoze = false; + config->enableRunInDbg = false; + config->enableFreeRun = false; + config->enableMode = true; +} diff --git a/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.h b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.h new file mode 100644 index 0000000000..9ad873ad7a --- /dev/null +++ b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/drivers/fsl_gpt.h @@ -0,0 +1,529 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_GPT_H_ +#define _FSL_GPT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup gpt + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_GPT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ + /*@}*/ + +/*! + * @brief List of clock sources + * @note Actual number of clock sources is SoC dependent + */ +typedef enum _gpt_clock_source +{ + kGPT_ClockSource_Off = 0U, /*!< GPT Clock Source Off.*/ + kGPT_ClockSource_Periph = 1U, /*!< GPT Clock Source from Peripheral Clock.*/ + kGPT_ClockSource_HighFreq = 2U, /*!< GPT Clock Source from High Frequency Reference Clock.*/ + kGPT_ClockSource_Ext = 3U, /*!< GPT Clock Source from external pin.*/ + kGPT_ClockSource_LowFreq = 4U, /*!< GPT Clock Source from Low Frequency Reference Clock.*/ + kGPT_ClockSource_Osc = 5U, /*!< GPT Clock Source from Crystal oscillator.*/ +} gpt_clock_source_t; + +/*! @brief List of input capture channel number. */ +typedef enum _gpt_input_capture_channel +{ + kGPT_InputCapture_Channel1 = 0U, /*!< GPT Input Capture Channel1.*/ + kGPT_InputCapture_Channel2 = 1U, /*!< GPT Input Capture Channel2.*/ +} gpt_input_capture_channel_t; + +/*! @brief List of input capture operation mode. */ +typedef enum _gpt_input_operation_mode +{ + kGPT_InputOperation_Disabled = 0U, /*!< Don't capture.*/ + kGPT_InputOperation_RiseEdge = 1U, /*!< Capture on rising edge of input pin.*/ + kGPT_InputOperation_FallEdge = 2U, /*!< Capture on falling edge of input pin.*/ + kGPT_InputOperation_BothEdge = 3U, /*!< Capture on both edges of input pin.*/ +} gpt_input_operation_mode_t; + +/*! @brief List of output compare channel number. */ +typedef enum _gpt_output_compare_channel +{ + kGPT_OutputCompare_Channel1 = 0U, /*!< Output Compare Channel1.*/ + kGPT_OutputCompare_Channel2 = 1U, /*!< Output Compare Channel2.*/ + kGPT_OutputCompare_Channel3 = 2U, /*!< Output Compare Channel3.*/ +} gpt_output_compare_channel_t; + +/*! @brief List of output compare operation mode. */ +typedef enum _gpt_output_operation_mode +{ + kGPT_OutputOperation_Disconnected = 0U, /*!< Don't change output pin.*/ + kGPT_OutputOperation_Toggle = 1U, /*!< Toggle output pin.*/ + kGPT_OutputOperation_Clear = 2U, /*!< Set output pin low.*/ + kGPT_OutputOperation_Set = 3U, /*!< Set output pin high.*/ + kGPT_OutputOperation_Activelow = 4U, /*!< Generate a active low pulse on output pin.*/ +} gpt_output_operation_mode_t; + +/*! @brief List of GPT interrupts */ +typedef enum _gpt_interrupt_enable +{ + kGPT_OutputCompare1InterruptEnable = GPT_IR_OF1IE_MASK, /*!< Output Compare Channel1 interrupt enable*/ + kGPT_OutputCompare2InterruptEnable = GPT_IR_OF2IE_MASK, /*!< Output Compare Channel2 interrupt enable*/ + kGPT_OutputCompare3InterruptEnable = GPT_IR_OF3IE_MASK, /*!< Output Compare Channel3 interrupt enable*/ + kGPT_InputCapture1InterruptEnable = GPT_IR_IF1IE_MASK, /*!< Input Capture Channel1 interrupt enable*/ + kGPT_InputCapture2InterruptEnable = GPT_IR_IF2IE_MASK, /*!< Input Capture Channel1 interrupt enable*/ + kGPT_RollOverFlagInterruptEnable = GPT_IR_ROVIE_MASK, /*!< Counter rolled over interrupt enable*/ +} gpt_interrupt_enable_t; + +/*! @brief Status flag. */ +typedef enum _gpt_status_flag +{ + kGPT_OutputCompare1Flag = GPT_SR_OF1_MASK, /*!< Output compare channel 1 event.*/ + kGPT_OutputCompare2Flag = GPT_SR_OF2_MASK, /*!< Output compare channel 2 event.*/ + kGPT_OutputCompare3Flag = GPT_SR_OF3_MASK, /*!< Output compare channel 3 event.*/ + kGPT_InputCapture1Flag = GPT_SR_IF1_MASK, /*!< Input Capture channel 1 event.*/ + kGPT_InputCapture2Flag = GPT_SR_IF2_MASK, /*!< Input Capture channel 2 event.*/ + kGPT_RollOverFlag = GPT_SR_ROV_MASK, /*!< Counter reaches maximum value and rolled over to 0 event.*/ +} gpt_status_flag_t; + +/*! @brief Structure to configure the running mode. */ +typedef struct _gpt_init_config +{ + gpt_clock_source_t clockSource; /*!< clock source for GPT module. */ + uint32_t divider; /*!< clock divider (prescaler+1) from clock source to counter. */ + bool enableFreeRun; /*!< true: FreeRun mode, false: Restart mode. */ + bool enableRunInWait; /*!< GPT enabled in wait mode. */ + bool enableRunInStop; /*!< GPT enabled in stop mode. */ + bool enableRunInDoze; /*!< GPT enabled in doze mode. */ + bool enableRunInDbg; /*!< GPT enabled in debug mode. */ + bool enableMode; /*!< true: counter reset to 0 when enabled; + false: counter retain its value when enabled. */ +} gpt_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initialize GPT to reset state and initialize running mode. + * + * @param base GPT peripheral base address. + * @param initConfig GPT mode setting configuration. + */ +void GPT_Init(GPT_Type *base, const gpt_config_t *initConfig); + +/*! + * @brief Disables the module and gates the GPT clock. + * + * @param base GPT peripheral base address. + */ +void GPT_Deinit(GPT_Type *base); + +/*! + * @brief Fills in the GPT configuration structure with default settings. + * + * The default values are: + * @code + * config->clockSource = kGPT_ClockSource_Periph; + * config->divider = 1U; + * config->enableRunInStop = true; + * config->enableRunInWait = true; + * config->enableRunInDoze = false; + * config->enableRunInDbg = false; + * config->enableFreeRun = true; + * config->enableMode = true; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void GPT_GetDefaultConfig(gpt_config_t *config); + +/*! + * @name Software Reset + * @{ + */ + +/*! + * @brief Software reset of GPT module. + * + * @param base GPT peripheral base address. + */ +static inline void GPT_SoftwareReset(GPT_Type *base) +{ + base->CR |= GPT_CR_SWR_MASK; + /* Wait reset finished. */ + while ((base->CR & GPT_CR_SWR_MASK) == GPT_CR_SWR_MASK) + { + } +} + +/*! + * @name Clock source and frequency control + * @{ + */ + +/*! + * @brief Set clock source of GPT. + * + * @param base GPT peripheral base address. + * @param source Clock source (see @ref gpt_clock_source_t typedef enumeration). + */ +static inline void GPT_SetClockSource(GPT_Type *base, gpt_clock_source_t source) +{ + if (source == kGPT_ClockSource_Osc) + { + base->CR = (base->CR & ~GPT_CR_CLKSRC_MASK) | GPT_CR_EN_24M_MASK | GPT_CR_CLKSRC(source); + } + else + { + base->CR = (base->CR & ~(GPT_CR_CLKSRC_MASK | GPT_CR_EN_24M_MASK)) | GPT_CR_CLKSRC(source); + } +} + +/*! + * @brief Get clock source of GPT. + * + * @param base GPT peripheral base address. + * @return clock source (see @ref gpt_clock_source_t typedef enumeration). + */ +static inline gpt_clock_source_t GPT_GetClockSource(GPT_Type *base) +{ + return (gpt_clock_source_t)((base->CR & GPT_CR_CLKSRC_MASK) >> GPT_CR_CLKSRC_SHIFT); +} + +/*! + * @brief Set pre scaler of GPT. + * + * @param base GPT peripheral base address. + * @param divider Divider of GPT (1-4096). + */ +static inline void GPT_SetClockDivider(GPT_Type *base, uint32_t divider) +{ + assert(divider - 1 <= GPT_PR_PRESCALER_MASK); + + base->PR = (base->PR & ~GPT_PR_PRESCALER_MASK) | GPT_PR_PRESCALER(divider - 1); +} + +/*! + * @brief Get clock divider in GPT module. + * + * @param base GPT peripheral base address. + * @return clock divider in GPT module (1-4096). + */ +static inline uint32_t GPT_GetClockDivider(GPT_Type *base) +{ + return ((base->PR & GPT_PR_PRESCALER_MASK) >> GPT_PR_PRESCALER_SHIFT) + 1; +} + +/*! + * @brief OSC 24M pre-scaler before selected by clock source. + * + * @param base GPT peripheral base address. + * @param divider OSC Divider(1-16). + */ +static inline void GPT_SetOscClockDivider(GPT_Type *base, uint32_t divider) +{ + assert(divider - 1 <= (GPT_PR_PRESCALER24M_MASK >> GPT_PR_PRESCALER24M_SHIFT)); + + base->PR = (base->PR & ~GPT_PR_PRESCALER24M_MASK) | GPT_PR_PRESCALER24M(divider - 1); +} + +/*! + * @brief Get OSC 24M clock divider in GPT module. + * + * @param base GPT peripheral base address. + * @return OSC clock divider in GPT module (1-16). + */ +static inline uint32_t GPT_GetOscClockDivider(GPT_Type *base) +{ + return ((base->PR & GPT_PR_PRESCALER24M_MASK) >> GPT_PR_PRESCALER24M_SHIFT) + 1; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ +/*! + * @brief Start GPT timer. + * + * @param base GPT peripheral base address. + */ +static inline void GPT_StartTimer(GPT_Type *base) +{ + base->CR |= GPT_CR_EN_MASK; +} + +/*! + * @brief Stop GPT timer. + * + * @param base GPT peripheral base address. + */ +static inline void GPT_StopTimer(GPT_Type *base) +{ + base->CR &= ~GPT_CR_EN_MASK; +} + +/*! + * @name Read the timer period + * @{ + */ + +/*! + * @brief Reads the current GPT counting value. + * + * @param base GPT peripheral base address. + * @return Current GPT counter value. + */ +static inline uint32_t GPT_GetCurrentTimerCount(GPT_Type *base) +{ + return base->CNT; +} + +/*@}*/ + +/*! + * @name GPT Input/Output Signal Control + * @{ + */ + +/*! + * @brief Set GPT operation mode of input capture channel. + * + * @param base GPT peripheral base address. + * @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration). + * @param mode GPT input capture operation mode (see @ref gpt_input_operation_mode_t typedef enumeration). + */ +static inline void GPT_SetInputOperationMode(GPT_Type *base, + gpt_input_capture_channel_t channel, + gpt_input_operation_mode_t mode) +{ + assert(channel <= kGPT_InputCapture_Channel2); + + base->CR = (base->CR & ~(GPT_CR_IM1_MASK << (channel * 2))) | (GPT_CR_IM1(mode) << (channel * 2)); +} + +/*! + * @brief Get GPT operation mode of input capture channel. + * + * @param base GPT peripheral base address. + * @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration). + * @return GPT input capture operation mode (see @ref gpt_input_operation_mode_t typedef enumeration). + */ +static inline gpt_input_operation_mode_t GPT_GetInputOperationMode(GPT_Type *base, gpt_input_capture_channel_t channel) +{ + assert(channel <= kGPT_InputCapture_Channel2); + + return (gpt_input_operation_mode_t)((base->CR >> (GPT_CR_IM1_SHIFT + channel * 2)) & + (GPT_CR_IM1_MASK >> GPT_CR_IM1_SHIFT)); +} + +/*! + * @brief Get GPT input capture value of certain channel. + * + * @param base GPT peripheral base address. + * @param channel GPT capture channel (see @ref gpt_input_capture_channel_t typedef enumeration). + * @return GPT input capture value. + */ +static inline uint32_t GPT_GetInputCaptureValue(GPT_Type *base, gpt_input_capture_channel_t channel) +{ + assert(channel <= kGPT_InputCapture_Channel2); + + return *(&base->ICR[0] + channel); +} + +/*! + * @brief Set GPT operation mode of output compare channel. + * + * @param base GPT peripheral base address. + * @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration). + * @param mode GPT output operation mode (see @ref gpt_output_operation_mode_t typedef enumeration). + */ +static inline void GPT_SetOutputOperationMode(GPT_Type *base, + gpt_output_compare_channel_t channel, + gpt_output_operation_mode_t mode) +{ + assert(channel <= kGPT_OutputCompare_Channel3); + + base->CR = (base->CR & ~(GPT_CR_OM1_MASK << (channel * 3))) | (GPT_CR_OM1(mode) << (channel * 3)); +} + +/*! + * @brief Get GPT operation mode of output compare channel. + * + * @param base GPT peripheral base address. + * @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration). + * @return GPT output operation mode (see @ref gpt_output_operation_mode_t typedef enumeration). + */ +static inline gpt_output_operation_mode_t GPT_GetOutputOperationMode(GPT_Type *base, + gpt_output_compare_channel_t channel) +{ + assert(channel <= kGPT_OutputCompare_Channel3); + + return (gpt_output_operation_mode_t)((base->CR >> (GPT_CR_OM1_SHIFT + channel * 3)) & + (GPT_CR_OM1_MASK >> GPT_CR_OM1_SHIFT)); +} + +/*! + * @brief Set GPT output compare value of output compare channel. + * + * @param base GPT peripheral base address. + * @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration). + * @param value GPT output compare value. + */ +static inline void GPT_SetOutputCompareValue(GPT_Type *base, gpt_output_compare_channel_t channel, uint32_t value) +{ + assert(channel <= kGPT_OutputCompare_Channel3); + + *(&base->OCR[0] + channel) = value; +} + +/*! + * @brief Get GPT output compare value of output compare channel. + * + * @param base GPT peripheral base address. + * @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration). + * @return GPT output compare value. + */ +static inline uint32_t GPT_GetOutputCompareValue(GPT_Type *base, gpt_output_compare_channel_t channel) +{ + assert(channel <= kGPT_OutputCompare_Channel3); + + return *(&base->OCR[0] + channel); +} + +/*! + * @brief Force GPT output action on output compare channel, ignoring comparator. + * + * @param base GPT peripheral base address. + * @param channel GPT output compare channel (see @ref gpt_output_compare_channel_t typedef enumeration). + */ +static inline void GPT_ForceOutput(GPT_Type *base, gpt_output_compare_channel_t channel) +{ + assert(channel <= kGPT_OutputCompare_Channel3); + + base->CR |= (GPT_CR_FO1_MASK << channel); +} + +/*@}*/ + +/*! + * @name GPT Interrupt and Status Interface + * @{ + */ + +/*! + * @brief Enables the selected GPT interrupts. + * + * @param base GPT peripheral base address. + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::gpt_interrupt_enable_t + */ +static inline void GPT_EnableInterrupts(GPT_Type *base, uint32_t mask) +{ + base->IR |= mask; +} + +/*! + * @brief Disables the selected GPT interrupts. + * + * @param base GPT peripheral base address + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::gpt_interrupt_enable_t + */ +static inline void GPT_DisableInterrupts(GPT_Type *base, uint32_t mask) +{ + base->IR &= ~mask; +} + +/*! + * @brief Gets the enabled GPT interrupts. + * + * @param base GPT peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::gpt_interrupt_enable_t + */ +static inline uint32_t GPT_GetEnabledInterrupts(GPT_Type *base) +{ + return (base->IR & (GPT_IR_OF1IE_MASK | GPT_IR_OF2IE_MASK | GPT_IR_OF3IE_MASK | GPT_IR_IF1IE_MASK | + GPT_IR_IF2IE_MASK | GPT_IR_ROVIE_MASK)); +} + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Get GPT status flags. + * + * @param base GPT peripheral base address. + * @param flags GPT status flag mask (see @ref gpt_status_flag_t for bit definition). + * @return GPT status, each bit represents one status flag. + */ +static inline uint32_t GPT_GetStatusFlags(GPT_Type *base, gpt_status_flag_t flags) +{ + return base->SR & flags; +} + +/*! + * @brief Clears the GPT status flags. + * + * @param base GPT peripheral base address. + * @param flags GPT status flag mask (see @ref gpt_status_flag_t for bit definition). + */ +static inline void GPT_ClearStatusFlags(GPT_Type *base, gpt_status_flag_t flags) +{ + base->SR = flags; +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_GPT_H_ */ diff --git a/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/system_MCIMX6Y2.c b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/system_MCIMX6Y2.c index d6717da2ac..96ac12f45a 100644 --- a/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/system_MCIMX6Y2.c +++ b/bsp/imx6ull-artpi-smart/libraries/sdk/devices/MCIMX6Y2/system_MCIMX6Y2.c @@ -103,6 +103,8 @@ extern void UART8_DriverIRQHandler (uint32_t giccIar, void *userParam); extern void USDHC1_DriverIRQHandler (uint32_t giccIar, void *userParam); extern void USDHC2_DriverIRQHandler (uint32_t giccIar, void *userParam); extern void SDMA_DriverIRQHandler (uint32_t giccIar, void *userParam); +extern void GPT1_IRQHandler (uint32_t giccIar, void *userParam); +extern void GPT2_IRQHandler (uint32_t giccIar, void *userParam); #if defined(__IAR_SYSTEMS_ICC__) #pragma weak CAN1_DriverIRQHandler=defaultIrqHandler @@ -134,6 +136,9 @@ extern void SDMA_DriverIRQHandler (uint32_t giccIar, void *userParam); #pragma weak USDHC1_DriverIRQHandler=defaultIrqHandler #pragma weak USDHC2_DriverIRQHandler=defaultIrqHandler #pragma weak SDMA_DriverIRQHandler=defaultIrqHandler +#pragma weak GPT1_IRQHandler=defaultIrqHandler +#pragma weak GPT2_IRQHandler=defaultIrqHandler + #elif defined(__GNUC__) void CAN1_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); void CAN2_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); @@ -164,6 +169,8 @@ void UART8_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); void USDHC1_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); void USDHC2_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); void SDMA_DriverIRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); +void GPT1_IRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); +void GPT2_IRQHandler() __attribute__((weak, alias("defaultIrqHandler"))); #else #error Not supported compiler type #endif @@ -331,6 +338,9 @@ void SystemInitIrqTable (void) { SystemInstallIrqHandler(USDHC2_IRQn, USDHC2_DriverIRQHandler, NULL); /* SDMA transaction driver handler */ SystemInstallIrqHandler(SDMA_IRQn, SDMA_DriverIRQHandler, NULL); + + SystemInstallIrqHandler(GPT1_IRQn, GPT1_IRQHandler, NULL); + SystemInstallIrqHandler(GPT2_IRQn, GPT2_IRQHandler, NULL); } /* ---------------------------------------------------------------------------- -- Gitee