Software APIs
pwrmgr_random_sleep_all_wake_ups.c
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
6 #include "sw/device/lib/runtime/irq.h"
8 #include "sw/device/lib/testing/ret_sram_testutils.h"
9 #include "sw/device/lib/testing/test_framework/check.h"
11 #include "sw/device/tests/pwrmgr_sleep_all_wake_ups_impl.h"
12 
13 /*
14  PWRMGR RANDOM SLEEP ALL WAKE UPS TEST
15 
16  This test runs power manager wake up from normal or deep sleep mode by
17  wake up inputs.
18 
19  For each wake up this tests normal and deep sleep in succession;
20  for example, case 2 is adc_ctrl normal sleep and case 3 is adc_ctrl
21  deep sleep.
22 
23  This is tracked by a retention sram counter, given there are resets involved.
24  */
25 
26 OTTF_DEFINE_TEST_CONFIG();
27 
28 /**
29  * Clean up pwrmgr wakeup reason register for the next round.
30  */
31 static void delay_n_clear(uint32_t delay_in_us) {
32  busy_spin_micros(delay_in_us);
33  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
34 }
35 
36 static uint32_t get_wakeup_unit(uint32_t count) { return count / 2; }
37 
38 static bool get_deep_sleep(uint32_t count) { return (count % 2) == 1; }
39 
40 bool test_main(void) {
41  // Enable global and external IRQ at Ibex.
42  irq_global_ctrl(true);
43  irq_external_ctrl(true);
44 
45  init_units();
46 
47  ret_sram_testutils_init();
48 
49  uint32_t wakeup_count = 0;
50  uint32_t wakeup_unit = 0;
51  bool deep_sleep = false;
52  dif_pwrmgr_wakeup_reason_t wakeup_reason;
53  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_get(&pwrmgr, &wakeup_reason));
54 
55  if (wakeup_reason.request_sources == 0) {
56  // This is a POR. Prepare to start the test.
57  CHECK_DIF_OK(dif_pwrmgr_wakeup_reason_clear(&pwrmgr));
58  CHECK_STATUS_OK(ret_sram_testutils_counter_clear(kCounterCases));
59  } else if (wakeup_reason.types != kDifPwrmgrWakeupTypeRequest) {
60  LOG_ERROR("Unexpected wakeup_reason.types 0x%x", wakeup_reason.types);
61  return false;
62  } else {
63  // This is a reset from deep_sleep wakeup. Run checks.
64  CHECK_STATUS_OK(
65  ret_sram_testutils_counter_get(kCounterCases, &wakeup_count));
66  wakeup_unit = get_wakeup_unit(wakeup_count);
67  deep_sleep = get_deep_sleep(wakeup_count);
68  CHECK(deep_sleep, "Should be deep sleep");
69  check_wakeup_reason(wakeup_unit);
70  LOG_INFO("Woke up by source %d", wakeup_unit);
71  clear_wakeup(wakeup_unit);
72 
73  // All is well, get ready for the next test.
74  CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterCases));
75  }
76  // All is well, get ready for the next unit, normal and deep sleep.
77  while (true) {
78  CHECK_STATUS_OK(
79  ret_sram_testutils_counter_get(kCounterCases, &wakeup_count));
80  if (wakeup_count >= 2 * get_wakeup_count()) {
81  return true;
82  }
83  wakeup_unit = get_wakeup_unit(wakeup_count);
84  deep_sleep = get_deep_sleep(wakeup_count);
85  delay_n_clear(4);
86  CHECK(!deep_sleep, "Should be normal sleep");
87  if (execute_test(wakeup_unit, deep_sleep)) {
88  check_wakeup_reason(wakeup_unit);
89  LOG_INFO("Woke up by source %d", wakeup_unit);
90  clear_wakeup(wakeup_unit);
91  }
92  // Prepare deep sleep. The check is done above where a reset is handled.
93  CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterCases));
94  CHECK_STATUS_OK(
95  ret_sram_testutils_counter_get(kCounterCases, &wakeup_count));
96  wakeup_unit = get_wakeup_unit(wakeup_count);
97  deep_sleep = get_deep_sleep(wakeup_count);
98  delay_n_clear(4);
99  CHECK(deep_sleep, "Should be deep sleep");
100  if (execute_test(wakeup_unit, deep_sleep)) {
101  CHECK(false, "This is not reachable since we entered deep sleep");
102  } else {
103  // Increment test counter.
104  CHECK_STATUS_OK(ret_sram_testutils_counter_increment(kCounterCases));
105  }
106  }
107 
108  // This is not reachable.
109  return false;
110 }