add ethernet for imxrt1176-sbc board and keep compatible with other boards

This commit is contained in:
Wang_Weigen 2022-09-28 09:15:51 +08:00
parent 85ed3a2c10
commit 088bf02fbd
72 changed files with 14986 additions and 113 deletions

View File

@ -15,6 +15,8 @@
// #include <user_api.h>
#include <transform.h>
extern void ShowTask();
extern int FrameworkInit();
extern void ApplicationOtaTaskInit(void);
int main(void)
@ -24,6 +26,10 @@ int main(void)
#ifdef APPLICATION_OTA
ApplicationOtaTaskInit();
#endif
while(1){
// ShowTask();
PrivTaskDelay(2000);
}
return 0;
}
// int cppmain(void);

View File

@ -139,6 +139,8 @@ This function initializes the Ethernet driver.
//------------------------------------------------------------------------------
tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p)
{
uint8_t enet_port = 0; ///< use enet port 0
// Check parameter validity
ASSERT(pEdrvInitParam_p != NULL);
@ -153,7 +155,7 @@ tOplkError edrv_init(const tEdrvInitParam* pEdrvInitParam_p)
edrvInstance_l.fStartCommunication = TRUE;
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
gnetif.input = ethernetInput;
edrvInstance_l.pNetif = &gnetif;

View File

@ -347,6 +347,7 @@ void PlcSocketTask(int argc, char *argv[])
{
int result = 0;
pthread_t th_id;
uint8_t enet_port = 0; ///< test enet port 0
pthread_attr_t attr;
attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO;
@ -355,7 +356,7 @@ void PlcSocketTask(int argc, char *argv[])
PlcCheckParam(argc, argv);
lwip_config_net(lwip_ipaddr, lwip_netmask, param->ip);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, param->ip);
PrivTaskCreate(&th_id, &attr, PlcSocketStart, param);
}

View File

@ -35,6 +35,10 @@ Modification:
#include <connect_uart.h>
#endif
#ifdef BSP_USING_LWIP
extern int ETH_BSP_Config();
#endif
#if __CORTEX_M == 7
void BOARD_ConfigMPU(void)
{
@ -368,6 +372,79 @@ void BOARD_ConfigMPU(void)
}
#endif
void BOARD_InitModuleClock(void)
{
const clock_sys_pll1_config_t sysPll1Config = {
.pllDiv2En = true,
};
CLOCK_InitSysPll1(&sysPll1Config);
clock_root_config_t rootCfg = {.mux = 4, .div = 10};
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
/* Generate 50M root clock. */
CLOCK_SetRootClock(kCLOCK_Root_Enet1, &rootCfg);
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
/* Generate 125M root clock. */
rootCfg.mux = 4;
rootCfg.div = 4;
CLOCK_SetRootClock(kCLOCK_Root_Enet2, &rootCfg);
#endif
/* Select syspll2pfd3, 528*18/24 = 396M */
CLOCK_InitPfd(kCLOCK_PllSys2, kCLOCK_Pfd3, 24);
rootCfg.mux = 7;
rootCfg.div = 2;
CLOCK_SetRootClock(kCLOCK_Root_Bus, &rootCfg); /* Generate 198M bus clock. */
}
void IOMUXC_SelectENETClock(void)
{
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
IOMUXC_GPR->GPR4 |= 0x3; /* 50M ENET_REF_CLOCK output to PHY and ENET module. */
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
IOMUXC_GPR->GPR5 |= IOMUXC_GPR_GPR5_ENET1G_RGMII_EN_MASK; /* bit1:iomuxc_gpr_enet_clk_dir
bit0:GPR_ENET_TX_CLK_SEL(internal or OSC) */
#endif
}
/*!
* @brief Utility function for comparing arrays
*/
static uint8_t compareArrays(uint8_t a[], uint8_t b[], int len)
{
for (int i=0; i<len; i++)
{
if (a[i] != b[i])
{
return 0;
}
}
return 1;
}
/*!
* @brief configure miiMode, miiSpeed based on the MAC address
*/
void BOARD_ENETFlexibleConfigure(enet_config_t *config, uint8_t *hwAddr)
{
uint8_t temp_arr[6] = configMAC_ADDR;
if (compareArrays(hwAddr, temp_arr, 6))
{
config->miiMode = kENET_RmiiMode;
config->miiSpeed = kENET_MiiSpeed100M;
}
else
{
config->miiMode = kENET_RgmiiMode;
config->miiSpeed = kENET_MiiSpeed1000M;
}
}
/* This is the timer interrupt service routine. */
void SysTick_Handler(int irqn, void *arg)
{
@ -381,6 +458,10 @@ struct InitSequenceDesc _board_init[] =
// { "hw_pin", Imxrt1052HwGpioInit },
#endif
#ifdef BSP_USING_LWIP
{"ETH_BSP", ETH_BSP_Config},
#endif
{ " NONE ",NONE },
};
@ -395,6 +476,15 @@ void InitBoardHardware()
BOARD_ConfigMPU();
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitModuleClock();
IOMUXC_SelectENETClock();
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
BOARD_InitEnetPins();
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
BOARD_InitEnet1GPins();
#endif
// NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

View File

@ -3,11 +3,22 @@ export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-imxrt1176-sbc.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
ifeq ($(CONFIG_LIB_MUSLLIB), y)
export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs
export LIBCC := -lgcc
export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a
endif
ifeq ($(CONFIG_RESOURCES_LWIP), y)
export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a
endif
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
# export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1052CVL5B -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS
export DEFINES := -DHAVE_CCONFIG_H -DCPU_MIMXRT1176DVMAA_cm7 -DSKIP_SYSCLK_INIT -DEVK_MCIMXRM -DFSL_SDK_ENABLE_DRIVER_CACHE_CONTROL=1 -DXIP_EXTERNAL_FLASH=1 -D__STARTUP_INITIALIZE_NONCACHEDATA -D__STARTUP_CLEAR_BSS
export ARCH = arm
export MCU = cortex-m7

View File

@ -24,21 +24,31 @@ Modification:
#include "fsl_common.h"
#include "fsl_gpio.h"
#include "fsl_clock.h"
// #include "fsl_enet.h"
#include "fsl_enet.h"
#include "clock_config.h"
#include "pin_mux.h"
#include <xizi.h>
#include <arch_interrupt.h>
#define BOARD_NET_COUNT (2)
/* MAC address configuration. */
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
#define configMAC_ADDR_ETH1 {0x02, 0x12, 0x13, 0x10, 0x15, 0x12}
/*! @brief The ENET0 PHY address. */
#define BOARD_ENET0_PHY_ADDRESS (0x02U) /* Phy address of enet port 0. */
/*! @brief The ENET1 PHY address. */
#define BOARD_ENET1_PHY_ADDRESS (0x07U) /* Phy address of enet port 1. */
#define BOARD_FLASH_SIZE (0x1000000U)
extern int heap_start;
extern int heap_end;
#define HEAP_BEGIN (&heap_start)
#define HEAP_END (&heap_end)
#define BOARD_FLASH_SIZE (0x1000000U)
#define HEAP_SIZE ((uint32_t)HEAP_END - (uint32_t)HEAP_BEGIN)
void InitBoardHardware(void);
/*******************************************************************************
@ -57,9 +67,6 @@ void InitBoardHardware(void);
1 bits for subpriority */
#define NVIC_PRIORITYGROUP_4 0x00000003U /*!< 4 bits for pre-emption priority*/
/*! @brief The ENET PHY address. */
#define BOARD_ENET0_PHY_ADDRESS (0x0U) /* Phy address of enet port 0. */
#if defined(__cplusplus)

View File

@ -69,6 +69,17 @@ void BOARD_InitBootPins(void);
*
*/
void BOARD_InitPins(void);
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitEnetPins(void); /* Function assigned for the Cortex-M7F */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitEnet1GPins(void); /* Function assigned for the Cortex-M7F */
#if defined(__cplusplus)
}

View File

@ -48,16 +48,15 @@ Modification:
/* Entry Point */
ENTRY(Reset_Handler)
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
/* Specify the memory areas */
/* Specify the memory areas- */
MEMORY
{
/* define flash 32MB */
m_boot_data (RX) : ORIGIN = 0x30000000, LENGTH = 0x00001000
m_image_vertor_table (RX) : ORIGIN = 0x30001000, LENGTH = 0x00001000
m_interrupts (RX) : ORIGIN = 0x30002000, LENGTH = 0x00000400
m_interrupts (RX) : ORIGIN = 0x30002000, LENGTH = 0x00001000
m_text (RX) : ORIGIN = 0x30002400, LENGTH = 0x01FFDC00
/* define itcm 256KB */
@ -91,12 +90,14 @@ SECTIONS
{
KEEP(*(.boot_hdr.conf))
} > m_boot_data
.image_vertor_table :
{
. = ALIGN(4);
KEEP(*(.boot_hdr.ivt))
KEEP(*(.boot_hdr.boot_data))
KEEP(*(.boot_hdr.dcd_data))
. = ALIGN(4);
} > m_image_vertor_table
/* The startup code goes first into internal RAM */
@ -240,15 +241,15 @@ SECTIONS
*(NonCacheable.init)
. = ALIGN(4);
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
} > sram_dtcm_cm7
} > NCACHE_REGION
. = __noncachedata_init_end__;
.ncache :
{
*(NonCacheable)
. = ALIGN(4);
. = ALIGN(8192);
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
__NCACHE_REGION_END = .;
} > sram_dtcm_cm7
} > NCACHE_REGION
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
text_end = ORIGIN(m_text) + LENGTH(m_text);

View File

@ -14,3 +14,12 @@ menuconfig BSP_USING_GPIO
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
menuconfig BSP_USING_LWIP
bool "Using LwIP device"
default n
select RESOURCES_LWIP
if BSP_USING_LWIP
source "$BSP_DIR/third_party_driver/ethernet/Kconfig"
endif

View File

