Software APIs
dma_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/dma_testutils.h"
6
8#include "spi_host_regs.h" // Generated.
9
10static const top_darjeeling_direct_pads_t spi_host0_direct_pads[6] = {
11 kTopDarjeelingDirectPadsSpiHost0Sck, // sck
12 kTopDarjeelingDirectPadsSpiHost0Csb, // csb
13 kTopDarjeelingDirectPadsSpiHost0Sd3, // sio[3]
14 kTopDarjeelingDirectPadsSpiHost0Sd2, // sio[2]
15 kTopDarjeelingDirectPadsSpiHost0Sd1, // sio[1]
16 kTopDarjeelingDirectPadsSpiHost0Sd0}; // sio[0]
17
18/**
19 * Initialize the provided SPI host for being used in the DMA hardware handshake
20 * mode.
21 */
22void init_spi_host(dif_spi_host_t *spi_host, uint32_t peripheral_clock_freq_hz,
23 uint32_t rx_watermark) {
24 dif_spi_host_config_t config = {
25 .spi_clock = peripheral_clock_freq_hz / 2,
26 .peripheral_clock_freq_hz = peripheral_clock_freq_hz,
27 .chip_select = {.idle = 2, .trail = 2, .lead = 2},
28 .full_cycle = true,
29 .cpha = true,
30 .cpol = true,
31 .rx_watermark = rx_watermark};
32 CHECK_DIF_OK(dif_spi_host_configure(spi_host, config));
33 CHECK_DIF_OK(dif_spi_host_output_set_enabled(spi_host, /*enabled=*/true));
34}
35
36/**
37 * Setup pads for spi_host0
38 *
39 * This peripheral is 'direct' connected to the pads.
40 */
41void setup_pads_spi_host0(dif_pinmux_t *pinmux) {
42 // set weak pull-ups for all the pads
43 dif_pinmux_pad_attr_t out_attr;
44 dif_pinmux_pad_attr_t in_attr = {
45 .slew_rate = 0,
46 .drive_strength = 0,
47 .flags = kDifPinmuxPadAttrPullResistorEnable |
48 kDifPinmuxPadAttrPullResistorUp};
49 for (uint32_t i = 0; i < ARRAYSIZE(spi_host0_direct_pads); ++i) {
50 CHECK_DIF_OK(dif_pinmux_pad_write_attrs(pinmux, spi_host0_direct_pads[i],
51 kDifPinmuxPadKindDio, in_attr,
52 &out_attr));
53 }
54}
55
56void setup_spi_dma_transaction(dif_spi_host_t *spi_host, dif_dma_t *dma,
57 uint8_t *rx_buffer, uint32_t chunk_size,
58 uint32_t total_size) {
59 dif_spi_host_segment_t host_operations[1] = {
61 .tx = {.width = kDifSpiHostWidthStandard,
62 .buf = NULL,
63 .length = total_size}},
64 };
65
66 // Issue the SPI transaction
67 CHECK_DIF_OK(dif_spi_host_start_transaction(
68 spi_host, /*csid=*/0, host_operations, ARRAYSIZE(host_operations)));
69
70 // Configure the DMA to read from SPI in hardware-handshake mode
71 dif_dma_transaction_t transaction = {
72 .source = {.address = TOP_DARJEELING_SPI_HOST0_BASE_ADDR +
73 SPI_HOST_RXDATA_REG_OFFSET,
74 .asid = kDifDmaOpentitanInternalBus},
75 .destination = {.address = (uint32_t)&rx_buffer[0],
76 .asid = kDifDmaOpentitanInternalBus},
77 .src_config = {.wrap = true, .increment = false},
78 .dst_config = {.wrap = false, .increment = true},
79 .total_size = total_size,
80 .chunk_size = chunk_size,
81 .width = kDifDmaTransWidth4Bytes};
82
83 CHECK_DIF_OK(dif_dma_memory_range_set(dma, TOP_DARJEELING_RAM_MAIN_BASE_ADDR,
85 // Enable LSIO trigger for SPI host at bit 1
86 CHECK_DIF_OK(dif_dma_handshake_irq_enable(dma, 0x2));
87 CHECK_DIF_OK(dif_dma_configure(dma, transaction));
88 CHECK_DIF_OK(dif_dma_handshake_enable(dma));
89}