337 lines
8.8 KiB
C
337 lines
8.8 KiB
C
/*
|
|
* Copyright (c) 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016-2020,2023 NXP
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
/*******************************************************************************
|
|
* Includes
|
|
******************************************************************************/
|
|
|
|
#include "lwip/opt.h"
|
|
|
|
#if LWIP_IPV4 && LWIP_DHCP
|
|
|
|
#include "lwip/timeouts.h"
|
|
#include "lwip/ip_addr.h"
|
|
#include "lwip/init.h"
|
|
#include "lwip/dhcp.h"
|
|
#include "lwip/netif.h"
|
|
#include "lwip/prot/dhcp.h"
|
|
#include "netif/ethernet.h"
|
|
#include "ethernetif.h"
|
|
|
|
#ifndef configMAC_ADDR
|
|
#include "fsl_silicon_id.h"
|
|
#endif
|
|
#include "fsl_phy.h"
|
|
#include "pin_mux.h"
|
|
#include "board.h"
|
|
|
|
#include "fsl_iomuxc.h"
|
|
#include "fsl_enet.h"
|
|
#include "fsl_phyksz8081.h"
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
/* @TEST_ANCHOR */
|
|
|
|
/* IP address configuration. */
|
|
#ifndef configIP_ADDR0
|
|
#define configIP_ADDR0 192
|
|
#endif
|
|
#ifndef configIP_ADDR1
|
|
#define configIP_ADDR1 168
|
|
#endif
|
|
#ifndef configIP_ADDR2
|
|
#define configIP_ADDR2 0
|
|
#endif
|
|
#ifndef configIP_ADDR3
|
|
#define configIP_ADDR3 102
|
|
#endif
|
|
|
|
/* Netmask configuration. */
|
|
#ifndef configNET_MASK0
|
|
#define configNET_MASK0 255
|
|
#endif
|
|
#ifndef configNET_MASK1
|
|
#define configNET_MASK1 255
|
|
#endif
|
|
#ifndef configNET_MASK2
|
|
#define configNET_MASK2 255
|
|
#endif
|
|
#ifndef configNET_MASK3
|
|
#define configNET_MASK3 0
|
|
#endif
|
|
|
|
/* Gateway address configuration. */
|
|
#ifndef configGW_ADDR0
|
|
#define configGW_ADDR0 192
|
|
#endif
|
|
#ifndef configGW_ADDR1
|
|
#define configGW_ADDR1 168
|
|
#endif
|
|
#ifndef configGW_ADDR2
|
|
#define configGW_ADDR2 0
|
|
#endif
|
|
#ifndef configGW_ADDR3
|
|
#define configGW_ADDR3 100
|
|
#endif
|
|
|
|
/* Ethernet configuration. */
|
|
extern phy_ksz8081_resource_t g_phy_resource;
|
|
#define EXAMPLE_ENET ENET
|
|
#define EXAMPLE_PHY_ADDRESS 0x02U
|
|
#define EXAMPLE_PHY_OPS &phyksz8081_ops
|
|
#define EXAMPLE_PHY_RESOURCE &g_phy_resource
|
|
#define EXAMPLE_CLOCK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk)
|
|
|
|
#ifndef EXAMPLE_NETIF_INIT_FN
|
|
/*! @brief Network interface initialization function. */
|
|
#define EXAMPLE_NETIF_INIT_FN ethernetif0_init
|
|
#endif /* EXAMPLE_NETIF_INIT_FN */
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
phy_ksz8081_resource_t g_phy_resource;
|
|
|
|
static phy_handle_t phyHandle;
|
|
static netif_ext_callback_t linkStatusCallbackInfo;
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
void BOARD_InitModuleClock(void)
|
|
{
|
|
const clock_enet_pll_config_t config = {
|
|
.enableClkOutput = true, .enableClkOutput500M = false, .enableClkOutput25M = false, .loopDivider = 1};
|
|
CLOCK_InitEnetPll(&config);
|
|
}
|
|
|
|
static void MDIO_Init(void)
|
|
{
|
|
(void)CLOCK_EnableClock(s_enetClock[ENET_GetInstance(EXAMPLE_ENET)]);
|
|
ENET_SetSMI(EXAMPLE_ENET, EXAMPLE_CLOCK_FREQ, false);
|
|
}
|
|
|
|
static status_t MDIO_Write(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
|
|
{
|
|
return ENET_MDIOWrite(EXAMPLE_ENET, phyAddr, regAddr, data);
|
|
}
|
|
|
|
static status_t MDIO_Read(uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
|
|
{
|
|
return ENET_MDIORead(EXAMPLE_ENET, phyAddr, regAddr, pData);
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
* @brief Link status callback - prints link status events.
|
|
*/
|
|
static void linkStatusCallback(struct netif *netif_, netif_nsc_reason_t reason, const netif_ext_callback_args_t *args)
|
|
{
|
|
if (reason != LWIP_NSC_LINK_CHANGED)
|
|
return;
|
|
|
|
PRINTF("[LINK STATE] netif=%d, state=%s", netif_->num, args->link_changed.state ? "up" : "down");
|
|
|
|
if (args->link_changed.state)
|
|
{
|
|
char *speedStr;
|
|
switch (ethernetif_get_link_speed(netif_))
|
|
{
|
|
case kPHY_Speed10M:
|
|
speedStr = "10M";
|
|
break;
|
|
case kPHY_Speed100M:
|
|
speedStr = "100M";
|
|
break;
|
|
case kPHY_Speed1000M:
|
|
speedStr = "1000M";
|
|
break;
|
|
default:
|
|
speedStr = "N/A";
|
|
break;
|
|
}
|
|
|
|
char *duplexStr;
|
|
switch (ethernetif_get_link_duplex(netif_))
|
|
{
|
|
case kPHY_HalfDuplex:
|
|
duplexStr = "half";
|
|
break;
|
|
case kPHY_FullDuplex:
|
|
duplexStr = "full";
|
|
break;
|
|
default:
|
|
duplexStr = "N/A";
|
|
break;
|
|
}
|
|
|
|
PRINTF(", speed=%s_%s", speedStr, duplexStr);
|
|
}
|
|
|
|
PRINTF("\r\n");
|
|
}
|
|
|
|
/*!
|
|
* @brief Interrupt service for SysTick timer.
|
|
*/
|
|
void SysTick_Handler(void)
|
|
{
|
|
time_isr();
|
|
}
|
|
|
|
/*!
|
|
* @brief Prints DHCP status of the interface when it has changed from last status.
|
|
*
|
|
* @param netif network interface structure
|
|
*/
|
|
static void print_dhcp_state(struct netif *netif)
|
|
{
|
|
static u8_t dhcp_last_state = DHCP_STATE_OFF;
|
|
struct dhcp *dhcp = netif_dhcp_data(netif);
|
|
|
|
if (dhcp == NULL)
|
|
{
|
|
dhcp_last_state = DHCP_STATE_OFF;
|
|
}
|
|
else 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 : %s\r\n", ipaddr_ntoa(&netif->ip_addr));
|
|
PRINTF(" IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask));
|
|
PRINTF(" IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* @brief Main function.
|
|
*/
|
|
int main(void)
|
|
{
|
|
struct netif netif;
|
|
ethernetif_config_t enet_config = {.phyHandle = &phyHandle,
|
|
.phyAddr = EXAMPLE_PHY_ADDRESS,
|
|
.phyOps = EXAMPLE_PHY_OPS,
|
|
.phyResource = EXAMPLE_PHY_RESOURCE,
|
|
#ifdef configMAC_ADDR
|
|
.macAddress = configMAC_ADDR
|
|
#endif
|
|
};
|
|
|
|
BOARD_ConfigMPU();
|
|
BOARD_InitBootPins();
|
|
BOARD_InitBootClocks();
|
|
BOARD_InitDebugConsole();
|
|
BOARD_InitModuleClock();
|
|
|
|
IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1TxClkOutputDir, true);
|
|
|
|
/* PHY hardware reset. */
|
|
BOARD_ENET_PHY_RESET;
|
|
|
|
MDIO_Init();
|
|
g_phy_resource.read = MDIO_Read;
|
|
g_phy_resource.write = MDIO_Write;
|
|
|
|
time_init();
|
|
|
|
/* Set MAC address. */
|
|
#ifndef configMAC_ADDR
|
|
(void)SILICONID_ConvertToMacAddr(&enet_config.macAddress);
|
|
#endif
|
|
|
|
/* Get clock after hardware init. */
|
|
enet_config.srcClockHz = EXAMPLE_CLOCK_FREQ;
|
|
|
|
lwip_init();
|
|
|
|
netif_add_ext_callback(&linkStatusCallbackInfo, linkStatusCallback);
|
|
|
|
netif_add(&netif, NULL, NULL, NULL, &enet_config, EXAMPLE_NETIF_INIT_FN, ethernet_input);
|
|
netif_set_default(&netif);
|
|
netif_set_up(&netif);
|
|
|
|
while (ethernetif_wait_linkup(&netif, 5000) != ERR_OK)
|
|
{
|
|
PRINTF("PHY Auto-negotiation failed. Please check the cable connection and link partner setting.\r\n");
|
|
}
|
|
|
|
dhcp_start(&netif);
|
|
|
|
PRINTF("\r\n************************************************\r\n");
|
|
PRINTF(" DHCP example\r\n");
|
|
PRINTF("************************************************\r\n");
|
|
|
|
while (1)
|
|
{
|
|
/* Poll the driver, get any outstanding frames */
|
|
ethernetif_input(&netif);
|
|
|
|
/* Handle all system timeouts for all core protocols */
|
|
sys_check_timeouts();
|
|
|
|
/* Print DHCP progress */
|
|
print_dhcp_state(&netif);
|
|
}
|
|
}
|
|
#endif
|