4 #include "sw/device/lib/testing/json/i2c_target.h"
17 #include "sw/device/lib/runtime/irq.h"
20 #include "sw/device/lib/testing/i2c_testutils.h"
21 #include "sw/device/lib/testing/json/command.h"
22 #include "sw/device/lib/testing/pwrmgr_testutils.h"
23 #include "sw/device/lib/testing/rv_plic_testutils.h"
24 #include "sw/device/lib/testing/test_framework/check.h"
25 #include "sw/device/lib/testing/test_framework/ottf_console.h"
27 #include "sw/device/lib/testing/test_framework/ujson_ottf.h"
28 #include "sw/device/lib/ujson/ujson.h"
30 static_assert(__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__,
31 "This test assumes the target platform is little endian.");
33 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control =
true);
36 kTestTimeout = 1000000,
37 kTransactionDelay = 10000,
41 static const dt_pwrmgr_t kPwrmgrDt = 0;
42 static_assert(kDtPwrmgrCount == 1,
"this test expects a pwrmgr");
43 static const dt_rv_plic_t kRvPlicDt = 0;
44 static_assert(kDtRvPlicCount == 1,
"this test expects exactly one rv_plic");
45 static const dt_pinmux_t kPinmuxDt = 0;
46 static_assert(kDtPinmuxCount == 1,
"this test expects exactly one pinmux");
48 static dif_pinmux_t pinmux;
49 static dif_pwrmgr_t pwrmgr;
50 static dif_rv_plic_t plic;
53 static uint8_t i2c_instance_under_test = 0;
54 static uint32_t i2c_clock_stretching_delay_micros = 0;
59 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
61 if (devid == dt_pwrmgr_instance_id(kPwrmgrDt) &&
62 irq_id == dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup)) {
63 CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr, kDtPwrmgrIrqWakeup));
70 static status_t reset_fifos(dif_i2c_t *i2c) {
78 static status_t i2c_detach_instance(dif_i2c_t *i2c, dif_pinmux_t *pinmux,
79 uint8_t i2c_instance) {
81 return i2c_testutils_detach_pinmux(pinmux, i2c_instance);
84 static status_t i2c_configure_instance(dif_i2c_t *i2c, dif_pinmux_t *pinmux,
85 uint8_t i2c_instance) {
86 TRY_CHECK(i2c_instance < kDtI2cCount);
88 dt_i2c_t dt_i2c = i2c_instance;
89 TRY(dif_i2c_init_from_dt(dt_i2c, i2c));
91 TRY(i2c_testutils_select_pinmux(pinmux, i2c_instance,
92 I2cPinmuxPlatformIdHyper310));
99 i2c_target_address_t address;
100 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_target_address_t, uj, &address));
105 TRY(i2c_detach_instance(i2c, &pinmux, i2c_instance_under_test));
106 i2c_instance_under_test = address.instance;
107 TRY(i2c_configure_instance(i2c, &pinmux, i2c_instance_under_test));
110 .
mask = address.mask0,
111 .address = address.id0,
114 .
mask = address.mask1,
115 .address = address.id1,
121 TRY(reset_fifos(i2c));
122 return RESP_OK_STATUS(uj);
131 acq_fifo_lvl >= at_least) {
135 return DEADLINE_EXCEEDED();
138 static status_t recv_write_transfer(dif_i2c_t *i2c, i2c_transfer_start_t *txn,
139 uint32_t micros, uint32_t delay_micros) {
145 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
150 txn->address =
byte >> 1;
154 if (txn->length % 64 == 0 && delay_micros) {
157 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
162 txn->data[txn->length++] = byte;
173 return OK_STATUS(txn->address);
180 i2c_transfer_start_t txn;
181 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_transfer_start_t, uj, &txn));
183 TRY(i2c_testutils_target_read(i2c, txn.length, txn.data));
185 TRY(wait_for_acq_fifo(i2c, 2, &deadline));
187 TRY(i2c_testutils_target_check_read(i2c, &address, NULL));
188 TRY_CHECK(txn.address == address,
"Address read (%x) is not the expected(%x)",
189 address, txn.address);
190 return RESP_OK_STATUS(uj);
194 uint32_t delay_micros) {
195 i2c_transfer_start_t txn = (i2c_transfer_start_t){0};
196 TRY(recv_write_transfer(i2c, &txn, kTestTimeout, delay_micros));
197 return RESP_OK(ujson_serialize_i2c_transfer_start_t, uj, &txn);
200 static status_t start_write_read_transaction(
ujson_t *uj, dif_i2c_t *i2c) {
201 i2c_transfer_start_t read_trans;
202 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_transfer_start_t, uj, &read_trans));
203 TRY(i2c_testutils_target_read(i2c, read_trans.length, read_trans.data));
205 i2c_transfer_start_t write_trans = (i2c_transfer_start_t){0};
207 (uint8_t)TRY(recv_write_transfer(i2c, &write_trans, kTestTimeout, 0));
208 TRY_CHECK(write_trans.stop ==
false,
"Stop bit not expected at this point.");
209 TRY_CHECK(read_trans.address == address,
210 "Address (0x%x) is not the expected(0x%x)", address,
213 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
215 return RESP_OK(ujson_serialize_i2c_transfer_start_t, uj, &write_trans);
218 static status_t enter_sleep(
ujson_t *uj, dif_i2c_t *i2c,
bool normal) {
221 .signal_filter =
false,
231 dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup);
232 rv_plic_testutils_irq_range_enable(&plic, kPlicTarget, plic_id, plic_id);
238 pwrmgr_domain_cfg |= kDifPwrmgrDomainOptionMainPowerInLowPower;
241 TRY(pwrmgr_testutils_enable_low_power(
242 &pwrmgr, kDifPwrmgrWakeupRequestSourceThree, pwrmgr_domain_cfg));
250 return RESP_OK_STATUS(uj);
255 LOG_ERROR(
"Unexpected wake from deep sleep.");
261 if (TRY(pwrmgr_testutils_is_wakeup_reason(
262 &pwrmgr, kDifPwrmgrWakeupRequestSourceThree)) ==
true) {
263 LOG_ERROR(
"Woke from deep sleep; resuming test.");
267 return RESP_OK_STATUS(uj);
273 TRY(wakeup_check(uj, &i2c));
275 test_command_t command;
276 TRY(UJSON_WITH_CRC(ujson_deserialize_test_command_t, uj, &command));
278 case kTestCommandEnterNormalSleep:
279 RESP_ERR(uj, enter_sleep(uj, &i2c,
true));
281 case kTestCommandEnterDeepSleep:
282 RESP_ERR(uj, enter_sleep(uj, &i2c,
false));
284 case kTestCommandI2cTargetAddress:
285 RESP_ERR(uj, configure_device_address(uj, &i2c));
287 case kTestCommandI2cStartTransferWrite:
288 RESP_ERR(uj, start_write_transaction(uj, &i2c, 0));
290 case kTestCommandI2cStartTransferRead:
291 RESP_ERR(uj, start_read_transaction(uj, &i2c));
293 case kTestCommandI2cStartTransferWriteRead:
294 RESP_ERR(uj, start_write_read_transaction(uj, &i2c));
296 case kTestCommandI2cStartTransferWriteSlow:
299 RESP_ERR(uj, start_write_transaction(uj, &i2c, kTransactionDelay));
301 case kTestCommandI2cTestConfig: {
302 i2c_test_config_t config;
303 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_test_config_t, uj, &config));
304 i2c_clock_stretching_delay_micros =
305 config.clock_stretching_delay_millis * 1000;
306 RESP_ERR(uj, RESP_OK_STATUS(uj));
309 LOG_ERROR(
"Unrecognized command: %d", command);
310 RESP_ERR(uj, INVALID_ARGUMENT());
318 TRY(dif_pinmux_init_from_dt(kPinmuxDt, &pinmux));
320 TRY(dif_pwrmgr_init_from_dt(kPwrmgrDt, &pwrmgr));
322 TRY(dif_rv_plic_init_from_dt(kRvPlicDt, &plic));
325 irq_global_ctrl(
true);
326 irq_external_ctrl(
true);
332 CHECK_STATUS_OK(test_init());
334 i2c_configure_instance(&i2c, &pinmux, i2c_instance_under_test));
336 ujson_t uj = ujson_ottf_console();
337 status = command_processor(&uj);