Software APIs
uart_testutils.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 "sw/device/lib/testing/uart_testutils.h"
6 
7 #include <assert.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 
17 #include "sw/device/lib/testing/pinmux_testutils.h"
18 #include "sw/device/lib/testing/test_framework/check.h"
19 
21 #include "uart_regs.h" // Generated.
22 
23 #define MODULE_ID MAKE_MODULE_ID('u', 't', 'u')
24 
25 /**
26  * This table stores the pins for all UART instances of Earlgrey.
27  */
28 static const pinmux_testutils_peripheral_pin_t kUartPinmuxPins[] = {
29  // UART0.
30  {
33  },
34  // UART1.
35  {
38  },
39  // UART2.
40  {
43  },
44  // UART3.
45  {
48  },
49 };
50 
51 /**
52  * This table stores UART pin mappings for synthesized platforms.
53  */
54 static const pinmux_testutils_mio_pin_t
55  kUartSynthPins[kUartPinmuxChannelCount] = {
56  [kUartPinmuxChannelConsole] =
57  {
60  },
61  [kUartPinmuxChannelDut] = {
64  }};
65 
66 /**
67  * The DV platform is handled separately at the moment: all four UARTs have
68  * their own channels that they map to rather than using one channel for the
69  * console and second for the DUT.
70  */
71 static const pinmux_testutils_mio_pin_t kUartDvPins[4] = {
72  // UART0.
73  {
76  },
77  // UART1.
78  {
81  },
82  // UART2.
83  {
86  },
87  // UART3.
88  {
91  }};
92 
93 static const uart_cfg_params_t kUartCfgParams[4] = {
95  .base_addr = TOP_EARLGREY_UART0_BASE_ADDR,
96  .peripheral_id = kTopEarlgreyPlicPeripheralUart0,
97  .irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart0TxWatermark,
98  .irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart0TxEmpty,
99  .irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart0RxWatermark,
100  .irq_tx_done_id = kTopEarlgreyPlicIrqIdUart0TxDone,
101  .irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart0RxOverflow,
102  .irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart0RxFrameErr,
103  .irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart0RxBreakErr,
104  .irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart0RxTimeout,
105  .irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart0RxParityErr,
106  },
108  .base_addr = TOP_EARLGREY_UART1_BASE_ADDR,
109  .peripheral_id = kTopEarlgreyPlicPeripheralUart1,
110  .irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart1TxWatermark,
111  .irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart1TxEmpty,
112  .irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart1RxWatermark,
113  .irq_tx_done_id = kTopEarlgreyPlicIrqIdUart1TxDone,
114  .irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart1RxOverflow,
115  .irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart1RxFrameErr,
116  .irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart1RxBreakErr,
117  .irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart1RxTimeout,
118  .irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart1RxParityErr,
119  },
121  .base_addr = TOP_EARLGREY_UART2_BASE_ADDR,
122  .peripheral_id = kTopEarlgreyPlicPeripheralUart2,
123  .irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart2TxWatermark,
124  .irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart2TxEmpty,
125  .irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart2RxWatermark,
126  .irq_tx_done_id = kTopEarlgreyPlicIrqIdUart2TxDone,
127  .irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart2RxOverflow,
128  .irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart2RxFrameErr,
129  .irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart2RxBreakErr,
130  .irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart2RxTimeout,
131  .irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart2RxParityErr,
132  },
134  .base_addr = TOP_EARLGREY_UART3_BASE_ADDR,
135  .peripheral_id = kTopEarlgreyPlicPeripheralUart3,
136  .irq_tx_watermark_id = kTopEarlgreyPlicIrqIdUart3TxWatermark,
137  .irq_tx_empty_id = kTopEarlgreyPlicIrqIdUart3TxEmpty,
138  .irq_rx_watermark_id = kTopEarlgreyPlicIrqIdUart3RxWatermark,
139  .irq_tx_done_id = kTopEarlgreyPlicIrqIdUart3TxDone,
140  .irq_rx_overflow_id = kTopEarlgreyPlicIrqIdUart3RxOverflow,
141  .irq_rx_frame_err_id = kTopEarlgreyPlicIrqIdUart3RxFrameErr,
142  .irq_rx_break_err_id = kTopEarlgreyPlicIrqIdUart3RxBreakErr,
143  .irq_rx_timeout_id = kTopEarlgreyPlicIrqIdUart3RxTimeout,
144  .irq_rx_parity_err_id = kTopEarlgreyPlicIrqIdUart3RxParityErr,
145  }};
146 
147 status_t uart_testutils_select_pinmux(const dif_pinmux_t *pinmux,
148  uint8_t uart_idx,
149  uart_pinmux_channel_t channel) {
150  TRY_CHECK(channel < kUartPinmuxChannelCount &&
151  uart_idx < ARRAYSIZE(kUartPinmuxPins),
152  "Index out of bounds");
153 
155  ? kUartDvPins[uart_idx]
156  : kUartSynthPins[channel];
157 
158  TRY(dif_pinmux_input_select(pinmux, kUartPinmuxPins[uart_idx].peripheral_in,
159  mio_pin.insel));
160  TRY(dif_pinmux_output_select(pinmux, mio_pin.mio_out,
161  kUartPinmuxPins[uart_idx].outsel));
162 
163  return OK_STATUS();
164 }
165 
166 status_t uart_testutils_detach_pinmux(const dif_pinmux_t *pinmux,
167  uint8_t uart_idx) {
168  TRY_CHECK(uart_idx < ARRAYSIZE(kUartPinmuxPins), "Index out of bounds");
169 
170  TRY(dif_pinmux_input_select(pinmux, kUartPinmuxPins[uart_idx].peripheral_in,
172 
173  return OK_STATUS();
174 }
175 
176 status_t uart_testutils_cfg_params(uint8_t uart_idx,
177  uart_cfg_params_t *params) {
178  TRY_CHECK(uart_idx < ARRAYSIZE(kUartCfgParams), "Index out of bounds");
179 
180  *params = kUartCfgParams[uart_idx];
181 
182  return OK_STATUS();
183 }