summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/sbc_harness/main.c3
-rw-r--r--libhw/rp2040_hwspi.c13
-rw-r--r--libhw/rp2040_include/libhw/rp2040_hwspi.h5
-rw-r--r--libhw/rp2040_include/libhw/w5500.h6
-rw-r--r--libhw/w5500.c4
-rw-r--r--libhw/w5500_ll.h16
-rw-r--r--libhw_generic/include/libhw/generic/spi.h16
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_ */