This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMDSCNCD28388D: Ethernet Module QuickStart

Part Number: TMDSCNCD28388D
Other Parts Discussed in Thread: C2000WARE

Hello

I was using SCI to communicate with my PC via serial port and send and receive 16 bit data. Due to reliability issue, I need to switch to ethernet. I am new to Ethernet and want to know if there is a tutorial for quickstart. I just want to define MAC address and simply send and receive data with my PC. 

Also, is ethercat better for my application? if so, are there any examples for ethercat? I didn't see any examples in C2000 V4.02 for ethercat. I want to avoid using CM core and IPC if possible.

Thanks

  • Chen, 

    My suggestion would be to use serial communication if you are running from c28x core but that depends on your application .  Please note that ethernet module is only accessible from CM core of F2838x and you will have to use IPC if you are running from C28x core. 

    There are examples for ethernet and ethercat provided in C2000Ware. 

    The driverlib based examples are available at C:\ti\c2000\C2000Ware_4_02_00_00\driverlib\f2838x\examples\cm\ethernet. 

    The stack based examples are available at C:\ti\c2000\C2000Ware_4_02_00_00\libraries\communications\Ethernet\third_party\lwip\examples

    Ethercat based examples are available at C:\ti\c2000\C2000Ware_4_02_00_00\libraries\communications\Ethercat\f2838x\examples

    Based on your application , you can decide which one to use. 

    Best Regards

    Siddharth

  • Hello

    Now I successfully modified lwip to send data  to PC with sockettool software with the lwip code. I have no idea how to receive data. I found that it looked like lwip_udp can send an receive data, but I cannot find the port on my PC, even though I used udp_connect() in  my code.I am wondering what is the port number in lwip-udp? I used udp_bind and udp_bind to define ports in lwip before forever loop but it doesn't work in lwip_udp. Do you have any idea how I can modify the lwip or lwip-udp code to receive and send message with PC? I found that I can use udp_send() function to send message and I did receive hex code on my PC side,  but I cannot find a function to receive message from ethernet port. I think I can handle the IPC part, but this Ethernet part is difficult for me.

    udp_bind(UdpPcb,IP_ADDR_ANY,6600);
    udp_connect(UdpPcb,&ipaddr,5530);

    Thanks

    Yifu

  • Yifu,

    What is the software that you are running on the PC side? 

    The UDP example needs the SocketTest/’Packet Sender’ software, configured for the IP Address and port that 

    Best Regards

    Siddharth

  • Hello. I am using a software called SocketTool4 which is used to debug Ethernet. I used this to debug Ethernet before. I need configure IP address and port in the software. I think this should be what you are talking about

  • Hello

    I downloaded SocketTool on my PC and it also needs port number of client side and server side.

     

    Thanks

    Yifu

  • //###########################################################################
    //
    // FILE:   enet_lwip.c
    //
    // TITLE:  lwIP based Ethernet Example.
    //
    //###########################################################################
    // $TI Release: $
    // $Release Date: $
    // $Copyright:
    // Copyright (C) 2022 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.
    // $
    //###########################################################################
    #define ADDRESS 0xC0A80004
    #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 "board_drivers/pinout.h"
    
    #include "lwip/apps/httpd.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:
    //! http://savannah.nongnu.org/projects/lwip/
    //
    //*****************************************************************************
    
    // These are defined by the linker (see device linker command file)
    extern uint16_t RamfuncsLoadStart;
    extern uint16_t RamfuncsLoadSize;
    extern uint16_t RamfuncsRunStart;
    extern uint16_t RamfuncsLoadEnd;
    extern uint16_t RamfuncsRunEnd;
    extern uint16_t RamfuncsRunSize;
    
    extern uint16_t constLoadStart;
    extern uint16_t constLoadEnd;
    extern uint16_t constLoadSize;
    extern uint16_t constRunStart;
    extern uint16_t constRunEnd;
    extern uint16_t constRunSize;
    
    #define DEVICE_FLASH_WAITSTATES 2
    
    //*****************************************************************************
    //
    // Driver specific initialization code and macro.
    //
    //*****************************************************************************
    
    #define ETHERNET_NO_OF_RX_PACKETS   2U
    #define ETHERNET_MAX_PACKET_LENGTH 1538U
    #define NUM_PACKET_DESC_RX_APPLICATION 8
    
    Ethernet_Handle emac_handle;
    Ethernet_InitConfig *pInitCfg;
    uint32_t Ethernet_numRxCallbackCustom = 0;
    uint32_t releaseTxCount = 0;
    uint32_t genericISRCustomcount = 0;
    uint32_t genericISRCustomRBUcount = 0;
    uint32_t genericISRCustomROVcount = 0;
    uint32_t genericISRCustomRIcount = 0;
    
    uint32_t systickPeriodValue = 15000000;
    Ethernet_Pkt_Desc  pktDescriptorRXCustom[NUM_PACKET_DESC_RX_APPLICATION];
    extern uint32_t Ethernet_numGetPacketBufferCallback;
    extern Ethernet_Device Ethernet_device_struct;
    uint8_t Ethernet_rxBuffer[ETHERNET_NO_OF_RX_PACKETS *
                              ETHERNET_MAX_PACKET_LENGTH];
    
    extern Ethernet_Pkt_Desc*
    lwIPEthernetIntHandler(Ethernet_Pkt_Desc *pPacket);
    
    void CM_init(void)
    {
        //
        // Disable the watchdog
        //
        SysCtl_disableWatchdog();
    
    #ifdef _FLASH
        //
        // Copy time critical code and flash setup code to RAM. This includes the
        // following functions: InitFlash();
        //
        // The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols
        // are created by the linker. Refer to the device .cmd file.
        // Html pages are also being copied from flash to ram.
        //
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
        memcpy(&constRunStart, &constLoadStart, (size_t)&constLoadSize);
        //
        // Call Flash Initialization to setup flash waitstates. This function must
        // reside in RAM.
        //
        Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
    #endif
    
        //
        // Sets the NVIC vector table offset address.
        //
    #ifdef _FLASH
        Interrupt_setVectorTableOffset((uint32_t)vectorTableFlash);
    #else
        Interrupt_setVectorTableOffset((uint32_t)vectorTableRAM);
    #endif
    
    }
    //*****************************************************************************
    //
    // HTTP Webserver related callbacks and definitions.
    //
    //*****************************************************************************
    //
    // Currently, this implemented as a pointer to function which is called when
    // corresponding query is received by the HTTP webserver daemon. When more
    // features are needed to be added, it should be implemented as a separate
    // interface.
    //
    void httpLEDToggle(void);
    void(*ledtoggleFuncPtr)(void) = &httpLEDToggle;
    
    //*****************************************************************************
    //
    // The interrupt handler for the SysTick interrupt.
    //
    //*****************************************************************************
    void
    SysTickIntHandler(void)
    {
        //
        // Call the lwIP timer handler.
        //
        lwIPTimer(systickPeriodValue);
    }
    
    //*****************************************************************************
    //
    //  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)
    {
        //
        // Get the next packet descriptor from the descriptor pool
        //
        uint32_t shortIndex = (Ethernet_numGetPacketBufferCallback + 3)
                    % NUM_PACKET_DESC_RX_APPLICATION;
    
        //
        // Increment the book-keeping pointer which acts as a head pointer
        // to the circular array of packet descriptor pool.
        //
        Ethernet_numGetPacketBufferCallback++;
    
        //
        // Update buffer length information to the newly procured packet
        // descriptor.
        //
        pktDescriptorRXCustom[shortIndex].bufferLength =
                                      ETHERNET_MAX_PACKET_LENGTH;
    
        //
        // Update the receive buffer address in the packer descriptor.
        //
        pktDescriptorRXCustom[shortIndex].dataBuffer =
                                          &Ethernet_device_struct.rxBuffer [ \
                   (ETHERNET_MAX_PACKET_LENGTH*Ethernet_device_struct.rxBuffIndex)];
    
        //
        // Update the receive buffer pool index.
        //
        Ethernet_device_struct.rxBuffIndex += 1U;
        Ethernet_device_struct.rxBuffIndex  = \
        (Ethernet_device_struct.rxBuffIndex%ETHERNET_NO_OF_RX_PACKETS);
    
        //
        // Receive buffer is usable from Address 0
        //
        pktDescriptorRXCustom[shortIndex].dataOffset = 0U;
    
        //
        // Return this new descriptor to the driver.
        //
        return (&(pktDescriptorRXCustom[shortIndex]));
    }
    
    //*****************************************************************************
    //
    //  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)
    {
        //
        // Book-keeping to maintain number of callbacks received.
        //
    #ifdef ETHERNET_DEBUG
        Ethernet_numRxCallbackCustom++;
    #endif
    
        //
        // This is a placeholder for Application specific handling
        // We are replenishing the buffer received with another buffer
        //
        return lwIPEthernetIntHandler(pPacket);
    }
    
    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);
    
        //
        // Increment the book-keeping counter.
        //
    #ifdef ETHERNET_DEBUG
        releaseTxCount++;
    #endif
    }
    
    interrupt void Ethernet_genericISRCustom(void)
    {
        genericISRCustomcount++;
        Ethernet_RxChDesc *rxChan;
        Ethernet_TxChDesc *txChan;
        Ethernet_HW_descriptor    *descPtr;
        Ethernet_HW_descriptor    *tailPtr;
        uint16_t i=0;
        Ethernet_clearMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
        Ethernet_clearMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_TE);
        for(i = 0U;i < Ethernet_device_struct.initConfig.numChannels;i++)
         {
             Ethernet_disableRxDMAReception(
                   Ethernet_device_struct.baseAddresses.enet_base,
                   i);
         }
        if(((ETHERNET_DMA_CH0_STATUS_AIS |
                             ETHERNET_DMA_CH0_STATUS_RBU) ==
                           (HWREG(Ethernet_device_struct.baseAddresses.enet_base +
                                  ETHERNET_O_DMA_CH0_STATUS) &
                                  (uint32_t)(ETHERNET_DMA_CH0_STATUS_AIS |
                                             ETHERNET_DMA_CH0_STATUS_RBU))) ||
              (ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOVFIS) ==
                                       (HWREG(Ethernet_device_struct.baseAddresses.enet_base +
                                              ETHERNET_O_MTL_Q0_INTERRUPT_CONTROL_STATUS) &
                                              (uint32_t)(ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOVFIS
                                                         )))
          {
              if((ETHERNET_DMA_CH0_STATUS_AIS |
                                 ETHERNET_DMA_CH0_STATUS_RBU) ==
                               (HWREG(Ethernet_device_struct.baseAddresses.enet_base +
                                      ETHERNET_O_DMA_CH0_STATUS) &
                                      (uint32_t)(ETHERNET_DMA_CH0_STATUS_AIS |
                                                 ETHERNET_DMA_CH0_STATUS_RBU)))
              {
              genericISRCustomRBUcount++;
              }
              if((ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOVFIS) ==
                      (HWREG(Ethernet_device_struct.baseAddresses.enet_base +
                             ETHERNET_O_MTL_Q0_INTERRUPT_CONTROL_STATUS) &
                             (uint32_t)(ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOVFIS
                                        )))
              {
                  genericISRCustomROVcount++;
                  Ethernet_enableMTLInterrupt(Ethernet_device_struct.baseAddresses.enet_base,0,
                                              ETHERNET_MTL_Q0_INTERRUPT_CONTROL_STATUS_RXOVFIS);
              }
    
            /*
                 * Clear the AIS and RBU status bit. These MUST be
                 * cleared together!
                 */
                Ethernet_clearDMAChannelInterrupt(
                        Ethernet_device_struct.baseAddresses.enet_base,
                        ETHERNET_DMA_CHANNEL_NUM_0,
                        ETHERNET_DMA_CH0_STATUS_AIS |
                        ETHERNET_DMA_CH0_STATUS_RBU);
    
                /*
               *Recover from Receive Buffer Unavailable (and hung DMA)
             *
             * All descriptor buffers are owned by the application, and
             * in result the DMA cannot transfer incoming frames to the
             * buffers (RBU condition). DMA has also entered suspend
             * mode at this point, too.
             *
             * Drain the RX queues
             */
    
                /* Upon RBU error, discard all previously received packets */
                if(Ethernet_device_struct.initConfig.pfcbDeletePackets != NULL)
                    (*Ethernet_device_struct.initConfig.pfcbDeletePackets)();
    
                rxChan =
                   &Ethernet_device_struct.dmaObj.rxDma[ETHERNET_DMA_CHANNEL_NUM_0];
                txChan=
                   &Ethernet_device_struct.dmaObj.txDma[ETHERNET_DMA_CHANNEL_NUM_0];
    
        /*
         * Need to disable multiple interrupts, so protect the code to do so within
         * a global disable block (to prevent getting interrupted in between)
         */
    
                if(NULL!= Ethernet_device_struct.ptrPlatformInterruptDisable)
                {
                    (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
                        Ethernet_device_struct.interruptNum[
                            ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
    
                    (*Ethernet_device_struct.ptrPlatformInterruptDisable)(
                        Ethernet_device_struct.interruptNum[
                            ETHERNET_GENERIC_INTERRUPT]);
                }
                /* verify we have full capacity in the descriptor queue */
                if(rxChan->descQueue.count < rxChan->descMax) {
                  /* The queue is not at full capacity due to OOM errors.
                  Try to fill it again */
                    Ethernet_addPacketsIntoRxQueue(rxChan);
                }
                Ethernet_initRxChannel(
                        &Ethernet_device_struct.initConfig.chInfo[ETHERNET_CH_DIR_RX][0]);
    
                Ethernet_writeRxDescTailPointer(
                    Ethernet_device_struct.baseAddresses.enet_base,
                    0,
                    (&Ethernet_device_struct.rxDesc[
                     ((uint32_t)ETHERNET_DESCRIPTORS_NUM_RX_PER_CHANNEL) *
                      (0 + (uint32_t)1U)]));
    
                if(NULL!= Ethernet_device_struct.ptrPlatformInterruptEnable)
                {
                    (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
                        Ethernet_device_struct.interruptNum[
                            ETHERNET_RX_INTR_CH0 + rxChan->chInfo->chNum]);
                    (*Ethernet_device_struct.ptrPlatformInterruptEnable)(
                        Ethernet_device_struct.interruptNum[
                            ETHERNET_GENERIC_INTERRUPT]);
                }
    
    
        }
        if(0U != (HWREG(Ethernet_device_struct.baseAddresses.enet_base +
                                     ETHERNET_O_DMA_CH0_STATUS) &
                               (uint32_t) ETHERNET_DMA_CH0_STATUS_RI))
        {
            genericISRCustomRIcount++;
            Ethernet_clearDMAChannelInterrupt(
                            Ethernet_device_struct.baseAddresses.enet_base,
                            ETHERNET_DMA_CHANNEL_NUM_0,
                            ETHERNET_DMA_CH0_STATUS_NIS | ETHERNET_DMA_CH0_STATUS_RI);
        }
    
        for(i = 0U;i < Ethernet_device_struct.initConfig.numChannels;i++)
         {
             Ethernet_enableRxDMAReception(
                   Ethernet_device_struct.baseAddresses.enet_base,
                   i);
         }
        Ethernet_setMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
        Ethernet_setMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_TE);
    }
    
    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_getPacketBuffer;
        pInitCfg->pfcbFreePacket = &Ethernet_releaseTxPacketBufferCustom;
    
        //
        //Assign the Buffer to be used by the Low level driver for receiving
        //Packets. This should be accessible by the Ethernet DMA
        //
        pInitCfg->rxBuffer = Ethernet_rxBuffer;
    
        //
        // 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;
        //
        //Do global Interrupt Enable
        //
        (void)Interrupt_enableInProcessor();
    
        //
        //Assign default ISRs
        //
        Interrupt_registerHandler(INT_EMAC_TX0, Ethernet_transmitISR);
        Interrupt_registerHandler(INT_EMAC_RX0, Ethernet_receiveISR);
        Interrupt_registerHandler(INT_EMAC, Ethernet_genericISRCustom);
    
        //
        //Enable the default interrupt handlers
        //
        Interrupt_enable(INT_EMAC_TX0);
        Interrupt_enable(INT_EMAC_RX0);
        Interrupt_enable(INT_EMAC);
    
        //
        // 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_clearMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
        Ethernet_setMACConfiguration(Ethernet_device_struct.baseAddresses.enet_base,ETHERNET_MAC_CONFIGURATION_RE);
    }
    
    
    //*****************************************************************************
    //
    // This example demonstrates the use of the Ethernet Controller.
    //
    //*****************************************************************************
    #define shuzulen 8
    struct pbuf *p;
    struct udp_pcb *UdpPcb;
    struct ip4_addr ipaddr;
    uint8_t UDPData[shuzulen]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
    uint8_t cnt = 0;
    
    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 = ADDRESS;
        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-00-80)
        // 0x00 MACOCT3 MACOCT2 MACOCT1
        ulUser0 = 0x00F263A8;
    
        // 0x00 MACOCT6 MACOCT5 MACOCT4
        ulUser1 = 0x00800000;
    
        //
        // 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);
    
        //
        // Initialize ethernet module.
        //
        Ethernet_init(pucMACArray);
    
        //
        // Initialze the lwIP library, using DHCP.
        //
        lwIPInit(0, pucMACArray, IPAddr, NetMask, GWAddr, IPADDR_USE_STATIC);
    
        //
        // Initialize the HTTP webserver daemon.
        //
        httpd_init();
    
        IP4_ADDR(&ipaddr,192,168,0,5); //Server IP
        UdpPcb = udp_new();
        udp_bind(UdpPcb,IP_ADDR_ANY,6600); //DSP Port# is 6600
        udp_connect(UdpPcb,&ipaddr,5530); //PC Port# is 6600
    
    
    
    
        //
        // Loop forever. All the work is done in interrupt handlers.
        //
        while(1)
        {
    
            p = pbuf_alloc(PBUF_TRANSPORT,shuzulen,PBUF_RAM);
            //UDPData[shuzulen]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}
    
            for(cnt = 0; cnt<shuzulen; cnt++)
                UDPData[cnt]++;
            p->payload=(void*)UDPData;
            //DEVICE_DELAY_US(2000);
            p->tot_len = shuzulen;        //17        // long_UDP_complete+4;
            p->len = shuzulen;            //17       // long_UDP_complete+4;
            udp_send(UdpPcb, p);
            SysCtl_delay(60000000);//aprox 1 sec
    
            if (p!= NULL)    pbuf_free(p);
            //udp_recv(UdpPcb, &udp_rx_callback, (void*) 1);
    
    
    
        }
    }
    
    //*****************************************************************************
    //
    // 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)
    {
    
    }
    

    Hello

    Please take a look at my code. In this code, the main changes that I made are in or outside the main function. I also made some changes in other files to enable UDP. I modified this code according to some posts in the forum and now I can successfully ping and send message to PC and my PC can receive it. Can you instruct me how to modify this to receive data from PC?

    It looks like udp_rx_callback or udp_rx function can be used but I have no idea how to use them in my code.

    Thanks

    Yifu

  • Yifu,

    udp_recv is used to register the callback function, In the example provided with C2000Ware, udp_rx_callback is the callback function. Whenever you send the messages from the SocketTest software from the client , this function will be invoked.  Received data is stored in ‘buf_rx’ array and this callback function handles the received data from the SocketTest/Packet Sender software.

    Best Regards

    Siddharth

  • Hello Siddharth

    Thanks for your help so far. I suucessfully realized communication(send and receive) between PC and 28388D and now I am working on IPC part. I am wondering if I can send data from CM to CPU1 and send data from CPU1 to CM. I am a little confused when reading the TRM IPC part. It looks like there are some R/W access limits when using IPC. Can you help take a look if I can realize my thoughts with these IPCs? I attached my  simplied system block diagram here.

    Now I finished signal processing part and commucation between PC and C core. I am working on IPC parts. 

    Thanks

    Yifu

  • Yifu.

    For IPC, recommend to refer this doc 

    https://software-dl.ti.com/C2000/docs/C2000_Multicore_Development_User_Guide/ipc_communication.html#

    Also, you can refer the examples provided for IPC in C2000Ware.

    Best Regards

    Siddharth