Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

Modbus TCP using lwIP stack

Hi,

I'm working on a project in which I'm trying to establish a connection between a PLC and a H52C1 Concerto Experimenter Kit .

It seems that the problem is that the program doesn't enter in the MB_recv function.

I can't figure out why.

Any ideas?

Thanks in advance.

here is the code I'm using :

int main(void)
{
    unsigned long ulUser0, ulUser1;
    unsigned char pucMACArray[8];

    // Disable Protection
    HWREG(SYSCTL_MWRALLOW) =  0xA5A5A5A5;


    // Sets up PLL, M3 running at 100MHz and C28 running at 100MHz
    SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xA) |
                         SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_1 |
                         SYSCTL_XCLKDIV_4);	

    //
    // Setup the pinout for this board
    //
    PinoutSet();

    // Enable clock supply for LED GPIOs
        SysCtlPeripheralEnable(LED_0_PERIPH);
        SysCtlPeripheralEnable(LED_1_PERIPH);
    //
    // Initialize the UART.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTStdioInit(0);
    UARTprintf("\033[2JEthernet with lwIP\n");
    
    //
    // Enable the peripherals required by the Ethernet module
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);

	//
    // Disable clock supply for the watchdog modules
    //
    SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
    SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);
    
    // Copy time critical code and Flash setup code to RAM
	// This includes the following ISR functions: InitFlash();
	// The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
	// symbols are created by the linker. Refer to the device .cmd file.
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
	
	// Call Flash Initialization to setup flash waitstates
	// This function must reside in RAM
    FlashInit(); 
       
	// Enable and Reset the Ethernet Controller.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);

    //
    // Configure SysTick for a periodic interrupt.
    //
    SysTickPeriodSet(SysCtlClockGet(SYSTEM_CLOCK_SPEED) / SYSTICKHZ);
    SysTickEnable();
    IntRegister(FAULT_SYSTICK, SysTickIntHandler);
    SysTickIntEnable();

    //
    // Enable processor interrupts.
    //    
    IntMasterEnable();
        
    // 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;

    
    if((ulUser0 == 0xffffffff) || (ulUser1 == 0xffffffff))
    {
        //
        // We should never get here.  This is an error if the MAC address has
        // not been programmed into the device.  Exit the program.
        //
        UARTprintf("MAC Address Not Programmed!\n");
        while(1)
        {
        }
    }

    //
    // 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);

    //
    // Initialze the lwIP library, using STATIC IP.
    //
    lwIPInit(pucMACArray, STATIC_IP_ADDRESS, STATIC_NETMASK, STATIC_GATEWAY, IPADDR_USE_STATIC);

    //
    // Setup the device locator service.
    //
    LocatorInit();
    LocatorMACAddrSet(pucMACArray);
    LocatorAppTitleSet("EK-LM3S9B92 enet_lwip");

    //
    // Indicate that DHCP has started.
    //
    UARTprintf("Waiting for IP... ");

    MB_init();
    //
    // Loop forever.  All the work is done in interrupt handlers.
    //
    while(1)
    {
    }
}


typedef struct MBAPHeader
{
	union
	{
		struct
		{
		unsigned short	    TransactionIdentifier;
		unsigned short	    ProtocolIdentifier;
		unsigned short      Length;
		unsigned short      UnitIdentifier;
		unsigned short      FunctionCode;
		unsigned short      Bytecount;
		unsigned int        Data1;
		}Data;
		struct
		{
		unsigned int A;
		unsigned int B;
		unsigned int C;
		unsigned int D;
		}DataB;
		struct
		{
		char Wordtosend[16];
		}Datatosend;
	};
} MBAPHeader;

static void MB_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p)
{
	char *receiveddata;
	static MBAPHeader test1;
	test1.Data.TransactionIdentifier=1;
	test1.Data.ProtocolIdentifier=0;
	test1.Data.Length=5;
	test1.Data.UnitIdentifier=2;
	test1.Data.FunctionCode=4;
	test1.Data.Bytecount=2;
	test1.Data.Data1=0x000A;
	/* If we got a NULL pbuf in p, the remote end has closed
	the connection. */
	UARTprintf("\nMBrecv\n");
	if(p != 0)
	{
	/* The payload pointer in the pbuf contains the data
	in the TCP segment. */
	receiveddata = p->payload;

	tcp_write(pcb, test1.Datatosend.Wordtosend, sizeof(test1.Datatosend.Wordtosend)+1, 0);
        tcp_output(pcb);
	/* Free the pbuf. */
	pbuf_free(p);
	}/* Close the connection. */
	tcp_close(pcb);
}

/* This is the callback function that is called when
a connection has been accepted. */
static void MB_accept(void *arg, struct tcp_pcb *pcb)
{
	/* Set up the function MB_recv() to be called when data
	arrives. */
	UARTprintf("\nMBaccept\n");
	tcp_recv(pcb, MB_recv);
}

void MB_init (void)
{
	LWIP_DEBUGF(MB_DEBUG, ("MB_init\n"));
	struct tcp_pcb *pcb;
	/* Create a new TCP PCB. */
	pcb = tcp_new();
	/* Bind the PCB to TCP port 502. */
	tcp_bind(pcb, IP_ADDR_ANY, 502);
	/* Change TCP state to LISTEN. */
	pcb = tcp_listen(pcb);
	/* Set up MB_accept() function to be called
	when a new connection arrives. */
	tcp_accept(pcb, MB_accept);
	//tcp_accepted();
	UARTprintf("\nMBinit\n");
}