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>
This commit is contained in:
Andrew Leech 2022-05-05 17:26:16 +10:00 committed by Damien George
parent 15fea3a1ff
commit bca816f5ac
7 changed files with 130 additions and 0 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}