Hi at all,
I try to extend an enetet_lwip example with IPC functionality.
I start with ent lwip example Project from the ControlSuite \v201\F28M35x_examples_Master\enet_lwip and merge this together withe the v201\F28M35x_examples_Dual\ctom_ipcdrivers\m3 example.
The C28 runs the default example Code.
If I disabled the IPC-functionality or better to say, If the CtoMIPC1IntHandler and CtoMIPC2IntHandler not fire, the Website is available. But even one of these Handler fire ones, the Website isn't available anymore. But the C2000 is reachable by a ping!
It seams to me that the CtoMIPCIntHandler block the EthernetHandler.
Can someone give me a hint to solve this problem?
This is my modified Sourecode
//########################################################################### // FILE: enet_lwip.c // TITLE: Sample WebServer Application using lwIP. //########################################################################### // $TI Release: F28M35x Support Library v201 $ // $Release Date: Fri Jun 7 10:51:13 CDT 2013 $ //########################################################################### #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_ethernet.h" #include "inc/hw_gpio.h" //--begin #include "inc/hw_ram.h" #include "inc/hw_ipc.h" //--end #include "board_drivers/set_pinout_f28m35x.h" #include "driverlib/ethernet.h" #include "driverlib/flash.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" //--begin #include "driverlib/cpu.h" #include "driverlib/ipc.h" #include "driverlib/ram.h" #include "driverlib/sysctl.h" //--end #include "utils/locator.h" #include "utils/lwiplib.h" #include "utils/uartstdio.h" //--begin #include "utils/ustdlib.h" //--end #include "httpserver_raw/httpd.h" #define WITH_IPC 1 int print1, print2; //***************************************************************************** // //! \addtogroup master_example_list //! <h1>Ethernet with lwIP (enet_lwip)</h1> //! //! This example application demonstrates the operation of the Concerto //! Ethernet controller using the lwIP TCP/IP Stack. DHCP is used to obtain //! an Ethernet address. If DHCP times out without obtaining an address, //! AutoIP will be used to obtain a link-local address. The address that is //! selected will be shown on the UART. //! //! Once an address has been obtained, a simple web server can be accessed //! through the network. The files served are located in the 'fs' directory. //! Instead of implementing a full file system, the included command-line //! application 'makefsfile.exe' is used to convert the 'fs' directory to the //! header file 'lmi-fsdata.h'. This file contains byte arrays for each file //! and is accessed using the functions in 'lmi_fs.c'. The header file must be //! re-generated after any changes to files in the 'fs' directory. //! //! For more information on 'makefsfile.exe' usage, run 'makefsfile.exe -?'. //! //! UART0, connected to the FTDI virtual COM port and running at 115,200, //! 8-N-1, is used to display messages from this application. //! //! 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 unsigned long RamfuncsLoadStart; extern unsigned long RamfuncsLoadSize; extern unsigned long RamfuncsRunStart; //***************************************************************************** // // Defines for setting up the system clock. // //***************************************************************************** #define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ) //***************************************************************************** // // A twirling line used to indicate that DHCP/AutoIP address acquisition is in // progress. // //***************************************************************************** static char g_pcTwirl[4] = { '\\', '|', '/', '-' }; //***************************************************************************** // // The index into the twirling line array of the next line orientation to be // printed. // //***************************************************************************** static unsigned long g_ulTwirlPos = 0; //***************************************************************************** // // The most recently assigned IP address. This is used to detect when the IP // address has changed (due to DHCP/AutoIP) so that the new address can be // printed. // //***************************************************************************** static unsigned long g_ulLastIPAddr = 0; //***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, unsigned long ulLine) { // Handle ASSERT conditions here } #endif //-- begin //***************************************************************************** // Definitions used in this example //***************************************************************************** #define M3_MTOC_PASSMSG 0x2007FFE8 // MTOC MSG RAM offsets for passing // addresses //***************************************************************************** // Function Prototypes //***************************************************************************** void Error(void); void FunctionCall(void); void FunctionCallParam(unsigned long ulParam); void CtoMIPC1IntHandler(void); void CtoMIPC2IntHandler(void); //***************************************************************************** // At least 1 volatile global tIpcController instance is required when using // IPC API Drivers. //***************************************************************************** volatile tIpcController g_sIpcController1; volatile tIpcController g_sIpcController2; //***************************************************************************** // Global variables used in this example to track errors //***************************************************************************** unsigned short ErrorFlag; volatile unsigned long FnCallStatus; //***************************************************************************** // Global variables used in this example to read/write data passed between // C28 and M3 //***************************************************************************** unsigned short usWWord16; unsigned long ulWWord32; unsigned short usMBuffer[256]; //--end //***************************************************************************** // // Required by lwIP library to support any host-related timer functions. // //***************************************************************************** void lwIPHostTimerHandler(void) { unsigned long ulIPAddress; // // Get the local IP address. // ulIPAddress = lwIPLocalIPAddrGet(); // // See if an IP address has been assigned. // if(ulIPAddress == 0) { // // Draw a spinning line to indicate that the IP address is being // discoverd. // UARTprintf("\b%c", g_pcTwirl[g_ulTwirlPos]); // // Update the index into the twirl. // g_ulTwirlPos = (g_ulTwirlPos + 1) & 3; } // // Check if IP address has changed, and display if it has. // else if(ulIPAddress != g_ulLastIPAddr) { // // Display the new IP address. // UARTprintf("\rIP: %d.%d.%d.%d \n", ulIPAddress & 0xff, (ulIPAddress >> 8) & 0xff, (ulIPAddress >> 16) & 0xff, (ulIPAddress >> 24) & 0xff); // // Save the new IP address. // g_ulLastIPAddr = ulIPAddress; // // Display the new network mask. // ulIPAddress = lwIPLocalNetMaskGet(); UARTprintf("Netmask: %d.%d.%d.%d\n", ulIPAddress & 0xff, (ulIPAddress >> 8) & 0xff, (ulIPAddress >> 16) & 0xff, (ulIPAddress >> 24) & 0xff); // // Display the new gateway address. // ulIPAddress = lwIPLocalGWAddrGet(); UARTprintf("Gateway: %d.%d.%d.%d\n", ulIPAddress & 0xff, (ulIPAddress >> 8) & 0xff, (ulIPAddress >> 16) & 0xff, (ulIPAddress >> 24) & 0xff); } } //***************************************************************************** // // The interrupt handler for the SysTick interrupt. // //***************************************************************************** void SysTickIntHandler(void) { // // Call the lwIP timer handler. // lwIPTimer(SYSTICKMS); } //***************************************************************************** // // This example demonstrates the use of the Ethernet Controller. // //***************************************************************************** int main(void) { unsigned long ulUser0, ulUser1; unsigned char pucMACArray[8]; #if WITH_IPC //--begin // Define Local Variables unsigned long *pulMsgRam; unsigned short counter; //-- end #endif // 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); #if WITH_IPC //--begin // Setup main clock tree for 75MHz - M3 and 150MHz - C28x //SysCtlClockConfigSet(SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 | SYSCTL_USE_PLL | // (SYSCTL_SPLLIMULT_M & 0x0F)); // Give M3 access to S0 SARAM RAMMReqSharedMemAccess (S0_ACCESS, SX_M3MASTER); // Initialize M3toC28 message RAM and Sx SARAM and wait until initialized HWREG(RAM_CONFIG_BASE + RAM_O_MSXRTESTINIT1) |= 0x1; while((HWREG(RAM_CONFIG_BASE + RAM_O_MSXRINITDONE1)&0x1) != 0x1) { } /* HWREG(RAM_CONFIG_BASE + RAM_O_MTOCCRTESTINIT1) |= 0x1; while((HWREG(RAM_CONFIG_BASE + RAM_O_MTOCRINITDONE)&0x1) != 0x1) { }*/ // Disable writes to protected registers. HWREG(SYSCTL_MWRALLOW) = 0; // Register M3 interrupt handlers IntRegister(INT_CTOMPIC1, CtoMIPC1IntHandler); IntRegister(INT_CTOMPIC2, CtoMIPC2IntHandler); //--end #endif // // Setup the pinout for this board // PinoutSet(); // // 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); #if WITH_IPC //--begin #ifdef _STANDALONE #ifdef _FLASH // Send boot command to allow the C28 application to begin execution IPCMtoCBootControlSystem(CBROM_MTOC_BOOTMODE_BOOT_FROM_FLASH); #else // Send boot command to allow the C28 application to begin execution IPCMtoCBootControlSystem(CBROM_MTOC_BOOTMODE_BOOT_FROM_RAM); #endif #endif //--end #endif // 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(); #if WITH_IPC //--begin // Initialize IPC Controllers IPCMInitialize (&g_sIpcController1, IPC_INT1, IPC_INT1); IPCMInitialize (&g_sIpcController2, IPC_INT2, IPC_INT2); //--end #endif // // Enable processor interrupts. // IntMasterEnable(); #if WITH_IPC //--begin // Enable the IPC interrupts. IntEnable(INT_CTOMPIC1); IntEnable(INT_CTOMPIC2); //--end #endif // 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 DHCP. //lwIPInit(pucMACArray, 0, 0, 0, IPADDR_USE_DHCP); //lwIPInit(pucMACArray, ip_addr.addr, net_mask.addr, gw_addr.addr ,IPADDR_USE_STATIC); lwIPInit(pucMACArray, inet_addr("22.0.168.192"),inet_addr("0.255.255.255"),inet_addr("1.0.168.192"),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... "); // // Initialize a sample httpd server. // httpd_init(); #if WITH_IPC UARTprintf("\n WITH IPC \n"); //--begin // Initialize all variables. ErrorFlag = 0; FnCallStatus = 0; usWWord16 = 0; ulWWord32 = 0; for (counter = 0; counter < 256; counter++) { usMBuffer[counter] = 0; } // Write addresses of variables where words should be written to pulMsgRam // array. // 0 = Address of 16-bit variable to write into. // 1 = Address of 32-bit variable to write into. // 2 = Address of buffer to block write into. // 3 = Address of FunctionCall() function to call. // 4 = Address of FunctionCallParam() function to call. // 5 = Address of 32-bit FnCallStatus variable to check function call // executed pulMsgRam = (void *)M3_MTOC_PASSMSG; pulMsgRam[0] = (unsigned long)&usWWord16; pulMsgRam[1] = (unsigned long)&ulWWord32; pulMsgRam[2] = (unsigned long)&usMBuffer[0]; pulMsgRam[3] = (unsigned long)&FunctionCall; pulMsgRam[4] = (unsigned long)&FunctionCallParam; pulMsgRam[5] = (unsigned long)&FnCallStatus; // Flag to C28 that the variables are ready in MSG RAM with MTOC IPC Flag 17 // HWREG(MTOCIPC_BASE + IPC_O_MTOCIPCSET) |= IPC_MTOCIPCSET_IPC17; //--end #endif // // Loop forever. All the work is done in interrupt handlers. // int i=0; while(1) { if (ErrorFlag == 1) { Error(); } if(print1 == 1) { UARTprintf("\n 1"); print1 = 0; } if (print2==1) { UARTprintf("\n 2"); print2 = 0; } if(i > 10000000){ UARTprintf("count\n"); i = 0; } i ++; } } // IPC Functions //***************************************************************************** // Function run by IPC_FUNC_CALL command //***************************************************************************** void FunctionCall (void) { FnCallStatus = 1; } void FunctionCallParam (unsigned long ulParam) { FnCallStatus = ulParam; } //***************************************************************************** // Function to Indicate an Error has Occurred (Invalid Command Received). //***************************************************************************** void Error(void) { // An error has occurred (invalid command received). Loop forever. for (;;) { UARTprintf("\n Error \n"); } } //***************************************************************************** // CtoM INT1 Interrupt Handler - Handles Data Word Reads/Writes //***************************************************************************** void CtoMIPC1IntHandler (void) { print1 = 1; tIpcMessage sMessage; // Continue processing messages as long as CtoM GetBuffer1 is full while (IpcGet (&g_sIpcController1, &sMessage, DISABLE_BLOCKING)!= STATUS_FAIL) { switch (sMessage.ulcommand) { case IPC_SET_BITS: IPCCtoMSetBits(&sMessage); break; case IPC_CLEAR_BITS: IPCCtoMClearBits(&sMessage); break; case IPC_DATA_WRITE: IPCCtoMDataWrite(&sMessage); break; case IPC_DATA_READ: IPCCtoMDataRead(&g_sIpcController1, &sMessage, ENABLE_BLOCKING); break; case IPC_FUNC_CALL: IPCCtoMFunctionCall(&sMessage); break; default: ErrorFlag = 1; break; } } HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC1; } //***************************************************************************** // CtoM INT2 Interrupt Handler - Handles Data Block Reads/Writes //***************************************************************************** void CtoMIPC2IntHandler (void) { print2 = 1; tIpcMessage sMessage; // Continue processing messages as long as CtoM GetBuffer2 is full while (IpcGet (&g_sIpcController2, &sMessage, DISABLE_BLOCKING)!= STATUS_FAIL) { switch (sMessage.ulcommand) { case IPC_SET_BITS_PROTECTED: IPCCtoMSetBits_Protected(&sMessage); // Processes // IPCCtoMReqMemAccess() // function break; case IPC_CLEAR_BITS_PROTECTED: IPCCtoMClearBits_Protected(&sMessage); // Processes // IPCCtoMReqMemAccess() // function break; case IPC_BLOCK_WRITE: IPCCtoMBlockWrite(&sMessage); break; case IPC_BLOCK_READ: IPCCtoMBlockRead(&sMessage); break; default: ErrorFlag = 1; break; } } HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC2; }