Software APIs
i2c_host_ambient_light_detector_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 
14 #include "sw/device/lib/testing/i2c_testutils.h"
15 #include "sw/device/lib/testing/rv_core_ibex_testutils.h"
16 #include "sw/device/lib/testing/test_framework/check.h"
18 
20 #include "i2c_regs.h" // Generated.
21 
22 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
23  "This test assumes the target platform is little endian.");
24 
25 OTTF_DEFINE_TEST_CONFIG();
26 
27 enum {
28  kDeviceAddr = 0x29,
29 
30  // Registers
31  kPartIdReg = 0x86,
32  kManufacturerIdReg = 0x87,
33  kAlsContrReg = 0x80,
34  kAlsMeasRateReg = 0x85,
35  kAlsDataCh10Reg = 0x88,
36  kAlsDataCh11Reg = 0x89,
37  kAlsDataCh00Reg = 0x8A,
38  kAlsDataCh01Reg = 0x8B,
39  kAlsStatusReg = 0x8C,
40 
41  // Registers values
42  kPartId = 0xA0,
43  kManufacturerId = 0x05,
44  kCtrlActive = 0x01,
45  kMeasRate = 0x01 << 3 | 0x02,
46 
47  // Register masks
48  kDataStatus = 1 << 2,
49 
50  // Other
51  kDefaultTimeoutMicros = 1000,
52 };
53 
54 static dif_rv_core_ibex_t rv_core_ibex;
55 static dif_pinmux_t pinmux;
56 static dif_i2c_t i2c;
57 
58 static status_t read_part_id(void) {
59  uint8_t reg = kPartIdReg, data = 0;
60  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &reg, true));
61  TRY(i2c_testutils_read(&i2c, kDeviceAddr, 1, &data, kDefaultTimeoutMicros));
62  TRY_CHECK(data == kPartId, "Unexpected value %x", data);
63  return OK_STATUS();
64 }
65 
66 static status_t read_manufacturer_id(void) {
67  uint8_t reg = kManufacturerIdReg, data = 0;
68  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &reg, true));
69  TRY(i2c_testutils_read(&i2c, kDeviceAddr, 1, &data, kDefaultTimeoutMicros));
70  TRY_CHECK(data == kManufacturerId, "Unexpected value %x", data);
71  return OK_STATUS();
72 }
73 
74 static status_t write_read_measure_rate(void) {
75  // Set the measurement rate to something non-default.
76  uint8_t meas_reg = kAlsMeasRateReg;
77  uint8_t rate[2] = {meas_reg, kMeasRate};
78  TRY(i2c_testutils_write(&i2c, kDeviceAddr, sizeof(rate), rate, true));
79  // Read back to confirm the write.
80  uint8_t rate_data = 0;
81  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &meas_reg, true));
82  TRY(i2c_testutils_read(&i2c, kDeviceAddr, 1, &rate_data,
83  kDefaultTimeoutMicros));
84  TRY_CHECK(rate_data == kMeasRate, "Unexpected value %x", rate_data);
85 
86  return OK_STATUS();
87 }
88 
89 static status_t take_measurement(void) {
90  // Enable active measurements.
91  uint8_t ctrl_reg = kAlsContrReg;
92  uint8_t ctrl[2] = {ctrl_reg, kCtrlActive};
93  TRY(i2c_testutils_write(&i2c, kDeviceAddr, sizeof(ctrl), ctrl, true));
94  // Read back the ctrl register to confirm active measurement mode was set.
95  uint8_t ctrl_data = 0;
96  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &ctrl_reg, true));
97  TRY(i2c_testutils_read(&i2c, kDeviceAddr, 1, &ctrl_data,
98  kDefaultTimeoutMicros));
99  TRY_CHECK(ctrl_data == kCtrlActive, "Unexpected value %x", ctrl_data);
100 
101  // Poll until the status register sets the "data status" bit.
102  uint8_t status_reg = kAlsStatusReg;
103  uint8_t status = 0;
104  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &status_reg, true));
105  do {
106  TRY(i2c_testutils_read(&i2c, kDeviceAddr, sizeof(status), &status,
107  kDefaultTimeoutMicros));
108  } while ((status & kDataStatus) == 0);
109 
110  // Read data in the order it's laid out in memory: 10, 11, 00, 01.
111  uint8_t data_start = kAlsDataCh10Reg;
112  uint8_t data[4] = {0xFF, 0xFF, 0xFF, 0xFF};
113  TRY(i2c_testutils_write(&i2c, kDeviceAddr, 1, &data_start, true));
114  TRY(i2c_testutils_read(&i2c, kDeviceAddr, sizeof(data), data,
115  kDefaultTimeoutMicros));
116 
117  // Check data isn't all 0xFF, which are more likely to be errors
118  // than real values.
119  uint8_t all_ff[4] = {0xFF, 0xFF, 0xFF, 0xFF};
120  LOG_INFO("Measured data: [0x%02x, 0x%02x, 0x%02x, 0x%02x]", data[0], data[1],
121  data[2], data[3]);
122  TRY_CHECK_ARRAYS_NE(data, all_ff, sizeof(data));
123 
124  return OK_STATUS();
125 }
126 
127 static status_t test_init(void) {
128  mmio_region_t base_addr =
130 
131  TRY(dif_rv_core_ibex_init(base_addr, &rv_core_ibex));
132 
134  TRY(dif_i2c_init(base_addr, &i2c));
135 
137  TRY(dif_pinmux_init(base_addr, &pinmux));
138 
139  TRY(i2c_testutils_select_pinmux(&pinmux, 2, I2cPinmuxPlatformIdCw310Pmod));
140 
142 
143  return OK_STATUS();
144 }
145 
146 bool test_main(void) {
147  status_t test_result;
148  CHECK_STATUS_OK(test_init());
149 
151 
152  // Give the device 100ms to start up.
153  busy_spin_micros(100000);
154 
155  test_result = OK_STATUS();
156  for (size_t i = 0; i < ARRAYSIZE(speeds); ++i) {
157  CHECK_STATUS_OK(i2c_testutils_set_speed(&i2c, speeds[i]));
158  EXECUTE_TEST(test_result, read_part_id);
159  EXECUTE_TEST(test_result, read_manufacturer_id);
160  EXECUTE_TEST(test_result, write_read_measure_rate);
161  EXECUTE_TEST(test_result, take_measurement);
162  }
163 
164  return status_ok(test_result);
165 }