mimxrt: Support selection of PHY type and address.
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.
This commit is contained in:
parent
bc1b0fd2c1
commit
bbe25f4704
@ -33,7 +33,6 @@
|
|||||||
|
|
||||||
#if defined(MICROPY_HW_ETH_MDC)
|
#if defined(MICROPY_HW_ETH_MDC)
|
||||||
|
|
||||||
#include "eth.h"
|
|
||||||
#include "pin.h"
|
#include "pin.h"
|
||||||
#include "shared/netutils/netutils.h"
|
#include "shared/netutils/netutils.h"
|
||||||
#include "extmod/modnetwork.h"
|
#include "extmod/modnetwork.h"
|
||||||
@ -46,6 +45,7 @@
|
|||||||
#include "hal/phy/device/phydp83825/fsl_phydp83825.h"
|
#include "hal/phy/device/phydp83825/fsl_phydp83825.h"
|
||||||
#include "hal/phy/device/phylan8720/fsl_phylan8720.h"
|
#include "hal/phy/device/phylan8720/fsl_phylan8720.h"
|
||||||
|
|
||||||
|
#include "eth.h"
|
||||||
#include "lwip/etharp.h"
|
#include "lwip/etharp.h"
|
||||||
#include "lwip/dns.h"
|
#include "lwip/dns.h"
|
||||||
#include "lwip/dhcp.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) {
|
if (event == kENET_RxEvent) {
|
||||||
do {
|
do {
|
||||||
status = ENET_GetRxFrameSize(&g_handle, &length);
|
status = ENET_GetRxFrameSize(handle, &length);
|
||||||
if (status == kStatus_Success) {
|
if (status == kStatus_Success) {
|
||||||
// Get the data
|
// 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);
|
eth_process_frame(self, g_rx_frame, length);
|
||||||
} else if (status == kStatus_ENET_RxFrameError) {
|
} else if (status == kStatus_ENET_RxFrameError) {
|
||||||
ENET_ReadFrame(ENET, &g_handle, NULL, 0);
|
ENET_ReadFrame(base, handle, NULL, 0);
|
||||||
}
|
}
|
||||||
} while (status != kStatus_ENET_RxFrameEmpty);
|
} while (status != kStatus_ENET_RxFrameEmpty);
|
||||||
} else {
|
} else {
|
||||||
ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt);
|
ENET_ClearInterruptStatus(base, kENET_TxFrameInterrupt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// eth_init: Set up GPIO and the transceiver
|
// 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);
|
CLOCK_EnableClock(kCLOCK_Iomuxc);
|
||||||
|
|
||||||
@ -242,6 +244,8 @@ void eth_init(eth_t *self, int mac_idx) {
|
|||||||
|
|
||||||
mp_hal_get_mac(0, hw_addr);
|
mp_hal_get_mac(0, hw_addr);
|
||||||
|
|
||||||
|
phyHandle.ops = phy_ops;
|
||||||
|
phyConfig.phyAddr = phy_addr;
|
||||||
phyConfig.autoNeg = true;
|
phyConfig.autoNeg = true;
|
||||||
mdioHandle.resource.base = ENET;
|
mdioHandle.resource.base = ENET;
|
||||||
mdioHandle.resource.csrClock_Hz = CLOCK_GetFreq(kCLOCK_IpgClk);
|
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_speed_t speed = kENET_MiiSpeed100M;
|
||||||
phy_duplex_t duplex = kENET_MiiFullDuplex;
|
phy_duplex_t duplex = kENET_MiiFullDuplex;
|
||||||
|
|
||||||
phyConfig.phyAddr = ENET_PHY_ADDRESS;
|
|
||||||
|
|
||||||
status_t status = PHY_Init(&phyHandle, &phyConfig);
|
status_t status = PHY_Init(&phyHandle, &phyConfig);
|
||||||
if (status == kStatus_Success) {
|
if (status == kStatus_Success) {
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
typedef struct _eth_t eth_t;
|
typedef struct _eth_t eth_t;
|
||||||
extern eth_t eth_instance;
|
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);
|
void eth_set_trace(eth_t *self, uint32_t value);
|
||||||
struct netif *eth_netif(eth_t *self);
|
struct netif *eth_netif(eth_t *self);
|
||||||
int eth_link_status(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);
|
int eth_stop(eth_t *self);
|
||||||
void eth_low_power_mode(eth_t *self, bool enable);
|
void eth_low_power_mode(eth_t *self, bool enable);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PHY_KSZ8081 = 0,
|
||||||
|
PHY_DP83825,
|
||||||
|
PHY_LAN8720,
|
||||||
|
};
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_MIMXRT_ETH_H
|
#endif // MICROPY_INCLUDED_MIMXRT_ETH_H
|
||||||
|
@ -97,6 +97,7 @@ enum {
|
|||||||
MP_HAL_MAC_WLAN1,
|
MP_HAL_MAC_WLAN1,
|
||||||
MP_HAL_MAC_BDADDR,
|
MP_HAL_MAC_BDADDR,
|
||||||
MP_HAL_MAC_ETH0,
|
MP_HAL_MAC_ETH0,
|
||||||
|
MP_HAL_MAC_ETH1,
|
||||||
};
|
};
|
||||||
|
|
||||||
void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]);
|
void mp_hal_generate_laa_mac(int idx, uint8_t buf[6]);
|
||||||
|
@ -27,10 +27,15 @@
|
|||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "extmod/modnetwork.h"
|
#include "extmod/modnetwork.h"
|
||||||
#include "eth.h"
|
|
||||||
|
|
||||||
#if defined(MICROPY_HW_ETH_MDC)
|
#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"
|
#include "lwip/netif.h"
|
||||||
|
|
||||||
typedef struct _network_lan_obj_t {
|
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) {
|
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) {
|
||||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
enum { ARG_id, ARG_phy_type, ARG_phy_addr};
|
||||||
const network_lan_obj_t *self = &network_lan_eth0;
|
static const mp_arg_t allowed_args[] = {
|
||||||
eth_init(self->eth, MP_HAL_MAC_ETH0);
|
{ 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
|
// register with network module
|
||||||
mod_network_register_nic((mp_obj_t *)self);
|
mod_network_register_nic((mp_obj_t *)self);
|
||||||
return MP_OBJ_FROM_PTR(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_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_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_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);
|
STATIC MP_DEFINE_CONST_DICT(network_lan_locals_dict, network_lan_locals_dict_table);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user