@ -1,7 +1,11 @@
SRC_DIR := common
SRC_DIR := common gpio cm7
ifeq ($(CONFIG_BSP_USING_LPUART),y)
SRC_DIR += uart
endif
ifeq ($(CONFIG_BSP_USING_LWIP),y)
SRC_DIR += ethernet
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES :=fsl_cache.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -80,21 +80,172 @@ void BOARD_InitPins(void) {
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 is configured as LPUART1_RXD */
0U); /* Software Input On Field: Input Path is determined by functionality */
1U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_24_LPUART1_TXD, /* GPIO_AD_24 PAD functional properties : */
0x02U); /* Slew Rate Field: Slow Slew Rate
0x00U); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: high driver
Pull / Keep Select Field: Pull Disable, Highz
Pull Up / Down Config. Field: Weak pull down
Open Drain Field: Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_25_LPUART1_RXD, /* GPIO_AD_25 PAD functional properties : */
0x02U); /* Slew Rate Field: Slow Slew Rate
0x00U); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: high driver
Pull / Keep Select Field: Pull Disable, Highz
Pull Up / Down Config. Field: Weak pull down
Open Drain Field: Disabled */
IOMUXC_SetPinMux(
IOMUXC_GPIO_EMC_B2_11_GPIO8_IO21, /* GPIO_EMC_B2_11 is configured as GPIO8_IO21 */
0U); /* Software Input On Field: Input Path is determined by functionality */
}
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitEnetPins:
- options: {callFromInitBoot: 'false', coreID: cm7, enableClock: 'true'}
- pin_list:
- {pin_num: P17, peripheral: GPIO9, signal: 'gpio_io, 11', pin_signal: GPIO_AD_12}
- {pin_num: U2, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_B2_19}
- {pin_num: R3, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_B2_20}
- {pin_num: E9, peripheral: ENET, signal: 'enet_tdata, 00', pin_signal: GPIO_DISP_B2_02}
- {pin_num: D7, peripheral: ENET, signal: 'enet_tdata, 01', pin_signal: GPIO_DISP_B2_03}
- {pin_num: C7, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_DISP_B2_04}
- {pin_num: C9, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_DISP_B2_05, software_input_on: Enable, slew_rate: Fast}
- {pin_num: C6, peripheral: ENET, signal: 'enet_rdata, 00', pin_signal: GPIO_DISP_B2_06}
- {pin_num: D6, peripheral: ENET, signal: 'enet_rdata, 01', pin_signal: GPIO_DISP_B2_07}
- {pin_num: B5, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_DISP_B2_08}
- {pin_num: D8, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_DISP_B2_09}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitEnetPins, assigned for the Cortex-M7F core.
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitEnetPins(void) {
CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_12_GPIO9_IO11, /* GPIO_AD_12 is configured as GPIO9_IO11 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_02_ENET_TX_DATA00, /* GPIO_DISP_B2_02 is configured as ENET_TX_DATA00 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_03_ENET_TX_DATA01, /* GPIO_DISP_B2_03 is configured as ENET_TX_DATA01 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_04_ENET_TX_EN, /* GPIO_DISP_B2_04 is configured as ENET_TX_EN */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_05_ENET_REF_CLK, /* GPIO_DISP_B2_05 is configured as ENET_REF_CLK */
1U); /* Software Input On Field: Force input path of pad GPIO_DISP_B2_05 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_06_ENET_RX_DATA00, /* GPIO_DISP_B2_06 is configured as ENET_RX_DATA00 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_07_ENET_RX_DATA01, /* GPIO_DISP_B2_07 is configured as ENET_RX_DATA01 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_08_ENET_RX_EN, /* GPIO_DISP_B2_08 is configured as ENET_RX_EN */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B2_09_ENET_RX_ER, /* GPIO_DISP_B2_09 is configured as ENET_RX_ER */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_EMC_B2_19_ENET_MDC, /* GPIO_EMC_B2_19 is configured as ENET_MDC */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_EMC_B2_20_ENET_MDIO, /* GPIO_EMC_B2_20 is configured as ENET_MDIO */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_DISP_B2_05_ENET_REF_CLK, /* GPIO_DISP_B2_05 PAD functional properties : */
0x03U); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: high drive strength
Pull / Keep Select Field: Pull Disable, Highz
Pull Up / Down Config. Field: Weak pull down
Open Drain Field: Disabled
Domain write protection: Both cores are allowed
Domain write protection lock: Neither of DWP bits is locked */
}
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitEnet1GPins:
- options: {callFromInitBoot: 'false', coreID: cm7, enableClock: 'true'}
- pin_list:
- {pin_num: E13, peripheral: ENET_1G, signal: enet_rx_en, pin_signal: GPIO_DISP_B1_00}
- {pin_num: D13, peripheral: ENET_1G, signal: enet_rx_clk, pin_signal: GPIO_DISP_B1_01}
- {pin_num: D11, peripheral: ENET_1G, signal: 'enet_rdata, 00', pin_signal: GPIO_DISP_B1_02}
- {pin_num: E11, peripheral: ENET_1G, signal: 'enet_rdata, 01', pin_signal: GPIO_DISP_B1_03}
- {pin_num: E10, peripheral: ENET_1G, signal: 'enet_rdata, 02', pin_signal: GPIO_DISP_B1_04}
- {pin_num: C11, peripheral: ENET_1G, signal: 'enet_rdata, 03', pin_signal: GPIO_DISP_B1_05}
- {pin_num: D10, peripheral: ENET_1G, signal: 'enet_tdata, 03', pin_signal: GPIO_DISP_B1_06}
- {pin_num: E12, peripheral: ENET_1G, signal: 'enet_tdata, 02', pin_signal: GPIO_DISP_B1_07}
- {pin_num: A15, peripheral: ENET_1G, signal: 'enet_tdata, 01', pin_signal: GPIO_DISP_B1_08}
- {pin_num: C13, peripheral: ENET_1G, signal: 'enet_tdata, 00', pin_signal: GPIO_DISP_B1_09}
- {pin_num: B14, peripheral: ENET_1G, signal: enet_tx_en, pin_signal: GPIO_DISP_B1_10}
- {pin_num: A14, peripheral: ENET_1G, signal: enet_tx_clk_io, pin_signal: GPIO_DISP_B1_11}
- {pin_num: N17, peripheral: ENET_1G, signal: enet_mdc, pin_signal: GPIO_AD_16}
- {pin_num: N15, peripheral: ENET_1G, signal: enet_mdio, pin_signal: GPIO_AD_17}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitEnet1GPins, assigned for the Cortex-M7F core.
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitEnet1GPins(void) {
CLOCK_EnableClock(kCLOCK_Iomuxc); /* LPCG on: LPCG is ON. */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_16_ENET_1G_MDC, /* GPIO_AD_16 is configured as ENET_1G_MDC */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_17_ENET_1G_MDIO, /* GPIO_AD_17 is configured as ENET_1G_MDIO */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_00_ENET_1G_RX_EN, /* GPIO_DISP_B1_00 is configured as ENET_1G_RX_EN */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_01_ENET_1G_RX_CLK, /* GPIO_DISP_B1_01 is configured as ENET_1G_RX_CLK */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_02_ENET_1G_RX_DATA00, /* GPIO_DISP_B1_02 is configured as ENET_1G_RX_DATA00 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_03_ENET_1G_RX_DATA01, /* GPIO_DISP_B1_03 is configured as ENET_1G_RX_DATA01 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_04_ENET_1G_RX_DATA02, /* GPIO_DISP_B1_04 is configured as ENET_1G_RX_DATA02 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_05_ENET_1G_RX_DATA03, /* GPIO_DISP_B1_05 is configured as ENET_1G_RX_DATA03 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_06_ENET_1G_TX_DATA03, /* GPIO_DISP_B1_06 is configured as ENET_1G_TX_DATA03 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_07_ENET_1G_TX_DATA02, /* GPIO_DISP_B1_07 is configured as ENET_1G_TX_DATA02 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_08_ENET_1G_TX_DATA01, /* GPIO_DISP_B1_08 is configured as ENET_1G_TX_DATA01 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_09_ENET_1G_TX_DATA00, /* GPIO_DISP_B1_09 is configured as ENET_1G_TX_DATA00 */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_10_ENET_1G_TX_EN, /* GPIO_DISP_B1_10 is configured as ENET_1G_TX_EN */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_DISP_B1_11_ENET_1G_TX_CLK_IO, /* GPIO_DISP_B1_11 is configured as ENET_1G_TX_CLK_IO */
0U); /* Software Input On Field: Input Path is determined by functionality */
}
/***********************************************************************************************************************

View File

@ -0,0 +1,8 @@
config BOARD_NETWORK_USE_100M_ENET_PORT
bool "Enable 100M Enet Port"
default y
config BOARD_NETWORK_USE_1G_ENET_PORT
bool "Enable 1000M Enet Port"
default y

View File

@ -0,0 +1,3 @@
SRC_FILES := enet_ethernetif.c enet_ethernetif_kinetis.c fsl_enet.c fsl_enet_qos.c
SRC_DIR := phy mdio
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,356 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/ethip6.h"
#include "netif/etharp.h"
#include "netif/ppp/pppoe.h"
#include "lwip/igmp.h"
#include "lwip/mld6.h"
#if USE_RTOS && defined(SDK_OS_FREE_RTOS)
#include "FreeRTOS.h"
#include "event_groups.h"
#endif
#include "pin_mux.h"
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#include "sys_arch.h"
/*******************************************************************************
* Definitions
******************************************************************************/
static mdio_handle_t mdioHandle = {.ops = &EXAMPLE_MDIO_OPS};
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
static phy_handle_t enet0_phyHandle = {.phyAddr = EXAMPLE_ENET0_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_ENET0_PHY_OPS};
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
static phy_handle_t enet1_phyHandle = {.phyAddr = EXAMPLE_ENET1_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_ENET1_PHY_OPS};
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
void Time_Update_LwIP(void)
{
}
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
ethernetif_config_t enet0_cfg = {
.phyHandle = &enet0_phyHandle,
.macAddress = configMAC_ADDR,
};
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
ethernetif_config_t enet1_cfg = {
.phyHandle = &enet1_phyHandle,
.macAddress = configMAC_ADDR_ETH1,
};
#endif
void *ethernetif_config_enet_set(uint8_t enet_port)
{
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
if(0 == enet_port) {
KPrintf("use 100M enet id[%d]\n",enet_port);
return (void *)&enet0_cfg;
}
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
if(1 == enet_port) {
KPrintf("use 1000M enet id[%d]\n",enet_port);
return (void *)&enet1_cfg;
}
#endif
return NULL;
}
int ETH_BSP_Config(void)
{
gpio_pin_config_t gpio_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
GPIO_PinInit(GPIO9, 11, &gpio_config);
GPIO_PinInit(GPIO8, 21, &gpio_config);
/* Pull up the ENET_INT before RESET. */
GPIO_WritePinOutput(GPIO9, 11, 1);
GPIO_WritePinOutput(GPIO8, 21, 0);
SDK_DelayAtLeastUs(10000, CLOCK_GetFreq(kCLOCK_CpuClk));
GPIO_WritePinOutput(GPIO8, 21, 1);
SDK_DelayAtLeastUs(6, CLOCK_GetFreq(kCLOCK_CpuClk));
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
EnableIRQ(ENET_1G_MAC0_Tx_Rx_1_IRQn);
EnableIRQ(ENET_1G_MAC0_Tx_Rx_2_IRQn);
#endif
mdioHandle.resource.csrClock_Hz = EXAMPLE_CLOCK_FREQ;
return 0;
}
void ethernetif_phy_init(struct ethernetif *ethernetif,
const ethernetif_config_t *ethernetifConfig,
phy_speed_t *speed,
phy_duplex_t *duplex)
{
status_t status;
bool link = false;
bool autonego = false;
uint32_t initWaitCount = 0;
uint32_t autoWaitCount = 0;
phy_config_t phyConfig = {
.phyAddr = ethernetifConfig->phyHandle->phyAddr,
.autoNeg = true,
};
ethernetifConfig->phyHandle->mdioHandle->resource.base = *ethernetif_enet_ptr(ethernetif);
LWIP_PLATFORM_DIAG(("Initializing PHY..."));
while ((initWaitCount < ENET_ATONEGOTIATION_TIMEOUT) && (!(link && autonego)))
{
status = PHY_Init(ethernetifConfig->phyHandle, &phyConfig);
if (kStatus_Success != status)
{
LWIP_ASSERT("\r\nCannot initialize PHY.\r\n", 0);
}
/* Wait for auto-negotiation success and link up */
autoWaitCount = ENET_ATONEGOTIATION_TIMEOUT;
do
{
PHY_GetAutoNegotiationStatus(ethernetifConfig->phyHandle, &autonego);
PHY_GetLinkStatus(ethernetifConfig->phyHandle, &link);
if (autonego && link)
{
break;
}
} while (--autoWaitCount);
if (!autonego)
{
LWIP_PLATFORM_DIAG(("PHY Auto-negotiation failed. Please check the cable connection and link partner setting."));
}
initWaitCount++;
}
if (autonego && link)
{
/* Get the actual PHY link speed. */
PHY_GetLinkSpeedDuplex(ethernetifConfig->phyHandle, speed, duplex);
}
#if 0 /* Disable assert. If initial auto-negation is timeout, \ \
the ENET is set to default (100Mbs and full-duplex). */
else
{
LWIP_ASSERT("\r\nGiving up PHY initialization. Please check the ENET cable connection and link partner setting and reset the board.\r\n", 0);
}
#endif
}
/**
* This function should be called when a packet is ready to be read
* from the interface. It uses the function ethernetif_linkinput() that
* should handle the actual reception of bytes from the network
* interface. Then the type of the received packet is determined and
* the appropriate input function is called.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void ethernetif_input(struct netif *netif)
{
struct pbuf *p;
LWIP_ASSERT("netif != NULL", (netif != NULL));
/* move received packet into a new pbuf */
while ((p = ethernetif_linkinput(netif)) != NULL)
{
/* pass all packets to ethernet_input, which decides what packets it supports */
if (netif->input(p, netif) != ERR_OK)
{
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
p = NULL;
}
}
}
void *ethernetif_get_enet_base(const uint8_t enetIdx)
{
ENET_Type *enets[] = ENET_BASE_PTRS;
int arrayIdx;
int enetCount;
for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++)
{
if (enets[arrayIdx] != 0U) /* process only defined positions */
{ /* (some SOC headers count ENETs from 1 instead of 0) */
if (enetCount == enetIdx)
{
return (void *)enets[arrayIdx];
}
enetCount++;
}
}
return NULL;
}
#if defined(FSL_FEATURE_SOC_ENET_QOS_COUNT) && (FSL_FEATURE_SOC_ENET_QOS_COUNT > 0)
void *ethernetif_get_enet_qos_base(const uint8_t enetIdx)
{
ENET_QOS_Type *enets[] = ENET_QOS_BASE_PTRS;
int arrayIdx;
int enetCount;
for (arrayIdx = 0, enetCount = 0; arrayIdx < ARRAY_SIZE(enets); arrayIdx++)
{
if (enets[arrayIdx] != 0U) /* process only defined positions */
{ /* (some SOC headers count ENETs from 1 instead of 0) */
if (enetCount == enetIdx)
{
return (void *)enets[arrayIdx];
}
enetCount++;
}
}
return NULL;
}
#endif
err_t ethernetif_init(struct netif *netif,
struct ethernetif *ethernetif,
void *enetBase,
const ethernetif_config_t *ethernetifConfig)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
LWIP_ASSERT("ethernetifConfig != NULL", (ethernetifConfig != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
/*
* Initialize the snmp variables and counters inside the struct netif.
* The last argument should be replaced with your link speed, in units
* of bits per second.
*/
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
#if LWIP_IPV4
netif->output = etharp_output;
#endif
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = ethernetif_linkoutput;
#if LWIP_IPV4 && LWIP_IGMP
netif_set_igmp_mac_filter(netif, ethernetif_igmp_mac_filter);
netif->flags |= NETIF_FLAG_IGMP;
#endif
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif_set_mld_mac_filter(netif, ethernetif_mld_mac_filter);
netif->flags |= NETIF_FLAG_MLD6;
#endif
/* Init ethernetif parameters.*/
*ethernetif_enet_ptr(ethernetif) = enetBase;
LWIP_ASSERT("*ethernetif_enet_ptr(ethernetif) != NULL", (*ethernetif_enet_ptr(ethernetif) != NULL));
/* set MAC hardware address length */
netif->hwaddr_len = ETH_HWADDR_LEN;
/* set MAC hardware address */
memcpy(netif->hwaddr, ethernetifConfig->macAddress, NETIF_MAX_HWADDR_LEN);
/* maximum transfer unit */
netif->mtu = 1500; /* TODO: define a config */
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
/* ENET driver initialization.*/
ethernetif_enet_init(netif, ethernetif, ethernetifConfig);
#if LWIP_IPV6 && LWIP_IPV6_MLD
/*
* For hardware/netifs that implement MAC filtering.
* All-nodes link-local is handled by default, so we must let the hardware know
* to allow multicast packets in.
* Should set mld_mac_filter previously. */
if (netif->mld_mac_filter != NULL)
{
ip6_addr_t ip6_allnodes_ll;
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
}
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
return ERR_OK;
}

View File

@ -0,0 +1,721 @@
/*
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/ethip6.h"
#include "lwip/igmp.h"
#include "lwip/mem.h"
#include "lwip/mld6.h"
#include "lwip/pbuf.h"
#include "lwip/snmp.h"
#include "lwip/stats.h"
#include "lwip/sys.h"
#include "netif/etharp.h"
#include "netif/ppp/pppoe.h"
#ifdef FSL_RTOS_XIUOS
#define USE_RTOS 1
#define FSL_RTOS_FREE_RTOS
#endif
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
#include "FreeRTOS.h"
#include "event_groups.h"
#endif
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#include "fsl_enet.h"
#include "fsl_phy.h"
#define LWIP_ENET_FLEXIBLE_CONFIGURATION
/*
* Padding of ethernet frames has to be disabled for zero-copy functionality
* since ENET driver requires the starting buffer addresses to be aligned.
*/
#if ETH_PAD_SIZE != 0
#error "ETH_PAD_SIZE != 0"
#endif /* ETH_PAD_SIZE != 0 */
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef ENET_RXBD_NUM
#define ENET_RXBD_NUM (5)
#endif
#ifndef ENET_TXBD_NUM
#define ENET_TXBD_NUM (3)
#endif
#ifndef ENET_RXBUFF_SIZE
#define ENET_RXBUFF_SIZE ENET_FRAME_MAX_FRAMELEN
#endif
#ifndef ENET_TXBUFF_SIZE
#define ENET_TXBUFF_SIZE (ENET_FRAME_MAX_FRAMELEN)
#endif
#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) \
&& ((!defined(FSL_SDK_DISBLE_L2CACHE_PRESENT)) || (FSL_SDK_DISBLE_L2CACHE_PRESENT == 0))
#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define FSL_CACHE_LINESIZE_MAX MAX(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_CACHE_LINESIZE_MAX)
#else
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
#endif
#elif defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#define FSL_ENET_BUFF_ALIGNMENT MAX(ENET_BUFF_ALIGNMENT, FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
#else
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
#endif
#else
#define FSL_ENET_BUFF_ALIGNMENT ENET_BUFF_ALIGNMENT
#endif
typedef uint8_t rx_buffer_t[SDK_SIZEALIGN(ENET_RXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
typedef uint8_t tx_buffer_t[SDK_SIZEALIGN(ENET_TXBUFF_SIZE, FSL_ENET_BUFF_ALIGNMENT)];
/*!
* @brief Used to wrap received data in a pbuf to be passed into lwIP
* without copying.
* Once last reference is released, RX descriptor will be returned to DMA.
*/
typedef struct rx_pbuf_wrapper
{
struct pbuf_custom p; /*!< Pbuf wrapper. Has to be first. */
void *buffer; /*!< Original buffer wrapped by p. */
struct ethernetif *ethernetif; /*!< Ethernet interface context data. */
} rx_pbuf_wrapper_t;
/**
* Helper struct to hold private data used to operate your ethernet interface.
*/
struct ethernetif
{
ENET_Type *base;
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 0)) || \
(USE_RTOS && defined(FSL_RTOS_FREE_RTOS))
enet_handle_t handle;
#endif
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
EventGroupHandle_t enetTransmitAccessEvent;
EventBits_t txFlag;
#endif
enet_rx_bd_struct_t *RxBuffDescrip;
enet_tx_bd_struct_t *TxBuffDescrip;
rx_buffer_t *RxDataBuff;
tx_buffer_t *TxDataBuff;
rx_pbuf_wrapper_t RxPbufs[ENET_RXBD_NUM];
};
/*******************************************************************************
* Prototypes
******************************************************************************/
static void ethernetif_rx_release(struct pbuf *p);
/*******************************************************************************
* Code
******************************************************************************/
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
static void ethernet_callback(ENET_Type *base,
enet_handle_t *handle,
#if FSL_FEATURE_ENET_QUEUE > 1
uint32_t ringId,
#endif /* FSL_FEATURE_ENET_QUEUE */
enet_event_t event,
enet_frame_info_t *frameInfo,
void *userData)
{
struct netif *netif = (struct netif *)userData;
struct ethernetif *ethernetif = netif->state;
BaseType_t xResult;
switch (event)
{
case kENET_RxEvent:
ethernetif_input(netif);
break;
case kENET_TxEvent:
{
portBASE_TYPE taskToWake = pdFALSE;
#ifdef __CA7_REV
if (SystemGetIRQNestingLevel())
#else
if (__get_IPSR())
#endif
{
xResult = xEventGroupSetBitsFromISR(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, &taskToWake);
if ((pdPASS == xResult) && (pdTRUE == taskToWake))
{
portYIELD_FROM_ISR(taskToWake);
}
}
else
{
xEventGroupSetBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag);
}
}
break;
default:
break;
}
}
#endif
#if LWIP_IPV4 && LWIP_IGMP
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
enum netif_mac_filter_action action)
{
struct ethernetif *ethernetif = netif->state;
uint8_t multicastMacAddr[6];
err_t result;
multicastMacAddr[0] = 0x01U;
multicastMacAddr[1] = 0x00U;
multicastMacAddr[2] = 0x5EU;
multicastMacAddr[3] = (group->addr >> 8) & 0x7FU;
multicastMacAddr[4] = (group->addr >> 16) & 0xFFU;
multicastMacAddr[5] = (group->addr >> 24) & 0xFFU;
switch (action)
{
case IGMP_ADD_MAC_FILTER:
/* Adds the ENET device to a multicast group.*/
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
result = ERR_OK;
break;
case IGMP_DEL_MAC_FILTER:
/*
* Moves the ENET device from a multicast group.
* Since the ENET_LeaveMulticastGroup() could filter out also other
* group addresses having the same hash, the call is commented out.
*/
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
result = ERR_OK;
break;
default:
result = ERR_IF;
break;
}
return result;
}
#endif
#if LWIP_IPV6 && LWIP_IPV6_MLD
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
enum netif_mac_filter_action action)
{
struct ethernetif *ethernetif = netif->state;
uint8_t multicastMacAddr[6];
err_t result;
multicastMacAddr[0] = 0x33U;
multicastMacAddr[1] = 0x33U;
multicastMacAddr[2] = (group->addr[3]) & 0xFFU;
multicastMacAddr[3] = (group->addr[3] >> 8) & 0xFFU;
multicastMacAddr[4] = (group->addr[3] >> 16) & 0xFFU;
multicastMacAddr[5] = (group->addr[3] >> 24) & 0xFFU;
switch (action)
{
case NETIF_ADD_MAC_FILTER:
/* Adds the ENET device to a multicast group.*/
ENET_AddMulticastGroup(ethernetif->base, multicastMacAddr);
result = ERR_OK;
break;
case NETIF_DEL_MAC_FILTER:
/*
* Moves the ENET device from a multicast group.
* Since the ENET_LeaveMulticastGroup() could filter out also other
* group addresses having the same hash, the call is commented out.
*/
/* ENET_LeaveMulticastGroup(ethernetif->base, multicastMacAddr); */
result = ERR_OK;
break;
default:
result = ERR_IF;
break;
}
return result;
}
#endif
/**
* Initializes ENET driver.
*/
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
const ethernetif_config_t *ethernetifConfig)
{
enet_config_t config;
uint32_t sysClock;
enet_buffer_config_t buffCfg[ENET_RING_NUM];
phy_speed_t speed;
phy_duplex_t duplex;
int i;
/* prepare the buffer configuration. */
buffCfg[0].rxBdNumber = ENET_RXBD_NUM; /* Receive buffer descriptor number. */
buffCfg[0].txBdNumber = ENET_TXBD_NUM; /* Transmit buffer descriptor number. */
buffCfg[0].rxBuffSizeAlign = sizeof(rx_buffer_t); /* Aligned receive data buffer size. */
buffCfg[0].txBuffSizeAlign = sizeof(tx_buffer_t); /* Aligned transmit data buffer size. */
buffCfg[0].rxBdStartAddrAlign = &(ethernetif->RxBuffDescrip[0]); /* Aligned receive buffer descriptor start address. */
buffCfg[0].txBdStartAddrAlign = &(ethernetif->TxBuffDescrip[0]); /* Aligned transmit buffer descriptor start address. */
buffCfg[0].rxBufferAlign = &(ethernetif->RxDataBuff[0][0]); /* Receive data buffer start address. */
buffCfg[0].txBufferAlign = &(ethernetif->TxDataBuff[0][0]); /* Transmit data buffer start address. */
buffCfg[0].txFrameInfo = NULL; /* Transmit frame information start address. Set only if using zero-copy transmit. */
buffCfg[0].rxMaintainEnable = true; /* Receive buffer cache maintain. */
buffCfg[0].txMaintainEnable = true; /* Transmit buffer cache maintain. */
sysClock = ethernetifConfig->phyHandle->mdioHandle->resource.csrClock_Hz;
ENET_GetDefaultConfig(&config);
config.ringNum = ENET_RING_NUM;
#ifdef LWIP_ENET_FLEXIBLE_CONFIGURATION
extern void BOARD_ENETFlexibleConfigure(enet_config_t *config, uint8_t *hwAddr);
BOARD_ENETFlexibleConfigure(&config, netif->hwaddr);
#endif
ethernetif_phy_init(ethernetif, ethernetifConfig, &speed, &duplex);
//Followings are configured by BOARD_ENETFlexibleConfigure function.
// config.miiSpeed = (enet_mii_speed_t)speed;
// config.miiDuplex = (enet_mii_duplex_t)duplex;
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
uint32_t instance;
static ENET_Type *const enetBases[] = ENET_BASE_PTRS;
static const IRQn_Type enetTxIrqId[] = ENET_Transmit_IRQS;
/*! @brief Pointers to enet receive IRQ number for each instance. */
static const IRQn_Type enetRxIrqId[] = ENET_Receive_IRQS;
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
/*! @brief Pointers to enet timestamp IRQ number for each instance. */
static const IRQn_Type enetTsIrqId[] = ENET_1588_Timer_IRQS;
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
/* Create the Event for transmit busy release trigger. */
ethernetif->enetTransmitAccessEvent = xEventGroupCreate();
ethernetif->txFlag = 0x1;
config.interrupt |= kENET_RxFrameInterrupt | kENET_TxFrameInterrupt | kENET_TxBufferInterrupt | kENET_LateCollisionInterrupt;
for (instance = 0; instance < ARRAY_SIZE(enetBases); instance++)
{
if (enetBases[instance] == ethernetif->base)
{
#ifdef __CA7_REV
GIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
GIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
GIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#else
NVIC_SetPriority(enetRxIrqId[instance], ENET_PRIORITY);
NVIC_SetPriority(enetTxIrqId[instance], ENET_PRIORITY);
#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
NVIC_SetPriority(enetTsIrqId[instance], ENET_1588_PRIORITY);
#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
#endif /* __CA7_REV */
break;
}
}
LWIP_ASSERT("Input Ethernet base error!", (instance != ARRAY_SIZE(enetBases)));
#endif /* USE_RTOS */
for (i = 0; i < ENET_RXBD_NUM; i++)
{
ethernetif->RxPbufs[i].p.custom_free_function = ethernetif_rx_release;
ethernetif->RxPbufs[i].buffer = &(ethernetif->RxDataBuff[i][0]);
ethernetif->RxPbufs[i].ethernetif = ethernetif;
}
/* Initialize the ENET module. */
ENET_Init(ethernetif->base, &ethernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock);
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
ENET_SetCallback(&ethernetif->handle, ethernet_callback, netif);
#endif
ENET_ActiveRead(ethernetif->base);
}
void **ethernetif_enet_ptr(struct ethernetif *ethernetif)
{
return (void **)&(ethernetif->base);
}
/**
* Returns next buffer for TX.
* Can wait if no buffer available.
*/
static unsigned char *enet_get_tx_buffer(struct ethernetif *ethernetif)
{
static unsigned char ucBuffer[ENET_FRAME_MAX_FRAMELEN];
return ucBuffer;
}
/**
* Sends frame via ENET.
*/
static err_t enet_send_frame(struct ethernetif *ethernetif, unsigned char *data, const uint32_t length)
{
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
{
status_t result;
do
{
result = ENET_SendFrame(ethernetif->base, &ethernetif->handle, data, length, 0, false, NULL);
if (result == kStatus_ENET_TxFrameBusy)
{
xEventGroupWaitBits(ethernetif->enetTransmitAccessEvent, ethernetif->txFlag, pdTRUE, (BaseType_t) false,
portMAX_DELAY);
}
} while (result == kStatus_ENET_TxFrameBusy);
return ERR_OK;
}
#else
{
uint32_t counter;
for (counter = ENET_TIMEOUT; counter != 0U; counter--)
{
if (ENET_SendFrame(ethernetif->base, &ethernetif->handle, data, length, 0, false, NULL) != kStatus_ENET_TxFrameBusy)
{
return ERR_OK;
}
}
return ERR_TIMEOUT;
}
#endif
}
/**
* Reclaims RX buffer held by the p after p is no longer used
* by the application / lwIP.
*/
static void ethernetif_rx_release(struct pbuf *p)
{
rx_pbuf_wrapper_t *wrapper = (rx_pbuf_wrapper_t *)p;
SYS_ARCH_DECL_PROTECT(old_level);
SYS_ARCH_PROTECT(old_level);
ENET_ReleaseRxBuffer(wrapper->ethernetif->base, &wrapper->ethernetif->handle, wrapper->buffer, 0);
SYS_ARCH_UNPROTECT(old_level);
}
/**
* Reads a received frame - wraps its descriptor buffer(s) into a pbuf or a pbuf chain and returns it.
* The descriptors are returned to DMA only once the returned pbuf is released.
* Function can be called only after ENET_GetRxFrameSize() indicates
* that there actually is a received frame.
*/
static struct pbuf *ethernetif_read_frame(struct ethernetif *ethernetif, uint32_t length)
{
rx_pbuf_wrapper_t *wrapper;
uint32_t len = 0;
uint32_t ts;
struct pbuf *p = NULL;
struct pbuf *q = NULL;
void *buffer;
bool isLastBuff;
status_t status;
int i;
do
{
status = ENET_GetRxBuffer(ethernetif->base, &ethernetif->handle, &buffer, &len, 0, &isLastBuff, &ts);
LWIP_UNUSED_ARG(status); /* for LWIP_NOASSERT */
LWIP_ASSERT("ENET_GetRxBuffer() status != kStatus_Success", status == kStatus_Success);
/* Find pbuf wrapper for the actually read byte buffer */
wrapper = NULL;
for (i = 0; i < ENET_RXBD_NUM; i++)
{
if (buffer == ethernetif->RxPbufs[i].buffer)
{
wrapper = &ethernetif->RxPbufs[i];
break;
}
}
LWIP_ASSERT("Buffer returned by ENET_GetRxBuffer() doesn't match any RX buffer descriptor", wrapper != NULL);
/* Wrap the receive buffer in pbuf. */
if (p == NULL)
{
p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p, buffer, len);
LWIP_ASSERT("pbuf_alloced_custom() failed", p);
}
else
{
q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &wrapper->p, buffer, len);
LWIP_ASSERT("pbuf_alloced_custom() failed", q);
pbuf_cat(p, q);
}
} while (!isLastBuff);
LWIP_ASSERT("p->tot_len != length", p->tot_len == length);
MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1)
{
/* broadcast or multicast packet */
MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
}
else
{
/* unicast packet */
MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
}
LINK_STATS_INC(link.recv);
return p;
}
/**
* Drops (releases) receive descriptors until the last one of a frame is reached.
* Function can be called only after ENET_GetRxFrameSize() indicates
* that there actually is a frame error or a received frame.
*/
static void ethernetif_drop_frame(struct ethernetif *ethernetif)
{
status_t status;
void *buffer;
uint32_t len;
uint32_t ts;
bool isLastBuff;
do
{
#if 0 /* Error statisctics */
enet_data_error_stats_t eErrStatic;
/* Get the error information of the received g_frame. */
ENET_GetRxErrBeforeReadFrame(&ethernetif->handle, &eErrStatic);
#endif
status = ENET_GetRxBuffer(ethernetif->base, &ethernetif->handle, &buffer, &len, 0, &isLastBuff, &ts);
LWIP_UNUSED_ARG(status); /* for LWIP_NOASSERT */
LWIP_ASSERT("ENET_GetRxBuffer() status != kStatus_Success", status == kStatus_Success);
ENET_ReleaseRxBuffer(ethernetif->base, &ethernetif->handle, buffer, 0);
} while (!isLastBuff);
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_linkinput: RxFrameError\n"));
LINK_STATS_INC(link.drop);
MIB2_STATS_NETIF_INC(netif, ifindiscards);
}
struct pbuf *ethernetif_linkinput(struct netif *netif)
{
struct ethernetif *ethernetif = netif->state;
struct pbuf *p = NULL;
status_t status;
uint32_t len;
/* Obtain the size of the packet and put it into the "len" variable. */
status = ENET_GetRxFrameSize(&ethernetif->handle, &len, 0);
if (status == kStatus_Success)
{
/* Read frame. */
p = ethernetif_read_frame(ethernetif, len);
}
else if (status != kStatus_ENET_RxFrameEmpty)
{
/* Drop the frame when error happened. */
ethernetif_drop_frame(ethernetif);
}
return p;
}
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p)
{
err_t result;
struct ethernetif *ethernetif = netif->state;
struct pbuf *q;
unsigned char *pucBuffer;
unsigned char *pucChar;
LWIP_ASSERT("Output packet buffer empty", p);
pucBuffer = enet_get_tx_buffer(ethernetif);
if (pucBuffer == NULL)
{
return ERR_BUF;
}
/* Initiate transfer. */
#if ETH_PAD_SIZE
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
if (p->len == p->tot_len)
{
/* No pbuf chain, don't have to copy -> faster. */
pucBuffer = (unsigned char *)p->payload;
}
else
{
/* pbuf chain, copy into contiguous ucBuffer. */
if (p->tot_len > ENET_FRAME_MAX_FRAMELEN)
{
return ERR_BUF;
}
else
{
pucChar = pucBuffer;
for (q = p; q != NULL; q = q->next)
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
memcpy(pucChar, q->payload, q->len);
pucChar += q->len;
}
}
}
/* Send frame. */
result = enet_send_frame(ethernetif, pucBuffer, p->tot_len);
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1)
{
/* broadcast or multicast packet*/
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
}
else
{
/* unicast packet */
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
}
/* increase ifoutdiscards or ifouterrors on error */
#if ETH_PAD_SIZE
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return result;
}
/**
* Should be called at the beginning of the program to set up the
* first network interface. It calls the function ethernetif_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif0_init(struct netif *netif)
{
static struct ethernetif ethernetif_0;
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
// SDK_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
// SDK_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static rx_buffer_t rxDataBuff_0[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static tx_buffer_t txDataBuff_0[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
ethernetif_0.RxBuffDescrip = &(rxBuffDescrip_0[0]);
ethernetif_0.TxBuffDescrip = &(txBuffDescrip_0[0]);
ethernetif_0.RxDataBuff = &(rxDataBuff_0[0]);
ethernetif_0.TxDataBuff = &(txDataBuff_0[0]);
return ethernetif_init(netif, &ethernetif_0, ethernetif_get_enet_base(0U), (ethernetif_config_t *)netif->state);
}
#if defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)
/**
* Should be called at the beginning of the program to set up the
* second network interface. It calls the function ethernetif_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif1_init(struct netif *netif)
{
static struct ethernetif ethernetif_1;
AT_NONCACHEABLE_SECTION_ALIGN(static enet_rx_bd_struct_t rxBuffDescrip_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static enet_tx_bd_struct_t txBuffDescrip_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
// SDK_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
// SDK_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static rx_buffer_t rxDataBuff_1[ENET_RXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
AT_NONCACHEABLE_SECTION_ALIGN(static tx_buffer_t txDataBuff_1[ENET_TXBD_NUM], FSL_ENET_BUFF_ALIGNMENT);
ethernetif_1.RxBuffDescrip = &(rxBuffDescrip_1[0]);
ethernetif_1.TxBuffDescrip = &(txBuffDescrip_1[0]);
ethernetif_1.RxDataBuff = &(rxDataBuff_1[0]);
ethernetif_1.TxDataBuff = &(txDataBuff_1[0]);
return ethernetif_init(netif, &ethernetif_1, ethernetif_get_enet_base(1U), (ethernetif_config_t *)netif->state);
}
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
SRC_FILES :=
SRC_DIR := enet enet_qos
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_enet_mdio.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,133 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_enet_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void ENET_MDIO_Init(mdio_handle_t *handle);
static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data);
static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr);
/*******************************************************************************
* Variables
******************************************************************************/
const mdio_operations_t enet_ops = {.mdioInit = ENET_MDIO_Init,
.mdioWrite = ENET_MDIO_Write,
.mdioRead = ENET_MDIO_Read,
.mdioWriteExt = NULL,
.mdioReadExt = NULL};
/*******************************************************************************
* Code
******************************************************************************/
static void ENET_MDIO_Init(mdio_handle_t *handle)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
uint32_t instance = ENET_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Set SMI first. */
(void)CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
ENET_SetSMI(base, resource->csrClock_Hz, false);
}
static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
status_t result = kStatus_Success;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
/* Clear the SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI write command. */
ENET_StartSMIWrite(base, phyAddr, devAddr, kENET_MiiWriteValidFrame, data);
/* Wait for SMI complete. */
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
result = kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
}
#endif
/* Clear SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return result;
}
static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr)
{
assert(dataPtr);
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_Type *base = (ENET_Type *)resource->base;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
/* Clear the SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI read command operation. */
ENET_StartSMIRead(base, phyAddr, devAddr, kENET_MiiReadValidFrame);
/* Wait for SMI complete. */
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (ENET_EIR_MII_MASK == (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
return kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_EIR_MII_MASK != (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK))
{
}
#endif
/* Get data from SMI register. */
*dataPtr = ENET_ReadSMIData(base);
/* Clear SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return kStatus_Success;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_ENET_MDIO_H_
#define _FSL_ENET_MDIO_H_
#include "fsl_enet.h"
#include "fsl_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ENET MDIO operations structure. */
extern const mdio_operations_t enet_ops;
#endif

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_enet_qos_mdio.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,113 @@
/*
* Copyright 2020-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_enet_qos_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
static void ENET_QOS_MDIO_Init(mdio_handle_t *handle);
static status_t ENET_QOS_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data);
static status_t ENET_QOS_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr);
/*******************************************************************************
* Variables
******************************************************************************/
const mdio_operations_t enet_qos_ops = {.mdioInit = ENET_QOS_MDIO_Init,
.mdioWrite = ENET_QOS_MDIO_Write,
.mdioRead = ENET_QOS_MDIO_Read,
.mdioWriteExt = NULL,
.mdioReadExt = NULL};
/*******************************************************************************
* Code
******************************************************************************/
static void ENET_QOS_MDIO_Init(mdio_handle_t *handle)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_QOS_Type *base = (ENET_QOS_Type *)resource->base;
uint32_t instance = ENET_QOS_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Set SMI first. */
CLOCK_EnableClock(s_enetqosClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
ENET_QOS_SetSMI(base, resource->csrClock_Hz);
}
static status_t ENET_QOS_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_QOS_Type *base = (ENET_QOS_Type *)resource->base;
status_t result = kStatus_Success;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
ENET_QOS_StartSMIWrite(base, phyAddr, devAddr, data);
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (!ENET_QOS_IsSMIBusy(base))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
result = kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_QOS_IsSMIBusy(base))
{
}
#endif
return result;
}
static status_t ENET_QOS_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr)
{
mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
ENET_QOS_Type *base = (ENET_QOS_Type *)resource->base;
status_t result = kStatus_Success;
#ifdef MDIO_TIMEOUT_COUNT
uint32_t counter;
#endif
ENET_QOS_StartSMIRead(base, phyAddr, devAddr);
#ifdef MDIO_TIMEOUT_COUNT
for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
{
if (!ENET_QOS_IsSMIBusy(base))
{
break;
}
}
/* Check for timeout. */
if (0U == counter)
{
result = kStatus_PHY_SMIVisitTimeout;
}
#else
while (ENET_QOS_IsSMIBusy(base))
{
}
#endif
*dataPtr = ENET_QOS_ReadSMIData(base);
return result;
}

