2022-03-08 12:03:06 +08:00
|
|
|
/*
|
2023-03-20 12:04:18 +08:00
|
|
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
2022-03-08 12:03:06 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*
|
|
|
|
* Change Logs:
|
|
|
|
* Date Author Notes
|
|
|
|
* 2022-03-04 stevetong459 first version
|
2022-07-22 15:05:14 +08:00
|
|
|
* 2022-07-15 Aligagago add apm32F4 serie MCU support
|
2023-01-05 14:15:02 +08:00
|
|
|
* 2022-12-26 luobeihai add apm32F0 serie MCU support
|
2022-03-08 12:03:06 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <board.h>
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
#define DBG_TAG "drv.hwtimer"
|
2022-03-08 12:03:06 +08:00
|
|
|
#define DBG_LVL DBG_INFO
|
|
|
|
#include <rtdbg.h>
|
|
|
|
|
|
|
|
#ifdef RT_USING_HWTIMER
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static const struct rt_hwtimer_info apm32_timer_info =
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
.maxfreq = 1000000,
|
|
|
|
.minfreq = 2000,
|
|
|
|
.maxcnt = 0xFFFF,
|
|
|
|
.cntmode = HWTIMER_CNTMODE_UP,
|
|
|
|
};
|
|
|
|
|
|
|
|
/* apm32 config class */
|
|
|
|
struct apm32_timer
|
|
|
|
{
|
|
|
|
char *name;
|
|
|
|
TMR_T *tmr;
|
|
|
|
IRQn_Type irqn;
|
|
|
|
rt_hwtimer_t device;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
#ifdef BSP_USING_TMR1
|
|
|
|
TMR1_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR2
|
|
|
|
TMR2_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR3
|
|
|
|
TMR3_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR4
|
|
|
|
TMR4_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR5
|
|
|
|
TMR5_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR6
|
|
|
|
TMR6_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR7
|
|
|
|
TMR7_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR8
|
|
|
|
TMR8_INDEX,
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
#ifdef BSP_USING_TMR9
|
|
|
|
TMR9_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR10
|
|
|
|
TMR10_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR11
|
|
|
|
TMR11_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR12
|
|
|
|
TMR12_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR13
|
|
|
|
TMR13_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR14
|
|
|
|
TMR14_INDEX,
|
|
|
|
#endif
|
2023-01-05 14:15:02 +08:00
|
|
|
#ifdef BSP_USING_TMR15
|
|
|
|
TMR15_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR16
|
|
|
|
TMR16_INDEX,
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR17
|
|
|
|
TMR17_INDEX,
|
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct apm32_timer tmr_config[] =
|
|
|
|
{
|
|
|
|
#ifdef BSP_USING_TMR1
|
|
|
|
{
|
|
|
|
"timer1",
|
|
|
|
TMR1,
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F1)
|
2022-03-08 12:03:06 +08:00
|
|
|
TMR1_UP_IRQn,
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2022-07-22 15:05:14 +08:00
|
|
|
TMR1_UP_TMR10_IRQn,
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F0)
|
|
|
|
TMR1_BRK_UP_TRG_COM_IRQn
|
2022-07-25 10:21:18 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR2
|
|
|
|
{
|
|
|
|
"timer2",
|
|
|
|
TMR2,
|
|
|
|
TMR2_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR3
|
|
|
|
{
|
|
|
|
"timer3",
|
|
|
|
TMR3,
|
|
|
|
TMR3_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR4
|
|
|
|
{
|
|
|
|
"timer4",
|
|
|
|
TMR4,
|
|
|
|
TMR4_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR5
|
|
|
|
{
|
|
|
|
"timer5",
|
|
|
|
TMR5,
|
|
|
|
TMR5_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR6
|
|
|
|
{
|
|
|
|
"timer6",
|
|
|
|
TMR6,
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F1) || defined(APM32F030) || defined(APM32F070)
|
2022-03-08 12:03:06 +08:00
|
|
|
TMR6_IRQn,
|
2023-03-20 12:04:18 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2023-01-05 14:15:02 +08:00
|
|
|
TMR6_DAC_IRQn
|
|
|
|
#elif defined(SOC_SERIES_APM32F0) && !defined(APM32F030) && !defined(APM32F070)
|
2022-07-22 15:05:14 +08:00
|
|
|
TMR6_DAC_IRQn
|
2022-07-25 10:21:18 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR7
|
|
|
|
{
|
|
|
|
"timer7",
|
|
|
|
TMR7,
|
|
|
|
TMR7_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR8
|
|
|
|
{
|
|
|
|
"timer8",
|
|
|
|
TMR8,
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F1)
|
2022-03-08 12:03:06 +08:00
|
|
|
TMR8_UP_IRQn,
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2022-07-22 15:05:14 +08:00
|
|
|
TMR8_UP_TMR13_IRQn,
|
2022-07-25 10:21:18 +08:00
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR9
|
|
|
|
{
|
|
|
|
"timer9",
|
|
|
|
TMR9,
|
|
|
|
TMR1_BRK_TMR9_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR10
|
|
|
|
{
|
|
|
|
"timer10",
|
|
|
|
TMR10,
|
|
|
|
TMR1_UP_TMR10_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR11
|
|
|
|
{
|
|
|
|
"timer11",
|
|
|
|
TMR11,
|
|
|
|
TMR1_TRG_COM_TMR11_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR12
|
|
|
|
{
|
|
|
|
"timer12",
|
|
|
|
TMR12,
|
|
|
|
TMR8_BRK_TMR12_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR13
|
|
|
|
{
|
|
|
|
"timer13",
|
|
|
|
TMR13,
|
|
|
|
TMR8_UP_TMR13_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR14
|
|
|
|
{
|
|
|
|
"timer14",
|
|
|
|
TMR14,
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
TMR14_IRQn,
|
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2022-07-22 15:05:14 +08:00
|
|
|
TMR8_TRG_COM_TMR14_IRQn,
|
2023-01-05 14:15:02 +08:00
|
|
|
#endif
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR15
|
|
|
|
{
|
|
|
|
"timer15",
|
|
|
|
TMR15,
|
|
|
|
TMR15_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR16
|
|
|
|
{
|
|
|
|
"timer16",
|
|
|
|
TMR16,
|
|
|
|
TMR16_IRQn,
|
|
|
|
},
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR17
|
|
|
|
{
|
|
|
|
"timer17",
|
|
|
|
TMR17,
|
|
|
|
TMR17_IRQn,
|
2022-03-08 12:03:06 +08:00
|
|
|
},
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static rt_uint32_t apm32_hwtimer_clock_get(TMR_T *tmr)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
uint32_t pclk1;
|
2023-03-20 12:04:18 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
pclk1 = RCM_ReadPCLKFreq();
|
2023-03-20 12:04:18 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
return (rt_uint32_t)(pclk1 * ((RCM->CFG1_B.APB1PSC != 0) ? 2 : 1));
|
|
|
|
#else
|
2022-07-25 10:21:18 +08:00
|
|
|
uint32_t pclk1, pclk2;
|
2022-03-08 12:03:06 +08:00
|
|
|
|
2022-07-22 15:05:14 +08:00
|
|
|
RCM_ReadPCLKFreq(&pclk1, &pclk2);
|
2022-03-08 12:03:06 +08:00
|
|
|
|
2022-07-25 10:21:18 +08:00
|
|
|
if (tmr == TMR1 || tmr == TMR8 || tmr == TMR9 || tmr == TMR10 || tmr == TMR11)
|
2022-07-22 15:05:14 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
return (rt_uint32_t)(pclk2 * ((RCM->CFG_B.APB2PSC != 0) ? 2 : 1));
|
2022-07-22 15:05:14 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
return (rt_uint32_t)(pclk1 * ((RCM->CFG_B.APB1PSC != 0) ? 2 : 1));
|
2022-07-22 15:05:14 +08:00
|
|
|
}
|
2023-01-05 14:15:02 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static void apm32_hwtimer_enable_clock(void)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
#ifdef BSP_USING_TMR1
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR1);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR2
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR2);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR3
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR4
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR5
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR5);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR6
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR6);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR7
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR7);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR8
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR8);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR9
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR10
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR10);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR11
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR11);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR12
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR12);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR13
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR13);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR14
|
|
|
|
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR14);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR15
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR15);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR16
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR16);
|
|
|
|
#endif
|
|
|
|
#ifdef BSP_USING_TMR17
|
|
|
|
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR17);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static void apm32_hwtimer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
|
|
|
|
{
|
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
TMR_TimeBase_T base_config;
|
|
|
|
#else
|
2022-03-08 12:03:06 +08:00
|
|
|
TMR_BaseConfig_T base_config;
|
2023-01-05 14:15:02 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
uint32_t prescaler = 0;
|
|
|
|
struct apm32_timer *timer_config;
|
|
|
|
|
|
|
|
RT_ASSERT(timer != RT_NULL);
|
|
|
|
|
|
|
|
if (state)
|
|
|
|
{
|
|
|
|
timer_config = (struct apm32_timer *)timer->parent.user_data;
|
2023-03-20 12:04:18 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
apm32_hwtimer_enable_clock();
|
2023-03-20 12:04:18 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
prescaler = (uint32_t)(apm32_hwtimer_clock_get(timer_config->tmr) / 10000) - 1;
|
|
|
|
|
|
|
|
base_config.period = 10000 - 1;
|
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
base_config.div = prescaler;
|
|
|
|
base_config.clockDivision = TMR_CKD_DIV1;
|
|
|
|
if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
|
2022-07-22 15:05:14 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
base_config.counterMode = TMR_COUNTER_MODE_UP;
|
2022-07-22 15:05:14 +08:00
|
|
|
}
|
2023-01-05 14:15:02 +08:00
|
|
|
else
|
2022-07-22 15:05:14 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
base_config.counterMode = TMR_COUNTER_MODE_DOWN;
|
2022-07-22 15:05:14 +08:00
|
|
|
}
|
2023-01-05 14:15:02 +08:00
|
|
|
#else
|
2022-03-08 12:03:06 +08:00
|
|
|
base_config.division = prescaler;
|
|
|
|
base_config.clockDivision = TMR_CLOCK_DIV_1;
|
|
|
|
if (timer->info->cntmode == HWTIMER_CNTMODE_UP)
|
|
|
|
{
|
|
|
|
base_config.countMode = TMR_COUNTER_MODE_UP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
base_config.countMode = TMR_COUNTER_MODE_DOWN;
|
|
|
|
}
|
2023-01-05 14:15:02 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
base_config.repetitionCounter = 0;
|
|
|
|
TMR_ConfigTimeBase(timer_config->tmr, &base_config);
|
2023-03-20 12:04:18 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
/* set the TIMx priority */
|
|
|
|
NVIC_EnableIRQRequest(timer_config->irqn, 3);
|
|
|
|
/* enable update request source */
|
|
|
|
TMR_ConfigUPdateRequest(timer_config->tmr, TMR_UPDATE_SOURCE_REGULAR);
|
|
|
|
#else
|
2022-03-08 12:03:06 +08:00
|
|
|
/* set the TIMx priority */
|
|
|
|
NVIC_EnableIRQRequest(timer_config->irqn, 3, 0);
|
|
|
|
/* enable update request source */
|
|
|
|
TMR_ConfigUpdateRequest(timer_config->tmr, TMR_UPDATE_SOURCE_REGULAR);
|
2023-01-05 14:15:02 +08:00
|
|
|
#endif
|
|
|
|
/* clear update flag */
|
|
|
|
TMR_ClearStatusFlag(timer_config->tmr, TMR_FLAG_UPDATE);
|
2022-03-08 12:03:06 +08:00
|
|
|
LOG_D("%s init success", timer_config->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static rt_err_t apm32_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
rt_err_t result = RT_EOK;
|
|
|
|
struct apm32_timer *timer_config = RT_NULL;
|
|
|
|
|
|
|
|
RT_ASSERT(timer != RT_NULL);
|
|
|
|
|
|
|
|
timer_config = (struct apm32_timer *)timer->parent.user_data;
|
|
|
|
|
|
|
|
/* set timer_config counter */
|
2023-01-05 14:15:02 +08:00
|
|
|
timer_config->tmr->CNT = 0;
|
2022-03-08 12:03:06 +08:00
|
|
|
/* set timer_config autoReload */
|
2023-01-05 14:15:02 +08:00
|
|
|
timer_config->tmr->AUTORLD = t - 1;
|
2022-03-08 12:03:06 +08:00
|
|
|
|
|
|
|
if (opmode == HWTIMER_MODE_ONESHOT)
|
|
|
|
{
|
|
|
|
/* set timer to single mode */
|
2023-01-05 14:15:02 +08:00
|
|
|
timer_config->tmr->CTRL1_B.SPMEN = 1;
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
timer_config->tmr->CTRL1_B.SPMEN = 0;
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
TMR_EnableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
if (timer_config->tmr == TMR1 || timer_config->tmr == TMR2 || timer_config->tmr == TMR3 || \
|
|
|
|
timer_config->tmr == TMR15)
|
|
|
|
#else
|
|
|
|
if (timer_config->tmr == TMR1 || timer_config->tmr == TMR2 || timer_config->tmr == TMR3 || \
|
|
|
|
timer_config->tmr == TMR4 || timer_config->tmr == TMR5 || timer_config->tmr == TMR8 || \
|
|
|
|
timer_config->tmr == TMR9 || timer_config->tmr == TMR12)
|
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
if (timer_config->tmr->SMCTRL_B.SMFSEL != 0x06)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
TMR_Enable(timer_config->tmr);
|
2023-01-05 14:15:02 +08:00
|
|
|
result = RT_EOK;
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TMR_Enable(timer_config->tmr);
|
2023-01-05 14:15:02 +08:00
|
|
|
result = RT_EOK;
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static void apm32_hwtimer_stop(rt_hwtimer_t *timer)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
struct apm32_timer *timer_config = RT_NULL;
|
|
|
|
RT_ASSERT(timer != RT_NULL);
|
|
|
|
timer_config = (struct apm32_timer *)timer->parent.user_data;
|
|
|
|
|
|
|
|
TMR_DisableInterrupt(timer_config->tmr, TMR_INT_UPDATE);
|
|
|
|
TMR_Enable(timer_config->tmr);
|
2023-01-05 14:15:02 +08:00
|
|
|
timer_config->tmr->CNT = 0;
|
2022-03-08 12:03:06 +08:00
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static rt_err_t apm32_hwtimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
struct apm32_timer *timer_config = RT_NULL;
|
|
|
|
rt_err_t result = RT_EOK;
|
|
|
|
rt_uint32_t freq;
|
|
|
|
rt_uint16_t val;
|
|
|
|
|
|
|
|
RT_ASSERT(timer != RT_NULL);
|
|
|
|
RT_ASSERT(arg != RT_NULL);
|
|
|
|
|
|
|
|
timer_config = (struct apm32_timer *)timer->parent.user_data;
|
|
|
|
|
|
|
|
switch (cmd)
|
|
|
|
{
|
|
|
|
case HWTIMER_CTRL_FREQ_SET:
|
|
|
|
/* set timer frequence */
|
|
|
|
freq = *((rt_uint32_t *)arg);
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
val = apm32_hwtimer_clock_get(timer_config->tmr) / freq;
|
2022-03-08 12:03:06 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
/* Configures the timer prescaler */
|
|
|
|
timer_config->tmr->PSC_B.PSC = val - 1;
|
|
|
|
timer_config->tmr->CEG_B.UEG = 1;
|
2022-03-08 12:03:06 +08:00
|
|
|
break;
|
|
|
|
default:
|
2023-01-05 14:15:02 +08:00
|
|
|
LOG_E("invalid cmd: 0x%x\n", cmd);
|
2022-03-08 12:03:06 +08:00
|
|
|
result = -RT_ENOSYS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static rt_uint32_t apm32_hwtimer_counter_get(rt_hwtimer_t *timer)
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
struct apm32_timer *timer_config = RT_NULL;
|
|
|
|
RT_ASSERT(timer != RT_NULL);
|
|
|
|
timer_config = (struct apm32_timer *)timer->parent.user_data;
|
|
|
|
|
|
|
|
return timer_config->tmr->CNT;
|
|
|
|
}
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
static const struct rt_hwtimer_ops apm32_hwtimer_ops =
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
.init = apm32_hwtimer_init,
|
|
|
|
.start = apm32_hwtimer_start,
|
|
|
|
.stop = apm32_hwtimer_stop,
|
|
|
|
.count_get = apm32_hwtimer_counter_get,
|
|
|
|
.control = apm32_hwtimer_ctrl,
|
2022-03-08 12:03:06 +08:00
|
|
|
};
|
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
|
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
#ifdef BSP_USING_TMR1
|
|
|
|
void TMR1_BRK_UP_TRG_COM_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR1_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#elif defined(SOC_SERIES_APM32F1)
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR1
|
|
|
|
void TMR1_UP_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR1_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2022-07-22 15:05:14 +08:00
|
|
|
#if (defined(BSP_USING_TMR1) || defined(BSP_USING_TMR10))
|
|
|
|
void TMR1_UP_TMR10_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
if (TMR_ReadIntFlag(TMR1, TMR_INT_UPDATE))
|
|
|
|
{
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR1_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR1, TMR_INT_UPDATE);
|
|
|
|
}
|
|
|
|
if (TMR_ReadIntFlag(TMR10, TMR_INT_UPDATE))
|
|
|
|
{
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR10_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR10, TMR_INT_UPDATE);
|
|
|
|
}
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR2
|
|
|
|
void TMR2_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR2_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR2, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR3
|
|
|
|
void TMR3_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR3_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR3, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR4
|
|
|
|
void TMR4_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR4_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR4, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR5
|
|
|
|
void TMR5_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR5_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR5, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR6
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F1) || defined(APM32F030) || defined(APM32F070)
|
2022-07-25 10:21:18 +08:00
|
|
|
void TMR6_IRQHandler(void)
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
|
|
|
void TMR6_DAC_IRQHandler(void)
|
|
|
|
#elif defined(SOC_SERIES_APM32F0) && !defined(APM32F030) && !defined(APM32F070)
|
2022-07-25 10:21:18 +08:00
|
|
|
void TMR6_DAC_IRQHandler(void)
|
2022-07-22 15:05:14 +08:00
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR6_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR6, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR7
|
|
|
|
void TMR7_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR7_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR7, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F1)
|
2022-03-08 12:03:06 +08:00
|
|
|
#ifdef BSP_USING_TMR8
|
|
|
|
void TMR8_UP_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR8_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR8, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2023-01-05 14:15:02 +08:00
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
2022-07-22 15:05:14 +08:00
|
|
|
#if (defined(BSP_USING_TMR8) || defined(BSP_USING_TMR13))
|
|
|
|
void TMR8_UP_TMR13_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
if (TMR_ReadIntFlag(TMR8, TMR_INT_UPDATE))
|
|
|
|
{
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR8_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR8, TMR_INT_UPDATE);
|
|
|
|
}
|
|
|
|
if (TMR_ReadIntFlag(TMR13, TMR_INT_UPDATE))
|
|
|
|
{
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR13_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR13, TMR_INT_UPDATE);
|
|
|
|
}
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR9
|
|
|
|
void TMR1_BRK_TMR9_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR9_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR9, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR11
|
|
|
|
void TMR1_TRG_COM_TMR11_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR11_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR11, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR12
|
|
|
|
void TMR8_BRK_TMR12_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR12_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR12, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR14
|
2023-01-05 14:15:02 +08:00
|
|
|
#if defined(SOC_SERIES_APM32F0)
|
|
|
|
void TMR14_IRQHandler(void)
|
|
|
|
#elif defined(SOC_SERIES_APM32F4)
|
|
|
|
void TMR8_TRG_COM_TMR14_IRQHandler(void)
|
|
|
|
#endif
|
2022-07-22 15:05:14 +08:00
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR14_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR14, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
2022-03-08 12:03:06 +08:00
|
|
|
|
2023-01-05 14:15:02 +08:00
|
|
|
#ifdef BSP_USING_TMR15
|
|
|
|
void TMR15_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR15_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR15, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR16
|
|
|
|
void TMR16_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR16_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR16, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef BSP_USING_TMR17
|
|
|
|
void TMR17_IRQHandler(void)
|
|
|
|
{
|
|
|
|
rt_interrupt_enter();
|
|
|
|
rt_device_hwtimer_isr(&tmr_config[TMR17_INDEX].device);
|
|
|
|
TMR_ClearIntFlag(TMR17, TMR_INT_UPDATE);
|
|
|
|
rt_interrupt_leave();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-03-08 12:03:06 +08:00
|
|
|
static int rt_hw_hwtimer_init(void)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
int result = RT_EOK;
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(tmr_config) / sizeof(tmr_config[0]); i++)
|
|
|
|
{
|
2023-01-05 14:15:02 +08:00
|
|
|
tmr_config[i].device.info = &apm32_timer_info;
|
|
|
|
tmr_config[i].device.ops = &apm32_hwtimer_ops;
|
2022-03-08 12:03:06 +08:00
|
|
|
if (rt_device_hwtimer_register(&tmr_config[i].device, tmr_config[i].name, &tmr_config[i]) == RT_EOK)
|
|
|
|
{
|
|
|
|
LOG_D("%s register success", tmr_config[i].name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LOG_E("%s register failed", tmr_config[i].name);
|
|
|
|
result = -RT_ERROR;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
INIT_BOARD_EXPORT(rt_hw_hwtimer_init);
|
|
|
|
|
|
|
|
#endif /* RT_USING_HWTIMER */
|