[MCU] AM3352捕获三个通道中ecap1与ecap2同时捕获模式均不可用

[复制链接]
135|3
 楼主 | 2019-10-31 14:21 | 显示全部楼层 ||阅读模式
各位安:

使用AM335X芯片做ecap捕获,用到了全部三个ecap通道,ecap0用于时钟频率捕获,其中ecap1通道和ecap2通道用来捕获45HZ~55HZ方波,ecap1配置为APWM模式时,ecap2可以正常捕获到正确的周期,反之 ecap2设置为APWM模式时,ecap1也可以正常捕获到正确的周期。同时配置为ECAP_CAPTURE_MODE就都不能正常工作,求赐教。

代码如下:
  1. int freq_init(void)
  2. {
  3.     void __iomem *p_REGS;

  4.    /**************************配置时钟和设备地址映射****************************/
  5.     p_REGS = ioremap(SOC_PWMSS1_REGS, SZ_8K);
  6.     if(!p_REGS)
  7.     {
  8.         printk("%s:ioremap(%x) error\r\n", __func__, SOC_PWMSS1_REGS);
  9.                
  10.         return -1;
  11.     }
  12.     g_SOC_PWMSS1_REGS = (unsigned int)p_REGS;
  13.     g_SOC_ECAP_1_REGS = g_SOC_PWMSS1_REGS + SOC_ECAP_REGS;
  14.     g_aREGS[0] = g_SOC_ECAP_1_REGS;
  15.    
  16.     p_REGS = ioremap(SOC_PWMSS2_REGS, SZ_8K);
  17.     if(!p_REGS)
  18.     {
  19.         printk("%s:ioremap(%x) error\r\n", __func__, SOC_PWMSS2_REGS);
  20.         iounmap((void __iomem *)g_SOC_CONTROL_REGS);
  21.         iounmap((void __iomem *)g_SOC_PWMSS1_REGS);
  22.                
  23.         return -1;
  24.     }
  25.     g_SOC_PWMSS2_REGS = (unsigned int)p_REGS;
  26.     g_SOC_ECAP_2_REGS = g_SOC_PWMSS2_REGS + SOC_ECAP_REGS;       
  27.     g_aREGS[1] = g_SOC_ECAP_2_REGS;
  28.        
  29.     /* Enable Clock */
  30.     ECAPClockEnable(g_SOC_PWMSS1_REGS);
  31.     while(ECAPClockEnableStatusGet(g_SOC_PWMSS1_REGS) == 0);     
  32.     ECAPClockEnable(g_SOC_PWMSS2_REGS);
  33.     while(ECAPClockEnableStatusGet(g_SOC_PWMSS2_REGS) == 0);
  34.        
  35.         /***************************配置两个ecap的硬件管脚*****************************/
  36.         p_REGS = ioremap(SOC_CONTROL_REGS, SZ_8K);
  37.         if(!p_REGS)
  38.         {
  39.                 printk("%s:ioremap(%x) error\r\n", __func__, SOC_CONTROL_REGS);
  40.                
  41.                 return -1;
  42.         }
  43.         g_SOC_CONTROL_REGS = (unsigned int)p_REGS;

  44.         /* eCAP1输入管脚 AM335X_ECAP1_IN I2C0_SCL C16 */
  45.         HWREG(g_SOC_CONTROL_REGS + CONTROL_CONF_I2C0_SCL) =
  46.                 (CONTROL_CONF_PULLUPSEL |CONTROL_CONF_RXACTIVE       
  47.                 | CONTROL_CONF_MUXMODE(3));
  48.        
  49.         /* eCAP2输入管脚 eCAP2_in_PWM2_out模式 MCASP0_AHCLKR C12        */
  50.         HWREG(g_SOC_CONTROL_REGS + CONTROL_CONF_MCASP0_AHCLKR) =
  51.                 (CONTROL_CONF_PULLUPSEL |CONTROL_CONF_RXACTIVE       
  52.                 | CONTROL_CONF_MUXMODE(4));

  53.         /****************************配置两个ecap的寄存器******************************/
  54.         /* 捕捉模式
  55.         ** ECCTL2[9] CAP_APWM CAP/APWM operating mode select
  56.     ** 0h = ECAP module operates in capture mode. This mode forces the
  57.     ** following configuration. (a) Inhibits TSCTR resets via PRDEQ event.
  58.     ** (b) Inhibits shadow loads on CAP1 and 2 registers. (c) Permits user
  59.     ** to enable CAP1-4 register load. (d) ECAPn/APWMn pin operates as
  60.     ** a capture input.
  61.     ** 1h = ECAP module operates in APWM mode. This mode forces the
  62.     ** following configuration. (a) Resets TSCTR on PRDEQ event (period
  63.     ** boundary). (b) Permits shadow loading on CAP1 and 2 registers. (c)
  64.     ** Disables loading of time-stamps into CAP1-4 registers. (d)
  65.     ** ECAPn/APWMn pin operates as a APWM output.
  66.         */
  67.     ECAPOperatingModeSelect(g_SOC_ECAP_1_REGS, ECAP_CAPTURE_MODE);
  68.     ECAPOperatingModeSelect(g_SOC_ECAP_2_REGS, ECAP_APWM_MODE);    /* 问题就在此处 ecap2设备APWM模式时 ecap1才能正常捕获,反之亦然 */
  69.    
  70.     /* 连续模式
  71.         ** ECCTL2[0] CONT_ONESHT  0h = Operate in continuous mode
  72.     */
  73.     ECAPContinousModeConfig(g_SOC_ECAP_1_REGS);
  74.     ECAPContinousModeConfig(g_SOC_ECAP_2_REGS);

  75.         /* 清除中断
  76.         ** ECCLR[0:7] EC**&0xFF Writing a 1 clears the Int flag condition
  77.         */
  78.     ECAPIntStatusClear(g_SOC_ECAP_1_REGS, 0xFF);
  79.     ECAPIntStatusClear(g_SOC_ECAP_2_REGS, 0xFF);

  80.     /* 这里的分频是指输入信号的分频,不是ECAP的时钟分频
  81.     ** ECCTL1[9:13] PRESCALE 0h = Divide by 1 (i.e,. no prescale, by-pass the prescaler)
  82.         */
  83.     ECAPPrescaleConfig(g_SOC_ECAP_1_REGS, 0);
  84.     ECAPPrescaleConfig(g_SOC_ECAP_2_REGS, 0);
  85.        
  86.     /* enables capture loading
  87.     ** ECCTL1[8] CAPLDEN 1h = Enable CAP1-4 register loads at capture event time.
  88.         */
  89.     ECAPCaptureLoadingEnable(g_SOC_ECAP_1_REGS);
  90.     ECAPCaptureLoadingEnable(g_SOC_ECAP_2_REGS);
  91.        
  92.     /* configures Capture Event polarity.上升沿捕捉 */
  93.     ECAPCapeEvtPolarityConfig(g_SOC_ECAP_1_REGS, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE);       
  94.     ECAPCapeEvtPolarityConfig(g_SOC_ECAP_2_REGS, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE, EC_RISING_EDGE);       
  95.    
  96.     /* enables reset of the counters upon Capture Events. */
  97.     ECAPCaptureEvtCntrRstConfig(g_SOC_ECAP_1_REGS, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE);
  98.     ECAPCaptureEvtCntrRstConfig(g_SOC_ECAP_2_REGS, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE, EC_DELTA_MODE);
  99.        
  100.         /* 0h = Stop after Capture Event 1 in one-shot mode. Wrap after
  101.            Capture Event 1 in continuous mode
  102.            0->0->0 CAP1 */
  103.     //ECAPStopWrapConfig(g_SOC_ECAP_1_REGS, ECAP_CAPTURE_EVENT4_STOP);
  104.     //ECAPStopWrapConfig(g_SOC_ECAP_2_REGS, ECAP_CAPTURE_EVENT1_STOP);
  105.        
  106.     /* 使能中断 */
  107.     ECAPIntEnable(g_SOC_ECAP_1_REGS, ECAP_CEVT1_INT|ECAP_CEVT2_INT|ECAP_CEVT3_INT|ECAP_CEVT4_INT);
  108.     ECAPIntEnable(g_SOC_ECAP_2_REGS, ECAP_CEVT1_INT|ECAP_CEVT2_INT|ECAP_CEVT3_INT|ECAP_CEVT4_INT);       

  109.     /* Disables the sync out ,sync in. TI定义的宏ECAP_SYNC_OUT_DISABLE有问题,改用EC_SYNC_OUT_DISABLE
  110.     ** ECCTL2[5] SYNCI_EN  0h = Disable sync-in option
  111.     ** ECCTL2[6:7] SYNCO_SEL  2h = Disable sync out signal
  112.         */
  113.     ECAPSyncInOutSelect(g_SOC_ECAP_1_REGS, ECAP_SYNC_IN_DISABLE, EC_SYNC_OUT_DISABLE);
  114.     ECAPSyncInOutSelect(g_SOC_ECAP_2_REGS, ECAP_SYNC_IN_DISABLE, EC_SYNC_OUT_DISABLE);
  115.        
  116.     /* Set Counter
  117.         ** RSCTR[0:31] 0 Active 32 bit counter register that is used as the capture time-base
  118.         */
  119.     ECAPCounterConfig(g_SOC_ECAP_1_REGS, 0);
  120.     ECAPCounterConfig(g_SOC_ECAP_2_REGS, 0);
  121.        
  122.     /* 自由运行     ECCTL2[4] 1  TSCTRSTOP->TSCTR free-running 计数器停止位控制 计数器开始计数 */
  123.     ECAPCounterControl(g_SOC_ECAP_1_REGS, ECAP_COUNTER_FREE_RUNNING);
  124.     ECAPCounterControl(g_SOC_ECAP_2_REGS, ECAP_COUNTER_FREE_RUNNING);
  125.        
  126.     rt_request_irq(CFG_ECAP1INT, CFG_INT_LEVEL_ECAP, freq_isr0, "ecap1", 0);
  127.     rt_request_irq(CFG_ECAP2INT, CFG_INT_LEVEL_ECAP, freq_isr1, "ecap2", 0);
  128.    
  129.     return 0;       
  130. }


  131. void freq_isr(int index)
  132. {
  133.         unsigned int         status, count = 0;
  134.         float         freq;

  135.         /* 读取中断状态值 */
  136.         status = ECAPIntStatus(g_aREGS[index], 0x3F);
  137.         if(status & ECAP_CEVT1_INT)
  138.         {
  139.                 count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_1);
  140.         }
  141.         if(status & ECAP_CEVT2_INT)
  142.         {
  143.                 count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_2);   
  144.         }
  145.         if(status & ECAP_CEVT3_INT)
  146.         {
  147.                 count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_3);
  148.         }
  149.         if(status & ECAP_CEVT4_INT)
  150.         {
  151.                 count = ECAPTimeStampRead(g_aREGS[index], ECAP_CAPTURE_EVENT_4);
  152.         }       
  153.         /* 清中断标志位 */
  154.         ECAPIntStatusClear(g_aREGS[index], 0x3F);

  155.         /* 换算成频率.不能除0 */
  156.         if(count)
  157.         {
  158.                 freq = (float)ECAP_CLK_FREQ/count;
  159.         }
  160.         else
  161.         {
  162.                 freq = 0;
  163.         }

  164.         //将频率范围限定在45hz到55hz。
  165.         if(freq>=44.0 && freq <= 56.0)
  166.         {
  167.                 g_freqency[index] = freq;
  168.         }
  169. }
复制代码

使用特权

评论回复
| 2019-11-1 10:49 | 显示全部楼层
谢谢楼主分享~

使用特权

评论回复
| 2019-11-2 16:35 | 显示全部楼层
是不是两个通道捕获逻辑冲突了?

使用特权

评论回复
 楼主 | 2019-11-18 14:49 | 显示全部楼层
硬件问题,如上代码没问题

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表