Part Number: TMDSCNCD28388D
Other Parts Discussed in Thread: C2000WARE
Hi Team,
Posting on behalf of our customer.
I am running the enet_lwip example code on the TMDSCNCD28388D using C2000Ware_6_00_01_00. The example works properly with the default dynamic IP / MAC settings, but stops working after I change the IP address and MAC address.
OBSERVED:
C:\Users\gpc3>ping 192.168.1.190
Pinging 192.168.1.190 with 32 bytes of data:
Reply from 192.168.1.53: Destination host unreachable.
Reply from 192.168.1.53: Destination host unreachable.
Reply from 192.168.1.53: Destination host unreachable.
Reply from 192.168.1.53: Destination host unreachable.
Ping statistics for 192.168.1.190:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
//###########################################################################
//
// FILE: enet_lwip.c
//
// TITLE: lwIP based Ethernet Example.
//
//###########################################################################
// $TI Release: $
// $Release Date: $
//
// C2000Ware v6.00.01.00
//
// Copyright (C) 2024 Texas Instruments Incorporated - http://www.ti.com
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 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.
//
// Neither the name of Texas Instruments Incorporated 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
// OWNER 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 <string.h>
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_emac.h"
#include "driverlib_cm/ethernet.h"
#include "driverlib_cm/gpio.h"
#include "driverlib_cm/interrupt.h"
#include "driverlib_cm/flash.h"
#include "driverlib_cm/sysctl.h"
#include "driverlib_cm/systick.h"
#include "utils/lwiplib.h"
#include "driver/device.h"
#include "driver/ethernet.h"
#include "board_drivers/pinout.h"
#include "lwip/apps/httpd.h"
#include "lwipopts.h"
//*****************************************************************************
//
//! \addtogroup master_example_list
//! <h1>Ethernet with lwIP (enet_lwip)</h1>
//!
//! This example application demonstrates the operation of the F2838x
//! microcontroller Ethernet controller using the lwIP TCP/IP Stack. Once
//! programmed, the device sits endlessly waiting for ICMP ping requests. It
//! has a static IP address. To ping the device, the sender has to be in the
//! same network. The stack also supports ARP.
//!
//! For additional details on lwIP, refer to the lwIP web page at:
//! savannah.nongnu.org/.../
//
//*****************************************************************************
#define MAKE_IP_ADDRESS(a0,a1,a2,a3) (((a0<<24) & 0xFF000000) | ((a1<<16) & 0x00FF0000) | ((a2<<8) & 0x0000FF00) | (a3 & 0x000000FF) )
#define RX_ISR_BIT 1
#define TX_ISR_BIT 4
#define RX_ISR_MASK (1 << RX_ISR_BIT)
#define TX_ISR_MASK (1 << TX_ISR_BIT)
/*
g_uiISRsignal variable signals the Interrupt.
*/
uint32_t g_uiISRsignal = 0;
const unsigned long IPAddr = 0xC0A801BE; // 0xC0A80004; //192.168.1.190
const unsigned long NetMask = 0xFFFFFF00;
const unsigned long GWAddr = 0x00000000;
Ethernet_Handle emac_handle;
Ethernet_InitConfig *pInitCfg;
extern Ethernet_Device Ethernet_device_struct;
/*
systick Timer acts as source for lwip timer,
125000 implies 1ms.
*/
const uint32_t systickPeriodValue = 125000;
/***********************************************************************************************
* Ethernet_transmitISRCustom
*
* This function is a custom interrupt service routine (ISR) for handling Ethernet
* transmission interrupts. It is called when a packet is succesfully transmitted.
*
************************************************************************************************/
void Ethernet_transmitISRCustom(void);
/************************************************************************************************
* Ethernet_receiveISRCustom
*
* This function is a custom interrupt service routine (ISR) for handling Ethernet
* reception interrupts. It is called when a packet is received.
*
************************************************************************************************/
void Ethernet_receiveISRCustom(void);
//*****************************************************************************
//
// This function is a callback function called by the example to
// get a Packet Buffer. Has to return a Ethernet_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_getPacketBufferCustom(void)
{
Ethernet_Pkt_Desc* pktPtr = lwIP_getFreePacket();
ENET_DRIVER_STATS_INC(RXgetPacketBuffer);
return (pktPtr);
}
//*****************************************************************************
//
// This is a hook function and called by the driver when it receives a
// packet. Application is expected to replenish the buffer after consuming it.
// Has to return a ETHERNET_Pkt_Desc Structure.
// Rewrite this API for custom use case.
//
//*****************************************************************************
Ethernet_Pkt_Desc* Ethernet_receivePacketCallbackCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
Ethernet_Pkt_Desc* temp_eth_pkt;
ENET_DRIVER_STATS_INC(RXPacketCallback);
temp_eth_pkt=lwIPEthernetIntHandler(pPacket);
return temp_eth_pkt;
}
void Ethernet_releaseTxPacketBufferCustom(
Ethernet_Handle handleApplication,
Ethernet_Pkt_Desc *pPacket)
{
//
// Once the packet is sent, reuse the packet memory to avoid
// memory leaks. Call this interrupt handler function which will take care
// of freeing the memory used by the packet descriptor.
//
lwIPEthernetIntHandler(pPacket);
ENET_DRIVER_STATS_INC(TXreleasePacket);
}
void
Ethernet_init(const unsigned char *mac)
{
Ethernet_InitInterfaceConfig initInterfaceConfig;
uint32_t macLower;
uint32_t macHigher;
uint8_t *temp;
initInterfaceConfig.ssbase = EMAC_SS_BASE;
initInterfaceConfig.enet_base = EMAC_BASE;
initInterfaceConfig.phyMode = ETHERNET_SS_PHY_INTF_SEL_MII;
//
// Assign SoC specific functions for Enabling,Disabling interrupts
// and for enabling the Peripheral at system level
//
initInterfaceConfig.ptrPlatformInterruptDisable =
&Platform_disableInterrupt;
initInterfaceConfig.ptrPlatformInterruptEnable =
&Platform_enableInterrupt;
initInterfaceConfig.ptrPlatformPeripheralEnable =
&Platform_enablePeripheral;
initInterfaceConfig.ptrPlatformPeripheralReset =
&Platform_resetPeripheral;
//
// Assign the peripheral number at the SoC
//
initInterfaceConfig.peripheralNum = SYSCTL_PERIPH_CLK_ENET;
//
// Assign the default SoC specific interrupt numbers of Ethernet interrupts
//
initInterfaceConfig.interruptNum[0] = INT_EMAC;
initInterfaceConfig.interruptNum[1] = INT_EMAC_TX0;
initInterfaceConfig.interruptNum[2] = INT_EMAC_TX1;
initInterfaceConfig.interruptNum[3] = INT_EMAC_RX0;
initInterfaceConfig.interruptNum[4] = INT_EMAC_RX1;
pInitCfg = Ethernet_initInterface(initInterfaceConfig);
Ethernet_getInitConfig(pInitCfg);
pInitCfg->dmaMode.InterruptMode = ETHERNET_DMA_MODE_INTM_MODE2;
//
// Assign the callbacks for Getting packet buffer when needed
// Releasing the TxPacketBuffer on Transmit interrupt callbacks
// Receive packet callback on Receive packet completion interrupt
//
pInitCfg->pfcbRxPacket = &Ethernet_receivePacketCallbackCustom;
pInitCfg->pfcbGetPacket = &Ethernet_getPacketBufferCustom;
pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBufferCustom;
pInitCfg->numChannels = 1U;
//
// The Application handle is not used by this application
// Hence using a dummy value of 1
//
Ethernet_getHandle((Ethernet_Handle)1, pInitCfg , &emac_handle);
//
// Disable transmit buffer unavailable and normal interrupt which
// are enabled by default in Ethernet_getHandle.
//
Ethernet_disableDmaInterrupt(Ethernet_device_struct.baseAddresses.enet_base,
0, (ETHERNET_DMA_CH0_INTERRUPT_ENABLE_TBUE |
ETHERNET_DMA_CH0_INTERRUPT_ENABLE_NIE));
//
// Enable the MTL interrupt to service the receive FIFO overflow
// condition in the Ethernet module.
//
Ethernet_enableMTLInterrupt(Ethernet_device_struct.baseAddresses.enet_base,0,
ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOIE);
//
// Disable the MAC Management counter interrupts as they are not used
// in this application.
//
HWREG(Ethernet_device_struct.baseAddresses.enet_base + ETHERNET_O_MMC_RX_INTERRUPT_MASK) = 0xFFFFFFFF;
HWREG(Ethernet_device_struct.baseAddresses.enet_base + ETHERNET_O_MMC_IPC_RX_INTERRUPT_MASK) = 0xFFFFFFFF;
HWREG(Ethernet_device_struct.baseAddresses.enet_base + ETHERNET_O_MMC_TX_INTERRUPT_MASK) = 0xFFFFFFFF;
//
//Do global Interrupt Enable
//
(void)Interrupt_enableInProcessor();
//
//Assign default ISRs
//
Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISRCustom);
Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISRCustom);
Interrupt_registerHandler(INT_EMAC, Ethernet_genericISRCustom);
//
// Convert the mac address string into the 32/16 split variables format
// that is required by the driver to program into hardware registers.
// Note: This step is done after the Ethernet_getHandle function because
// a dummy MAC address is programmed in that function.
//
temp = (uint8_t *)&macLower;
temp[0] = mac[0];
temp[1] = mac[1];
temp[2] = mac[2];
temp[3] = mac[3];
temp = (uint8_t *)&macHigher;
temp[0] = mac[4];
temp[1] = mac[5];
//
// Program the unicast mac address.
//
Ethernet_setMACAddr(EMAC_BASE,
0,
macHigher,
macLower,
ETHERNET_CHANNEL_0);
Ethernet_clearMACConfigurationCustom(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
Ethernet_setMACConfigurationCustom(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
(&Ethernet_device_struct.dmaObj.txDma[ETHERNET_DMA_CHANNEL_NUM_0])->descCount = 0;
}
void httpLEDToggle(void);
void(*ledtoggleFuncPtr)(void) = &httpLEDToggle;
//*****************************************************************************
//
// The interrupt handler for the SysTick interrupt.
//
//*****************************************************************************
void
SysTickIntHandler(void)
{
//
// Call the lwIP timer handler.
//
lwIPTimer(1);
}
//*****************************************************************************
//
// This example demonstrates the use of the Ethernet Controller.
//
//*****************************************************************************
int
main(void)
{
unsigned long ulUser0, ulUser1;
unsigned char pucMACArray[8];
//
// User specific IP Address Configuration.
// Current implementation works with Static IP address only.
//
unsigned long IPAddr = 0xC0A801BE;
unsigned long NetMask = 0xFFFFFF00;
unsigned long GWAddr = 0x00000000;
//
// Initializing the CM. Loading the required functions to SRAM.
//
CM_init();
SYSTICK_setPeriod(systickPeriodValue);
SYSTICK_enableCounter();
SYSTICK_registerInterruptHandler(SysTickIntHandler);
SYSTICK_enableInterrupt();
//
// Enable processor interrupts.
//
Interrupt_enableInProcessor();
// Set user/company specific MAC octets
// (for this code we are using A8-63-F2-00-3C-5C)
// 0x00 MACOCT3 MACOCT2 MACOCT1
ulUser0 = 0x00F263A8;
// 0x00 MACOCT6 MACOCT5 MACOCT4
ulUser1 = 0x005C3C00;
//
// Convert the 24/24 split MAC address from NV ram into a 32/16 split MAC
// address needed to program the hardware registers, then program the MAC
// address into the Ethernet Controller registers.
//
pucMACArray[0] = ((ulUser0 >> 0) & 0xff);
pucMACArray[1] = ((ulUser0 >> 8) & 0xff);
pucMACArray[2] = ((ulUser0 >> 16) & 0xff);
pucMACArray[3] = ((ulUser1 >> 0) & 0xff);
pucMACArray[4] = ((ulUser1 >> 8) & 0xff);
pucMACArray[5] = ((ulUser1 >> 16) & 0xff);
Interrupt_enable(INT_EMAC_TX0);
Interrupt_enable(INT_EMAC_RX0);
Interrupt_enable(INT_EMAC);
//
// Initialze the lwIP library, using DHCP.
//
lwIPInit(0, pucMACArray, IPAddr, NetMask, GWAddr, IPADDR_USE_STATIC);
//
// Initialize ethernet module.
//
Ethernet_init(pucMACArray);
//
// Initialize the netif and start lwIP
//
lwIPStart(0);
//
// Initialize the HTTP webserver daemon.
//
httpd_init();
//
// Loop forever. All the work is done in interrupt handlers.
//
while(1)
{
uint32_t uiISRsignal = g_uiISRsignal;
if((uiISRsignal & RX_ISR_MASK) != 0)
{
Ethernet_removePacketsFromRxQueueCustom(
(Ethernet_DescCh*)&Ethernet_device_struct.dmaObj.rxDma[ETHERNET_DMA_CHANNEL_NUM_0], ETHERNET_COMPLETION_NORMAL);
ETHERNET_DISABLE_INTERRUPTS();
g_uiISRsignal &= (~RX_ISR_MASK);
ETHERNET_ENABLE_INTERRUPTS();
}
if((uiISRsignal & TX_ISR_MASK) != 0)
{
Ethernet_removePacketsFromTxQueueCustom(
(Ethernet_DescCh*)&Ethernet_device_struct.dmaObj.txDma[ETHERNET_DMA_CHANNEL_NUM_0], ETHERNET_COMPLETION_NORMAL);
ETHERNET_DISABLE_INTERRUPTS();
g_uiISRsignal &= (~TX_ISR_MASK);
ETHERNET_ENABLE_INTERRUPTS();
}
}
}
void Ethernet_transmitISRCustom(void)
{
ENET_DRIVER_STATS_INC(TXinterrupt);
Ethernet_clearDMAChannelInterrupt(
Ethernet_device_struct.baseAddresses.enet_base,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_TI);
g_uiISRsignal |= TX_ISR_MASK;
}
void Ethernet_receiveISRCustom(void)
{
ENET_DRIVER_STATS_INC(RXinterrupt);
Ethernet_clearDMAChannelInterrupt(
Ethernet_device_struct.baseAddresses.enet_base,
ETHERNET_DMA_CHANNEL_NUM_0,
ETHERNET_DMA_CH0_STATUS_RI);
g_uiISRsignal |= RX_ISR_MASK;
}
//*****************************************************************************
//
// Called by lwIP Library. Toggles the led when a command is received by the
// HTTP webserver.
//
//*****************************************************************************
void httpLEDToggle(void)
{
//
// Toggle the LED D1 on the control card.
//
GPIO_togglePin(DEVICE_GPIO_PIN_LED1);
}
//*****************************************************************************
//
// Called by lwIP Library. Could be used for periodic custom tasks.
//
//*****************************************************************************
void lwIPHostTimerHandler(void)
{
}
Regards,
Danilo








