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.
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
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 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.