/* libhw_cr/rp2040_piospi.c - implementation for the RP2040's PIO * * Copyright (C) 2025 Luke T. Shumaker * 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)); }