diff --git a/ports/mimxrt/eth.c b/ports/mimxrt/eth.c index 414e8d51f2..d14c713961 100644 --- a/ports/mimxrt/eth.c +++ b/ports/mimxrt/eth.c @@ -33,7 +33,6 @@ #if defined(MICROPY_HW_ETH_MDC) -#include "eth.h" #include "pin.h" #include "shared/netutils/netutils.h" #include "extmod/modnetwork.h" @@ -46,6 +45,7 @@ #include "hal/phy/device/phydp83825/fsl_phydp83825.h" #include "hal/phy/device/phylan8720/fsl_phylan8720.h" +#include "eth.h" #include "lwip/etharp.h" #include "lwip/dns.h" #include "lwip/dhcp.h" @@ -167,22 +167,24 @@ void eth_irq_handler(ENET_Type *base, enet_handle_t *handle, enet_event_t event, if (event == kENET_RxEvent) { do { - status = ENET_GetRxFrameSize(&g_handle, &length); + status = ENET_GetRxFrameSize(handle, &length); if (status == kStatus_Success) { // Get the data - ENET_ReadFrame(ENET, &g_handle, g_rx_frame, length); + ENET_ReadFrame(base, handle, g_rx_frame, length); eth_process_frame(self, g_rx_frame, length); } else if (status == kStatus_ENET_RxFrameError) { - ENET_ReadFrame(ENET, &g_handle, NULL, 0); + ENET_ReadFrame(base, handle, NULL, 0); } } while (status != kStatus_ENET_RxFrameEmpty); } else { - ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt); + ENET_ClearInterruptStatus(base, kENET_TxFrameInterrupt); } } // eth_init: Set up GPIO and the transceiver -void eth_init(eth_t *self, int mac_idx) { +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr) { + + self->netif.num = mac_idx; // Set the interface number CLOCK_EnableClock(kCLOCK_Iomuxc); @@ -242,6 +244,8 @@ void eth_init(eth_t *self, int mac_idx) { mp_hal_get_mac(0, hw_addr); + phyHandle.ops = phy_ops; + phyConfig.phyAddr = phy_addr; phyConfig.autoNeg = true; mdioHandle.resource.base = ENET; mdioHandle.resource.csrClock_Hz = CLOCK_GetFreq(kCLOCK_IpgClk); @@ -252,7 +256,6 @@ void eth_init(eth_t *self, int mac_idx) { phy_speed_t speed = kENET_MiiSpeed100M; phy_duplex_t duplex = kENET_MiiFullDuplex; - phyConfig.phyAddr = ENET_PHY_ADDRESS; status_t status = PHY_Init(&phyHandle, &phyConfig); if (status == kStatus_Success) { diff --git a/ports/mimxrt/eth.h b/ports/mimxrt/eth.h index 56327d08ae..962b6c88cb 100644 --- a/ports/mimxrt/eth.h +++ b/ports/mimxrt/eth.h @@ -30,7 +30,7 @@ typedef struct _eth_t eth_t; extern eth_t eth_instance; -void eth_init(eth_t *self, int mac_idx); +void eth_init(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr); void eth_set_trace(eth_t *self, uint32_t value); struct netif *eth_netif(eth_t *self); int eth_link_status(eth_t *self); @@ -38,4 +38,10 @@ int eth_start(eth_t *self); int eth_stop(eth_t *self); void eth_low_power_mode(eth_t *self, bool enable); +enum { + PHY_KSZ8081 = 0, + PHY_DP83825, + PHY_LAN8720, +}; + #endif // MICROPY_INCLUDED_MIMXRT_ETH_H diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index 0dc49f01a5..5210ff44a3 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -97,6 +97,7 @@ enum { MP_HAL_MAC_WLAN1, MP_HAL_MAC_BDADDR, MP_HAL_MAC_ETH0, + MP_HAL_MAC_ETH1, }; void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]); diff --git a/ports/mimxrt/network_lan.c b/ports/mimxrt/network_lan.c index c0d6e41362..7b725276a1 100644 --- a/ports/mimxrt/network_lan.c +++ b/ports/mimxrt/network_lan.c @@ -27,10 +27,15 @@ #include "py/runtime.h" #include "py/mphal.h" #include "extmod/modnetwork.h" -#include "eth.h" #if defined(MICROPY_HW_ETH_MDC) +#include "fsl_phy.h" +#include "eth.h" +#include "hal/phy/device/phyksz8081/fsl_phyksz8081.h" +#include "hal/phy/device/phydp83825/fsl_phydp83825.h" +#include "hal/phy/device/phylan8720/fsl_phylan8720.h" + #include "lwip/netif.h" typedef struct _network_lan_obj_t { @@ -53,10 +58,48 @@ STATIC void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin ); } -STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 0, false); - const network_lan_obj_t *self = &network_lan_eth0; - eth_init(self->eth, MP_HAL_MAC_ETH0); +STATIC mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_id, ARG_phy_type, ARG_phy_addr}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_id, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phy_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, + { MP_QSTR_phy_addr, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ENET_PHY_ADDRESS} }, + }; + // Parse args. + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const phy_operations_t *phy_ops = &ENET_PHY_OPS; + + // Select PHY driver + int phy_type = args[ARG_phy_type].u_int; + if (phy_type != -1) { + if (phy_type == PHY_KSZ8081) { + phy_ops = &phyksz8081_ops; + } else if (phy_type == PHY_DP83825) { + phy_ops = &phydp83825_ops; + } else if (phy_type == PHY_LAN8720) { + phy_ops = &phylan8720_ops; + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid value %d for phy"), phy_type); + } + } + int phy_addr = args[ARG_phy_addr].u_int; + + // Prepare for two ETH interfaces. + const network_lan_obj_t *self; + int mac_id = args[ARG_id].u_int; + if (mac_id == 0) { + self = &network_lan_eth0; + mac_id = MP_HAL_MAC_ETH0; + } else if (mac_id == 1) { + self = &network_lan_eth0; + mac_id = MP_HAL_MAC_ETH1; + } else { + mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid LAN interface %d"), mac_id); + } + + eth_init(self->eth, mac_id, phy_ops, phy_addr); // register with network module mod_network_register_nic((mp_obj_t *)self); return MP_OBJ_FROM_PTR(self); @@ -157,6 +200,10 @@ STATIC const mp_rom_map_elem_t network_lan_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&network_lan_ifconfig_obj) }, { MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&network_lan_status_obj) }, { MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&network_lan_config_obj) }, + + { MP_ROM_QSTR(MP_QSTR_PHY_KSZ8081), MP_ROM_INT(PHY_KSZ8081) }, + { MP_ROM_QSTR(MP_QSTR_PHY_DP83825), MP_ROM_INT(PHY_DP83825) }, + { MP_ROM_QSTR(MP_QSTR_PHY_LAN8720), MP_ROM_INT(PHY_LAN8720) }, }; STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table);