1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
/* libhw_cr/rp2040_piospi.c - <libhw/generic/spi.h> implementation for the RP2040's PIO
*
* Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
void _rp2040_piospi_init(struct rp2040_piospi *self,
enum spi_mode mode,
uint baudrate_hz,
uint64_t min_delay_ns,
uint8_t bogus_data,
uint pin_miso,
uint pin_mosi,
uint pin_clk,
uint pin_cs,
uint dma1,
uint dma2,
uint dma3,
uint dma4) {
x
}
/**
* At a maximum rate of sys_clk/4 bps.
*
*/
/**
*
* 2^32 b = 512 MiB
*/
size_t_and_error rp2040_piospi_readwritev(struct rp2040_piospi *self, const struct duplex_iovec *iov, int iovcnt) {
assert(self);
assert(iov);
assert(iovcnt > 0);
/* - The .pio file transfers data at a rate of 1/4 bit/cycle.
*
* - Even at the slow DMA_SIZE_8 (which allows us to not have
* to worry about alignment) goes at 8 bit/cycle; plenty
* fast.
* - If the PIO push/pull-size is 32 bits, then that gives us
* 32 cycles for DMA changeovers; plenty of time for
* separate ctrl and data channel changeovers (we don't
* need the complexity of toggling between 2 data channels
* for instaneous changeovers).
*/
[[gnu::cleanup(heap_cleanup)]] struct dma_alias1 *tx_data_blocks = heap_alloc(pruned_iovcnt+1, struct dma_alias1);
[[gnu::cleanup(heap_cleanup)]] struct dma_alias0 *rx_data_blocks = heap_alloc(pruned_iovcnt+1, struct dma_alias0);
static_assert(!DMA_IS_TRIGGER(typeof(tx_data_blocks[0]), ctrl));
static_assert(DMA_IS_TRIGGER(typeof(rx_data_blocks[0]), ctrl));
}
|