Software APIs
sensor_ctrl_status.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 
9 #include "sw/device/lib/runtime/irq.h"
11 #include "sw/device/lib/testing/rv_plic_testutils.h"
12 #include "sw/device/lib/testing/test_framework/check.h"
14 
16 #include "sensor_ctrl_regs.h" // Generated.
17 #include "sw/device/lib/testing/autogen/isr_testutils.h"
18 
19 OTTF_DEFINE_TEST_CONFIG();
20 
21 /* In this test, the IO POK status is randomly change by an
22  * an external source (user or dv).
23  * Only 1 IO change is made at a time.
24  * When an IO change is made, an interrupt is triggered and
25  * checked by the device. After the interrupt, the status is
26  * is checked to ensure only 1 IO change was observed.
27  */
28 
29 static dif_sensor_ctrl_t sensor_ctrl;
30 static dif_rv_plic_t plic;
31 static plic_isr_ctx_t plic_ctx = {.rv_plic = &plic,
32  .hart_id = kTopEarlgreyPlicTargetIbex0};
33 
34 static sensor_ctrl_isr_ctx_t sensor_ctrl_isr_ctx = {
35  .sensor_ctrl = &sensor_ctrl,
36  .plic_sensor_ctrl_start_irq_id =
38  .expected_irq = kDifSensorCtrlIrqIoStatusChange,
39  .is_only_irq = false};
40 
41 /**
42  * External interrupt handler.
43  */
44 void ottf_external_isr(uint32_t *exc_info) {
45  dif_sensor_ctrl_irq_t irq_id;
47 
48  isr_testutils_sensor_ctrl_isr(plic_ctx, sensor_ctrl_isr_ctx, &peripheral,
49  &irq_id);
50 
51  // Check that both the peripheral and the irq id is correct
52  CHECK(peripheral == kTopEarlgreyPlicPeripheralSensorCtrlAon,
53  "IRQ peripheral: %d is incorrect", peripheral);
54  CHECK(irq_id == kDifSensorCtrlIrqIoStatusChange, "IRQ ID: %d is incorrect",
55  irq_id);
56 }
57 
58 bool test_main(void) {
59  uint32_t iterations = 10;
60  uint32_t io_mask = (1 << SENSOR_CTRL_PARAM_NUM_IO_RAILS) - 1;
61  dif_sensor_ctrl_io_power_status_t last_io_status, curr_io_status;
62 
63  // Enable global and external IRQ at Ibex.
64  irq_global_ctrl(true);
65  irq_external_ctrl(true);
66 
67  // Initialize the PLIC.
68  CHECK_DIF_OK(dif_rv_plic_init(
70 
71  // Initialize sensor_ctrl
72  CHECK_DIF_OK(dif_sensor_ctrl_init(
74  &sensor_ctrl));
75 
76  // Enable interrupts
77  rv_plic_testutils_irq_range_enable(
81 
82  // Acknowledge the interrupt state that sets by default
83  CHECK_DIF_OK(dif_sensor_ctrl_irq_acknowledge_all(&sensor_ctrl));
84 
85  // Enable sensor_ctrl interrupt
86  CHECK_DIF_OK(dif_sensor_ctrl_irq_set_enabled(
87  &sensor_ctrl, kDifSensorCtrlIrqIoStatusChange, kDifToggleEnabled));
88 
89  last_io_status = io_mask;
90  for (uint32_t i = 0; i < iterations; ++i) {
91  LOG_INFO("Waiting for IO change");
93  CHECK_DIF_OK(
94  dif_sensor_ctrl_get_io_power_status(&sensor_ctrl, &curr_io_status));
95  CHECK(bitfield_popcount32(last_io_status ^ curr_io_status) == 1);
96  last_io_status = curr_io_status;
97  LOG_INFO("IO change complete");
98  }
99 
100  return true;
101 }