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.

MSP432E401Y: Configuring the Ethernet Controller

Part Number: MSP432E401Y
Other Parts Discussed in Thread: MSP-EXP432E401Y

Hi,

We are working with the MSP-EXP432E401Y development board and CCS because we are interested in using the MSP432E401Y microcontroller in our product line. So far I have been looking at the out-of-box example. Our application is written in assembly so the end product will be primarily assembly code based.

I'd like to get information on how to configure and use the Ethernet Controller. The Ethernet requirements for our applications are very simple. It is a server. It receives a command (about 30 bytes) and sends a response (about 100 bytes) every few seconds.

What I'd like to find out is how to set the ip address (IPv4), gateway, subnet mask, & port# and any other parameters that will need to be set for my application to work properly. Then I'd like to know what bit to read to see when incoming data is available, and where to get the data that came in. And finally I'd like to know where I should put any outgoing bytes that will be sent in response.

Thank you so much for your answer,
Brad McMillan

  • Hi Brad,

    The most bare bones example we will have for setting up the ethernet controller would be the lwIP example that you can find in resource explorer:

    https://dev.ti.com/tirex/explore/node?node=AAHyKiGer9-hMcoEDUONLg__J4.hfJy__LATEST 

    This should have some simple primitives for setting up the IP address and other associated parameters.

    BR,
    Leo 

  • Hello Leo,

    Thank you so much for your response. I was able to download and successfully run 2 of the examples; ethernet-based_io_control and ethernet_with_lwIP. However, my applications differ from these examples in important ways.

    Our products operate in isolated networks. Each device in the network is permanently assigned an IP address and a port# (and sometimes a gateway address and subnet mask).

    In contrast, the ethernet examples use DHCP to obtain the ip address, and the ip address is sent out the serial port so it can be entered in a browser to complete the connection. The ip address that I received from the board was 169.254.79.187, (A9 FE 4F BB hex). I looked at the block of memory that contains the parameters for the Ethernet controller at 0x400EC000 and I didn't see anything that was even close to that number so I still don't know where I should enter an ip address for the microcontroller.

    There's one other thing that really puzzles me. I read through the Ethernet Controller chapter in the MSP432E4 Technical Reference Manual (slau723a) and I didn't see ip address, gateway, subnet mask, or port number even mentioned. In fact, when I searched for them they weren't mentioned anywhere in the manual at all.

    Thank you in advance to anyone who can clarify any of these issues for me.

    Regards,
    Brad McMillan

  • Hi Brad,

    The IP address is specific to the Internet Protocol stack software that runs on top of the MAC(Media Access Controller) layer.  You won't see any mention of this in the technical reference because this address is typically set in the ip stack software.  You should be able to disable DHCP and provide a static IP address in the LWIP code.  LWIP should have the MAC address of your hardware to bind to. 

    I found the following lwip wiki which shows how to bind a static IP address in lwip(let me know if this helps):

    https://lwip.fandom.com/wiki/IPv4 

    BR,

    Leo 

  • Hi Leo,

    I've been looking at the ethernet_with_lwIP example to see if I can disable DHCP and provide my own static IP address and I'm not having any luck.

    It looks like the IP address is picked up at line 144 of enet_lwip.c ( ui32NewIPAddress = lwIPLocalIPAddrGet(); ). If I go into lwIPLocalIPAddrGet() it's just a function that returns a valid IP address whenever g_bLinkActive is non-zero so it looks like the IP address is being set by some other code that is being run in the background.

    Do you know how to disable DHCP? That might be what is causing the IP address to be set in the background.

    It's also not clear to me how to bind a static IP address in lwip. I looked at the wiki reference and didn't see anything that said how to do that. The link went to a single page but at the top said 92 pages so maybe I need to learn how to go to the other 90+ pages to get the information I need.

    Thank you for any information you can provide to help me move forward.

    Brad McMillan

  • Hi Brad,

    If DHCP fails, lwip should use autoip. AutoIP will randomly generate an IP address within a specified range and then check to see if there is a conflict on the local network.  I would recommend that you look at the autoip code(located in the core/ipv4 directory).  One simple solution would be to insert your own static IP address to bypass the randomly generated IP address from auto IP.

    BR,
    Leo

  • Brad McMillan said:
    It's also not clear to me how to bind a static IP address in lwip.

    Looking at the main function in the enet_lwip.c source file from importing the ethernet_with_lwip_MSP_EXP432E401Y_nortos_ccs example from simplelink_msp432e4_sdk_4_20_00_12 shows the following function call which is selecting to use DHCP:

        //
        // Initialize the lwIP library, using DHCP.
        //
        lwIPInit(g_ui32SysClock, pui8MACArray, 0, 0, 0, IPADDR_USE_DHCP);

    To change to use a static IP address think you need to:

    1. Change the 6th parameter to IPADDR_USE_STATIC.
    2. Set the 3rd parameter to the static IP address to be used.
    3. Set the 4th parameter to the network mark to be used.
    4. Set the 5th parameter to the default gateway to be used.

    There is the ipaddr_addr() function which can convert the IP4 ASCII internet address into the uint32_t address parameters passed to lwIPInit().

    I found this by browsing the example code, haven't yet attempted to set a static IP address.

  • Hello Leo and Chester,

    I'm making some progress, but it's not quite working yet.

    The IP address that was picked by DHCP was 169.254.79.187 (0xBB4FFEA9), and everything worked fine. Then I changed to autoip with the command:

    lwIPInit(g_ui32SysClock, pui8MACArray, 0, 0, 0, IPADDR_USE_AUTOIP);

    and that worked, too, with the same ip address as with DHCP. I tried using debug to go through autoip.c so I could see where I could change to another ip address, but it wasn't clear at all how to do that. I also tried to step through the code to see if there was someplace where I could set my own ip address, but it wasn't given a value until I released debug so it looks like it might be getting set in an interrupt routine somewhere.

    Then I tried entering a static address directly:

    lwIPInit(g_ui32SysClock, pui8MACArray, 0xBB4FFEA9, 0x00FFFFFF, 0xFE4FFEA9, IPADDR_USE_STATIC);

    and that didn't work. It got hung up at "Waiting for IP address", so it looks like the static ip address in the third parameter was never used.

    Thank you in advance for any suggested next steps,

    Brad McMillan

  • Brad McMillan said:
    Thank you in advance for any suggested next steps,

    I had another look, with the following steps.

    1. Import ethernet_with_lwip_MSP_EXP432E401Y_nortos_ccs from simplelink_msp432e4_sdk_4_20_00_12

    Uses DHCP which works:

    Ethernet lwIP example
    
    Waiting for IP.
    Waiting for link.
    Waiting for IP address.
    IP Address: 192.168.0.5
    Open a browser and enter the IP address.

    2. In the main() function in enet_lwip.c change from:

        //
        // Initialize the lwIP library, using DHCP.
        //
        lwIPInit(g_ui32SysClock, pui8MACArray, 0, 0, 0, IPADDR_USE_DHCP);

    To:

        //
        // Initialize the lwIP library, using a static IP address.
        //
        uint32_t ui32IPAddr = htonl(ipaddr_addr ("192.168.0.101"));
        uint32_t ui32NetMask = htonl (ipaddr_addr ("255.255.255.0"));
        uint32_t ui32GWAddr = htonl (ipaddr_addr ("192.168.0.1"));
        lwIPInit(g_ui32SysClock, pui8MACArray, ui32IPAddr, ui32NetMask, ui32GWAddr, IPADDR_USE_STATIC);

    Where the IP address range was chosen to match my network, and use a static IP address outside of the range allocated by the DHCP server.

    Following this change the example doesn't successfully initialise. The serial console displays the following and there are no Ethernet packets transmitted:

    Ethernet lwIP example
    
    Waiting for IP.
    Waiting for link.
    Waiting for IP address.

    3. In the lwipopts.h file change from:

    #define LWIP_DHCP                       1           // default is 0
    #define LWIP_AUTOIP                     1           // default is 0

    To:

    #define LWIP_DHCP                       0           // default is 0
    #define LWIP_AUTOIP                     0           // default is 0

    The initial attempt to disable DHCP failed with the compile errors:

    Building file: "/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/utils/lwiplib.c"
    Invoking: Arm Compiler
    "/home/mr_halfword/ti/ccs1020/ccs/tools/compiler/ti-cgt-arm_20.2.4.LTS/bin/armcl" -mv7M4 --code_state=16 --float_support=FPv4SPD16 -me --include_path="/home/mr_halfword/workspace_v10/ethernet_with_lwip_MSP_EXP432E401Y_nortos_ccs" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/include" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/include/utils" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/src/include" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/CMSIS/Include" --include_path="/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/ti/net/bsd" --include_path="/home/mr_halfword/ti/ccs1020/ccs/tools/compiler/ti-cgt-arm_20.2.4.LTS/include" --advice:power=none --define=DeviceFamily_MSP432E4 --define=__MSP432E401Y__ -g --diag_warning=225 --diag_warning=255 --diag_wrap=off --display_error_number --gen_func_subsections=on --preproc_with_compile --preproc_dependency="lwip/ports/msp432e4/utils/lwiplib.d_raw" --obj_directory="lwip/ports/msp432e4/utils"  "/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/utils/lwiplib.c"
     
    >> Compilation failure
    lwip/ports/msp432e4/utils/subdir_rules.mk:14: recipe for target 'lwip/ports/msp432e4/utils/lwiplib.obj' failed
    "/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/utils/lwiplib.c", line 448: error #20: identifier "ARP_TMR_INTERVAL" is undefined
    "/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/utils/lwiplib.c", line 451: warning #225-D: function "etharp_tmr" declared implicitly
    1 error detected in the compilation of "/home/mr_halfword/ti/simplelink_msp432e4_sdk_4_20_00_12/source/third_party/lwip/ports/msp432e4/utils/lwiplib.c".
    gmake: *** [lwip/ports/msp432e4/utils/lwiplib.obj] Error 1
    gmake: Target 'all' not remade because of errors.

    4. To resolve the above compile errors added the following in the "DHCP options" section of lwipopts.h:

    #if !LWIP_DHCP
    // @todo These values are taken from lwip/src/include/lwip/etharp.h and are required to get a clean build when compiling with
    //       DHCP disabled when using a static IP address.
    //       Haven't been able to determine how to do this by changing other options in this include file.
    void etharp_tmr(void);
    
    /** 1 seconds period */
    #define ARP_TMR_INTERVAL 1000
    
    #endif

    Following this change the serial console now indicates the static IP address is being used:

    Ethernet lwIP example
    
    Waiting for IP.
    IP Address: 192.168.0.101
    Open a browser and enter the IP address.

    The EXP432E401Y launchpad is responding to pings on the static IP address, and a browser can view the webpage in the example at the static IP address.

    I have attached the example which has been modified to use a static IP address. ethernet_with_lwip_MSP_EXP432E401Y_nortos_ccs.zip

  • Hi Chester,

    It works! Thank you so much. That is a big step in getting my application to work.

    My application is much simpler than a webpage so I'm hoping there is an easy answer to the next thing I need to accomplish. Our products are used in isolated networks where they receive a command a few bytes long and then send a response, also a few bytes long. One popular protocol, DNP 3.0, for example, has a reset command 10 bytes long:

    05 64 05 C9 C9 00 10 27 5E 04

    with a typical response it would get, also 10 bytes long:

    05 64 05 0B 10 27 C9 00 AE 24

    It looks like there is a similar function in the "ethernet_with_lwip" example where you press one of the buttons to send a command to the EXP432E401Y launchpad and it responds with text and/or graphics to be displayed by the browser.

    Do you know where those commands are being received and the responses sent out? I don't see that functionality in the main "while(1)" infinite loop in enet_lwip.c.

    I also assume that I will need to disable transmission of the webpage when the connection is initially established.

    I really appreciate your help in getting the static ip address working and hope this has an easy answer.

    Thanks,
    Brad McMillan

  • Brad McMillan said:
    Do you know where those commands are being received and the responses sent out? I don't see that functionality in the main "while(1)" infinite loop in enet_lwip.c.

    From a quick look at the ethernet_with_lwip they are all handled by files served by the webpage.

    The simplelink_msp432e4_sdk_4_20_00_12/examples/nortos/MSP_EXP432E401Y/lwip/ethernet_with_lwip/fs directory contains the source of the files for the webpage. The javascript.js file has functions which load pages based upon button presses on the webpage.

    The contents of the above directory are embedded into look-up arrays in the enet_fsdata.h file, and enet_fs.c has functions which perform file system processing for the LwIP Web Server application using the contents of enet_fsdata.h.

    Brad McMillan said:
    Our products are used in isolated networks where they receive a command a few bytes long and then send a response, also a few bytes long. One popular protocol, DNP 3.0, for example, has a reset command 10 bytes long

    What Ethernet based network protocol are you planning to encapsulate DNP 3.0 with?

    E.g. TCP/IP, UDP/IP or something else?

  • Hi Chester,

    I found the files you referenced. It's probably obvious that I don't have much experience implementing Ethernet at this level. Prior to this we just used an external Ethernet module. All that was required was to pass the ip address, subnet mask, etc to the module during startup and then receive commands and send responses over an SPI port. No details required.

    So it looks like the launchpad is using Javascript and possibly other high level functionality to service the webpage. I'm 99.9% sure that we use TCP/IP for our applications. BTW, we have Ethernet functionality built into the configuration software for our products. We use it for testing.

    Is it possible to get the "ethernet_with_lwip" example to use TCP/IP so we can receive and send the short DNP bursts successfully between the launchpad and the configuration software?

    Thank you for your answer,
    Brad

  • Brad McMillan said:
    Is it possible to get the "ethernet_with_lwip" example to use TCP/IP so we can receive and send the short DNP bursts successfully between the launchpad and the configuration software?

    The "ethernet_with_lwip" example code doesn't directly perform TCP/IP communication by calling LwIP functions, but instead uses the LwIP HTTP server in lwip/src/apps/httpd/httpd.c

    In the SimpleLink MSP432E SDK Examples -> Development Tools -> MSP432E401Y LaunchPad -> LwIP -> ethernet_weather -> No RTOS -> CCS Compiler -> ethernet_weather shows code in the example which performs TCP/IP communication - see the eth_client.c source file.

    Will the launchpad be a TCP client or server?

    As well as LwIP which is designed to be used without an OS, the SimpleLink MSP432E SDK also supports the TI Network Services which can be used with TI-RTOS or FreeRTOS. Is there any benefit of your application using an OS?

  • I installed the ethernet_weather example and it appears to run ok, but I can't connect to it with a browser. The terminal says the IP address should be 169.254.79.187 (though even that gets flaky sometimes with it alternating between 255.255.255.255 and 0.0.0.0), but when I point the browser to that address it says that the ip address can't be found. I even tried putting the Ethernet adapter setting in the same subnet with no luck.

    Then I looked to see if I could modify it to use a static ip address similar to the changes you made to the ethernet_with_lwip example, but it looks like the ethernet_weather example has a different way of handling this so it was not clear to me how to implement a static ip address for it.

    I reloaded the ethernet_with_lwip example and it still works fine, so I know the connections are all ok.

    WRT the TCP client or server question, our existing product has web pages that can be displayed from the Ethernet port so I'm assuming that means it's a server and the launchpad should be a server also.

    Our end products will be written in assembly code so we won't be using an OS at all.

    Thanks again.

  • Hi Brad,

    If you have to go to a non-RTOS solution, I would propose that you stay with LWIP and look at some example http servers that are available for this like:

    https://www.nongnu.org/lwip/2_0_x/group__httpd.html 

    BR,

    Leo

  • Hi Leo,

    We left LWIP because it didn't handle TCP/IP.  Will the example http server at nongnu handle TCP/IP? 

    I hope that's not a silly question.  I know very little about Ethernet technology. 

    Thanks,

    Brad 

  • Hi Brad,

    LWIP supports TCP/IP.  HTTP involves get and put commands which are sent through the underlying tcp/ip stack. The tcp.c and ip.c source files can be found in the core directory. The httpd source is in the apps directory. 

    https://dev.ti.com/tirex/explore/node?node=AFTdHS0U2PiFpcjBcOiSeg__J4.hfJy__LATEST 

    BR,
    Leo 

  • Hi Leo,

    I'm starting to understand some of the issues here but I still have a ways to go. When Chester Gillon suggested looking at the ethernet_weather example I mistakenly thought he meant to use that example, but what he really meant was to look at the eth_client.c source file to see how to send and receive data. I should still be using Lwip.

    As I mentioned earlier in this thread, all I'm trying to do is have the msp432 receive these 10 bytes:

    05 64 05 C9 C9 00 10 27 5E 04

    and respond with these 10 bytes:

    05 64 05 0B 10 27 C9 00 AE 24

    The boards we are looking to replace with the msp432 also have webpages that can be displayed with a browser so that tells me the msp432 should be a server, but other than that I'm not 100% sure.

    You have both suggested that I use httpd.c and I was able to find it in lwip > src > apps. I was also able to find tcp.c and ip.c in lwip > src > core where you said they would be. But, I don't see the get and put commands you mentioned in any of these files so I still don't know how to read the incoming string and how to send the outgoing response.

    I also looked at the httpd reference that is at www.nongnu.org and it's not clear to me how to read the files and/or if I should be downloading them to the lwip example or not.

    Thank you in advance for any clarification you can provide,

    Brad

  • Brad McMillan said:
    The boards we are looking to replace with the msp432 also have webpages that can be displayed with a browser so that tells me the msp432 should be a server, but other than that I'm not 100% sure.

    Have you got a link to the documentation for the existing boards, to better understand what services the webpages provide?

    And a description of what additional functionality, if any, the MSP432 product needs to provide.

  • Hi Chester,

    Our application is a Remote Terminal Unit (RTU) used to monitor and control different variables for industrial applications. For the Ethernet interface we use a design based on a module from Zilog. Documentation for the module, and the software for programming it can be found at

    www.zilog.com/index.php

    The document that describes the module is PS0193 (eZ80F91 Module Product Specification) and the document that describes the software is RM0041 (Zilog TCP/IP Software Suite Programmer's Guide).

    But, it's probably not necessary to look at those documents. I did a little more digging and it looks like the MSP432 should be configured to be a client after all. RTUs like ours are part of SCADA (Supervisory Control and Data Acquisition) systems. I did a google search for SCADA Server and SCADA Client and it looks like the RTU should be configured as a client. Then I looked at the software we upload to the module and it looks like it is being configured to be a client there, too.

    WRT your earlier suggestion that I look at the eth_client.c source file in the ethernet_weather example, I'm assuming you mean I should try to bring some of the functions from that file (TCPReceive, TCPSent, EthClientSend, etc.) into the infinite loop at the bottom of main() in the enet_lwip.c file of the ethernet_with_lwip example. Is that correct? Please let me know if I'm going in the wrong direction.

    Thank you in advance for any further clarification.

  • Brad McMillan said:
    I'm assuming you mean I should try to bring some of the functions from that file (TCPReceive, TCPSent, EthClientSend, etc.) into the infinite loop at the bottom of main() in the enet_lwip.c file of the ethernet_with_lwip example. Is that correct?

    Yes. My answer was a bit vague since not sure exactly what TCP/IP communication is needed for a RTU configured as a client.

    I did try and search how the DNP protocol is encapsulated over TCP/IP but couldn't find a definition.

  • Hi Chester,

    My understanding is that there is nothing unique about RTU's or the DNP protocol wrt TCP/IP communication. All I need to do is receive a few bytes of data from the server and respond with another few bytes of data. Very simple.

    I looked at the TCPReceive() function in eth_client.c of the ethernet_weather example and it looks like this is the code that picks up the incoming data:

      if(g_sEnet.ulRequest == WEATHER_CURRENT)
      {
         i32Items = JSONParseCurrent(0, g_sWeather.psWeatherReport, psBuf);                                       // Read items from buffer
         if(i32Items > 0)                                                                                                                                   // Make sure items found
         {
              if(g_sWeather.pfnEvent)
              {
                    g_sWeather.pfnEvent(ETH_EVENT_RECEIVE, (void *)g_sWeather.psWeatherReport, 0);
                    g_sEnet.eState = iEthIdle;                                                                                                       // Clear function
               }
          }
          else if(i32Items < 0)
          {
                 if(g_sWeather.pfnEvent)
                 {
                      g_sWeather.pfnEvent(ETH_EVENT_INVALID_REQ, 0, 0);                                                  // Invalid request
                      g_sEnet.eState = iEthIdle;                                                                                                     // Clear function
                 }
           }
     }

    It looks to me that the function is looking for data that has been received elsewhere and that the data needs to have a predefined structure. The requirement for the RTU is much simpler than that. Right now, I'm just trying to receive a few bytes of data from the server and I'm using the ethernet_with_lwip example.

    I just need to know how to:

    1. Configure the MSP432 as a client.
    2. Ask if a byte or a string of bytes has been received.
    3. Pick up the data that has been received.

    Thank you in advance for any clarification you can provide,

    Brad

  • Hi,

    I went back to the ethernet_weather example because it is already configured to be a client and I think it was successful in connecting to the server I have running on another computer. But, I still haven't been successful in getting data that is being sent from the server to the MSP432.

    First, I programmed it to use a static ip address (192.168.1.101) with the same modification Chester used for the ethernet_with_lwip example above. It looks like that worked because I get the following when I run the program:

    Ethernet Weather Example

    IP: 192.168.1.101

    Type 'help' for help.

    Then I pointed the server on another computer to the same ip address and when I send a string of data to the MSP432 one of the leds lights up so that tells me it is a good connection and sending data is successful.

    However, I still don't know how to pickup the data that is being received by the MSP432. I looked at the infinite loop at the bottom of main() and it is running because I can stop it with a breakpoint, but it thinks there is no connection because g_iState = STATE_NOT_CONNECTED.

    Can anyone tell me where I can find the string of data that was sent to the MSP432?

    Thank you.

  • Hi Brad,

    If you want http client code, you would need httpc built in your project - (httpd is for an http server implementation).  The example projects you're looking at don't include httpc in the apps directory(which is where I would expect to find this code).  This is higher level code which you could merge into this code base if you tapped into the right release of lwip in the open source community. 

    Do you have experience with open source integration?

    BR,
    Leo

  • Hi Leo,

    Thank you for your response. I've been working with the ethernet_weather example because it says it is a client implementation and I can see some changes in the EMAC registers whenever I send a string of bytes to it from a server pointed to the same address. But, that is as far as I've been able to go. I still don't know what indicates that some data has arrived at the MSP432 or where the incoming data is located in memory.

    I'm very interested in looking at a release of lwip that would be more successful in implementing an ethernet client, but I don't have any experience with open source integration. I'm hoping you will be able to help me with:

    1. Identifying which release of lwip I should choose, and
    2. How to download and integrate it into a project so I can use it in the MSP432E401Y with ccs.

    Thank you in advance,
    Brad

  • Hi Brad,

    I did some digging around and found this thread which should be a simpler way forward. Basically, you would be contructing a TCP Get packet and send that packet to your server. The http server would respond and this thread explains where you would expect to find that data. Please note that if you are testing this with a PC, you would need to be running an http server on that PC. You could download an open source http server like Apache to on computer - and then use another computer to open a page served by that computer first. Once this is working, you should be able to do what is described at this link to send a Get command to the computer with the http server and retrieve the results:

    https://stackoverflow.com/questions/26192758/how-can-i-send-a-simple-http-request-with-a-lwip-stack

    BR,
    Leo