Working LwIP.

This commit is contained in:
imi415 2022-05-21 19:35:12 +08:00
parent 2ad49636ec
commit 48dd430ad2
Signed by: imi415
GPG Key ID: 885EC2B5A8A6F8A7
20 changed files with 3154 additions and 58 deletions

2
.gitmodules vendored
View File

@ -5,5 +5,5 @@
path = lib/FreeRTOS
url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git
[submodule "lib/LwIP"]
path = lib/LwIP
path = lib/LwIP/lwip
url = https://git.savannah.nongnu.org/git/lwip.git

View File

@ -59,7 +59,11 @@ set(TARGET_SOURCES
"board/clock_config.c"
"board/peripherals.c"
"board/pin_mux.c"
"lib/LwIP/port/lwip_helpers.c"
"lib/LwIP/port/sys_arch.c"
"src/ethernetif.c"
"src/freertos_helpers.c"
"src/fsl_phy.c"
"src/main.c"
"src/system_utilities.c"
)
@ -81,6 +85,7 @@ set(TARGET_C_INCLUDES
# Shared libraries linked with application
set(TARGET_LIBS
"freertos_kernel"
"lwip"
)
# Shared library and linker script search paths
@ -114,6 +119,9 @@ set(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/include" CACHE STRING ""
set(FREERTOS_PORT "GCC_ARM_CM3" CACHE STRING "")
add_subdirectory(lib/FreeRTOS)
set(LWIP_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/LwIP/port/include" CACHE STRING "")
add_subdirectory(lib/LwIP)
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})
include_directories(${TARGET_C_INCLUDES})

View File

@ -117,14 +117,14 @@
<pin peripheral="FB" signal="A, 27" pin_num="77" pin_signal="PTA26/MII0_TXD3/FB_A27"/>
<pin peripheral="FB" signal="CS5_TSIZ1_BE23_16_BLS15_8" pin_num="123" pin_signal="PTC16/CAN1_RX/UART3_RX/ENET0_1588_TMR0/FB_CS5_b/FB_TSIZ1/FB_BE23_16_b"/>
<pin peripheral="FB" signal="CS4_TSIZ0_BE31_24_BLS7_0" pin_num="124" pin_signal="PTC17/CAN1_TX/UART3_TX/ENET0_1588_TMR1/FB_CS4_b/FB_TSIZ0/FB_BE31_24_b"/>
<pin peripheral="ENET" signal="RMII_CRS_DV" pin_num="66" pin_signal="PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2S0_RX_BCLK/I2S0_TXD1"/>
<pin peripheral="ENET" signal="RMII_MDC" pin_num="82" pin_signal="ADC0_SE9/ADC1_SE9/TSI0_CH6/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB"/>
<pin peripheral="ENET" signal="RMII_MDIO" pin_num="81" pin_signal="ADC0_SE8/ADC1_SE8/TSI0_CH0/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA"/>
<pin peripheral="ENET" signal="RMII_TXD0" pin_num="68" pin_signal="PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1"/>
<pin peripheral="ENET" signal="RMII_TXD1" pin_num="69" pin_signal="ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK"/>
<pin peripheral="ENET" signal="RMII_RXER" pin_num="55" pin_signal="PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b"/>
<pin peripheral="ENET" signal="RMII_RXD0" pin_num="65" pin_signal="CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2S0_TX_FS/FTM1_QD_PHB"/>
<pin peripheral="ENET" signal="RMII_RXD1" pin_num="64" pin_signal="CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2S0_TXD0/FTM1_QD_PHA"/>
<pin peripheral="ENET" signal="RMII_CRS_DV" pin_num="66" pin_signal="PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2S0_RX_BCLK/I2S0_TXD1"/>
<pin peripheral="ENET" signal="RMII_RXER" pin_num="55" pin_signal="PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b"/>
<pin peripheral="ENET" signal="RMII_TXD0" pin_num="68" pin_signal="PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1"/>
<pin peripheral="ENET" signal="RMII_TXD1" pin_num="69" pin_signal="ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK"/>
<pin peripheral="ENET" signal="rmii_txen" pin_num="67" pin_signal="PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0"/>
<pin peripheral="ENET" signal="RMII_CLKIN" pin_num="72" pin_signal="EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0"/>
</pins>
@ -191,25 +191,32 @@
</clock_sources>
<clock_outputs>
<clock_output id="Bus_clock.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="Core_clock.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="Core_clock.outFreq" value="100 MHz" locked="false" accuracy=""/>
<clock_output id="Flash_clock.outFreq" value="25 MHz" locked="false" accuracy=""/>
<clock_output id="FlexBus_clock.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="LPO_clock.outFreq" value="1 kHz" locked="false" accuracy=""/>
<clock_output id="MCGFFCLK.outFreq" value="39.0625 kHz" locked="false" accuracy=""/>
<clock_output id="PLLFLLCLK.outFreq" value="25 MHz" locked="false" accuracy=""/>
<clock_output id="System_clock.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="OSCERCLK.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="RMIICLK.outFreq" value="50 MHz" locked="false" accuracy=""/>
<clock_output id="System_clock.outFreq" value="100 MHz" locked="false" accuracy=""/>
</clock_outputs>
<clock_settings>
<setting id="MCGMode" value="FBE" locked="false"/>
<setting id="MCG.CLKS.sel" value="MCG.OSCSEL" locked="false"/>
<setting id="MCGMode" value="PEE" locked="false"/>
<setting id="MCG.FRDIV.scale" value="1280" locked="false"/>
<setting id="MCG.IREFS.sel" value="MCG.FRDIV" locked="false"/>
<setting id="MCG.PRDIV.scale" value="13" locked="false"/>
<setting id="MCG.PLLS.sel" value="MCG.PLL" locked="false"/>
<setting id="MCG.PRDIV.scale" value="13" locked="true"/>
<setting id="MCG.VDIV.scale" value="26" locked="true"/>
<setting id="MCG_C2_RANGE0_CFG" value="Very_high" locked="false"/>
<setting id="MCG_C2_RANGE0_FRDIV_CFG" value="Very_high" locked="false"/>
<setting id="OSC_CR_ERCLKEN_CFG" value="Enabled" locked="false"/>
<setting id="OSC_CR_SYS_OSC_CAP_LOAD_CFG" value="SC18PF" locked="false"/>
<setting id="RMIISrcConfig" value="yes" locked="false"/>
<setting id="RTC_CR_OSCE_CFG" value="Enabled" locked="false"/>
<setting id="RTC_CR_OSC_CAP_LOAD_CFG" value="SC12PF" locked="false"/>
<setting id="SIM.OUTDIV2.scale" value="2" locked="false"/>
<setting id="SIM.OUTDIV3.scale" value="2" locked="false"/>
<setting id="SIM.OUTDIV4.scale" value="4" locked="false"/>
</clock_settings>
<called_from_default_init>true</called_from_default_init>
</clock_configuration>

2
SDK

@ -1 +1 @@
Subproject commit 855e1be1225ff859dd5a9a5a3959ecc702a028df
Subproject commit d22b5f5974384786fbc1488f395c3af984a4c466

View File

@ -49,9 +49,9 @@ processor_version: 11.0.1
******************************************************************************/
#define MCG_IRCLK_DISABLE 0U /*!< MCGIRCLK disabled */
#define MCG_PLL_DISABLE 0U /*!< MCGPLLCLK disabled */
#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */
#define RTC_OSC_CAP_LOAD_12PF 0x1800U /*!< RTC oscillator capacity load: 12pF */
#define RTC_RTC32KCLK_PERIPHERALS_ENABLED 1U /*!< RTC32KCLK to other peripherals: enabled */
#define SIM_ENET_RMII_CLK_SEL_EXTAL_CLK 0U /*!< SDHC clock select: Core/system clock */
#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */
#define SIM_PLLFLLSEL_MCGFLLCLK_CLK 0U /*!< PLLFLL select: MCGFLLCLK clock */
@ -64,21 +64,6 @@ extern uint32_t SystemCoreClock;
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : CLOCK_CONFIG_FllStableDelay
* Description : This function is used to delay for FLL stable.
*
*END**************************************************************************/
static void CLOCK_CONFIG_FllStableDelay(void)
{
uint32_t i = 30000U;
while (i--)
{
__NOP();
}
}
/*FUNCTION**********************************************************************
*
* Function Name : CLOCK_CONFIG_SetRtcClock
@ -115,6 +100,18 @@ static void CLOCK_CONFIG_SetRtcClock(uint32_t capLoad, uint8_t enableOutPeriph)
CLOCK_DisableClock(kCLOCK_Rtc0);
}
/*FUNCTION**********************************************************************
*
* Function Name : CLOCK_CONFIG_SetFllExtRefDiv
* Description : Configure FLL external reference divider (FRDIV).
* Param frdiv : The value to set FRDIV.
*
*END**************************************************************************/
static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv)
{
MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
}
/*******************************************************************************
************************ BOARD_InitBootClocks function ************************
******************************************************************************/
@ -133,24 +130,31 @@ name: BOARD_BootClockRUN
called_from_default_init: true
outputs:
- {id: Bus_clock.outFreq, value: 50 MHz}
- {id: Core_clock.outFreq, value: 50 MHz}
- {id: Core_clock.outFreq, value: 100 MHz}
- {id: Flash_clock.outFreq, value: 25 MHz}
- {id: FlexBus_clock.outFreq, value: 50 MHz}
- {id: LPO_clock.outFreq, value: 1 kHz}
- {id: MCGFFCLK.outFreq, value: 39.0625 kHz}
- {id: PLLFLLCLK.outFreq, value: 25 MHz}
- {id: System_clock.outFreq, value: 50 MHz}
- {id: OSCERCLK.outFreq, value: 50 MHz}
- {id: RMIICLK.outFreq, value: 50 MHz}
- {id: System_clock.outFreq, value: 100 MHz}
settings:
- {id: MCGMode, value: FBE}
- {id: MCG.CLKS.sel, value: MCG.OSCSEL}
- {id: MCGMode, value: PEE}
- {id: MCG.FRDIV.scale, value: '1280'}
- {id: MCG.IREFS.sel, value: MCG.FRDIV}
- {id: MCG.PRDIV.scale, value: '13'}
- {id: MCG.PLLS.sel, value: MCG.PLL}
- {id: MCG.PRDIV.scale, value: '13', locked: true}
- {id: MCG.VDIV.scale, value: '26', locked: true}
- {id: MCG_C2_RANGE0_CFG, value: Very_high}
- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high}
- {id: OSC_CR_ERCLKEN_CFG, value: Enabled}
- {id: OSC_CR_SYS_OSC_CAP_LOAD_CFG, value: SC18PF}
- {id: RMIISrcConfig, value: 'yes'}
- {id: RTC_CR_OSCE_CFG, value: Enabled}
- {id: RTC_CR_OSC_CAP_LOAD_CFG, value: SC12PF}
- {id: SIM.OUTDIV2.scale, value: '2'}
- {id: SIM.OUTDIV3.scale, value: '2'}
- {id: SIM.OUTDIV4.scale, value: '4'}
sources:
- {id: OSC.OSC.outFreq, value: 50 MHz, enabled: true}
- {id: RTC.RTC32kHz.outFreq, value: 32.768 kHz, enabled: true}
@ -162,7 +166,7 @@ sources:
******************************************************************************/
const mcg_config_t mcgConfig_BOARD_BootClockRUN =
{
.mcgMode = kMCG_ModeFBE, /* FBE - FLL Bypassed External */
.mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */
.irclkEnableMode = MCG_IRCLK_DISABLE, /* MCGIRCLK disabled */
.ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */
.fcrdiv = 0x1U, /* Fast IRC divider: divided by 2 */
@ -174,14 +178,14 @@ const mcg_config_t mcgConfig_BOARD_BootClockRUN =
{
.enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */
.prdiv = 0xcU, /* PLL Reference divider: divided by 13 */
.vdiv = 0x0U, /* VCO divider: multiplied by 24 */
.vdiv = 0x2U, /* VCO divider: multiplied by 26 */
},
};
const sim_clock_config_t simConfig_BOARD_BootClockRUN =
{
.pllFllSel = SIM_PLLFLLSEL_MCGFLLCLK_CLK, /* PLLFLL select: MCGFLLCLK clock */
.er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */
.clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /2 */
.clkdiv1 = 0x1130000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /2, OUTDIV4: /4 */
};
const osc_config_t oscConfig_BOARD_BootClockRUN =
{
@ -190,7 +194,7 @@ const osc_config_t oscConfig_BOARD_BootClockRUN =
.workMode = kOSC_ModeExt, /* Use external clock */
.oscerConfig =
{
.enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */
.enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */
}
};
@ -206,15 +210,17 @@ void BOARD_BootClockRUN(void)
/* Initializes OSC0 according to board configuration. */
CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN);
CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq);
/* Set MCG to FBE mode. */
CLOCK_SetExternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.oscsel);
CLOCK_SetFbeMode(mcgConfig_BOARD_BootClockRUN.frdiv,
mcgConfig_BOARD_BootClockRUN.dmx32,
mcgConfig_BOARD_BootClockRUN.drs,
CLOCK_CONFIG_FllStableDelay);
/* Configure FLL external reference divider (FRDIV). */
CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv);
/* Set MCG to PEE mode. */
CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel,
kMCG_PllClkSelPll0,
&mcgConfig_BOARD_BootClockRUN.pll0Config);
/* Set the clock configuration in SIM module. */
CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN);
/* Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
/* Set RMII clock source. */
CLOCK_SetRmii0Clock(SIM_ENET_RMII_CLK_SEL_EXTAL_CLK);
}

