summaryrefslogtreecommitdiff
path: root/libhw_cr
diff options
context:
space:
mode:
Diffstat (limited to 'libhw_cr')
-rw-r--r--libhw_cr/rp2040_hwspi.c8
-rw-r--r--libhw_cr/rp2040_include/libhw/rp2040_hwspi.h2
-rw-r--r--libhw_cr/w5500_ll.h63
3 files changed, 19 insertions, 54 deletions
diff --git a/libhw_cr/rp2040_hwspi.c b/libhw_cr/rp2040_hwspi.c
index 7b57792..d4adb11 100644
--- a/libhw_cr/rp2040_hwspi.c
+++ b/libhw_cr/rp2040_hwspi.c
@@ -185,23 +185,23 @@ static void rp2040_hwspi_readwritev(struct rp2040_hwspi *self, const struct dupl
if (!iov[i].iov_len)
continue;
tx_data_blocks[j] = (typeof(tx_data_blocks[0])){
- .read_addr = iov[i].iov_write_src ?: &self->bogus_data,
+ .read_addr = (iov[i].iov_write_from != IOVEC_DISCARD) ? iov[i].iov_write_from : &self->bogus_data,
.write_addr = &spi_get_hw(self->inst)->dr,
.trans_count = iov[i].iov_len,
.ctrl = (DMA_CTRL_ENABLE
| DMA_CTRL_DATA_SIZE(DMA_SIZE_8)
- | (iov[i].iov_write_src ? DMA_CTRL_INCR_READ : 0)
+ | ((iov[i].iov_write_from != IOVEC_DISCARD) ? DMA_CTRL_INCR_READ : 0)
| DMA_CTRL_CHAIN_TO(self->dma_tx_ctrl)
| DMA_CTRL_TREQ_SEL(SPI_DREQ_NUM(self->inst, true))
| DMA_CTRL_IRQ_QUIET),
};
rx_data_blocks[j] = (typeof(rx_data_blocks[0])){
.read_addr = &spi_get_hw(self->inst)->dr,
- .write_addr = iov[i].iov_read_dst ?: &bogus_rx_dst,
+ .write_addr = (iov[i].iov_read_to != IOVEC_DISCARD) ? iov[i].iov_read_to : &bogus_rx_dst,
.trans_count = iov[i].iov_len,
.ctrl = (DMA_CTRL_ENABLE
| DMA_CTRL_DATA_SIZE(DMA_SIZE_8)
- | (iov[i].iov_read_dst ? DMA_CTRL_INCR_WRITE : 0)
+ | ((iov[i].iov_read_to != IOVEC_DISCARD) ? DMA_CTRL_INCR_WRITE : 0)
| DMA_CTRL_CHAIN_TO(self->dma_rx_ctrl)
| DMA_CTRL_TREQ_SEL(SPI_DREQ_NUM(self->inst, false))
| DMA_CTRL_IRQ_QUIET),
diff --git a/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h b/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
index eb54cdc..9d99f7b 100644
--- a/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
+++ b/libhw_cr/rp2040_include/libhw/rp2040_hwspi.h
@@ -48,7 +48,7 @@ LO_IMPLEMENTATION_H(spi, struct rp2040_hwspi, rp2040_hwspi)
* @param mode : enum spi_mode : the SPI mode; SPI_MODE_{0..3}
* @param baudrate_hz : uint : baudrate in Hz
* @param min_delay_ns: uint64_t : minimum time for pin_cs to be high between messages
- * @param bogus_data : uint8_t : bogus data to write when .iov_write_src is NULL
+ * @param bogus_data : uint8_t : bogus data to write when .iov_write_from is IOVEC_DISCARD
* @param pin_miso : uint : pin number; 0, 4, 16, or 20 for _HWSPI_0; 8, 12, 24, or 28 for _HWSPI_1
* @param pin_mosi : uint : pin number; 3, 7, 19, or 23 for _HWSPI_0; 11, 15, or 27 for _HWSPI_1
* @param pin_clk : uint : pin number; 2, 6, 18, or 22 for _HWSPI_0; 10, 14, or 26 for _HWSPI_1
diff --git a/libhw_cr/w5500_ll.h b/libhw_cr/w5500_ll.h
index 8f5f9ec..2506cd2 100644
--- a/libhw_cr/w5500_ll.h
+++ b/libhw_cr/w5500_ll.h
@@ -93,39 +93,15 @@ w5500ll_writev(
(uint8_t)(addr & 0xFF),
(block & CTL_MASK_BLOCK) | CTL_W | CTL_OM_VDM,
};
- struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*(iovcnt+1));
+ int inner_cnt = 1+io_slice_cnt(iov, iovcnt, skip, max);
+ struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt);
inner[0] = (struct duplex_iovec){
- .iov_read_dst = NULL,
- .iov_write_src = header,
- .iov_len = sizeof(header),
+ .iov_read_to = IOVEC_DISCARD,
+ .iov_write_from = header,
+ .iov_len = sizeof(header),
};
- int j = 1;
- size_t skipped = 0, done = 0;
- for (int i = 0; i < iovcnt && (max == 0 || done < max); i++) {
- if (skipped < skip) {
- if (skip - skipped >= iov[i].iov_len) {
- skipped += iov[i].iov_len;
- continue;
- }
- inner[j] = (struct duplex_iovec){
- .iov_read_dst = NULL,
- .iov_write_src = iov[i].iov_base+(skip-skipped),
- .iov_len = iov[i].iov_len-(skip-skipped),
- };
- skipped = skip;
- } else {
- inner[j] = (struct duplex_iovec){
- .iov_read_dst = NULL,
- .iov_write_src = iov[i].iov_base,
- .iov_len = iov[i].iov_len,
- };
- }
- done += inner[j].iov_len;
- if (max > 0 && done > max)
- inner[j].iov_len -= done - max;
- j++;
- };
- LO_CALL(spidev, readwritev, inner, j);
+ io_slice_wr_to_duplex(&inner[1], iov, iovcnt, skip, max);
+ LO_CALL(spidev, readwritev, inner, inner_cnt);
}
static inline void
@@ -154,26 +130,15 @@ w5500ll_readv(
(uint8_t)(addr & 0xFF),
(block & CTL_MASK_BLOCK) | CTL_R | CTL_OM_VDM,
};
- struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*(iovcnt+1));
+ int inner_cnt = 1+io_slice_cnt(iov, iovcnt, 0, max);
+ struct duplex_iovec *inner = alloca(sizeof(struct duplex_iovec)*inner_cnt);
inner[0] = (struct duplex_iovec){
- .iov_read_dst = NULL,
- .iov_write_src = header,
- .iov_len = sizeof(header),
- };
- int j = 1;
- size_t done = 0;
- for (int i = 0; i < iovcnt && (max == 0 || done < max); i++) {
- inner[j] = (struct duplex_iovec){
- .iov_read_dst = iov[i].iov_base,
- .iov_write_src = NULL,
- .iov_len = iov[i].iov_len,
- };
- done += inner[j].iov_len;
- if (max > 0 && done > max)
- inner[j].iov_len -= done - max;
- j++;
+ .iov_read_to = IOVEC_DISCARD,
+ .iov_write_from = header,
+ .iov_len = sizeof(header),
};
- LO_CALL(spidev, readwritev, inner, j);
+ io_slice_rd_to_duplex(&inner[1], iov, iovcnt, 0, max);
+ LO_CALL(spidev, readwritev, inner, inner_cnt);
}
/* Common chip-wide registers. ***********************************************/