nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Discussion about wireless devices

nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Postby Ray » Thu Jan 28, 2010 2:19 pm

I've managed to get data in both directions using enhanced shockburst with the auto-ack enabled. The PTX sends to the PRX which in turn activates the TX function and sends back to the PTX and so on.

I notice that on the datasheet, they whisper about the W_ACK_PAYLOAD command. This should allow the Receiver to send a payload with the ACK packet back to the transmitter.

If this is possible, then it would most likely allow a bidirectional link without the receiver having to put itself specifically into transmit mode and then send a regular packet. There would be a lot less overhead in theory and there would be a higher data rate. It would not be as reliable a link as with both specifially sending and receiving with ACK's but it would be good enough to get data back from the receiver with the packet.

So I've been trying to figure out how to use the excellent library by Brennen to add in the W_ACK_PAYLOAD part.

So far I've come up with these additions:

nrf24l01.h

#define nrf24l01_W_ACK_PAYLOAD 0xA8
#define nrf24l01_W_TX_PAYLOAD_NACK 0xB0
#define nrf24l01_ACTIVATE 0x50
#define nrf24l01_DYNPD 0x1C
#define nrf24l01_FEATURE 0x1D



main unit:

//setup the dynamic packets and put the data into the W_ACK_PAYLOAD to send with the next ACK
nrf24l01_write_register(nrf24l01_ACTIVATE,0x73,1,false);
nrf24l01_write_register(nrf24l01_ACTIVATE,0x73,1);
nrf24l01_write_register(nrf24l01_DYNPD,0x01,1);
nrf24l01_write_register(nrf24l01_FEATURE,0x06,1);
nrf24l01_clear_csn();
nrf24l01_execute_command(nrf24l01_W_ACK_PAYLOAD,&data[1], 32, true);
nrf24l01_set_csn();
nrf24l01_write_register(nrf24l01_ACTIVATE,0x73,1);

nrf24l01_set_as_rx(true);

for(count = 0; count < 2000; count++) //a 2000 timeout to stop the chip from waiting forever if there is no received data.
{
if (nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active())
{
nrf24l01_read_rx_payload(&data[1], 32); //get the payload into data
nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
break; //data came in so exit this loop
}
}

Now my questions:
1. Is it correct to be using the write_register() function to put the data into the registers?
2. Am I writing the correct data to the registers?
3. Is the order correct?
4. In the transmitter code, how do I read it? I am currently just using the nrf24l01_read_rx_payload(&data[1], 32); after I send the packet - i.e. after the ACK is received from the Receiver
Ray
 
Posts: 2
Joined: Thu Jan 28, 2010 2:02 pm

Re: nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Postby brennen » Fri Jan 29, 2010 2:14 pm

1. Is it correct to be using the write_register() function to put the data into the registers?
Yes, this should work fine.

2. Am I writing the correct data to the registers?
Since I can't see all your code, notice that the datasheet says, "A new ACTIVATE command with the same data deactivates them again. This is executable in power down or stand by modes only." Therefore, make sure you only write the ACTIVATE register *once* (it appears you are writing it at least twice in this code), and you are either in standby or power down when you do it (i.e., when CE is *low*). I would probably initially test DYNPD by enabling auto-ack on all pipes instead of pipe 0. I also *would not* enable dynamic payload length in the FEATURE register until you get payload with ACK working first. Also, take out the calls to clear_csn() and set_csn(), as those are already handled in the driver functions.

3. Is the order correct?
I would probably set up the FEATURE register and the EN_AA register before setting up the DYNPD register, but it shouldn't matter. You should also remove all writes to the ACTIVATE register except for the second one you have in the code below (the first one should have caused a syntax error).

4. In the transmitter code, how do I read it? I am currently just using the nrf24l01_read_rx_payload(&data[1], 32); after I send the packet - i.e. after the ACK is received from the Receiver
It doesn't really seem to specify how to read it in the manual, so I assume that you're write by reading the RX payload.
brennen
Site Admin
 
Posts: 395
Joined: Sun Aug 17, 2008 2:15 pm

Re: nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Postby zristic » Mon Feb 08, 2010 10:04 am

I finally got it working. My source code is a bit messy at the moment, but I will post it when I get it organized. It is entirely written in mikroPascal as a part of a commercial project, but I will publish a portion which sets the ack payload feature.

The few main points are:
1. Turn on dynamic payload,
2. Turn on ack payload feature,
3. Make sure that the ARD is set to at least 500us,
4. Prepare the ackpayload data on Rx side before any data arrives,

Points 1. and 2. are done by writing 0x06 to the Feature register. After setting the Feature register, read it back. If it returns zero then call the Activate command with the parameter 0x73. Then set the feature register again.

Reading the payload on Tx side is done simply by reading the RxBuff register.

I am doing tests at the moment, so far I am very happy with how it works.
zristic
 
Posts: 3
Joined: Sat Apr 25, 2009 2:38 pm

