add ethernet for imxrt1176-sbc board and keep compatible with other boards
This commit is contained in:
parent
85ed3a2c10
commit
088bf02fbd
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES :=fsl_cache.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 */
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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, ðernetif->handle, &config, &buffCfg[0], netif->hwaddr, sysClock);
|
||||
|
||||
#if USE_RTOS && defined(FSL_RTOS_FREE_RTOS)
|
||||
ENET_SetCallback(ðernetif->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, ðernetif->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, ðernetif->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, ðernetif->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 = ðernetif->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(ðernetif->handle, &eErrStatic);
|
||||
#endif
|
||||
status = ENET_GetRxBuffer(ethernetif->base, ðernetif->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, ðernetif->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(ðernetif->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, ðernetif_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, ðernetif_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
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES :=
|
||||
SRC_DIR := enet enet_qos
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_enet_mdio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_enet_qos_mdio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES :=
|
||||
SRC_DIR := ksz8081 ksz9131rnx
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
SRC_FILES := fsl_phyksz8081.c
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
if (result == kStatus_Success)
|
||||
{
|
||||
return MDIO_Write(handle->mdioHandle, handle->phyAddr, PHY_CONTROL2_REG,
|
||||
(regValue & ~PHY_CTL2_REMOTELOOP_MASK));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -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_ */
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := fsl_phyksz9131rnx.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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, ®Value);
|
||||
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;
|
||||
}
|
|
@ -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_ */
|
|
@ -1,3 +1,3 @@
|
|||
SRC_FILES := connect_gpio.c fsl_gpio.c
|
||||
SRC_FILES := fsl_gpio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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
|
||||
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE
|
||||
|
||||
/*! @brief Defines the timeout macro. */
|
||||
#define PHY_TIMEOUT_COUNT 100000
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ðernetif0_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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue