Losing interrupts because SN_IR_RECV to SN_IR fails (silicon glitch?)
Ethernet Chips
No replies yet. Be the first to reply.
Join the discussion.
Ethernet Chips
- Replies
- 4
- Views
- 2,508
- Likes
- 0
Ethernet Chips
No replies yet. Be the first to reply.
Join the discussion.
Ethernet Chips
Share projects and connect with makers.
Joined before the site update? first.
New to WIZnet Makers?
We sent a verification link to your address. Open it to activate your account, then log in.
Accounts from this email provider are reviewed by an administrator after verification. Approval usually takes one business day.
Already have an account?
Enter your email address. If it belongs to an account, we'll send a link to set a new password. Members who joined before the site update use this to set their password.
If an account uses that address, we sent a link to set a new password. The link works once and expires in 30 minutes.
Know your password?
Need an account?
Please set a new password
We have upgraded security on WIZnet Makers. If you joined before October 6, 2026, please set a new password once: enter the email you signed up with, then open the link we send you.
Can't get into your old account? Email secure@wiznet.io with your username and we'll help.
RE: Losing interrupts because SN_IR_RECV to SN_IR fails (silicon glitch?)
by Candela12 ·
Btw, it is chip version 04
RE: Losing interrupts because SN_IR_RECV to SN_IR fails (silicon glitch?)
by Eugeny ·
The main issue in your design is
using edge to trigger interrupt. You should use low level of the interrupt line strobed using clock signal. You should NOT use interrupt signal as a clock because interrupt line state change may occur when interrupts are disabled, and can cause timing violations and metastability in your design.
This applies to whole WIZnet chip family. You need to flush all data from buffer before clearing bit 2, otherwise this bit will not clear because there’s still data in the RX buffer, and interrupt line will still be low. In case you use interrupt level (instead of edge) when you exit interrupt service routine and enable interrupt, interrupt routine is invoked again, and it will be happening until there will be no data in the RX buffer.
RE: Losing interrupts because SN_IR_RECV to SN_IR fails (silicon glitch?)
by Candela12 ·
[quote=“Eugeny”]The main issue in your design is
using edge to trigger interrupt. You should use low level of the interrupt line strobed using clock signal. You should NOT use interrupt signal as a clock because interrupt line state change may occur when interrupts are disabled, and can cause timing violations and metastability in your design.
[/quote]
I don’t disable interrupts on the w5500 nor my micro (dspic33e)
That is not documented as such for the w5500 I think. But reading this triggered rereading the w5100/5200 docs, and indeed it is there. I’m gearing up in wiznet again after a small two years of relative idleness, so thanks for that.
However, the problem is that I don’t see that happening. I reset SN_IR(SN_IR_RECV) every receive to kill the interrupt status, but I only adjust buffer pointers once every 2k. (while the avg packet is much smaller) for latency and throughput.
So there are thus nearly always bytes left in the buffer (SN_RX_RSR), and then SN_IR(SN_IR_RECV) should be high always, and shouldn’t be resettable, which is not what I see. I only see this behaviour (SN_IR_RECV not happening) if there are interrupts during the SN_IR_RECV resetting packet itself, which leads me to assume there is some race there.
I assumed that this was something that could not be fixed easily in silicon (buffer being updated by the ethernet side very near the moment I try to reset the interrupt), and they left in a known racecondition because fixing it would require increasing clock, and was looking for an official source for the mitigation of this problem, just like the “stable mode” is a fix for unshadowed 16-bit pointer reads
My current workaround is to simply check the level of the interrupt after the combine SN_IR_RECV reset and double RSR packet. (stable mode), and if it hasn’t been reset, simulate an interrupt.
That’s what I originally did, but there are two problems with that, which is why I changed it to the current situation.
In any situations this can only be resolved by additional polling of registers, which is a shame. (I now have a 14 byte dma pakket followed by a 2+ payload dma pakket to drain a buffer, and additional polling would decrease throughput, latency etc).
I can only conclude that my workaround might not be so bad because that way I only poll when needed. Still it would be good to have an official source for all this, since I assume it is a common problem when implement a low latency interrupt driven application.
[quote]
In case you use interrupt level (instead of edge) when you exit interrupt service routine and enable interrupt, interrupt routine is invoked again, and it will be happening until there will be no data in the RX buffer.[/quote]
I don’'t disable interrupts, and I have a hardware INT peripheral interrupt w5200 INT pin that probably would detects pin changes in the 10ns range. (140MHz peripheral clock)
In general we are mightily impressed by the wiz5500, specially since we optimize it for low latency UDP I/O slaves on a local network which is not the most common goal in these IoT times. The nicest part is the low cpu burden when the program is rewritten using event (interrupt) driven DMA. (less than 10-15us CPU time to receive, process and reply (one small pkt in and one out) for a relatively puny 70MIPS dspice. The wall time (from interrupt till the send process is completed) can be as low as 100us, but once every 2-3kb received it will be 20us more.
I’m currently ironing out the last remaining kinks, because we are working on bringing in the design-in of 2 years ago to production, and hopefully our experiences will be helpful for people trying to do something similar. If somebody knows more advanced examples for any micro for low latency, low cpu use, or even just descriptions of it, I would be extremely interested.
RE: Losing interrupts because SN_IR_RECV to SN_IR fails (silicon glitch?)
by Candela12 ·
In retrospect back then I didn’t realize what the main problem is. That is that the w5500 INT pin is a level based interrupt instead of a edge interrupt. I meanwhile used other parts that use level based interrupts, and realized this is the same behaviour as the w5500. Eugeny seems to hint on that in his message, but I then didn’t understand.
An level based interrupt remains high if the condition is not resolved, without generating a new interrupt. Level interrupts are more common in
faster parts. (like >100-200MHz PIC32/MIPS and ARMs) that have caches and peripheral busses.
If you know that, the workaround is simple, you just rerun the service routine as long as the interrupt is high after the action that should reset the interrupt (writing SN_IR).
I do this via a separate variable (socketinterrupt in the below fragment) to rerun the entire mainloop (and allow other interrupts to be serviced)
So the interrupt routine looks like this (schematic only, I use Microchip Dspic)