Skip to content

Commit

Permalink
Use read_register() to write 1 byte SPI commands
Browse files Browse the repository at this point in the history
I came across this tactic when writing the rust implementation.

By telling `read_register()` to read 0 bytes from a register that is actually a reserved SPI command byte, we don't need to use a special form of `write_register(uint8_t, uint8_t)`. The same transaction still occurs with less code executed to do it.

This only affects `get_status()`, `flush_tx()`, and `flush_rx()`.
Luckily, those SPI commands already have 0x20 bit asserted, so there's no need to mask the command byte with `W_REGISTER` as is done in `write_register()`.
This needs testing on the various supported platforms to ensure a 1-byte buffer behaves as expected.
  • Loading branch information
2bndy5 committed Jul 15, 2024
1 parent bae5111 commit 76302fc
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 42 deletions.
60 changes: 21 additions & 39 deletions RF24.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,54 +282,36 @@ void RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)

/****************************************************************************/

void RF24::write_register(uint8_t reg, uint8_t value, bool is_cmd_only)
void RF24::write_register(uint8_t reg, uint8_t value)
{
if (is_cmd_only) {
if (reg != RF24_NOP) { // don't print the get_status() operation
IF_RF24_DEBUG(printf_P(PSTR("write_register(%02x)\r\n"), reg));
}
beginTransaction();
#if defined(RF24_LINUX)
status = _SPI.transfer(W_REGISTER | reg);
#else // !defined(RF24_LINUX) || defined (RF24_RP2)
#if defined(RF24_SPI_PTR)
status = _spi->transfer(W_REGISTER | reg);
#else // !defined (RF24_SPI_PTR)
status = _SPI.transfer(W_REGISTER | reg);
#endif // !defined (RF24_SPI_PTR)
#endif // !defined(RF24_LINUX) || defined(RF24_RP2)
endTransaction();
}
else {
IF_RF24_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"), reg, value));
IF_RF24_DEBUG(printf_P(PSTR("write_register(%02x,%02x)\r\n"), reg, value));
#if defined(RF24_LINUX) || defined(RF24_RP2)
beginTransaction();
uint8_t* prx = spi_rxbuff;
uint8_t* ptx = spi_txbuff;
*ptx++ = (W_REGISTER | reg);
*ptx = value;
beginTransaction();
uint8_t* prx = spi_rxbuff;
uint8_t* ptx = spi_txbuff;
*ptx++ = (W_REGISTER | reg);
*ptx = value;

#if defined(RF24_RP2)
_spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, 2);
_spi->transfernb((const uint8_t*)spi_txbuff, spi_rxbuff, 2);
#else // !defined(RF24_RP2)
_SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), 2);
_SPI.transfernb(reinterpret_cast<char*>(spi_txbuff), reinterpret_cast<char*>(spi_rxbuff), 2);
#endif // !defined(RF24_RP2)

status = *prx++; // status is 1st byte of receive buffer
endTransaction();
status = *prx++; // status is 1st byte of receive buffer
endTransaction();
#else // !defined(RF24_LINUX) && !defined(RF24_RP2)

beginTransaction();
beginTransaction();
#if defined(RF24_SPI_PTR)
status = _spi->transfer(W_REGISTER | reg);
_spi->transfer(value);
status = _spi->transfer(W_REGISTER | reg);
_spi->transfer(value);
#else // !defined(RF24_SPI_PTR)
status = _SPI.transfer(W_REGISTER | reg);
_SPI.transfer(value);
status = _SPI.transfer(W_REGISTER | reg);
_SPI.transfer(value);
#endif // !defined(RF24_SPI_PTR)
endTransaction();
endTransaction();
#endif // !defined(RF24_LINUX) && !defined(RF24_RP2)
}
}

/****************************************************************************/
Expand Down Expand Up @@ -486,23 +468,23 @@ void RF24::read_payload(void* buf, uint8_t data_len)

uint8_t RF24::flush_rx(void)
{
write_register(FLUSH_RX, RF24_NOP, true);
read_register(FLUSH_RX, (uint8_t*)nullptr, 0);
return status;
}

/****************************************************************************/

uint8_t RF24::flush_tx(void)
{
write_register(FLUSH_TX, RF24_NOP, true);
read_register(FLUSH_TX, (uint8_t*)nullptr, 0);
return status;
}

/****************************************************************************/

uint8_t RF24::get_status(void)
{
write_register(RF24_NOP, RF24_NOP, true);
read_register(RF24_NOP, (uint8_t*)nullptr, 0);
return status;
}

Expand Down Expand Up @@ -1325,7 +1307,7 @@ bool RF24::writeBlocking(const void* buf, uint8_t len, uint32_t timeout)
void RF24::reUseTX()
{
write_register(NRF_STATUS, _BV(MAX_RT)); //Clear max retry flag
write_register(REUSE_TX_PL, RF24_NOP, true);
read_register(REUSE_TX_PL, (uint8_t*)nullptr, 0);
ce(LOW); //Re-Transfer packet
ce(HIGH);
}
Expand Down
4 changes: 1 addition & 3 deletions RF24.h
Original file line number Diff line number Diff line change
Expand Up @@ -1929,12 +1929,10 @@ class RF24
*
* @param reg Which register. Use constants from nRF24L01.h
* @param value The new value to write
* @param is_cmd_only if this parameter is true, then the `reg` parameter
* is written, and the `value` param is ignored.
* @return Nothing. Older versions of this function returned the status
* byte, but that it now saved to a private member on all SPI transactions.
*/
void write_register(uint8_t reg, uint8_t value, bool is_cmd_only = false);
void write_register(uint8_t reg, uint8_t value);

/**
* Write the transmit payload
Expand Down

0 comments on commit 76302fc

Please sign in to comment.