Files
test/drivers/source/etimer/sdrv_multicapture.c
2025-11-07 20:19:23 +08:00

1062 lines
43 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file sdrv_multicapture
* @brief SemiDrive etimer capture driver source file.
*
* @copyright Copyright (c) 2022 Semidrive Semiconductor.
* All rights reserved.
*/
#include <config.h>
#include <debug.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regs_base.h>
#include <clock_cfg.h>
#include <reset_cfg.h>
#include <pinmux_cfg.h>
#include <sdrv_uart.h>
#include <irq.h>
#include <irq_num.h>
#include "sdrv_etimer.h"
#include "sdrv_xtrg.h"
#include "board.h"
#include "sdrv_multicapture.h"
#include "sdrv_dma.h"
#include <armv7-r/cache.h>
#include <reset_ip.h>
uint32_t ETMR_BASE[ETIMER_IP_MAX_MODULE];
#ifndef CONFIG_E3L
#define ICU_MULTI_ETMR_SCR_CFG_ADDR(tm) (0x100CU + ((uint32_t)tm*0x4U))
#else
#define ICU_MULTI_ETMR_SCR_CFG_ADDR (0x1070U)
#endif
#define ICU_INT_STA_ADDR32(tm) (ETMR_BASE[tm])
#define ICU_INT_STA_EN_ADDR32(tm) (ETMR_BASE[tm] + (uint32_t)0x4U)
#define ICU_INT_SIG_EN_ADDR32(tm) (ETMR_BASE[tm] + (uint32_t)0x8U)
#define ICU_FIFO_ADDR32(tm, cha) (ETMR_BASE[tm] + (uint32_t)0xC0U + ((uint32_t)cha*0x4u))
#define ICU_TIM_CLK_CONFIG(tm) (ETMR_BASE[tm] + (uint32_t)0xA0U)
#define ICU_BM_TIM_CLK_CONFIG_CLK_CHANGE_UPD (0x01U << 31U)
#define ICU_FM_TIM_CLK_CONFIG_SRC_CLK_SEL (0x3U << 16U)
#define ICU_FV_TIM_CLK_CONFIG_SRC_CLK_SEL(v) (((v) << 16U) & ICU_FM_TIM_CLK_CONFIG_SRC_CLK_SEL)
#define ICU_FM_TIM_CLK_CONFIG_DIV_NUM (0xffffU << 0U)
#define ICU_FV_TIM_CLK_CONFIG_DIV_NUM(v) (((v) << 0U) & ICU_FM_TIM_CLK_CONFIG_DIV_NUM)
#define ICU_FIFO_STA(tm) (ETMR_BASE[tm] + (uint32_t)0xD0U)
#define ICU_CLK_MON_EN(tm) (ETMR_BASE[tm] + (uint32_t)0xA4U)
#define ICU_BM_CLK_MON_EN_CMP_SET (0x01U << 2U)
#define ICU_BM_CLK_MON_EN_EN_N (0x01U << 1U)
#define ICU_BM_CLK_MON_EN_EN_P (0x01U << 0U)
#define ICU_LOCAL_CNT_CFG(tm,cha) (ETMR_BASE[tm] + 0x148U + (cha)*0x20)
#define ICU_CNT_CFG_START_BY_FIRST_CPT_START_BIT 25
#define ICU_CNT_CFG_CPT1_CLR_EN_START_BIT 24
#define ICU_CNT_CFG_CPT0_CLR_EN_START_BIT 23
#define ICU_CNT_CFG_INIT_UPD_START_BIT 16
#define ICU_CNT_CFG_OVF_UPD_START_BIT 17
#define ICU_LOCAL_CNT(tm,cha) (ETMR_BASE[tm] + 0x150U + (cha)*0x20)
#define ICU_LOCAL_CNT_EN(tm, cha) (ETMR_BASE[tm] + 0x14Cu + ((uint32_t)cha*0x20u))
#define ICU_LOCAL_CNT_OVF_VAL(tm, cha) (ETMR_BASE[tm] + 0x144u + ((uint32_t)cha*0x20u))
#define ICU_CPT_CONFIG(tm, cha) (ETMR_BASE[tm] + 0x200u + ((uint32_t)cha*0x4u))
#define ICU_CPT_CONFIG_DUAL_MODE_BIT (1u)
#define ICU_CPT_CONFIG_CPT0_TRIG_MODE_START_BIT (2u)
#define ICU_CPT_CONFIG_CPT1_TRIG_MODE_START_BIT (4u)
#define ICU_CPT_CONFIG_CNT_SEL_START_BIT (6u)
#define ICU_CHN_DMA_CTRL(tm) (ETMR_BASE[tm] + (uint32_t)0xB0U)
#define ICU_BM_CHN_DMA_CTRL_CHN_16BIT_MODE(cha) (0x01U << (16U + (cha)))
#define ICU_BM_CHN_DMA_CTRL_CHN_SIG_MASK(cha) (0x01U << (12U + (cha)))
#define ICU_FM_CHN_DMA_CTRL_CHN_SEL(cha) (0x3U << (4U + (cha)*0x2U))
#define ICU_FV_CHN_DMA_CTRL_CHN_SEL(v, cha) (((v) << (4U + (cha)*0x2U)) & ICU_FM_CHN_DMA_CTRL_CHN_SEL(cha))
#define ICU_BM_CHN_DMA_CTRL_CHN_EN(cha) (0x01U << (cha))
#define ICU_CHN_DMA_WML(tm) (ETMR_BASE[tm] + (uint32_t)0xB4U)
#define ICU_FM_DMA_WML_CHN(cha) (0xfU << ((cha)*0x8U))
#define ICU_FV_DMA_WML_CHN(v, cha) (((v) << ((cha)*0x8U)) & ICU_FM_DMA_WML_CHN(cha))
#define ICU_CHN_FIFO_ADDR(tm, cha) (ETMR_BASE[tm] + (uint32_t)0xC0U + cha*0x4)
#define ICU_CPT_CTRL(tm) (ETMR_BASE[tm] + (uint32_t)0x210U)
#define ICU_CPT_CTRL_CPT_CONFIG_SET_START_BIT(cha) (4U + (cha))
#define ICU_CPT_CTRL_CPT_EN_START_BIT(cha) (cha)
#define ICU_CPT_SSE_CTRL_OFF(tm, cha) (ETMR_BASE[tm] + (uint32_t)0x300U + (cha)*0x8U)
#define ICU_FM_CPT_SSE_CTRL_EDGE_SEL (0x3ffU << 6U)
#define ICU_FV_CPT_SSE_CTRL_EDGE_SEL(v) (((v) << 6U) & ICU_FM_CPT_SSE_CTRL_EDGE_SEL)
#define ICU_FM_CPT_SSE_CTRL_SSE_MODE (0x1fU << 1U)
#define ICU_FV_CPT_SSE_CTRL_SSE_MODE(v) (((v) << 1U) & ICU_FM_CPT_SSE_CTRL_SSE_MODE)
#define ICU_BM_CPT_SSE_CTRL_SSE_EN (0x01U << 0U)
#define ICU_CPT_SSE_REG_OFF(tm, cha) (ETMR_BASE[tm] + (uint32_t)0x304U + (cha)*0x8U)
#define ICU_CPT_X0_FLT(tm, cha) (ETMR_BASE[tm] + 0x400u + ((uint32_t)cha*0x4u))
/**************************************************************************************************************/
/**************************************************************************************************************/
static uint32_t ICU_MULTI_CPT_B_BUFFER[MULTI_CPT_MODULE_NUM][4] __attribute__((__aligned__
(CONFIG_ARCH_CACHE_LINE)));
static uint32_t ICU_MULTI_CPT_C_BUFFER[MULTI_CPT_MODULE_NUM][4] __attribute__((__aligned__
(CONFIG_ARCH_CACHE_LINE)));
/*虽然ICU_MULTI_CPT_B_BUFFER 和 ICU_MULTI_CPT_C_BUFFER 只使用了8字节但是为了cache对齐需要占满32字节以防止影响到其它的变量*/
static bool g_multicpt_clk_info[ETIMER_IP_MAX_MODULE];
static bool g_multicpt_timer_enable[MULTI_CPT_MODULE_NUM]; /*module*/
static bool
g_multicpt_dma_enable[MULTI_CPT_MODULE_NUM]; /*是否使用DMA*/
static bool g_multicpt_channel_enable[MULTI_CPT_MODULE_NUM][MULTI_CPT_MAX_IO_NUM]; /*channel*/
static sdrv_dma_t g_dma_instance[2 * MULTI_CPT_MODULE_NUM];
static sdrv_dma_channel_t g_channel[2 * MULTI_CPT_MODULE_NUM];
uint8_t sdrv_get_chip_version(void)
{
/*1.1芯片返回1 1.0芯片返回0*/
static uint8_t version = 0xFFu;
if (version == 0xFFu) {
version = (uint8_t)(readl(APB_EFUSEC_BASE + 0x1018) >> 16u);
}
else {
}
return version;
}
uint32_t timer_fifo_a(uint8_t timer_module)
{
return readl(ICU_FIFO_ADDR32(timer_module, 0));
}
uint32_t timer_fifo_b(uint8_t timer_module)
{
return readl(ICU_FIFO_ADDR32(timer_module, 1));
}
uint32_t timer_fifo_c(uint8_t timer_module)
{
return readl(ICU_FIFO_ADDR32(timer_module, 2));
}
uint32_t timer_fifo_d(uint8_t timer_module)
{
return readl(ICU_FIFO_ADDR32(timer_module, 3));
}
void sdrv_etimer_multicpt_set_base_addr(void)
{
uint8_t i = 0u;
sdrv_recovery_module_t *recovery_module = &recovery_module_array;
memset(&ETMR_BASE[0], 0, sizeof(ETMR_BASE));
for (i = 0; i < recovery_module->etimer_list->etimer_num; i++) {
ETMR_BASE[i] = recovery_module->etimer_list->etimer_base[i];
}
}
/**
* @brief sdrv_etimer_multicpt_xtrig_config
* @details set multi cpt xtrg config.
* @param[in] timer The etimer module.
* @param[in] multinum used multi cpt io number.
* @implements sdrv_etimer_multicpt_xtrig_config
* @return none
*/
void sdrv_etimer_multicpt_xtrig_config(uint8_t timer_module, uint8_t multinum)
{
sdrv_xtrg_sse5_config_t sse5_config_0;
sdrv_xtrg_config_t xtrg_config;
memset(&sse5_config_0, 0, sizeof(sse5_config_0));
memset(&xtrg_config, 0, sizeof(xtrg_config));
sdrv_xtrg_t xtrg_dev = {
.base = APB_XTRG_BASE
};
uint8_t IoIndex = 0U;
/* single group ssm5 io num : 8 */
uint8_t Ssm5Num = multinum / 8U;
uint8_t Ssm5NumReminder = multinum % 8U;
/* single group ssm io num : 4 */
uint8_t RemainSsmNum = ((Ssm5NumReminder % 4U) == 0U) ? (Ssm5NumReminder / 4U) : ((
Ssm5NumReminder / 4U) + 1U);
if (RemainSsmNum % 2U == 0U) {
Ssm5Num = Ssm5Num + 1U;
}
if (Ssm5Num == 0U) {
for (IoIndex = 0; IoIndex < multinum; IoIndex++) {
sse5_config_0.in[IoIndex].sig = IO_i((32 * timer_module) + IoIndex);
sse5_config_0.in[IoIndex].edge_detect = 1U;
sse5_config_0.in[IoIndex].edge = SDRV_XTRG_BOTHEDGE;
}
sse5_config_0.synthesis_val =
0xFFFEFFFEU; /*表示当前SSM的增值值 0xFFFEFFFEU */
sse5_config_0.ssm_sel = (sdrv_xtrg_ssm_sel_e)(8U *
timer_module); /*ssm_sel表示使用的是哪一个SSM总共有16个SSM。*/
sdrv_xtrg_sse5_config(&xtrg_dev, &sse5_config_0,
true); /*etimer1使用0 -7 SSM; etimer2使用8-15 SSM。*/
memset(&xtrg_config, 0, sizeof(xtrg_config));
xtrg_config.sig_i = (uint32_t)SSIG(8 * timer_module);
xtrg_config.sig_o = ETIMER_CPT0(timer_module,
0); /*表示使用SSM0与capture A0连接*/
sdrv_xtrg_smux_config(&xtrg_dev, &xtrg_config);
}
else {
uint8_t LoopSsm5 = ((Ssm5Num * 8U) > multinum) ? multinum : (Ssm5Num * 8U);
for (IoIndex = 0; IoIndex < LoopSsm5; IoIndex++) {
if ((IoIndex % 4U == 0U) && (IoIndex > 0U)) {
sse5_config_0.synthesis_val = 0xFFFEFFFEU;
sse5_config_0.ssm_sel = (sdrv_xtrg_ssm_sel_e)((8U * timer_module) + ((IoIndex / 4U) - 1U));
if ((IoIndex % 8U == 0U) && (IoIndex > 0U)) {
uint8_t MuxIdx = (2U * ((IoIndex / 8U) - 1U));
/* sse5 mux cfg */
sse5_config_0.in[4].sig = SSIG((uint8_t)((8u * timer_module) + MuxIdx));
sse5_config_0.in[4].edge_detect = 0U;
sse5_config_0.in[4].edge = SDRV_XTRG_BOTHEDGE;
sse5_config_0.synthesis_val = 0xFFFFFFFE;
/* xtrg-etimer mux config */
xtrg_config.sig_i = SSIG((uint8_t)((8u * timer_module) + (IoIndex / 4U) - 1U));
xtrg_config.sig_o = ETIMER_CPT0(timer_module, MuxIdx);
sdrv_xtrg_smux_config(&xtrg_dev, &xtrg_config);
}
/*sdrv_xtrg_sse5_enable(&xtrg_dev, &sse5_config_0, true);*/
sdrv_xtrg_sse5_config(&xtrg_dev, &sse5_config_0, true);
/* set xtrg_config and sse5_config_0 to 0 */
memset(&xtrg_config, 0, sizeof(xtrg_config));
memset(&sse5_config_0, 0, sizeof(sse5_config_0));
}
uint8_t Sse5Idx = IoIndex % 4;
sse5_config_0.in[Sse5Idx].sig = IO_i((32 * timer_module) + IoIndex);
sse5_config_0.in[Sse5Idx].edge_detect = 1U;
sse5_config_0.in[Sse5Idx].edge = SDRV_XTRG_BOTHEDGE;
/* the last time for ss5 cfg xtrg */
if (IoIndex == LoopSsm5 - 1U) {
uint8_t MuxIdx = (2U * (IoIndex / 8U));
/* sse5 mux cfg */
sse5_config_0.in[4].sig = SSIG(MuxIdx + (8 * timer_module));
sse5_config_0.in[4].edge_detect = 0U;
sse5_config_0.in[4].edge = SDRV_XTRG_BOTHEDGE;
/* xtrg-etimer mux config */
xtrg_config.sig_i = SSIG((uint8_t)((8 * timer_module) + (IoIndex / 4U)));
xtrg_config.sig_o = ETIMER_CPT0(timer_module, MuxIdx);
sdrv_xtrg_smux_config(&xtrg_dev, &xtrg_config);
sse5_config_0.synthesis_val = 0xFFFFFFFEU;
sse5_config_0.ssm_sel = (sdrv_xtrg_ssm_sel_e)((8U * timer_module) + (IoIndex / 4U));
/*sdrv_xtrg_sse5_enable(&xtrg_dev, &sse5_config_0, true);*/
sdrv_xtrg_sse5_config(&xtrg_dev, &sse5_config_0, true);
/* set xtrg_config and sse5_config_0 to 0 */
memset(&xtrg_config, 0, sizeof(xtrg_config));
memset(&sse5_config_0, 0, sizeof(sse5_config_0));
}
}
if (RemainSsmNum == 1) {
/* the last ssm cfg */
for (uint8_t RemainSSmIo = IoIndex; RemainSSmIo < multinum; RemainSSmIo++) {
uint8_t RemianSse5Idx = RemainSSmIo % 4U;
sse5_config_0.in[RemianSse5Idx].sig = IO_i((32 * timer_module) + RemainSSmIo);
sse5_config_0.in[RemianSse5Idx].edge_detect = 1U;
sse5_config_0.in[RemianSse5Idx].edge = SDRV_XTRG_BOTHEDGE;
if (RemainSSmIo == multinum - 1U) {
sse5_config_0.synthesis_val = 0xFFFEFFFE;
sse5_config_0.ssm_sel = (sdrv_xtrg_ssm_sel_e)((8U * timer_module) + (RemainSSmIo / 4U));
/*sdrv_xtrg_sse5_enable(&xtrg_dev, &sse5_config_0, true);*/
sdrv_xtrg_sse5_config(&xtrg_dev, &sse5_config_0, true);
/* xtrg-etimer mux config */
xtrg_config.sig_i = SSIG((uint8_t)((8U * timer_module) + (RemainSSmIo / 4U)));
xtrg_config.sig_o = ETIMER_CPT0(timer_module, (2U * (RemainSSmIo / 8U)));
sdrv_xtrg_smux_config(&xtrg_dev, &xtrg_config);
}
}
}
}
}
uint32_t sdrv_etimer_GetInterrupt(uint8_t eModule)
{
return readl(ICU_INT_STA_ADDR32(eModule));
}
void sdrv_etimer_ClearInterrupt(uint8_t eModule, uint8_t Position)
{
writel( 1UL << Position, ICU_INT_STA_ADDR32(eModule));
/* Delay a while unitl setting be synced */
uint32_t i = readl(ICU_LOCAL_CNT(eModule, Position));
/* Delay a while unitl setting be synced */
while (readl(ICU_LOCAL_CNT(eModule, Position)) == i) {
/*wait*/
};
}
bool sdrv_etimer_CheckFifoSta(uint8_t eModule, uint8_t Position)
{
bool errStatus = false;
uint32_t FifoSta = readl(ICU_FIFO_STA(eModule));
uint32_t FifoErr = (FifoSta >> ((8u * Position) + 7u)) & 0x1u;
if (FifoErr > 0) {
/* fifo frror generate : clear fifo */
uint32_t FifoEntry = (FifoSta >> ((8u * Position) + 2u)) & 0x1fu;
for (uint8_t i = 0; i < FifoEntry; i++) {
readl(ICU_FIFO_ADDR32(eModule, Position));
}
errStatus = true;
}
return errStatus;
}
uint32_t sdrv_etimer_GetFifoVal(uint8_t TimerModule, uint8_t Channel)
{
uint32_t value = (uint32_t)0u;
value = readl(ICU_FIFO_ADDR32(TimerModule, Channel));
return value;
}
/*中断触发方式*/
static int sdrv_etimer_multicpt_irq_handle(uint32_t irq, void *arg)
{
uint8_t timer_module = 0u;
uint8_t MultiCptChanNum = 0u;
uint32_t Irq_Status = 0u; /*中断状态*/
uint32_t Chn_B_Val = 0u; /*capture b 的值 电平的值*/
uint32_t Chn_C_Val = 0u; /*capture c 的值 时间搓的值*/
uint8_t Channel_B = 1u;
uint8_t Channel_C = 2u;
static uint32_t pre_iochange[MULTI_CPT_MODULE_NUM] = {0u, 0u};
static uint32_t last_stamp[MULTI_CPT_MODULE_NUM][MULTI_CPT_MAX_IO_NUM] = {0};
uint32_t IoChange[MULTI_CPT_MODULE_NUM] = {0u, 0u};
uint32_t curr_stamp[MULTI_CPT_MODULE_NUM][MULTI_CPT_MAX_IO_NUM] = {0};
sdrv_multicpt_edge_change_type edge_type;
uint32_t time_cost = 0u;
sdrv_multicpt_config *pmulticpt_config = NULL;
pmulticpt_config = (sdrv_multicpt_config *)arg;
timer_module = (uint8_t)pmulticpt_config->u8TimerModule;
MultiCptChanNum = (uint8_t)pmulticpt_config->u8MultiCptChannum;
Irq_Status = sdrv_etimer_GetInterrupt(timer_module);
if (Irq_Status & (0x1 << Channel_C)) {
/* clear interrupt */
sdrv_etimer_ClearInterrupt(timer_module, Channel_C);
/* check chan b if fifo has error generate */
bool fifoErrChnb = sdrv_etimer_CheckFifoSta(timer_module, Channel_B);
/* check chan c if fifo has error generate */
bool fifoErrChnc = sdrv_etimer_CheckFifoSta(timer_module, Channel_C);
if (fifoErrChnb || fifoErrChnc) {
return -1;
}
Chn_B_Val = sdrv_etimer_GetFifoVal(timer_module, Channel_B);
Chn_C_Val = sdrv_etimer_GetFifoVal(timer_module, Channel_C);
}
IoChange[timer_module] = Chn_B_Val ^ pre_iochange[timer_module];
/*ssdk_printf(SSDK_ERR, "%u\n", unIoChange[TimerModule]);*/
for (uint8_t IoIdx = 0; IoIdx < MultiCptChanNum; IoIdx++) {
/*表示当前IoIdx通道未开启输入捕获的功能*/
if (g_multicpt_channel_enable[timer_module][IoIdx] == false)
continue;
bool IoEdgeChange = (IoChange[timer_module] & (0x1u << IoIdx)) ? true : false;
/*判断IO是否有电平变化*/
if (IoEdgeChange == true) {
/*判断边沿触发类型*/
if (((pre_iochange[timer_module] >> IoIdx) & 0x1u) == 0) {
edge_type = MULTI_CPT_RISING_EDGE;
}
else {
edge_type = MULTI_CPT_FALLING_EDGE;
}
curr_stamp[timer_module][IoIdx] = Chn_C_Val;
if (Chn_C_Val < last_stamp[timer_module][IoIdx]) {
time_cost = (0xFFFFFFFFU - last_stamp[timer_module][IoIdx]) + Chn_C_Val;
}
else {
time_cost = Chn_C_Val - last_stamp[timer_module][IoIdx];
}
ssdk_printf(SSDK_ERR, "timer:%u CPTB=%u ch=%u timecost=%u stamp=%u type=%u\n", timer_module,
Chn_B_Val, IoIdx, time_cost, curr_stamp[timer_module][IoIdx], edge_type);
last_stamp[timer_module][IoIdx] = curr_stamp[timer_module][IoIdx];
}
}
pre_iochange[timer_module] = Chn_B_Val;
//ssdk_printf(SSDK_ERR, "sdrv_etimer_multicpt_irq_handle\n");
return 0;
}
/*DMA触发方式*/
static void sdrv_etimer_multicpt_dma_irq_handler(uint32_t status, uint32_t param, void *Arg)
{
sdrv_multicpt_config *pmulticpt_config = (sdrv_multicpt_config *)Arg;
static uint32_t pre_iochange[MULTI_CPT_MODULE_NUM] = {0u, 0u};
static uint32_t last_stamp[MULTI_CPT_MODULE_NUM][MULTI_CPT_MAX_IO_NUM] = {0};
uint32_t IoChange[MULTI_CPT_MODULE_NUM] = {0u, 0u};
uint32_t curr_stamp[MULTI_CPT_MODULE_NUM][MULTI_CPT_MAX_IO_NUM] = {0};
sdrv_multicpt_edge_change_type edge_type;
uint32_t time_cost = 0u;
uint8_t timer_module = (uint8_t)pmulticpt_config->u8TimerModule;
uint8_t multicpt_chan_num = (uint8_t)pmulticpt_config->u8MultiCptChannum;
if ((status != SDRV_DMA_BLOCK_DONE) && (status != SDRV_DMA_PENDING)) {
return;
}
/*刷新Capture_B 和 Capture_C的数据*/
arch_invalidate_cache_range((addr_t)(&ICU_MULTI_CPT_B_BUFFER[timer_module][0]),
MULTI_CPT_BURST_LEN * SDRV_DMA_BUSWIDTH_4_BYTES);
arch_invalidate_cache_range((addr_t)(&ICU_MULTI_CPT_C_BUFFER[timer_module][0]),
MULTI_CPT_BURST_LEN * SDRV_DMA_BUSWIDTH_4_BYTES);
IoChange[timer_module] = ICU_MULTI_CPT_B_BUFFER[timer_module][0] ^ pre_iochange[timer_module];
/*ssdk_printf(SSDK_ERR, "%u\n", unIoChange[TimerModule]);*/
for (uint8_t IoIdx = 0; IoIdx < multicpt_chan_num; IoIdx++) {
/*表示当前IoIdx通道未开启输入捕获的功能*/
if (g_multicpt_channel_enable[timer_module][IoIdx] == false)
continue;
bool IoEdgeChange = (IoChange[timer_module] & (0x1u << IoIdx)) ? true : false;
/*判断IO是否有电平变化*/
if (IoEdgeChange == true) {
/*判断边沿触发类型*/
if (((pre_iochange[timer_module] >> IoIdx) & 0x1u) == 0) {
edge_type = MULTI_CPT_RISING_EDGE;
}
else {
edge_type = MULTI_CPT_FALLING_EDGE;
}
curr_stamp[timer_module][IoIdx] = ICU_MULTI_CPT_C_BUFFER[timer_module][0];
if (ICU_MULTI_CPT_C_BUFFER[timer_module][0] < last_stamp[timer_module][IoIdx]) {
time_cost = (0xFFFFFFFFU - last_stamp[timer_module][IoIdx]) +
ICU_MULTI_CPT_C_BUFFER[timer_module][0];
}
else {
time_cost = ICU_MULTI_CPT_C_BUFFER[timer_module][0] - last_stamp[timer_module][IoIdx];
}
ssdk_printf(SSDK_ERR, "timer:%u CPTB=%u ch=%u timecost=%u stamp=%u type=%u\n", timer_module,
ICU_MULTI_CPT_B_BUFFER[timer_module][0], IoIdx, time_cost, curr_stamp[timer_module][IoIdx],
edge_type);
last_stamp[timer_module][IoIdx] = curr_stamp[timer_module][IoIdx];
}
}
pre_iochange[timer_module] = ICU_MULTI_CPT_B_BUFFER[timer_module][0];
}
/**
* @brief sdrv_etimer_multicpt_dma_config
* @details set multi cpt dma config.
* @param[in] pstMultiCptConfig const channel config .
* @implements sdrv_etimer_multicpt_dma_config
* @return none
*/
void sdrv_etimer_multicpt_dma_config(sdrv_multicpt_config *pmulticpt_config)
{
/*etimer1 module use DMA channel 0 and channel 1*/
/*etimer2 module use DMA channel 2 and channel 3*/
static uint8_t first_flag = true;
uint8_t timer_module = 0u;
timer_module = (uint8_t)pmulticpt_config->u8TimerModule;
/*************************** timer channel B start ****************************/
if (first_flag) {
first_flag = false;
/* init dma controller (only one time) */
sdrv_dma_init_dmac(APB_DMA_SF0_BASE);
}
sdrv_dma_channel_config_t xfer_config;
/* 1.create dma instance */
sdrv_dma_create_instance(&g_dma_instance[2 * timer_module], APB_DMA_SF0_BASE);
/* 2.get default config */
sdrv_dma_init_channel_config(&xfer_config, &g_dma_instance[2 * timer_module]);
/* 3.modify config param */
xfer_config.channel_id = (sdrv_dma_channel_id_e)((2 * timer_module) +
SDRV_DMA_CHANNEL_0); /* select channel */
xfer_config.xfer_type =
SDRV_DMA_DIR_DEV2MEM; /* mem2mem or mem2dev or dev2mem */
xfer_config.xfer_mode =
SDRV_DMA_TRANSFER_MODE_CONTINUOUS; /* single or continuous or linklist*/
xfer_config.src_inc =
SDRV_DMA_ADDR_NO_INC; /* source address increase or not */
xfer_config.dst_inc =
SDRV_DMA_ADDR_INC; /* destination address increase or not */
xfer_config.src_width = SDRV_DMA_BUSWIDTH_4_BYTES; /* source address width */
xfer_config.dst_width =
SDRV_DMA_BUSWIDTH_4_BYTES; /* destination address width */
xfer_config.src_burst_len =
MULTI_CPT_DMA_BURST_LEN; /* source burst_length (transfer level) */
xfer_config.dst_burst_len = MULTI_CPT_DMA_BURST_LEN; /* source burst_length */
xfer_config.loop_mode =
SDRV_DMA_LOOP_MODE_1; /* mem2mem(MODE_0) mem2dev/dev2mem(MODE_1) */
xfer_config.buffer_mode = SDRV_DMA_CIRCULAR_BUFFER;
xfer_config.src_port_sel =
SDRV_DMA_PORT_AHB32; /* periph -> SDRV_DMA_PORT_AHB32 */
xfer_config.dst_port_sel = SDRV_DMA_PORT_AXI64;
xfer_config.interrupt_type = SDRV_DMA_EVERY_MAD_DONE; /* set interrupt type */
xfer_config.trig_mode = SDRV_DMA_TRIGGER_BY_HARDWARE; /* by hardware trig */
xfer_config.src_addr = ETMR_BASE[timer_module] + ETMR_FIFO_OFF(1); /* FIFO B*/
xfer_config.dst_addr = (paddr_t)(&ICU_MULTI_CPT_B_BUFFER[timer_module][0]);
xfer_config.xfer_bytes = MULTI_CPT_BURST_LEN * sizeof(uint32_t); /* transaction bytes */
/* 4.init channel config */
sdrv_dma_init_channel(&g_channel[2 * timer_module], &xfer_config);
/* 5.set interrupt callback */
g_channel[2 * timer_module].irq_callback = NULL;
g_channel[2 * timer_module].irq_context = NULL;
/* 6.start channel transfer */
sdrv_dma_start_channel_xfer(&g_channel[2 * timer_module]);
/*************************** timer channel C start ****************************/
sdrv_dma_channel_config_t xfer_config2;
/* 1.create dma instance */
sdrv_dma_create_instance(&g_dma_instance[2 * timer_module + 1], APB_DMA_SF0_BASE);
/* 2.get default config */
sdrv_dma_init_channel_config(&xfer_config2, &g_dma_instance[2 * timer_module + 1]);
/* 3.modify config param */
xfer_config2.channel_id = (sdrv_dma_channel_id_e)((2 * timer_module) +
SDRV_DMA_CHANNEL_1); /* select channel */
xfer_config2.xfer_type =
SDRV_DMA_DIR_DEV2MEM; /* mem2mem or mem2dev or dev2mem */
xfer_config2.xfer_mode =
SDRV_DMA_TRANSFER_MODE_CONTINUOUS; /* single or continuous or linklist*/
xfer_config2.src_inc =
SDRV_DMA_ADDR_NO_INC; /* source address increase or not */
xfer_config2.dst_inc =
SDRV_DMA_ADDR_INC; /* destination address increase or not */
xfer_config2.src_width = SDRV_DMA_BUSWIDTH_4_BYTES; /* source address width */
xfer_config2.dst_width =
SDRV_DMA_BUSWIDTH_4_BYTES; /* destination address width */
xfer_config2.src_burst_len =
MULTI_CPT_DMA_BURST_LEN; /* source burst_length (transfer level) */
xfer_config2.dst_burst_len = MULTI_CPT_DMA_BURST_LEN; /* source burst_length */
xfer_config2.loop_mode =
SDRV_DMA_LOOP_MODE_1; /* mem2mem(MODE_0) mem2dev/dev2mem(MODE_1) */
xfer_config2.buffer_mode = SDRV_DMA_CIRCULAR_BUFFER;
xfer_config2.src_port_sel =
SDRV_DMA_PORT_AHB32; /* periph -> SDRV_DMA_PORT_AHB32 */
xfer_config2.dst_port_sel = SDRV_DMA_PORT_AXI64;
xfer_config2.interrupt_type = SDRV_DMA_EVERY_MAD_DONE; /* set interrupt type */
xfer_config2.trig_mode = SDRV_DMA_TRIGGER_BY_HARDWARE; /* by hardware trig */
xfer_config2.src_addr = ETMR_BASE[timer_module] + ETMR_FIFO_OFF(2); /* FIFO C*/
xfer_config2.dst_addr = (paddr_t)(&ICU_MULTI_CPT_C_BUFFER[timer_module][0]);
xfer_config2.xfer_bytes = MULTI_CPT_BURST_LEN * sizeof(uint32_t); /* transaction bytes */
/* 4.init channel config */
sdrv_dma_init_channel(&g_channel[2 * timer_module + 1], &xfer_config2);
/* 5.set interrupt callback */
g_channel[2 * timer_module + 1].irq_callback = sdrv_etimer_multicpt_dma_irq_handler;
g_channel[2 * timer_module + 1].irq_context = (void *)pmulticpt_config;
/* 6.start channel transfer */
sdrv_dma_start_channel_xfer(&g_channel[2 * timer_module + 1]);
}
/**
* @brief sdrv_etimer_multicpt_dma_req_config
* @details set multi cpt etimer dma reg config.
* @param[in] timer selected etimer module.
* @param[in] waterlevel dma water level.
* @implements sdrv_etimer_multicpt_dma_req_config
* @return none
*/
void sdrv_etimer_multicpt_dma_req_config(uint8_t timer_module, bool intMode, uint8_t waterlevel)
{
if (intMode == false) {
/* set fifo wml */
uint32_t Chn_Wml = readl(ICU_CHN_DMA_WML(timer_module));
/* set fifo b wml */
Chn_Wml &= ~ICU_FM_DMA_WML_CHN(1);
Chn_Wml |= ICU_FV_DMA_WML_CHN(waterlevel, 1); /*set fifo b dma water level*/
/* set fifo c wml */
Chn_Wml &= ~ICU_FM_DMA_WML_CHN(2);
Chn_Wml |= ICU_FV_DMA_WML_CHN(waterlevel, 2); /*set fifo c dma water level*/
writel(Chn_Wml, ICU_CHN_DMA_WML(timer_module));
}
/* clear fifo */
uint32_t FifoSta = readl(ICU_FIFO_STA(timer_module));
/* clear fifo b */
for (uint8_t i = 0; i < ((FifoSta >> ((8U * 1U) + 2U)) & 0x1fU); i++) {
readl(ICU_FIFO_ADDR32(timer_module, 1));
}
/* clear fifo c */
for (uint8_t i = 0; i < ((FifoSta >> ((8U * 2U) + 2U)) & 0x1fU); i++) {
readl(ICU_FIFO_ADDR32(timer_module, 2));
}
/* select the dma block */
uint32_t Dma_Ctrl = readl(ICU_CHN_DMA_CTRL(timer_module));
/* enable dma channel b */
Dma_Ctrl |= ICU_BM_CHN_DMA_CTRL_CHN_EN(1);
/* set channel b dma block as capture */
Dma_Ctrl |= ICU_FV_CHN_DMA_CTRL_CHN_SEL(1, 1);
/* enable dma channel c */
Dma_Ctrl |= ICU_BM_CHN_DMA_CTRL_CHN_EN(2);
/* set channel c dma block as capture */
Dma_Ctrl |= ICU_FV_CHN_DMA_CTRL_CHN_SEL(1, 2);
writel(Dma_Ctrl, ICU_CHN_DMA_CTRL(timer_module));
}
/**
* @brief sdrv_etimer_multicpt_sse_config
* @details set multi cpt etimer sse config.
* @param[in] timer selected etimer module .
* @implements sdrv_etimer_multicpt_sse_config
* @return none
*/
void sdrv_etimer_multicpt_sse_config(uint8_t timer_module)
{
/* set cpt b sse */
/* sse b reg : cpt_a0 | cpt_b0 | cpt_c0 | cpt_d0*/
uint32_t Sse_Reg = 0xFFFEFFFEU;
writel(Sse_Reg, ICU_CPT_SSE_REG_OFF(timer_module, 1));
uint32_t Sse_Ctrl = readl(ICU_CPT_SSE_CTRL_OFF(timer_module, 1));
Sse_Ctrl &= ~ICU_FM_CPT_SSE_CTRL_SSE_MODE;
/* set cpt b sse1-sse5 mode : all edge mode */
Sse_Ctrl |= ICU_FV_CPT_SSE_CTRL_SSE_MODE(0x1F);
Sse_Ctrl &= ~ICU_FM_CPT_SSE_CTRL_EDGE_SEL;
/* set cpt b sse1-sse5 edge mode : rising edge */
Sse_Ctrl |= ICU_FV_CPT_SSE_CTRL_EDGE_SEL(0x0);
/* sse cpt b enable */
Sse_Ctrl |= ICU_BM_CPT_SSE_CTRL_SSE_EN;
writel(Sse_Ctrl, ICU_CPT_SSE_CTRL_OFF(timer_module, 1));
/* set cpt c sse */
/* sse c reg : cpt_a0 | cpt_b0 | cpt_c0 | cpt_d0*/
Sse_Reg = 0xFFFEFFFE;
writel(Sse_Reg, ICU_CPT_SSE_REG_OFF(timer_module, 2));
Sse_Ctrl = readl(ICU_CPT_SSE_CTRL_OFF(timer_module, 2));
Sse_Ctrl &= ~ICU_FM_CPT_SSE_CTRL_SSE_MODE;
/* set cpt c sse1-sse5 mode : all edge mode */
Sse_Ctrl |= ICU_FV_CPT_SSE_CTRL_SSE_MODE(0x1F);
Sse_Ctrl &= ~ICU_FM_CPT_SSE_CTRL_EDGE_SEL;
/* set cpt c sse1-sse5 edge mode : rising edge */
Sse_Ctrl |= ICU_FV_CPT_SSE_CTRL_EDGE_SEL(0x0);
/* sse cpt c enable */
Sse_Ctrl |= ICU_BM_CPT_SSE_CTRL_SSE_EN;
writel(Sse_Ctrl, ICU_CPT_SSE_CTRL_OFF(timer_module, 2));
}
/**
* @brief sdrv_etimer_multicpt_module_init
* @details multi cpt channel init.
* @param[in] pmulticpt_config multi cpt channel config .
* @implements sdrv_etimer_multicpt_module_init
* @return none
*/
void sdrv_etimer_multicpt_module_init(sdrv_multicpt_config *pmulticpt_config)
{
uint8_t timer_module = (uint8_t)pmulticpt_config->u8TimerModule;
uint8_t MultiCptChanNum = (uint8_t)pmulticpt_config->u8MultiCptChannum;
/* set timer clock and predivider */
if (g_multicpt_clk_info[timer_module] == false) {
uint32_t Clk_Mon = 0u;
Clk_Mon = ICU_BM_CLK_MON_EN_CMP_SET | ICU_BM_CLK_MON_EN_EN_N;
/* disable clk mon first */
writel(Clk_Mon, ICU_CLK_MON_EN(timer_module));
/* set clk info */
uint32_t Clk_Set = 0u;
Clk_Set = ICU_FV_TIM_CLK_CONFIG_DIV_NUM(pmulticpt_config->u16Prescaler);
/* multi cpt clk select same with xtrg */
Clk_Set |= ICU_FV_TIM_CLK_CONFIG_SRC_CLK_SEL(1);
Clk_Set |= ICU_BM_TIM_CLK_CONFIG_CLK_CHANGE_UPD;
writel(Clk_Set, ICU_TIM_CLK_CONFIG(timer_module));
while (readl(ICU_TIM_CLK_CONFIG(timer_module)) & ICU_BM_TIM_CLK_CONFIG_CLK_CHANGE_UPD) {
};
Clk_Mon = ICU_BM_CLK_MON_EN_CMP_SET | ICU_BM_CLK_MON_EN_EN_P;
/* enable clk mon */
writel(Clk_Mon, ICU_CLK_MON_EN(timer_module));
g_multicpt_clk_info[timer_module] = true;
}
#ifndef CONFIG_E3L
/* set scr multi cpt mux enable */
uint32_t Scr_Cfg = readl(APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR(timer_module));
/* bit1 : mux cpt en */
Scr_Cfg |= 0x2U;
writel(Scr_Cfg, APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR(timer_module));
#else
/* set scr multi cpt mux enable */
uint32_t Scr_Cfg = readl(APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR);
Scr_Cfg |= (0x1 << timer_module);
writel(Scr_Cfg, APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR);
#endif
/* xtrg.io mux cfg */
sdrv_etimer_multicpt_xtrig_config(timer_module, MultiCptChanNum);
/*保存中断还是DMA的触发方式*/
g_multicpt_dma_enable[timer_module] = pmulticpt_config->int_en;
if (pmulticpt_config->int_en) {
/*使能中断*/
/* set etimer dma reg */
sdrv_etimer_multicpt_dma_req_config(timer_module, true, 1);
}
else {
/*使能DMA*/
/* setup multi cpt dma config */
sdrv_etimer_multicpt_dma_config(pmulticpt_config);
/* set etimer dma reg */
sdrv_etimer_multicpt_dma_req_config(timer_module, false, 1);
}
/* set etimer sse reg */
sdrv_etimer_multicpt_sse_config(timer_module);
/* set local counter c ovf value 0xffffffff */
writel(0xFFFFFFFF, ICU_LOCAL_CNT_OVF_VAL(timer_module, 2));
RMWREG32(ICU_LOCAL_CNT_CFG(timer_module, 2), ICU_CNT_CFG_OVF_UPD_START_BIT, 1u, 1u);
uint32_t PollTime = 0u;
while (readl(ICU_LOCAL_CNT_CFG(timer_module, 2)) & (1 << ICU_CNT_CFG_OVF_UPD_START_BIT)) {
/* prevent system hang */
if (PollTime > 1000u) {
break;
}
PollTime ++;
}
/* enable timer local counter c */
writel(1, ICU_LOCAL_CNT_EN(timer_module, 2));
/* set cpt config */
/* Set the cpt b triggered edge : for multi cpt , 3 means multi cpt level mode */
RMWREG32(ICU_CPT_CONFIG(timer_module, 1), ICU_CPT_CONFIG_CPT0_TRIG_MODE_START_BIT, 2u, 3);
/* set the local timer as cpt b counter */
RMWREG32(ICU_CPT_CONFIG(timer_module, 1), ICU_CPT_CONFIG_CNT_SEL_START_BIT, 2u,
2u); /*select local count*/
RMWREG32(ICU_CPT_CTRL(timer_module), ICU_CPT_CTRL_CPT_CONFIG_SET_START_BIT(1), 1u,
1u); /*Enable capture B channel*/
/* Set the cpt c triggered edge : for multi cpt , 3 means multi cpt level mode */
RMWREG32(ICU_CPT_CONFIG(timer_module, 2), ICU_CPT_CONFIG_CPT0_TRIG_MODE_START_BIT, 2u, 3);
/* set the local timer as cpt c counter */
RMWREG32(ICU_CPT_CONFIG(timer_module, 2), ICU_CPT_CONFIG_CNT_SEL_START_BIT, 2u,
2u); /*select local count*/
RMWREG32(ICU_CPT_CTRL(timer_module), ICU_CPT_CTRL_CPT_CONFIG_SET_START_BIT(2), 1u,
1u); /*Enable capture C channel*/
if (pmulticpt_config->irq > 0u) {
irq_attach(pmulticpt_config->irq, sdrv_etimer_multicpt_irq_handle, pmulticpt_config);
irq_enable(pmulticpt_config->irq);
}
}
/**
* @brief sdrv_etimer_multicpt_free_dma
* @details stop multi capture dma transfer.
* @param[in] TimerModule selected etimer module .
* @implements sdrv_etimer_multicpt_free_dma
* @return none
*/
void sdrv_etimer_multicpt_free_dma(uint8_t timer_module)
{
if (g_channel[2 * timer_module].dma != NULL) {
/*stop cpt b dma*/
sdrv_dma_stop_channel_xfer(&g_channel[2 * timer_module]);
g_channel[2 * timer_module].dma = NULL;
}
if (g_channel[2 * timer_module + 1].dma != NULL) {
/*stop cpt c dma*/
sdrv_dma_stop_channel_xfer(&g_channel[2 * timer_module + 1]);
g_channel[2 * timer_module + 1].dma = NULL;
}
}
/**
* @brief sdrv_etimer_multicpt_turnon_capture
* @details turn on etimer multi cpt.
* @param[in] timer_module selected etimer module .
* @implements sdrv_etimer_multicpt_turnon_capture
* @return none
*/
static void sdrv_etimer_multicpt_turnon_capture(uint8_t timer_module, bool intMode)
{
/* bit1 cpt b en bit2 : cpt c en */
uint32_t MultiCptEn = readl(ICU_CPT_CTRL(timer_module));
MultiCptEn |= 0x6U; /*enable capture b and capture c*/
uint32_t cpt_ctrl = ICU_CPT_CTRL(timer_module);
writel(MultiCptEn, cpt_ctrl);
if (intMode) {
/* Turn on channel C Capture interrupt */
RMWREG32(ICU_INT_STA_EN_ADDR32(timer_module), 2, 1u, 1u);
RMWREG32(ICU_INT_SIG_EN_ADDR32(timer_module), 2, 1u, 1u);
}
}
/**
* @brief sdrv_etimer_multicpt_turnoff_capture
* @details turn off etimer multi cpt.
* @param[in] timer_module selected etimer module .
* @implements sdrv_etimer_multicpt_turnoff_capture
* @return none
*/
static void sdrv_etimer_multicpt_turnoff_capture(uint8_t timer_module, bool intMode)
{
/* bit1 cpt b en bit2 : cpt c en */
uint32_t MultiCptEn = readl(ICU_CPT_CTRL(timer_module));
MultiCptEn &= ~0x6u; /*disable capture b and capture c*/
uint32_t cpt_ctrl = ICU_CPT_CTRL(timer_module);
writel(MultiCptEn, cpt_ctrl);
if (intMode) {
/* Turn off channel C Capture interrupt */
RMWREG32(ICU_INT_STA_EN_ADDR32(timer_module), 2, 1u, 0u);
RMWREG32(ICU_INT_SIG_EN_ADDR32(timer_module), 2, 1u, 0u);
}
/* clear fifo */
uint32_t FifoSta = readl(ICU_FIFO_STA(timer_module));
uint32_t fifoEntry = (FifoSta >> ((8U * 1U) + 2U)) & 0x1fU;
/* clear fifo b */
for (uint8_t i = 0; i < fifoEntry; i++) {
readl(ICU_FIFO_ADDR32(timer_module, 1));
}
fifoEntry = (FifoSta >> ((8U * 2U) + 2U)) & 0x1fU;
/* clear fifo c */
for (uint8_t i = 0; i < fifoEntry; i++) {
readl(ICU_FIFO_ADDR32(timer_module, 2));
}
}
/**
* @brief sdrv_etimer_multicpt_module_deinit
* @details multi cpt channel deinit.
* @param[in] timer_module selected etimer module.
* @implements sdrv_etimer_multicpt_module_deinit
* @return none
*/
void sdrv_etimer_multicpt_module_deinit(uint8_t timer_module)
{
#ifndef CONFIG_E3L
/* disable set scr multi cpt mux */
uint32_t Scr_Cfg = readl(APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR(timer_module));
/* bit1 : mux cpt en */
Scr_Cfg &= ~0x2;
writel(Scr_Cfg, APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR(timer_module));
#else
/* disable set scr multi cpt mux */
uint32_t Scr_Cfg = readl(APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR);
Scr_Cfg &= ~(0x1 << timer_module);
writel(Scr_Cfg, APB_SCR_SF_BASE + ICU_MULTI_ETMR_SCR_CFG_ADDR);
#endif
if (g_multicpt_dma_enable[timer_module] == false) {
/*表示当前是DMA方式*/
/* setup multi cpt dma config */
sdrv_etimer_multicpt_free_dma(timer_module);
}
/* select the dma block */
uint32_t Dma_Ctrl = readl(ICU_CHN_DMA_CTRL(timer_module));
/* disable dma channel b */
Dma_Ctrl &= ~ ICU_BM_CHN_DMA_CTRL_CHN_EN(1);
/* disable dma channel c */
Dma_Ctrl &= ~ ICU_BM_CHN_DMA_CTRL_CHN_EN(2);
writel(Dma_Ctrl, ICU_CHN_DMA_CTRL(timer_module));
/* disable sse b */
uint32_t Sse_Ctrl = readl(ICU_CPT_SSE_CTRL_OFF(timer_module, 1));
Sse_Ctrl &= ~ICU_BM_CPT_SSE_CTRL_SSE_EN;
writel(Sse_Ctrl, ICU_CPT_SSE_REG_OFF(timer_module, 1));
/* disable sse c */
Sse_Ctrl = readl(ICU_CPT_SSE_CTRL_OFF(timer_module, 2));
Sse_Ctrl &= ~ICU_BM_CPT_SSE_CTRL_SSE_EN;
writel(Sse_Ctrl, ICU_CPT_SSE_REG_OFF(timer_module, 2));
if (g_multicpt_dma_enable[timer_module] == false) {
/*表示当前是DMA方式*/
/* turn off capture module */
sdrv_etimer_multicpt_turnoff_capture(timer_module, false);
}
else {
/*表示当前是中断方式*/
/* turn off capture module */
sdrv_etimer_multicpt_turnoff_capture(timer_module, true);
}
/* disable timer local counter c */
writel(0, ICU_LOCAL_CNT_EN(timer_module, 2));
g_multicpt_clk_info[timer_module] = false;
}
/**
* @brief sdrv_etimer_multicpt_init
* @details multi cpt init.
* @implements sdrv_etimer_multicpt_init
* @return none
*/
void sdrv_etimer_multicpt_init(void)
{
if (sdrv_get_chip_version() == 0x1U) {
sdrv_etimer_multicpt_set_base_addr();
memset(ICU_MULTI_CPT_B_BUFFER, 0, sizeof(ICU_MULTI_CPT_B_BUFFER));
memset(ICU_MULTI_CPT_C_BUFFER, 0, sizeof(ICU_MULTI_CPT_C_BUFFER));
memset(g_multicpt_clk_info, 0, sizeof(g_multicpt_clk_info));
memset(g_multicpt_timer_enable, 0, sizeof(g_multicpt_timer_enable));
memset(g_multicpt_dma_enable, 0, sizeof(g_multicpt_dma_enable));
memset(g_multicpt_channel_enable, 0, sizeof(g_multicpt_channel_enable));
memset(g_dma_instance, 0, sizeof(g_dma_instance));
memset(g_channel, 0, sizeof(g_channel));
}
else {
ssdk_printf(SSDK_ERR, "sdrv_etimer_multicpt_init sdrv_get_chip_version err\n");
}
}
/**
* @brief sdrv_etimer_multicpt_channel_start_capture
* @details multi cpt channel start capture.
* @param[in] timer_module selected etimer module.
* @param[in] channel selected etimer channel.
* @implements sdrv_etimer_multicpt_channel_start_capture
* @return none
*/
void sdrv_etimer_multicpt_channel_start_capture(uint8_t timer_module, uint8_t channel)
{
if ((timer_module >= MULTI_CPT_MODULE_NUM) || (channel >= MULTI_CPT_MAX_IO_NUM))
return;
if (sdrv_get_chip_version() == 0x1U) {
g_multicpt_channel_enable[timer_module][channel] = true;
if (g_multicpt_timer_enable[timer_module] == false) {
g_multicpt_timer_enable[timer_module] = true;
if (g_multicpt_dma_enable[timer_module] == false) {
/*表示当前是DMA方式*/
sdrv_etimer_multicpt_turnon_capture(timer_module, false);
}
else {
/*表示当前是中断方式*/
sdrv_etimer_multicpt_turnon_capture(timer_module, true);
}
}
}
else {
ssdk_printf(SSDK_ERR, "sdrv_etimer_multicpt_channel_start_capture sdrv_get_chip_version err\n");
}
}
/**
* @brief sdrv_etimer_multicpt_channel_stop_capture
* @details multi cpt channel stop capture.
* @param[in] timer_module selected etimer module.
* @param[in] channel selected etimer channel.
* @implements sdrv_etimer_multicpt_channel_stop_capture
* @return none
*/
void sdrv_etimer_multicpt_channel_stop_capture(uint8_t timer_module, uint8_t channel)
{
if ((timer_module >= MULTI_CPT_MODULE_NUM) || (channel >= MULTI_CPT_MAX_IO_NUM))
return;
if (sdrv_get_chip_version() == 0x1U) {
g_multicpt_channel_enable[timer_module][channel] = false;
}
else {
ssdk_printf(SSDK_ERR, "sdrv_etimer_multicpt_channel_stop_capture sdrv_get_chip_version err\n");
}
}