Re: nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Postby zristic » Tue Mar 02, 2010 8:12 pm

Here are pieces of my code which is a part of a commercial project, so I cannot reveal all the details, but I am sure this will be more than enough to make ACK PYLD feature working.
I hope you guys can read Pascal, at least we learned it in school at the beginning of our programming days. Let's not forget it, it is such a beautiful language. :ugeek:

1. 2. Turn on dynamic payload and ack payload:
Code: Select all
 
procedure TurnOnAckPayload;
var temp, buffer: byte;
begin
  temp := Read_Register(Feature);  // read feature Register

                                   // prepare the data for writing to the feature register
  buffer := temp or 0x06;          // turn on ack payload and dynamic payload
  Write_Register(Feature, buffer); // write to the feature register

  temp := Read_Register(Feature);  // read feature Register to see if the setting has taken effect
  if temp = 0 then                 // no success, execute the "Activate" command and try again
     begin
       buffer := 0x73;
       Write_Command(Activate, buffer);
                                   // prepare the data for writing to the feature register
       buffer := temp or 0x06;     // turn on ack payload and dynamic payload
       Write_Register(Feature, buffer); // write to the feature register
     end;
end;


3. Make sure that the ARD is set to at least 500us:

Code: Select all
  buffer := 0xFF;  // max Number of retries = 15; 4ms between two retries
  Write_Register(Setup_Retr, buffer);


4. Prepare the ackpayload data on Rx side before any data arrives:
Code: Select all
  // write some data to the outgoing buffer
  PayLoadBuff[0] := 0;
  PayLoadBuff[1] := 1;
  PayLoadBuff[2] := 2;
  ... etc
  // clear the previous payload buffer, it might not have been sent yet
  FlushTxBuffer();
  // put the new payload data into the outgoing buffer
  write_ack_payload(PayLoadBuff, 0);
  // now we wait for the Tx to call us:
  while IRQ <> 0 do
    begin
      // do something while waiting
    end;


Here are some auxiliary functions:

Code: Select all
procedure write_ack_payload(var payload : array[20] of byte; pipe : byte);
var i, buffer : byte;
begin
  Write_Register(w_ack_payload, pipe);
  for i := 0 to 19 do
    begin
        buffer := payload[i];   
       Write_Register(w_ack_payload, buffer);
    end;
end;


Flushing the Tx Buffer
Code: Select all
procedure FlushTxBuffer();
begin
  //flush The Tx_fifo Buffer
  Write_Command(Flush_tx);
end;


This is what i did in order to make the ACK PAYLOAD feature work on NRF24L01 and L01+.
I am using this code for some time now. It is not perfectly organized, but at least it is working for me.
Any suggestions/improvements are welcomed.
zristic
 
Posts: 3
Joined: Sat Apr 25, 2009 2:38 pm

Re: nrf24l01+ Bidirectional link using W_ACK_PAYLOAD

Postby Ray » Mon Nov 02, 2015 1:44 pm

Hi all,

I would like to try again with the W_ACK_PAYLOAD stuff. Has anyone gotten it working yet?

I can send and receive data fine on both sides if I set the TX and RX separately. The data is quite good with a packet lost every few minutes or so. If I increase the range then more packets are lost. It is a bidirectional link and works really nicely.

I would like to now try the W_ACK_PAYLOAD again, increase the data rate and then hopefully have a bidirectional link without having to separately set both RX TX then TX RX etc...

Any advice on the code below? I can transmit and get the ACK, but not the ACK with payload. Perhaps I am setting something incorrectly. Any help would be greatly appreciated.

RECEIVER CODE:

char data[32];

Code: Select all
nrf24l01_initialize_debug(true, 32, true); //initialize the 24L01 to the debug configuration as TX, 1 data byte, and auto-ack disabled
                               //false transmit   true receive

 nrf24l01_read_register(nrf24l01_FEATURE,temp,1);
 btemp= temp|0x06;
 nrf24l01_write_register(nrf24l01_FEATURE,btemp,1);

 nrf24l01_read_register(nrf24l01_FEATURE,temp,1);
 
 if (temp==0)
 {
   nrf24l01_write_register(nrf24l01_ACTIVATE,0x73,1);
   btemp= 0x06;//temp|0x06;
   nrf24l01_write_register(nrf24l01_FEATURE,btemp,1);
 }

  nrf24l01_write_register(nrf24l01_DYNPD,0x01,1);

 for (i=1;i<32;i++)   //197
     {
     data[i]= 0x33;
     }
 
nrf24l01_write_register(nrf24l01_W_ACK_PAYLOAD,&data[1], 32);
 

