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.

LWIP with IPC in the Concerto leads to a Fault Interrupt loop.

Hi there

I was already using the uDMA with the Ethernet controller (I copy it from the enet_uip example) together with InterProcessorCommunication interrupts.

Nevertheless I am trying to improve by using lwIP (enet_lwip example) with IPC again (the uDMA is no used now).

LwIP works fine but when the IPC sends a INT_CTOMPIC2, the M3 goes to a infinite loop for faulty interrupts (startup_css.c). Just one interrupt is enough to generate this faulty interrupt.

Are the IPC interrupts (from C28 to M3) incompatible with LWIP? (at least as is carried out in the enet_lwip example).

Should I send the IPC interrupt to the uDMA? is this possible? In the uDMA documentation the IPC are not one of the interrupt sources.

Thanks in advance.

Dionisio

My hardware setup for the M3 is:

//########################################################################################
// FILE: Config_Hardware.c
// This code makes the setup of the M3 (Cortex)
//########################################################################################
#include "hw_gpio.h"
#include "hw_ints.h"
#include "hw_ipc.h"
#include "hw_memmap.h"
#include "hw_nvic.h"
#include "hw_ram.h"
#include "hw_sysctl.h"
#include "hw_types.h"
#include "hw_udma.h"
#include "udma.h"
#include "hw_ethernet.h"

#include "cpu.h"
#include "debug.h"
#include "gpio.h"
#include "interrupt.h"
#include "ipc.h"
#include "ram.h"
#include "sysctl.h"
#include "flash.h"
#include "uart.h"
#include "ustdlib.h"
#include "uartstdio.h"
#include "uart.h"
#include <string.h>
#include <stdio.h>
#include "timer.h"

#include "systick.h"
#include "ethernet.h"
#include "lwiplib.h"
#include "httpd.h"

#include "board_drivers/set_pinout_f28m35x.h"
#include "lwipopts.h"

#include "Extern_y_Defines.h"

//----------------------------------------------------------------------------------------
// These are defined by the linker (see device linker command file)
extern unsigned long RamfuncsLoadStart;
extern unsigned long RamfuncsRunStart;
extern unsigned long RamfuncsLoadSize;

void Hardware_M3 (void)
{
    int i=0;
    //unsigned long ulUser0, ulUser1;
    unsigned char pucMACArray[8];

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


    // Sets up PLL, M3 running at 75MHz and C28 running at 150MHz
    SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
                         SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 |
                         SYSCTL_XCLKDIV_4);

#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.
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);

    // Call Flash Initialization to setup flash waitstates
    // This function must reside in RAM
    FlashInit();
#endif


#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

    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    // Setup the pinout for this board
    PinoutSet(); // Cofigura Ethernet, USB(para PHY), UART y SD card
    // Initialize the UART.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTStdioInit(0);
    //UARTprintf("\033[2JEthernet with lwIP\n");
    UARTprintf("Ethernet with lwIP\n");

    // Enable the peripherals required by the Ethernet module
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
    // Enable all GPIOs: Cofigura Ethernet, USB(para PHY), UART y SD card
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);

        GPIOPinConfigureCoreSelect(GPIO_PORTA_BASE, 0xFF, GPIO_PIN_C_CORE_SELECT);// ePW1+ePWM2: 1111 1111: [C28, C28, C28, C28,  C28, C28, C28, C28]-> PWM2: 6-7, 8-9, 10-11; PWM1: 0-1, 2-3, 4-5
        GPIOPinConfigureCoreSelect(GPIO_PORTB_BASE, 0x1F, GPIO_PIN_C_CORE_SELECT);//  0001 1111: 0x0F [M3, M3, M3, C28, C28, C28, C28, C28]
        GPIOPinConfigureCoreSelect(GPIO_PORTC_BASE, 0x4F, GPIO_PIN_C_CORE_SELECT);// LED C28: [0100 XXXX]: 0x4F [M3, C28, M3, M3,  M3, M3, M3, M3]
        GPIOPinConfigureCoreSelect(GPIO_PORTD_BASE, 0xF0, GPIO_PIN_C_CORE_SELECT);// eQEP [C28 C28 C28 C28 M3 M3 M3 M3]
        GPIOPinConfigureCoreSelect(GPIO_PORTE_BASE, 0x0F, GPIO_PIN_C_CORE_SELECT);// M3 Ethernet + Serial port: 0xCF; [(0);(PE6_GPIO30:Ethernet)(PE5_GPIO29: U0TX);(PE4_GPIO28: U0RX); (1);(1);(1);(1)]= [M3, M3, M3, M3,  C28, C28, C28, C28]

