This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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

Part Number: TDA4VM

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

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

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

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

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

    尽管输入信号无变化,

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

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

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

  • 输入信号在10个mcu_timer_io

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

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

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

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

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

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

  • sdk:    ti-processor-sdk-rtos-j721e-evm-08_00_00_12
    os:    freertos

    SDK示例: mcusw/mcuss_demos/profiling/can

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

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

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

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

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

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

  • 的确,原生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])
    #endif


    typedef 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_TIMERS
    static uint8 LnkIO[COUNT_OF_ICU_TMR] = {NVLDIF}; /* Recored IO index */
    static uint8 LnkTmr[COUNT_OF_ICU_IO];
    #endif


    extern 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;
            }
        }
    }
    #endif

    void 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
        }
    }

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

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

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

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

  • 谢谢您耐心支持。

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

    上面代码是我们自己的。

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

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

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

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

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

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

x 出现错误。请重试或与管理员联系。