View File

@ -0,0 +1,21 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_ENET_QOS_MDIO_H_
#define _FSL_ENET_QOS_MDIO_H_
#include "fsl_enet_qos.h"
#include "fsl_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ENET_QOS MDIO operations structure. */
extern const mdio_operations_t enet_qos_ops;
#endif

View File

@ -0,0 +1,3 @@
SRC_FILES :=
SRC_DIR := ksz8081 ksz9131rnx
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,2 @@
SRC_FILES := fsl_phyksz8081.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,344 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_phyksz8081.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/* define by AIIT lab */
#define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE
/*! @brief Defines the PHY KSZ8081 vendor defined registers. */
#define PHY_CONTROL1_REG 0x1EU /*!< The PHY control one register. */
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */
/*! @brief Defines the PHY KSZ8081 ID number. */
#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1 */
/*! @brief Defines the mask flag of operation mode in control registers */
#define PHY_CTL2_REMOTELOOP_MASK 0x0004U /*!< The PHY remote loopback mask. */
#define PHY_CTL2_REFCLK_SELECT_MASK 0x0080U /*!< The PHY RMII reference clock select. */
#define PHY_CTL1_10HALFDUPLEX_MASK 0x0001U /*!< The PHY 10M half duplex mask. */
#define PHY_CTL1_100HALFDUPLEX_MASK 0x0002U /*!< The PHY 100M half duplex mask. */
#define PHY_CTL1_10FULLDUPLEX_MASK 0x0005U /*!< The PHY 10M full duplex mask. */
#define PHY_CTL1_100FULLDUPLEX_MASK 0x0006U /*!< The PHY 100M full duplex mask. */
#define PHY_CTL1_SPEEDUPLX_MASK 0x0007U /*!< The PHY speed and duplex mask. */
#define PHY_CTL1_ENERGYDETECT_MASK 0x10U /*!< The PHY signal present on rx differential pair. */
#define PHY_CTL1_LINKUP_MASK 0x100U /*!< The PHY link up. */
#define PHY_LINK_READY_MASK (PHY_CTL1_ENERGYDETECT_MASK | PHY_CTL1_LINKUP_MASK)
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
const phy_operations_t phyksz8081_ops = {.phyInit = PHY_KSZ8081_Init,
.phyWrite = PHY_KSZ8081_Write,
.phyRead = PHY_KSZ8081_Read,
.getAutoNegoStatus = PHY_KSZ8081_GetAutoNegotiationStatus,
.getLinkStatus = PHY_KSZ8081_GetLinkStatus,
.getLinkSpeedDuplex = PHY_KSZ8081_GetLinkSpeedDuplex,
.setLinkSpeedDuplex = PHY_KSZ8081_SetLinkSpeedDuplex,
.enableLoopback = PHY_KSZ8081_EnableLoopback};
/*******************************************************************************
* Code
******************************************************************************/
status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config)
{
uint32_t counter = PHY_READID_TIMEOUT_COUNT;
status_t result = kStatus_Success;
uint32_t regValue = 0;
/* Init MDIO interface. */
MDIO_Init(handle->mdioHandle);
/* Assign phy address. */
handle->phyAddr = config->phyAddr;
/* Check PHY ID. */
do
{
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);
if (result != kStatus_Success)
{
return result;
}
counter--;
} while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
if (counter == 0U)
{
return kStatus_Fail;
}
/* Reset PHY. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
if (result == kStatus_Success)
{
#if defined(FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE)
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, &regValue);
if (result != kStatus_Success)
{
return result;
}
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, (regValue | PHY_CTL2_REFCLK_SELECT_MASK));
if (result != kStatus_Success)
{
return result;
}
#endif /* FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE */
if (config->autoNeg)
{
/* Set the auto-negotiation then start it. */
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG,
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | PHY_IEEE802_3_SELECTOR_MASK));
if (result == kStatus_Success)
{
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
else
{
/* This PHY only supports 10/100M speed. */
assert(config->speed <= kPHY_Speed100M);
/* Disable isolate mode */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result != kStatus_Success)
{
return result;
}
regValue &= ~PHY_BCTL_ISOLATE_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
if (result != kStatus_Success)
{
return result;
}
/* Disable the auto-negotiation and set user-defined speed/duplex configuration. */
result = PHY_KSZ8081_SetLinkSpeedDuplex(handle, config->speed, config->duplex);
}
}
return result;
}
status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data)
{
return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
}
status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr)
{
return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
}
status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status)
{
assert(status);
status_t result;
uint32_t regValue;
*status = false;
/* Check auto negotiation complete. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success)
{
if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U)
{
*status = true;
}
}
return result;
}
status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status)
{
assert(status);
status_t result;
uint32_t regValue;
/* Read the basic status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success)
{
if ((PHY_BSTATUS_LINKSTATUS_MASK & regValue) != 0U)
{
/* Link up. */
*status = true;
}
else
{
/* Link down. */
*status = false;
}
}
return result;
}
status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
{
assert(!((speed == NULL) && (duplex == NULL)));
status_t result;
uint32_t regValue;
uint32_t flag;
/* Read the control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL1_REG, &regValue);
if (result == kStatus_Success)
{
if (speed != NULL)
{
flag = regValue & PHY_CTL1_SPEEDUPLX_MASK;
if ((PHY_CTL1_100HALFDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag))
{
*speed = kPHY_Speed100M;
}
else
{
*speed = kPHY_Speed10M;
}
}
if (duplex != NULL)
{
flag = regValue & PHY_CTL1_SPEEDUPLX_MASK;
if ((PHY_CTL1_10FULLDUPLEX_MASK == flag) || (PHY_CTL1_100FULLDUPLEX_MASK == flag))
{
*duplex = kPHY_FullDuplex;
}
else
{
*duplex = kPHY_HalfDuplex;
}
}
}
return result;
}
status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex)
{
/* This PHY only supports 10/100M speed. */
assert(speed <= kPHY_Speed100M);
status_t result;
uint32_t regValue;
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success)
{
/* Disable the auto-negotiation and set according to user-defined configuration. */
regValue &= ~PHY_BCTL_AUTONEG_MASK;
if (speed == kPHY_Speed100M)
{
regValue |= PHY_BCTL_SPEED0_MASK;
}
else
{
regValue &= ~PHY_BCTL_SPEED0_MASK;
}
if (duplex == kPHY_FullDuplex)
{
regValue |= PHY_BCTL_DUPLEX_MASK;
}
else
{
regValue &= ~PHY_BCTL_DUPLEX_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
return result;
}
status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable)
{
/* This PHY only supports local/remote loopback and 10/100M speed. */
assert(mode <= kPHY_RemoteLoop);
assert(speed <= kPHY_Speed100M);
status_t result;
uint32_t regValue;
/* Set the loop mode. */
if (enable)
{
if (mode == kPHY_LocalLoop)
{
if (speed == kPHY_Speed100M)
{
regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
else
{
regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
else
{
/* Remote loopback only supports 100M full-duplex. */
assert(speed == kPHY_Speed100M);
regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
if (result != kStatus_Success)
{
return result;
}
/* Set the remote loopback bit. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, &regValue);
if (result == kStatus_Success)
{
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG,
(regValue | PHY_CTL2_REMOTELOOP_MASK));
}
}
}
else
{
/* Disable the loop mode. */
if (mode == kPHY_LocalLoop)
{
/* First read the current status in control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success)
{
regValue &= ~PHY_BCTL_LOOP_MASK;
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
else
{
/* First read the current status in control one register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG, &regValue);
if (result == kStatus_Success)
{
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG,
(regValue & ~PHY_CTL2_REMOTELOOP_MASK));
}
}
}
return result;
}

View File

@ -0,0 +1,163 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*****************************************************************************
* PHY KSZ8081 driver change log
*****************************************************************************/
/*!
@page driver_log Driver Change Log
@section phyksz8081 PHYKSZ8081
The current PHYKSZ8081 driver version is 2.0.0.
- 2.0.0
- Initial version.
*/
#ifndef _FSL_PHYKSZ8081_H_
#define _FSL_PHYKSZ8081_H_
#include "fsl_phy.h"
/*!
* @addtogroup phy_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief PHY driver version */
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*! @brief PHY operations structure. */
extern const phy_operations_t phyksz8081_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize PHY.
*
* @param handle PHY device handle.
* @param config Pointer to structure of phy_config_t.
* @retval kStatus_Success PHY initialization succeeds
* @retval kStatus_Fail PHY initialization fails
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_Init(phy_handle_t *handle, const phy_config_t *config);
/*!
* @brief PHY Write function. This function writes data over the SMI to
* the specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param data The data written to the PHY register.
* @retval kStatus_Success PHY write success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data);
/*!
* @brief PHY Read function. This interface read data over the SMI from the
* specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param dataPtr The address to store the data read from the PHY register.
* @retval kStatus_Success PHY read success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr);
/*!
* @brief Gets the PHY auto-negotiation status.
*
* @param handle PHY device handle.
* @param status The auto-negotiation status of the PHY.
* - true the auto-negotiation is over.
* - false the auto-negotiation is on-going or not started.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link status.
*
* @param handle PHY device handle.
* @param status The link up or down status of the PHY.
* - true the link is up.
* - false the link is down.
* @retval kStatus_Success PHY gets link status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_GetLinkStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link speed and duplex.
*
* @brief This function gets the speed and duplex mode of PHY. User can give one of speed
* and duplex address paramter and set the other as NULL if only wants to get one of them.
*
* @param handle PHY device handle.
* @param speed The address of PHY link speed.
* @param duplex The link duplex of PHY.
* @retval kStatus_Success PHY gets link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex);
/*!
* @brief Sets the PHY link speed and duplex.
*
* @param handle PHY device handle.
* @param speed Specified PHY link speed.
* @param duplex Specified PHY link duplex.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex);
/*!
* @brief Enables/disables PHY loopback.
*
* @param handle PHY device handle.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* All loopback modes should not be set together, when one loopback mode is set
* another should be disabled.
* @param speed PHY speed for loopback mode.
* @param enable True to enable, false to disable.
* @retval kStatus_Success PHY loopback success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ8081_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_PHYKSZ8081_H_ */

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_phyksz9131rnx.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,302 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_phyksz9131rnx.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines the PHY RTL8211F vendor defined registers. */
#define PHY_SPECIFIC_STATUS_REG 0x01U /*!< The PHY specific status register. */
#define PHY_PAGE_SELECT_REG 0x1FU /*!< The PHY page select register. */
/*! @brief Defines the PHY RTL8211F ID number. */
#define PHY_CONTROL_ID1 0x0022U /*!< The PHY ID1 . */
/*! @brief Defines the mask flag in specific status register. */
#define PHY_SSTATUS_LINKSTATUS_MASK 0x04U /*!< The PHY link status mask. */
#define PHY_SSTATUS_LINKSPEED_MASK 0x30U /*!< The PHY link speed mask. */
#define PHY_SSTATUS_LINKDUPLEX_MASK 0x08U /*!< The PHY link duplex mask. */
#define PHY_SSTATUS_LINKSPEED_SHIFT 4U /*!< The link speed shift */
/*! @brief Defines the PHY RTL8211F extra page and the registers in specified page. */
#define PHY_PAGE_RGMII_TXRX_DELAY_ADDR 0xD08U /*!< The register page including RGMII TX/RX delay setting. */
#define PHY_RGMII_TX_DELAY_REG 0x11U /*!< The RGMII TXC delay register. */
#define PHY_RGMII_RX_DELAY_REG 0x15U /*!< The RGMII RXC delay register. */
#define PHY_RGMII_TX_DELAY_MASK 0x100U /*!< The RGMII TXC delay mask. */
#define PHY_RGMII_RX_DELAY_MASK 0x8U /*!< The RGMII RXC delay mask. */
/*! @brief MDIO MMD Devices .*/
#define PHY_MDIO_MMD_PCS 3U
#define PHY_MDIO_MMD_AN 7U
/*! @brief MDIO MMD Physical Coding layer device registers .*/
#define PHY_MDIO_PCS_EEE_CAP 0x14U /* EEE capability */
/*! @brief MDIO MMD AutoNegotiation device registers .*/
#define PHY_MDIO_AN_EEE_ADV 0x3CU /* EEE advertisement */
/*! @brief MDIO MMD EEE mask flags. (common for adv and cap) */
#define PHY_MDIO_EEE_100TX 0x2U
#define PHY_MDIO_EEE_1000T 0x4U
/*! @brief Defines the timeout macro. */
#define PHY_READID_TIMEOUT_COUNT 1000U
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
const phy_operations_t phyksz9131rnx_ops = {.phyInit = PHY_KSZ9131RNX_Init,
.phyWrite = PHY_KSZ9131RNX_Write,
.phyRead = PHY_KSZ9131RNX_Read,
.getAutoNegoStatus = PHY_KSZ9131RNX_GetAutoNegotiationStatus,
.getLinkStatus = PHY_KSZ9131RNX_GetLinkStatus,
.getLinkSpeedDuplex = PHY_KSZ9131RNX_GetLinkSpeedDuplex,
.setLinkSpeedDuplex = PHY_KSZ9131RNX_SetLinkSpeedDuplex,
.enableLoopback = PHY_KSZ9131RNX_EnableLoopback};
/*******************************************************************************
* Code
******************************************************************************/
status_t PHY_KSZ9131RNX_Init(phy_handle_t *handle, const phy_config_t *config)
{
uint32_t counter = PHY_READID_TIMEOUT_COUNT;
status_t result;
uint32_t regValue = 0U;
/* Init MDIO interface. */
MDIO_Init(handle->mdioHandle);
/* Assign phy address. */
handle->phyAddr = config->phyAddr;
/* Check PHY ID. */
do
{
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_ID1_REG, &regValue);
if (result != kStatus_Success)
{
return result;
}
counter--;
} while ((regValue != PHY_CONTROL_ID1) && (counter != 0U));
if (counter == 0U)
{
return kStatus_Fail;
}
/* Reset PHY. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
if (result != kStatus_Success)
{
return result;
}
/* Set the negotiation. */
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_AUTONEG_ADVERTISE_REG,
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK | PHY_10BASETX_FULLDUPLEX_MASK |
PHY_10BASETX_HALFDUPLEX_MASK));
if (result == kStatus_Success)
{
result =
MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_1000BASET_CONTROL_REG, PHY_1000BASET_FULLDUPLEX_MASK);
if (result == kStatus_Success)
{
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
return result;
}
status_t PHY_KSZ9131RNX_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data)
{
return MDIO_Write(handle->mdioHandle, handle->phyAddr, phyReg, data);
}
status_t PHY_KSZ9131RNX_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr)
{
return MDIO_Read(handle->mdioHandle, handle->phyAddr, phyReg, dataPtr);
}
status_t PHY_KSZ9131RNX_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status)
{
assert(status);
status_t result;
uint32_t regValue;
*status = false;
/* Check auto negotiation complete. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICSTATUS_REG, &regValue);
if (result == kStatus_Success)
{
if ((regValue & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0U)
{
*status = true;
}
}
return result;
}
status_t PHY_KSZ9131RNX_GetLinkStatus(phy_handle_t *handle, bool *status)
{
assert(status);
status_t result;
uint32_t regValue;
/* Read the basic status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
if (result == kStatus_Success)
{
if ((PHY_SSTATUS_LINKSTATUS_MASK & regValue) != 0U)
{
/* Link up. */
*status = true;
}
else
{
/* Link down. */
*status = false;
}
}
return result;
}
status_t PHY_KSZ9131RNX_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
{
assert(!((speed == NULL) && (duplex == NULL)));
status_t result;
uint32_t regValue;
/* Read the status register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_SPECIFIC_STATUS_REG, &regValue);
if (result == kStatus_Success)
{
if (speed != NULL)
{
switch ((regValue & PHY_SSTATUS_LINKSPEED_MASK) >> PHY_SSTATUS_LINKSPEED_SHIFT)
{
case (uint32_t)kPHY_Speed10M:
*speed = kPHY_Speed10M;
break;
case (uint32_t)kPHY_Speed100M:
*speed = kPHY_Speed100M;
break;
case (uint32_t)kPHY_Speed1000M:
*speed = kPHY_Speed1000M;
break;
default:
*speed = kPHY_Speed10M;
break;
}
}
if (duplex != NULL)
{
if ((regValue & PHY_SSTATUS_LINKDUPLEX_MASK) != 0U)
{
*duplex = kPHY_FullDuplex;
}
else
{
*duplex = kPHY_HalfDuplex;
}
}
}
return result;
}
status_t PHY_KSZ9131RNX_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex)
{
status_t result;
uint32_t regValue;
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success)
{
/* Disable the auto-negotiation and set according to user-defined configuration. */
regValue &= ~PHY_BCTL_AUTONEG_MASK;
if (speed == kPHY_Speed1000M)
{
regValue &= PHY_BCTL_SPEED0_MASK;
regValue |= PHY_BCTL_SPEED1_MASK;
}
else if (speed == kPHY_Speed100M)
{
regValue |= PHY_BCTL_SPEED0_MASK;
regValue &= ~PHY_BCTL_SPEED1_MASK;
}
else
{
regValue &= ~PHY_BCTL_SPEED0_MASK;
regValue &= ~PHY_BCTL_SPEED1_MASK;
}
if (duplex == kPHY_FullDuplex)
{
regValue |= PHY_BCTL_DUPLEX_MASK;
}
else
{
regValue &= ~PHY_BCTL_DUPLEX_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
return result;
}
status_t PHY_KSZ9131RNX_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable)
{
/* This PHY only supports local loopback. */
assert(mode == kPHY_LocalLoop);
status_t result;
uint32_t regValue;
/* Set the loop mode. */
if (enable)
{
if (speed == kPHY_Speed1000M)
{
regValue = PHY_BCTL_SPEED1_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
else if (speed == kPHY_Speed100M)
{
regValue = PHY_BCTL_SPEED0_MASK | PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
else
{
regValue = PHY_BCTL_DUPLEX_MASK | PHY_BCTL_LOOP_MASK;
}
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, regValue);
}
else
{
/* First read the current status in control register. */
result = MDIO_Read(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG, &regValue);
if (result == kStatus_Success)
{
regValue &= ~PHY_BCTL_LOOP_MASK;
result = MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_BASICCONTROL_REG,
(regValue | PHY_BCTL_RESTART_AUTONEG_MASK));
}
}
return result;
}

