MCUXpresso_MIMXRT1021xxxxx/boards/evkmimxrt1020/lwip_examples/lwip_dhcp/bm/lwip_dhcp_bm.c
Yilin Sun 763d32be90
Updated SDK to v2.15.000
Signed-off-by: Yilin Sun <imi415@imi.moe>
2024-03-15 22:23:36 +08:00

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