Software APIs
pwrmgr_deep_sleep_por_reset_test.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 
5 #include <assert.h>
6 #include <limits.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 
18 #include "sw/device/lib/testing/pwrmgr_testutils.h"
19 #include "sw/device/lib/testing/rstmgr_testutils.h"
20 #include "sw/device/lib/testing/test_framework/FreeRTOSConfig.h"
21 #include "sw/device/lib/testing/test_framework/check.h"
23 
24 static const dt_rstmgr_t kRstmgrDt = 0;
25 static_assert(kDtRstmgrCount == 1, "this test expects a rstmgr");
26 static const dt_pwrmgr_t kPwrmgrDt = 0;
27 static_assert(kDtPwrmgrCount == 1, "this test expects a pwrmgr");
28 static const dt_sysrst_ctrl_t kSysrstCtrlDt = 0;
29 static_assert(kDtSysrstCtrlCount == 1, "this test expects a sysrst_ctrl");
30 static const dt_pinmux_t kPinmuxDt = 0;
31 static_assert(kDtPinmuxCount == 1, "this test expects a pinmux");
32 
33 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
34 
35 /**
36  * Objects to access the peripherals used in this test via dif API.
37  */
38 static dif_pwrmgr_t pwrmgr;
39 static dif_sysrst_ctrl_t sysrst_ctrl_aon;
40 static dif_rstmgr_t rstmgr;
41 
42 /**
43  * Initialize the peripherals used in this test.
44  */
45 void init_peripherals(void) {
46  // Initialize pwrmgr.
47  CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
48 
49  // Initialize sysrst_ctrl.
50  CHECK_DIF_OK(dif_sysrst_ctrl_init_from_dt(kSysrstCtrlDt, &sysrst_ctrl_aon));
51 
52  // Initialize rstmgr to check the reset reason.
53  CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
54 }
55 
56 /**
57  * Configure the sysrst.
58  */
59 static void config_sysrst(const dif_pwrmgr_t *pwrmgr,
60  const dif_sysrst_ctrl_t *sysrst_ctrl_aon) {
61  LOG_INFO("sysrst enabled");
62 
63  // Set sysrst as a reset source.
64  dif_pwrmgr_request_sources_t reset_sources;
65  CHECK_DIF_OK(dif_pwrmgr_find_request_source(
66  pwrmgr, kDifPwrmgrReqTypeReset, dt_sysrst_ctrl_instance_id(kSysrstCtrlDt),
67  kDtSysrstCtrlResetReqRstReq, &reset_sources));
68  CHECK_DIF_OK(dif_pwrmgr_set_request_sources(
69  pwrmgr, kDifPwrmgrReqTypeReset, reset_sources, kDifToggleEnabled));
70  LOG_INFO("syrst_ctrl Reset Request is set");
71 
72  // Configure sysrst key combo
73  // reset pulse : 50 us
74  // detect durration : 50 us
75 
76  dif_sysrst_ctrl_key_combo_config_t sysrst_ctrl_key_combo_config = {
78  .detection_time_threshold = 10,
80  .embedded_controller_reset_duration = 10};
81 
83  sysrst_ctrl_aon, kDifSysrstCtrlKeyCombo0, sysrst_ctrl_key_combo_config));
84  // Configure sysrst input change
85  // debounce duration : 100 us
86  dif_sysrst_ctrl_input_change_config_t sysrst_ctrl_input_change_config = {
87  .input_changes = kDifSysrstCtrlInputAll, .debounce_time_threshold = 20};
88 
89  // Configure pinmux
90  dif_pinmux_t pinmux;
91  CHECK_DIF_OK(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
92 
94  sysrst_ctrl_aon, sysrst_ctrl_input_change_config));
95 
96  CHECK_DIF_OK(dif_pinmux_mio_select_input(
97  &pinmux,
98  dt_sysrst_ctrl_periph_io(kSysrstCtrlDt, kDtSysrstCtrlPeriphIoKey0In),
99  kDtPadIor13));
100 }
101 
102 static void low_power_por(const dif_pwrmgr_t *pwrmgr) {
103  // Program the pwrmgr to go to deep sleep state (clocks off).
104  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(pwrmgr, 0, 0));
105  LOG_INFO("Ready for pad POR");
106  // Enter in low power mode.
108  // If we arrive here the test must fail.
109  CHECK(false, "Fail to enter in low power mode!");
110 }
111 
112 bool test_main(void) {
113  init_peripherals();
114 
115  // Check if there was a HW reset caused by expected cases
117  rst_info = rstmgr_testutils_reason_get();
118  rstmgr_testutils_reason_clear();
119  LOG_INFO("Reset info 0x%x", rst_info);
120  if (rst_info == kDifRstmgrResetInfoPor) {
121  config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
122  LOG_INFO("Setting sleep mode");
123  low_power_por(&pwrmgr);
124  CHECK(false, "This is unreachable");
125  } else if ((rst_info & kDifRstmgrResetInfoSysRstCtrl) != 0) {
126  // This means the host/sim_dv side found the POR case to work so all
127  // went well.
128  return true;
129  } else {
130  LOG_ERROR("Wrong reset reason %02X", rst_info);
131  }
132  return false;
133 }