View File

@ -0,0 +1,163 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*****************************************************************************
* PHY KSZ9131RNX driver change log
*****************************************************************************/
/*!
@page driver_log Driver Change Log
@section phyrtl8211 PHYKSZ9131RNX
The current PHYKSZ9131RNX driver version is 2.0.0.
- 2.0.0
- Initial version.
*/
#ifndef _FSL_PHYKSZ9131RNX_H_
#define _FSL_PHYKSZ9131RNX_H_
#include "fsl_phy.h"
/*!
* @addtogroup phy_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief PHY driver version */
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*! @brief PHY operations structure. */
extern const phy_operations_t phyksz9131rnx_ops;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize PHY.
*
* @param handle PHY device handle.
* @param config Pointer to structure of phy_config_t.
* @retval kStatus_Success PHY initialization succeeds
* @retval kStatus_Fail PHY initialization fails
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_Init(phy_handle_t *handle, const phy_config_t *config);
/*!
* @brief PHY Write function. This function writes data over the SMI to
* the specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param data The data written to the PHY register.
* @retval kStatus_Success PHY write success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data);
/*!
* @brief PHY Read function. This interface reads data over the SMI from the
* specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param dataPtr The address to store the data read from the PHY register.
* @retval kStatus_Success PHY read success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr);
/*!
* @brief Gets the PHY auto-negotiation status.
*
* @param handle PHY device handle.
* @param status The auto-negotiation status of the PHY.
* - true the auto-negotiation is over.
* - false the auto-negotiation is on-going or not started.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link status.
*
* @param handle PHY device handle.
* @param status The link up or down status of the PHY.
* - true the link is up.
* - false the link is down.
* @retval kStatus_Success PHY gets link status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_GetLinkStatus(phy_handle_t *handle, bool *status);
/*!
* @brief Gets the PHY link speed and duplex.
*
* @brief This function gets the speed and duplex mode of PHY. User can give one of speed
* and duplex address paramter and set the other as NULL if only wants to get one of them.
*
* @param handle PHY device handle.
* @param speed The address of PHY link speed.
* @param duplex The link duplex of PHY.
* @retval kStatus_Success PHY gets link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex);
/*!
* @brief Sets the PHY link speed and duplex.
*
* @param handle PHY device handle.
* @param speed Specified PHY link speed.
* @param duplex Specified PHY link duplex.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex);
/*!
* @brief Enables/disables PHY loopback.
*
* @param handle PHY device handle.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* All loopback modes should not be set together, when one loopback mode is set
* another should be disabled.
* @param speed PHY speed for loopback mode.
* @param enable True to enable, false to disable.
* @retval kStatus_Success PHY loopback success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
status_t PHY_KSZ9131RNX_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_PHY_H_ */

