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.

[参考译文] CC2652R7:同时捕获脉冲、但丢弃一个脉冲中断。

Guru**** 2325560 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1488538/cc2652r7-capturing-pulses-at-the-same-time-but-one-pulse-interrupt-gets-dropped

器件型号:CC2652R7

工具/软件:

您好:

我使用 GPT 计时器捕获脉冲宽度。 涉及两个计时器、我设置两个 GPTTImers 以捕获脉冲的两个边沿、然后计算第一个边沿和第二个边沿的差值。 我有一条 TX 线路、这条线路将在两个计时器都设置完毕后启用。 Tx 线路将连接到两个相同的电容器、每个电容器的两端连接到不同的 Rx GPIO。 RX 信号是相同的、因此生成的中断应同时发生、但似乎实际上只产生了一个中断、 而不是两者都产生。

谢谢、
Kenneth T.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Kenneth、

    您是否能够提供一个基本代码文件来演示您的 GPTimer 设置、并能帮助我们重现您所描述的问题?  是否调用了同一个 GPTimer 中断、或者两者之间是否不同?  如果其中一个被禁用、那么另一个中断是否始终被处理?  如果使用3.3V 电源电平、是否会发生相同的行为?

    您是否正在使用 TI 驱动程序driverlib直接访问硬件寄存器?  您可以通过调试计时器的寄存器中断状态来收集哪些信息?  此外、您正在评估哪个版本的 F2 SDK?

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    vector<GPTimerCC26XX_Handle> gptimer_handles(2);
    for (size_t t = 0; t < 2; t++) 
    { 
        // Configure GPTimer for edge time capture
        GPTimerCC26XX_Params gptimer_params;
        GPTimerCC26XX_Params_init(&gptimer_params);
        gptimer_params.width          = GPT_CONFIG_16BIT;
        gptimer_params.mode           = GPT_MODE_EDGE_TIME;
        gptimer_params.matchTiming    = GPTimerCC26XX_SET_MATCH_NEXT_CLOCK;
        gptimer_params.direction      = GPTimerCC26XX_DIRECTION_UP;
        gptimer_params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    
        // Open GPTimer and set argument to "this" object for callback to use
        GPTimerCC26XX_Handle gptimer_handle = GPTimerCC26XX_open(t, &gptimer_params);
        gptimer_handles[t] = gptimer_handle;
        GPTimerCC26XX_setArg(gptimer_handle, this);
    
        // Configure Gpio for edge interrupt
        if (t == 0)
        {
            gpio.configure(Gpio::PinId::DIO_16, Gpio::Direction::INPUT, Gpio::Pull::NONE, Gpio::State::NONE, Gpio::Strength::NONE, GPTimerCC26XX_getPinMux(gptimer_handle));
        }
        else if (t == 1)
        {
            gpio.configure(Gpio::PinId::DIO_1, Gpio::Direction::INPUT, Gpio::Pull::NONE, Gpio::State::NONE, Gpio::Strength::NONE, GPTimerCC26XX_getPinMux(gptimer_handle));
        }
    
        // Set load value in order to support full/max 24-bit capability, configure edge mode and register callback
        GPTimerCC26XX_setLoadValue(gptimer_handle, MAX_GPTIMER_COUNT);
        GPTimerCC26XX_setCaptureEdge(gptimer_handle,
                                     both_edges ? GPTimerCC26XX_BOTH_EDGES : (rising_edge ? GPTimerCC26XX_POS_EDGE : GPTimerCC26XX_NEG_EDGE));
        GPTimerCC26XX_registerInterrupt(gptimer_handle, gptimerCallback, GPT_INT_CAPTURE);
        GPTimerCC26XX_start(gptimer_handle); 
    } 
    
    tx_gpio.writeHigh(); 
    
    for (size_t t = 0; t < 2; t++) 
    { 
        first_edge_sem.wait(); 
    } 
    
    for (size_t t = 0; t < 2; t++) 
    { 
        _second_edge_sem.wait(); 
    } 
    
    tx_gpio.writeLow();
    
    for (size_t t = 0; t < 2; t++) 
    { 
        // Stop and close GPTimer
        GPTimerCC26XX_unregisterInterrupt(gptimer_handles[t]);
        GPTimerCC26XX_stop(gptimer_handles[t]);
        GPTimerCC26XX_close(gptimer_handles[t]);
    } 
    

    void Timer::gptimerCallback(GPTimerCC26XX_Handle gptimer_handle, GPTimerCC26XX_IntMask interruptMask)
    {
        // Capture edge value
        Timer* timer = reinterpret_cast<Timer*>(GPTimerCC26XX_getArg(gptimer_handle));
        if (timer->_edge_count == 0)
        {
            timer->_first_edge_gpt = GPTimerCC26XX_getValue(gptimer_handle);
            timer->_first_edge_sem.post();
        }
        else if (timer->_edge_count == 1)
        {
            timer->_second_edge_gpt = GPTimerCC26XX_getValue(gptimer_handle);
            timer->_second_edge_sem.post();
        }
        timer->_edge_count++;
    }


    调用了两个不同的 GPTimer 中断:INT_GPT2A 和 INT_GPT3A。 如果我们禁用其中一个、则另一个将被维护、但两个都不会同时维护。 我们将使用 TI 驱动程序  GPTimerCC26XX.h 我没有使用3.3V 电源电平对它进行测试、但是使用 IntPendGet ()我能够验证中断是否正在发生、但是它从未被服务。 我正在使用 simplelink_cc13xx_cc26xx_sdk_7_41_00_17版本

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kenneth:

    感谢您提供这些详细信息。  我需要一段时间来找到复制和调试此行为的时间。  作为 额外的调试信息、 是否是始终被调用的同一 GPTimer 中断(即另一个中断始终被忽略)、这是哪一个?   如果对每个 GPTimer 使用单独的回调(gptimerCallback)、问题是否会得到缓解?

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Ryan、

    看起来两个中断都在产生、但其中一个中断被忽略。 被忽略的 GPTtime 中断与被处理的中断相同。 我尝试使用单独的回调并在每个 GPTimer 的不同线程中进行脉冲捕获。

    谢谢、
    Kenneth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嘿、Kenneth、

    您能否针对寄存器级或核心功能差异对我的代码设置进行评论?

    /*
     * Copyright (c) 2016-2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== timerled.c ========
     */
    
    #include <stddef.h>
    #include <unistd.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/timer/GPTimerCC26XX.h>
    
    /* Board Header file */
    #include "ti_drivers_config.h"
    
    #define MAX_GPTIMER_COUNT 16777215
    
    GPTimerCC26XX_Handle GPTimer0;
    GPTimerCC26XX_Handle GPTimer1;
    
    uint8_t timerCount0 = 0;
    uint8_t timerCount1 = 0;
    
    
    void gptimerCallback(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask) {
        // interrupt callback code goes here. Minimize processing in interrupt.
        if (handle == GPTimer0)
        {
            timerCount0++;
        }
        else if (handle == GPTimer1)
        {
            timerCount1++;
        }
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Turn off user LED */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
    
        GPTimerCC26XX_Params gptimer_params;
        GPTimerCC26XX_Params_init(&gptimer_params);
        gptimer_params.width          = GPT_CONFIG_16BIT;
        gptimer_params.mode           = GPT_MODE_EDGE_TIME;
        gptimer_params.matchTiming    = GPTimerCC26XX_SET_MATCH_NEXT_CLOCK;
        gptimer_params.direction      = GPTimerCC26XX_DIRECTION_UP;
        gptimer_params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
    
        // Open GPTimer and set argument to "this" object for callback to use
        GPTimer0 = GPTimerCC26XX_open(CONFIG_GPTIMER_0, &gptimer_params);
        GPTimer1 = GPTimerCC26XX_open(CONFIG_GPTIMER_1, &gptimer_params);
    
        GPTimerCC26XX_setArg(GPTimer0, (void *)0x00);
        GPTimerCC26XX_setArg(GPTimer1, (void *)0x01);
    
        GPTimerCC26XX_setLoadValue(GPTimer0, MAX_GPTIMER_COUNT);
        GPTimerCC26XX_setCaptureEdge(GPTimer0, GPTimerCC26XX_BOTH_EDGES);
        GPTimerCC26XX_registerInterrupt(GPTimer0, gptimerCallback, GPT_INT_CAPTURE);
        GPTimerCC26XX_start(GPTimer0);
    
        GPTimerCC26XX_setLoadValue(GPTimer1, MAX_GPTIMER_COUNT);
        GPTimerCC26XX_setCaptureEdge(GPTimer1, GPTimerCC26XX_BOTH_EDGES);
        GPTimerCC26XX_registerInterrupt(GPTimer1, gptimerCallback, GPT_INT_CAPTURE);
        GPTimerCC26XX_start(GPTimer1);
    
        GPIO_setConfigAndMux(CONFIG_GPIO_0, GPIO_CFG_IN_PU, GPTimerCC26XX_getPinMux(GPTimer0));
        GPIO_setConfigAndMux(CONFIG_GPIO_1, GPIO_CFG_IN_PU, GPTimerCC26XX_getPinMux(GPTimer1));
    
        while(1)
        {
            sleep(10);
        }
    
        return (NULL);
    }

    两个计时器都由同一中断提供服务、因为我可以看到 两个 timerCount 值的递增、但我只是使用一个开关(即没有电容器)下拉两个 GPIO 并短接至 GND、然后工作电压为3.3V、因此我不确定这些变量中是否有任何一个导致了可观察到的差异。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Ryan、

    您是否碰巧知道正在产生的脉冲的脉冲宽度? 根据我们的观察结果、如果两个脉冲的脉冲宽度大约为10-12 微秒 、似乎会出现这个问题、但如果两个脉冲的脉冲宽度为490-500微秒、似乎可以正确处理这两个中断。

    谢谢、
    Kenneth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我修改了代码、现在脉冲宽度为20 微秒、但结果仍然成功。  

    您可以观察到一个竞态条件、因为在此期间必须发生四个中断(每个输入都向上和向下)并由同一个 HWI 函数(CPTimerCC26XX.c 中的 GPTimerCC26XXHwiFxn)进行处理。  可能第一个计时器的第一个边沿超过10微秒、因此第一个计时器的第二个边沿接下来会处理、而不是第二个计时器的第一个边沿。  我不清楚的是第二个计时器的第一个或第二个边沿是否触发了 HWiFxn、但它会导致至少一个 gptimerCallback 中断服务例程被覆盖/跳过。

    我不认为 GPTimer TI 驱动程序适用于此类操作。  您能否尝试减少 gptimerCallback 中的处理、作为测试并评论这是否会改善行为?  您可能需要修改  CPTimerCC26XX.c 或将其用作参考、以便独立于 TI 驱动程序创建您的 HWI、从而进一步减少处理中断所花费的时间。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    嗨、Ryan、

    很抱歉晚才回复。 我离开了另一个项目。 我们决定最终 按顺序进行脉冲采集、然后将其移至传感器控制器以 降低功耗。

    谢谢、
    Kenneth T.