View File

@ -38,7 +38,7 @@ void BOARD_InitBootClocks(void);
/*******************************************************************************
* Definitions for BOARD_BootClockRUN configuration
******************************************************************************/
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 50000000U /*!< Core clock frequency: 50000000Hz */
#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */
/*! @brief MCG set for BOARD_BootClockRUN configuration.
*/

View File

@ -84,14 +84,14 @@ BOARD_InitPins:
- {pin_num: '77', peripheral: FB, signal: 'A, 27', pin_signal: PTA26/MII0_TXD3/FB_A27}
- {pin_num: '123', peripheral: FB, signal: CS5_TSIZ1_BE23_16_BLS15_8, pin_signal: PTC16/CAN1_RX/UART3_RX/ENET0_1588_TMR0/FB_CS5_b/FB_TSIZ1/FB_BE23_16_b}
- {pin_num: '124', peripheral: FB, signal: CS4_TSIZ0_BE31_24_BLS7_0, pin_signal: PTC17/CAN1_TX/UART3_TX/ENET0_1588_TMR1/FB_CS4_b/FB_TSIZ0/FB_BE31_24_b}
- {pin_num: '66', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2S0_RX_BCLK/I2S0_TXD1}
- {pin_num: '82', peripheral: ENET, signal: RMII_MDC, pin_signal: ADC0_SE9/ADC1_SE9/TSI0_CH6/PTB1/I2C0_SDA/FTM1_CH1/RMII0_MDC/MII0_MDC/FTM1_QD_PHB}
- {pin_num: '81', peripheral: ENET, signal: RMII_MDIO, pin_signal: ADC0_SE8/ADC1_SE8/TSI0_CH0/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/RMII0_MDIO/MII0_MDIO/FTM1_QD_PHA}
- {pin_num: '68', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1}
- {pin_num: '69', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK}
- {pin_num: '55', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b}
- {pin_num: '65', peripheral: ENET, signal: RMII_RXD0, pin_signal: CMP2_IN1/PTA13/LLWU_P4/CAN0_RX/FTM1_CH1/RMII0_RXD0/MII0_RXD0/I2S0_TX_FS/FTM1_QD_PHB}
- {pin_num: '64', peripheral: ENET, signal: RMII_RXD1, pin_signal: CMP2_IN0/PTA12/CAN0_TX/FTM1_CH0/RMII0_RXD1/MII0_RXD1/I2S0_TXD0/FTM1_QD_PHA}
- {pin_num: '66', peripheral: ENET, signal: RMII_CRS_DV, pin_signal: PTA14/SPI0_PCS0/UART0_TX/RMII0_CRS_DV/MII0_RXDV/I2S0_RX_BCLK/I2S0_TXD1}
- {pin_num: '55', peripheral: ENET, signal: RMII_RXER, pin_signal: PTA5/USB_CLKIN/FTM0_CH2/RMII0_RXER/MII0_RXER/CMP2_OUT/I2S0_TX_BCLK/JTAG_TRST_b}
- {pin_num: '68', peripheral: ENET, signal: RMII_TXD0, pin_signal: PTA16/SPI0_SOUT/UART0_CTS_b/UART0_COL_b/RMII0_TXD0/MII0_TXD0/I2S0_RX_FS/I2S0_RXD1}
- {pin_num: '69', peripheral: ENET, signal: RMII_TXD1, pin_signal: ADC1_SE17/PTA17/SPI0_SIN/UART0_RTS_b/RMII0_TXD1/MII0_TXD1/I2S0_MCLK}
- {pin_num: '67', peripheral: ENET, signal: rmii_txen, pin_signal: PTA15/SPI0_SCK/UART0_RX/RMII0_TXEN/MII0_TXEN/I2S0_RXD0}
- {pin_num: '72', peripheral: ENET, signal: RMII_CLKIN, pin_signal: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********

View File

@ -19,8 +19,8 @@
#define configIDLE_SHOULD_YIELD 1
#define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
#define configUSE_MUTEXES 0
#define configUSE_RECURSIVE_MUTEXES 0
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 0
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
#define configQUEUE_REGISTRY_SIZE 10
@ -122,7 +122,7 @@ standard names. */
#define INCLUDE_xTaskGetIdleTaskHandle 0
#define INCLUDE_eTaskGetState 0
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 0
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 0
#define INCLUDE_xTaskGetHandle 0
#define INCLUDE_xTaskResumeFromISR 1

146
include/ethernetif.h Normal file
View File

@ -0,0 +1,146 @@
/*
* 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 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#ifndef ETHERNETIF_H
#define ETHERNETIF_H
#include "lwip/err.h"
#include "fsl_enet.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#ifndef ENET_RXBD_NUM
#define ENET_RXBD_NUM (5)
#endif
#ifndef ENET_TXBD_NUM
#if defined(FSL_FEATURE_SOC_LPC_ENET_COUNT) && (FSL_FEATURE_SOC_LPC_ENET_COUNT > 0)
#define ENET_TXBD_NUM (5)
#else
#define ENET_TXBD_NUM (3)
#endif
#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
/* MAC address configuration. */
#ifndef configMAC_ADDR0
#define configMAC_ADDR0 0x00
#endif
#ifndef configMAC_ADDR1
#define configMAC_ADDR1 0x12
#endif
#ifndef configMAC_ADDR2
#define configMAC_ADDR2 0x13
#endif
#ifndef configMAC_ADDR3
#define configMAC_ADDR3 0x10
#endif
#ifndef configMAC_ADDR4
#define configMAC_ADDR4 0x15
#endif
#ifndef configMAC_ADDR5
#define configMAC_ADDR5 0x11
#endif
#define ENET_OK (0U)
#define ENET_ERROR (0xFFU)
#define ENET_TIMEOUT (0xFFFU)
/* ENET IRQ priority. Used in FreeRTOS. */
#ifndef ENET_PRIORITY
#define ENET_PRIORITY (6U)
#endif
#ifndef ENET_1588_PRIORITY
#define ENET_1588_PRIORITY (5U)
#endif
/* The PHY address.*/
#ifndef ENET_PHY_ADDRESS
#define ENET_PHY_ADDRESS (1)
#endif
/* Defines Ethernet Autonegotiation Timeout during initialization.
* Set it to 0 to disable the waiting. */
#ifndef ENET_ATONEGOTIATION_TIMEOUT
#define ENET_ATONEGOTIATION_TIMEOUT (0xFFFU)
#endif
/**
* This function should be passed as a parameter to netif_add()
*/
err_t ethernetif_init(struct netif *netif);
/**
* 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);
#endif

216
include/fsl_phy.h Normal file
View File

@ -0,0 +1,216 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#ifndef _FSL_PHY_H_
#define _FSL_PHY_H_
#include "fsl_enet.h"
/*!
* @addtogroup phy_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief PHY driver version */
#define FSL_PHY_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
/*! @brief Defines the 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_CONTROL1_REG 0x1EU /*!< The PHY control one register. */
#define PHY_CONTROL2_REG 0x1FU /*!< The PHY control two register. */
#define PHY_CONTROL_ID1 0x22U /*!< The PHY ID1*/
/*! @brief Defines the mask flag in basic control register. */
#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_SPEED_MASK 0x2000U /*!< The PHY speed bit mask. */
#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 of operation mode in control two register*/
#define PHY_CTL1_REMOTELOOP_MASK 0x0008U /*!< The PHY remote loopback mask. */
#define PHY_CTL2_10HALFDUPLEX_MASK 0x0004U /*!< The PHY 10M half duplex mask. */
#define PHY_CTL2_100HALFDUPLEX_MASK 0x0008U /*!< The PHY 100M half duplex mask. */
#define PHY_CTL2_10FULLDUPLEX_MASK 0x0014U /*!< The PHY 10M full duplex mask. */
#define PHY_CTL2_100FULLDUPLEX_MASK 0x0018U /*!< The PHY 100M full duplex mask. */
/*! @brief Defines the mask flag in basic status register. */
#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. */
#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.*/
/*! @brief Defines the PHY status. */
enum _phy_status
{
kStatus_PHY_SMIVisitTimeout = MAKE_STATUS(kStatusGroup_PHY, 0), /*!< ENET PHY SMI visit timeout. */
kStatus_PHY_AutoNegotiateFail = MAKE_STATUS(kStatusGroup_PHY, 1) /*!< ENET PHY AutoNegotiate Fail. */
};
/*! @brief Defines the PHY link speed. This is align with the speed for ENET MAC. */
typedef enum _phy_speed
{
kPHY_Speed10M = 0U, /*!< ENET PHY 10M speed. */
kPHY_Speed100M /*!< ENET PHY 100M 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 loopback. */
kPHY_RemoteLoop /*!< ENET PHY remote loopback. */
} phy_loop_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name PHY Driver
* @{
*/
/*!
* @brief Initializes PHY.
*
* This function initialize the SMI interface and initialize PHY.
* The SMI is the MII management interface between PHY and MAC, which should be
* firstly initialized before any other operation for PHY.
*
* @param base ENET peripheral base address.
* @param phyAddr The PHY address.
* @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI.
* @retval kStatus_Success PHY initialize success
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
*/
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
/*!
* @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 base ENET peripheral base address.
* @param phyAddr The PHY address.
* @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_Write(ENET_Type *base, uint32_t phyAddr, 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 base ENET peripheral base address.
* @param phyAddr The PHY address.
* @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_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr);
/*!
* @brief Enables/disables PHY loopback.
*
* @param base ENET peripheral base address.
* @param phyAddr The PHY address.
* @param mode The loopback mode to be enabled, please see "phy_loop_t".
* the two loopback mode should not be both set. when one loopback mode is set
* the other one should be disabled.
* @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_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable);
/*!
* @brief Gets the PHY link status.
*
* @param base ENET peripheral base address.
* @param phyAddr The PHY address.
* @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
*/
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status);
/*!
* @brief Gets the PHY link speed and duplex.
*
* @param base ENET peripheral base address.
* @param phyAddr The PHY address.
* @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
*/
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex);
/* @} */
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* _FSL_PHY_H_ */

