Software APIs
i2c_host_compass_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 #include <assert.h>
5 
15 #include "sw/device/lib/testing/i2c_testutils.h"
16 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
17 #include "sw/device/lib/testing/test_framework/check.h"
19 
21 #include "i2c_regs.h" // Generated.
22 
23 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
24  "This test assumes the target platform is little endian.");
25 
26 OTTF_DEFINE_TEST_CONFIG();
27 
28 enum {
29  kDeviceAddr = 0x30,
30 
31  // Registers
32  kProductIdReg = 0x20,
33  kXOutLowReg = 0x00,
34  kXOutHighReg = 0x01,
35  kYOutLowReg = 0x02,
36  kYOutHighReg = 0x03,
37  kZOutLowReg = 0x04,
38  kZOutHighReg = 0x05,
39  kStatusReg = 0x06,
40  kInternalControlReg = 0x07,
41 
42  // Registers values
43  kProductId = 0x06,
44 
45  // Bit masks
46  kMeasDone = 0x01,
47 
48  kDefaultTimeoutMicros = 5000,
49 };
50 
51 static dif_rv_core_ibex_t rv_core_ibex;
52 static dif_pinmux_t pinmux;
53 static dif_i2c_t i2c;
54 
55 static status_t read_product_id(void) {
56  uint8_t reg = kProductIdReg, data = 0;
57  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &reg, true));
58  TRY(i2c_testutils_read(&i2c, kDeviceAddr, 1, &data, kDefaultTimeoutMicros));
59  TRY_CHECK(data == kProductId, "Unexpected value %x", data);
60  return OK_STATUS();
61 }
62 
63 static status_t take_measurement(void) {
64  // Write 0b1 (take measurement) to the internal control register.
65  uint8_t write_data[2] = {kInternalControlReg, 0x01};
66  TRY(i2c_testutils_write(&i2c, kDeviceAddr, sizeof(write_data), write_data,
67  true));
68 
69  // Poll until status indicates measurement was taken.
70  uint8_t status = 0;
71  uint8_t status_reg = kStatusReg;
72  do {
73  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &status_reg, true));
74  TRY(i2c_testutils_read(&i2c, kDeviceAddr, sizeof(status), &status,
75  kDefaultTimeoutMicros));
76  } while ((status & kMeasDone) == 0);
77 
78  LOG_INFO("Status:%x", status);
79 
80  // Reading six bytes from Xout Low covers the other "out" registers, too.
81  uint8_t read_data[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
82  uint8_t xout_reg = kXOutLowReg;
83  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &xout_reg, true));
84  TRY(i2c_testutils_read(&i2c, kDeviceAddr, sizeof(read_data), read_data,
85  kDefaultTimeoutMicros));
86 
87  // Check the registers didn't all read as 0x00, which could be legitimate
88  // measurements, but are more likely to show a read failure.
89  uint8_t all_bits = 0x00;
90  for (size_t i = 0; i < ARRAYSIZE(read_data); ++i) {
91  all_bits |= read_data[i];
92  }
93  TRY_CHECK(all_bits != 0x00, "All measurement registers zero");
94 
95  return OK_STATUS();
96 }
97 
98 static status_t test_init(void) {
99  mmio_region_t base_addr =
101 
102  TRY(dif_rv_core_ibex_init(base_addr, &rv_core_ibex));
103 
105  TRY(dif_i2c_init(base_addr, &i2c));
106 
108  TRY(dif_pinmux_init(base_addr, &pinmux));
109 
110  TRY(i2c_testutils_select_pinmux(&pinmux, 2, I2cPinmuxPlatformIdCw310Pmod));
111 
113 
114  return OK_STATUS();
115 }
116 
117 static status_t reset_i2c_and_check(void) {
118  dif_rstmgr_t rstmgr;
120  &rstmgr));
121 
122  TRY(dif_rstmgr_software_reset(&rstmgr, kTopEarlgreyResetManagerSwResetsI2c2,
124 
125  dif_i2c_status_t i2c_status;
126  TRY(dif_i2c_get_status(&i2c, &i2c_status));
127  TRY_CHECK(!i2c_status.enable_host, "I2C doesn't appear to have been reset.");
128 
130  return OK_STATUS();
131 }
132 
133 bool test_main(void) {
134  status_t test_result;
135  CHECK_STATUS_OK(test_init());
136 
138 
139  test_result = OK_STATUS();
140  for (size_t i = 0; i < ARRAYSIZE(speeds); ++i) {
141  CHECK_STATUS_OK(i2c_testutils_set_speed(&i2c, speeds[i]));
142  EXECUTE_TEST(test_result, read_product_id);
143  EXECUTE_TEST(test_result, take_measurement);
144  }
145 
146  // Reset the i2c peripheral and re-run a test
147  // to check the peripheral works after reset.
148  CHECK_STATUS_OK(reset_i2c_and_check());
149  CHECK_STATUS_OK(i2c_testutils_set_speed(&i2c, kDifI2cSpeedFast));
150  EXECUTE_TEST(test_result, read_product_id);
151 
152  return status_ok(test_result);
153 }