-
Notifications
You must be signed in to change notification settings - Fork 164
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
avoid SPI repetition during fragmentation #182
Comments
I’m not sure. I’ll have to do a code review to figure out what your talking about, but it seems to make sense.
… On Jul 23, 2021, at 7:45 PM, Brendan ***@***.***> wrote:
I'm asking because it seems there is a lot of repetitive overhead when sending each fragment of a message going to the same to_node & to_pipe (referring to the call to logicalToPhysicalAddress() in _write()). Additionally, managing the auto-ack feature for pipe 0, writing the same TX address, and manually toggling TX/RX mode for each fragment seems like it would be unnecessarily time consuming.
I understand that there's additional considerations concerning networkFlags & FLAG_FAST_FRAG and the 3 manual retries (which invokes a 2 ms delay on failed attempts) for each fragment, but I'm just looking for an expert opinion. I thought the whole point of using RF24::writeFast() was to fill up the TX FIFO (blocking only when TX FIFO is full), and let the radio do it's thing (during RF24::txStandby()). Maybe I'm reading the source code wrong or just overthinking it again.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
I believe the There's also the case of waiting for
I should enable |
Network acks are handled in the |
This is so explicitly insightful! I'm adding a comment in the |
did a quick test with SERIAL_DEBUG enabled in RF24 lib. The following results are from that dev_test.py script I mentioned: >>> network.write(header, bytes(range(26)))
write_register(00,0e) # CONFIG - stopListening() called
write_register(02,3f) # EN_RXADDR - side effect of stopListening()
141381: NET Sending id 1 from 00 to 01 type 148
141381: FRG frame size 32
141381: FRG frame 00 00 01 00 01 00 94 02 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
141381: MAC Sending to 01 via 01 on pipe 5
write_register(01,3f) # EN_AA - pipe 0 is enabled
141381: NET Pipe 5 on node 01 has address cccccc3ce3 # SPI transaction to write TX address not output
[Writing 32 bytes 0 blanks]
141382: NET Sending id 1 from 00 to 01 type 150
141382: FRG frame size 10
141382: FRG frame 00 00 01 00 01 00 96 00 18 19
141382: MAC Sending to 01 via 01 on pipe 5
write_register(01,3f) # EN_AA - pipe 0 is enabled
141382: NET Pipe 5 on node 01 has address cccccc3ce3 # SPI transaction to write TX address not output
[Writing 10 bytes 0 blanks]
write_register(07,10) # STATUS - clearing the MAX_RT flag
write_register(00,0f) # CONFIG - startListening() called
write_register(07,70) # STATUS - side effect of startListening()
write_register(01,3e) # EN_AA - pipe 0 is disabled
True I've added comments to the output that should help decipher what is going on. As I suspected, unnecessary repetition includes
|
Maybe it would be a good idea. It would be a fair bit of work as well.
… On Jul 24, 2021, at 3:10 PM, Brendan ***@***.***> wrote:
did a quick test with SERIAL_DEBUG enabled in RF24 lib. The following results are from that dev_test.py script I mentioned:
>>> network.write(header, bytes(range(26)))
write_register(00,0e) # CONFIG - stopListening() called
write_register(02,3f) # EN_RXADDR - side effect of stopListening()
141381: NET Sending id 1 from 00 to 01 type 148
141381: FRG frame size 32
141381: FRG frame 00 00 01 00 01 00 94 02 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
141381: MAC Sending to 01 via 01 on pipe 5
write_register(01,3f) # EN_AA - pipe 0 is enabled
141381: NET Pipe 5 on node 01 has address cccccc3ce3 # SPI transaction to write TX address not output
[Writing 32 bytes 0 blanks]
141382: NET Sending id 1 from 00 to 01 type 150
141382: FRG frame size 10
141382: FRG frame 00 00 01 00 01 00 96 00 18 19
141382: MAC Sending to 01 via 01 on pipe 5
write_register(01,3f) # EN_AA - pipe 0 is enabled
141382: NET Pipe 5 on node 01 has address cccccc3ce3 # SPI transaction to write TX address not output
[Writing 10 bytes 0 blanks]
write_register(07,10) # STATUS - clearing the MAX_RT flag
write_register(00,0f) # CONFIG - startListening() called
write_register(07,70) # STATUS - side effect of startListening()
write_register(01,3e) # EN_AA - pipe 0 is disabled
True
I've added comments to the output that should help decipher what is going on.
As I suspected, unnecessary repetition includes
the TX address is written (this is a detrimental slow-down)
auto-ack on pipe 0 enabled (doesn't hurt as much as writing 5 bytes, but still...)
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Kinda, but I shy from no worthy challenge. I've been brainstorming...
I'll probably start a new branch based on the CMake-4-Linux branch so undoing this change won't be difficult if it doesn't work out. |
I didn't realize the Alternative idea to avoid the repetitionAdd a new flag called
So, to summarize, leave code as is, use a new flag
This should look like in psuedo-code (for step 4) #define FLAG_FIRST_FRAG 16
uint8_t assertedFlags = networkFlags & (FLAG_FIRST_FRAG + FAST_FAST_FRAG);
if (assertedFlags > FLAG_FIRST_FRAG || !assertedFlags) {
networkFlags &= ~FLAG_FIRST_FRAG;
// do SPI transactions
} |
Yeah that could work I think.
… On Jul 26, 2021, at 11:52 PM, Brendan ***@***.***> wrote:
I didn't realize the frame_buffer is limited to 32 bytes (should've guessed though). Thus, it does not make sense to move the fragging algorithm to write_to_pipe().
Alternative idea to avoid the repetition
Add a new flag called FLAG_FIRST_FRAG for use in the networkFlags member as the networkFlags is allocated to 8 bits (current flags only use 4 LSB). This new flag can only be used to avoid the unnecessary SPI transactions because the call to logicalToPhysicalAddress() is baked into the workflow as a message is passed from
write(header, msg, ...) (where fragmentation occurs) to
_write() (where args for logicalToPhysicalAddress() are assembled) to
write(toNode, directTo) (where logicalToPhysicalAddress() is called) to
write_to_pipe() (where all the repeated SPI transactions occur)
So, to summarize, leave code as is, use a new flag FLAG_FIRST_FRAG asserted on the first fragment in step 1 than get immediately de-asserted in step 4.
Perform the SPI transactions in step 4 only when the new FLAG_FIRST_FRAG and FAST_FAST_FRAG are assert at the same time.
If FLAG_FIRST_FRAG is de-asserted and FAST_FAST_FRAG is asserted, then don't do SPI transactions in step 4.
If both FLAG_FIRST_FRAG and FAST_FAST_FRAG are de-asserted, then always do SPI transactions in step 4.
This should look like in psuedo-code (for step 4)
#define FLAG_FIRST_FRAG 16
uint8_t assertedFlags = networkFlags & (FLAG_FIRST_FRAG + FAST_FAST_FRAG);
if (assertedFlags > FLAG_FIRST_FRAG || !assertedFlags) {
networkFlags &= ~FLAG_FIRST_FRAG;
// do SPI transactions
}
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
well, the new flag works on Arduino platform, but I just thought of way to not use a new flag at all: use the outgoing header's message type. The math/comparison logic would be simpler at least... |
this issue has been addressed without the need for a new flag >>> network.write(header, bytes(range(99)))
write_register(00,0e)
write_register(02,3f)
67305: NET Sending id 1 from 01 to 00 type 148
67305: FRG frame size 32
67305: FRG frame 01 00 00 00 01 00 94 05 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17
67305: MAC Sending to 00 via 00 on pipe 1
write_register(01,3f)
67305: NET Pipe 1 on node 00 has address cccccccc3c
[Writing 32 bytes 0 blanks]
67306: NET Sending id 1 from 01 to 00 type 149
67306: FRG frame size 32
67306: FRG frame 01 00 00 00 01 00 95 04 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
67306: MAC Sending to 00 via 00 on pipe 1
[Writing 32 bytes 0 blanks]
67306: NET Sending id 1 from 01 to 00 type 149
67306: FRG frame size 32
67306: FRG frame 01 00 00 00 01 00 95 03 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47
67306: MAC Sending to 00 via 00 on pipe 1
[Writing 32 bytes 0 blanks]
67306: NET Sending id 1 from 01 to 00 type 149
67307: FRG frame size 32
67307: FRG frame 01 00 00 00 01 00 95 02 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F
67307: MAC Sending to 00 via 00 on pipe 1
[Writing 32 bytes 0 blanks]
67307: NET Sending id 1 from 01 to 00 type 150
67307: FRG frame size 11
67307: FRG frame 01 00 00 00 01 00 96 00 60 61 62
67307: MAC Sending to 00 via 00 on pipe 1
[Writing 11 bytes 0 blanks]
write_register(00,0f)
write_register(07,70)
write_register(01,3e)
True Notice that the necessary configuring SPI transactions are only performed before and after all fragments are transmitted. This is indicated by the following 2 lines write_register(01,3f)
67305: NET Pipe 1 on node 00 has address cccccccc3c |
I'm asking because it seems there is a lot of repetitive overhead when sending each fragment of a message going to the same
to_node
&to_pipe
(referring to the call tologicalToPhysicalAddress()
in_write()
). Additionally, managing the auto-ack feature for pipe 0, writing the same TX address, and manually toggling TX/RX mode for each fragment seems like it would be unnecessarily time consuming.I understand that there's additional considerations concerning
networkFlags & FLAG_FAST_FRAG
and the 3 manual retries (which invokes a 2 ms delay on failed attempts) for each fragment, but I'm just looking for an expert opinion. I thought the whole point of usingRF24::writeFast()
was to fill up the TX FIFO (blocking only when TX FIFO is full), and let the radio do it's thing (duringRF24::txStandby()
). Maybe I'm reading the source code wrong or just overthinking it again.The text was updated successfully, but these errors were encountered: