123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- /**************************************************************************//**
- *
- * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2020-2-7 YCHuang12 First version
- *
- ******************************************************************************/
- #include <rtconfig.h>
- #if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))
- #include <rtdevice.h>
- #include "NuMicro.h"
- /* Private define ---------------------------------------------------------------*/
- #define NU_TIMER_DEVICE(timer) (nu_timer_t *)(timer)
- /* Private typedef --------------------------------------------------------------*/
- typedef struct nu_timer
- {
- rt_hwtimer_t parent;
- TIMER_T *timer_periph;
- IRQn_Type IRQn;
- } nu_timer_t;
- /* Private functions ------------------------------------------------------------*/
- static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state);
- static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode);
- static void nu_timer_stop(rt_hwtimer_t *timer);
- static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer);
- static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
- /* Public functions -------------------------------------------------------------*/
- /* Private variables ------------------------------------------------------------*/
- #ifdef BSP_USING_TIMER0
- static nu_timer_t nu_timer0;
- #endif
- #ifdef BSP_USING_TIMER1
- static nu_timer_t nu_timer1;
- #endif
- #ifdef BSP_USING_TIMER2
- static nu_timer_t nu_timer2;
- #endif
- #ifdef BSP_USING_TIMER3
- static nu_timer_t nu_timer3;
- #endif
- static struct rt_hwtimer_info nu_timer_info =
- {
- 12000000, /* maximum count frequency */
- 46875, /* minimum count frequency */
- 0xFFFFFF, /* the maximum counter value */
- HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
- };
- static struct rt_hwtimer_ops nu_timer_ops =
- {
- nu_timer_init,
- nu_timer_start,
- nu_timer_stop,
- nu_timer_count_get,
- nu_timer_control
- };
- /* Functions define ------------------------------------------------------------*/
- static void nu_timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
- {
- RT_ASSERT(timer != RT_NULL);
- nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
- RT_ASSERT(nu_timer != RT_NULL);
- RT_ASSERT(nu_timer->timer_periph != RT_NULL);
- if (1 == state)
- {
- uint32_t timer_clk;
- struct rt_hwtimer_info *info = &nu_timer_info;
- timer_clk = TIMER_GetModuleClock(nu_timer->timer_periph);
- info->maxfreq = timer_clk;
- info->minfreq = timer_clk / 256;
- TIMER_Open(nu_timer->timer_periph, TIMER_ONESHOT_MODE, 1);
- TIMER_EnableInt(nu_timer->timer_periph);
- NVIC_EnableIRQ(nu_timer->IRQn);
- }
- else
- {
- NVIC_DisableIRQ(nu_timer->IRQn);
- TIMER_DisableInt(nu_timer->timer_periph);
- TIMER_Close(nu_timer->timer_periph);
- }
- }
- static rt_err_t nu_timer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t opmode)
- {
- rt_err_t err = RT_EOK;
- RT_ASSERT(timer != RT_NULL);
- nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
- RT_ASSERT(nu_timer != RT_NULL);
- RT_ASSERT(nu_timer->timer_periph != RT_NULL);
- if (cnt > 1 && cnt <= 0xFFFFFF)
- {
- TIMER_SET_CMP_VALUE(nu_timer->timer_periph, cnt);
- }
- else
- {
- rt_kprintf("nu_timer_start set compared value failed\n");
- err = RT_ERROR;
- }
- if (HWTIMER_MODE_PERIOD == opmode)
- {
- TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_PERIODIC_MODE);
- }
- else if (HWTIMER_MODE_ONESHOT == opmode)
- {
- TIMER_SET_OPMODE(nu_timer->timer_periph, TIMER_ONESHOT_MODE);
- }
- else
- {
- rt_kprintf("nu_timer_start set operation mode failed\n");
- err = RT_ERROR;
- }
- TIMER_Start(nu_timer->timer_periph);
- return err;
- }
- static void nu_timer_stop(rt_hwtimer_t *timer)
- {
- RT_ASSERT(timer != RT_NULL);
- nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
- RT_ASSERT(nu_timer != RT_NULL);
- RT_ASSERT(nu_timer->timer_periph != RT_NULL);
- TIMER_Stop(nu_timer->timer_periph);
- }
- static rt_uint32_t nu_timer_count_get(rt_hwtimer_t *timer)
- {
- RT_ASSERT(timer != RT_NULL);
- nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
- RT_ASSERT(nu_timer != RT_NULL);
- RT_ASSERT(nu_timer->timer_periph != RT_NULL);
- return TIMER_GetCounter(nu_timer->timer_periph);
- }
- static rt_err_t nu_timer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
- {
- rt_err_t ret = RT_EOK;
- RT_ASSERT(timer != RT_NULL);
- nu_timer_t *nu_timer = NU_TIMER_DEVICE(timer->parent.user_data);
- RT_ASSERT(nu_timer != RT_NULL);
- RT_ASSERT(nu_timer->timer_periph != RT_NULL);
- switch (cmd)
- {
- case HWTIMER_CTRL_FREQ_SET:
- {
- uint32_t clk;
- uint32_t pre;
- clk = TIMER_GetModuleClock(nu_timer->timer_periph);
- pre = clk / *((uint32_t *)args) - 1;
- TIMER_SET_PRESCALE_VALUE(nu_timer->timer_periph, pre);
- *((uint32_t *)args) = clk / (pre + 1) ;
- }
- break;
- case HWTIMER_CTRL_STOP:
- TIMER_Stop(nu_timer->timer_periph);
- break;
- default:
- ret = RT_EINVAL;
- break;
- }
- return ret;
- }
- int rt_hw_timer_init(void)
- {
- rt_err_t ret = RT_EOK;
- #ifdef BSP_USING_TIMER0
- nu_timer0.timer_periph = TIMER0;
- nu_timer0.parent.info = &nu_timer_info;
- nu_timer0.parent.ops = &nu_timer_ops;
- nu_timer0.IRQn = TMR0_IRQn;
- ret = rt_device_hwtimer_register(&nu_timer0.parent, "timer0", &nu_timer0);
- if (ret != RT_EOK)
- {
- rt_kprintf("timer0 register failed\n");
- }
- SYS_ResetModule(TMR0_RST);
- CLK_EnableModuleClock(TMR0_MODULE);
- #endif
- #ifdef BSP_USING_TIMER1
- nu_timer1.timer_periph = TIMER1;
- nu_timer1.parent.info = &nu_timer_info;
- nu_timer1.parent.ops = &nu_timer_ops;
- nu_timer1.IRQn = TMR1_IRQn;
- ret = rt_device_hwtimer_register(&nu_timer1.parent, "timer1", &nu_timer1);
- if (ret != RT_EOK)
- {
- rt_kprintf("timer1 register failed\n");
- }
- SYS_ResetModule(TMR1_RST);
- CLK_EnableModuleClock(TMR1_MODULE);
- #endif
- #ifdef BSP_USING_TIMER2
- nu_timer2.timer_periph = TIMER2;
- nu_timer2.parent.info = &nu_timer_info;
- nu_timer2.parent.ops = &nu_timer_ops;
- nu_timer2.IRQn = TMR2_IRQn;
- ret = rt_device_hwtimer_register(&nu_timer2.parent, "timer2", &nu_timer2);
- if (ret != RT_EOK)
- {
- rt_kprintf("timer2 register failed\n");
- }
- SYS_ResetModule(TMR2_RST);
- CLK_EnableModuleClock(TMR2_MODULE);
- #endif
- #ifdef BSP_USING_TIMER3
- nu_timer3.timer_periph = TIMER3;
- nu_timer3.parent.info = &nu_timer_info;
- nu_timer3.parent.ops = &nu_timer_ops;
- nu_timer3.IRQn = TMR3_IRQn;
- ret = rt_device_hwtimer_register(&nu_timer3.parent, "timer3", &nu_timer3);
- if (ret != RT_EOK)
- {
- rt_kprintf("timer3 register failed\n");
- }
- SYS_ResetModule(TMR3_RST);
- CLK_EnableModuleClock(TMR3_MODULE);
- #endif
- return ret;
- }
- INIT_BOARD_EXPORT(rt_hw_timer_init);
- #ifdef BSP_USING_TIMER0
- void TMR0_IRQHandler(void)
- {
- rt_interrupt_enter();
- if (TIMER_GetIntFlag(TIMER0))
- {
- TIMER_ClearIntFlag(TIMER0);
- rt_device_hwtimer_isr(&nu_timer0.parent);
- }
- rt_interrupt_leave();
- }
- #endif
- #ifdef BSP_USING_TIMER1
- void TMR1_IRQHandler(void)
- {
- rt_interrupt_enter();
- if (TIMER_GetIntFlag(TIMER1))
- {
- TIMER_ClearIntFlag(TIMER1);
- rt_device_hwtimer_isr(&nu_timer1.parent);
- }
- rt_interrupt_leave();
- }
- #endif
- #ifdef BSP_USING_TIMER2
- void TMR2_IRQHandler(void)
- {
- rt_interrupt_enter();
- if (TIMER_GetIntFlag(TIMER2))
- {
- TIMER_ClearIntFlag(TIMER2);
- rt_device_hwtimer_isr(&nu_timer2.parent);
- }
- rt_interrupt_leave();
- }
- #endif
- #ifdef BSP_USING_TIMER3
- void TMR3_IRQHandler(void)
- {
- rt_interrupt_enter();
- if (TIMER_GetIntFlag(TIMER3))
- {
- TIMER_ClearIntFlag(TIMER3);
- rt_device_hwtimer_isr(&nu_timer3.parent);
- }
- rt_interrupt_leave();
- }
- #endif
- #endif //#if (defined(BSP_USING_TIMER) && defined(RT_USING_HWTIMER))
|