Skip to content

Commit

Permalink
mimxrt: Support selection of PHY type and address.
Browse files Browse the repository at this point in the history
Useful for boards without a PHY interface, where that has to be
attached. Like the Seed ARCH MIX board or Vision SOM. Phy drivers
supported so far are:

- KSZ8081
- DP83825
- LAN8720

More to come. Usage e.g.:
lan = LAN(phy_type=LAN.PHY_LAN8720, phy_addr=1)

The default values are those set in mpconfigboard.h.
  • Loading branch information
robert-hh committed Dec 14, 2021
1 parent bc1b0fd commit bbe25f4
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 13 deletions.
17 changes: 10 additions & 7 deletions ports/mimxrt/eth.c
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand All @@ -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) {
Expand Down
8 changes: 7 additions & 1 deletion ports/mimxrt/eth.h
Expand Up @@ -30,12 +30,18 @@
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);
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
1 change: 1 addition & 0 deletions ports/mimxrt/mphalport.h
Expand Up @@ -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]);
Expand Down
57 changes: 52 additions & 5 deletions ports/mimxrt/network_lan.c
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down

0 comments on commit bbe25f4

Please sign in to comment.