View File

@ -1,3 +1,3 @@
SRC_FILES := connect_gpio.c fsl_gpio.c
SRC_FILES := fsl_gpio.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_ethernet.h
* @brief Adapted network software protocol stack and hardware operation functions
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-12-7
*/
#ifndef __CONNECT_ETHERNET_H_
#define __CONNECT_ETHERNET_H_
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef sourceClock
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/*
* Copyright (c) 2013-2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ENET_ETHERNETIF_H
#define ENET_ETHERNETIF_H
#include "lwip/err.h"
#include "lwip/netif.h"
#include "fsl_phy.h"
#include <board.h>
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
#include "fsl_phyksz8081.h"
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
#include "fsl_phyksz9131rnx.h"
#endif
#include "fsl_enet_mdio.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#ifdef BOARD_NETWORK_USE_100M_ENET_PORT
/* Address of PHY interface. */
#define EXAMPLE_ENET0_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS
/* PHY operations. */
#define EXAMPLE_ENET0_PHY_OPS phyksz8081_ops
/* ENET instance select. */
#define NETIF_ENET0_INIT_FUNC ethernetif0_init
#endif
#ifdef BOARD_NETWORK_USE_1G_ENET_PORT
/* Address of PHY interface. */
#define EXAMPLE_ENET1_PHY_ADDRESS BOARD_ENET1_PHY_ADDRESS
/* PHY operations. */
#define EXAMPLE_ENET1_PHY_OPS phyksz9131rnx_ops
/* ENET instance select. */
#define NETIF_ENET1_INIT_FUNC ethernetif1_init
#endif
/* MDIO operations. */
#define EXAMPLE_MDIO_OPS enet_ops
/* ENET clock frequency. */
#define EXAMPLE_CLOCK_FREQ CLOCK_GetRootClockFreq(kCLOCK_Root_Bus)
#define ENET_TIMEOUT (0xFFFU)
/* ENET IRQ priority. Used in FreeRTOS. */
/* Interrupt priorities. */
#ifdef __CA7_REV
#ifndef ENET_PRIORITY
#define ENET_PRIORITY (21U)
#endif
#ifndef ENET_1588_PRIORITY
#define ENET_1588_PRIORITY (20U)
#endif
#else
#ifndef ENET_PRIORITY
#define ENET_PRIORITY (6U)
#endif
#ifndef ENET_1588_PRIORITY
#define ENET_1588_PRIORITY (5U)
#endif
#endif
/* Defines Ethernet Autonegotiation Timeout during initialization.
* Set it to 0 to disable the waiting. */
#ifndef ENET_ATONEGOTIATION_TIMEOUT
#define ENET_ATONEGOTIATION_TIMEOUT (0x2FFFFU)
#endif
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'n'
#define ENET_RING_NUM 1U
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
typedef struct mem_range
{
uint32_t start;
uint32_t end;
} mem_range_t;
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
/**
* Helper struct to hold data for configuration of ethernet interface.
*/
typedef struct ethernetif_config
{
phy_handle_t *phyHandle;
uint8_t macAddress[NETIF_MAX_HWADDR_LEN];
#if (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0))
const mem_range_t *non_dma_memory;
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
} ethernetif_config_t;
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/**
* This function should be passed as a parameter to netif_add()
* if you initialize the first ENET interface.
*/
err_t ethernetif0_init(struct netif *netif);
#if (defined(FSL_FEATURE_SOC_ENET_COUNT) && (FSL_FEATURE_SOC_ENET_COUNT > 1)) \
|| (defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 1))
/**
* This function should be passed as a parameter to netif_add()
* if you initialize the second ENET interface.
*/
err_t ethernetif1_init(struct netif *netif);
#endif /* FSL_FEATURE_SOC_*_ENET_COUNT */
/**
* This function should be called when a packet is ready to be read
* from the interface.
* It is used by bare-metal applications.
*
* @param netif the lwip network interface structure for this ethernetif
*/
void ethernetif_input( struct netif *netif);
int ETH_BSP_Config(void);
void *ethernetif_config_enet_set(uint8_t enet_port);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* ENET_ETHERNETIF_H */

