mirror of
https://github.com/micropython/micropython.git
synced 2026-01-28 06:40:19 +01:00
mimxrt/eth: Improve Dual Ethernet configuration.
Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
This commit is contained in:
committed by
Damien George
parent
5021137f32
commit
77e62f627a
@@ -167,9 +167,7 @@
|
||||
{ IOMUXC_GPIO_AD_33_ENET_MDIO, 0, 0x06u }, \
|
||||
{ IOMUXC_GPIO_AD_32_ENET_MDC, 0, 0x06u },
|
||||
|
||||
// A second ETH port is present.
|
||||
#define ENET_DUAL_PORT (1)
|
||||
// 1G Transceiver Phy Parameters
|
||||
// 1G Transceiver Phy Parameters (second ETH port)
|
||||
#define ENET_1_PHY_ADDRESS (1)
|
||||
#define ENET_1_PHY RTL8211F
|
||||
#define ENET_1_PHY_OPS phyrtl8211f_ops
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "py/mperrno.h"
|
||||
#include "ticks.h"
|
||||
|
||||
#if defined(IOMUX_TABLE_ENET)
|
||||
#if defined(ENET_PHY_ADDRESS) || defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
#include "pin.h"
|
||||
#include "shared/netutils/netutils.h"
|
||||
@@ -75,6 +75,8 @@ typedef struct _iomux_table_t {
|
||||
uint32_t configValue;
|
||||
} iomux_table_t;
|
||||
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
|
||||
// ETH0 buffers and handles
|
||||
static AT_NONCACHEABLE_SECTION_ALIGN(enet_rx_bd_struct_t g_rxBuffDescrip[ENET_RXBD_NUM], ENET_BUFF_ALIGNMENT);
|
||||
static AT_NONCACHEABLE_SECTION_ALIGN(enet_tx_bd_struct_t g_txBuffDescrip[ENET_TXBD_NUM], ENET_BUFF_ALIGNMENT);
|
||||
@@ -111,7 +113,9 @@ static const iomux_table_t iomux_table_enet[] = {
|
||||
|
||||
static uint8_t hw_addr[6]; // The MAC address field
|
||||
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
#endif // defined(ENET_PHY_ADDRESS)
|
||||
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
// ETH1 buffers and handles
|
||||
static AT_NONCACHEABLE_SECTION_ALIGN(enet_rx_bd_struct_t g_rxBuffDescrip_1[ENET_RXBD_NUM], ENET_BUFF_ALIGNMENT);
|
||||
@@ -148,17 +152,14 @@ static const iomux_table_t iomux_table_enet_1[] = {
|
||||
|
||||
static uint8_t hw_addr_1[6]; // The MAC address field
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
// Define ENET_1 to the appropriate controller for this hardware
|
||||
#if defined MIMXRT117x_SERIES
|
||||
#define ENET_1 ENET_1G
|
||||
#else
|
||||
#define ENET_1 ENET2
|
||||
#endif
|
||||
#else
|
||||
#define ENET_1 ENET
|
||||
#endif
|
||||
|
||||
#endif // defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
#define PHY_AUTONEGO_TIMEOUT_US (5000000)
|
||||
#define PHY_SETTLE_TIME_US (1000)
|
||||
@@ -357,6 +358,8 @@ static void eth_phy_init(phy_handle_t *phyHandle, phy_config_t *phy_config,
|
||||
mp_hal_delay_us(phy_settle_time);
|
||||
}
|
||||
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
|
||||
// eth_init: Set up GPIO and the transceiver
|
||||
void eth_init_0(eth_t *self, int eth_id, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock) {
|
||||
// Configuration values
|
||||
@@ -411,7 +414,9 @@ void eth_init_0(eth_t *self, int eth_id, const phy_operations_t *phy_ops, int ph
|
||||
ENET_ActiveRead(ENET);
|
||||
}
|
||||
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
#endif // defined(ENET_PHY_ADDRESS)
|
||||
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
// eth_init: Set up GPIO and the transceiver
|
||||
void eth_init_1(eth_t *self, int eth_id, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock) {
|
||||
@@ -474,7 +479,8 @@ void eth_init_1(eth_t *self, int eth_id, const phy_operations_t *phy_ops, int ph
|
||||
ENET_ActiveRead(ENET_1);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
// Initialize the phy interface
|
||||
static int eth_mac_init(eth_t *self) {
|
||||
return 0;
|
||||
@@ -512,14 +518,26 @@ static err_t eth_send_frame_blocking(ENET_Type *base, enet_handle_t *handle, uin
|
||||
static err_t eth_netif_output(struct netif *netif, struct pbuf *p) {
|
||||
// This function should always be called from a context where PendSV-level IRQs are disabled
|
||||
status_t status;
|
||||
ENET_Type *enet = ENET;
|
||||
enet_handle_t *handle = &g_handle;
|
||||
ENET_Type *enet;
|
||||
enet_handle_t *handle;
|
||||
|
||||
#if defined ENET_DUAL_PORT
|
||||
#if defined(ENET_PHY_ADDRESS) && defined(ENET_1_PHY_ADDRESS)
|
||||
// Dual port: select based on netif->state
|
||||
if (netif->state == ð_instance1) {
|
||||
enet = ENET_1;
|
||||
handle = &g_handle_1;
|
||||
} else {
|
||||
enet = ENET;
|
||||
handle = &g_handle;
|
||||
}
|
||||
#elif defined(ENET_1_PHY_ADDRESS)
|
||||
// Only ENET_1 available
|
||||
enet = ENET_1;
|
||||
handle = &g_handle_1;
|
||||
#else
|
||||
// Only ENET available
|
||||
enet = ENET;
|
||||
handle = &g_handle;
|
||||
#endif
|
||||
|
||||
eth_trace(netif->state, (size_t)-1, p, NETUTILS_TRACE_IS_TX | NETUTILS_TRACE_NEWLINE);
|
||||
@@ -562,15 +580,18 @@ static void eth_lwip_init(eth_t *self) {
|
||||
ip_addr_t ipconfig[4];
|
||||
|
||||
self->netif.hwaddr_len = 6;
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
if (self == ð_instance0) {
|
||||
memcpy(self->netif.hwaddr, hw_addr, 6);
|
||||
IP4_ADDR(&ipconfig[0], 192, 168, 0, 2);
|
||||
#if defined ENET_DUAL_PORT
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
if (self == ð_instance1) {
|
||||
memcpy(self->netif.hwaddr, hw_addr_1, 6);
|
||||
IP4_ADDR(&ipconfig[0], 192, 168, 0, 3);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
IP4_ADDR(&ipconfig[1], 255, 255, 255, 0);
|
||||
IP4_ADDR(&ipconfig[2], 192, 168, 0, 1);
|
||||
IP4_ADDR(&ipconfig[3], 8, 8, 8, 8);
|
||||
@@ -578,7 +599,11 @@ static void eth_lwip_init(eth_t *self) {
|
||||
MICROPY_PY_LWIP_ENTER
|
||||
|
||||
n->name[0] = 'e';
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
n->name[1] = (self == ð_instance0 ? '0' : '1');
|
||||
#else
|
||||
n->name[1] = '1';
|
||||
#endif
|
||||
netif_add(n, &ipconfig[0], &ipconfig[1], &ipconfig[2], self, eth_netif_init, ethernet_input);
|
||||
netif_set_hostname(n, mod_network_hostname_data);
|
||||
netif_set_default(n);
|
||||
@@ -620,8 +645,10 @@ int eth_link_status(eth_t *self) {
|
||||
}
|
||||
} else {
|
||||
bool link;
|
||||
#if defined ENET_DUAL_PORT
|
||||
#if defined(ENET_PHY_ADDRESS) && defined(ENET_1_PHY_ADDRESS)
|
||||
PHY_GetLinkStatus(self == ð_instance0 ? &phyHandle : &phyHandle_1, &link);
|
||||
#elif defined(ENET_1_PHY_ADDRESS)
|
||||
PHY_GetLinkStatus(&phyHandle_1, &link);
|
||||
#else
|
||||
PHY_GetLinkStatus(&phyHandle, &link);
|
||||
#endif
|
||||
@@ -654,10 +681,12 @@ int eth_stop(eth_t *self) {
|
||||
}
|
||||
|
||||
void eth_low_power_mode(eth_t *self, bool enable) {
|
||||
#if defined ENET_DUAL_PORT
|
||||
#if defined(ENET_PHY_ADDRESS) && defined(ENET_1_PHY_ADDRESS)
|
||||
ENET_EnableSleepMode(self == ð_instance0 ? ENET : ENET_1, enable);
|
||||
#elif defined(ENET_1_PHY_ADDRESS)
|
||||
ENET_EnableSleepMode(ENET_1, enable);
|
||||
#else
|
||||
ENET_EnableSleepMode(ENET, enable);
|
||||
#endif
|
||||
}
|
||||
#endif // defined(IOMUX_TABLE_ENET)
|
||||
#endif // defined(ENET_PHY_ADDRESS) || defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
@@ -28,11 +28,14 @@
|
||||
#define MICROPY_INCLUDED_MIMXRT_ETH_H
|
||||
|
||||
typedef struct _eth_t eth_t;
|
||||
extern eth_t eth_instance0;
|
||||
extern eth_t eth_instance1;
|
||||
void eth_init_0(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock);
|
||||
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
extern eth_t eth_instance0;
|
||||
void eth_init_0(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock);
|
||||
#endif
|
||||
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
extern eth_t eth_instance1;
|
||||
void eth_init_1(eth_t *self, int mac_idx, const phy_operations_t *phy_ops, int phy_addr, bool phy_clock);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ uint32_t trng_random_u32(void);
|
||||
|
||||
// Hooks to add builtins
|
||||
|
||||
#if defined(IOMUX_TABLE_ENET)
|
||||
#if defined(ENET_PHY_ADDRESS) || defined(ENET_1_PHY_ADDRESS)
|
||||
extern const struct _mp_obj_type_t network_lan_type;
|
||||
#define MICROPY_HW_NIC_ETH { MP_ROM_QSTR(MP_QSTR_LAN), MP_ROM_PTR(&network_lan_type) },
|
||||
#else
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/modnetwork.h"
|
||||
|
||||
#if defined(IOMUX_TABLE_ENET)
|
||||
#if defined(ENET_PHY_ADDRESS) || defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
#include "fsl_phy.h"
|
||||
#include "eth.h"
|
||||
@@ -55,9 +55,13 @@ typedef struct _network_lan_obj_t {
|
||||
eth_t *eth;
|
||||
} network_lan_obj_t;
|
||||
|
||||
// Forward declaration of the type
|
||||
extern const mp_obj_type_t network_lan_type;
|
||||
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
static const network_lan_obj_t network_lan_eth0 = { { &network_lan_type }, ð_instance0 };
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
#endif
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
static const network_lan_obj_t network_lan_eth1 = { { &network_lan_type }, ð_instance1 };
|
||||
#endif
|
||||
|
||||
@@ -65,8 +69,19 @@ static void network_lan_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
|
||||
network_lan_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
struct netif *netif = eth_netif(self->eth);
|
||||
int status = eth_link_status(self->eth);
|
||||
int eth_id = 0;
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
if (self->eth == ð_instance0) {
|
||||
eth_id = 0;
|
||||
}
|
||||
#endif
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
if (self->eth == ð_instance1) {
|
||||
eth_id = 1;
|
||||
}
|
||||
#endif
|
||||
mp_printf(print, "<ETH%d status=%u ip=%u.%u.%u.%u>",
|
||||
self->eth == ð_instance0 ? 0 : 1,
|
||||
eth_id,
|
||||
status,
|
||||
netif->ip_addr.addr & 0xff,
|
||||
netif->ip_addr.addr >> 8 & 0xff,
|
||||
@@ -77,8 +92,18 @@ 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 *all_args) {
|
||||
enum { ARG_id, ARG_phy_type, ARG_phy_addr, ARG_ref_clk_mode};
|
||||
|
||||
// Default to port 0 if ENET available, else port 1 if only ENET_1 available
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
#define DEFAULT_ETH_ID 0
|
||||
#elif defined(ENET_1_PHY_ADDRESS)
|
||||
#define DEFAULT_ETH_ID 1
|
||||
#else
|
||||
#error "No Ethernet PHY configured"
|
||||
#endif
|
||||
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_id, MP_ARG_INT, {.u_int = DEFAULT_ETH_ID} },
|
||||
{ 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 = -1} },
|
||||
{ MP_QSTR_ref_clk_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
|
||||
@@ -92,18 +117,21 @@ static mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
bool phy_clock;
|
||||
|
||||
int mac_id = args[ARG_id].u_int;
|
||||
// set default
|
||||
// set default based on which interface is being used
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
if (mac_id == 0) {
|
||||
phy_ops = &ENET_PHY_OPS;
|
||||
phy_addr = ENET_PHY_ADDRESS;
|
||||
phy_clock = ENET_TX_CLK_OUTPUT;
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
} else {
|
||||
}
|
||||
#endif
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
if (mac_id == 1) {
|
||||
phy_ops = &ENET_1_PHY_OPS;
|
||||
phy_addr = ENET_1_PHY_ADDRESS;
|
||||
phy_clock = ENET_1_TX_CLK_OUTPUT;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Select PHY driver
|
||||
int phy_type = args[ARG_phy_type].u_int;
|
||||
@@ -132,17 +160,21 @@ static mp_obj_t network_lan_make_new(const mp_obj_type_t *type, size_t n_args, s
|
||||
phy_clock = args[ARG_ref_clk_mode].u_int;
|
||||
}
|
||||
|
||||
// Prepare for two ETH interfaces.
|
||||
const network_lan_obj_t *self;
|
||||
// Initialize the appropriate ETH interface
|
||||
const network_lan_obj_t *self = NULL;
|
||||
#if defined(ENET_PHY_ADDRESS)
|
||||
if (mac_id == 0) {
|
||||
self = &network_lan_eth0;
|
||||
eth_init_0(self->eth, MP_HAL_MAC_ETH0, phy_ops, phy_addr, phy_clock);
|
||||
#if defined(ENET_DUAL_PORT)
|
||||
} else if (mac_id == 1) {
|
||||
}
|
||||
#endif
|
||||
#if defined(ENET_1_PHY_ADDRESS)
|
||||
if (mac_id == 1) {
|
||||
self = &network_lan_eth1;
|
||||
eth_init_1(self->eth, MP_HAL_MAC_ETH1, phy_ops, phy_addr, phy_clock);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if (self == NULL) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Invalid LAN interface %d"), mac_id);
|
||||
}
|
||||
|
||||
@@ -275,4 +307,4 @@ MP_DEFINE_CONST_OBJ_TYPE(
|
||||
);
|
||||
|
||||
|
||||
#endif // defined(IOMUX_TABLE_ENET)
|
||||
#endif // defined(ENET_PHY_ADDRESS) || defined(ENET_1_PHY_ADDRESS)
|
||||
|
||||
Reference in New Issue
Block a user