141
lib/LwIP/CMakeLists.txt Normal file
View File

@ -0,0 +1,141 @@
cmake_minimum_required(VERSION 3.10)
project(lwip)
if(NOT LWIP_CONFIG_FILE_DIRECTORY)
message(FATAL_ERROR "Please specify LWIP_CONFIG_FILE_DIRECTORY for lwipopts.h")
endif()
set(lwip_SRCS
"lwip/src/api/api_lib.c"
"lwip/src/api/api_msg.c"
"lwip/src/api/err.c"
"lwip/src/api/if_api.c"
"lwip/src/api/netbuf.c"
"lwip/src/api/netdb.c"
"lwip/src/api/netifapi.c"
"lwip/src/api/sockets.c"
"lwip/src/api/tcpip.c"
"lwip/src/apps/altcp_tls/altcp_tls_mbedtls.c"
"lwip/src/apps/altcp_tls/altcp_tls_mbedtls_mem.c"
"lwip/src/apps/http/altcp_proxyconnect.c"
"lwip/src/apps/http/fs.c"
"lwip/src/apps/http/fsdata.c"
"lwip/src/apps/http/http_client.c"
"lwip/src/apps/http/httpd.c"
"lwip/src/apps/lwiperf/lwiperf.c"
"lwip/src/apps/mdns/mdns.c"
"lwip/src/apps/mdns/mdns_domain.c"
"lwip/src/apps/mdns/mdns_out.c"
"lwip/src/apps/mqtt/mqtt.c"
"lwip/src/apps/netbiosns/netbiosns.c"
"lwip/src/apps/smtp/smtp.c"
"lwip/src/apps/snmp/snmp_asn1.c"
"lwip/src/apps/snmp/snmp_core.c"
"lwip/src/apps/snmp/snmp_mib2.c"
"lwip/src/apps/snmp/snmp_mib2_icmp.c"
"lwip/src/apps/snmp/snmp_mib2_interfaces.c"
"lwip/src/apps/snmp/snmp_mib2_ip.c"
"lwip/src/apps/snmp/snmp_mib2_snmp.c"
"lwip/src/apps/snmp/snmp_mib2_system.c"
"lwip/src/apps/snmp/snmp_mib2_tcp.c"
"lwip/src/apps/snmp/snmp_mib2_udp.c"
"lwip/src/apps/snmp/snmp_msg.c"
"lwip/src/apps/snmp/snmp_netconn.c"
"lwip/src/apps/snmp/snmp_pbuf_stream.c"
"lwip/src/apps/snmp/snmp_raw.c"
"lwip/src/apps/snmp/snmp_scalar.c"
"lwip/src/apps/snmp/snmp_snmpv2_framework.c"
"lwip/src/apps/snmp/snmp_snmpv2_usm.c"
"lwip/src/apps/snmp/snmp_table.c"
"lwip/src/apps/snmp/snmp_threadsync.c"
"lwip/src/apps/snmp/snmp_traps.c"
"lwip/src/apps/snmp/snmpv3.c"
"lwip/src/apps/snmp/snmpv3_mbedtls.c"
"lwip/src/apps/sntp/sntp.c"
"lwip/src/apps/tftp/tftp.c"
"lwip/src/core/altcp.c"
"lwip/src/core/altcp_alloc.c"
"lwip/src/core/altcp_tcp.c"
"lwip/src/core/def.c"
"lwip/src/core/dns.c"
"lwip/src/core/inet_chksum.c"
"lwip/src/core/init.c"
"lwip/src/core/ip.c"
"lwip/src/core/ipv4/acd.c"
"lwip/src/core/ipv4/autoip.c"
"lwip/src/core/ipv4/dhcp.c"
"lwip/src/core/ipv4/etharp.c"
"lwip/src/core/ipv4/icmp.c"
"lwip/src/core/ipv4/igmp.c"
"lwip/src/core/ipv4/ip4.c"
"lwip/src/core/ipv4/ip4_addr.c"
"lwip/src/core/ipv4/ip4_frag.c"
"lwip/src/core/ipv6/dhcp6.c"
"lwip/src/core/ipv6/ethip6.c"
"lwip/src/core/ipv6/icmp6.c"
"lwip/src/core/ipv6/inet6.c"
"lwip/src/core/ipv6/ip6.c"
"lwip/src/core/ipv6/ip6_addr.c"
"lwip/src/core/ipv6/ip6_frag.c"
"lwip/src/core/ipv6/mld6.c"
"lwip/src/core/ipv6/nd6.c"
"lwip/src/core/mem.c"
"lwip/src/core/memp.c"
"lwip/src/core/netif.c"
"lwip/src/core/pbuf.c"
"lwip/src/core/raw.c"
"lwip/src/core/stats.c"
"lwip/src/core/sys.c"
"lwip/src/core/tcp.c"
"lwip/src/core/tcp_in.c"
"lwip/src/core/tcp_out.c"
"lwip/src/core/timeouts.c"
"lwip/src/core/udp.c"
"lwip/src/netif/bridgeif.c"
"lwip/src/netif/bridgeif_fdb.c"
"lwip/src/netif/ethernet.c"
"lwip/src/netif/lowpan6.c"
"lwip/src/netif/lowpan6_ble.c"
"lwip/src/netif/lowpan6_common.c"
"lwip/src/netif/ppp/auth.c"
"lwip/src/netif/ppp/ccp.c"
"lwip/src/netif/ppp/chap-md5.c"
"lwip/src/netif/ppp/chap-new.c"
"lwip/src/netif/ppp/chap_ms.c"
"lwip/src/netif/ppp/demand.c"
"lwip/src/netif/ppp/eap.c"
"lwip/src/netif/ppp/ecp.c"
"lwip/src/netif/ppp/eui64.c"
"lwip/src/netif/ppp/fsm.c"
"lwip/src/netif/ppp/ipcp.c"
"lwip/src/netif/ppp/ipv6cp.c"
"lwip/src/netif/ppp/lcp.c"
"lwip/src/netif/ppp/magic.c"
"lwip/src/netif/ppp/mppe.c"
"lwip/src/netif/ppp/multilink.c"
"lwip/src/netif/ppp/polarssl/arc4.c"
"lwip/src/netif/ppp/polarssl/des.c"
"lwip/src/netif/ppp/polarssl/md4.c"
"lwip/src/netif/ppp/polarssl/md5.c"
"lwip/src/netif/ppp/polarssl/sha1.c"
"lwip/src/netif/ppp/ppp.c"
"lwip/src/netif/ppp/pppapi.c"
"lwip/src/netif/ppp/pppcrypt.c"
"lwip/src/netif/ppp/pppoe.c"
"lwip/src/netif/ppp/pppol2tp.c"
"lwip/src/netif/ppp/pppos.c"
"lwip/src/netif/ppp/upap.c"
"lwip/src/netif/ppp/utils.c"
"lwip/src/netif/ppp/vj.c"
"lwip/src/netif/slipif.c"
"lwip/src/netif/zepif.c"
)
set(lwip_INCS
"lwip/src/include"
)
add_library(${PROJECT_NAME} ${lwip_SRCS})
target_include_directories(${PROJECT_NAME} PUBLIC ${lwip_INCS} ${LWIP_CONFIG_FILE_DIRECTORY})

