diff options
| author | Bernard Xiong <[email protected]> | 2015-09-09 22:30:45 +0800 |
|---|---|---|
| committer | Bernard Xiong <[email protected]> | 2015-09-09 22:30:45 +0800 |
| commit | 342e8d688dfb355a64f6fe95424c30d370a7ccd5 (patch) | |
| tree | 929db08ebc07c51e24bfee0cf61619ae15f2a2c6 /bsp | |
| parent | f43a861e4c39aa4edad1df30fe9f5307dcd97372 (diff) | |
| parent | 984a7ba05128992d8b89fc689f5f5e4f135e2f1b (diff) | |
Merge pull request #546 from heyuanjie87/ForPullRequest
[DeviceDrivers] Add hardware timer framework
Diffstat (limited to 'bsp')
| -rw-r--r-- | bsp/lpc408x/drivers/drv_hwtimer.c | 153 | ||||
| -rw-r--r-- | bsp/lpc408x/drivers/drv_hwtimer.h | 8 | ||||
| -rw-r--r-- | bsp/stm32f40x/drivers/drv_hwtimer.c | 157 | ||||
| -rw-r--r-- | bsp/stm32f40x/drivers/drv_hwtimer.h | 8 | ||||
| -rw-r--r-- | bsp/stm32f40x/rtconfig.h | 3 |
5 files changed, 329 insertions, 0 deletions
diff --git a/bsp/lpc408x/drivers/drv_hwtimer.c b/bsp/lpc408x/drivers/drv_hwtimer.c new file mode 100644 index 0000000000..163c91fcd1 --- /dev/null +++ b/bsp/lpc408x/drivers/drv_hwtimer.c @@ -0,0 +1,153 @@ +/* + * File : drv_hwtimer.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2015-09-02 heyuanjie87 the first version + */ + +#include <rtthread.h> +#include <rtdevice.h> +#include "lpc_timer.h" +#include "lpc_clkpwr.h" +#include "drv_hwtimer.h" + +#ifdef RT_USING_HWTIMER + +static void NVIC_Configuration(void) +{ + NVIC_EnableIRQ(TIMER0_IRQn); +} + +static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state) +{ + LPC_TIM_TypeDef *tim; + TIM_TIMERCFG_Type cfg; + + tim = (LPC_TIM_TypeDef *)timer->parent.user_data; + + TIM_DeInit(tim); + + if (state == 1) + { + NVIC_Configuration(); + + cfg.PrescaleOption = TIM_PRESCALE_TICKVAL; + cfg.PrescaleValue = 0xFFFF; + TIM_Init(tim, TIM_TIMER_MODE, &cfg); + } +} + +static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) +{ + LPC_TIM_TypeDef *tim; + TIM_MATCHCFG_Type match; + + tim = (LPC_TIM_TypeDef *)timer->parent.user_data; + + match.MatchChannel = 0; + match.IntOnMatch = ENABLE; + match.ResetOnMatch = ENABLE; + match.StopOnMatch = (opmode == HWTIMER_MODE_ONESHOT)? ENABLE : DISABLE; + match.ExtMatchOutputType = 0; + match.MatchValue = t; + + TIM_ConfigMatch(tim, &match); + TIM_Cmd(tim, ENABLE); + + return RT_EOK; +} + +static void timer_stop(rt_hwtimer_t *timer) +{ + LPC_TIM_TypeDef *tim; + + tim = (LPC_TIM_TypeDef *)timer->parent.user_data; + + TIM_Cmd(tim, DISABLE); +} + +static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + LPC_TIM_TypeDef *tim; + rt_err_t err = RT_EOK; + + tim = (LPC_TIM_TypeDef *)timer->parent.user_data; + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + uint32_t clk; + uint32_t pre; + + clk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER); + pre = clk / *((uint32_t*)arg) - 1; + tim->PR = pre; + } + break; + default: + { + err = -RT_ENOSYS; + } + break; + } + + return err; +} + +static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) +{ + LPC_TIM_TypeDef *tim; + + tim = (LPC_TIM_TypeDef *)timer->parent.user_data; + + return tim->TC; +} + +static const struct rt_hwtimer_info _info = +{ + 1000000, /* the maximum count frequency can be set */ + 2000, /* the minimum count frequency can be set */ + 0xFFFFFF, /* the maximum counter value */ + HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */ +}; + +static const struct rt_hwtimer_ops _ops = +{ + timer_init, + timer_start, + timer_stop, + timer_counter_get, + timer_ctrl, +}; + +static rt_hwtimer_t _timer0; + +int lpc_hwtimer_init(void) +{ + _timer0.info = &_info; + _timer0.ops = &_ops; + + rt_device_hwtimer_register(&_timer0, "timer0", LPC_TIM0); + + return 0; +} + +void TIMER0_IRQHandler(void) +{ + if (TIM_GetIntStatus(LPC_TIM0, TIM_MR0_INT) != RESET) + { + TIM_ClearIntPending(LPC_TIM0, TIM_MR0_INT); + rt_device_hwtimer_isr(&_timer0); + } +} + +INIT_BOARD_EXPORT(lpc_hwtimer_init); +#endif diff --git a/bsp/lpc408x/drivers/drv_hwtimer.h b/bsp/lpc408x/drivers/drv_hwtimer.h new file mode 100644 index 0000000000..b45b27dc06 --- /dev/null +++ b/bsp/lpc408x/drivers/drv_hwtimer.h @@ -0,0 +1,8 @@ +#ifndef __DRV_HWTIMER_H__ +#define __DRV_HWTIMER_H__ + + +int stm32_hwtimer_init(void); + + +#endif diff --git a/bsp/stm32f40x/drivers/drv_hwtimer.c b/bsp/stm32f40x/drivers/drv_hwtimer.c new file mode 100644 index 0000000000..8802021e18 --- /dev/null +++ b/bsp/stm32f40x/drivers/drv_hwtimer.c @@ -0,0 +1,157 @@ +/* + * File : drv_hwtimer.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2015, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2015-09-02 heyuanjie87 the first version + */ + +#include <rtthread.h> +#include <rtdevice.h> +#include <board.h> +#include "drv_hwtimer.h" + +#ifdef RT_USING_HWTIMER + +static void NVIC_Configuration(void) +{ + NVIC_InitTypeDef NVIC_InitStructure; + + /* Enable the TIM5 global Interrupt */ + NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +} + +static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state) +{ + TIM_TypeDef *tim; + + tim = (TIM_TypeDef *)timer->parent.user_data; + + TIM_DeInit(tim); + + if (state == 1) + { + NVIC_Configuration(); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + TIM_CounterModeConfig(tim, TIM_CounterMode_Up); + } +} + +static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode) +{ + TIM_TypeDef *tim; + uint16_t m; + + tim = (TIM_TypeDef *)timer->parent.user_data; + TIM_SetAutoreload(tim, t); + m = (opmode == HWTIMER_MODE_ONESHOT)? TIM_OPMode_Single : TIM_OPMode_Repetitive; + TIM_SelectOnePulseMode(tim, m); + TIM_Cmd(tim, ENABLE); + + return RT_EOK; +} + +static void timer_stop(rt_hwtimer_t *timer) +{ + TIM_TypeDef *tim; + + tim = (TIM_TypeDef *)timer->parent.user_data; + TIM_Cmd(tim, DISABLE); +} + +static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg) +{ + TIM_TypeDef *tim; + rt_err_t err = RT_EOK; + + tim = (TIM_TypeDef *)timer->parent.user_data; + + switch (cmd) + { + case HWTIMER_CTRL_FREQ_SET: + { + RCC_ClocksTypeDef clk; + uint16_t val; + rt_uint32_t freq; + + RCC_GetClocksFreq(&clk); + + freq = *((rt_uint32_t*)arg); + clk.PCLK1_Frequency *= 2; + val = clk.PCLK1_Frequency/freq; + + TIM_ITConfig(tim, TIM_IT_Update, DISABLE); + TIM_PrescalerConfig(tim, val - 1, TIM_PSCReloadMode_Immediate); + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + TIM_ITConfig(tim, TIM_IT_Update, ENABLE); + } + break; + default: + { + err = -RT_ENOSYS; + } + break; + } + + return err; +} + +static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer) +{ + TIM_TypeDef *tim; + + tim = (TIM_TypeDef *)timer->parent.user_data; + + return TIM_GetCounter(tim); +} + +static const struct rt_hwtimer_info _info = +{ + 1000000, /* the maximum count frequency can be set */ + 2000, /* the minimum count frequency can be set */ + 0xFFFF, /* the maximum counter value */ + HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */ +}; + +static const struct rt_hwtimer_ops _ops = +{ + timer_init, + timer_start, + timer_stop, + timer_counter_get, + timer_ctrl, +}; + +static rt_hwtimer_t _timer0; + +int stm32_hwtimer_init(void) +{ + _timer0.info = &_info; + _timer0.ops = &_ops; + + rt_device_hwtimer_register(&_timer0, "timer0", TIM2); + + return 0; +} + +void TIM2_IRQHandler(void) +{ + if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) + { + TIM_ClearITPendingBit(TIM2, TIM_IT_Update); + rt_device_hwtimer_isr(&_timer0); + } +} + +INIT_BOARD_EXPORT(stm32_hwtimer_init); +#endif diff --git a/bsp/stm32f40x/drivers/drv_hwtimer.h b/bsp/stm32f40x/drivers/drv_hwtimer.h new file mode 100644 index 0000000000..b45b27dc06 --- /dev/null +++ b/bsp/stm32f40x/drivers/drv_hwtimer.h @@ -0,0 +1,8 @@ +#ifndef __DRV_HWTIMER_H__ +#define __DRV_HWTIMER_H__ + + +int stm32_hwtimer_init(void); + + +#endif diff --git a/bsp/stm32f40x/rtconfig.h b/bsp/stm32f40x/rtconfig.h index 88dfd0b616..9cca3f8424 100644 --- a/bsp/stm32f40x/rtconfig.h +++ b/bsp/stm32f40x/rtconfig.h @@ -69,6 +69,9 @@ /* Using GPIO pin framework */ #define RT_USING_PIN +/* Using Hardware Timer framework */ +//#define RT_USING_HWTIMER + /* SECTION: Console options */ #define RT_USING_CONSOLE /* the buffer size of console*/ |