while(1)
{
// nrf24l01_flush_tx();     

for (i=1;i<32;i++)   //197
     {
     data[i]= 0x33;
     }
 
nrf24l01_write_register(nrf24l01_W_ACK_PAYLOAD,&data[1], 32);

 PORTDbits.RD1 = 0; //BLUE
 PORTDbits.RD2 = 0; //GREEN
 PORTDbits.RD3 = 0; //RED

 nrf24l01_set_as_rx(true);
 
for(count = 0; count <400; count++) 
  {
 
    if (nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active())   //Received Data
   {
       
     
      nrf24l01_read_rx_payload(&data[1], 32); //get the payload into data
      nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
     
      PORTDbits.RD1 = 1; //BLUE
      PORTDbits.RD2 = 0; //GREEN
      PORTDbits.RD3 = 0; //RED
         
    }
    _asm CLRWDT _endasm   
  }


 nrf24l01_irq_clear_all(); //put in for TX
  nrf24l01_flush_tx();
  nrf24l01_flush_rx();   

}



TRANSMIT CODE:

The BLUE LED comes on indicating that the auto ack was received. When we check a byte on the payload, it should be 0x33, but alas, it is 0x00.


Code: Select all

char data[32];

nrf24l01_initialize_debug(false, 32, true); //initialize the 24L01 to the debug configuration as TX, 1 data byte, and auto-ack disabled
                               //false transmit   true receive

nrf24l01_read_register(nrf24l01_FEATURE,temp,1);
btemp= temp|0x06;
nrf24l01_write_register(nrf24l01_FEATURE,btemp,1);
nrf24l01_read_register(nrf24l01_FEATURE,temp,1);
 
if (temp==0)
{
  nrf24l01_write_register(nrf24l01_ACTIVATE,0x73,1);
  btemp= 0x06;//temp|0x06;
  nrf24l01_write_register(nrf24l01_FEATURE,btemp,1);
}

 nrf24l01_write_register(nrf24l01_DYNPD,0x01,1);

while(1)
{
_asm CLRWDT _endasm 

nrf24l01_irq_clear_all();
nrf24l01_flush_tx();
nrf24l01_flush_rx();
       
nrf24l01_set_as_tx();

nrf24l01_write_tx_payload(&data[1], 32, true);
 
 for(count = 0; count < 350; count++)  //350 okay
  {
   _asm CLRWDT _endasm 
   
    if (nrf24l01_irq_max_rt_active() ) //Max retries have been triggered - unsucessful send
    {
      PORTDbits.RD1 = 0;
      PORTDbits.RD2 = 0;
      PORTDbits.RD3 = 1;                    //Red LED comes on.
      break;
    }


    if (nrf24l01_irq_tx_ds_active() && nrf24l01_irq_pin_active()) //
    {
     nrf24l01_read_rx_payload(&data[1], 32);
     
      PORTDbits.RD1 = 1;                               // BLUE LED comes on all the time showing that the data was successfully sent
    //  PORTDbits.RD2 = 0;//1;
      PORTDbits.RD3 = 0;

      if (data[10] == 0x33)
      {
      PORTDbits.RD1 = 1;                                // RED, BLUE, GREEN = WHITE LED - It never gets to this part
      PORTDbits.RD2 = 1;
      PORTDbits.RD3 = 1;
      while(1) { }
      }
      break;
    }
  }

}


HEADERS - Added the W_ACK_PAYLOAD STUFF to Brennon's Library

Code: Select all
/******************************************************************************
*
* File: nrf24l01.h
*
* Copyright S. Brennen Ball, 2006-2007
*
* The author provides no guarantees, warantees, or promises, implied or
*   otherwise.  By using this software you agree to indemnify the author
*    of any damages incurred by using it.
*
*****************************************************************************/

#ifndef NRF24L01_H_
#define NRF24L01_H_

#include <stddef.h>
//#include "system\typedefs.h"   

//typedef enum _bool { false = 0, true =1 } bool;



#ifndef bool
#define bool unsigned char
#endif
#ifndef false
#define false 0
#endif
#ifndef true
#define true !false
#endif




/////////////////////////////////////////////////////////////////////////////////
// SPI function requirements
//
// The user must define a function to send one byte of data and also return the
//   resulting byte of data data through the SPI port. The function used here
//   has the function prototype
//
//       unsigned char spi_send_read_byte(unsigned char byte);
//
// This function should take the argument unsigned char byte and send it through
//   the SPI port to the 24L01.  Then, it should wait until the 24L01 has returned
//   its response over SPI.  This received byte should be the return value of the
//   function.
//
// You should also change the include file name below to whatever the name of your
//   SPI include file is.
//////////////////////////////////////////////////////////////////////////////////
#include "spi1.h"
#define spi_send_read_byte(byte)   spi1_send_read_byte(byte)


/////////////////////////////////////////////////////////////////////////////////
// Delay function requirements
//
// The user must define a function that delays for the specified number of
//    microseconds. This function needs to be as precise as possible, and the use
//   of a timer module within your microcontroller is highly recommended. The
//   function used here has the prototype
//
//       void delay_us(unsigned int microseconds);
//
// You should also change the include file name below to whatever the name of your
//   delay include file is.
//////////////////////////////////////////////////////////////////////////////////
#include "delays.h"
#define delay_us(microseconds)      DelayUS(microseconds)