View File

@ -0,0 +1,43 @@
/*
* 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>
*
*/
#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H
#define LWIP_ERRNO_INCLUDE <errno.h>
#define LWIP_ERRNO_STDINCLUDE 1
extern unsigned int lwip_platform_rand(void);
#define LWIP_RAND() (lwip_platform_rand())
#define LWIP_TIMEVAL_PRIVATE 0
#endif /* LWIP_ARCH_CC_H */

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2017 Simon Goldschmidt
* 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: Simon Goldschmdit <goldsimon@gmx.de>
*
*/
#ifndef LWIP_ARCH_SYS_ARCH_H
#define LWIP_ARCH_SYS_ARCH_H
#include "lwip/opt.h"
#include "lwip/arch.h"
/** This is returned by _fromisr() sys functions to tell the outermost function
* that a higher priority task was woken and the scheduler needs to be invoked.
*/
#define ERR_NEED_SCHED 123
/* This port includes FreeRTOS headers in sys_arch.c only.
* FreeRTOS uses pointers as object types. We use wrapper structs instead of
* void pointers directly to get a tiny bit of type safety.
*/
void sys_arch_msleep(u32_t delay_ms);
#define sys_msleep(ms) sys_arch_msleep(ms)
#if SYS_LIGHTWEIGHT_PROT
typedef u32_t sys_prot_t;
#endif /* SYS_LIGHTWEIGHT_PROT */
#if !LWIP_COMPAT_MUTEX
struct _sys_mut {
void *mut;
};
typedef struct _sys_mut sys_mutex_t;
#define sys_mutex_valid_val(mutex) ((mutex).mut != NULL)
#define sys_mutex_valid(mutex) (((mutex) != NULL) && sys_mutex_valid_val(*(mutex)))
#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL)
#endif /* !LWIP_COMPAT_MUTEX */
struct _sys_sem {
void *sem;
};
typedef struct _sys_sem sys_sem_t;
#define sys_sem_valid_val(sema) ((sema).sem != NULL)
#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema)))
#define sys_sem_set_invalid(sema) ((sema)->sem = NULL)
struct _sys_mbox {
void *mbx;
};
typedef struct _sys_mbox sys_mbox_t;
#define sys_mbox_valid_val(mbox) ((mbox).mbx != NULL)
#define sys_mbox_valid(mbox) (((mbox) != NULL) && sys_mbox_valid_val(*(mbox)))
#define sys_mbox_set_invalid(mbox) ((mbox)->mbx = NULL)
struct _sys_thread {
void *thread_handle;
};
typedef struct _sys_thread sys_thread_t;
#if LWIP_NETCONN_SEM_PER_THREAD
sys_sem_t* sys_arch_netconn_sem_get(void);
void sys_arch_netconn_sem_alloc(void);
void sys_arch_netconn_sem_free(void);
#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get()
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free()
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#endif /* LWIP_ARCH_SYS_ARCH_H */