/*        // Unlock the register to change the commit register value for Port B Pin 7
        // This disables the NMI functionality on the pin and allows other muxing
        // options to be used
        HWREG(GPIO_PORTB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
        // Write to commit register
        HWREG(GPIO_PORTB_BASE+GPIO_O_CR) |= 0x000000FF;
        // Delay before accessing to the bus
        for (i=0;i<20;i++){};
*/
        // LED6 para C28 (LED7 para ARM)
        GPIOPinConfigureCoreSelect(GPIO_PORTC_BASE, 0x4F, GPIO_PIN_C_CORE_SELECT);// LED C28: [0100 XXXX]: 0x4F [M3, C28, M3, M3,  M3, M3, M3, M3]
        // Set up LED7 pin
        GPIOPinTypeGPIOOutput(LED_1_BASE, LED_1_PIN);
        GPIOPinWrite(LED_1_BASE, LED_1_PIN, 0);


     // Disable clock supply for the watchdog modules
     SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
     SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);

    //***********************************************************************************
    // Configure ETHERNET.
    //***********************************************************************************
    // 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();

    //***********************************************************************************
    // INITIALIZE UIP, NETMASK, default Router, etc
    //***********************************************************************************

    UARTprintf("MAC: %x.%x.%x.%x.%x.%x\n",(ulUser1 >> 4) & 0xf,(ulUser1 >> 0) & 0xf,(ulUser1 >> 12) & 0xf,(ulUser1 >> 8) & 0xf,(ulUser1 >> 20) & 0xf, (ulUser1 >> 16) & 0xf);

    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)
        {
        }
    }

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

//------------------------------------------------------------------------------
#ifdef USE_STATIC_IP

    // HAY QUE AÑADIR CÓDIGO NUEVO PARA PROGRAMAR LA IP ESTÁTICA: [43.1.168.192]ORDEN INVERSO!!
    lwlP_IPAddr=(0xFF&DEFAULT_IPADDR0)<<24 | (0xFF&DEFAULT_IPADDR1)<<16 | (0xFF&DEFAULT_IPADDR2)<<8  | 0xFF&DEFAULT_IPADDR3;
    lwlP_NetMask=(0xFF&DEFAULT_NETMASK0)<<24 | (0xFF&DEFAULT_NETMASK1)<<16 | (0xFF&DEFAULT_NETMASK2)<<8  | 0xFF&DEFAULT_NETMASK3;
    lwIP_GWAddr=(0xFF&DEFAULT_ROUTER0)<<24 | (0xFF&DEFAULT_ROUTER1)<<16 | (0xFF&DEFAULT_ROUTER2)<<8  | 0xFF&DEFAULT_ROUTER3;



    // Display the new IP address.
    UARTprintf("\rIP: %d.%d.%d.%d\n", (lwlP_IPAddr >> 24) & 0xff,
            (lwlP_IPAddr >> 16) & 0xff,(lwlP_IPAddr >> 8) & 0xff,
            lwlP_IPAddr & 0xff);

    // Display the new network mask.
    UARTprintf("Netmask: %d.%d.%d.%d\n", (lwlP_NetMask >> 24) & 0xff,
            (lwlP_NetMask >> 16) & 0xff,(lwlP_NetMask >> 8) & 0xff,
            lwlP_NetMask & 0xff);

    // Display the new gateway address.
    UARTprintf("Gateway: %d.%d.%d.%d\n", (lwIP_GWAddr >> 24) & 0xff,
            (lwIP_GWAddr >> 16) & 0xff,(lwIP_GWAddr >> 8) & 0xff,
            lwIP_GWAddr & 0xff);


    //OJO: AQUÍ SE PASAN LOS DATOS DE LA CONFIGURACIÓN IP ESTÁTICA
    // Initialize the lwIP library, using IP Estática.
    lwIPInit(pucMACArray, lwlP_IPAddr, lwlP_NetMask, lwIP_GWAddr, IPADDR_USE_STATIC);
    // Comprobamos el resultado de la configuración y vemos en Expressions:
    direccion_IP = lwIPLocalIPAddrGet();
    Mascara=lwIPLocalNetMaskGet();
    Gateway=lwIPLocalGWAddrGet();
