From e4f7fd910c17d9c27136f0bbea1c7443f12cc111 Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Fri, 28 Aug 2015 17:58:28 +0200 Subject: [PATCH] Fixes #2790: power on/off lop if big VCC capcitor was used --- radio/src/loadboot.cpp | 29 +++++++++++++++++---- radio/src/targets/taranis/pwr_driver.c | 36 ++++++++++++-------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/radio/src/loadboot.cpp b/radio/src/loadboot.cpp index f71fbd520..affa37fd6 100644 --- a/radio/src/loadboot.cpp +++ b/radio/src/loadboot.cpp @@ -100,13 +100,19 @@ void _bootStart() __ASM volatile ("nop"); __ASM volatile ("nop"); - // Turn soft power ON now - GPIOD->BSRRL = 1; // set PWR_GPIO_PIN_ON pin to 1 - GPIOD->MODER = (GPIOD->MODER & 0xFFFFFFFC) | 1; // General purpose output mode + // Turn soft power ON now, but only if we got started because of the watchdog + // or software reset. If the radio was started by user pressing the power button + // then that button is providing power and we don't need to enable it here. + // + // If we were to turn it on here indiscriminately, then the radio can go into the + // power on/off loop after being powered off by the user. (issue #2790) + if (WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { + GPIOD->BSRRL = 1; // set PWR_GPIO_PIN_ON pin to 1 + GPIOD->MODER = (GPIOD->MODER & 0xFFFFFFFC) | 1; // General purpose output mode + } // TRIMS_GPIO_PIN_LHR is on PG0 on 9XE and on PE3 on Taranis // TRIMS_GPIO_PIN_RHL is on PC1 on all versions - // turn on pull-ups on trim keys GPIOC->PUPDR = 0x00000004; #if defined(REV9E) @@ -114,11 +120,24 @@ void _bootStart() #else GPIOE->PUPDR = 0x00000040; #endif - + + // wait for inputs to stabilize for (uint32_t i = 0; i < 50000; i += 1) { bwdt_reset(); } + // now the second part of power on sequence + // If we got here and the radio was not started by the watchdog/software reset, + // then we must have a power button pressed. If not then we are in power on/off loop + // and to terminate it, just wait here without turning on PWR pin. The power supply will + // eventually exhaust and the radio will turn off. + if (!WAS_RESET_BY_WATCHDOG_OR_SOFTWARE()) { + // wait here until the power key is pressed + while (GPIOD->IDR & PWR_GPIO_PIN_SWITCH) { + bwdt_reset(); + } + } + if (!(TRIMS_GPIO_REG_LHR & TRIMS_GPIO_PIN_LHR) && !(TRIMS_GPIO_REG_RHL & TRIMS_GPIO_PIN_RHL)) { // Bootloader needed const uint8_t *src; diff --git a/radio/src/targets/taranis/pwr_driver.c b/radio/src/targets/taranis/pwr_driver.c index 1d2038a5d..6ad746999 100644 --- a/radio/src/targets/taranis/pwr_driver.c +++ b/radio/src/targets/taranis/pwr_driver.c @@ -87,29 +87,25 @@ void pwrOff() // disable interrupts __disable_irq(); - -#if defined(REV9E) - // 9E needs watchdog reset because CPU is still running while - // the power key is held pressed by the user. - // The power key should be released by now, but we must make sure - while (pwrPressed()) { - wdt_reset(); - } - // Put the CPU into sleep to reduce the consumption, - // it might help with the RTC reset issue - PWR->CR |= PWR_CR_CWUF; - /* Select STANDBY mode */ - PWR->CR |= PWR_CR_PDDS; - /* Set SLEEPDEEP bit of Cortex System Control Register */ - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - /* Request Wait For Event */ - __WFE(); -#endif - while(1) { wdt_reset(); +#if defined(REV9E) + // 9E needs watchdog reset because CPU is still running while + // the power key is held pressed by the user. + // The power key should be released by now, but we must make sure + if (!pwrPressed()) { + // Put the CPU into sleep to reduce the consumption, + // it might help with the RTC reset issue + PWR->CR |= PWR_CR_CWUF; + /* Select STANDBY mode */ + PWR->CR |= PWR_CR_PDDS; + /* Set SLEEPDEEP bit of Cortex System Control Register */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + /* Request Wait For Event */ + __WFE(); + } +#endif } - //this function must not return! }