diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-26 21:20:54 -0600 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-03-26 21:20:54 -0600 |
commit | 0378f059440d4702203f9bc005894f7b53cad889 (patch) | |
tree | ad738d3ce97e2f76071b6b2f448eecc8526d6bd0 /libhw/rp2040_include | |
parent | 61b14883c1ddbd5985c681ef7b559cf3c8c15525 (diff) |
Have libhw_generic be independent of libcr, rename libhw to libhw_cr
Diffstat (limited to 'libhw/rp2040_include')
-rw-r--r-- | libhw/rp2040_include/libhw/rp2040_hwspi.h | 118 | ||||
-rw-r--r-- | libhw/rp2040_include/libhw/rp2040_hwtimer.h | 25 | ||||
-rw-r--r-- | libhw/rp2040_include/libhw/w5500.h | 114 |
3 files changed, 0 insertions, 257 deletions
diff --git a/libhw/rp2040_include/libhw/rp2040_hwspi.h b/libhw/rp2040_include/libhw/rp2040_hwspi.h deleted file mode 100644 index eb54cdc..0000000 --- a/libhw/rp2040_include/libhw/rp2040_hwspi.h +++ /dev/null @@ -1,118 +0,0 @@ -/* libhw/rp2040_hwspi.h - <libhw/generic/spi.h> implementation for the RP2040's ARM Primecell SSP (PL022) - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIBHW_RP2040_HWSPI_H_ -#define _LIBHW_RP2040_HWSPI_H_ - -#include <pico/binary_info.h> /* for bi_* */ - -#include <libcr_ipc/sema.h> -#include <libmisc/private.h> - -#include <libhw/generic/spi.h> - -enum rp2040_hwspi_instance { - RP2040_HWSPI_0 = 0, - RP2040_HWSPI_1 = 1, -}; - -struct rp2040_hwspi { - BEGIN_PRIVATE(LIBHW_RP2040_HWSPI_H) - /* const */ - LM_IF(IS_IMPLEMENTATION_FOR(LIBHW_RP2040_HWSPI_H))(spi_inst_t)(void) *inst; - uint64_t min_delay_ns; - uint8_t bogus_data; - uint pin_cs; - uint dma_tx_data; - uint dma_tx_ctrl; - uint dma_rx_data; - uint dma_rx_ctrl; - - /* mutable */ - uint64_t dead_until_ns; - cr_sema_t sema; - END_PRIVATE(LIBHW_RP2040_HWSPI_H) -}; -LO_IMPLEMENTATION_H(io_duplex_readwriter, struct rp2040_hwspi, rp2040_hwspi) -LO_IMPLEMENTATION_H(spi, struct rp2040_hwspi, rp2040_hwspi) - -/** - * Initialize an instance of `struct rp2040_hwspi`. - * - * @param self : struct rp2040_hwspi : the structure to initialize - * @param name : char * : a name for the SPI port; to include in the bininfo - * @param inst_num : enum rp2040_hwspi_instance : the PL220 instance number; RP2040_HWSPI_{0,1} - * @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 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 - * @param pin_cs : uint : pin number; any unused GPIO pin - * @param dma{1-4} : uint : DMA channel; any unused channel - * - * There is no bit-order argument; the RP2040's hardware SPI always - * uses MSB-first bit order. - * - * I know we called this "hwspi", but we're actually going to - * disconnect the CS pin from the PL022 SSP and manually GPIO it from - * the CPU. This is because the PL022 has a maximum of 16-bit frames, - * but we need to be able to do *at least* 32-bit frames (and ideally, - * much larger). By managing it ourselves, we can just keep CS pulled - * low extra-long, making the frame extra-long. - * - * Restrictions on baudrate: - * - * - The PL022 requires that the baudrate is an even-number fraction - * of clk_peri. - * + This implies that the maximum baudrate is clk_peri/2. - * + Pico-SDK' default clk_peri is 125MHz, max is 200MHz. - * - The CS-from-GPIO hack above means that that we can't go so fast - * that the CPU can't do things in time. - * + Experimentally: - * | clk_sys=125MHz | baud=31.25MHz | works OK | - * | clk_sys=160MHz | baud=40 MHz | works OK | - * | clk_sys=170MHz | baud=42.5 MHz | works OK | - * | clk_sys=180MHz | baud=45 MHz | mangled in funny ways? | - * | clk_sys=200MHz | baud=50 MHz | messages get shifted right a bit | - * | clk_sys=125MHz | baud=62.5 MHz | messages get shifted right a bit | - * - * Both of these restrictions aught to be avoidable by using a - * PIO-based SPI driver instead of this PLL02-based driver. - */ -#define rp2040_hwspi_init(self, name, \ - inst_num, mode, baudrate_hz, \ - min_delay_ns, bogus_data, \ - pin_miso, pin_mosi, pin_clk, pin_cs, \ - dma1, dma2, dma3, dma4) \ - do { \ - bi_decl(bi_4pins_with_names(pin_miso, name" SPI MISO", \ - pin_mosi, name" SPI MOSI", \ - pin_mosi, name" SPI CLK", \ - pin_mosi, name" SPI CS")); \ - _rp2040_hwspi_init(self, \ - inst_num, mode, baudrate_hz, \ - min_delay_ns, bogus_data, \ - pin_miso, pin_mosi, pin_clk, pin_cs, \ - dma1, dma2, dma3, dma4); \ - } while(0) -void _rp2040_hwspi_init(struct rp2040_hwspi *self, - enum rp2040_hwspi_instance inst_num, - enum spi_mode mode, - uint baudrate_hz, - uint64_t min_delay_ns, - uint8_t bogus_data, - uint pin_miso, - uint pin_mosi, - uint pin_clk, - uint pin_cs, - uint dma1, - uint dma2, - uint dma3, - uint dma4); - -#endif /* _LIBHW_RP2040_HWSPI_H_ */ diff --git a/libhw/rp2040_include/libhw/rp2040_hwtimer.h b/libhw/rp2040_include/libhw/rp2040_hwtimer.h deleted file mode 100644 index 40e4172..0000000 --- a/libhw/rp2040_include/libhw/rp2040_hwtimer.h +++ /dev/null @@ -1,25 +0,0 @@ -/* libhw/rp2040_hwtimer.h - <libhw/generic/alarmclock.h> implementation for the RP2040's hardware timer - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIBHW_RP2040_HWTIMER_H_ -#define _LIBHW_RP2040_HWTIMER_H_ - -#include <libhw/generic/alarmclock.h> - -/** - * The RP2040 has one system "timer" with 4 alarm interrupts. - */ -enum rp2040_hwalarm_instance { - RP2040_HWALARM_0 = 0, - RP2040_HWALARM_1 = 1, - RP2040_HWALARM_2 = 2, - RP2040_HWALARM_3 = 3, - _RP2040_HWALARM_NUM, -}; - -lo_interface alarmclock rp2040_hwtimer(enum rp2040_hwalarm_instance alarm_num); - -#endif /* _LIBHW_RP2040_HWTIMER_H_ */ diff --git a/libhw/rp2040_include/libhw/w5500.h b/libhw/rp2040_include/libhw/w5500.h deleted file mode 100644 index 51effba..0000000 --- a/libhw/rp2040_include/libhw/w5500.h +++ /dev/null @@ -1,114 +0,0 @@ -/* libhw/w5500.h - <libhw/generic/net.h> implementation for the WIZnet W5500 chip - * - * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -#ifndef _LIBHW_W5500_H_ -#define _LIBHW_W5500_H_ - -#include <pico/binary_info.h> /* for bi_* */ - -#include <libcr_ipc/chan.h> -#include <libcr_ipc/mutex.h> -#include <libcr_ipc/sema.h> -#include <libmisc/private.h> - -#include <libhw/generic/net.h> -#include <libhw/generic/spi.h> - -CR_CHAN_DECLARE(_w5500_sockintr_ch, uint8_t) - -struct _w5500_socket { - BEGIN_PRIVATE(LIBHW_W5500_H) - /* const-after-init */ - uint8_t socknum; - - /* mutable */ - struct _w5500_socket *next_free; - enum { - W5500_MODE_NONE = 0, - W5500_MODE_TCP, - W5500_MODE_UDP, - } mode; - uint16_t port; /* MODE_{TCP,UDP} */ - uint64_t read_deadline_ns; /* MODE_{TCP,UDP} */ - cr_sema_t listen_sema; /* MODE_TCP */ - cr_sema_t read_sema; /* MODE_{TCP,UDP} */ - _w5500_sockintr_ch_t write_ch; /* MODE_{TCP,UDP} */ - bool list_open, read_open, write_open; /* MODE_TCP */ - - END_PRIVATE(LIBHW_W5500_H) -}; - -LO_IMPLEMENTATION_H(io_closer, struct _w5500_socket, w5500_tcplist) -LO_IMPLEMENTATION_H(net_stream_listener, struct _w5500_socket, w5500_tcplist) - -LO_IMPLEMENTATION_H(io_reader, struct _w5500_socket, w5500_tcp) -LO_IMPLEMENTATION_H(io_writer, struct _w5500_socket, w5500_tcp) -LO_IMPLEMENTATION_H(io_readwriter, struct _w5500_socket, w5500_tcp) -LO_IMPLEMENTATION_H(io_closer, struct _w5500_socket, w5500_tcp) -LO_IMPLEMENTATION_H(io_bidi_closer, struct _w5500_socket, w5500_tcp) -LO_IMPLEMENTATION_H(net_stream_conn, struct _w5500_socket, w5500_tcp) - -LO_IMPLEMENTATION_H(io_closer, struct _w5500_socket, w5500_udp) -LO_IMPLEMENTATION_H(net_packet_conn, struct _w5500_socket, w5500_udp) - -struct w5500 { - BEGIN_PRIVATE(LIBHW_W5500_H) - /* const-after-init */ - lo_interface spi spidev; - uint pin_intr; - uint pin_reset; - struct net_eth_addr hwaddr; - - /* mutable */ - uint16_t next_local_port; - struct _w5500_socket sockets[8]; - struct _w5500_socket *free; - cr_sema_t intr; - cr_mutex_t mu; - END_PRIVATE(LIBHW_W5500_H) -}; -LO_IMPLEMENTATION_H(net_iface, struct w5500, w5500_if) - -/** - * Initialize a WIZnet W5500 Ethernet-and-TCP/IP-offload chip. - * - * The W5500 has 3 lines of communication with the MCU: - * - * - An SPI-based RPC protocol: - * + mode: mode 0 or mode 3 - * + bit-order: MSB-first - * + clock frequency: 33.3MHz - 80MHz - * - An interrupt pin that it pulls low when an event happens (to let - * the MCU know that it should do an SPI RPC "get" to see what - * happened.) - * - A reset pin that the MCU can pull low to reset the W5500. - */ -#define w5500_init(self, name, spi, pin_intr, pin_reset, eth_addr) do { \ - bi_decl(bi_2pins_with_names(pin_intr, name" interrupt", \ - pin_reset, name" reset")); \ - _w5500_init(self, spi, pin_intr, pin_reset, eth_addr); \ - } while (0) -void _w5500_init(struct w5500 *self, - lo_interface spi spi, uint pin_intr, uint pin_reset, - struct net_eth_addr addr); - -/** - * Perform a hard reset on the chip (pull the reset line low). - * - * If you have any in-use sockets when you call this, you're going to - * have a bad time. - */ -void w5500_hard_reset(struct w5500 *self); - -/** - * Perform a soft reset on the chip (send the RST command). - * - * If you have any in-use sockets when you call this, you're going to - * have a bad time. - */ -void w5500_soft_reset(struct w5500 *self); - -#endif /* _LIBHW_W5500_H_ */ |