View File

@ -0,0 +1,80 @@
/*
* Copyright 2019 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef ENET_ETHERNETIF_PRIV_H
#define ENET_ETHERNETIF_PRIV_H
#include "lwip/err.h"
struct ethernetif;
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
err_t ethernetif_init(struct netif *netif, struct ethernetif *ethernetif,
void *enetBase,
const ethernetif_config_t *ethernetifConfig);
void ethernetif_enet_init(struct netif *netif, struct ethernetif *ethernetif,
const ethernetif_config_t *ethernetifConfig);
void ethernetif_phy_init(struct ethernetif *ethernetif,
const ethernetif_config_t *ethernetifConfig,
phy_speed_t *speed,
phy_duplex_t *duplex);
void *ethernetif_get_enet_base(const uint8_t enetIdx);
#if defined(FSL_FEATURE_SOC_ENET_QOS_COUNT) && (FSL_FEATURE_SOC_ENET_QOS_COUNT > 0)
void *ethernetif_get_enet_qos_base(const uint8_t enetIdx);
#endif
void **ethernetif_enet_ptr(struct ethernetif *ethernetif);
#if LWIP_IPV4 && LWIP_IGMP
err_t ethernetif_igmp_mac_filter(struct netif *netif, const ip4_addr_t *group,
enum netif_mac_filter_action action);
#endif
#if LWIP_IPV6 && LWIP_IPV6_MLD
err_t ethernetif_mld_mac_filter(struct netif *netif, const ip6_addr_t *group,
enum netif_mac_filter_action action);
#endif
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param netif the lwip network interface structure for this ethernetif
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
struct pbuf *ethernetif_linkinput(struct netif *netif);
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param netif the lwip network interface structure for this ethernetif
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become available since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
err_t ethernetif_linkoutput(struct netif *netif, struct pbuf *p);
#if defined(__cplusplus)
}
#endif /* __cplusplus */
#endif /* ENET_ETHERNETIF_PRIV_H */

View File

