diff options
Diffstat (limited to 'libhw_cr/w5500_ll.c')
-rw-r--r-- | libhw_cr/w5500_ll.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/libhw_cr/w5500_ll.c b/libhw_cr/w5500_ll.c index d9f4fc5..c60e045 100644 --- a/libhw_cr/w5500_ll.c +++ b/libhw_cr/w5500_ll.c @@ -1,12 +1,14 @@ /* libhw_cr/w5500_ll.c - Low-level library for the WIZnet W5500 chip * - * Based entirely on the W5500 datasheet, v1.1.0. + * Based entirely on the W5500 datasheet (v1.1.0), not on reference code. * https://docs.wiznet.io/img/products/w5500/W5500_ds_v110e.pdf * * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ +#include <string.h> /* for memcmp() and mempy() */ + #include <libmisc/alloc.h> /* for stack_alloc() */ #include <libmisc/fmt.h> @@ -24,15 +26,10 @@ static void fmt_print_ctl_block(lo_interface fmt_dest, uint8_t b) { } #endif -void -#if CONFIG_W5500_LL_DEBUG -_w5500ll_writev(const char *func, -#else -w5500ll_writev( -#endif - lo_interface spi spidev, uint16_t addr, uint8_t block, - const struct iovec *iov, int iovcnt, - size_t skip, size_t max) +void _w5500ll_n_writev(const char *func, + lo_interface spi spidev, uint16_t addr, uint8_t block, + const struct iovec *iov, int iovcnt, + size_t skip, size_t max) { assert(!LO_IS_NULL(spidev)); assert((block & ~CTL_MASK_BLOCK) == 0); @@ -64,15 +61,11 @@ w5500ll_writev( LO_CALL(spidev, readwritev, inner, inner_cnt); } -void -#if CONFIG_W5500_LL_DEBUG -_w5500ll_readv(const char *func, -#else -w5500ll_readv( -#endif - lo_interface spi spidev, uint16_t addr, uint8_t block, - const struct iovec *iov, int iovcnt, - size_t max) + +void _w5500ll_n_readv(const char *func, + lo_interface spi spidev, uint16_t addr, uint8_t block, + const struct iovec *iov, int iovcnt, + size_t max) { assert(!LO_IS_NULL(spidev)); assert((block & ~CTL_MASK_BLOCK) == 0); @@ -103,3 +96,20 @@ w5500ll_readv( io_slice_rd_to_duplex(&inner[1], iov, iovcnt, 0, max); LO_CALL(spidev, readwritev, inner, inner_cnt); } + +void _w5500ll_n_read_repeated(const char *func, + lo_interface spi spidev, uint16_t addr, uint8_t block, + void *buf, void *buf_scratch, size_t len) +{ + _w5500ll_n_readv(func, spidev, addr, block, + &((struct iovec){.iov_base=buf, .iov_len=len}), 1, + 0); + for (;;) { + _w5500ll_n_readv(func, spidev, addr, block, + &((struct iovec){.iov_base=buf_scratch, .iov_len=len}), 1, + 0); + if (memcmp(buf, buf_scratch, len) == 0) + break; + memcpy(buf, buf_scratch, len); + } +} |