# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging import time import pytest from pytest_embedded import Dut from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic @idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_light_sleep(dut: Dut) -> None: ENTERING_SLEEP_STR = 'Entering light sleep' EXIT_SLEEP_REGEX = r'Returned from light sleep, reason: (\w+), t=(\d+) ms, slept for (\d+) ms' EXIT_SLEEP_PIN_REGEX = r'Returned from light sleep, reason: (pin), t=(\d+) ms, slept for (\d+) ms' EXIT_SLEEP_UART_REGEX = r'Returned from light sleep, reason: (uart), t=(\d+) ms, slept for (\d+) ms' WAITING_FOR_GPIO_STR = r'Waiting for GPIO\d+ to go high...' WAKEUP_INTERVAL_MS = 2000 # esp32h4/esp32h21 boot button is not connected to GPIO0; DTR cannot trigger pin wakeup in CI GPIO_WAKEUP_SKIP_TARGETS = ['esp32h4', 'esp32h21'] # Ensure DTR and RTS are de-asserted for proper control of GPIO0 dut.serial.proc.setDTR(False) dut.serial.proc.setRTS(False) # enter sleep first time dut.expect_exact(ENTERING_SLEEP_STR, timeout=30) # don't check timing here, might be cache dependent dut.expect(EXIT_SLEEP_REGEX) logging.info('Got first sleep period') # enter sleep second time dut.expect_exact(ENTERING_SLEEP_STR) match = dut.expect(EXIT_SLEEP_REGEX) logging.info(f'Got second sleep period, wakeup from {match.group(1)}, slept for {match.group(3)}') # sleep time error should be less than 1ms # TODO: Need to update sleep overhead_out time for esp32c5 (PM-209) assert ( match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 2 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1 ) if dut.target not in GPIO_WAKEUP_SKIP_TARGETS: # this time we'll test gpio wakeup dut.expect_exact(ENTERING_SLEEP_STR) logging.info('Pulling GPIO0 low using DTR') dut.serial.proc.setDTR(True) time.sleep(1) match = dut.expect(EXIT_SLEEP_PIN_REGEX) logging.info(f'Got third sleep period, wakeup from {match.group(1)}, slept for {match.group(3)}') assert int(match.group(3)) < WAKEUP_INTERVAL_MS dut.expect(WAITING_FOR_GPIO_STR) logging.info('Is waiting for GPIO...') dut.serial.proc.setDTR(False) dut.expect_exact(ENTERING_SLEEP_STR) logging.info('Went to sleep again') # Write 'tt' to uart, 'tt' in ascii is 0x74 0x74 which contains 6 rising edges in total (including the stop bit) dut.serial.proc.write(b'tt') time.sleep(1) match = dut.expect(EXIT_SLEEP_UART_REGEX) logging.info(f'Got third sleep period, wakeup from {match.group(1)}, slept for {match.group(3)}') assert int(match.group(3)) < WAKEUP_INTERVAL_MS logging.info('Went to sleep again') match = dut.expect(EXIT_SLEEP_REGEX) # TODO: Need to support dynamically change retention overhead for chips which support pmu (PM-232) assert ( match.group(1).decode('utf8') == 'timer' and int(match.group(3)) >= WAKEUP_INTERVAL_MS - 2 and int(match.group(3)) <= WAKEUP_INTERVAL_MS + 1 ) logging.info('Woke up from timer again')