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;
54 static uint8_t i2c_instance_under_test = 0;
55 static uint32_t i2c_clock_stretching_delay_micros = 0;
60 bool ottf_handle_irq(uint32_t *exc_info, dt_instance_id_t devid,
62 if (devid == dt_pwrmgr_instance_id(kPwrmgrDt) &&
63 irq_id == dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup)) {
64 CHECK_DIF_OK(dif_pwrmgr_irq_acknowledge(&pwrmgr, kDtPwrmgrIrqWakeup));
71 static status_t reset_fifos(dif_i2c_t *i2c) {
79 static status_t i2c_detach_instance(dif_i2c_t *i2c, dif_pinmux_t *pinmux,
80 uint8_t i2c_instance) {
82 return i2c_testutils_detach_pinmux(pinmux, i2c_instance);
85 static status_t i2c_configure_instance(dif_i2c_t *i2c, dif_pinmux_t *pinmux,
86 uint8_t i2c_instance) {
87 TRY_CHECK(i2c_instance < kDtI2cCount);
89 dt_i2c_t dt_i2c = i2c_instance;
90 TRY(dif_i2c_init_from_dt(dt_i2c, i2c));
92 TRY(i2c_testutils_select_pinmux(pinmux, i2c_instance,
93 I2cPinmuxPlatformIdHyper310));
100 i2c_target_address_t address;
101 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_target_address_t, uj, &address));
106 TRY(i2c_detach_instance(i2c, &pinmux, i2c_instance_under_test));
107 i2c_instance_under_test = address.instance;
108 TRY(i2c_configure_instance(i2c, &pinmux, i2c_instance_under_test));
111 .
mask = address.mask0,
112 .address = address.id0,
115 .
mask = address.mask1,
116 .address = address.id1,
122 TRY(reset_fifos(i2c));
123 return RESP_OK_STATUS(uj);
132 acq_fifo_lvl >= at_least) {
136 return DEADLINE_EXCEEDED();
139 static status_t recv_write_transfer(dif_i2c_t *i2c, i2c_transfer_start_t *txn,
140 uint32_t micros, uint32_t delay_micros) {
146 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
151 txn->address =
byte >> 1;
155 if (txn->length % 64 == 0 && delay_micros) {
158 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
163 txn->data[txn->length++] = byte;
174 return OK_STATUS(txn->address);
181 i2c_transfer_start_t txn;
182 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_transfer_start_t, uj, &txn));
184 TRY(i2c_testutils_target_read(i2c, txn.length, txn.data));
186 TRY(wait_for_acq_fifo(i2c, 2, &deadline));
188 TRY(i2c_testutils_target_check_read(i2c, &address, NULL));
189 TRY_CHECK(txn.address == address,
"Address read (%x) is not the expected(%x)",
190 address, txn.address);
191 return RESP_OK_STATUS(uj);
195 uint32_t delay_micros) {
196 i2c_transfer_start_t txn = (i2c_transfer_start_t){0};
197 TRY(recv_write_transfer(i2c, &txn, kTestTimeout, delay_micros));
198 return RESP_OK(ujson_serialize_i2c_transfer_start_t, uj, &txn);
201 static status_t start_write_read_transaction(
ujson_t *uj, dif_i2c_t *i2c) {
202 i2c_transfer_start_t read_trans;
203 TRY(UJSON_WITH_CRC(ujson_deserialize_i2c_transfer_start_t, uj, &read_trans));
204 TRY(i2c_testutils_target_read(i2c, read_trans.length, read_trans.data));
206 i2c_transfer_start_t write_trans = (i2c_transfer_start_t){0};
208 (uint8_t)TRY(recv_write_transfer(i2c, &write_trans, kTestTimeout, 0));
209 TRY_CHECK(write_trans.stop ==
false,
"Stop bit not expected at this point.");
210 TRY_CHECK(read_trans.address == address,
211 "Address (0x%x) is not the expected(0x%x)", address,
214 TRY(wait_for_acq_fifo(i2c, 1, &deadline));
216 return RESP_OK(ujson_serialize_i2c_transfer_start_t, uj, &write_trans);
219 static status_t enter_sleep(
ujson_t *uj, dif_i2c_t *i2c,
bool normal) {
222 .signal_filter =
false,
232 dt_pwrmgr_irq_to_plic_id(kPwrmgrDt, kDtPwrmgrIrqWakeup);
233 rv_plic_testutils_irq_range_enable(&plic, kPlicTarget, plic_id, plic_id);
239 pwrmgr_domain_cfg |= kDifPwrmgrDomainOptionMainPowerInLowPower;
242 TRY(pwrmgr_testutils_enable_low_power(&pwrmgr, wakeup_sources,
251 return RESP_OK_STATUS(uj);
256 LOG_ERROR(
"Unexpected wake from deep sleep.");
262 if (TRY(pwrmgr_testutils_is_wakeup_reason(&pwrmgr, wakeup_sources)) ==
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));
324 kDtPinmuxWakeupPinWkupReq, &wakeup_sources));
326 TRY(dif_rv_plic_init_from_dt(kRvPlicDt, &plic));
329 irq_global_ctrl(
true);
330 irq_external_ctrl(
true);
336 CHECK_STATUS_OK(test_init());
338 i2c_configure_instance(&i2c, &pinmux, i2c_instance_under_test));
340 ujson_t uj = ujson_ottf_console();
341 status = command_processor(&uj);