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:片上 OAD 项目中的按钮关断/唤醒

Guru**** 2528170 points
Other Parts Discussed in Thread: CC2652R7

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1540996/cc2652r7-button-shutdown-wake-up-in-on-chip-oad-project

器件型号:CC2652R7


工具/软件:

尊敬的团队:

我正在开发一款可以在长按后使用按钮打开/关闭电源的器件。 以前它可以正常工作、但最近我在它上添加了一个片上 OAD 功能。

之后、我发现只能在长按后关闭器件、但无法再次唤醒。
下面是长按一下按钮唤醒/关闭的主要逻辑,我将 Boot_init () 放在 SimplePeripheral_taskFxn 函数的开头:

void Boot_Init ()

PowerCC26X2_ResetReason resetReason = PowerCC26X2_getResetReason ();

if (resetReason == PowerCC26X2_RESET_SHUTDOWN_IO)

PowerCC26X2_releaseLatters();
BootCountDownCreate();
BootCountDownInit();
GPIO_setConfig (CONFIG_GPIO_MPB_CONST、GPIO_CFG_IN_PU);
uint8_t PRESS = GPIO_READ (CONFIG_GPIO_MPB_CONST);
BootServiceRoutine(印刷机);
BootCountEliminate();
GPIO_resetconfig (CONFIG_GPIO_MPB_CONST);
howToBoot = 0x00;
}
否则 if (resetReason == PowerCC26X2_RESET_TCK_NOISE)

howToBoot = 0x01;
}
否则 if (resetReason == PowerCC26X2_RESET_SYSTEM)

howToBoot = 0x02;
}
否则 if (resetReason == PowerCC26X2_RESET_WARM_RESET)/*快速引导*/

howToBoot = 0x03;
}
否则 if (resetReason == PowerCC26X2_RESET_CLK)

howToBoot = 0x04;
}
否则 if (resetReason == PowerCC26X2_RESET_VDDR)

howToBoot = 0x05;
}
否则 if (resetReason == PowerCC26X2_RESET_VDDS)

howToBoot = 0x06;
}
否则 if (resetReason == PowerCC26X2_RESET_PIN)

howToBoot = 0x07;
}
否则 if (resetReason == PowerCC26X2_RESET_POR)

howToBoot = 0x08;
}
}

void BootServiceRoutine (uint8_t isWakeUp)

uint8_t boot_finished = 0x00;
IF (isWakeUp = 0)

/*如果用户仍在按此按钮、倒计时器将立即启动*/
uint8_t stillPress = GPIO_READ (CONFIG_GPIO_MPB_CONST);
if (stillPress == 0x00)

/*开始向下计数的时间为 BOOTREADY_TIME x BOOTREADY_COUNT 秒*/
BootCountStart();
}
/*我们还没有启动! 尽管您正在按下按钮! 不要放下你的手!*/
while (boot_finished == 0x00)

/* STATUS = 0x01 -->释放按钮
* status = 0x00 -->按下按钮
*/
uint8_t status = GPIO_READ (CONFIG_GPIO_MPB_CONST);
我的天哪! 您已释放按钮! 让我再睡一觉!*/
IF (STATUS == 0x01)

/*倒计时器停止*/
BootCountStop();
/*再次进入关闭模式*/
SystemShutDownRoutine();
}
/*如果用户仍在按按钮直到时间增加、倒计时器将停止! 引导例程已完成! */
/*对于每 500 毫秒计时器溢出、bootCount 会增加 1。
*要有 1.5 秒的延迟, bootReady 是 3.
*要查看闪烁,请等待 bootReady 为 3 ,同时按下按钮!
**/
IF (bootReady >= BOOTREADY_COUNT)

/*已完成倒计数*/
BootCountStop();
/*祝贺您! 引导过程已完成! 走出圈子! 享受驾驶! */
BOOT_FINISED = 0x01;
}
}
}
否则 if (isWakeUp == 1)

while (boot_finished == 0x00)

/*再次进入关闭模式*/
SystemShutDownRoutine();
}
}
}

作废系统 ShutDownRoutine()

GPIO_resetconfig (CONFIG_GPIO_MPB_CONST);
/*如何唤醒我? */
GPIO_setConfig (CONFIG_GPIO_MPB_CONST、GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_PULL_UP_INTERNAL | GPIO_CFG_SHUTDOWN_WAKE_LOW);
/*让我睡觉! 再见! */
POWER_SHUTDOWN (0、0);
while (1)

}
}