@ -28,7 +28,6 @@ Modification:
#ifndef __FSL_DEVICE_REGISTERS_H__
#define __FSL_DEVICE_REGISTERS_H__
#define CPU_MIMXRT1176DVMAA_cm7
/*
* Include the cpu specific register header files.
*

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,128 @@
/*
* Copyright 2020-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_MDIO_H_
#define _FSL_MDIO_H_
#include "fsl_common.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines the timeout macro. */
#if defined(MDIO_TIMEOUT_COUNT_NUMBER) && MDIO_TIMEOUT_COUNT_NUMBER
#define MDIO_TIMEOUT_COUNT MDIO_TIMEOUT_COUNT_NUMBER
#endif
/*! @brief Defines the PHY status. */
enum _mdio_status
{
kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 0), /*!< ENET PHY SMI visit timeout. */
};
typedef struct _mdio_operations mdio_operations_t;
/*! @brief MDIO resource. */
typedef struct _mdio_resource
{
void *base; /*!< ENET Ip register base. */
uint32_t csrClock_Hz; /*!< ENET CSR clock. */
} mdio_resource_t;
/*! @brief MDIO handle. */
typedef struct _mdio_handle
{
mdio_resource_t resource;
const mdio_operations_t *ops;
} mdio_handle_t;
/*! @brief Camera receiver operations. */
struct _mdio_operations
{
void (*mdioInit)(mdio_handle_t *handle); /*!< MDIO interface init. */
status_t (*mdioWrite)(mdio_handle_t *handle,
uint32_t phyAddr,
uint32_t devAddr,
uint32_t data); /*!< IEEE 802.3 Clause 22 MDIO write data. */
status_t (*mdioRead)(mdio_handle_t *handle,
uint32_t phyAddr,
uint32_t devAddr,
uint32_t *dataPtr); /*!< IEEE 802.3 Clause 22 MDIO read data. */
status_t (*mdioWriteExt)(mdio_handle_t *handle,
uint32_t phyAddr,
uint32_t devAddr,
uint32_t data); /*!< IEEE 802.3 Clause 45 MDIO write data. */
status_t (*mdioReadExt)(mdio_handle_t *handle,
uint32_t phyAddr,
uint32_t devAddr,
uint32_t *dataPtr); /*!< IEEE 802.3 Clause 45 MDIO read data. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name MDIO Driver
* @{
*/
/*!
* @brief MDIO Write function. This function write data over the SMI to
* the specified MDIO register. This function is called by all MDIO interfaces.
*
* @param handle MDIO device handle.
* @retval kStatus_Success MDIO write success
* @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out
*/
static inline void MDIO_Init(mdio_handle_t *handle)
{
handle->ops->mdioInit(handle);
}
/*!
* @brief MDIO Write function. This function write data over the SMI to
* the specified MDIO register. This function is called by all MDIO interfaces.
*
* @param handle MDIO device handle.
* @param phyAddr MDIO PHY address handle.
* @param devAddr The PHY device register.
* @param data The data written to the MDIO register.
* @retval kStatus_Success MDIO write success
* @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out
*/
static inline status_t MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data)
{
return handle->ops->mdioWrite(handle, phyAddr, devAddr, data);
}
/*!
* @brief MDIO Read function. This interface read data over the SMI from the
* specified MDIO register. This function is called by all MDIO interfaces.
*
* @param handle MDIO device handle.
* @param phyAddr MDIO PHY address handle.
* @param devAddr The PHY device register.
* @param dataPtr The address to store the data read from the MDIO register.
* @retval kStatus_Success MDIO read success
* @retval kStatus_MDIO_SMIVisitTimeout MDIO SMI visit time out
*/
static inline status_t MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr)
{
return handle->ops->mdioRead(handle, phyAddr, devAddr, dataPtr);
}
/* @} */
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,266 @@
/*
* Copyright 2020 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_PHY_H_
#define _FSL_PHY_H_
#include "fsl_mdio.h"
/*! @note The following PHY registers are the IEEE802.3 standard definition, same register and bit field may
have different names in various PHYs, but the feature they represent should be same or very similar. */
/*! @brief Defines the IEEE802.3 standard PHY registers. */
#define PHY_BASICCONTROL_REG 0x00U /*!< The PHY basic control register. */
#define PHY_BASICSTATUS_REG 0x01U /*!< The PHY basic status register. */
#define PHY_ID1_REG 0x02U /*!< The PHY ID one register. */
#define PHY_ID2_REG 0x03U /*!< The PHY ID two register. */
#define PHY_AUTONEG_ADVERTISE_REG 0x04U /*!< The PHY auto-negotiate advertise register. */
#define PHY_AUTONEG_LINKPARTNER_REG 0x05U /*!< The PHY auto negotiation link partner ability register. */
#define PHY_AUTONEG_EXPANSION_REG 0x06U /*!< The PHY auto negotiation expansion register. */
#define PHY_1000BASET_CONTROL_REG 0x09U /*!< The PHY 1000BASE-T control register. */
#define PHY_MMD_ACCESS_CONTROL_REG 0x0DU /*!< The PHY MMD access control register. */
#define PHY_MMD_ACCESS_DATA_REG 0x0EU /*!< The PHY MMD access data register. */
/*! @brief Defines the mask flag in basic control register(Address 0x00). */
#define PHY_BCTL_SPEED1_MASK 0x0040U /*!< The PHY speed bit mask(MSB).*/
#define PHY_BCTL_ISOLATE_MASK 0x0400U /*!< The PHY isolate mask.*/
#define PHY_BCTL_DUPLEX_MASK 0x0100U /*!< The PHY duplex bit mask. */
#define PHY_BCTL_RESTART_AUTONEG_MASK 0x0200U /*!< The PHY restart auto negotiation mask. */
#define PHY_BCTL_AUTONEG_MASK 0x1000U /*!< The PHY auto negotiation bit mask. */
#define PHY_BCTL_SPEED0_MASK 0x2000U /*!< The PHY speed bit mask(LSB). */
#define PHY_BCTL_LOOP_MASK 0x4000U /*!< The PHY loop bit mask. */
#define PHY_BCTL_RESET_MASK 0x8000U /*!< The PHY reset bit mask. */
/*! @brief Defines the mask flag in basic status register(Address 0x01). */
#define PHY_BSTATUS_LINKSTATUS_MASK 0x0004U /*!< The PHY link status mask. */
#define PHY_BSTATUS_AUTONEGABLE_MASK 0x0008U /*!< The PHY auto-negotiation ability mask. */
#define PHY_BSTATUS_SPEEDUPLX_MASK 0x001CU /*!< The PHY speed and duplex mask. */
#define PHY_BSTATUS_AUTONEGCOMP_MASK 0x0020U /*!< The PHY auto-negotiation complete mask. */
/*! @brief Defines the mask flag in PHY auto-negotiation advertise register(Address 0x04). */
#define PHY_100BaseT4_ABILITY_MASK 0x200U /*!< The PHY have the T4 ability. */
#define PHY_100BASETX_FULLDUPLEX_MASK 0x100U /*!< The PHY has the 100M full duplex ability.*/
#define PHY_100BASETX_HALFDUPLEX_MASK 0x080U /*!< The PHY has the 100M full duplex ability.*/
#define PHY_10BASETX_FULLDUPLEX_MASK 0x040U /*!< The PHY has the 10M full duplex ability.*/
#define PHY_10BASETX_HALFDUPLEX_MASK 0x020U /*!< The PHY has the 10M full duplex ability.*/
#define PHY_IEEE802_3_SELECTOR_MASK 0x001U /*!< The message type being sent by Auto-Nego.*/
/*! @brief Defines the mask flag in the 1000BASE-T control register(Address 0x09). */
#define PHY_1000BASET_FULLDUPLEX_MASK 0x200U /*!< The PHY has the 1000M full duplex ability.*/
#define PHY_1000BASET_HALFDUPLEX_MASK 0x100U /*!< The PHY has the 1000M half duplex ability.*/
/*******************************************************************************
* Definitions
******************************************************************************/
typedef struct _phy_handle phy_handle_t;
/*! @brief Defines the PHY link speed. */
typedef enum _phy_speed
{
kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */
kPHY_Speed100M, /*!< ENET PHY 100M speed. */
kPHY_Speed1000M /*!< ENET PHY 1000M speed. */
} phy_speed_t;
/*! @brief Defines the PHY link duplex. */
typedef enum _phy_duplex
{
kPHY_HalfDuplex = 0U, /*!< ENET PHY half duplex. */
kPHY_FullDuplex /*!< ENET PHY full duplex. */
} phy_duplex_t;
/*! @brief Defines the PHY loopback mode. */
typedef enum _phy_loop
{
kPHY_LocalLoop = 0U, /*!< ENET PHY local/digital loopback. */
kPHY_RemoteLoop, /*!< ENET PHY remote loopback. */
kPHY_ExternalLoop, /*!< ENET PHY external loopback. */
} phy_loop_t;
/*! @brief Defines the PHY MMD data access mode. */
typedef enum _phy_mmd_access_mode
{
kPHY_MMDAccessNoPostIncrement = (1U << 14), /*!< ENET PHY MMD access data with no address post increment. */
kPHY_MMDAccessRdWrPostIncrement =
(2U << 14), /*!< ENET PHY MMD access data with Read/Write address post increment. */
kPHY_MMDAccessWrPostIncrement = (3U << 14), /*!< ENET PHY MMD access data with Write address post increment. */
} phy_mmd_access_mode_t;
/*! @brief Defines PHY configuration. */
typedef struct _phy_config
{
uint32_t phyAddr; /*!< PHY address. */
phy_speed_t speed; /*!< PHY speed configuration. */
phy_duplex_t duplex; /*!< PHY duplex configuration. */
bool autoNeg; /*!< PHY auto-negotiation, true: enable, false: disable. */
bool enableEEE; /*!< PHY Energy Efficient Ethernet. */
} phy_config_t;
/*! @brief PHY device operations. */
typedef struct _phy_operations
{
status_t (*phyInit)(phy_handle_t *handle, const phy_config_t *config);
status_t (*phyWrite)(phy_handle_t *handle, uint32_t phyReg, uint32_t data);
status_t (*phyRead)(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr);
status_t (*getAutoNegoStatus)(phy_handle_t *handle, bool *status);
status_t (*getLinkStatus)(phy_handle_t *handle, bool *status);
status_t (*getLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex);
status_t (*setLinkSpeedDuplex)(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex);
status_t (*enableLoopback)(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable);
} phy_operations_t;
/*! @brief PHY device handle. */
struct _phy_handle
{
uint32_t phyAddr; /*!< PHY address. */
mdio_handle_t *mdioHandle; /*!< The MDIO handle used by the phy device, it is specified by device. */
const phy_operations_t *ops; /*!< The device related operations. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize PHY.
*
* @param handle PHY device handle.
* @param config Pointer to structure of phy_config_t.
* @retval kStatus_Success PHY initialization succeeds
* @retval kStatus_Fail PHY initialization fails
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_Init(phy_handle_t *handle, const phy_config_t *config)
{
return handle->ops->phyInit(handle, config);
}
/*!
* @brief PHY Write function. This function write data over the SMI to
* the specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param data The data written to the PHY register.
* @retval kStatus_Success PHY write success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_Write(phy_handle_t *handle, uint32_t phyReg, uint32_t data)
{
return handle->ops->phyWrite(handle, phyReg, data);
}
/*!
* @brief PHY Read function. This interface read data over the SMI from the
* specified PHY register. This function is called by all PHY interfaces.
*
* @param handle PHY device handle.
* @param phyReg The PHY register.
* @param dataPtr The address to store the data read from the PHY register.
* @retval kStatus_Success PHY read success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_Read(phy_handle_t *handle, uint32_t phyReg, uint32_t *dataPtr)
{
return handle->ops->phyRead(handle, phyReg, dataPtr);
}
/*!
* @brief Gets the PHY auto-negotiation status.
*
* @param handle PHY device handle.
* @param status The auto-negotiation status of the PHY.
* - true the auto-negotiation is over.
* - false the auto-negotiation is on-going or not started.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_GetAutoNegotiationStatus(phy_handle_t *handle, bool *status)
{
return handle->ops->getAutoNegoStatus(handle, status);
}
/*!
* @brief Gets the PHY link status.
*
* @param handle PHY device handle.
* @param status The link up or down status of the PHY.
* - true the link is up.
* - false the link is down.
* @retval kStatus_Success PHY get link status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_GetLinkStatus(phy_handle_t *handle, bool *status)
{
return handle->ops->getLinkStatus(handle, status);
}
/*!
* @brief Gets the PHY link speed and duplex.
*
* @brief This function gets the speed and duplex mode of PHY. User can give one of speed
* and duplex address paramter and set the other as NULL if only wants to get one of them.
*
* @param handle PHY device handle.
* @param speed The address of PHY link speed.
* @param duplex The link duplex of PHY.
* @retval kStatus_Success PHY get link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_GetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t *speed, phy_duplex_t *duplex)
{
return handle->ops->getLinkSpeedDuplex(handle, speed, duplex);
}
/*!
* @brief Sets the PHY link speed and duplex.
*
* @param handle PHY device handle.
* @param speed Specified PHY link speed.
* @param duplex Specified PHY link duplex.
* @retval kStatus_Success PHY gets status success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_SetLinkSpeedDuplex(phy_handle_t *handle, phy_speed_t speed, phy_duplex_t duplex)
{
return handle->ops->setLinkSpeedDuplex(handle, speed, duplex);
}
/*!
* @brief Enable PHY loopcback mode.
*
* @param handle PHY device handle.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* All loopback modes should not be set together, when one loopback mode is set
* another should be disabled.
* @param speed PHY speed for loopback mode.
* @param enable True to enable, false to disable.
* @retval kStatus_Success PHY get link speed and duplex success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
*/
static inline status_t PHY_EnableLoopback(phy_handle_t *handle, phy_loop_t mode, phy_speed_t speed, bool enable)
{
return handle->ops->enableLoopback(handle, mode, speed, enable);
}
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif

View File

@ -4,6 +4,15 @@ export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -D
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
### if use USB function, use special lds file because USB uses ITCM
ifeq ($(CONFIG_LIB_MUSLLIB), y)
export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs
export LIBCC := -lgcc
export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a
endif
ifeq ($(CONFIG_RESOURCES_LWIP), y)
export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a
endif
ifeq ($(CONFIG_BSP_USING_USB),y)
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds

View File

@ -35,7 +35,10 @@ Modification:
#include "clock_config.h"
#include <xizi.h>
#include <arch_interrupt.h>
#ifdef BSP_USING_LWIP
#include "enet_ethernetif.h"
#endif
extern int heap_start;
extern int heap_end;
@ -52,6 +55,8 @@ void InitBoardHardware(void);
/*! @brief The board name */
#define BOARD_NAME "IMXRT1050-EVKB"
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
/* The UART to use for debug messages. */
#define BOARD_DEBUG_UART_TYPE kSerialPort_Uart
#define BOARD_DEBUG_UART_BASEADDR (uint32_t) LPUART1

View File

@ -62,7 +62,7 @@
//#include "FreeRTOS.h"
//#include "event_groups.h"
#endif
#include <board.h>
#include "netif/ethernet.h"
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
@ -94,6 +94,19 @@ void enet_delay(void)
void Time_Update_LwIP(void)
{
}
ethernetif_config_t enet_cfg = {
.phyAddress = BOARD_ENET0_PHY_ADDRESS,
.clockName = kCLOCK_CoreSysClk,
.macAddress = configMAC_ADDR,
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
.non_dma_memory = non_dma_memory,
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
};
void *ethernetif_config_enet_set(uint8_t enet_port)
{
return (void *)&enet_cfg;
}
void ethernetif_clk_init(void)
{

View File

@ -21,6 +21,8 @@
* Definitions
******************************************************************************/
#define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE
/*! @brief Defines the timeout macro. */
#define PHY_TIMEOUT_COUNT 100000

View File

@ -21,6 +21,9 @@
#ifndef __CONNECT_ETHERNET_H_
#define __CONNECT_ETHERNET_H_
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -182,9 +182,12 @@ err_t ethernetif1_init(struct netif *netif);
void ethernetif_input( struct netif *netif);
void ETH_BSP_Config(void);
void *ethernetif_config_enet_set(uint8_t enet_port);
int32 lwip_obtain_semaphore(struct netif *netif);
#define NETIF_ENET0_INIT_FUNC ethernetif0_init
#if defined(__cplusplus)
}
#endif /* __cplusplus */

View File

@ -50,6 +50,9 @@ extern int Stm32HwRtcInit();
extern int HwSdioInit();
extern int Stm32HwAdcInit(void);
extern int Stm32HwDacInit(void);
#ifdef BSP_USING_LWIP
extern int ETH_BSP_Config();
#endif
static void ClockConfiguration()
{
@ -142,6 +145,10 @@ struct InitSequenceDesc _board_init[] =
#ifdef BSP_USING_DAC
{"hw dac init", Stm32HwDacInit},
#endif
#ifdef BSP_USING_LWIP
{"ETH_BSP", ETH_BSP_Config},
#endif
{ " NONE ",NONE },
};
void InitBoardHardware()

View File

@ -40,6 +40,8 @@ extern int __stack_end__;
extern unsigned int g_service_table_start;
extern unsigned int g_service_table_end;
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
#define STM32_USE_SDIO 0
#define STM32_EXT_SRAM 0

View File

@ -62,7 +62,10 @@ extern int32 s_xSemaphore;
/* Private functions ---------------------------------------------------------*/
void *ethernetif_config_enet_set(uint8_t enet_port)
{
return NONE;
}
/**
* @brief ETH_BSP_Config
* @param None

View File

@ -48,9 +48,9 @@
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "netif/etharp.h"
#include "err.h"
#include "ethernetif.h"
#include "main.h"
#include <string.h>
@ -101,7 +101,7 @@ extern ETH_DMA_Rx_Frame_infos *DMA_RX_FRAME_infos;
void ethernetif_input( void * pvParameters );
void LoopGetMacPkg(void * pvParameters);
static void arp_timer(void *arg);
@ -140,7 +140,7 @@ void LwIP_Pkt_Handle(struct netif *netif)
void Time_Update_LwIP(void)
{
LocalTime += MS_PER_SYSTICK_F407;
LocalTime += MS_PER_SYSTICK;
}
@ -413,7 +413,7 @@ void LoopGetMacPkg(void * pvParameters)
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
err_t ethernetif0_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));

View File

@ -43,6 +43,9 @@
#ifndef __STM32F4x7_ETH_BSP_H
#define __STM32F4x7_ETH_BSP_H
#include "hardware_eth.h"
#include "hardware_conf.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -98,6 +101,7 @@
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void ETH_BSP_Config(void);
void *ethernetif_config_enet_set(uint8_t enet_port);
uint32_t Eth_Link_PHYITConfig(uint16_t PHYAddress);
void Eth_Link_EXTIConfig(void);
void Eth_Link_ITHandler(unsigned short PHYAddress);

View File

@ -30,6 +30,8 @@
/* Includes ------------------------------------------------------------------*/
#include "hardware_eth_conf.h"
#include "err.h"
#include "netif/ethernet.h"
/** @addtogroup STM32F4x7_ETH_Driver
* @{
@ -1866,6 +1868,9 @@ void ETH_MMCITConfig(uint32_t ETH_MMC_IT, FunctionalState NewState);
ITStatus ETH_GetMMCITStatus(uint32_t ETH_MMC_IT);
uint32_t ETH_GetMMCRegister(uint32_t ETH_MMCReg);
void ethernetif_input( void * pvParameters );
err_t ethernetif0_init(struct netif *netif);
#define NETIF_ENET0_INIT_FUNC ethernetif0_init
#ifdef __cplusplus
}
#endif

View File

@ -51,6 +51,9 @@ void InitBoardHardware(void);
/*! @brief The board name */
#define BOARD_NAME "IMXRT1050"
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
4 bits for subpriority */
#define NVIC_PRIORITYGROUP_1 0x00000006U /*!< 1 bits for pre-emption priority

View File

@ -66,7 +66,7 @@
#include "netif/ethernet.h"
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#include <board.h>
#include "fsl_enet.h"
#include "fsl_phy.h"
#include "fsl_gpio.h"
@ -95,6 +95,20 @@ void Time_Update_LwIP(void)
{
}
ethernetif_config_t enet_cfg = {
.phyAddress = BOARD_ENET0_PHY_ADDRESS,
.clockName = kCLOCK_CoreSysClk,
.macAddress = configMAC_ADDR,
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
.non_dma_memory = non_dma_memory,
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
};
void *ethernetif_config_enet_set(uint8_t enet_port)
{
return (void *)&enet_cfg;
}
void ethernetif_clk_init(void)
{
const clock_enet_pll_config_t config = {.enableClkOutput = true, .enableClkOutput25M = false, .loopDivider = 1};

View File

@ -21,6 +21,9 @@
#ifndef __CONNECT_ETHERNET_H_
#define __CONNECT_ETHERNET_H_
#include "enet_ethernetif.h"
#include "enet_ethernetif_priv.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -182,9 +182,11 @@ err_t ethernetif1_init(struct netif *netif);
void ethernetif_input( struct netif *netif);
int ETH_BSP_Config(void);
void *ethernetif_config_enet_set(uint8_t enet_port);
int32 lwip_obtain_semaphore(struct netif *netif);
#define NETIF_ENET0_INIT_FUNC ethernetif0_init
#if defined(__cplusplus)
}
#endif /* __cplusplus */

View File

@ -289,6 +289,12 @@ KERNELPATHS += \
-I$(BSP_ROOT)/third_party_driver \
-I$(BSP_ROOT)/third_party_driver/include \
-I$(BSP_ROOT)/third_party_driver/CMSIS/Include \
-I$(BSP_ROOT)/third_party_driver/ethernet \
-I$(BSP_ROOT)/third_party_driver/ethernet/mdio/enet \
-I$(BSP_ROOT)/third_party_driver/ethernet/mdio/enet_qos \
-I$(BSP_ROOT)/third_party_driver/ethernet/phy/ksz8081 \
-I$(BSP_ROOT)/third_party_driver/ethernet/phy/ksz9131rnx \
-I$(BSP_ROOT)/third_party_driver/cm7 \
-I$(BSP_ROOT)/xip \
-I$(KERNEL_ROOT)/include \
-I$(KERNEL_ROOT)/resources/include \

View File

@ -265,7 +265,6 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
typedef unsigned int nfds_t;
#endif
#define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE
#define MEMP_LIB_MALLOC 1
#define MEMP_MEM_MALLOC 1

View File

@ -67,12 +67,21 @@
#include "board.h"
#include "ethernet.h"
#include "enet_ethernetif.h"
#include "connect_ethernet.h"
#include <transform.h>
char lwip_ipaddr[] = {192, 168, 250, 253};
char lwip_netmask[] = {255, 255, 255, 0};
char lwip_gwaddr[] = {192, 168, 250, 252};
char lwip_ipaddr[20] = {192, 168, 131, 77};
char lwip_netmask[20] = {255, 255, 254, 0};
char lwip_gwaddr[20] = {192, 168, 131, 23};
char lwip_eth0_ipaddr[20] = {192, 168, 131, 77};
char lwip_eth0_netmask[20] = {255, 255, 254, 0};
char lwip_eth0_gwaddr[20] = {192, 168, 131, 23};
char lwip_eth1_ipaddr[20] = {192, 168, 131, 99};
char lwip_eth1_netmask[20] = {255, 255, 254, 0};
char lwip_eth1_gwaddr[20] = {192, 168, 131, 23};
char lwip_flag = 0;
x_ticks_t lwip_sys_now;
@ -389,7 +398,9 @@ void lwip_tcp_init(void)
/* USER CODE END 0 */
/* Initilialize the LwIP stack without RTOS */
/* add the network interface (IPv4/IPv6) without RTOS */
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif0_init, &tcpip_input);
#ifdef NETIF_ENET0_INIT_FUNC
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, NETIF_ENET0_INIT_FUNC, &tcpip_input);
#endif
/* Registers the default network interface */
netif_set_default(&gnetif);
@ -463,22 +474,12 @@ void lwip_config_input(struct netif *net)
}
}
void lwip_config_net(char *ip, char *mask, char *gw)
void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw)
{
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
mem_range_t non_dma_memory[] = NON_DMA_MEMORY_ARRAY;
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
ip4_addr_t net_ipaddr, net_netmask, net_gw;
ethernetif_config_t cfg = {
.phyAddress = BOARD_ENET0_PHY_ADDRESS,
.clockName = kCLOCK_CoreSysClk,
.macAddress = configMAC_ADDR,
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
.non_dma_memory = non_dma_memory,
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
};
char* eth_cfg;
ETH_BSP_Config();
eth_cfg = ethernetif_config_enet_set(enet_port);
if(chk_lwip_bit(LWIP_INIT_FLAG))
{
@ -506,8 +507,18 @@ void lwip_config_net(char *ip, char *mask, char *gw)
lwip_init();
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, &cfg, ethernetif0_init,
if(0 == enet_port) {
#ifdef NETIF_ENET0_INIT_FUNC
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC,
ethernet_input);
#endif
} else if (1 == enet_port) {
#ifdef NETIF_ENET1_INIT_FUNC
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC,
ethernet_input);
#endif
}
netif_set_default(&gnetif);
netif_set_up(&gnetif);
@ -527,22 +538,12 @@ void lwip_config_net(char *ip, char *mask, char *gw)
lwip_config_input(&gnetif);
}
void lwip_config_tcp(char *ip, char *mask, char *gw)
void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw)
{
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
mem_range_t non_dma_memory[] = NON_DMA_MEMORY_ARRAY;
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
ip4_addr_t net_ipaddr, net_netmask, net_gw;
ethernetif_config_t cfg = {
.phyAddress = BOARD_ENET0_PHY_ADDRESS,
.clockName = kCLOCK_CoreSysClk,
.macAddress = configMAC_ADDR,
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
.non_dma_memory = non_dma_memory,
#endif /* FSL_FEATURE_SOC_LPC_ENET_COUNT */
};
char* eth_cfg;
ETH_BSP_Config();
eth_cfg = ethernetif_config_enet_set(enet_port);
if(chk_lwip_bit(LWIP_INIT_FLAG))
{
@ -560,8 +561,17 @@ void lwip_config_tcp(char *ip, char *mask, char *gw)
IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]);
IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]);
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, &cfg, ethernetif0_init,
tcpip_input);
if(0 == enet_port) {
#ifdef NETIF_ENET0_INIT_FUNC
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC,
ethernet_input);
#endif
} else if (1 == enet_port) {
#ifdef NETIF_ENET1_INIT_FUNC
netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC,
ethernet_input);
#endif
}
netif_set_default(&gnetif);
netif_set_up(&gnetif);

