Software APIs
pwrmgr_normal_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_pwrmgr_t kPwrmgrDt = 0;
25 static_assert(kDtPwrmgrCount == 1, "this test expects a pwrmgr");
26 static const dt_pinmux_t kPinmuxDt = 0;
27 static_assert(kDtPinmuxCount == 1, "this test expects a pinmux");
28 static const dt_rstmgr_t kRstmgrDt = 0;
29 static_assert(kDtRstmgrCount == 1, "this test expects a rstmgr");
30 static const dt_sysrst_ctrl_t kSysrstCtrlDt = 0;
31 static_assert(kDtSysrstCtrlCount == 1, "this test expects a sysrst_ctrl");
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 static 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("Reset Request SourceOne 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 normal_sleep_por(const dif_pwrmgr_t *pwrmgr) {
103  // Place device into low power and immediately wake.
105  config = kDifPwrmgrDomainOptionUsbClockInLowPower |
108  kDifPwrmgrDomainOptionMainPowerInLowPower;
109 
110  // Program the pwrmgr to go to deep sleep state (clocks off).
111  CHECK_STATUS_OK(pwrmgr_testutils_enable_low_power(pwrmgr, 0, config));
112  LOG_INFO("Ready for pad POR");
113  // Enter in low power mode.
115 }
116 
117 bool test_main(void) {
118  init_peripherals();
119 
120  // Check if there was a HW reset caused by expected cases
122  rst_info = rstmgr_testutils_reason_get();
123  rstmgr_testutils_reason_clear();
124  LOG_INFO("Reset info 0x%x", rst_info);
125  if (rst_info == kDifRstmgrResetInfoPor) {
126  config_sysrst(&pwrmgr, &sysrst_ctrl_aon);
127  LOG_INFO("Setting sleep mode");
128  normal_sleep_por(&pwrmgr);
129  CHECK(false, "This is unreachable");
130  } else if ((rst_info & kDifRstmgrResetInfoSysRstCtrl) != 0) {
131  // This means the host/sim_dv side found the POR case to work so all
132  // went well.
133  return true;
134  } else {
135  LOG_ERROR("Wrong reset reason %02X", rst_info);
136  }
137  return false;
138 }