//////////////////////////////////////////////////////////////////////////////////
// IO pin definitions
//
// Below you will find several definitions and includes.  The first is an #include
//   for your microcontroller's include file to allow you to use register names
//   rather than numbers.  The next three are to allow you to control the pins on
//   the 24L01 that aren't automatically handled by SPI.  These are CE, CSN, and
//   IRQ.
//
// The general format of these defines is a define for the IO register the pin is
//   attached to.  The second define is a mask for the pin.  For example, say that
//   your CE pin is tied to an IO port with the register name IOPORT1. Also, let's
//   say that the IO port is 8-bits wide, and you have attached the pin to pin 0 of
//   the port.  Then your define would look like this:
//
//    #define nrf24l01_CE_IOREGISTER      IOPORT1
//   #define nrf24l01_CE_PINMASK      0x01
//
// If you have defines in your include file for individual IO pins, you could use
//   this define in this file, as well.  Using the previous example, assume that in
//   your microcontroller's include file, pin 0 of IOPORT1 has a define like this
//
//   #define IOPORT1_PIN0   0x01
//
// Then, you could make your defines for the CE pin in this file look like this:
//
//    #define nrf24l01_CE_IOREGISTER      IOPORT1
//   #define nrf24l01_CE_PINMASK      IOPORT1_PIN0
//
// You should also change the include file name below to whatever the name of your
//   processor's register definition include file is.
/////////////////////////////////////////////////////////////////////////////////////
#include <p18f4550.h>

//defines for uC pins CE pin is connected to
//This is used so that the routines can send TX payload data and
//   properly initialize the nrf24l01 in TX and RX states.
//Change these definitions (and then recompile) to suit your particular application.
#define nrf24l01_CE_IOREGISTER      PORTB  //PORTB  //RB4
#define nrf24l01_CE_PINMASK         0x10   //0x10

//defines for uC pins CSN pin is connected to
//This is used so that the routines can send properly operate the SPI interface
// on the nrf24l01.
//Change these definitions (and then recompile) to suit your particular application.
#define nrf24l01_CSN_IOREGISTER      PORTB  //PORTB  //RB3
#define nrf24l01_CSN_PINMASK      0x08   //0x08

//defines for uC pins IRQ pin is connected to
//This is used so that the routines can poll for IRQ or create an ISR.
//Change these definitions (and then recompile) to suit your particular application.
#define nrf24l01_IRQ_IOREGISTER      PORTB   //PORTB  //RB2
#define nrf24l01_IRQ_PINMASK      0x04    //0x04


////////////////////////////////////////////////////////////////////////////////////
// SPI commands
//
// The following are defines for all of the commands and data masks on the SPI
//   interface.
////////////////////////////////////////////////////////////////////////////////////
//SPI command defines
#define nrf24l01_R_REGISTER      0x00
#define nrf24l01_W_REGISTER      0x20
#define nrf24l01_R_RX_PAYLOAD   0x61
#define nrf24l01_W_TX_PAYLOAD   0xA0
#define nrf24l01_FLUSH_TX      0xE1
#define nrf24l01_FLUSH_RX      0xE2
#define nrf24l01_REUSE_TX_PL   0xE3
#define nrf24l01_NOP         0xFF

#define nrf24l01_ACTIVATE 0x50

#define nrf24L01_R_RX_PL_WID        0x60
#define nrf24L01_W_ACK_PAYLOAD      0xA8
#define nrf24L01_W_TX_PAYLOAD_NOACK 0xB0


//SPI command data mask defines
#define nrf24l01_R_REGISTER_DATA   0x1F
#define nrf24l01_W_REGISTER_DATA   0x1F

///////////////////NEW HIDDEN FEATURES FOR ACK PAYLOAD

//#define nrf24l01_W_ACK_PAYLOAD       0xA8
//#define NRF24L01_W_TX_PAYLOAD_NACK   0xB0

