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 */
28static 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 */
54static 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 */
71static 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
93static const uart_cfg_params_t kUartCfgParams[4] = {
94 (uart_cfg_params_t){
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 },
107 (uart_cfg_params_t){
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 },
120 (uart_cfg_params_t){
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 },
133 (uart_cfg_params_t){
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
147status_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
154 pinmux_testutils_mio_pin_t mio_pin = kDeviceType == kDeviceSimDV
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
166status_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
176status_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}