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.

RM46 LwIP Demo Hanging

Other Parts Discussed in Thread: DP83640, HALCOGEN

Hi,

I am attempting to migrate the LwIP demo onto a custom board, it uses the RM46L852CPGET in MII with the DP83640 PHY. I modified the demo files for LwIP slightly to fit my hardware and got the demo to work properly, so the hardware is functioning properly. So going with this I started porting files over to my code base to begin the integration. I am at the point where the demo will output:

HERCULES MICROCONTROLLERS
Texas Instruments
Little Endian device
Initializing ethernet (DHCP)
        DEBUG - Getting PHY ID....SUCCESS
        DEBUG - Getting PHY Alive Status...SUCCESS
        DEBUG - Getting PHY Link Status...SUCCESS
        DEBUG - Setting up Link...SUCCESS

and then nothing. When I open the debugger the system is stuck in the following while statement (from HalCoGen's emac.c):

/* Make sure that the transmission is over */
/*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
/*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */   
while(((curr_bd->flags_pktlen) & EMAC_BUF_DESC_OWNER) == EMAC_BUF_DESC_OWNER)
{
}

which is in the "EMACTxIntHandler(hdkif_t *hdkif)" function. The initialization is using DCHP. The only difference I can find is that HalCoGen project for the demo is for the BGA package instead of the LQFP that I am using. Any ideas what could be happening? I am happy to provide any info necessary. I attached a copy of the new project that is not working.


Thanks!4744.Code.zip

  • Hi Nathan,
    Not too sure what went wrong perhaps due to your integration since the running the demo alone with your custom board seems to work, right? I will forward your post to our expert for additional insights.
  • Correct Charles. The demo works with some slight modifications (gio to enable phy, changing sci port, setting pin mux to MII, changing to the CPP compiler). It is able to acquire a DCHP instantly unlike the project I am trying to integrate.


    Another thought I had is the RM46 is servicing a RTI and CAN interrupts in the new project. Maybe it cannot clear the ethernet buffer quick enough with the other IRQs firing?

    Thanks for the help!

  • Hi Nathan,

     I don't think the RTI/CAN interrupt can cause the EMAC to hang. However, if possible it does not hurt to disable RTI and CAN interrupts to see if it makes a difference.

     If you have the RM46 HDK board can you try to run your integrated project there and will it work?

     I'm not an ethernet expert so hopefully what I'm writing below will provide some tips to checks.

     The reason that the code is looping is that the EMAC has not cleared the OWNER flag.  Accoring to the TRM it says:

     "When set the OWNER flag indicates that all the descriptors for the given packet (from SOP to EOP) are currently owned by the EMAC. This flag is set by the software application on the SOP packet descriptor before adding the descriptor to the transmit descriptor queue. For a single fragment packet, the SOP, EOP, and OWNER flags are all set. The OWNER flag is cleared by the EMAC once it is finished with all the descriptors for the given packet. Note that this flag is valid on SOP descriptors only."

     Since the OWNER bit is set by the software application, is it possible that the software might have set the flag again before you entered the interrupt handler via EMACTxIntHandler? In another word, is there a race condition where the EMAC has cleared the OWNER flag but the software has set it before the EMACTxIntHandler() is entered?

     Below are additional description about the EMAC transmit operation from the TRM. 

    "When the last packet in a queue has been transmitted, the port sets the End Of Queue bit in the EOP buffer descriptor, clears the Ownership bit in

    the SOP Descriptor, zeroes the appropriate DMA state head descriptor pointer, and then issues a TX interrupt to the host by writing to the queue's associated TX completion pointer (address of the last buffer descriptor processed by the port). The port issues a maskable level interrupt (which may then be routed through external interrupt control logic to the host).

    On interrupt from the port, the host processes the buffer queue, detecting transmitted packets by the status of the Ownership bit in the SOP buffer descriptor. If the Ownership bit is cleared to zero, then the packet has been transmitted and the host may reclaim the buffers associated with the packet. The host continues queue processing until the end of the queue or until a SOP buffer descriptor is read that contains a set Ownership bit indicating that the packet transmission is not complete."

     Base on the above description it will be good to check if the EOQ is set. 

     

     

  • I do not have a HDK to try it on. I'll check those flags and registers when I am in the lab later today and report back. Thanks for the advice!

  • Hi Charles,

    I got a chance to look at this more today. The snapshot of the variables where the code hangs looks like this:

    It shows that the curr_bd->flags_pktlen has a value of 0xEAFFFFFE. What I found interesting though is the value of curr_bd is 0.

    Looking in the calling function (EMACTxIntISR() in emac.c) shows that the pack passed in has a value of 0 for the pointer. Here's what it looks like it:

  • Hi Nathan,
    Looking at your buffer desriptor I think the content is all wrong. The next pointer is pointing to an address 0xEA00E85D. This is an illegal address. 0xEA00E85D is more like an instructon opcode to me. Especially the flags_pklen which is 0xEAFFFFFE. 0xEAFFFFFE is normally a branch to itself instruction. The buffer pointer and buffer offset are also pointing to an illegal address. So what I will suggest you do is to investigate how the buffer descriptors are written compared to the demo. Another suggestion is if you can integrate your code base piece by piece at a time into the demo rather than integrating the demo into the code base since you have proven that the demo works in your custom board.
  • Hi Charles,


    Figured it out finally. The demo is based on the RM46L852ZWT and has EMAC ISRs named "EMACCore0RxIsr" and "EMACCore0TxIsr" which are defined in the lwip_main.c file. For the RM46L852PGE these ISRs are named "EMACRxIntISR" and "EMACTxIntISR" and defined in the emac.c by HalCoGen. Changing the ones in lwip_main.c and commenting out the ones in the emac.c lets the program run as expected.


    Is there a proper way to overload the ISRs in emac.c since they get overwritten each time by HalCoGen?


    Thanks,

    Nathan

  • Hi Nathan,

     Glad that you figure the problem yourself.

     If you go to the VIM RAM tab in HalCoGen you can change the interrupt ISR name to EMACCore0RxIsr  for channel 77 and EMACCore0TxIsr for channel 79. See below screenshot. They currently have the names of EMACRxIntISR and EMACTxIntISR respectively. Let me know if that fixes the problem. 

  • Worked great, thanks for the help!

    Nathan