Сергей Борщ 126 5 апреля, 2023 Опубликовано 5 апреля, 2023 · Жалоба Столкнулся с такой проблемой - устройство должно уйти в shutdown и по сигналу WKUP3 проснуться. Реализовано это так: Спойлер void sleep_manager::do_shutdown() { __disable_irq(); // enable RTC write access, select Shutdown as deep sleep mode PWR->CR1 = 0 | 0 * PWR_CR1_LPR // Supply mode, 0: main regulator, 1: low power regulator | 1 * (PWR_CR1_VOS & -PWR_CR1_VOS) // Voltage scaling, 1: Range 1 (fast), 2: Range 2 (slow), 0, 3: forbidden | 1 * PWR_CR1_DBP // Enable write access to backup domain registers | 0 * PWR_CR1_FPDS // Flash mode during LPSleep, 0: Idle, 1: Power-down | 0 * PWR_CR1_FPDR // Flash mode during LPRun, 0: Idle, 1: Power-down | 0 * PWR_CR1_SUBGHZSPINSSSEL // Radio SPI NSS select, 0: PWR->SUBGHZSPICR.NSS, 1: LPTIM3_OUT | 4 * (PWR_CR1_LPMS & -PWR_CR1_LPMS) // Low-power selection: 0: Stop0, 1: Stop1, 2: Stop2, 3: Standby, 4..7: Shutdown ; PWR->PUCRB = 0 | 1 * PIN_BITMASK(SM353_INPUT) // подтяжка к питанию на WKUP3 ; PWR->CR4 = 0 | 0 * PWR_CR4_WRFBUSYP // Wakeup from radio BUSY polarity, 0: active high(rising), 1: active low (falling) | 0 * PWR_CR4_VBRS // Vbat battery charging resistor, 0: 5 kOhm, 1: 1.5 kOhm | 0 * PWR_CR4_VBE // Vbat battery charging enable | 1 * PWR_CR4_WP3 // WKUP3 polarity, 0: active high(rising), 1: active low (falling) | 0 * PWR_CR4_WP2 // WKUP3 polarity, 0: active high(rising), 1: active low (falling) | 0 * PWR_CR4_WP1 // WKUP3 polarity, 0: active high(rising), 1: active low (falling) ; // disable PVD if was enabled PWR->CR2 = 0 | 0 * PWR_CR2_PVME3 // Vdda monitoring versus 1.62v threshold enable | 0 * (PWR_CR2_PLS & -PWR_CR2_PLS) // PVD threshold, 0: 2.0v, 1: 2.2v, 2: 2.4v, 3: 2.5v, 4: 2.6v, 5: 2.8v, 6: 2.9v, 7: PVD_IN < VREFINT | 0 * PWR_CR2_PVDE // PVD enable ; // настройка подтяжек на всех выводах PWR->PDCRA = ... PWR->PDCRB = ... PWR->PDCRC = ... PWR->PDCRH = ... PWR->CR3 = 0 | 0 * PWR_CR3_EIWUL // Internal wakeup line interrupt enable | 0 * PWR_CR3_EWRFIRQ // Radio IRQ wakeup from standby enable | 0 * PWR_CR3_EWRFBUSY // Radio busy wakeup from standby enable | 1 * PWR_CR3_APC // Apply pull-up/down configuration, 1: use PWR->PUCRx, PWR->PDCRx | 0 * PWR_CR3_RRS // SRAM2 power in Standby mode, 0: off, 1: low-power regulator | 0 * PWR_CR3_EWPVD // PVD enable by radio active state | 1 * PWR_CR3_ULPEN // Supply voltage sampling in Stop & Standby modes, 0: continuously, 1: periodically (~12 ms) | 1 * PWR_CR3_EWUP3 // WKUPx enable | 0 * PWR_CR3_EWUP2 // WKUPx enable | 0 * PWR_CR3_EWUP1 // WKUPx enable ; SCB->SCR |= SCB_SCR_SLEEPDEEP; EXTI->IMR1 = 0; { // errata 2.2.11: Potential deadlock condition on wakeup from some low-power modes auto Attempts = 48/6 * 1000 * 1000; // ~1 sec at MSI48 for(;;) { if(PWR->SR2 & PWR_SR2_LDORDY) break; if(!--Attempts) wdt_reboot(); } } for(;;) { EXTI->PR1 = ~0; // clear pending EXTI. PWR->SCR = ~0; // clear wakeup status __WFI(); } } Почти всегда это работает, но очень редко устройство может сбойнуть (захочешь конкретное устройство специально загнать в это состояние - хоть обусыпляйся, но если ~сотню устройств разбудить/усыпить - где-то на третьем проходе одно из устройств может сбойнуть). При этом программа постоянно крутится в бесконечном цикле вокруг WFI, PWR->EXTSCR в нулях, т.е. ядро даже не пытается уйти в сон. В PWR->SR1 все флаги в нулях, EXTI->PRx в нулях, NVIC->ISPRx в нулях. Контроллер тактируется от MSI, настроенного на 48 МГц. Что может мешать ему уснуть? Если программу перезапустить ножкой сброса - все будет работать и засыпать/просыпаться как ни в чем не бывало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 207 5 апреля, 2023 Опубликовано 5 апреля, 2023 · Жалоба А если заменить на WFE? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 126 5 апреля, 2023 Опубликовано 5 апреля, 2023 · Жалоба 3 минуты назад, jcxz сказал: А если заменить на WFE? Перепрошить ~сотню устройств (пусть около 20 сек на устройство - это займет около получаса) и пройти несколько кругов побудки/усыпления (это еще часа два-три) чисто ради любопытства - сомнительное удовольствие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 126 5 апреля, 2023 Опубликовано 5 апреля, 2023 · Жалоба Как всегда - стоило написать на форум и решение нашлось. В SCB->ICSR стоял бит PENDSTSET (SysTick exception is pending). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться