-
Notifications
You must be signed in to change notification settings - Fork 1k
refactor: migrate to stopListening(txAddress)
from openWritingPipe()
#1030
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
Conversation
Memory usage change @ a04c324
Click for full report table
Click for full report CSV
|
I have one suggestion about this, since it changes the API so much.
Why not change it so the user just calls the following:
This way users don't need to know about or use the memcpy function or openWritingPipe. *EDIT: It could also allow use to keep the old stopListening() function in place, for when users don't want the bother of overwriting the pipe0 rx address. |
That could work. It is a little less intuitive because
We could even overload
setting the address was separate from activating TX mode for a reason though
|
Would this be a bad time to phase in the newer grammar |
It kind of is, it makes things more difficult to address in RF24Network. I really have to look at the order of operations to see how this will work out.
Thats why we leave the old stopListening and openWritingPipe in place, so users can just use the old functionality. Here is what I am playing around with: void RF24::stopListening()
{
ce(LOW);
//delayMicroseconds(100);
delayMicroseconds(static_cast<int>(txDelay));
if (ack_payloads_enabled) {
flush_tx();
}
config_reg = static_cast<uint8_t>(config_reg & ~_BV(PRIM_RX));
write_register(NRF_CONFIG, config_reg);
#if defined(RF24_TINY) || defined(LITTLEWIRE)
// for 3 pins solution TX mode is only left with additional powerDown/powerUp cycle
if (ce_pin == csn_pin) {
powerDown();
powerUp();
}
#endif
write_register(EN_RXADDR, static_cast<uint8_t>(read_register(EN_RXADDR) | _BV(pgm_read_byte(&child_pipe_enable[0])))); // Enable RX on pipe0
}
/****************************************************************************/
void RF24::stopListening(uint8_t address[5])
{
stopListening();
write_register(TX_ADDR, address, addr_width);
write_register(RX_ADDR_P0, address, addr_width);
}
/****************************************************************************/
void RF24::stopListening(uint64_t address)
{
stopListening();
write_register(TX_ADDR, reinterpret_cast<uint8_t*>(&address), addr_width);
write_register(RX_ADDR_P0, reinterpret_cast<uint8_t*>(&address), addr_width);
} I think most users are already avoiding pipe 0 because of this bug. |
Without a doubt, |
Its a little difficult for me to remember the order of ops. In the examples, I noticed that most of them set the addresses to the pipes first and then call It only works out in the examples because they often call EDIT: I think if we publicly expose the |
This is what I changed in RF24Network template<class radio_t>
bool ESBNetwork<radio_t>::write_to_pipe(uint16_t node, uint8_t pipe, bool multicast)
{
bool ok = false;
// Open the correct pipe for writing.
// First, stop listening so we can talk
if (!(networkFlags & FLAG_FAST_FRAG)) {
if(pipe){
radio.stopListening();
}else{
radio.stopListening(pipe_address(node, pipe)); // << **** CHANGED THIS
}
} Now I'm getting upwards of 27KB/s with the same tests. Not sure what was going on before, but this is more inline with the capabilities of the radios. |
That's with only 1 hop or a multitude?
Honestly, this could be done quicker with just toggling the CE pin. I find it weird this lib hides the CE pin capability and the STATUS flags. Every time I write a nRF24L driver from scratch, I always expose these as a fail-safe for advanced usage; networking and streaming consecutive payloads definitely qualify as advanced usage. |
|
Yeah, but lumping that in with CE management is what mandates the confusing order of operations. |
Well in that case, lets make CE() public! |
Should I combine this PR changes with your It still doesn't hurt to have the TX address public too. I can't think of a point where this lib (or other network layers) needs exclusive access/control over it. FYI, rust doesn't have implicit function overloading like in C++. Python 3 had to be patched to support overloaded functions (making it an explicit opt-in feature/syntax in pure python). |
Whichever way is easiest I guess. |
Missed this comment, but to me those names are more confusing than startListening/stopListening. Maybe I'm just old and averse to change :p |
Fair enough. After writing examples with |
related to nRF24/RF24#1028 but takes a different approach from nRF24/RF24#1029 (more like nRF24/RF24#1030)
This comment was marked as resolved.
This comment was marked as resolved.
08624c0
to
7125fb4
Compare
I found a problem with the overloaded radio.stopListening(txAddress); // write the TX address to RX_ADDR_P0
radio.openReadingPipe(0, rxAddress); // write the RX address to RX_ADDR_P0
// !!! still in TX mode but RX pipe 0 address is not the TX address My gut reaction is to use the cached Lines 1651 to 1656 in 7125fb4
gets changed to if (child > 1) {
write_register(pgm_read_byte(&child_pipe[child]), address, 1);
}
else if (static_cast<bool>(config_reg & _BV(PRIM_RX)) || child != 0) {
write_register(pgm_read_byte(&child_pipe[child]), address, addr_width);
} Fortunately, the cached Lines 1158 to 1161 in 7125fb4
Following the state of the EN_RXADDR register in this scenario, I think we should be fine because both openReadingPipe() and stopListening() open RX pipe 0, and startListening() won't close it because _is_p0_rx is true.
|
b2d7a97
to
f9fa18b
Compare
explain logic in comment
user code should ultimately specify address(es) regardless of initialization
for plus variants only
This one needs diligent review. My brain is sore from |
Well good news so far, this doesn't seem to break any old code. I'm running this on all my RPis & a couple Arduinos to test. Will move on to testing the new API soon. |
I don't think it would even if you use pipe 0 to RX (the real crux of the problem). If pipe 0 is used, then there should just be an extra/duplicate write to I must admit, your |
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.
Arduino sketches all seem to check out now:
- gettingStarted (pipe0, pipe1, pipe2, etc working)
- interruptConfigure - good
- AckknowledgementPayloads - good
- Multiceiver - good
RF24Network, Mesh, Ethernet & Gateway examples all functioning well also
I'm too tired to think. Mind if this sits overnight (my time). I'll give this another code review pass tomorrow and we can do the merge crusade. I still think the network layers would be more performant with the overloaded |
Yeah, I guess the DPL bug has existed forever, one more night won't hurt
I'll take a look at it today also. |
I 'm going to deprecate that new
Both of these disadvantages are briefly explained (with example snippets) in the migration guide, so we shouldn't have to repeat ourselves when people ask. PS - I get why you added it; it makes migration practically a swapping of function names. But, the address passed needs to be changed into a buffer to complete the migration. There would also be a duplicate |
review migration guide again
Yeah, I should probably have a look at RF24Network some time and see about converting from using uint64_t for addressing. Soo, release crusade? |
Already done in nRF24/RF24Network#251. I'm testing that branch now (against another RPi running just master branches).
Sure. |
If you're going to do it, remember RF24 gets a minor bump, not a patch. |
stopListening()
now writes the TX address to pipe 0 (for reading and writing). This deprecates the need foropenWritingPipe()
by offering an overloadedstopListening(txAddress)
.All examples (and the python wrapper) have been updated to use the new public
stopListening(txAddress)
accordingly.Important
RF24Network should be updated to use the new
stopListening(txAddress)
also. This approach should retain current performance in networking layers while still satisfying #1028.The main take away is no duplicate SPI transactions when switching to TX mode and (re)setting the TX address. This aims to fix the performance regression in #1029.