View File

@ -53,12 +53,13 @@
#define LWIP_LOCAL_PORT 4840
#define LWIP_TARGET_PORT LWIP_LOCAL_PORT
#define LWIP_DEMO_TIMES 3
#define LWIP_DEMO_TIMES 10
#define LWIP_TASK_STACK_SIZE 4096
#define LWIP_DEMO_TASK_PRIO 20
/* MAC address configuration. */
#define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
// /* MAC address configuration. */
// #define configMAC_ADDR {0x02, 0x12, 0x13, 0x10, 0x15, 0x11}
// #define configMAC_ADDR_ETH1 {0x02, 0x12, 0x13, 0x10, 0x15, 0x12}
/* USER CODE END 0 */
#define SYS_MBOX_NULL -1
@ -88,10 +89,19 @@ extern char lwip_flag;
extern char lwip_ipaddr[];
extern char lwip_netmask[];
extern char lwip_gwaddr[];
extern char lwip_eth0_ipaddr[];
extern char lwip_eth0_netmask[];
extern char lwip_eth0_gwaddr[];
extern char lwip_eth1_ipaddr[];
extern char lwip_eth1_netmask[];
extern char lwip_eth1_gwaddr[];
extern struct netif gnetif;
void lwip_tcp_init(void);
void lwip_config_net(char *ip, char *mask, char *gw);
void lwip_config_tcp(char *ip, char *mask, char *gw);
void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw);
void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw);
#endif

View File

@ -24,49 +24,82 @@
#include <sys.h>
/******************************************************************************/
uint8_t enet_id = 0;
static void LwipSetIPTask(void *param)
{
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
uint8_t enet_port = *(uint8_t *)param; ///< test enet port
printf("lw: [%s] config netport id[%d]\n", __func__, enet_port);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
}
void LwipSetIPTest(int argc, char *argv[])
{
if(argc >= 4)
{
lw_print("lw: [%s] ip %s mask %s gw %s\n", __func__, argv[1], argv[2], argv[3]);
printf("lw: [%s] ip %s mask %s gw %s netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]);
sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]);
sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]);
sscanf(argv[4], "%d", &enet_id);
if(0 == enet_id)
{
printf("save eth0 info\n");
memcpy(lwip_eth0_ipaddr, lwip_ipaddr, 20);
memcpy(lwip_eth0_netmask, lwip_netmask, 20);
memcpy(lwip_eth0_gwaddr, lwip_gwaddr, 20);
}
else if(1 == enet_id)
{
printf("save eth1 info\n");
memcpy(lwip_eth1_ipaddr, lwip_ipaddr, 20);
memcpy(lwip_eth1_netmask, lwip_netmask, 20);
memcpy(lwip_eth1_gwaddr, lwip_gwaddr, 20);
}
}
else if(argc == 2)
{
lw_print("lw: [%s] ipaddr %s\n", __func__, argv[1]);
printf("lw: [%s] set eth0 ipaddr %s \n", __func__, argv[1]);
sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
}
sys_thread_new("SET ip address", LwipSetIPTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
setip, LwipSetIPTest, SetIp [IP] [Netmask] [Gateway]);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5),
setip, LwipSetIPTest, setip [IP] [Netmask] [Gateway] [port]);
void LwipShowIPTask(int argc, char *argv[])
{
char mac_addr[] = configMAC_ADDR;
char mac_addr0[] = configMAC_ADDR;
lw_notice("\r\n************************************************\r\n");
lw_notice(" Network Configuration\r\n");
lw_notice("************************************************\r\n");
lw_notice(" IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_ipaddr)[0], ((u8_t *)&lwip_ipaddr)[1],
((u8_t *)&lwip_ipaddr)[2], ((u8_t *)&lwip_ipaddr)[3]);
lw_notice(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_netmask)[0], ((u8_t *)&lwip_netmask)[1],
((u8_t *)&lwip_netmask)[2], ((u8_t *)&lwip_netmask)[3]);
lw_notice(" IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_gwaddr)[1],
((u8_t *)&lwip_gwaddr)[2], ((u8_t *)&lwip_gwaddr)[3]);
lw_notice(" MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr[0], mac_addr[1], mac_addr[2],
mac_addr[3], mac_addr[4], mac_addr[5]);
lw_notice(" ETH0 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth0_ipaddr)[0], ((u8_t *)&lwip_eth0_ipaddr)[1],
((u8_t *)&lwip_eth0_ipaddr)[2], ((u8_t *)&lwip_eth0_ipaddr)[3]);
lw_notice(" ETH0 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth0_netmask)[0], ((u8_t *)&lwip_eth0_netmask)[1],
((u8_t *)&lwip_eth0_netmask)[2], ((u8_t *)&lwip_eth0_netmask)[3]);
lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_eth0_gwaddr)[1],
((u8_t *)&lwip_eth0_gwaddr)[2], ((u8_t *)&lwip_eth0_gwaddr)[3]);
lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2],
mac_addr0[3], mac_addr0[4], mac_addr0[5]);
#ifdef BOARD_NET_COUNT
if(BOARD_NET_COUNT > 1)
{
char mac_addr1[] = configMAC_ADDR_ETH1;
lw_notice("\r\n");
lw_notice(" ETH1 IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_ipaddr)[0], ((u8_t *)&lwip_eth1_ipaddr)[1],
((u8_t *)&lwip_eth1_ipaddr)[2], ((u8_t *)&lwip_eth1_ipaddr)[3]);
lw_notice(" ETH1 IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_netmask)[0], ((u8_t *)&lwip_eth1_netmask)[1],
((u8_t *)&lwip_eth1_netmask)[2], ((u8_t *)&lwip_eth1_netmask)[3]);
lw_notice(" ETH1 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_eth1_gwaddr)[0], ((u8_t *)&lwip_eth1_gwaddr)[1],
((u8_t *)&lwip_eth1_gwaddr)[2], ((u8_t *)&lwip_eth1_gwaddr)[3]);
lw_notice(" ETH1 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr1[0], mac_addr1[1], mac_addr1[2],
mac_addr1[3], mac_addr1[4], mac_addr1[5]);
}
#endif
lw_notice("************************************************\r\n");
}

View File

@ -29,16 +29,12 @@
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "netif/ethernet.h"
#include "enet_ethernetif.h"
#include <shell.h>
#include <assert.h>
#include <sys_arch.h>
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
#include "sys_arch.h"
#include "connect_ethernet.h"
#define LWIP_DHCP_TIME 10000 // 10s
@ -123,9 +119,10 @@ void LwipDHCPTest(void)
{
u32_t dhcp_time;
static int flag = 0;
uint8_t enet_port = 0; ///< test enet port 0
char ip_addr[4] = {0, 0, 0, 0};
lwip_config_net(ip_addr, ip_addr, ip_addr);
lwip_config_net(enet_port, ip_addr, ip_addr, ip_addr);
set_lwip_bit(LWIP_PRINT_FLAG);
dhcp_start(&gnetif);

View File

@ -29,15 +29,10 @@
#include "netif/ethernet.h"
#include <shell.h>
#include "board.h"
#include "pin_mux.h"
#include "clock_config.h"
#include <sys_arch.h>
#include "connect_ethernet.h"
char test_ip_addr[] = {192, 168, 145, 220};
char test_net_mask[] = {255, 255, 255, 0};
char test_gw_addr[] = {192, 168, 145, 1};
ip4_addr_t ping_addr;
/******************************************************************************/
@ -45,17 +40,52 @@ ip4_addr_t ping_addr;
void LwipPingTest(int argc, char *argv[])
{
int result = 0;
uint8_t enet_port = 0; ///< test enet port 0
if(argc >= 4)
{
lw_print("lw: [%s] ip %s mask %s gw %s\n", __func__, argv[1], argv[2], argv[3]);
printf("lw: [%s] ip %s mask %s gw %s for netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]);
sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]);
sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]);
sscanf(argv[4], "%d", &enet_port);
if(0 == enet_port)
{
memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
memcpy(lwip_eth0_netmask, lwip_netmask, strlen(lwip_netmask));
memcpy(lwip_eth0_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr));
}
if(1 == enet_port)
{
memcpy(lwip_eth1_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
memcpy(lwip_eth1_netmask, lwip_netmask, strlen(lwip_netmask));
memcpy(lwip_eth1_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr));
}
}
else if(argc == 3)
{
sscanf(argv[2], "%d", &enet_port);
printf("lw: [%s] gw %s netport %d\n", __func__, argv[1], enet_port);
if(isdigit(argv[1][0]))
{
if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF)
{
lw_notice("input wrong ip\n");
return;
}
}
#if (LWIP_DHCP) && (PING_USE_SOCKETS)
else
{
get_url_ip(argv[1]);
return;
}
#endif
}
else if(argc == 2)
{
lw_print("lw: [%s] gw %s\n", __func__, argv[1]);
printf("lw: [%s] gw %s\n", __func__, argv[1]);
if(isdigit(argv[1][0]))
{
if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF)
@ -73,14 +103,14 @@ void LwipPingTest(int argc, char *argv[])
#endif
}
lw_print("lw: [%s] argc %d\n", __func__, argc);
printf("lw: [%s] argc %d\n", __func__, argc);
IP4_ADDR(&ping_addr, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]);
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
ping_init(&ping_addr);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
ping, LwipPingTest, ping [IP] 3 times);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5),
ping, LwipPingTest, ping [IP] 10 times);
#endif

View File

@ -70,6 +70,7 @@ static void LwipTcpSendTask(void *arg)
void LwipTcpSendTest(int argc, char *argv[])
{
LwipTcpSocketParamType param;
uint8_t enet_port = 0;
memset(tcp_demo_msg, 0, LWIP_TEST_MSG_SIZE);
if(argc >= 2)
{
@ -89,7 +90,7 @@ void LwipTcpSendTest(int argc, char *argv[])
}
}
lw_notice("get ipaddr %d.%d.%d.%d:%d\n", tcp_demo_ip[0], tcp_demo_ip[1], tcp_demo_ip[2], tcp_demo_ip[3], tcp_demo_port);
lwip_config_tcp(lwip_ipaddr, lwip_netmask, tcp_demo_ip);
lwip_config_tcp(enet_port, lwip_ipaddr, lwip_netmask, tcp_demo_ip);
memcpy(param.ip, tcp_demo_ip, 4);
param.port = tcp_demo_port;
@ -104,7 +105,9 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) |
void LwipTcpRecvTest(void)
{
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
uint8_t enet_port = 0; ///< test enet port 0
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
tcpecho_raw_init();
}

View File

@ -75,6 +75,7 @@ static void LwipUDPSendTask(void *arg)
void *LwipUdpSendTest(int argc, char *argv[])
{
uint8_t enet_port = 0; ///< test enet port 0
memset(udp_demo_msg, 0, sizeof(udp_demo_msg));
if(argc == 1)
@ -94,7 +95,7 @@ void *LwipUdpSendTest(int argc, char *argv[])
lw_print("lw: [%s] gw %d.%d.%d.%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3]);
lwip_config_net(lwip_ipaddr, lwip_netmask, udp_demo_ip);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, udp_demo_ip);
sys_thread_new("udp send", LwipUDPSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
}
@ -140,8 +141,9 @@ static void LwipUdpRecvTask(void *arg, struct udp_pcb *upcb, struct pbuf *p,
void LwipUdpRecvTest(void)
{
err_t err;
uint8_t enet_port = 0; ///< test enet port 0
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
udpecho_raw_pcb = udp_new_ip_type(IPADDR_TYPE_ANY);
if (udpecho_raw_pcb == NULL)