-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/kw2xrf: Improved event callback policy #12083
Conversation
@PeterKietzmann @gebart |
@Ilmu011 yes it did, I'm sorry. Next time, just tell me personally about your PRs :-). Right now I don't find the time for a review but I'll come back to it very soon. |
Have you checked whether the NOACK event is being called as expected? I don't have the hardware to test with but my understanding is that SEQIRQ will be asserted at the end of the sequence no matter whether it ended with a received ACK or a timeout. That would mean that the check for TMR4IRQ is never reached. |
I have checked, whether the NOACK event is being called as expected. It is. Which makes sense, since TMR4IRQ is always checked when SEQIRQ is NOT asserted. Did you miss the " NOACK is called correctly... but right now it doesn't do anything. From my understanding, the callback function is defined at line 1408 in The only handled events are Everything else will be ignored and treated as an "unhandled event". |
And another thing; I didn't even realize it, until you pointed it out, but why is TMR4 used to detect an ACK timeout? There is a dedicated timer for detecting timeouts in RX-operations and that is TMR3. I am working on #10364 right now and the kw41z driver uses TMR3 for this purpose, which makes much more sense to me. This is also smoother since a TMR3 timeout also means that the sequence is aborted, asserting the SEQIRQ flag. This is described on page 130 of the reference manual.
|
@benemorius are you okay with @Ilmu011's explanation? @Ilmu011 for the TMR3 vs TMR4 discussion, please keep that one separate in an own issue or even better in a fixing PR :-) |
Ok I didn't catch the different usages between TMR3 and TMR4 either but I think you've discovered already that this was the source of my wrong assumption about the check not being reached. If a TMR4 expiration doesn't assert SEQIRQ then indeed my comment is invalid. |
@PeterKietzmann I created #12287 regarding this topic |
As discussed offline, something behaves unexpected following the proposed CCA test procedure. Please double-check and report back. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
The purpose and thus, the use of
NETDEV_EVENT_TX_COMPLETE
which incrementstx_success
generally seems a bit imprecise, but this is not a problem of this PR. What is success, a driver that returns? Successful channel access? Received ACK? In any way, this contribution aligns with other drivers. -
I've tested the two described scenarios that worked as described. Most importantly, I've placed a jammer next to the DUT and only the error counter incremented.
-
The logic in
_isr_event_seq_tr
and_isr_event_seq_t
is implemented differently. Why / for what?
if (dregs[MKW2XDM_IRQSTS3] & MKW2XDM_IRQSTS3_TMR3IRQ) { | ||
/* if the sequence was aborted by timer 3, ACK timed out */ | ||
DEBUG("[kw2xrf] TC3TMOUT, SEQIRQ, TX failed\n"); | ||
netdev->event_callback(netdev, NETDEV_EVENT_TX_NOACK); | ||
} else { | ||
DEBUG("[kw2xrf] SEQIRQ\n"); | ||
} else if(!channel_was_busy) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need to check here if the channel was busy before? Isn't this the case where an ACK was received?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding there are two scenarios, where a TMR3IRQ does NOT occur:
Either the ACK came in time (success) OR the initial CCA failed and aborted the sequence (failure).
@PeterKietzmann |
@@ -625,6 +625,9 @@ static void _isr_event_seq_t(netdev_t *netdev, uint8_t *dregs) | |||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE); | |||
} | |||
} | |||
else { | |||
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a comment here too, to document the occurrence. If I see it correctly, this is the case where SEQIRQ
fired because
This interrupt will assert whenever the Sequence Manager transitions from non-idle to idle state, for any reason
and CCAIRQ
did not fire because it is disabled by configuration
CCA Interrupt. A '1' indicates the completion of a CCA operation.
@Ilmu011 approaching release status ping, there are still some unaddressed comments here but maybe you can find to address before hard feature freeze? |
@Ilmu011 why did you close this one? |
Contribution description
kw2xrf driver; kw2xrf_netdev.c:
The event_callback policy was kind of messy; after a TX operation, depending on internal flags, 0, 1 or 2 event callbacks were made, with different parameters.
This change makes sure that a TX operation (T or TR) always results in exactly one event callback.
Testing procedure
The callback functions currently only increment netstat counters. Making an event callback with the parameter
NETDEV_EVENT_TX_MEDIUM_BUSY
will increment the fail counter. Making an event callback with the parameterNETDEV_EVENT_TX_COMPLETE
will increment the success counter.To observe faulty behaviour follow these instructions:
ifconfig
TX succeeded <x> errors <y>
Scenario 1: 0 callbacks made
Disable the NETOPTs
AUTOACK
,ACK_REQ
andAUTOCCA
. To do this type these lines into the console:ifconfig <interface_id> -autoack
ifconfig <interface_id> -ack_req
ifconfig <interface_id> -autocca
Send a UDP packet to any address
udp send <address> <port> <data>
Type
ifconfig
Under "statistics for layer 2" look at the line
TX succeeded <x> errors <y>
; neither x or y will have incremented but we would have expected x to increment by one.Scenario 2: 2 callbacks made
Or, if you don't want to do that, go todrivers/kw2xrf/kw2xrf_netdev.c
and in line 694 changeif (dregs[MKW2XDM_IRQSTS2] & MKW2XDM_IRQSTS2_CCA) {
toif ( !( dregs[MKW2XDM_IRQSTS2] & MKW2XDM_IRQSTS2_CCA ) ) {
and recompile and flash. This will make the driver interpret a clear channel as a busy channel instead.Edit: This doesn't quite work, because this only influences the ISR assessments. A CCAIRQ will also terminate the sequence, which does not happen, when using this workaround. Jamming the channel seems to be the only safe way to test this.
udp send <address> <port> <data>
ifconfig
TX succeeded <x> errors <y>
; both x and y will have incremented but we only would have expected y to increment by one.Keep in mind, the board does some stuff in the background too, including receiving and sending data over the radio. This will increment the netstat counters too. To avoid misinterpretations, you may want to enable debug prints.