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.

AM3358: eCAP issue

Part Number: AM3358

Hi,

The customer used three ecap modules. Ecap0 used to capture clock frequency . Ecap1 and ecap2  used to capture 45HZ~55HZ square wave. When ecap1 is configured in APWM mode, ecap2 can capture the correct cycle normally. And ecap1 can also capture the correct cycle when ecap2 set to APWM. But when ecap1 and ecap2 both configured as ECAP_CAPTURE_MODE that they can not work properly.

Below is related code:

int freq_init(void)
{
    void __iomem *p_REGS;
   /**************************配置时钟和设备地址映射****************************/
    p_REGS = ioremap(SOC_PWMSS1_REGS, SZ_8K);
    if(!p_REGS)
    {
        printk("%s:ioremap(%x) error\r\n", __func__, SOC_PWMSS1_REGS);
        
        return -1;
    }
    g_SOC_PWMSS1_REGS = (unsigned int)p_REGS;
    g_SOC_ECAP_1_REGS = g_SOC_PWMSS1_REGS + SOC_ECAP_REGS;
    g_aREGS[0] = g_SOC_ECAP_1_REGS;
    
    p_REGS = ioremap(SOC_PWMSS2_REGS, SZ_8K);
    if(!p_REGS)
    {
        printk("%s:ioremap(%x) error\r\n", __func__, SOC_PWMSS2_REGS);
        iounmap((void __iomem *)g_SOC_CONTROL_REGS);
        iounmap((void __iomem *)g_SOC_PWMSS1_REGS);
        
        return -1;
    }
    g_SOC_PWMSS2_REGS = (unsigned int)p_REGS;
    g_SOC_ECAP_2_REGS = g_SOC_PWMSS2_REGS + SOC_ECAP_REGS; 
    g_aREGS[1] = g_SOC_ECAP_2_REGS;
    
    /* Enable Clock */
    ECAPClockEnable(g_SOC_PWMSS1_REGS);
    while(ECAPClockEnableStatusGet(g_SOC_PWMSS1_REGS) == 0);    
    ECAPClockEnable(g_SOC_PWMSS2_REGS);
    while(ECAPClockEnableStatusGet(g_SOC_PWMSS2_REGS) == 0);
    
    /***************************配置两个ecap的硬件管脚*****************************/
    p_REGS = ioremap(SOC_CONTROL_REGS, SZ_8K);
    if(!p_REGS)
    {
        printk("%s:ioremap(%x) error\r\n", __func__, SOC_CONTROL_REGS);
        
        return -1;
    }
    g_SOC_CONTROL_REGS = (unsigned int)p_REGS;
    /* eCAP1输入管脚 AM335X_ECAP1_IN I2C0_SCL C16 */
    HWREG(g_SOC_CONTROL_REGS + CONTROL_CONF_I2C0_SCL) =
        (CONTROL_CONF_PULLUPSEL |CONTROL_CONF_RXACTIVE 
        | CONTROL_CONF_MUXMODE(3));
    
    /* eCAP2输入管脚 eCAP2_in_PWM2_out模式 MCASP0_AHCLKR C12  */
    HWREG(g_SOC_CONTROL_REGS + CONTROL_CONF_MCASP0_AHCLKR) =
        (CONTROL_CONF_PULLUPSEL |CONTROL_CONF_RXACTIVE 
        | CONTROL_CONF_MUXMODE(4));
    /****************************配置两个ecap的寄存器******************************/
    /* 捕捉模式
    ** ECCTL2[9] CAP_APWM CAP/APWM operating mode select
    ** 0h = ECAP module operates in capture mode. This mode forces the
    ** following configuration. (a) Inhibits TSCTR resets via PRDEQ event.
    ** (b) Inhibits shadow loads on CAP1 and 2 registers. (c) Permits user
    ** to enable CAP1-4 register load. (d) ECAPn/APWMn pin operates as
    ** a capture input.
    ** 1h = ECAP module operates in APWM mode. This mode forces the
    ** following configuration. (a) Resets TSCTR on PRDEQ event (period
    ** boundary). (b) Permits shadow loading on CAP1 and 2 registers. (c)
    ** Disables loading of time-stamps into CAP1-4 registers. (d)
    ** ECAPn/APWMn pin operates as a APWM output.
    */
    ECAPOperatingModeSelect(g_SOC_ECAP_1_REGS, ECAP_CAPTURE_MODE);
    ECAPOperatingModeSelect(g_SOC_ECAP_2_REGS, ECAP_APWM_MODE);    /* 问题就在此处 ecap2设备APWM模式时 ecap1才能正常捕获,反之亦然 */
    
    /* 连续模式
    ** ECCTL2[0] CONT_ONESHT  0h = Operate in continuous mode
    */
    ECAPContinousModeConfig(g_SOC_ECAP_1_REGS);
    ECAPContinousModeConfig(g_SOC_ECAP_2_REGS);
    /* 清除中断
    ** ECCLR[0:7] ECFLG&0xFF Writing a 1 clears the Int flag condition
    */
    ECAPIntStatusClear(g_SOC_ECAP_1_REGS, 0xFF);
    ECAPIntStatusClear(g_SOC_ECAP_2_REGS, 0xFF);
    /* 这里的分频是指输入信号的分频,不是ECAP的时钟分频
    ** ECCTL1[9:13] PRESCALE 0h = Divide by 1 (i.e,. no prescale, by-pass the prescaler)
    */
    ECAPPrescaleConfig(g_SOC_ECAP_1_REGS, 0);
    ECAPPrescaleConfig(g_SOC_ECAP_2_REGS, 0);
    
    /* enables capture loading
    ** ECCTL1[8] CAPLDEN 1h = Enable CAP1-4 register loads at capture event time.
    */
    ECAPCaptureLoadingEnable(g_SOC_ECAP_1_REGS);
    ECAPCaptureLoadingEnable(g_SOC_ECAP_2_REGS);
    
    /* configures Capture Event polarity.上升沿捕捉 */
    ECAPCapeEvtPolarityConfig(g_SOC_ECAP_1_REGS, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE);  
    ECAPCapeEvtPolarityConfig(g_SOC_ECAP_2_REGS, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE);  
    
    /* enables reset of the counters upon Capture Events. */
    ECAPCaptureEvtCntrRstConfig(g_SOC_ECAP_1_REGS, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE);
    ECAPCaptureEvtCntrRstConfig(g_SOC_ECAP_2_REGS, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE);
    
    /* 0h = Stop after Capture Event 1 in one-shot mode. Wrap after
       Capture Event 1 in continuous mode
       0->0->0 CAP1 */
    //ECAPStopWrapConfig(g_SOC_ECAP_1_REGS, ECAP_CAPTURE_EVENT4_STOP);
    //ECAPStopWrapConfig(g_SOC_ECAP_2_REGS, ECAP_CAPTURE_EVENT1_STOP);
    
    /* 使能中断 */
    ECAPIntEnable(g_SOC_ECAP_1_REGS, ECAP_CEVT1_INT|ECAP_CEVT2_INT|ECAP_CEVT3_INT|ECAP_CEVT4_INT);
    ECAPIntEnable(g_SOC_ECAP_2_REGS, ECAP_CEVT1_INT|ECAP_CEVT2_INT|ECAP_CEVT3_INT|ECAP_CEVT4_INT); 
    /* Disables the sync out ,sync in. TI定义的宏ECAP_SYNC_OUT_DISABLE有问题,改用EC_SYNC_OUT_DISABLE
    ** ECCTL2[5] SYNCI_EN  0h = Disable sync-in option
    ** ECCTL2[6:7] SYNCO_SEL  2h = Disable sync out signal
    */
    ECAPSyncInOutSelect(g_SOC_ECAP_1_REGS, ECAP_SYNC_IN_DISABLE, EC_SYNC_OUT_DISABLE);
    ECAPSyncInOutSelect(g_SOC_ECAP_2_REGS, ECAP_SYNC_IN_DISABLE, EC_SYNC_OUT_DISABLE);
    
    /* Set Counter
    ** RSCTR[0:31] 0 Active 32 bit counter register that is used as the capture time-base
    */
    ECAPCounterConfig(g_SOC_ECAP_1_REGS, 0);
    ECAPCounterConfig(g_SOC_ECAP_2_REGS, 0);
    
    /* 自由运行     ECCTL2[4] 1  TSCTRSTOP->TSCTR free-running 计数器停止位控制 计数器开始计数 */
    ECAPCounterControl(g_SOC_ECAP_1_REGS, ECAP_COUNTER_FREE_RUNNING);
    ECAPCounterControl(g_SOC_ECAP_2_REGS, ECAP_COUNTER_FREE_RUNNING);
    
    rt_request_irq(CFG_ECAP1INT, CFG_INT_LEVEL_ECAP, freq_isr0, "ecap1", 0);
    rt_request_irq(CFG_ECAP2INT, CFG_INT_LEVEL_ECAP, freq_isr1, "ecap2", 0);
    
    return 0;  
}
void freq_isr0(void *data)
{
    freq_isr(0);
}
void freq_isr1(void *data)
{
    freq_isr(1);
}
void freq_isr(int index)
{
    unsigned int    status, count = 0;
    float   freq;
    /* 读取中断状态值 */
    status = ECAPIntStatus(g_aREGS[index], 0x3F);
    if(status & ECAP_CEVT1_INT)
    {
        count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_1);
    }
    if(status & ECAP_CEVT2_INT)
    {
        count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_2);   
    }
    if(status & ECAP_CEVT3_INT)
    {
        count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_3);
    }
    if(status & ECAP_CEVT4_INT)
    {
        count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_4);
    }  
    /* 清中断标志位 */
    ECAPIntStatusClear(g_aREGS[index], 0x3F);
    /* 换算成频率.不能除0 */
    if(count)
    {
        freq = (float)ECAP_CLK_FREQ/count;
    }
    else
    {
        freq = 0;
    }
    //将频率范围限定在45hz到55hz。
    if(freq>=44.0 && freq <= 56.0)
    {
        g_freqency[index] = freq;
    }