View File

@ -0,0 +1,334 @@
/*
* 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>
*
*/
#ifndef LWIP_LWIPOPTS_H
#define LWIP_LWIPOPTS_H
#ifdef LWIP_OPTTEST_FILE
#include "lwipopts_test.h"
#else /* LWIP_OPTTEST_FILE */
#define LWIP_IPV4 1
#define LWIP_IPV6 1
#define NO_SYS 0
#define LWIP_SOCKET (NO_SYS==0)
#define LWIP_NETCONN (NO_SYS==0)
#define LWIP_NETIF_API (NO_SYS==0)
#define LWIP_IGMP LWIP_IPV4
#define LWIP_ICMP LWIP_IPV4
#define LWIP_SNMP LWIP_UDP
#define MIB2_STATS LWIP_SNMP
#ifdef LWIP_HAVE_MBEDTLS
#define LWIP_SNMP_V3 (LWIP_SNMP)
#endif
#define LWIP_DNS LWIP_UDP
#define LWIP_MDNS_RESPONDER LWIP_UDP
#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER)
#define LWIP_HAVE_LOOPIF 1
#define LWIP_NETIF_LOOPBACK 1
#define LWIP_LOOPBACK_MAX_PBUFS 10
#define TCP_LISTEN_BACKLOG 1
#define LWIP_COMPAT_SOCKETS 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SO_RCVBUF 1
#define LWIP_TCPIP_CORE_LOCKING 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
#define LWIP_DEBUG 1
#ifdef LWIP_DEBUG
#define LWIP_DBG_MIN_LEVEL 0
#define PPP_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_ON
#define NETIF_DEBUG LWIP_DBG_ON
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_ON
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define IGMP_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#endif
#define LWIP_DBG_TYPES_ON (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT)
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
/* MSVC port: intel processors don't need 4-byte alignment,
but are faster that way! */
#define MEM_ALIGNMENT 4U
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 10240
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 16
/* MEMP_NUM_RAW_PCB: the number of UDP protocol control blocks. One
per active RAW "connection". */
#define MEMP_NUM_RAW_PCB 3
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 8
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 5
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 16
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 17
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 2
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 12
/* MEMP_NUM_TCPIP_MSG_*: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG_API 16
#define MEMP_NUM_TCPIP_MSG_INPKT 16
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 72
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 256
/** SYS_LIGHTWEIGHT_PROT
* define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection
* for certain critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT (NO_SYS==0)
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
#define LWIP_ALTCP (LWIP_TCP)
#ifdef LWIP_HAVE_MBEDTLS
#define LWIP_ALTCP_TLS (LWIP_TCP)
#define LWIP_ALTCP_TLS_MBEDTLS (LWIP_TCP)
#endif
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 1024
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 2048
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN (4 * TCP_SND_BUF/TCP_MSS)
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
#define TCP_SNDLOWAT (TCP_SND_BUF/2)
/* TCP receive window. */
#define TCP_WND (10 * 1024)
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4
/* ---------- ARP options ---------- */
#define LWIP_ARP 1
#define ARP_TABLE_SIZE 10
#define ARP_QUEUEING 1
/* ---------- IP options ---------- */
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 1
/* IP reassembly and segmentation.These are orthogonal even
* if they both deal with IP fragments */
#define IP_REASSEMBLY 1
#define IP_REASS_MAX_PBUFS (10 * ((1500 + PBUF_POOL_BUFSIZE - 1) / PBUF_POOL_BUFSIZE))
#define MEMP_NUM_REASSDATA IP_REASS_MAX_PBUFS
#define IP_FRAG 1
#define IPV6_FRAG_COPYHEADER 1
/* ---------- ICMP options ---------- */
#define ICMP_TTL 255
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. */
#define LWIP_DHCP LWIP_UDP
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK (LWIP_DHCP)
/* ---------- AUTOIP options ------- */
#define LWIP_AUTOIP (LWIP_DHCP)
#define LWIP_DHCP_AUTOIP_COOP (LWIP_DHCP && LWIP_AUTOIP)
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define LWIP_UDPLITE LWIP_UDP
#define UDP_TTL 255
/* ---------- RAW options ---------- */
#define LWIP_RAW 1
/* ---------- Statistics options ---------- */
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#if LWIP_STATS
#define LINK_STATS 1
#define IP_STATS 1
#define ICMP_STATS 1
#define IGMP_STATS 1
#define IPFRAG_STATS 1
#define UDP_STATS 1
#define TCP_STATS 1
#define MEM_STATS 1
#define MEMP_STATS 1
#define PBUF_STATS 1
#define SYS_STATS 1
#endif /* LWIP_STATS */
/* ---------- NETBIOS options ---------- */
#define LWIP_NETBIOS_RESPOND_NAME_QUERY 1
/* ---------- PPP options ---------- */
#define PPP_SUPPORT 1 /* Set > 0 for PPP */
#if PPP_SUPPORT
#define NUM_PPP 1 /* Max PPP sessions. */
/* Select modules to enable. Ideally these would be set in the makefile but
* we're limited by the command line length so you need to modify the settings
* in this file.
*/
#define PPPOE_SUPPORT 1
#define PPPOS_SUPPORT 1
#define PAP_SUPPORT 1 /* Set > 0 for PAP. */
#define CHAP_SUPPORT 1 /* Set > 0 for CHAP. */
#define MSCHAP_SUPPORT 0 /* Set > 0 for MSCHAP */
#define CBCP_SUPPORT 0 /* Set > 0 for CBCP (NOT FUNCTIONAL!) */
#define CCP_SUPPORT 0 /* Set > 0 for CCP */
#define VJ_SUPPORT 0 /* Set > 0 for VJ header compression. */
#define MD5_SUPPORT 1 /* Set > 0 for MD5 (see also CHAP) */
#endif /* PPP_SUPPORT */
#endif /* LWIP_OPTTEST_FILE */
/* The following defines must be done even in OPTTEST mode: */
#if !defined(NO_SYS) || !NO_SYS /* default is 0 */
void sys_check_core_locking(void);
#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
#endif
#ifndef LWIP_PLATFORM_ASSERT
/* Define LWIP_PLATFORM_ASSERT to something to catch missing stdio.h includes */
void lwip_platform_assert(const char *msg, int line, const char *file);
#define LWIP_PLATFORM_ASSERT(x) lwip_platform_assert(x, __LINE__, __FILE__)
#endif
/* FreeRTOS related settings */
#define TCPIP_MBOX_SIZE 32
#define TCPIP_THREAD_STACKSIZE 1024
#endif /* LWIP_LWIPOPTS_H */