////////////////////////////////////////////////////////////////////////////////////
// Register definitions
//
// Below are the defines for each register's address in the 24L01.
////////////////////////////////////////////////////////////////////////////////////
#define nrf24l01_CONFIG         0x00
#define nrf24l01_EN_AA         0x01
#define nrf24l01_EN_RXADDR      0x02
#define nrf24l01_SETUP_AW      0x03
#define nrf24l01_SETUP_RETR      0x04
#define nrf24l01_RF_CH         0x05
#define nrf24l01_RF_SETUP      0x06 
#define nrf24l01_STATUS         0x07
#define nrf24l01_OBSERVE_TX      0x08
#define nrf24l01_CD            0x09
#define nrf24l01_RX_ADDR_P0      0x0A
#define nrf24l01_RX_ADDR_P1      0x0B
#define nrf24l01_RX_ADDR_P2      0x0C
#define nrf24l01_RX_ADDR_P3      0x0D
#define nrf24l01_RX_ADDR_P4      0x0E
#define nrf24l01_RX_ADDR_P5      0x0F
#define nrf24l01_TX_ADDR      0x10
#define nrf24l01_RX_PW_P0      0x11
#define nrf24l01_RX_PW_P1      0x12
#define nrf24l01_RX_PW_P2      0x13
#define nrf24l01_RX_PW_P3      0x14
#define nrf24l01_RX_PW_P4      0x15
#define nrf24l01_RX_PW_P5      0x16
#define nrf24l01_FIFO_STATUS   0x17
#define nrf24l01_DYNPD         0x1C
#define nrf24l01_FEATURE         0x1D

#define nrf24l01_W_ACK_PAYLOAD 0xA8
#define nrf24l01_W_TX_PAYLOAD_NACK 0xB0
#define nrf24l01_ACTIVATE 0x50
#define nrf24l01_DYNPD 0x1C
#define nrf24l01_FEATURE 0x1D

////////////////////////////////////////////////////////////////////////////////////
// Default register values
//
// Below are the defines for each register's default value in the 24L01. Multi-byte
//   registers use notation B<X>, where "B" represents "byte" and <X> is the byte
//   number.
////////////////////////////////////////////////////////////////////////////////////
#define nrf24l01_CONFIG_DEFAULT_VAL         0x08
#define nrf24l01_EN_AA_DEFAULT_VAL         0x3F
#define nrf24l01_EN_RXADDR_DEFAULT_VAL      0x03
#define nrf24l01_SETUP_AW_DEFAULT_VAL      0x03
#define nrf24l01_SETUP_RETR_DEFAULT_VAL      0x37//25//4F   //0x17
#define nrf24l01_RF_CH_DEFAULT_VAL         0x15//2A//1A//15//41   // was 0x52 Channel for Radio ******************************************************************************************************************
#define nrf24l01_RF_SETUP_DEFAULT_VAL      0x27//27   //27  //was 0x0f

#define nrf24l01_STATUS_DEFAULT_VAL         0x0e  //0e
#define nrf24l01_OBSERVE_TX_DEFAULT_VAL      0x00
#define nrf24l01_CD_DEFAULT_VAL            0x00
#define nrf24l01_RX_ADDR_P0_B0_DEFAULT_VAL   0xE7
#define nrf24l01_RX_ADDR_P0_B1_DEFAULT_VAL   0xE7
#define nrf24l01_RX_ADDR_P0_B2_DEFAULT_VAL   0xE7
#define nrf24l01_RX_ADDR_P0_B3_DEFAULT_VAL   0xE7
#define nrf24l01_RX_ADDR_P0_B4_DEFAULT_VAL   0xE7
#define nrf24l01_RX_ADDR_P1_B0_DEFAULT_VAL   0xC2
#define nrf24l01_RX_ADDR_P1_B1_DEFAULT_VAL   0xC2
#define nrf24l01_RX_ADDR_P1_B2_DEFAULT_VAL   0xC2
#define nrf24l01_RX_ADDR_P1_B3_DEFAULT_VAL   0xC2
#define nrf24l01_RX_ADDR_P1_B4_DEFAULT_VAL   0xC2
#define nrf24l01_RX_ADDR_P2_DEFAULT_VAL      0xC3
#define nrf24l01_RX_ADDR_P3_DEFAULT_VAL      0xC4
#define nrf24l01_RX_ADDR_P4_DEFAULT_VAL      0xC5
#define nrf24l01_RX_ADDR_P5_DEFAULT_VAL      0xC6
#define nrf24l01_TX_ADDR_B0_DEFAULT_VAL      0xE7
#define nrf24l01_TX_ADDR_B1_DEFAULT_VAL      0xE7
#define nrf24l01_TX_ADDR_B2_DEFAULT_VAL      0xE7
#define nrf24l01_TX_ADDR_B3_DEFAULT_VAL      0xE7
#define nrf24l01_TX_ADDR_B4_DEFAULT_VAL      0xE7
#define nrf24l01_RX_PW_P0_DEFAULT_VAL      0x00
#define nrf24l01_RX_PW_P1_DEFAULT_VAL      0x00
#define nrf24l01_RX_PW_P2_DEFAULT_VAL      0x00
#define nrf24l01_RX_PW_P3_DEFAULT_VAL      0x00
#define nrf24l01_RX_PW_P4_DEFAULT_VAL      0x00
#define nrf24l01_RX_PW_P5_DEFAULT_VAL      0x00
#define nrf24l01_FIFO_STATUS_DEFAULT_VAL   0x11

////////////////////////////////////////////////////////////////////////////////////
// Register bitwise definitions
//
// Below are the defines for each register's bitwise fields in the 24L01.
////////////////////////////////////////////////////////////////////////////////////
//CONFIG register bitwise definitions
#define nrf24l01_CONFIG_RESERVED   0x80
#define   nrf24l01_CONFIG_MASK_RX_DR   0x40
#define   nrf24l01_CONFIG_MASK_TX_DS   0x20
#define   nrf24l01_CONFIG_MASK_MAX_RT   0x10
#define   nrf24l01_CONFIG_EN_CRC      0x08
#define   nrf24l01_CONFIG_CRCO      0x04
#define   nrf24l01_CONFIG_PWR_UP      0x02
#define   nrf24l01_CONFIG_PRIM_RX      0x01

//EN_AA register bitwise definitions
#define nrf24l01_EN_AA_RESERVED      0xC0
#define nrf24l01_EN_AA_ENAA_ALL      0x3F
#define nrf24l01_EN_AA_ENAA_P5      0x20
#define nrf24l01_EN_AA_ENAA_P4      0x10
#define nrf24l01_EN_AA_ENAA_P3      0x08
#define nrf24l01_EN_AA_ENAA_P2      0x04
#define nrf24l01_EN_AA_ENAA_P1      0x02
#define nrf24l01_EN_AA_ENAA_P0      0x01
#define nrf24l01_EN_AA_ENAA_NONE   0x00

//EN_RXADDR register bitwise definitions
#define nrf24l01_EN_RXADDR_RESERVED   0xC0
#define nrf24l01_EN_RXADDR_ERX_ALL   0x3F
#define nrf24l01_EN_RXADDR_ERX_P5   0x20
#define nrf24l01_EN_RXADDR_ERX_P4   0x10
#define nrf24l01_EN_RXADDR_ERX_P3   0x08
#define nrf24l01_EN_RXADDR_ERX_P2   0x04
#define nrf24l01_EN_RXADDR_ERX_P1   0x02
#define nrf24l01_EN_RXADDR_ERX_P0   0x01
#define nrf24l01_EN_RXADDR_ERX_NONE   0x00

//SETUP_AW register bitwise definitions
#define nrf24l01_SETUP_AW_RESERVED   0xFC
#define nrf24l01_SETUP_AW         0x03
#define nrf24l01_SETUP_AW_5BYTES   0x03
#define nrf24l01_SETUP_AW_4BYTES   0x02
#define nrf24l01_SETUP_AW_3BYTES   0x01
#define nrf24l01_SETUP_AW_ILLEGAL   0x00

//SETUP_RETR register bitwise definitions
#define nrf24l01_SETUP_RETR_ARD         0xF0
#define nrf24l01_SETUP_RETR_ARD_4000   0xF0
#define nrf24l01_SETUP_RETR_ARD_3750   0xE0
#define nrf24l01_SETUP_RETR_ARD_3500   0xD0
#define nrf24l01_SETUP_RETR_ARD_3250   0xC0
#define nrf24l01_SETUP_RETR_ARD_3000   0xB0
#define nrf24l01_SETUP_RETR_ARD_2750   0xA0
#define nrf24l01_SETUP_RETR_ARD_2500   0x90
#define nrf24l01_SETUP_RETR_ARD_2250   0x80
#define nrf24l01_SETUP_RETR_ARD_2000   0x70
#define nrf24l01_SETUP_RETR_ARD_1750   0x60
#define nrf24l01_SETUP_RETR_ARD_1500   0x50
#define nrf24l01_SETUP_RETR_ARD_1250   0x40
#define nrf24l01_SETUP_RETR_ARD_1000   0x30
#define nrf24l01_SETUP_RETR_ARD_750      0x20
#define nrf24l01_SETUP_RETR_ARD_500      0x10
#define nrf24l01_SETUP_RETR_ARD_250      0x00
#define nrf24l01_SETUP_RETR_ARC         0x0F
#define nrf24l01_SETUP_RETR_ARC_15      0x0F
#define nrf24l01_SETUP_RETR_ARC_14      0x0E
#define nrf24l01_SETUP_RETR_ARC_13      0x0D
#define nrf24l01_SETUP_RETR_ARC_12      0x0C
#define nrf24l01_SETUP_RETR_ARC_11      0x0B
#define nrf24l01_SETUP_RETR_ARC_10      0x0A
#define nrf24l01_SETUP_RETR_ARC_9      0x09
#define nrf24l01_SETUP_RETR_ARC_8      0x08
#define nrf24l01_SETUP_RETR_ARC_7      0x07
#define nrf24l01_SETUP_RETR_ARC_6      0x06
#define nrf24l01_SETUP_RETR_ARC_5      0x05
#define nrf24l01_SETUP_RETR_ARC_4      0x04
#define nrf24l01_SETUP_RETR_ARC_3      0x03
#define nrf24l01_SETUP_RETR_ARC_2      0x02
#define nrf24l01_SETUP_RETR_ARC_1      0x01
#define nrf24l01_SETUP_RETR_ARC_0      0x00

//RF_CH register bitwise definitions
#define nrf24l01_RF_CH_RESERVED   0x80

//RF_SETUP register bitwise definitions
#define nrf24l01_RF_SETUP_RESERVED   0xE0
#define nrf24l01_RF_SETUP_PLL_LOCK   0x10
#define nrf24l01_RF_SETUP_RF_DR      0x08
#define nrf24l01_RF_SETUP_RF_PWR   0x06
#define nrf24l01_RF_SETUP_RF_PWR_0   0x06
#define nrf24l01_RF_SETUP_RF_PWR_6    0x04
#define nrf24l01_RF_SETUP_RF_PWR_12   0x02
#define nrf24l01_RF_SETUP_RF_PWR_18   0x00
#define nrf24l01_RF_SETUP_LNA_HCURR   0x01

//STATUS register bitwise definitions
#define nrf24l01_STATUS_RESERVED               0x80
#define nrf24l01_STATUS_RX_DR                  0x40
#define nrf24l01_STATUS_TX_DS                  0x20
#define nrf24l01_STATUS_MAX_RT                  0x10
#define nrf24l01_STATUS_RX_P_NO                  0x0E
#define nrf24l01_STATUS_RX_P_NO_RX_FIFO_NOT_EMPTY   0x0E
#define nrf24l01_STATUS_RX_P_NO_UNUSED            0x0C
#define nrf24l01_STATUS_RX_P_NO_5               0x0A
#define nrf24l01_STATUS_RX_P_NO_4               0x08
#define nrf24l01_STATUS_RX_P_NO_3               0x06
#define nrf24l01_STATUS_RX_P_NO_2               0x04
#define nrf24l01_STATUS_RX_P_NO_1               0x02
#define nrf24l01_STATUS_RX_P_NO_0               0x00
#define nrf24l01_STATUS_TX_FULL                  0x01

//OBSERVE_TX register bitwise definitions
#define nrf24l01_OBSERVE_TX_PLOS_CNT   0xF0
#define nrf24l01_OBSERVE_TX_ARC_CNT      0x0F

//CD register bitwise definitions
#define nrf24l01_CD_RESERVED   0xFE
#define nrf24l01_CD_CD         0x01

//RX_PW_P0 register bitwise definitions
#define nrf24l01_RX_PW_P0_RESERVED   0xC0

//RX_PW_P0 register bitwise definitions
#define nrf24l01_RX_PW_P0_RESERVED   0xC0

//RX_PW_P1 register bitwise definitions
#define nrf24l01_RX_PW_P1_RESERVED   0xC0

//RX_PW_P2 register bitwise definitions
#define nrf24l01_RX_PW_P2_RESERVED   0xC0

//RX_PW_P3 register bitwise definitions
#define nrf24l01_RX_PW_P3_RESERVED   0xC0

//RX_PW_P4 register bitwise definitions
#define nrf24l01_RX_PW_P4_RESERVED   0xC0

//RX_PW_P5 register bitwise definitions
#define nrf24l01_RX_PW_P5_RESERVED   0xC0

//FIFO_STATUS register bitwise definitions
#define nrf24l01_FIFO_STATUS_RESERVED   0x8C
#define nrf24l01_FIFO_STATUS_TX_REUSE   0x40
#define nrf24l01_FIFO_STATUS_TX_FULL   0x20
#define nrf24l01_FIFO_STATUS_TX_EMPTY   0x10
#define nrf24l01_FIFO_STATUS_RX_FULL   0x02
#define nrf24l01_FIFO_STATUS_RX_EMPTY   0x01

////////////////////////////////////////////////////////////////////////////////////
// Function declarations
//
// Below are all function definitions contained in the library.  Please see
//   nrf24l01.c for comments regarding the usage of each function.
////////////////////////////////////////////////////////////////////////////////////
//initialization functions
void nrf24l01_initialize(unsigned char config,
                   unsigned char opt_rx_standby_mode,
                   unsigned char en_aa,
                   unsigned char en_rxaddr,
                   unsigned char setup_aw,
                   unsigned char setup_retr,
                   unsigned char rf_ch,
                   unsigned char rf_setup,
                   unsigned char * rx_addr_p0,
                   unsigned char * rx_addr_p1,
                   unsigned char rx_addr_p2,
                   unsigned char rx_addr_p3,
                   unsigned char rx_addr_p4,
                   unsigned char rx_addr_p5,
                   unsigned char * tx_addr,
                   unsigned char rx_pw_p0,
                   unsigned char rx_pw_p1,
                   unsigned char rx_pw_p2,
                   unsigned char rx_pw_p3,
                   unsigned char rx_pw_p4,
                   unsigned char rx_pw_p5);
void nrf24l01_initialize_debug(bool rx, unsigned char p0_payload_width, bool enable_auto_ack);
void nrf24l01_initialize_debug_lite(bool rx, unsigned char p0_payload_width);

//power-up, power-down functions
void nrf24l01_power_up(bool rx_active_mode);
void nrf24l01_power_up_param(bool rx_active_mode, unsigned char config);
void nrf24l01_power_down(void);
void nrf24l01_power_down_param(unsigned char config);

//SPI commands defined by the spec
//for regnumber values, see section above titled "register definitions"
//all functions return the STATUS register
unsigned char nrf24l01_write_register(unsigned char regnumber, unsigned char * data, unsigned int len);
unsigned char nrf24l01_read_register(unsigned char regnumber, unsigned char * data, unsigned int len);
unsigned char nrf24l01_write_tx_payload(unsigned char * data, unsigned int len, bool transmit);
unsigned char nrf24l01_read_rx_payload(unsigned char * data, unsigned int len);
unsigned char nrf24l01_flush_tx(void);
unsigned char nrf24l01_flush_rx(void);
unsigned char nrf24l01_reuse_tx_pl(void);
unsigned char nrf24l01_nop(void);

//RX/TX setting functions
void nrf24l01_set_as_rx(bool rx_active_mode);
void nrf24l01_set_as_rx_param(bool rx_active_mode, unsigned char config);
void nrf24l01_rx_standby_to_active(void);
void nrf24l01_rx_active_to_standby(void);
void nrf24l01_set_as_tx(void);
void nrf24l01_set_as_tx_param(unsigned char config);

//register-oriented get/set functions for commonly-used registers during operation
unsigned char nrf24l01_get_config(void);
void nrf24l01_set_config(unsigned char config);
unsigned char nrf24l01_get_rf_ch(void);
void nrf24l01_set_rf_ch(unsigned char channel);
unsigned char nrf24l01_get_status(void);
unsigned char nrf24l01_get_observe_tx(void);
void nrf24l01_set_rx_addr(unsigned char * address, unsigned int len, unsigned char rxpipenum);
void nrf24l01_set_tx_addr(unsigned char * address, unsigned int len);
void nrf24l01_set_rx_pw(unsigned char payloadwidth, unsigned char rxpipenum);
unsigned char nrf24l01_get_rx_pw(unsigned char rxpipenum);
unsigned char nrf24l01_get_fifo_status(void);

//auto-ack and pipe-related functions
bool nrf24l01_aa_enabled(unsigned char rxpipenum);
void nrf24l01_aa_enable(unsigned char rxpipenum);
void nrf24l01_aa_disable(unsigned char rxpipenum);
bool nrf24l01_rx_pipe_enabled(unsigned char rxpipenum);
void nrf24l01_rx_pipe_enable(unsigned char rxpipenum);
void nrf24l01_rx_pipe_disable(unsigned char rxpipenum);
unsigned char nrf24l01_get_plos_cnt(void);
void nrf24l01_clear_plos_cnt(void);
void nrf24l01_clear_plos_cnt_param(unsigned char rf_ch);
unsigned char nrf24l01_get_arc_cnt(void);

//utility functions
bool nrf24l01_cd_active(void);
void nrf24l01_clear_flush(void);
unsigned char nrf24l01_get_rx_pipe(void);
unsigned char nrf24l01_get_rx_pipe_from_status(unsigned char status);
void nrf24l01_get_all_registers(unsigned char * data);

//interrupt check/clear functions
bool nrf24l01_irq_pin_active(void);
bool nrf24l01_irq_rx_dr_active(void);
bool nrf24l01_irq_tx_ds_active(void);
bool nrf24l01_irq_max_rt_active(void);
void nrf24l01_irq_clear_all(void);
void nrf24l01_irq_clear_rx_dr(void);
void nrf24l01_irq_clear_tx_ds(void);
void nrf24l01_irq_clear_max_rt(void);

//FIFO_STATUS check functions
bool nrf24l01_fifo_tx_reuse(void);
bool nrf24l01_fifo_tx_full(void);
bool nrf24l01_fifo_tx_empty(void);
bool nrf24l01_fifo_rx_full(void);
bool nrf24l01_fifo_rx_empty(void);

//IO interface-related functions
void nrf24l01_transmit(void);
void nrf24l01_clear_ce(void);
void nrf24l01_set_ce(void);
void nrf24l01_clear_csn(void);
void nrf24l01_set_csn(void);
bool nrf24l01_ce_pin_active(void);
bool nrf24l01_csn_pin_active(void);




//low-level functions for library use only
unsigned char nrf24l01_execute_command(unsigned char instruction, unsigned char * data, unsigned int len, bool copydata);
void nrf24l01_spi_send_read(unsigned char * data, unsigned int len, bool copydata);

#endif /*NRF24L01_H_*/
Ray
 
Posts: 2
Joined: Thu Jan 28, 2010 2:02 pm


Return to Wireless

Who is online

Users browsing this forum: No registered users and 2 guests

cron