TI中文支持网
TI专业的中文技术问题搜集分享网站

TDA4VM: 复用mcu timer做捕捉器,有误触发问题

Part Number:TDA4VM

          我复用mcu timer[4:9]做捕捉器,对MCU_TIMER_IO[0:9]分时捕捉。 启动捕捉时,首先切换TIMER IO, 后使能定时器捕捉。 一段时间后,关闭timer捕捉,读取数值。

但发现,尽管输入信号无变化,每次启动一次捕捉,总有1到2个数据采集到。

这是什么原因,正确的操作流程应该是怎样的,要注意哪些操作?

Cherry Zhou:

您好我们已收到您的问题并升级到英文论坛,如有答复将尽快回复您。谢谢!

,

Cherry Zhou:

您好,请问您的usecase是什么?

Qingyu Zhuang 说:尽管输入信号无变化,

以及您这里说的输入信号是什么?

,

Qingyu Zhuang:

我这是我们自动泊车项目。用捕捉功能做超声波雷达。

,

Cherry Zhou:

好的感谢您提供的信息,请问下输入信号是哪里的输入信号呢?

,

Qingyu Zhuang:

输入信号在10个mcu_timer_io

,

Cherry Zhou:

Qingyu Zhuang 说:  我复用mcu timer[4:9]做捕捉器,对MCU_TIMER_IO[0:9]分时捕捉。 启动捕捉时,首先切换TIMER IO, 后使能定时器捕捉。

您好,这里的捕捉器是什么意义?这些定时器是怎么使用的?

,

Qingyu Zhuang:

这里的捕捉器,就是AUTOSAR的ICU,输入捕捉单元。

目前使用mcu_timer[4:9],以timerIO为纲复用这些定时器。

Icu_StartTimestamp时,从空闲的mcu_timer列表中,分配一个给启动的IO;Icu_StopTimestamp时,停止硬件后,把对应的mcu_timer回收到空闲列表。

,

Cherry Zhou:

您好,请问您用的是SDK中的计时器吗?如果是的话,您能否告知一下SDK版本,以及SDK示例/驱动程序?

,

Qingyu Zhuang:

sdk:    ti-processor-sdk-rtos-j721e-evm-08_00_00_12os:    freertos

SDK示例: mcusw/mcuss_demos/profiling/can

,

Cherry Zhou:

您好,您使用哪些 ICU (ECAP) 进行捕获? ICU 驱动程序目前支持 3 个 ECAP 模块。 您的输入看起来比 ICU 多,这就是为什么您将不同的定时器模块多路复用到 ICU 的原因?

Qingyu Zhuang 说:

目前使用mcu_timer[4:9],以timerIO为纲复用这些定时器。

Icu_StartTimestamp时,从空闲的mcu_timer列表中,分配一个给启动的IO;Icu_StopTimestamp时,停止硬件后,把对应的mcu_timer回收到空闲列表。

在该示例中,您提到在定时器未运行时,您看到 1-2 个数据捕获。 代码是怎样的?

当您启动 ICM_StartTimestamp() 时,使用 "tiperIO" 将其中一个计时器分配给 ECAP 模块,您能详细说下这个硬件是什么吗?

此外您能否分享下您的参考代码,以便我们更好地了解 ICU 驱动程序的用法?

,

Qingyu Zhuang:

的确,原生ECAP只有三路,而我们需要12路。MCU这边暂时做10路。这10路完全用mcu_timer硬件捕捉。根ECAP没有关系。源码如下:

#define MULTIPLEX_ICU_TIMERS#define MCU_TIMER0_BASE     (0x40400000UL)#define ICU_BASE_TIMER0        (0x02400000UL)#define ICU_BASE_TIMER1        (0x02410000UL)#define ICU_BASE_TIMER2        (0x02420000UL)#define ICU_BASE_TIMER3        (0x02430000UL)#define ICU_BASE_TIMER4        (0x02440000UL)#define ICU_BASE_TIMER5        (0x02450000UL)#define ICU_BASE_TIMER6        (0x02460000UL)#define ICU_BASE_TIMER7        (0x02470000UL)#define ICU_BASE_TIMER8        (0x02480000UL)#define ICU_BASE_TIMER9        (0x02490000UL)#define ICU_BASE_TIMER10    (0x024A0000UL)#define ICU_BASE_TIMER11    (0x024B0000UL)#define ICU_BASE_TIMER12    (0x024C0000UL)#define ICU_BASE_TIMER13    (0x024D0000UL)#define ICU_BASE_TIMER14    (0x024E0000UL)#define ICU_BASE_TIMER15    (0x024F0000UL)#define ICU_BASE_TIMER16    (0x02500000UL)#define ICU_BASE_TIMER17    (0x02510000UL)#define ICU_BASE_TIMER18    (0x02520000UL)#define ICU_BASE_TIMER19    (0x02530000UL)#define ICU_BASE_MCU_TIMER0    (0x40400000UL)#define ICU_BASE_MCU_TIMER1    (0x40410000UL)#define ICU_BASE_MCU_TIMER2    (0x40420000UL)#define ICU_BASE_MCU_TIMER3    (0x40430000UL)#define ICU_BASE_MCU_TIMER4    (0x40440000UL)#define ICU_BASE_MCU_TIMER5    (0x40450000UL)#define ICU_BASE_MCU_TIMER6    (0x40460000UL)#define ICU_BASE_MCU_TIMER7    (0x40470000UL)#define ICU_BASE_MCU_TIMER8    (0x40480000UL)#define ICU_BASE_MCU_TIMER9    (0x40490000UL)#define MCU_TIMER0_INTR_PEND_0    (38U)#define MCU_TIMER1_INTR_PEND_0    (39U)#define MCU_TIMER2_INTR_PEND_0    (40U)#define MCU_TIMER3_INTR_PEND_0    (41U)#define MCU_TIMER4_INTR_PEND_0    (108U) #define MCU_TIMER5_INTR_PEND_0    (109U) #define MCU_TIMER6_INTR_PEND_0    (110U) #define MCU_TIMER7_INTR_PEND_0    (111U) #define MCU_TIMER8_INTR_PEND_0    (112U) #define MCU_TIMER9_INTR_PEND_0    (113U)#define TIMER0_INTR_PEND_0     (256UL)#define TIMER1_INTR_PEND_0     (257UL)#define TIMER2_INTR_PEND_0     (258UL)#define TIMER3_INTR_PEND_0     (259UL)#define TIMER4_INTR_PEND_0     (260UL)#define TIMER5_INTR_PEND_0     (261UL)#define TIMER6_INTR_PEND_0     (262UL)#define TIMER7_INTR_PEND_0     (263UL)#define TIMER8_INTR_PEND_0     (264UL)#define TIMER9_INTR_PEND_0     (265UL)#define TIMER10_INTR_PEND_0    (266UL)#define TIMER11_INTR_PEND_0    (267UL)#define TIMER12_INTR_PEND_0    (268UL)#define TIMER13_INTR_PEND_0    (269UL)#define TIMER14_INTR_PEND_0    (270UL)#define TIMER15_INTR_PEND_0    (271UL)#define TIMER16_INTR_PEND_0    (272UL)#define TIMER17_INTR_PEND_0    (273UL)#define TIMER18_INTR_PEND_0    (274UL)#define TIMER19_INTR_PEND_0    (275UL)#ifdef MULTIPLEX_ICU_TIMERS#define FIRST_ICU_TMR_IDX   (4U) /* MCU timer[0:3] used as GPT by RTOS. And here, mcu_timer[4:9] is for ICU */#define LAST_ICU_TMR_IDX    (9U) /* mcu_timer[4:9] for ICU */#define NVLDIF              (0xFFU)#define COUNT_OF_ICU_TMR    (((LAST_ICU_TMR_IDX)+1)-(FIRST_ICU_TMR_IDX))#define COUNT_OF_ICU_IO     (sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0]))#define isIcuTmrUsed(Tmr)   ((COUNT_OF_ICU_IO) > LnkIO[Tmr])#define isIoAssigned(nIO)   ((COUNT_OF_ICU_TMR) > LnkTmr[nIO])#endiftypedef struct{    uint32 baseAddress;    uint32 ClockRegister;    uint32 PadConfigRegister;    uint32 PadConfigVal;    uint32 TimerControllRegster;    uint32 TimerIoControllRegister;    uint32 MmrVal;    uint32 Vector;}tIcuePinmuxInfo;static const tIcuePinmuxInfo IcuTmrInfo[] = {    [0] = {    .baseAddress =             ICU_BASE_MCU_TIMER0,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER0_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG21),    .PadConfigVal =            0x00050002UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER0_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO0_CTRL),    .MmrVal =                  0x0UL,    .Vector =                  MCU_TIMER0_INTR_PEND_0,    },    [1] = {    .baseAddress =             ICU_BASE_MCU_TIMER1,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER1_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG55),    .PadConfigVal =            0x00050004UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER1_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO1_CTRL),    .MmrVal =                  0x1UL,    .Vector =                  MCU_TIMER1_INTR_PEND_0,    },    [2] = {    .baseAddress =             ICU_BASE_MCU_TIMER2,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER2_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG24),    .PadConfigVal =            0x00050001UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER2_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO2_CTRL),    .MmrVal =                  0x2UL,    .Vector =                  MCU_TIMER2_INTR_PEND_0,    },    [3] = {    .baseAddress =             ICU_BASE_MCU_TIMER3,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER3_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG25),    .PadConfigVal =            0x00050001UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER3_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO3_CTRL),    .MmrVal =                  0x3UL,    .Vector =                  MCU_TIMER3_INTR_PEND_0,    },    [4] = {    .baseAddress =             ICU_BASE_MCU_TIMER4,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER4_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG30),    .PadConfigVal =            0x00050001UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER4_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO4_CTRL),    .MmrVal =                  0x4UL,    .Vector =                  MCU_TIMER4_INTR_PEND_0,    },    [5] = {    .baseAddress =             ICU_BASE_MCU_TIMER5,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER5_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG31),    .PadConfigVal =            0x00050001UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER5_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO5_CTRL),    .MmrVal =                  0x5UL,    .Vector =                  MCU_TIMER5_INTR_PEND_0,    },    [6] = {    .baseAddress =             ICU_BASE_MCU_TIMER6,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER6_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG52),    .PadConfigVal =            0x00050004UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER6_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO6_CTRL),    .MmrVal =                  0x6UL,    .Vector =                  MCU_TIMER6_INTR_PEND_0,    },    [7] = {    .baseAddress =             ICU_BASE_MCU_TIMER7,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER7_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG53),    .PadConfigVal =            0x00050004UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER7_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO7_CTRL),    .MmrVal =                  0x7UL,    .Vector =                  MCU_TIMER7_INTR_PEND_0,    },    [8] = {    .baseAddress =             ICU_BASE_MCU_TIMER8,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER8_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG60),    .PadConfigVal =            0x00050004UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER8_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO8_CTRL),    .MmrVal =                  0x8UL,    .Vector =                  MCU_TIMER8_INTR_PEND_0,    },    [9] = {    .baseAddress =             ICU_BASE_MCU_TIMER9,    .ClockRegister =           (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER9_CLKSEL),    .PadConfigRegister =       (CSL_WKUP_CTRL_MMR0_CFG0_BASE + CSL_WKUP_CTRL_MMR_CFG0_PADCONFIG61),    .PadConfigVal =            0x00050004UL,    .TimerControllRegster =    (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMER9_CTRL),    .TimerIoControllRegister = (CSL_MCU_CTRL_MMR0_CFG0_BASE + CSL_MCU_CTRL_MMR_CFG0_MCU_TIMERIO9_CTRL),    .MmrVal =                  0x9UL,    .Vector =                  MCU_TIMER9_INTR_PEND_0,    },    /*    [10] = {    .baseAddress =             ICU_BASE_TIMER0,    .ClockRegister =           (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER0_CLKSEL),    .PadConfigRegister =       (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_PADCONFIG154),    .PadConfigVal =            0x00050003UL,    .TimerControllRegster =    (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER0_CTRL),    .TimerIoControllRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMERIO0_CTRL),    .MmrVal =                  0x4UL,    .Vector =                  TIMER0_INTR_PEND_0,    },    [11] = {    .baseAddress =             ICU_BASE_TIMER1,    .ClockRegister =           (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER1_CLKSEL),    .PadConfigRegister =       (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_PADCONFIG155),    .PadConfigVal =            0x00050003UL,    .TimerControllRegster =    (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMER1_CTRL),    .TimerIoControllRegister = (CSL_CTRL_MMR0_CFG0_BASE + CSL_MAIN_CTRL_MMR_CFG0_TIMERIO1_CTRL),    .MmrVal =                  0x5UL,    .MmrVal =                  TIMER1_INTR_PEND_0,    },    */};#ifdef MULTIPLEX_ICU_TIMERSstatic uint8 LnkIO[COUNT_OF_ICU_TMR] = {NVLDIF}; /* Recored IO index */static uint8 LnkTmr[COUNT_OF_ICU_IO];#endifextern void AppUtils_Printf (uint32 type,const char *pcString, …);extern FUNC(void, ICU_CODE) IcuE_ISR(Icu_ChannelType Channel, uint32 Value);static inline int32_t IcuE_timerWaitForWrite(uint32_t reg, uint32_t baseAddr){    int32_t          retVal = CSL_PASS;    volatile uint32_t exit_count = (uint32_t) 0U;    uint32_t step_size           = (uint32_t) 1U;    if (0U != HW_RD_FIELD32(baseAddr + TIMER_TSICR, TIMER_TSICR_POSTED))    {        while ((uint32_t) 0U != (reg & TIMERWritePostedStatusGet(baseAddr)))        {             exit_count += step_size;            /* Do nothing – Busy wait,             * quit the loop if posted transations are not complete              * by one full cycle of counting             * This check and break prevents getting stuck in the loop             */             if (exit_count == 0U)             {                retVal = CSL_ETIMEOUT;                break;             }        }    }    return (retVal);}static void ICUHW_Isr(uint32 Module){    uint32 baseAddr;    uint32 status;    //AppUtils_Printf(2, "isr%d\n", Module);    if((sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0])) > Module)    {    //    SchM_Enter_Icu_ICU_EXCLUSIVE_AREA_0();        baseAddr = IcuTmrInfo[Module].baseAddress;        status = TIMERIntStatusGet(baseAddr);        #ifdef MULTIPLEX_ICU_TIMERS        if((FIRST_ICU_TMR_IDX) <= Module && (LAST_ICU_TMR_IDX) >= Module)        {            Module = LnkIO[Module – (FIRST_ICU_TMR_IDX)];        #endif        /* Wait until event detected? */        /* Read timer capture value */        if(0 != (TIMER_INT_TCAR_IT_FLAG & status))        {                            IcuE_ISR(Module, HW_RD_REG32(baseAddr + TIMER_TCAR1));        }        if(0 != (TIMER_INT_OVF_IT_FLAG & status))        {        }        if(0!= (TIMER_INT_MAT_IT_FLAG & status))        {        }        /* Clear capture interrupt request. */        TIMERIntStatusClear(baseAddr, TIMER_INT_TCAR_IT_FLAG|TIMER_INT_OVF_IT_FLAG|TIMER_INT_MAT_IT_FLAG);        #ifdef MULTIPLEX_ICU_TIMERS        }        #endif    //    SchM_Exit_Icu_ICU_EXCLUSIVE_AREA_0();    }}void ICUHW_init(uint32 nModule, Icu_ChannelConfigType* cfg){    uint32 baseAddr;    int32_t regVal;    OsalRegisterIntrParams_t intrPrms;    HwiP_Handle hwiHandle;     uint32 tmp32;    tIcuePinmuxInfo *HwInfo;    if ((sizeof(IcuTmrInfo)/sizeof(IcuTmrInfo[0])) > nModule)    {        HwInfo = (tIcuePinmuxInfo*)(&(IcuTmrInfo[nModule]));        baseAddr = HwInfo->baseAddress;#ifdef MULTIPLEX_ICU_TIMERS        LnkTmr[nModule] = NVLDIF;        if(FIRST_ICU_TMR_IDX <= nModule)        {        LnkIO[nModule-FIRST_ICU_TMR_IDX] = NVLDIF;#endif        /* Execute software reset.          TIMER_TIOCP_CFG[0] SOFTRESET    0x1    */        /* Wait until reset release?        TIMER_TIOCP_CFG[0] SOFTRESET    0x0    */        TIMERReset(baseAddr);        /* Configure idle mode. TIMER_      TIOCP_CFG[3-2] IDLEMODE         0x-    */        TIMERIdleModeConfigure(baseAddr, TIMER_SMART_IDLE);        /* Enable wake-up interrupt events. TIMER_IRQWAKEEN[2-0]            0x-    */        /* Select posted mode.              TIMER_TSICR[2] POSTED           0x-    */        /* ע\B2\E1\D6жϺ\AF\CA\FD */        Osal_RegisterInterrupt_initParams(&intrPrms);        intrPrms.corepacConfig.arg          = nModule;        intrPrms.corepacConfig.isrRoutine   = &ICUHW_Isr;        intrPrms.corepacConfig.priority     = 2U;        intrPrms.corepacConfig.corepacEventNum = 0U; /* NOT USED ? */        intrPrms.corepacConfig.intVecNum        = HwInfo->Vector;        (void)Osal_RegisterInterrupt(&intrPrms, &hwiHandle);                HW_WR_REG32(HwInfo->ClockRegister, 0x2UL/* CLK_12M_RC SPRUIL1B P1506 */);    /* Select clock */        HW_WR_REG32(baseAddr + TIMER_TIOCP_CFG, 0xAUL);        /* Initialize capture mode. See Section 12.10.3.5.2.3.2.                 */        /* Select autoreload mode.                     TIMER_TCLR[1]     AR         0x-  */        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal |= (TIMER_TCLR_AR_MASK);            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Set prescale timer value.                 TIMER_TCLR[4-2] PTV         0x-  */        tmp32 = cfg->prescaler;        if(8 <= tmp32)  {tmp32 = 7;}        else if(0 < tmp32)  {tmp32–;}        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal &= (~(TIMER_TCLR_PTV_MASK));            regVal |= (tmp32 << (TIMER_TCLR_PTV_SHIFT));            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Enable prescaler.                         TIMER_TCLR[5]     PRE         0x1  */        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal |= (TIMER_TCLR_PRE_MASK);            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Select TIMER[19-0] or MCU_TIMER[9-0]        TIMER_TCLR[14]     GPO_CFG     0x1  */        /* Capture input at device pins                                                 */        /* TIMER_IO[7-0] for TIMER[19-0] or at pins                                     */        /* MCU_TIMER_IO[9-0] for MCU_TIMER[9-0].                                        */        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal |= (TIMER_TCLR_GPO_CFG_MASK);            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Binding IO */        #ifndef MULTIPLEX_ICU_TIMERS        HW_WR_REG32(HwInfo->TimerControllRegster, HwInfo->MmrVal);        HW_WR_REG32(HwInfo->TimerIoControllRegister, HwInfo->MmrVal);        #endif        /* Select single or second event capture.    TIMER_TCLR[13]     CAPT_MODE     0x-  */        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal &= (~(TIMER_TCLR_CAPT_MODE_MASK));            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Select transition capture mode.             TIMER_TCLR[9-8] TCM         0x-  */        if(ICU_RISING_EDGE == cfg->defaultStartEdge)        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X1) << (TIMER_TCLR_TCM_SHIFT));        }        else if(ICU_FALLING_EDGE == cfg->defaultStartEdge)        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X2) << (TIMER_TCLR_TCM_SHIFT));        }        else        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X3) << (TIMER_TCLR_TCM_SHIFT));        }        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal &= (~(TIMER_TCLR_TCM_MASK));            regVal |=  tmp32;            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        /* Enable capture interrupt. TIMER_IRQSTATUS_SET[2] TCAR_EN_FLAG 0x1     */        //TIMERIntEnable(baseAddr, TIMER_INT_TCAR_EN_FLAG/*|TIMER_INT_OVF_EN_FLAG*/);        /* Start the timer. TIMER_TCLR[0] ST 0x1                                 */        //TIMEREnable(baseAddr);        /* Detect event. See Section 12.10.3.5.2.3.3.                            */        #ifdef MULTIPLEX_ICU_TIMERS        }        #endif        /* PAD work as timer IO */        HW_WR_REG32(HwInfo->PadConfigRegister, HwInfo->PadConfigVal);    }        }void ICUHW_deinit(uint32 nModule){    if(COUNT_OF_ICU_IO > nModule)    {        TIMERReset(IcuTmrInfo[nModule].baseAddress);    }}#ifdef MULTIPLEX_ICU_TIMERS/******************************************************************************* \BA\AF\CA\FD\C3\FB\B3ƣ\BAICUHW_assignTimer    *——————————————————————————* \BA\AF\CA\FD\B9\A6\C4ܣ\BAIf the module has be assigned a timer, return the timer index, oth-*              erwise assigned a timer to it* \CA\E4\C8\EB\B2\CE\CA\FD\A3\BAnModule–Hardware module* \B7\B5\BB\D8ֵ  \A3\BArelative timer index. The value 0xFFu means assignment filed.* \B1\B8    ע\A3\BA******************************************************************************/static uint8 ICUHW_assignTimer(uint32 nModule){    uint8 i = 0xFFu;    tIcuePinmuxInfo *HwInfo;    if(COUNT_OF_ICU_IO > nModule)    {        if(isIoAssigned(nModule))                          /* \B7\D6\C5\E4Ӳ\BC\FE */        {            i = LnkTmr[nModule];        }        else        {            for(i=0; i<(COUNT_OF_ICU_TMR); i++)            {                if(!isIcuTmrUsed(i))                {                    LnkIO[i] = nModule;         /* Timer link to witch IO */                    LnkTmr[nModule] = i;        /* Assigne timer */                    HwInfo = (tIcuePinmuxInfo*)&IcuTmrInfo[i + FIRST_ICU_TMR_IDX];                    HW_WR_REG32(HwInfo->TimerControllRegster, nModule);                    HW_WR_REG32(HwInfo->TimerIoControllRegister, nModule);                    break;                }            }            if(COUNT_OF_ICU_TMR <= i)                     /* \CE޿\C9\D3\C3Ӳ\BC\FE\A3\AC\B7\D6\C5\E4ʧ\B0ܣ\ACֱ\BD\D3\CD˳\F6 */            {                i = 0xFF;                AppUtils_Printf(2, " f\n");            }        }    }    return (i);}static void ICUHW_reclaimTimer(uint32 nModule){    if(COUNT_OF_ICU_IO > nModule)    {        if(isIoAssigned(nModule))        {            LnkIO[LnkTmr[nModule]] = NVLDIF;            LnkTmr[nModule] = NVLDIF;        }    }}#endifvoid IcuhW_SetActivationCondition( Icu_ChannelType nModule, Icu_ActivationType Activation ){    uint32 tmp32;    int32_t regVal;    uint32 baseAddr;    if (COUNT_OF_ICU_IO > nModule)    {        #ifdef MULTIPLEX_ICU_TIMERS        tmp32 = ICUHW_assignTimer(nModule);        if(COUNT_OF_ICU_TMR > tmp32)        {            nModule = (Icu_ChannelType)(tmp32 + (FIRST_ICU_TMR_IDX));        #endif        baseAddr = IcuTmrInfo[nModule].baseAddress;        /* Select transition capture mode.             TIMER_TCLR[9-8] TCM         0x-  */        if(ICU_RISING_EDGE == Activation)        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X1) << (TIMER_TCLR_TCM_SHIFT));        }        else if(ICU_FALLING_EDGE == Activation)        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X2) << (TIMER_TCLR_TCM_SHIFT));        }        else        {            tmp32 = ((TIMER_TCLR_TCM_TCM_VALUE_0X3) << (TIMER_TCLR_TCM_SHIFT));        }        regVal = IcuE_timerWaitForWrite(TIMER_WRITE_POST_TCLR, baseAddr);        if(CSL_PASS == regVal)        {            regVal = HW_RD_REG32(baseAddr + TIMER_TCLR);            regVal &= (~(TIMER_TCLR_TCM_MASK));            regVal |=  tmp32;            HW_WR_REG32(baseAddr + TIMER_TCLR, regVal);        }        #ifdef MULTIPLEX_ICU_TIMERS        }        #endif    }}void ICUHW_startModule(Icu_ChannelType nModule){    uint32 baseAddr;    if(COUNT_OF_ICU_IO > nModule)    {        #ifdef MULTIPLEX_ICU_TIMERS        uint8  i;        tIcuePinmuxInfo *HwInfo;        AppUtils_Printf(2, ">%d", nModule);        i = ICUHW_assignTimer(nModule);        if(COUNT_OF_ICU_TMR > i)        {            nModule = i + FIRST_ICU_TMR_IDX;        #endif        baseAddr = IcuTmrInfo[nModule].baseAddress;        HW_WR_REG32(baseAddr+TIMER_IRQSTATUS_RAW, 0UL);        HW_WR_REG32(baseAddr+TIMER_IRQSTATUS, 7UL);        /* Enable capture interrupt. TIMER_IRQSTATUS_SET[2] TCAR_EN_FLAG 0x1     */        TIMERIntEnable(baseAddr, TIMER_INT_TCAR_EN_FLAG/*|TIMER_INT_OVF_EN_FLAG*/);        /* Start the timer. TIMER_TCLR[0] ST 0x1                                 */        TIMEREnable(baseAddr);        #ifdef MULTIPLEX_ICU_TIMERS        }        #endif    }}void ICUHW_stopModule(Icu_ChannelType nModule){    uint32 baseAddr;    if(COUNT_OF_ICU_IO > nModule)    {        #ifdef MULTIPLEX_ICU_TIMERS        //AppUtils_Printf(2, "<%d", nModule);        if(isIoAssigned(nModule))        {            nModule = LnkTmr[nModule] + (FIRST_ICU_TMR_IDX);        #endif        baseAddr = IcuTmrInfo[nModule].baseAddress;        TIMERIntDisable(baseAddr, TIMER_INT_TCAR_EN_FLAG);        TIMERDisable(baseAddr);        #ifdef MULTIPLEX_ICU_TIMERS            ICUHW_reclaimTimer(nModule);        }        #endif    }}

,

Cherry Zhou:

您好,您能否试下用示波器或者其他仪器以查看 ICU 是否正在读取任何内容?或者更简单的测试,看下在断开 ICU 与任何这些外设的连接时,是否仍有读数? 这样我们可以确定 ICU 本身不会进行随机读数。

,

Qingyu Zhuang:

目前使用mcu_timer[4:9]六个,mcu_timer_io[0:9]十个。十个输入口都能捕捉,但频率低于550hz才能捕捉到双边沿,否则只捕捉到周期。不链接信号时,io[0:5]不会干扰,io[6:9]总捕捉到一个数值。优先级调整过到0,效果不明显。示波器跟踪过信号,硬件能保证10khz占空比1%的信号输入,到tda4管脚信号有完整的高和低电平。已对上面代码做排查调整,算法不变。

,

Cherry Zhou:

好的感谢您提供的信息,已经反馈给工程师这边了,有答复尽快给到您哈。

,

Cherry Zhou:

您好,有一点需要说明,我们不支持 MCAL/AUTOSAR 的 ICU 驱动器用于计时器输入捕获。 请问您是在哪里获得这个驱动程序的? 我们的 MCAL 驱动程序支持 ECAP,您是否使用定时器自己制作了 MCAL 驱动程序?

,

Qingyu Zhuang:

谢谢您耐心支持。

我们没有使用<sdk>/mcusw/mcal_drv/mcal/Icu

上面代码是我们自己的。

,

Cherry Zhou:

好的感谢您提供的信息,现在您这边和工程师是同步的了。您能否重新总结一下关于您在使用计时器时的问题?

有可能是硬件中的配置问题? 还是说您使用 TI 提供的软件?

,

Qingyu Zhuang:

上面代码是按自己的理解去配置这些寄存器的,所以没办法识别这样的配置问题在哪里。需要技术支持进一步给建议和帮助。

,

Cherry Zhou:

嗯嗯好的,能否请您重新总结下您的问题,您在使用定时器时出现的问题?

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1082678/tda4vm-multiplexed-mcu-timer-as-a-grabber-with-false-touch-issue

以上链接是帮助您升级到英文论坛寻求帮助的帖子,您也可以持续关注。

赞(0)
未经允许不得转载:TI中文支持网 » TDA4VM: 复用mcu timer做捕捉器,有误触发问题
分享到: 更多 (0)