View File

@ -0,0 +1,15 @@
#include <stdlib.h>
#include "fsl_debug_console.h"
void lwip_platform_assert(const char *msg, int line, const char *file) {
PRINTF("Assertion \"%s\" failed at line %d in %s\r\n", msg, line, file);
for(;;) {
/**/
}
}
int lwip_platform_rand(void) {
/* TODO: Use RNG. */
return rand();
}

607
lib/LwIP/port/sys_arch.c Normal file
View File

@ -0,0 +1,607 @@
/*
* Copyright (c) 2017 Simon Goldschmidt
* 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: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
/** Set this to 1 if you want the stack size passed to sys_thread_new() to be
* interpreted as number of stack words (FreeRTOS-like).
* Default is that they are interpreted as byte count (lwIP-like).
*/
#ifndef LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
#define LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS 0
#endif
/** Set this to 1 to use a mutex for SYS_ARCH_PROTECT() critical regions.
* Default is 0 and locks interrupts/scheduler for SYS_ARCH_PROTECT().
*/
#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX 1
#endif
/** Set this to 1 to include a sanity check that SYS_ARCH_PROTECT() and
* SYS_ARCH_UNPROTECT() are called matching.
*/
#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
#define LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK 0
#endif
/** Set this to 1 to let sys_mbox_free check that queues are empty when freed */
#ifndef LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
#define LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE 0
#endif
/** Set this to 1 to enable core locking check functions in this port.
* For this to work, you'll have to define LWIP_ASSERT_CORE_LOCKED()
* and LWIP_MARK_TCPIP_THREAD() correctly in your lwipopts.h! */
#ifndef LWIP_FREERTOS_CHECK_CORE_LOCKING
#define LWIP_FREERTOS_CHECK_CORE_LOCKING 1
#endif
/** Set this to 0 to implement sys_now() yourself, e.g. using a hw timer.
* Default is 1, where FreeRTOS ticks are used to calculate back to ms.
*/
#ifndef LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
#define LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS 1
#endif
#if !configSUPPORT_DYNAMIC_ALLOCATION
# error "lwIP FreeRTOS port requires configSUPPORT_DYNAMIC_ALLOCATION"
#endif
#if !INCLUDE_vTaskDelay
# error "lwIP FreeRTOS port requires INCLUDE_vTaskDelay"
#endif
#if !INCLUDE_vTaskSuspend
# error "lwIP FreeRTOS port requires INCLUDE_vTaskSuspend"
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX || !LWIP_COMPAT_MUTEX
#if !configUSE_MUTEXES
# error "lwIP FreeRTOS port requires configUSE_MUTEXES"
#endif
#endif
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
static SemaphoreHandle_t sys_arch_protect_mutex;
#endif
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
static sys_prot_t sys_arch_protect_nesting;
#endif
/* Initialize this module (see description in sys.h) */
void
sys_init(void)
{
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
/* initialize sys_arch_protect global mutex */
sys_arch_protect_mutex = xSemaphoreCreateRecursiveMutex();
LWIP_ASSERT("failed to create sys_arch_protect mutex",
sys_arch_protect_mutex != NULL);
#endif /* SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
}
#if configUSE_16_BIT_TICKS == 1
#error This port requires 32 bit ticks or timer overflow will fail
#endif
#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
u32_t
sys_now(void)
{
return xTaskGetTickCount() * portTICK_PERIOD_MS;
}
#endif
u32_t
sys_jiffies(void)
{
return xTaskGetTickCount();
}
#if SYS_LIGHTWEIGHT_PROT
sys_prot_t
sys_arch_protect(void)
{
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
BaseType_t ret;
LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
ret = xSemaphoreTakeRecursive(sys_arch_protect_mutex, portMAX_DELAY);
LWIP_ASSERT("sys_arch_protect failed to take the mutex", ret == pdTRUE);
#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
taskENTER_CRITICAL();
#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
{
/* every nested call to sys_arch_protect() returns an increased number */
sys_prot_t ret = sys_arch_protect_nesting;
sys_arch_protect_nesting++;
LWIP_ASSERT("sys_arch_protect overflow", sys_arch_protect_nesting > ret);
return ret;
}
#else
return 1;
#endif
}
void
sys_arch_unprotect(sys_prot_t pval)
{
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
BaseType_t ret;
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting > 0);
sys_arch_protect_nesting--;
LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting == pval);
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
ret = xSemaphoreGiveRecursive(sys_arch_protect_mutex);
LWIP_ASSERT("sys_arch_unprotect failed to give the mutex", ret == pdTRUE);
#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
taskEXIT_CRITICAL();
#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
LWIP_UNUSED_ARG(pval);
}
#endif /* SYS_LIGHTWEIGHT_PROT */
void
sys_arch_msleep(u32_t delay_ms)
{
TickType_t delay_ticks = pdMS_TO_TICKS(delay_ms);
vTaskDelay(delay_ticks);
}
#if !LWIP_COMPAT_MUTEX
/* Create a new mutex*/
err_t
sys_mutex_new(sys_mutex_t *mutex)
{
LWIP_ASSERT("mutex != NULL", mutex != NULL);
mutex->mut = xSemaphoreCreateRecursiveMutex();
if(mutex->mut == NULL) {
SYS_STATS_INC(mutex.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(mutex);
return ERR_OK;
}
void
sys_mutex_lock(sys_mutex_t *mutex)
{
BaseType_t ret;
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY);
LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
}
void
sys_mutex_unlock(sys_mutex_t *mutex)
{
BaseType_t ret;
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
ret = xSemaphoreGiveRecursive(mutex->mut);
LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
}
void
sys_mutex_free(sys_mutex_t *mutex)
{
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
SYS_STATS_DEC(mutex.used);
vSemaphoreDelete(mutex->mut);
mutex->mut = NULL;
}
#endif /* !LWIP_COMPAT_MUTEX */
err_t
sys_sem_new(sys_sem_t *sem, u8_t initial_count)
{
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("initial_count invalid (not 0 or 1)",
(initial_count == 0) || (initial_count == 1));
sem->sem = xSemaphoreCreateBinary();
if(sem->sem == NULL) {
SYS_STATS_INC(sem.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(sem);
if(initial_count == 1) {
BaseType_t ret = xSemaphoreGive(sem->sem);
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
}
return ERR_OK;
}
void
sys_sem_signal(sys_sem_t *sem)
{
BaseType_t ret;
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
ret = xSemaphoreGive(sem->sem);
/* queue full is OK, this is a signal only... */
LWIP_ASSERT("sys_sem_signal: sane return value",
(ret == pdTRUE) || (ret == errQUEUE_FULL));
}
u32_t
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms)
{
BaseType_t ret;
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
if(!timeout_ms) {
/* wait infinite */
ret = xSemaphoreTake(sem->sem, portMAX_DELAY);
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
} else {
TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);
ret = xSemaphoreTake(sem->sem, timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
return SYS_ARCH_TIMEOUT;
}
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
void
sys_sem_free(sys_sem_t *sem)
{
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
SYS_STATS_DEC(sem.used);
vSemaphoreDelete(sem->sem);
sem->sem = NULL;
}
err_t
sys_mbox_new(sys_mbox_t *mbox, int size)
{
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("size > 0", size > 0);
mbox->mbx = xQueueCreate((UBaseType_t)size, sizeof(void *));
if(mbox->mbx == NULL) {
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(mbox);
return ERR_OK;
}
void
sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY);
LWIP_ASSERT("mbox post failed", ret == pdTRUE);
}
err_t
sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBack(mbox->mbx, &msg, 0);
if (ret == pdTRUE) {
return ERR_OK;
} else {
LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
}
err_t
sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken);
if (ret == pdTRUE) {
if (xHigherPriorityTaskWoken == pdTRUE) {
return ERR_NEED_SCHED;
}
return ERR_OK;
} else {
LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
}
u32_t
sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms)
{
BaseType_t ret;
void *msg_dummy;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
if (!msg) {
msg = &msg_dummy;
}
if (!timeout_ms) {
/* wait infinite */
ret = xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY);
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
} else {
TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);
ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
u32_t
sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
BaseType_t ret;
void *msg_dummy;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
if (!msg) {
msg = &msg_dummy;
}
ret = xQueueReceive(mbox->mbx, &(*msg), 0);
if (ret == errQUEUE_EMPTY) {
*msg = NULL;
return SYS_MBOX_EMPTY;
}
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
return 0;
}
void
sys_mbox_free(sys_mbox_t *mbox)
{
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
{
UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx);
LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
if (msgs_waiting != 0) {
SYS_STATS_INC(mbox.err);
}
}
#endif
vQueueDelete(mbox->mbx);
SYS_STATS_DEC(mbox.used);
}
sys_thread_t
sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
{
TaskHandle_t rtos_task;
BaseType_t ret;
sys_thread_t lwip_thread;
size_t rtos_stacksize;
LWIP_ASSERT("invalid stacksize", stacksize > 0);
#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
rtos_stacksize = (size_t)stacksize;
#else
rtos_stacksize = (size_t)stacksize / sizeof(StackType_t);
#endif
/* lwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the
thread function without adaption here. */
ret = xTaskCreate(thread, name, (configSTACK_DEPTH_TYPE)rtos_stacksize, arg, prio, &rtos_task);
LWIP_ASSERT("task creation failed", ret == pdTRUE);
lwip_thread.thread_handle = rtos_task;
return lwip_thread;
}
#if LWIP_NETCONN_SEM_PER_THREAD
#if configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0
sys_sem_t *
sys_arch_netconn_sem_get(void)
{
void* ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
return ret;
}
void
sys_arch_netconn_sem_alloc(void)
{
void *ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
if(ret == NULL) {
sys_sem_t *sem;
err_t err;
/* need to allocate the memory for this semaphore */
sem = mem_malloc(sizeof(sys_sem_t));
LWIP_ASSERT("sem != NULL", sem != NULL);
err = sys_sem_new(sem, 0);
LWIP_ASSERT("err == ERR_OK", err == ERR_OK);
LWIP_ASSERT("sem invalid", sys_sem_valid(sem));
vTaskSetThreadLocalStoragePointer(task, 0, sem);
}
}
void sys_arch_netconn_sem_free(void)
{
void* ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
if(ret != NULL) {
sys_sem_t *sem = ret;
sys_sem_free(sem);
mem_free(sem);
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
}
}
#else /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
#error LWIP_NETCONN_SEM_PER_THREAD needs configNUM_THREAD_LOCAL_STORAGE_POINTERS
#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#if LWIP_FREERTOS_CHECK_CORE_LOCKING
#if LWIP_TCPIP_CORE_LOCKING
/** Flag the core lock held. A counter for recursive locks. */
static u8_t lwip_core_lock_count;
static TaskHandle_t lwip_core_lock_holder_thread;
void
sys_lock_tcpip_core(void)
{
sys_mutex_lock(&lock_tcpip_core);
if (lwip_core_lock_count == 0) {
lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle();
}
lwip_core_lock_count++;
}
void
sys_unlock_tcpip_core(void)
{
lwip_core_lock_count--;
if (lwip_core_lock_count == 0) {
lwip_core_lock_holder_thread = 0;
}
sys_mutex_unlock(&lock_tcpip_core);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if !NO_SYS
static TaskHandle_t lwip_tcpip_thread;
#endif
void
sys_mark_tcpip_thread(void)
{
#if !NO_SYS
lwip_tcpip_thread = xTaskGetCurrentTaskHandle();
#endif
}
void
sys_check_core_locking(void)
{
/* Embedded systems should check we are NOT in an interrupt context here */
/* E.g. core Cortex-M3/M4 ports:
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
Instead, we use more generic FreeRTOS functions here, which should fail from ISR: */
taskENTER_CRITICAL();
taskEXIT_CRITICAL();
#if !NO_SYS
if (lwip_tcpip_thread != 0) {
TaskHandle_t current_thread = xTaskGetCurrentTaskHandle();
#if LWIP_TCPIP_CORE_LOCKING
LWIP_ASSERT("Function called without core lock",
current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0);
#else /* LWIP_TCPIP_CORE_LOCKING */
LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread);
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
#endif /* !NO_SYS */
}
#endif /* LWIP_FREERTOS_CHECK_CORE_LOCKING*/

1077
src/ethernetif.c Normal file

File diff suppressed because it is too large Load Diff

310
src/fsl_phy.c Normal file
View File

@ -0,0 +1,310 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
#include "fsl_phy.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Defines the timeout macro. */
#define PHY_TIMEOUT_COUNT 0xFFFFFU
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get the ENET instance from peripheral base address.
*
* @param base ENET peripheral base address.
* @return ENET instance.
*/
extern uint32_t ENET_GetInstance(ENET_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to enet clocks for each instance. */
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
{
uint32_t bssReg;
uint32_t counter = PHY_TIMEOUT_COUNT;
uint32_t idReg = 0;
status_t result = kStatus_Success;
uint32_t instance = ENET_GetInstance(base);
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Set SMI first. */
CLOCK_EnableClock(s_enetClock[instance]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
ENET_SetSMI(base, srcClock_Hz, false);
/* Initialization after PHY stars to work. */
while ((idReg != PHY_CONTROL_ID1) && (counter != 0))
{
PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
counter --;
}
if (!counter)
{
return kStatus_Fail;
}
/* Reset PHY. */
counter = PHY_TIMEOUT_COUNT;
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
if (result == kStatus_Success)
{
/* Set the negotiation. */
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
if (result == kStatus_Success)
{
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
if (result == kStatus_Success)
{
/* Check auto negotiation complete. */
while (counter --)
{
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
if ( result == kStatus_Success)
{
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
{
break;
}
}
if (!counter)
{
return kStatus_PHY_AutoNegotiateFail;
}
}
}
}
}
return result;
}
status_t PHY_Write(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
{
uint32_t counter;
/* Clear the SMI interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI write command. */
ENET_StartSMIWrite(base, phyAddr, phyReg, kENET_MiiWriteValidFrame, data);
/* Wait for SMI complete. */
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
{
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
{
break;
}
}
/* Check for timeout. */
if (!counter)
{
return kStatus_PHY_SMIVisitTimeout;
}
/* Clear MII interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return kStatus_Success;
}
status_t PHY_Read(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t *dataPtr)
{
assert(dataPtr);
uint32_t counter;
/* Clear the MII interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
/* Starts a SMI read command operation. */
ENET_StartSMIRead(base, phyAddr, phyReg, kENET_MiiReadValidFrame);
/* Wait for MII complete. */
for (counter = PHY_TIMEOUT_COUNT; counter > 0; counter--)
{
if (ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK)
{
break;
}
}
/* Check for timeout. */
if (!counter)
{
return kStatus_PHY_SMIVisitTimeout;
}
/* Get data from MII register. */
*dataPtr = ENET_ReadSMIData(base);
/* Clear MII interrupt event. */
ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
return kStatus_Success;
}
status_t PHY_EnableLoopback(ENET_Type *base, uint32_t phyAddr, phy_loop_t mode, bool enable)
{
status_t result;
uint32_t data = 0;
/* Set the loop mode. */
if (enable)
{
if (mode == kPHY_LocalLoop)
{
/* First read the current status in control register. */
result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data);
if (result == kStatus_Success)
{
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data | PHY_BCTL_LOOP_MASK));
}
}
else
{
/* First read the current status in control register. */
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data);
if (result == kStatus_Success)
{
return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data | PHY_CTL1_REMOTELOOP_MASK));
}
}
}
else
{
/* Disable the loop mode. */
if (mode == kPHY_LocalLoop)
{
/* First read the current status in the basic control register. */
result = PHY_Read(base, phyAddr, PHY_BASICCONTROL_REG, &data);
if (result == kStatus_Success)
{
return PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, (data & ~PHY_BCTL_LOOP_MASK));
}
}
else
{
/* First read the current status in control one register. */
result = PHY_Read(base, phyAddr, PHY_CONTROL1_REG, &data);
if (result == kStatus_Success)
{
return PHY_Write(base, phyAddr, PHY_CONTROL1_REG, (data & ~PHY_CTL1_REMOTELOOP_MASK));
}
}
}
return result;
}
status_t PHY_GetLinkStatus(ENET_Type *base, uint32_t phyAddr, bool *status)
{
assert(status);
status_t result = kStatus_Success;
uint32_t data;
/* Read the basic status register. */
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &data);
if (result == kStatus_Success)
{
if (!(PHY_BSTATUS_LINKSTATUS_MASK & data))
{
/* link down. */
*status = false;
}
else
{
/* link up. */
*status = true;
}
}
return result;
}
status_t PHY_GetLinkSpeedDuplex(ENET_Type *base, uint32_t phyAddr, phy_speed_t *speed, phy_duplex_t *duplex)
{
assert(duplex);
status_t result = kStatus_Success;
uint32_t data, ctlReg;
/* Read the control two register. */
result = PHY_Read(base, phyAddr, PHY_CONTROL2_REG, &ctlReg);
if (result == kStatus_Success)
{
data = ctlReg & PHY_BSTATUS_SPEEDUPLX_MASK;
if ((PHY_CTL2_10FULLDUPLEX_MASK == data) || (PHY_CTL2_100FULLDUPLEX_MASK == data))
{
/* Full duplex. */
*duplex = kPHY_FullDuplex;
}
else
{
/* Half duplex. */
*duplex = kPHY_HalfDuplex;
}
data = ctlReg & PHY_BSTATUS_SPEEDUPLX_MASK;
if ((PHY_CTL2_100HALFDUPLEX_MASK == data) || (PHY_CTL2_100FULLDUPLEX_MASK == data))
{
/* 100M speed. */
*speed = kPHY_Speed100M;
}
else
{ /* 10M speed. */
*speed = kPHY_Speed10M;
}
}
return result;
}