//------------------------------------------------------------------------------
#else
    // Initialize the lwIP library, using DHCP.
    //
    lwIPInit(pucMACArray, 0, 0, 0, IPADDR_USE_DHCP);

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

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

    //***********************************************************************************
    // Initialize the TCP/IP Application (e.g. web server).
    //***********************************************************************************
        httpd_init();

    //------------------------------------------------------------------------------------
    // TIMER 0
    //------------------------------------------------------------------------------------
    // Configure the two 32-bit periodic timers.
    TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
    //TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);
    TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet(SYSTEM_CLOCK_SPEED)/2);
    //TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet(SYSTEM_CLOCK_SPEED) / 2);

    // Setup the interrupts for the timer timeouts.
    IntEnable(INT_TIMER0A);
    //IntEnable(INT_TIMER1A);
    TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    //TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    IntRegister(INT_TIMER0A, Timer0IntHandler);
    //IntRegister(INT_TIMER1A, Timer1IntHandler);

    // Enable the timers.
    TimerEnable(TIMER0_BASE, TIMER_A);
    //TimerEnable(TIMER1_BASE, TIMER_A);

    //------------------------------------------------------------------------------------
    // SERIAL PORT (UART)
    //------------------------------------------------------------------------------------
    InitConsole();
    UART=0;

    //------------------------------------------------------------------------------------
    // INTER PROCESSOR COMMUNICATION
    //------------------------------------------------------------------------------------
     // Give M3 access to S0 SARAM
    RAMMReqSharedMemAccess (S0_ACCESS, SX_M3MASTER);

    // Allow writes to protected registers.
    HWREG(SYSCTL_MWRALLOW) = 0xA5A5A5A5;

    // 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); // Data M3 -> C28
    IntRegister(INT_CTOMPIC2, CtoMIPC2IntHandler); // Data C28 -> M3
    //IntRegister(INT_CTOMPIC3, CtoMIPC3IntHandler);

    // Initialize IPC Controllers
    IPCMInitialize (&g_sIpcController1, IPC_INT1, IPC_INT1); // Data M3 -> C28
    IPCMInitialize (&g_sIpcController2, IPC_INT2, IPC_INT2); // Data C28 -> M3
    //IPCMInitialize (&g_sIpcController3, IPC_INT3, IPC_INT3);

    //------------------------------------------------------------------------------------
    // INITIALIZING BUFFERS FOR INTER PROCESSOR COMMUNICATION
    //------------------------------------------------------------------------------------

    // Initialize the buffer where the data coming from the C28 will be downloaded
    for (counter = 0; counter < buffer_size; counter++)
    {
        Buffer_M3[counter] = 0;
    }

    // Initialize local variables C28 to M3
    pulMsgRam = (void *)M3_MtoC_PASSMSG;
    pulMsgRam[0] = (unsigned long)&Buffer_M3[0];

    // Initialize local variables M3 to C28
    pulMsgRam2 = (void *)(M3_CtoM_PASSMSG);
    pusMBufferPt2 = (void *)(M3_S0_SARAM_START_buttons);

    //Clear/Ack all the Interrupt Flags  to avoid problems if the C28 has been stopped instead of be reseted.
    HWREG(MTOCIPC_BASE + IPC_O_MTOCIPCCLR) |= IPC_MTOCIPCCLR_IPC1; // Data M3 -> C28
    HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC2; // Data C28 -> M3
    //HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC3; // Data_dq C28 -> M3
    HWREG(MTOCIPC_BASE + IPC_O_MTOCIPCCLR) |= IPC_MTOCIPCCLR_IPC6; // Serial Port busy or empty

    HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |=IPC_CTOMIPCACK_IPC17;
    // Nofies to C28 that M3 is already running using, for instance, Flag 18 (Flag 5 to Flag 32 can be chosen)
    HWREG(MTOCIPC_BASE + IPC_O_MTOCIPCSET) |=IPC_MTOCIPCSET_IPC18;

    //------------------------------------------------------------------------------------
     // ENABLING INTERRUPTS
    //------------------------------------------------------------------------------------
    //  Disable writes to protected registers.
    HWREG(SYSCTL_MWRALLOW) = 0;
    // Enable all processor interrupts.
    IntMasterEnable();
}

