add hwtimer device (#6230)
This commit is contained in:
parent
77067f8729
commit
38154c4656
|
@ -46,6 +46,9 @@ if GetDepend('BSP_USING_ON_CHIP_FLASH'):
|
|||
|
||||
if GetDepend(['RT_USING_WDT']):
|
||||
src += ['drv_wdt.c']
|
||||
|
||||
if GetDepend(['BSP_USING_TIM']):
|
||||
src += ['drv_hwtimer.c']
|
||||
|
||||
path = [cwd]
|
||||
path += [cwd + '/config']
|
||||
|
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-07-29 rtthread qiu first version
|
||||
*/
|
||||
#include "drv_common.h"
|
||||
#include "drv_hwtimer.h"
|
||||
|
||||
#include <board.h>
|
||||
#ifdef BSP_USING_TIM
|
||||
|
||||
//#define DRV_DEBUG
|
||||
#define LOG_TAG "drv.hwtimer"
|
||||
#include <drv_log.h>
|
||||
static void isr_timer(void *callback_arg, cyhal_timer_event_t event);
|
||||
|
||||
#ifdef RT_USING_HWTIMER
|
||||
enum
|
||||
{
|
||||
#ifdef BSP_USING_TIM1
|
||||
TIM1_INDEX,
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM2
|
||||
TIM2_INDEX,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct cyp_hwtimer
|
||||
{
|
||||
rt_hwtimer_t time_device;
|
||||
cyhal_timer_t tim_handle;
|
||||
IRQn_Type tim_irqn;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct cyp_hwtimer cyp_hwtimer_obj[] =
|
||||
{
|
||||
#ifdef BSP_USING_TIM1
|
||||
TIM1_CONFIG,
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM2
|
||||
TIM2_CONFIG,
|
||||
#endif
|
||||
};
|
||||
|
||||
static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
|
||||
{
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
cy_rslt_t result = RT_EOK;
|
||||
|
||||
cyhal_timer_t *tim = RT_NULL;
|
||||
|
||||
tim = (cyhal_timer_t *)timer->parent.user_data;
|
||||
|
||||
const cyhal_timer_cfg_t init_timer_cfg =
|
||||
{
|
||||
.compare_value = 0, /* Timer compare value, not used */
|
||||
.period = 9999, /* Defines the timer period */
|
||||
.direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */
|
||||
.is_compare = false, /* Don't use compare mode */
|
||||
.is_continuous = true, /* Run timer indefinitely */
|
||||
.value = 0 /* Initial value of counter */
|
||||
};
|
||||
|
||||
if (state)
|
||||
{
|
||||
/* Initialize the timer object. Does not use input pin ('pin' is NC) and
|
||||
* does not use a pre-configured clock source ('clk' is NULL). */
|
||||
result = cyhal_timer_init(tim, NC, NULL);
|
||||
|
||||
if (result != CY_RSLT_SUCCESS)
|
||||
{
|
||||
LOG_E("timer init error \r\n");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Configure timer period and operation mode such as count direction,
|
||||
duration */
|
||||
cyhal_timer_configure(tim, &init_timer_cfg);
|
||||
|
||||
/* Set the frequency of timer's clock source */
|
||||
cyhal_timer_set_frequency(tim, 10000);
|
||||
|
||||
cyhal_timer_start(tim);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cyhal_timer_free(tim);
|
||||
LOG_E("free time \r\n");
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
|
||||
{
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
RT_ASSERT(opmode != RT_NULL);
|
||||
|
||||
cy_rslt_t result = RT_EOK;
|
||||
|
||||
cyhal_timer_t *tim = RT_NULL;
|
||||
|
||||
tim = (cyhal_timer_t *)timer->parent.user_data;
|
||||
|
||||
const cyhal_timer_cfg_t init_timer_cfg =
|
||||
{
|
||||
.compare_value = 0, /* Timer compare value, not used */
|
||||
.period = t - 1, /* Defines the timer period */
|
||||
.direction = CYHAL_TIMER_DIR_UP, /* Timer counts up */
|
||||
.is_compare = false, /* Don't use compare mode */
|
||||
.is_continuous = true, /* Run timer indefinitely */
|
||||
.value = 0 /* Initial value of counter */
|
||||
};
|
||||
/* Configure timer period and operation mode such as count direction,
|
||||
duration */
|
||||
cyhal_timer_configure(tim, &init_timer_cfg);
|
||||
|
||||
if (opmode == HWTIMER_MODE_ONESHOT)
|
||||
{
|
||||
/* set timer to single mode */
|
||||
cyhal_timer_stop(tim);
|
||||
}
|
||||
else
|
||||
{
|
||||
cyhal_timer_reset(tim);
|
||||
}
|
||||
|
||||
result = cyhal_timer_start(tim);
|
||||
if (result != CY_RSLT_SUCCESS)
|
||||
{
|
||||
LOG_E("time start error\r\n");
|
||||
cyhal_timer_free(tim);
|
||||
}
|
||||
|
||||
/* Assign the ISR to execute on timer interrupt */
|
||||
cyhal_timer_register_callback(tim, isr_timer, NULL);
|
||||
/* Set the event on which timer interrupt occurs and enable it */
|
||||
cyhal_timer_enable_event(tim, CYHAL_TIMER_IRQ_TERMINAL_COUNT, 1, true);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void timer_stop(rt_hwtimer_t *timer)
|
||||
{
|
||||
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
cyhal_timer_t *tim = RT_NULL;
|
||||
|
||||
tim = (cyhal_timer_t *)timer->parent.user_data;
|
||||
|
||||
cyhal_timer_stop(tim);
|
||||
}
|
||||
|
||||
static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
|
||||
{
|
||||
cyhal_timer_t *tim = RT_NULL;
|
||||
|
||||
rt_uint32_t count;
|
||||
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
|
||||
tim = (cyhal_timer_t *)timer->parent.user_data;
|
||||
|
||||
count = cyhal_timer_read(tim);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
|
||||
{
|
||||
RT_ASSERT(timer != RT_NULL);
|
||||
RT_ASSERT(arg != RT_NULL);
|
||||
|
||||
cyhal_timer_t *tim = RT_NULL;
|
||||
|
||||
rt_err_t result = -RT_ERROR;
|
||||
|
||||
tim = (cyhal_timer_t *)timer->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case HWTIMER_CTRL_FREQ_SET:
|
||||
{
|
||||
rt_uint32_t freq;
|
||||
rt_uint16_t val;
|
||||
|
||||
freq = *((rt_uint32_t *)arg);
|
||||
|
||||
result = cyhal_timer_set_frequency(tim, freq);
|
||||
|
||||
if (result != CY_RSLT_SUCCESS)
|
||||
{
|
||||
LOG_E("cyhal_timer_set_frequency error\r\n");
|
||||
return RT_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
result = -RT_EINVAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct rt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;
|
||||
|
||||
static const struct rt_hwtimer_ops _ops =
|
||||
{
|
||||
.init = timer_init,
|
||||
.start = timer_start,
|
||||
.stop = timer_stop,
|
||||
.count_get = timer_counter_get,
|
||||
.control = timer_ctrl,
|
||||
};
|
||||
|
||||
#ifdef BSP_USING_TIM1
|
||||
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
(void)callback_arg;
|
||||
(void)event;
|
||||
|
||||
rt_device_hwtimer_isr(&cyp_hwtimer_obj[TIM1_INDEX].time_device);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
#ifdef BSP_USING_TIM2
|
||||
static void isr_timer(void *callback_arg, cyhal_timer_event_t event)
|
||||
{
|
||||
/* enter interrupt */
|
||||
rt_interrupt_enter();
|
||||
|
||||
(void)callback_arg;
|
||||
(void)event;
|
||||
|
||||
rt_device_hwtimer_isr(&cyp_hwtimer_obj[TIM2_INDEX].time_device);
|
||||
|
||||
/* leave interrupt */
|
||||
rt_interrupt_leave();
|
||||
}
|
||||
#endif
|
||||
|
||||
int cyp_hwtimer_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
int result = RT_EOK;
|
||||
|
||||
for (i = 0; i < sizeof(cyp_hwtimer_obj) / sizeof(cyp_hwtimer_obj[0]); i++)
|
||||
{
|
||||
cyp_hwtimer_obj[i].time_device.info = &_info;
|
||||
cyp_hwtimer_obj[i].time_device.ops = &_ops;
|
||||
if (rt_device_hwtimer_register(&cyp_hwtimer_obj[i].time_device, cyp_hwtimer_obj[i].name, &cyp_hwtimer_obj[i].tim_handle) != RT_EOK)
|
||||
{
|
||||
LOG_E("%s register failed", cyp_hwtimer_obj[i].name);
|
||||
result = -RT_ERROR;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
INIT_BOARD_EXPORT(cyp_hwtimer_init);
|
||||
|
||||
#endif /*RT_USING_HWTIMER*/
|
||||
#endif /*BSP_USING_TIM*/
|
||||
|
||||
/* this is a hwtimer test demo*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#define HWTIMER_DEV_NAME "time2" /* device name */
|
||||
|
||||
static rt_err_t timeout_cb(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 hwtimer_sample()
|
||||
{
|
||||
rt_err_t ret = RT_EOK;
|
||||
rt_hwtimerval_t timeout_s;
|
||||
rt_device_t hw_dev = RT_NULL;
|
||||
rt_hwtimer_mode_t mode;
|
||||
rt_uint32_t freq = 10000;
|
||||
|
||||
hw_dev = rt_device_find(HWTIMER_DEV_NAME);
|
||||
if (hw_dev == RT_NULL)
|
||||
{
|
||||
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_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_DEV_NAME);
|
||||
return ret;
|
||||
}
|
||||
|
||||
rt_device_set_rx_indicate(hw_dev, timeout_cb);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Example Set the timeout period of the timer */
|
||||
timeout_s.sec = 3; /* secend */
|
||||
timeout_s.usec = 0; /* microsecend */
|
||||
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;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
rt_thread_mdelay(1500);
|
||||
|
||||
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;
|
||||
}
|
||||
MSH_CMD_EXPORT(hwtimer_sample, hwtimer sample);
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-07-29 rtthread qiu first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_HWTIMER_H__
|
||||
#define __DRV_HWTIMER_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "cy_pdl.h"
|
||||
#include "cyhal.h"
|
||||
#include "cybsp.h"
|
||||
#include "cy_retarget_io.h"
|
||||
|
||||
#ifndef TIM_DEV_INFO_CONFIG
|
||||
#define TIM_DEV_INFO_CONFIG \
|
||||
{ \
|
||||
.maxfreq = 1000000, \
|
||||
.minfreq = 2000, \
|
||||
.maxcnt = 0xFFFF, \
|
||||
.cntmode = HWTIMER_CNTMODE_UP, \
|
||||
}
|
||||
#endif /* TIM_DEV_INFO_CONFIG */
|
||||
|
||||
#ifdef BSP_USING_TIM1
|
||||
#ifndef TIM1_CONFIG
|
||||
#define TIM1_CONFIG \
|
||||
{ \
|
||||
.tim_irqn = tcpwm_0_interrupts_0_IRQn, \
|
||||
.name = "time1", \
|
||||
}
|
||||
#endif /*TIM1_CONFIG*/
|
||||
#endif /* BSP_USING_TIM1 */
|
||||
|
||||
#ifdef BSP_USING_TIM2
|
||||
#ifndef TIM2_CONFIG
|
||||
#define TIM2_CONFIG \
|
||||
{ \
|
||||
.tim_irqn = tcpwm_1_interrupts_0_IRQn, \
|
||||
.name = "time2", \
|
||||
}
|
||||
#endif /*TIM2_CONFIG*/
|
||||
#endif /* BSP_USING_TIM2 */
|
||||
|
||||
#endif /* __DRV_HWTIMER_H__ */
|
|
@ -121,6 +121,9 @@ if GetDepend(['RT_USING_WDT']):
|
|||
src += ['mtb-pdl-cat1/drivers/source/cy_wdt.c']
|
||||
src += ['mtb-hal-cat1/source/cyhal_wdt.c']
|
||||
|
||||
if GetDepend(['RT_USING_HWTIMER']):
|
||||
src += ['mtb-hal-cat1/source/cyhal_timer.c']
|
||||
|
||||
path = [cwd + '/capsense',
|
||||
cwd + '/psoc6cm0p',
|
||||
cwd + '/retarget-io',
|
||||
|
|
|
@ -229,6 +229,34 @@ menu "On-chip Peripheral Drivers"
|
|||
bool "Enable Watchdog Timer"
|
||||
select RT_USING_WDT
|
||||
default n
|
||||
|
||||
menuconfig BSP_USING_DAC
|
||||
bool "Enable DAC"
|
||||
default n
|
||||
select RT_USING_DAC
|
||||
if BSP_USING_DAC
|
||||
config BSP_USING_DAC1
|
||||
bool "Enable DAC1"
|
||||
default n
|
||||
config BSP_USING_DAC2
|
||||
bool "Enable DAC2"
|
||||
default n
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_TIM
|
||||
bool "Enable timer"
|
||||
default n
|
||||
select RT_USING_HWTIMER
|
||||
if BSP_USING_TIM
|
||||
config BSP_USING_TIM1
|
||||
bool "Enable TIM1"
|
||||
default n
|
||||
config BSP_USING_TIM2
|
||||
bool "Enable TIM2"
|
||||
default n
|
||||
endif
|
||||
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Board extended module Drivers"
|
||||
|
|
Loading…
Reference in New Issue