Software APIs
uart_baud_rate_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 #include <stdint.h>
6 
12 #include "sw/device/lib/testing/test_framework/check.h"
13 #include "sw/device/lib/testing/test_framework/ottf_console.h"
15 #include "sw/device/lib/testing/test_framework/ottf_utils.h"
16 #include "sw/device/lib/testing/uart_testutils.h"
17 
19 
20 static const uint8_t kSendData[] = "UART baud test!";
21 static const uint32_t kBaseAddrs[4] = {
26 };
27 static const uint32_t kBauds[11] = {
28  4800, 9600, 19200, 38400, 57600, 115200, 230400, 128000, 256000, 1000000,
29  // This baud rate will only work on silicon, the FPGA cannot go fast enough:
30  1500000};
31 
32 enum {
33  kTestTimeoutMillis = 500000,
34 };
35 
36 typedef enum test_phase {
37  kTestPhaseInit,
38  kTestPhaseCfg,
39  kTestPhaseSend,
40  kTestPhaseRecv,
41  kTestPhaseDone,
42 } test_phase_t;
43 
44 static volatile uint8_t test_phase = kTestPhaseInit;
45 static volatile uint8_t uart_idx = UINT8_MAX;
46 static volatile uint32_t baud_rate = UINT32_MAX;
47 
48 static dif_uart_t uart;
49 static dif_pinmux_t pinmux;
50 
51 OTTF_DEFINE_TEST_CONFIG(.enable_uart_flow_control = true);
52 
53 // Send all bytes in `kSendData`, and check that they are received via the
54 // loopback mechanism.
55 static status_t test_uart_baud(void) {
56  test_phase = kTestPhaseCfg;
57 
58  TRY(dif_uart_configure(&uart,
60  .baudrate = (uint32_t)baud_rate,
61  .clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
62  .parity_enable = kDifToggleDisabled,
63  .parity = kDifUartParityEven,
64  .tx_enable = kDifToggleEnabled,
65  .rx_enable = kDifToggleEnabled,
66  }));
67 
69 
70  LOG_INFO("Configured UART%d with Baud rate %d", uart_idx, baud_rate);
71 
72  OTTF_WAIT_FOR(test_phase == kTestPhaseSend, kTestTimeoutMillis);
73 
74  LOG_INFO("Sending data...");
75  TRY(dif_uart_bytes_send(&uart, kSendData, sizeof(kSendData), NULL));
76  LOG_INFO("Data sent");
77 
78  OTTF_WAIT_FOR(test_phase == kTestPhaseRecv, kTestTimeoutMillis);
79 
80  LOG_INFO("Receiving data...");
81  uint8_t data[sizeof(kSendData)] = {0};
82  for (size_t i = 0; i < sizeof(data); ++i) {
83  TRY(dif_uart_byte_receive_polled(&uart, &data[i]));
84  }
85  TRY_CHECK_ARRAYS_EQ(data, kSendData, sizeof(kSendData));
86 
87  test_phase = kTestPhaseDone;
88 
89  return OK_STATUS();
90 }
91 
92 bool test_main(void) {
93  OTTF_WAIT_FOR(uart_idx != 0xff, kTestTimeoutMillis);
94 
95  mmio_region_t base_addr;
96 
98  CHECK_DIF_OK(dif_pinmux_init(base_addr, &pinmux));
99 
100  base_addr = mmio_region_from_addr(kBaseAddrs[uart_idx]);
101  CHECK_DIF_OK(dif_uart_init(base_addr, &uart));
102 
103  if (uart_idx == 0) {
104  CHECK_STATUS_OK(
105  uart_testutils_select_pinmux(&pinmux, 1, kUartPinmuxChannelConsole));
106  ottf_console_configure_uart(TOP_EARLGREY_UART1_BASE_ADDR);
107  }
108 
109  CHECK_STATUS_OK(
110  uart_testutils_select_pinmux(&pinmux, uart_idx, kUartPinmuxChannelDut));
111 
112  size_t baud_count = ARRAYSIZE(kBauds);
113 
114  // We only want to run the highest bauds (1MBd and 1.5MBd) on chips going
115  // at the real speed (24MHz). FPGAs clocking slower cannot test these.
116  if (kClockFreqPeripheralHz < 24 * 1000 * 1000) {
117  baud_count -= 2;
118  }
119 
120  // Check every baud rate is sent and received okay.
121  status_t result = OK_STATUS();
122  for (size_t baud_idx = 0; baud_idx < baud_count; ++baud_idx) {
123  baud_rate = kBauds[baud_idx];
124  EXECUTE_TEST(result, test_uart_baud);
125  }
126  return status_ok(result);
127 }