Software APIs
otp_ctrl_smoketest.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 
5 #include <assert.h>
6 #include <stdbool.h>
7 
8 #include "dt/dt_otp_ctrl.h"
14 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
15 #include "sw/device/lib/testing/test_framework/check.h"
17 
18 static dif_otp_ctrl_t otp;
19 
20 static const char kTestData[] = "abcdefghijklmno";
21 static_assert(ARRAYSIZE(kTestData) % sizeof(uint32_t) == 0,
22  "kTestData must be a word array");
23 
24 static_assert(kDtOtpCtrlCount >= 1,
25  "This test requires at least one OTP Control instance");
26 
27 static dt_otp_ctrl_t kTestOtpCtrl = (dt_otp_ctrl_t)0;
28 
29 OTTF_DEFINE_TEST_CONFIG();
30 
31 /**
32  * Tests that the OTP can be programed in a particular spot, and that the
33  * value can then be read out exactly through the blocking read interface.
34  */
35 bool test_main(void) {
36  CHECK_DIF_OK(dif_otp_ctrl_init_from_dt(kTestOtpCtrl, &otp));
37 
38  dif_otp_ctrl_config_t config = {
39  .check_timeout = 100000,
40  .integrity_period_mask = 0x3ffff,
41  .consistency_period_mask = 0x3ffffff,
42  };
43  CHECK_DIF_OK(dif_otp_ctrl_configure(&otp, config));
44 
45  for (uint32_t i = 0; i < ARRAYSIZE(kTestData); i += sizeof(uint32_t)) {
46  uint32_t word;
47  memcpy(&word, &kTestData[i], sizeof(word));
48 
49  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
50  CHECK_DIF_OK(dif_otp_ctrl_dai_program32(
51  &otp, kDifOtpCtrlPartitionVendorTest, 0x10 + i, word),
52  "Failed to program word kTestData[%d] = 0x%08x.", i, word);
53  }
54  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
55 
56  uint32_t readout[ARRAYSIZE(kTestData) / sizeof(uint32_t)] = {0};
58  0x10, readout, ARRAYSIZE(kTestData)),
59  "Failed to perform OTP blocking readout.");
60 
61  CHECK(memcmp(kTestData, readout, ARRAYSIZE(kTestData)) == 0);
62 
63  return true;
64 }