//------------------------------------------------------------------------------------
// Configure the pin muxing for UART0 functions on port E0 and E1
//------------------------------------------------------------------------------------
void InitConsole(void)
{

    UARTStdioInit(0);

    // Enable GPIO port E which is used for UART0 pins
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    // Configure the pin muxing for UART0 functions on port E0 and E1.
    // This step is not necessary if your part does not support pin muxing.
    GPIOPinConfigure(GPIO_PE4_U0RX);
    GPIOPinConfigure(GPIO_PE5_U0TX);

    // Select the alternate (UART) function for these pins.
    GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);
    // Enable the UART interrupt.
    IntRegister(INT_UART0, UARTIntHandler);
    IntEnable(INT_UART0);
    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

}

  • IPC supports 4 interrupts on each core. M3 can set MTOCIPCFLG 1-3 and trigger corresponding interrupts on PIE on C28x and similarly C28x can set CTOMIPC1-3 and trigger corresponding interrupts on M3 core. If you want to use IPC between the cores without triggering interrupts then you can use the rest of the flags that don't have an interrupt tied to them.

    However I don't completely understand what you are trying to do with IPC (or how you intend to use IPC), do you want C28x core to send an IPC command requesting some data from M3 that it has received over LWIP? 

    Best Regards

    Santosh Athuru

  • Hi Santosh

    I am working in a project with my university in Spain and with another university in the USA.

    In this project, the C28 carry out the contol of a electric drive so it is continuosly sampling voltages, electric currents, etc.

    Every single time that the M3 ask for measuring data to the C28, the C28 sends the data about the electric measurements to the M3 using the IPC.

    The user interface has been carried out in HTML (and runs using lwIP stack) and also in Matlab.

    The HTML is stored in a SD card and the M3 sends the web page (user interface) to the browser so we are able to control the GPIOs using this html interface.

    Nevertheless, we would like to plot some waveforms, either in the html interface or in the Matlab interface.

    We are able to do that using micro-IP.

    Nonetheless, using lwIP, when the C28 send an interrupt to the M3 by using IPCINT1, the M3 freezes and ends up in a "Fault interrupt" loop.

    I know that it is possible to do the same using only flags instead of interrupts but it is a simpler solution that I don't like (so far).

    My question is, Why the IPCINT1 is not compatible with lwIP?

    Is not possible to use IPC interrupts with this lwIP implementation for Concerto?

    Have I made any mistake in my hardware cofiguration?

    Thank you,

    Dionisio

  • Dionisio,

    thanks for your explanation. It helps and looks like Concerto is a very good fit for your project as it has separate communication and control subsystems to share the load.

    Dionisio Ramirez Prieto said:
    Nonetheless, using lwIP, when the C28 send an interrupt to the M3 by using IPCINT1, the M3 freezes and ends up in a "Fault interrupt" loop.

    regarding above, it is taking up the FaultISR because it is the default and because your application didn't install/configure any IPC ISR on M3. You can put your own ISR function which moves/copies data from C28x to M3 RAMs (shared RAMs or MSG RAMs).

    Dionisio Ramirez Prieto said:

    My question is, Why the IPCINT1 is not compatible with lwIP?

    Is not possible to use IPC interrupts with this lwIP implementation for Concerto?

    Have I made any mistake in my hardware cofiguration?

    regarding above, LWIP has nothing to do with IPC interrupts. IPC is to help communication between the master and control subsystems and help move data using Sx RAMs or MSG RAMs. 

    You might have to look at the dual core IPC examples from Control Suite to understand how you can use IPC and include the needed code into the LWIP example/project.

    Best Regards

    Santosh Athuru

  • Thanks Santosh

    Thanks for your explanations.

    I'm sure that I'm missing something...

    Nevertheless, I have already registered the ISRs in the M3 and the ISRs themselves are included in the project.

    If the code compile without errors and I have registered the ISRs and the ISR are included in the project, why the CPU can't find the ISR? Have you any suggestion?

    Thank you in advance,

    Dionisio

    // Register M3 interrupt handlers

    IntRegister(INT_CTOMPIC1, CtoMIPC1IntHandler); // Data M3 -> C28

    IntRegister(INT_CTOMPIC2, CtoMIPC2IntHandler); // Data C28 -> M3

    //IntRegister(INT_CTOMPIC3, CtoMIPC3IntHandler);

    // Initialize IPC Controllers

    IPCMInitialize (&g_sIpcController1, IPC_INT1, IPC_INT1); // Data M3 -> C28

    IPCMInitialize (&g_sIpcController2, IPC_INT2, IPC_INT2); // Data C28 -> M3

    .....

    .....

    //****************************************************************************************

    // INTERRUPTS FOR THE INTERPROCESSOR COMMUNICATION

    //****************************************************************************************

    // CtoM INT1 Interrupt Handler - Handles Data Word Reads/Writes

    //****************************************************************************************

    void

    CtoMIPC1IntHandler (void)

    {

    tIpcMessage sMessage;

    unsigned short ErrorFlag=0;

    IntDisable(INT_ETH);

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

    }

    }

    ISR1++;

    HWREG(MTOCIPC_BASE + IPC_O_MTOCIPCCLR) |= IPC_MTOCIPCCLR_IPC1;

    IntEnable(INT_ETH);

    }

    //****************************************************************************************

    // CtoM INT2 Interrupt Handler - Handles Data Block Reads/Writes

    //****************************************************************************************

    void

    CtoMIPC2IntHandler (void)

    {

    tIpcMessage sMessage;

    unsigned short ErrorFlag=0;

    IntDisable(INT_ETH);

    // 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);//reads the shared RAM location, word size (16-or 32-bit), and block size from pointer to sMessage and writes the block to the M3 address specified in the pointer to sMessage

    break;

    case IPC_BLOCK_READ:

    IPCCtoMBlockRead(&sMessage);

    break;

    default:

    ErrorFlag = 1;

    break;

    }

    }

    ISR2++;

    //read_data=1;

    HWREG(MTOCIPC_BASE + IPC_O_CTOMIPCACK) |= IPC_CTOMIPCACK_IPC2;

    IntEnable(INT_ETH);

    }

     

  • Hi Santosh

    I have found and fixed the problem.

    In the example about lwIP (enet_lwip) all the S0 t0 S7 banks of memory has been joined in order to get a much bigger RAM memory.

    The problem is that the Sx RAM memory is also the Shared Memory to be used by IPC. During the IPC interrupt the C28 takes the control of the memory so that the lwIP code can't write anything in there, leading to a "Fault interrupt loop".

    It would have been a better option to choose not shared RAM (as much as possible) for the lwIP code.

     Now, by combining  C3-S0-...-S6 the S7 remains free to be used with IPC and everything works fine.

    Thanks

    Dionisio