View File

@ -1,12 +1,28 @@
#include "FreeRTOS.h"
#include "board.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "peripherals.h"
#include "pin_mux.h"
/* Console */
#include "fsl_debug_console.h"
/* MISC */
#include "system_utilities.h"
/*FreeRTOS*/
#include "FreeRTOS.h"
#include "task.h"
/* LwIP */
#include "lwip/dhcp.h"
#include "lwip/prot/dhcp.h"
#include "lwip/tcpip.h"
/* ENET */
#include "ethernetif.h"
static struct netif fsl_netif0;
static void vTaskHello(void *pvParameters);
int main(void) {
@ -28,9 +44,84 @@ int main(void) {
}
}
static void vTaskHello(void *pvParameters) {
for(;;) {
vTaskDelay(pdMS_TO_TICKS(1000));
PRINTF("Hello world @%d\r\n", xTaskGetTickCount());
static void setup_lwip(void) {
ip4_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw;
SYSMPU->CESR &= ~(SYSMPU_CESR_VLD_MASK); /* Disable MPU */
tcpip_init(NULL, NULL);
netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, tcpip_input);
netif_set_default(&fsl_netif0);
netif_set_up(&fsl_netif0);
dhcp_start(&fsl_netif0);
}
static void print_dhcp_state(struct netif *netif) {
static u8_t dhcp_last_state = DHCP_STATE_OFF;
struct dhcp *dhcp = (struct dhcp *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
if (dhcp_last_state != dhcp->state) {
dhcp_last_state = dhcp->state;
PRINTF(" DHCP state : ");
switch (dhcp_last_state) {
case DHCP_STATE_OFF:
PRINTF("OFF");
break;
case DHCP_STATE_REQUESTING:
PRINTF("REQUESTING");
break;
case DHCP_STATE_INIT:
PRINTF("INIT");
break;
case DHCP_STATE_REBOOTING:
PRINTF("REBOOTING");
break;
case DHCP_STATE_REBINDING:
PRINTF("REBINDING");
break;
case DHCP_STATE_RENEWING:
PRINTF("RENEWING");
break;
case DHCP_STATE_SELECTING:
PRINTF("SELECTING");
break;
case DHCP_STATE_INFORMING:
PRINTF("INFORMING");
break;
case DHCP_STATE_CHECKING:
PRINTF("CHECKING");
break;
case DHCP_STATE_BOUND:
PRINTF("BOUND");
break;
case DHCP_STATE_BACKING_OFF:
PRINTF("BACKING_OFF");
break;
default:
PRINTF("%u", dhcp_last_state);
assert(0);
break;
}
PRINTF("\r\n");
if (dhcp_last_state == DHCP_STATE_BOUND) {
PRINTF("\r\n IPv4 Address : %u.%u.%u.%u\r\n", ((u8_t *)&netif->ip_addr.u_addr)[0],
((u8_t *)&netif->ip_addr.u_addr)[1], ((u8_t *)&netif->ip_addr.u_addr)[2],
((u8_t *)&netif->ip_addr.u_addr)[3]);
PRINTF(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&netif->netmask.u_addr)[0],
((u8_t *)&netif->netmask.u_addr)[1], ((u8_t *)&netif->netmask.u_addr)[2],
((u8_t *)&netif->netmask.u_addr)[3]);
PRINTF(" IPv4 Gateway : %u.%u.%u.%u\r\n\r\n", ((u8_t *)&netif->gw.u_addr)[0],
((u8_t *)&netif->gw.u_addr)[1], ((u8_t *)&netif->gw.u_addr)[2], ((u8_t *)&netif->gw.u_addr)[3]);
}
}
}
static void vTaskHello(void *pvParameters) {
setup_lwip();
for (;;) {
vTaskDelay(pdMS_TO_TICKS(1000));
print_dhcp_state(&fsl_netif0);
}
}