Added ack payload. Added a sample using pingpair as a base with minimal changes.
This commit is contained in:
111
RF24.cpp
111
RF24.cpp
@@ -11,7 +11,7 @@
|
||||
#include "RF24.h"
|
||||
#include "nRF24L01.h"
|
||||
|
||||
#undef SERIAL_DEBUG
|
||||
#define SERIAL_DEBUG
|
||||
#ifdef SERIAL_DEBUG
|
||||
#define IF_SERIAL_DEBUG(x) (x)
|
||||
#else
|
||||
@@ -51,6 +51,18 @@ uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
uint8_t RF24::read_register(uint8_t reg)
|
||||
{
|
||||
csn(LOW);
|
||||
SPI.transfer( R_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
uint8_t result = SPI.transfer(0xff);
|
||||
|
||||
csn(HIGH);
|
||||
return result;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
|
||||
{
|
||||
uint8_t status;
|
||||
@@ -190,7 +202,7 @@ void RF24::print_observe_tx(uint8_t value)
|
||||
/******************************************************************/
|
||||
|
||||
RF24::RF24(uint8_t _cepin, uint8_t _cspin):
|
||||
ce_pin(_cepin), csn_pin(_cspin), payload_size(32)
|
||||
ce_pin(_cepin), csn_pin(_cspin), payload_size(32), ack_packet_available(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -327,6 +339,7 @@ boolean RF24::write( const void* buf, uint8_t len )
|
||||
|
||||
// Transmitter power-up
|
||||
write_register(CONFIG, _BV(EN_CRC) | _BV(PWR_UP));
|
||||
delay(2);
|
||||
|
||||
// Send the payload
|
||||
write_payload( buf, len );
|
||||
@@ -339,18 +352,37 @@ boolean RF24::write( const void* buf, uint8_t len )
|
||||
// Monitor the send
|
||||
uint8_t observe_tx;
|
||||
uint8_t status;
|
||||
uint8_t retries = 255;
|
||||
do
|
||||
{
|
||||
status = read_register(OBSERVE_TX,&observe_tx,1);
|
||||
IF_SERIAL_DEBUG(Serial.print(status,HEX));
|
||||
IF_SERIAL_DEBUG(Serial.print(observe_tx,HEX));
|
||||
if ( ! retries-- )
|
||||
{
|
||||
IF_SERIAL_DEBUG(printf("ABORTED: too many retries\n\r"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
while( ! ( status & ( _BV(TX_DS) | _BV(MAX_RT) ) ) );
|
||||
|
||||
if ( status & _BV(TX_DS) )
|
||||
result = true;
|
||||
|
||||
IF_SERIAL_DEBUG(Serial.println(result?"...OK.":"...Failed"));
|
||||
|
||||
IF_SERIAL_DEBUG(Serial.print(result?"...OK.":"...Failed"));
|
||||
|
||||
ack_packet_available = ( status & _BV(RX_DR) );
|
||||
uint8_t pl_len = 0;
|
||||
if ( ack_packet_available )
|
||||
{
|
||||
write_register(STATUS,_BV(RX_DR) );
|
||||
csn(LOW);
|
||||
SPI.transfer( R_RX_PL_WID );
|
||||
pl_len = SPI.transfer(0xff);
|
||||
csn(HIGH);
|
||||
IF_SERIAL_DEBUG(Serial.print("[AckPacket]/"));
|
||||
IF_SERIAL_DEBUG(Serial.println(pl_len,DEC));
|
||||
}
|
||||
|
||||
// Yay, we are done.
|
||||
ce(LOW);
|
||||
@@ -378,12 +410,11 @@ boolean RF24::available(void)
|
||||
boolean RF24::available(uint8_t* pipe_num)
|
||||
{
|
||||
uint8_t status = get_status();
|
||||
IF_SERIAL_DEBUG(print_status(status));
|
||||
boolean result = ( status & _BV(RX_DR) );
|
||||
|
||||
if (result)
|
||||
{
|
||||
IF_SERIAL_DEBUG(print_status(status));
|
||||
|
||||
// If the caller wants the pipe number, include that
|
||||
if ( pipe_num )
|
||||
*pipe_num = ( status >> RX_P_NO ) & B111;
|
||||
@@ -394,6 +425,12 @@ boolean RF24::available(uint8_t* pipe_num)
|
||||
// actually READ the payload?
|
||||
|
||||
write_register(STATUS,_BV(RX_DR) );
|
||||
|
||||
// Handle ack payload receipt
|
||||
if ( status & _BV(TX_DS) )
|
||||
{
|
||||
write_register(STATUS,_BV(TX_DS));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -458,5 +495,67 @@ void RF24::openReadingPipe(uint8_t child, uint64_t value)
|
||||
write_register(EN_RXADDR,en_rx);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
void RF24::toggle_features(void)
|
||||
{
|
||||
csn(LOW);
|
||||
SPI.transfer( ACTIVATE );
|
||||
SPI.transfer( 0x73 );
|
||||
csn(HIGH);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
void RF24::enableAckPayload(void)
|
||||
{
|
||||
//
|
||||
// enable ack payload and dynamic payload features
|
||||
//
|
||||
|
||||
write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
|
||||
|
||||
// If it didn't work, the features are not enabled
|
||||
if ( ! read_register(FEATURE) )
|
||||
{
|
||||
// So enable them and try again
|
||||
toggle_features();
|
||||
write_register(FEATURE,read_register(FEATURE) | _BV(EN_ACK_PAY) | _BV(EN_DPL) );
|
||||
}
|
||||
|
||||
IF_SERIAL_DEBUG(printf("FEATURE=%i\n\r",read_register(FEATURE)));
|
||||
|
||||
//
|
||||
// Enable dynamic payload on pipe 0
|
||||
//
|
||||
|
||||
write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
|
||||
{
|
||||
const uint8_t* current = (const uint8_t*)buf;
|
||||
|
||||
csn(LOW);
|
||||
SPI.transfer( W_ACK_PAYLOAD | ( pipe & B111 ) );
|
||||
uint8_t data_len = min(len,32);
|
||||
while ( data_len-- )
|
||||
SPI.transfer(*current++);
|
||||
|
||||
csn(HIGH);
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
boolean RF24::isAckPayloadAvailable(void)
|
||||
{
|
||||
boolean result = ack_packet_available;
|
||||
ack_packet_available = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
// vim:ai:cin:sts=2 sw=2 ft=cpp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user