diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-27 23:22:01 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2024-10-27 23:49:37 -0600 |
commit | 88adb90f5e805bea27e619fd5209ef58dbff6fd1 (patch) | |
tree | c3e24877b40ce183f1d72f6e064b0478ecf92207 /libhw/common_include | |
parent | 89761191a98f7dce4d1049b9a84c3d645378222a (diff) |
Factor out a libhw
Diffstat (limited to 'libhw/common_include')
-rw-r--r-- | libhw/common_include/libhw/generic/net.h | 99 | ||||
-rw-r--r-- | libhw/common_include/libhw/generic/spi.h | 47 |
2 files changed, 146 insertions, 0 deletions
diff --git a/libhw/common_include/libhw/generic/net.h b/libhw/common_include/libhw/generic/net.h new file mode 100644 index 0000000..40bcd3b --- /dev/null +++ b/libhw/common_include/libhw/generic/net.h @@ -0,0 +1,99 @@ +/* libhw/generic/net.h - Device-independent network definitions + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBHW_GENERIC_NET_H_ +#define _LIBHW_GENERIC_NET_H_ + +#include <stdbool.h> /* for bool */ +#include <stddef.h> /* for size_t */ +#include <stdint.h> /* for uint{n}_t} */ +#include <sys/types.h> /* for ssize_t */ + +/* Errnos *********************************************************************/ + +#define NET_EOTHER 1 +#define NET_ETIMEDOUT 2 +#define NET_ETHREAD 3 + +/* Address types **************************************************************/ + +struct net_ip4_addr { + unsigned char octets[4]; +}; + +static const struct net_ip4_addr net_ip4_addr_broadcast = {{255, 255, 255, 255}}; +static const struct net_ip4_addr net_ip4_addr_zero = {{0, 0, 0, 0}}; + +struct net_eth_addr { + unsigned char octets[6]; +}; + +/* Streams (e.g. TCP) *********************************************************/ + +struct net_stream_listener_vtable; +struct net_stream_conn_btable; + +typedef struct { + struct net_stream_listener_vtable *vtable; +} implements_net_stream_listener; + +typedef struct { + struct net_stream_conn_vtable *vtable; +} implements_net_stream_conn; + +struct net_stream_listener_vtable { + /** + * It is invalid to accept() a new connection if an existing + * connection is still open. + */ + implements_net_stream_conn *(*accept)(implements_net_stream_listener *self); +}; + +struct net_stream_conn_vtable { + /** + * Return bytes-read on success, 0 on EOF, -errno on error; a + * short read is *not* an error. + */ + ssize_t (*read)(implements_net_stream_conn *self, + void *buf, size_t count); + + /** + * Return `count` on success, -errno on error; a short write *is* an + * error. + * + * Writes are *not* guaranteed to be atomic (as this would be + * expensive to implement), so if you have concurrent writers then you + * should arrange for a mutex to protect the connection. + */ + ssize_t (*write)(implements_net_stream_conn *self, + void *buf, size_t count); + + /** + * Return 0 on success, -errno on error. + */ + int (*close)(implements_net_stream_conn *self, + bool rd, bool wr); +}; + +/* Packets (e.g. UDP) *********************************************************/ + +struct net_packet_conn_vtable; + +typedef struct { + struct net_packet_conn_vtable *vtable; +} implements_net_packet_conn; + +struct net_packet_conn_vtable { + ssize_t (*sendto )(implements_net_packet_conn *self, + void *buf, size_t len, + struct net_ip4_addr node, uint16_t port); + ssize_t (*recvfrom)(implements_net_packet_conn *self, + void *buf, size_t len, + struct net_ip4_addr *ret_node, uint16_t *ret_port); + int (*close )(implements_net_packet_conn *self); +}; + +#endif /* _LIBHW_GENERIC_NET_H_ */ diff --git a/libhw/common_include/libhw/generic/spi.h b/libhw/common_include/libhw/generic/spi.h new file mode 100644 index 0000000..fcba84e --- /dev/null +++ b/libhw/common_include/libhw/generic/spi.h @@ -0,0 +1,47 @@ +/* libhw/generic/spi.h - Device-independent SPI definitions + * + * Copyright (C) 2024 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-Licence-Identifier: AGPL-3.0-or-later + */ + +#ifndef _LIBHW_GENERIC_SPI_H_ +#define _LIBHW_GENERIC_SPI_H_ + +#include <stddef.h> /* for size_t */ + +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) */ + SPI_MODE_2 = 2, /* clk_polarity=1 (idle high), clk_phase=0 (sample on rise) */ + SPI_MODE_3 = 3, /* clk_polarity=1 (idle high), clk_phase=1 (sample on fall) */ +}; + +struct bidi_iovec { + void *iov_read_dst; + void *iov_write_src; + 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 + * hardware, and that the RP2040 is somewhat unusual in that it allows + * frames of any length 4-16 bits (we disconnect the CS pin from the + * PL022 SSP and manually GPIO it from the CPU in order to achieve + * longer frames). + * + * But, more relevantly: The W5500's protocol uses frames that are 4-N + * 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); +}; + +#endif /* _LIBHW_GENERIC_SPI_H_ */ |