11 #include "sw/device/lib/runtime/irq.h"
13 #include "sw/device/lib/testing/pwrmgr_testutils.h"
14 #include "sw/device/lib/testing/rstmgr_testutils.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
18 OTTF_DEFINE_TEST_CONFIG();
20 static const dt_adc_ctrl_t kAdcCtrlDt = 0;
21 static_assert(kDtAdcCtrlCount == 1,
"this test expects a adc_ctrl");
22 static const dt_rv_plic_t kRvPlicDt = 0;
23 static_assert(kDtRvPlicCount == 1,
"this test expects exactly one rv_plic");
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");
30 kPowerUpTimeAonCycles = 7,
37 static volatile const uint8_t kNumLowPowerSamples;
38 static volatile const uint8_t kNumNormalPowerSamples;
39 static volatile const uint8_t kWakeUpTimeAonCycles;
41 static volatile const uint8_t kChannel0MaxLowByte;
42 static volatile const uint8_t kChannel0MaxHighByte;
43 static volatile const uint8_t kChannel0MinLowByte;
44 static volatile const uint8_t kChannel0MinHighByte;
46 static volatile const uint8_t kChannel1MaxLowByte;
47 static volatile const uint8_t kChannel1MaxHighByte;
48 static volatile const uint8_t kChannel1MinLowByte;
49 static volatile const uint8_t kChannel1MinHighByte;
51 static void configure_adc_ctrl(
const dif_adc_ctrl_t *adc_ctrl) {
57 .num_low_power_samples = kNumLowPowerSamples,
58 .num_normal_power_samples = kNumNormalPowerSamples,
59 .power_up_time_aon_cycles = kPowerUpTimeAonCycles,
60 .wake_up_time_aon_cycles = kWakeUpTimeAonCycles}));
63 static dif_adc_ctrl_t adc_ctrl;
64 static dif_rv_plic_t plic;
65 static volatile bool interrupt_expected =
false;
66 static volatile bool interrupt_serviced =
false;
68 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
70 if (devid == dt_adc_ctrl_instance_id(kAdcCtrlDt) &&
72 dt_adc_ctrl_irq_to_plic_id(kAdcCtrlDt, kDtAdcCtrlIrqMatchPending)) {
74 CHECK(interrupt_expected);
75 interrupt_serviced =
true;
77 dif_adc_ctrl_irq_acknowledge(&adc_ctrl, kDtAdcCtrlIrqMatchPending));
84 static void en_plic_irqs(dif_rv_plic_t *plic) {
86 dt_adc_ctrl_irq_to_plic_id(kAdcCtrlDt, kDtAdcCtrlIrqMatchPending);
94 irq_global_ctrl(
true);
95 irq_external_ctrl(
true);
102 CHECK_DIF_OK(dif_adc_ctrl_init_from_dt(kAdcCtrlDt, &adc_ctrl));
103 CHECK_DIF_OK(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
104 CHECK_DIF_OK(dif_rstmgr_init_from_dt(kRstmgrDt, &rstmgr));
105 CHECK_DIF_OK(dif_rv_plic_init_from_dt(kRvPlicDt, &plic));
110 kDtAdcCtrlWakeupWkupReq, &wakeup_sources));
113 CHECK_DIF_OK(dif_adc_ctrl_irq_set_enabled(
116 uint16_t channel0_filter0_max =
117 (uint16_t)(kChannel0MaxHighByte << 8) | kChannel0MaxLowByte;
118 uint16_t channel0_filter0_min =
119 (uint16_t)(kChannel0MinHighByte << 8) | kChannel0MinLowByte;
120 uint16_t channel1_filter0_max =
121 (uint16_t)(kChannel1MaxHighByte << 8) | kChannel1MaxLowByte;
122 uint16_t channel1_filter0_min =
123 (uint16_t)(kChannel1MinHighByte << 8) | kChannel1MinLowByte;
126 if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, 0)) ==
true) {
128 interrupt_expected =
false;
135 configure_adc_ctrl(&adc_ctrl);
139 &adc_ctrl, kDifAdcCtrlChannel0,
141 .generate_irq_on_match =
true,
142 .generate_wakeup_on_match =
true,
144 .max_voltage = channel0_filter0_max,
145 .min_voltage = channel0_filter0_min},
148 &adc_ctrl, kDifAdcCtrlChannel1,
150 .generate_irq_on_match =
true,
151 .generate_wakeup_on_match =
true,
153 .max_voltage = channel1_filter0_max,
154 .min_voltage = channel1_filter0_min},
166 CHECK_STATUS_OK(rstmgr_testutils_pre_reset(&rstmgr));
168 pwrmgr_testutils_enable_low_power(&pwrmgr, wakeup_sources, 0));
170 LOG_INFO(
"Issued WFI to enter sleep.");
171 test_status_set(kTestStatusInWfi);
173 }
else if (UNWRAP(pwrmgr_testutils_is_wakeup_reason(
174 &pwrmgr, wakeup_sources)) ==
true) {
176 interrupt_expected =
true;
179 CHECK(UNWRAP(rstmgr_testutils_is_reset_info(
183 &adc_ctrl, kDifAdcCtrlChannel0, &adc_value));
184 CHECK(channel0_filter0_min <= adc_value &&
185 adc_value <= channel0_filter0_max);
188 &adc_ctrl, kDifAdcCtrlChannel1, &adc_value));
189 CHECK(channel1_filter0_min <= adc_value &&
190 adc_value <= channel1_filter0_max);
193 CHECK(interrupt_serviced);
199 LOG_ERROR(
"Unexpected wakeup detected: type = %d, request_source = %d",