Software APIs
usbdev_logging_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 //
5 // USB logging test
6 //
7 // This test exercises the USB logging functionality. It first initializes
8 // 4 logging streams via the USB device and cable to the host, and then
9 // transmits a number of tests messages to each stream directly.
10 //
11 // Subsequently, it reinitializes the software layer with redirection of
12 // stdout via a single stream and performs, to check that the LOG_INFO()
13 // and base_printf() functionality works over the USB connection.
14 //
15 // Currently this test requires manual support on the host side; on a Linux-
16 // based host, running 4 processes as follows will allow the test to complete:
17 //
18 // cat /dev/ttyUSB0
19 // cat /dev/ttyUSB1
20 // cat /dev/ttyUSB2
21 // cat /dev/ttyUSB3
22 //
23 // Note that the assigned port numbers on the host may differ from the defaults
24 // shown above. Since the logging streams have been initialized for reliable
25 // transfer, the CPU/test will stall until the receiving processes on the host
26 // have collected all of the logging output.
27 
31 #include "sw/device/lib/testing/usb_logging.h"
32 
33 // Presently we must reinstate the UART output manually.
35 
36 #include "hw/top_earlgrey/sw/autogen/top_earlgrey.h" // Generated.
37 
38 /**
39  * Number of concurrent logging streams to test.
40  */
41 static const unsigned kNumStreams = 4u;
42 /**
43  * Number of iterations of logging message.
44  */
45 static const unsigned kNumIters = 1000u;
46 
47 // Because this test redirects the console output to the USB, we need to
48 // indicate to OTTF that the console must be reinitialized before test
49 // completion can be reported.
50 OTTF_DEFINE_TEST_CONFIG(.console.test_may_clobber = true);
51 
52 bool test_main(void) {
53  LOG_INFO("Running USBDEV_LOGGING test");
54 
55  // ----------------- Test the more generic, direct interface ----------------
56 
57  // Enable USB logging
58  CHECK_STATUS_OK(
59  usb_logging_init(NULL, 0u, kNumStreams, (1u << kNumStreams) - 1u, true));
60 
61  for (uint8_t s = 0u; s < kNumStreams; ++s) {
62  usb_logging_text(s, "USB - Logging via direct interface\n");
63  }
64 
65  for (unsigned iter = 0u; iter < kNumIters; ++iter) {
66  for (uint8_t s = 0u; s < kNumStreams; ++s) {
67  char buf[44];
68  size_t len = base_snprintf(buf, sizeof(buf),
69  "S%u: Now logging %u over USB\n", s, iter);
70  CHECK_STATUS_OK(usb_logging_data(s, (uint8_t *)buf, len));
71  }
72  }
73 
74  // Finalize the logging code.
75  CHECK_STATUS_OK(usb_logging_fin(true, false));
76 
77  // ------------------- Test redirection of stdout via OTTF ------------------
78 
79  // Enable logging of stdout traffic over USB
80  CHECK_STATUS_OK(usb_logging_enable());
81 
82  for (unsigned iter = 0u; iter < kNumIters; ++iter) {
83  LOG_INFO("Now logging %u over USB", iter);
84  }
85 
86  // Just a quantity of data as ASCII hex...
87  const uint32_t kSramStart = TOP_EARLGREY_SRAM_CTRL_MAIN_RAM_BASE_ADDR;
88  const uint32_t kSramSize = TOP_EARLGREY_SRAM_CTRL_MAIN_RAM_SIZE_BYTES;
89  base_hexdump((char *)kSramStart, kSramSize);
90 
91  CHECK_STATUS_OK(usb_logging_fin(true, true));
92 
93  return true;
94 }