我想知道此问题是否与 bim_onchip 有关、因此我需要对 bim 工程实现我的按钮按压逻辑?

 我正在使用 simplelink_cc13xx_cc26xx_sdk_7_40_00_77 和 CCS 12.8.1、您能帮我解决这个问题吗?

非常感谢。

Jermyn

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

    尊敬的 Jermyn:

    很好的调试! 我同意您的假设、因为您的按钮按压逻辑的工作版本与非工作版本之间的主要区别是使用 bim_onchip。

    您是否可以访问复位引脚? 如果是、那么我建议的快速测试是:

    1. 将您的器件置于运行状态(例如擦除整个闪存,刷写所有相关二进制文件,例如 BIM,应用程序等)
    2. 现在、按下复位按钮
    3. 确认您的应用程序是否已启动

    谢谢、
    Toby

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

    尊敬的 Toby:

    是指 LaunchPad 上的复位引脚吗? 抱歉、我无法访问复位引脚。

    根据我的经验、连接到电源后我的应用就会开始。 然后长按按钮后、我的设备可以关闭(进入睡眠模式)。 它应该在长按后被唤醒,但它失败了。

    我想知道是否需要将启动逻辑复制到 bim_onchip 程序? 如果是、我需要添加一个 syscfg 文件、但我找不到有关向 CC2652R7 添加 syscfg 文件的任何说明。

    您对此有何建议? 感谢您发送编修。

    此致、

    Jermyn

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

    尊敬的 Jermyn:

    根据我的经验、一旦我连接到电源、我的应用程序就会启动。

    在您将 BIM 版本的项目新加载到设备后,关闭电源再打开,您是否看到应用程序正在启动?

    谢谢、
    Toby

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

    尊敬的 Tody:  

    这些天的调试过程中、我发现问题在于代码的计数逻辑、在我删除了唤醒逻辑的计数功能后、 我可以在短按按钮(而是长按)时成功唤醒器件。

    我想我应该正确配置我之前发送的代码中使用的时钟:

    #define BOOTREADY_TIME 300
    #define BOOTREADY_COUNT 2

    Void BootCountDownCreate()

    ERROR_INIT (&EB);
    BOOTClockTicks = BOOTREADY_TIME *(1000 / Clock_tickPeriod)- 1;// BOOTREADY_TIME 至溢出
    //创建 BootCountDown 时钟!!
    bootCountClockHandle = Clock_create (BootCountOVFxn、bootClockTicks、&clkParams、&EB);
    }

    Void BootCountDownInit()

    Clock_Params_初始化 (&clkParams);
    clkParams.period = bootClockTicks;
    clkParams.startFlag = false;
    clkParams.arg =(UArg) 0x0000;
    CLOCK_setTimeout (bootCountClockHandle、bootClockTicks);
    CLOCK_setPeriod (bootCountClockHandle、bootClockTicks);
    }

    Void BootCountStart()

    //设置初始超时
    CLOCK_START (bootCountClockHandle);
    }

    Void BootCountStop()

    CLOCK_STOP (bootCountClockHandle);
    }

    空引导计数消除 ()

    CLOCK_DELETE (&bootCountClockHandle);
    }

    Void BootCountOVFxn()

    bootReady++;
    }

    请问这 种方法适用于唤醒器件吗? 如果没有、我可以通过哪些其他方法尝试长按按钮来唤醒器件?

    非常感谢。

    好极了

    Jermyn  

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

    尊敬的 Jermyn:

    从器件的角度来看、它可以非常快速地通过 GPIO(大约 10usec)唤醒。

    对于长按/短按检测、如果不使用额外的硬件、则需要像此处所做的那样进行某种计数。
    在这种情况下、需要处理按钮按压小于长按持续时间的情况。

    例如、对于 SHUTDOWN 唤醒、序列可能如下所示:

    1. 器件处于关断状态
    2. 用户按下/按住按钮
    3. 器件唤醒并进入计数逻辑
    4. 如果用户在长按持续时间之前释放按钮、则器件进入关断状态
    5. 如果用户在长按持续时间后释放按钮、则器件会启动应用

    谢谢、
    Toby

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

    尊敬的 Toby:  

    谢谢你的重播,我可以理解的序列。 但在调试过程中、我仍然不清楚问题的根源是什么。

    但是、对于您前面的问题、在这种情况下、我的器件中有 LED 显示、如果应用程序启动、则可以对其进行初始化、并可以打开 LED。 之后  

    在我长按一个按钮关闭应用程序后,然后尝试通过长按再次唤醒它,没有发生任何事情。 我无法打开显示器、 因此我确定应用程序没有启动。

    回到需要 bim_onchip 的片上 OAD、我从 TI 技术参考手册中了解到了该 OAD、它说了系统复位、上电或从 SHUTDOWN 模式唤醒后的 CC13x2x7 和 CC26x2x7 器件平台状态是启动状态。

    1) 那么,这是否意味着每次从关断状态唤醒时,它可能会先进入 bim_onchip 程序? 我仍需要修改 bim 文件以进行关机/唤醒?

    2) 然后如何将.syscfg 文件添加到 BIM、因为我需要为外部按钮启用 GPIO。

    3) 为什么在删除唤醒逻辑的计数功能时、短按按钮(而是长按)即可成功唤醒器件、即使使用片上 OAD 设置也是如此? 这个问题的关键到底是什么。

    请您帮助澄清这些问题、非常感谢。

    BSet、

    Jermyn

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

    尊敬的 Jermyn:

    感谢您更详细地解释您的观察结果。

    借助所有这些线索,我认为关键的事情可能是,BIM 是一个非常简单的项目,它不会拉入在更复杂的应用程序中使用的许多模块,例如 调用 Clock_*函数。

    作为测试、是否可以改用 for 循环(而不是 Clock_*函数)? 空循环每次迭代通常需要大约~4 个周期、因此进行 2 秒长按的简单测试:

    char button_level = readButton(wakeupGpio);
    if (button_level == PRESSED) {
        int i;
        for (i = 0; i < 48000000 * 2 / 4; i++) {
            // delay about 2 sec, assuming 4 cycles per empty for-loop iteration
        }
        button_level = readButton(wakeupGpio);
        if (button_level == PRESSED) {
            // long press detected, startup application normally
        }
    }
    
    // not long pressed, so return to shutdown

    关于如何将.syscfg 文件添加到 BIM 工程、默认情况下不执行此操作、因为 BIM 是一个基本架构工程(尽可能减少闪存占用)、并且不会引入 TI 驱动程序(例如 GPIO_WRITE)、寄存器写入仍可用于控制引脚。

    下面是我过去用于读取引脚的一些寄存器写入的参考:

    #include DeviceFamily_constructPath(inc/hw_aon_pmctl.h)
    #include DeviceFamily_constructPath(inc/hw_nvic.h)
    #include DeviceFamily_constructPath(inc/hw_ioc.h)
    #include DeviceFamily_constructPath(driverlib/ioc.h)
    
    // ...
    
    // assume active low backdoor pin
    static const uint8_t ACTIVE_LEVEL = 0;
    uint8_t initBackDoorPin(uint8_t dioNum)
    {
        HWREG(PRCM_BASE + PRCM_O_PDCTL0PERIPH) = PRCM_PDCTL0PERIPH_ON;
        // Wait for stable power
        while((HWREG(PRCM_BASE + PRCM_O_PDSTAT0) &
                PRCM_PDSTAT0_PERIPH_ON) == 0)
        {
        }
        // Enable GPIO clock
        HWREG(PRCM_BASE + PRCM_O_GPIOCLKGR) = PRCM_GPIOCLKGR_CLK_EN;
        HWREG(PRCM_BASE + PRCM_O_CLKLOADCTL)  = PRCM_CLKLOADCTL_LOAD;
        // Enable for edge interrupt on both edges on GPIO-pin to be used for UART_RX
        uint32_t ui32RegOffset = dioNum * 4;
    
        HWREG(IOC_BASE + IOC_O_IOCFG0 + ui32RegOffset) = IOC_IOCFG0_IE  | IOC_IOPULL_UP;
    
        return dioNum;
    }
    uint8_t isBackdoorPinActive(uint8_t dioNum)
    {
        const uint32_t ACTIVE_THRESHOLD = 750;
    
        uint8_t level;
        uint32_t countOfActiveLevel = 0;
    
        uint32_t n;
        for (n = 0; n < 1000; n++)
        {
            level = GPIO_readDio(dioNum);
            if (level == ACTIVE_LEVEL)
            {
                countOfActiveLevel += 1;
            }
        }
    
        return (countOfActiveLevel >= ACTIVE_THRESHOLD);
    }
    
    //...
    
    uint8_t backdoorDio = initBackDoorPin(23);
    if (isBackdoorPinActive(backdoorDio))

    谢谢、
    Toby