summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Leech <andrew@alelec.net>2022-05-05 17:26:16 +1000
committerDamien George <damien@micropython.org>2022-06-03 14:34:29 +1000
commitbca816f5ac36609212ab087789ee028d1d5d534d (patch)
treeb3e75ecae89de2e3979ca3d4239048edbf6f9400
parent15fea3a1ff9b7437e0fed54bd4a16c1708faf321 (diff)
rp2: Add support for using Wiznet hardware as an Ethernet NIC.
Uses the extmod/network_wiznet5k driver to provide network connectivity. Signed-off-by: Andrew Leech <andrew@alelec.net>
-rw-r--r--ports/rp2/CMakeLists.txt47
-rw-r--r--ports/rp2/machine_spi.c9
-rw-r--r--ports/rp2/modmachine.h2
-rw-r--r--ports/rp2/mpconfigport.h13
-rw-r--r--ports/rp2/mphalport.c18
-rw-r--r--ports/rp2/mphalport.h9
-rw-r--r--ports/rp2/mpnetworkport.c32
7 files changed, 130 insertions, 0 deletions
diff --git a/ports/rp2/CMakeLists.txt b/ports/rp2/CMakeLists.txt
index d9e485f70..31284c840 100644
--- a/ports/rp2/CMakeLists.txt
+++ b/ports/rp2/CMakeLists.txt
@@ -244,6 +244,53 @@ if (MICROPY_PY_NETWORK_NINAW10)
)
endif()
+if (MICROPY_PY_WIZNET5K)
+ target_compile_definitions(${MICROPY_TARGET} PRIVATE
+ MICROPY_PY_WIZNET5K=1
+ WIZCHIP_PREFIXED_EXPORTS=1
+ _WIZCHIP_=${MICROPY_PY_WIZNET5K}
+ WIZCHIP_YIELD=mpy_wiznet_yield
+ )
+
+ if (MICROPY_PY_LWIP)
+ target_compile_definitions(${MICROPY_TARGET} PRIVATE
+ # When using MACRAW mode (with lwIP), maximum buffer space must be used for the raw socket
+ WIZCHIP_USE_MAX_BUFFER=1
+ )
+ endif()
+
+ target_include_directories(${MICROPY_TARGET} PRIVATE
+ ${MICROPY_DIR}/lib/wiznet5k/
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/
+ )
+
+ list(APPEND MICROPY_SOURCE_LIB
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/W5100/w5100.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/W5100S/w5100s.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/W5200/w5200.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/W5300/w5300.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/W5500/w5500.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/socket.c
+ ${MICROPY_DIR}/lib/wiznet5k/Ethernet/wizchip_conf.c
+ ${MICROPY_DIR}/lib/wiznet5k/Internet/DNS/dns.c
+ ${MICROPY_DIR}/lib/wiznet5k/Internet/DHCP/dhcp.c
+ )
+
+ list(APPEND MICROPY_SOURCE_EXTMOD
+ ${MICROPY_DIR}/extmod/modnetwork.c
+ ${MICROPY_DIR}/extmod/modusocket.c
+ ${MICROPY_DIR}/extmod/network_wiznet5k.c
+ )
+
+ list(APPEND MICROPY_SOURCE_QSTR
+ ${MICROPY_DIR}/extmod/modnetwork.c
+ ${MICROPY_DIR}/extmod/modusocket.c
+ ${MICROPY_DIR}/extmod/network_wiznet5k.c
+ )
+
+ string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/wiznet5k)
+endif()
+
# Define mpy-cross flags
set(MICROPY_CROSS_FLAGS -march=armv7m)
diff --git a/ports/rp2/machine_spi.c b/ports/rp2/machine_spi.c
index 332f44694..742a3cfdd 100644
--- a/ports/rp2/machine_spi.c
+++ b/ports/rp2/machine_spi.c
@@ -269,6 +269,15 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
}
}
+machine_spi_obj_t *spi_from_mp_obj(mp_obj_t o) {
+ if (mp_obj_is_type(o, &machine_spi_type)) {
+ machine_spi_obj_t *self = MP_OBJ_TO_PTR(o);
+ return self;
+ } else {
+ mp_raise_TypeError(MP_ERROR_TEXT("expecting an SPI object"));
+ }
+}
+
STATIC const mp_machine_spi_p_t machine_spi_p = {
.init = machine_spi_init,
.transfer = machine_spi_transfer,
diff --git a/ports/rp2/modmachine.h b/ports/rp2/modmachine.h
index af02cd193..0635ff248 100644
--- a/ports/rp2/modmachine.h
+++ b/ports/rp2/modmachine.h
@@ -17,4 +17,6 @@ void machine_pin_init(void);
void machine_pin_deinit(void);
void machine_i2s_init0(void);
+struct _machine_spi_obj_t *spi_from_mp_obj(mp_obj_t o);
+
#endif // MICROPY_INCLUDED_RP2_MODMACHINE_H
diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h
index 4cadc2617..e2d0ffd22 100644
--- a/ports/rp2/mpconfigport.h
+++ b/ports/rp2/mpconfigport.h
@@ -77,6 +77,7 @@
#define MICROPY_PY_SYS_PLATFORM "rp2"
#define MICROPY_PY_THREAD (1)
#define MICROPY_PY_THREAD_GIL (0)
+#define MICROPY_THREAD_YIELD() mp_handle_pending(true)
// Extended modules
#define MICROPY_EPOCH_IS_1970 (1)
@@ -163,12 +164,24 @@ extern const struct _mod_network_nic_type_t mod_network_nic_type_nina;
#define MICROPY_PORT_ROOT_POINTER_NINAW10
#endif
+#if MICROPY_PY_WIZNET5K
+#if MICROPY_PY_LWIP
+extern const struct _mp_obj_type_t mod_network_nic_type_wiznet5k;
+#else
+extern const struct _mod_network_nic_type_t mod_network_nic_type_wiznet5k;
+#endif
+#define MICROPY_HW_NIC_WIZNET5K { MP_ROM_QSTR(MP_QSTR_WIZNET5K), MP_ROM_PTR(&mod_network_nic_type_wiznet5k) },
+#else
+#define MICROPY_HW_NIC_WIZNET5K
+#endif
+
#ifndef MICROPY_BOARD_NETWORK_INTERFACES
#define MICROPY_BOARD_NETWORK_INTERFACES
#endif
#define MICROPY_PORT_NETWORK_INTERFACES \
MICROPY_HW_NIC_NINAW10 \
+ MICROPY_HW_NIC_WIZNET5K \
MICROPY_BOARD_NETWORK_INTERFACES \
#ifndef MICROPY_BOARD_ROOT_POINTERS
diff --git a/ports/rp2/mphalport.c b/ports/rp2/mphalport.c
index 4a5221cae..4ed648de0 100644
--- a/ports/rp2/mphalport.c
+++ b/ports/rp2/mphalport.c
@@ -33,6 +33,7 @@
#include "tusb.h"
#include "uart.h"
#include "hardware/rtc.h"
+#include "pico/unique_id.h"
#if MICROPY_HW_ENABLE_UART_REPL || MICROPY_HW_ENABLE_USBDEV
@@ -164,3 +165,20 @@ uint64_t mp_hal_time_ns(void) {
uint64_t s = timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec);
return s * 1000000000ULL;
}
+
+// Generate a random locally administered MAC address (LAA)
+void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]) {
+ pico_unique_board_id_t pid;
+ pico_get_unique_board_id(&pid);
+ buf[0] = 0x02; // LAA range
+ buf[1] = (pid.id[7] << 4) | (pid.id[6] & 0xf);
+ buf[2] = (pid.id[5] << 4) | (pid.id[4] & 0xf);
+ buf[3] = (pid.id[3] << 4) | (pid.id[2] & 0xf);
+ buf[4] = pid.id[1];
+ buf[5] = (pid.id[0] << 2) | idx;
+}
+
+// A board can override this if needed
+MP_WEAK void mp_hal_get_mac(int idx, uint8_t buf[6]) {
+ mp_hal_generate_laa_mac(idx, buf);
+}
diff --git a/ports/rp2/mphalport.h b/ports/rp2/mphalport.h
index 0aebf7d74..88eef1308 100644
--- a/ports/rp2/mphalport.h
+++ b/ports/rp2/mphalport.h
@@ -136,4 +136,13 @@ enum mp_hal_pin_interrupt_trigger {
void mp_hal_pin_interrupt(mp_hal_pin_obj_t pin, mp_obj_t handler, mp_uint_t trigger, bool hard);
+enum {
+ MP_HAL_MAC_WLAN0 = 0,
+ MP_HAL_MAC_BDADDR,
+ MP_HAL_MAC_ETH0,
+};
+
+void mp_hal_get_mac(int idx, uint8_t buf[6]);
+void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]);
+
#endif // MICROPY_INCLUDED_RP2_MPHALPORT_H
diff --git a/ports/rp2/mpnetworkport.c b/ports/rp2/mpnetworkport.c
index 1f59e28ea..7ee10bb03 100644
--- a/ports/rp2/mpnetworkport.c
+++ b/ports/rp2/mpnetworkport.c
@@ -39,6 +39,13 @@ static alarm_id_t lwip_alarm_id = -1;
static bool lwip_can_poll = true;
static bool lwip_poll_pending = false;
+#if MICROPY_PY_WIZNET5K
+static bool wiznet_poll_pending = false;
+
+void wiznet5k_poll(void);
+void wiznet5k_deinit(void);
+#endif
+
u32_t sys_now(void) {
// Used by LwIP
return mp_hal_ticks_ms();
@@ -57,6 +64,13 @@ void lwip_lock_acquire(void) {
void lwip_lock_release(void) {
lwip_can_poll = false;
+ #if MICROPY_PY_WIZNET5K
+ if (wiznet_poll_pending) {
+ wiznet5k_poll();
+ wiznet_poll_pending = false;
+ }
+ #endif
+
if (lwip_poll_pending) {
lwip_poll();
lwip_poll_pending = false;
@@ -76,11 +90,29 @@ uint32_t lwip_try_poll(void) {
return ret;
}
+#if MICROPY_PY_WIZNET5K
+void wiznet5k_try_poll(void) {
+ if (lwip_can_poll) {
+ lwip_can_poll = false;
+ wiznet5k_poll();
+ lwip_can_poll = true;
+ } else {
+ wiznet_poll_pending = true;
+ }
+}
+#endif
+
STATIC int64_t alarm_callback(alarm_id_t id, void *user_data) {
+ #if MICROPY_PY_WIZNET5K
+ wiznet5k_try_poll();
+ #endif
return lwip_try_poll();
}
void mod_network_lwip_init(void) {
+ #if MICROPY_PY_WIZNET5K
+ wiznet5k_deinit();
+ #endif
if (lwip_alarm_id != -1) {
cancel_alarm(lwip_alarm_id);
}