各位好:
使用AM335X芯片做ecap捕获,用到了全部三个ecap通道,ecap0用于时钟频率捕获,其中ecap1和ecap2用来捕获45HZ~55HZ方波,ecap1配置为APWM模式时,ecap2可以正常捕获到正确的周期,反之 ecap2设置为APWM模式时,ecap1也可以正常捕获到正确的周期。同时配置为ECAP_CAPTURE_MODE就都不能正常工作,求赐教。
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 afterCapture Event 1 in continuous mode0->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_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; } }
user6200184:
各位安:
使用AM335X芯片做ecap捕获,用到了全部三个ecap通道,ecap0用于时钟频率捕获,其中ecap1和ecap2用来捕获45HZ~55HZ方波,ecap1配置为APWM模式时,ecap2可以正常捕获到正确的周期,反之 ecap2设置为APWM模式时,ecap1也可以正常捕获到正确的周期。同时配置为ECAP_CAPTURE_MODE就都不能正常工作,求赐教。
代码如下:
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_ONESHT0h = 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 afterCapture Event 1 in continuous mode0->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_EN0h = Disable sync-in option** ECCTL2[6:7] SYNCO_SEL2h = 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] 1TSCTRSTOP->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 intstatus, count = 0;floatfreq;/* 读取中断状态值 */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;} }
Nancy Wang:
回复 user6200184:
感谢分享!
user4132396:
回复 user6200184:
楼主这是裸机代码?
yongqing wang:
回复 user4132396:
linux下的代码