diff options
-rw-r--r-- | cmd/sbc_harness/main.c | 3 | ||||
-rw-r--r-- | libhw/rp2040_hwspi.c | 13 | ||||
-rw-r--r-- | libhw/rp2040_include/libhw/rp2040_hwspi.h | 5 | ||||
-rw-r--r-- | libhw/rp2040_include/libhw/w5500.h | 6 | ||||
-rw-r--r-- | libhw/w5500.c | 4 | ||||
-rw-r--r-- | libhw/w5500_ll.h | 16 | ||||
-rw-r--r-- | libhw_generic/include/libhw/generic/spi.h | 16 |
7 files changed, 26 insertions, 37 deletions
diff --git a/cmd/sbc_harness/main.c b/cmd/sbc_harness/main.c index 4580acc..7b1d5c5 100644 --- a/cmd/sbc_harness/main.c +++ b/cmd/sbc_harness/main.c @@ -96,7 +96,8 @@ COROUTINE init_cr(void *) { 19, /* PIN_MOSI */ 18, /* PIN_CLK */ 17); /* PIN_CS */ - w5500_init(&globals.dev_w5500, "W5500", &globals.dev_spi, + w5500_init(&globals.dev_w5500, "W5500", + lo_box_rp2040_hwspi_as_spi(&globals.dev_spi), 21, /* PIN_INTR */ 20, /* PIN_RESET */ ((struct net_eth_addr){{ diff --git a/libhw/rp2040_hwspi.c b/libhw/rp2040_hwspi.c index 47dfc97..23f3e8c 100644 --- a/libhw/rp2040_hwspi.c +++ b/libhw/rp2040_hwspi.c @@ -1,6 +1,6 @@ /* libhw/rp2040_hwspi.c - <libhw/generic/spi.h> implementation for the RP2040's ARM Primecell SSP (PL022) * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -8,16 +8,11 @@ #include <hardware/gpio.h> /* pico-sdk:hardware_gpio */ #include <libmisc/assert.h> -#include <libmisc/vcall.h> #define IMPLEMENTATION_FOR_LIBHW_RP2040_HWSPI_H YES #include <libhw/rp2040_hwspi.h> -static void rp2040_hwspi_readwritev(implements_spi *, const struct bidi_iovec *iov, int iovcnt); - -struct spi_vtable rp2040_hwspi_vtable = { - .readwritev = rp2040_hwspi_readwritev, -}; +LO_IMPLEMENTATION_C(spi, struct rp2040_hwspi, rp2040_hwspi, static) void _rp2040_hwspi_init(struct rp2040_hwspi *self, enum rp2040_hwspi_instance inst_num, @@ -84,13 +79,11 @@ void _rp2040_hwspi_init(struct rp2040_hwspi *self, gpio_put(pin_cs, 1); /* Return. */ - self->vtable = &rp2040_hwspi_vtable; self->inst = inst; self->pin_cs = pin_cs; } -static void rp2040_hwspi_readwritev(implements_spi *_self, const struct bidi_iovec *iov, int iovcnt) { - struct rp2040_hwspi *self = VCALL_SELF(struct rp2040_hwspi, implements_spi, _self); +static void rp2040_hwspi_readwritev(struct rp2040_hwspi *self, const struct bidi_iovec *iov, int iovcnt) { assert(self); spi_inst_t *inst = self->inst; diff --git a/libhw/rp2040_include/libhw/rp2040_hwspi.h b/libhw/rp2040_include/libhw/rp2040_hwspi.h index 7c4991b..b1abe0c 100644 --- a/libhw/rp2040_include/libhw/rp2040_hwspi.h +++ b/libhw/rp2040_include/libhw/rp2040_hwspi.h @@ -1,6 +1,6 @@ /* libhw/rp2040_hwspi.h - <libhw/generic/spi.h> implementation for the RP2040's ARM Primecell SSP (PL022) * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -19,13 +19,12 @@ enum rp2040_hwspi_instance { }; struct rp2040_hwspi { - implements_spi; - BEGIN_PRIVATE(LIBHW_RP2040_HWSPI_H) void /*spi_inst_t*/ *inst; uint pin_cs; END_PRIVATE(LIBHW_RP2040_HWSPI_H) }; +LO_IMPLEMENTATION_H(spi, struct rp2040_hwspi, rp2040_hwspi) /** * Initialize an instance of `struct rp2040_hwspi`. diff --git a/libhw/rp2040_include/libhw/w5500.h b/libhw/rp2040_include/libhw/w5500.h index 3cae620..87d333a 100644 --- a/libhw/rp2040_include/libhw/w5500.h +++ b/libhw/rp2040_include/libhw/w5500.h @@ -1,6 +1,6 @@ /* libhw/w5500.h - <libhw/generic/net.h> implementation for the WIZnet W5500 chip * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -48,7 +48,7 @@ struct w5500 { /* const-after-init */ implements_net_iface; BEGIN_PRIVATE(LIBHW_W5500_H) - implements_spi *spidev; + lo_interface spi spidev; uint pin_intr; uint pin_reset; struct net_eth_addr hwaddr; @@ -82,7 +82,7 @@ struct w5500 { _w5500_init(self, spi, pin_intr, pin_reset, eth_addr); \ } while (0) void _w5500_init(struct w5500 *self, - implements_spi *spi, uint pin_intr, uint pin_reset, + lo_interface spi spi, uint pin_intr, uint pin_reset, struct net_eth_addr addr); /** diff --git a/libhw/w5500.c b/libhw/w5500.c index 5a9a718..2c130f5 100644 --- a/libhw/w5500.c +++ b/libhw/w5500.c @@ -333,10 +333,10 @@ static void w5500_intrhandler(uint gpio, uint32_t LM_UNUSED(event_mask)) { } void _w5500_init(struct w5500 *chip, - implements_spi *spi, uint pin_intr, uint pin_reset, + lo_interface spi spi, uint pin_intr, uint pin_reset, struct net_eth_addr addr) { assert(chip); - assert(spi); + assert(!LO_IS_NULL(spi)); /* Initialize the data structures. */ *chip = (struct w5500){ diff --git a/libhw/w5500_ll.h b/libhw/w5500_ll.h index 25aa6b5..c05a04f 100644 --- a/libhw/w5500_ll.h +++ b/libhw/w5500_ll.h @@ -3,7 +3,7 @@ * Based entirely on the W5500 datasheet, v1.1.0. * https://docs.wiznet.io/img/products/w5500/W5500_ds_v110e.pdf * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -18,7 +18,7 @@ #include <libmisc/vcall.h> /* for VCALL() */ #include <libhw/generic/net.h> /* for struct net_eth_addr, struct net_ip4_addr */ -#include <libhw/generic/spi.h> /* for implements_spi */ +#include <libhw/generic/spi.h> /* for lo_interface spi */ /* Config *********************************************************************/ @@ -74,8 +74,8 @@ _w5500ll_write(const char *func, #else w5500ll_write( #endif - implements_spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { - assert(spidev); + lo_interface spi spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { + assert(!LO_IS_NULL(spidev)); assert((block & ~CTL_MASK_BLOCK) == 0); assert(data); assert(data_len); @@ -94,7 +94,7 @@ w5500ll_write( {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, {.iov_read_dst = NULL, .iov_write_src = data, .iov_len = data_len}, }; - VCALL(spidev, readwritev, iov, 2); + LO_CALL(spidev, readwritev, iov, 2); } static inline void @@ -104,8 +104,8 @@ _w5500ll_read(const char *func, #else w5500ll_read( #endif - implements_spi *spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { - assert(spidev); + lo_interface spi spidev, uint16_t addr, uint8_t block, void *data, size_t data_len) { + assert(!LO_IS_NULL(spidev)); assert((block & ~CTL_MASK_BLOCK) == 0); assert(data); assert(data_len); @@ -124,7 +124,7 @@ w5500ll_read( {.iov_read_dst = NULL, .iov_write_src = header, .iov_len = sizeof(header)}, {.iov_read_dst = data, .iov_write_src = NULL, .iov_len = data_len}, }; - VCALL(spidev, readwritev, iov, 2); + LO_CALL(spidev, readwritev, iov, 2); } /* Common chip-wide registers. ***********************************************/ diff --git a/libhw_generic/include/libhw/generic/spi.h b/libhw_generic/include/libhw/generic/spi.h index 2207a2c..aeeca37 100644 --- a/libhw_generic/include/libhw/generic/spi.h +++ b/libhw_generic/include/libhw/generic/spi.h @@ -1,6 +1,6 @@ /* libhw/generic/spi.h - Device-independent SPI definitions * - * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> * SPDX-License-Identifier: AGPL-3.0-or-later */ @@ -9,6 +9,8 @@ #include <stddef.h> /* for size_t */ +#include <libobj/obj.h> + enum spi_mode { SPI_MODE_0 = 0, /* clk_polarity=0 (idle low), clk_phase=0 (sample on rise) */ SPI_MODE_1 = 1, /* clk_polarity=0 (idle low), clk_phase=1 (sample on fall) */ @@ -22,12 +24,6 @@ struct bidi_iovec { size_t iov_len; }; -struct spi_vtable; - -typedef struct { - struct spi_vtable *vtable; -} implements_spi; - /* This API assumes that an SPI frame is a multiple of 8-bits. * * It is my understanding that this is a common constraint of SPI @@ -40,8 +36,8 @@ typedef struct { * octets; so we have no need for an API that allows a * non-multiple-of-8 number of bits. */ -struct spi_vtable { - void (*readwritev)(implements_spi *, const struct bidi_iovec *iov, int iovcnt); -}; +#define spi_LO_IFACE \ + LO_FUNC(void, readwritev, const struct bidi_iovec *iov, int iovcnt) +LO_INTERFACE(spi) #endif /* _LIBHW_GENERIC_SPI_H_ */ |