Help enabling enhanced shockburst for the NRF24L01

I have working code for the NRF24L01 transceiver written with the CCS compiler. The driver works great as a standalone bidirectional transceiver but I’d like to use enhanced shockburst with the driver I have written.

I have followed the data sheet step by step for enhanced shockburst but cannot get it to work. Can someone shed some light?

Thanks

NRF24L01 DRIVER (not using enhanced shockbust)

/**************** Preprocessor Constants ***************************************/
#define CONFIG             0x20
#define EN_AA              0x21
#define EN_RXADDR          0x22
#define SETUP_AW           0x23
#define SETUP_RETR         0x24
#define RF_CH              0x25
#define RF_SETUP           0x26
#define STATUS             0x27
#define RX_ADDR_P0         0x2A
#define TX_ADDR            0x30
#define RX_PW_P0           0x31
#define FLUSH_TX           0xE1
#define FLUSH_RX           0xE2
#define TX_PAYLOAD         0xA0
#define RX_PAYLOAD         0x61
#define NO_OP              0xFF
#define ZERO               0x00
#define EOT                0x04
#define PAYLOAD_SIZE       0x20
#define start_transmit    {output_high(rf_CE);delay_us(20);output_low(rf_CE);}  //Pulse NRF24L01 CE pin for 20us

int1 rf_interrupt=false;                                                        // Declare interrupt flag default is false
static int16 rf_CE,rf_CSN;                                                      // Declare NRF24L01 SPI CE & CSN pins

/**************** Gets The Length Of A Data Packet *****************************/
unsigned int* length(unsigned int *data)
{
   int *cnt;                                                                    // Declare a pointer
   for (cnt = data; *cnt != 0; cnt++);                                          // Loop
   return(cnt - data);                                                          // Return the length of the data                             
}

/**************** Write To NRF24L01 Configuration Register *********************/
void set_register(unsigned int command,unsigned int data)
{
   output_low(rf_CSN);                                                          // Engage SPI chip select
   spi_write(command);                                                          // Write to register
   if(data!=NO_OP){spi_write(data);}                                            // Write data to register
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
   delay_us(10);
}

/**************** Write To NRF24L01 Configuration Register *********************/
void set_register(unsigned int command,unsigned int* data)
{
   int i,len;
   len=length(data);                                                            // Get the length of the data
   output_low(rf_CSN);                                                          // Engage SPI chip select
   spi_write(command);                                                          // Write to register
   for(i=0;i<len;i++){spi_write(data[i]);}                                      // Write data to register
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
   delay_us(10);
}

/**************** Enables NRF24L01 Transmit/Receive Mode ***********************/
void transmit_mode(unsigned int1 enable)
{
   output_low(rf_CE);                                                           // Disable receiver
   set_register(STATUS,0x7E);                                                   // Clear all interrupts
   if(enable)
   {
      set_register(FLUSH_TX,NO_OP);                                             // Flush TX FIFO buffer
      set_register(CONFIG,0x52);                                                // Power up in transmit mode
   }
   else
   {
      set_register(FLUSH_RX,NO_OP);                                             // Flush RX FIFO buffer
      set_register(CONFIG,0x33);                                                // Power up in receive mode
      output_high(rf_CE);                                                       // Enable receiver
      delay_us(130);                                                            // Delay 130us
   }
}

/**************** Transmits A Single Byte **************************************/
void rf_transmit(unsigned int data)
{
   transmit_mode(true);                                                         // Enable transmit mode
   output_low(rf_CSN);                                                          // Engage SPI chip select
   spi_write(TX_PAYLOAD);                                                       // Select tx payload register
   spi_write(data);                                                             // Write data to tx payload register
   spi_write(EOT);                                                              // End of transmission
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
   start_transmit;                                                              // Start transmission
   transmit_mode(false);                                                        // Enable receive mode
   delay_ms(50);                                                                // Delay 50ms
}

/**************** Transmits A String Of Data ***********************************/
void rf_transmit(unsigned char *string)
{
   int i,len=0;
   len=length(string);                                                          // Get the length of the data to transmit
   transmit_mode(true);                                                         // Enable transmit mode
   output_low(rf_CSN);                                                          // Engage SPI chip select
   spi_write(TX_PAYLOAD);                                                       // Select tx payload register
   for(i=0;i<len;i++){spi_write(string[i]);}                                    // Write data to tx payload register
   spi_write(EOT);                                                              // End of transmission
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
   start_transmit;                                                              // Start transmission
   transmit_mode(false);                                                        // Enable receive mode
   delay_ms(50);                                                                // Delay 50ms
}

/**************** Receive RF Data **********************************************/
unsigned int* rf_receive()
{
      int i;
      static int rf_rx_buffer[PAYLOAD_SIZE]={0};                                // Declare a receive buffer 
      rf_interrupt = false;                                                     // Clear interrupt flag
      output_low(rf_CE);                                                        // Disable receiver
      output_low(rf_CSN);                                                       // Engage SPI chip select
      spi_write(RX_PAYLOAD);                                                    // Initialize RX payload register
      for(i=0;i<=PAYLOAD_SIZE;i++)                                       
      {
         rf_rx_buffer[i]=spi_read(RX_PAYLOAD);                                  // Copy data from NRF24L01 to buffer
         if(rf_rx_buffer[i]==EOT){rf_rx_buffer[i]=ZERO;break;}                  // Stop when EOT found
      }
      output_high(rf_CSN);                                                      // Dis-engage SPI chip select 
      transmit_mode(false);                                                     // Enable receive mode
      return rf_rx_buffer;                                                      // Return received payload
}

/**************** Checks The Status Register ***********************************/
void check_interrupt()
{
   int i,reg;
   output_low(rf_CSN);                                                          // Engage SPI chip select
   for(i=0;i<5;i++){reg=spi_read(0x07)&0xFF;}                                   // Read 5 chars of data from NRF24L01 RX register
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select 
   if(reg>>6){rf_interrupt = true;}                                             // If RX_DR set,set data ready flag
   else{set_register(STATUS,0x7E);}                                             // Clear all interrupts
}

/**************** Initialize NRF24L01 Chip *************************************/
void setup_rf(unsigned int16 CE,unsigned int16 CSN,unsigned int* address,unsigned int CH,unsigned boolean Mbps,unsigned int dBm)
{
   rf_CE=CE;                                                                    // Define CE pin
   rf_CSN=CSN;                                                                  // Define CSN pin
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);             // Setup hardware spi
   output_low(rf_CE);                                                           // Disable receiver
   set_register(CONFIG,0x31);                                                   // Power down chip
   set_register(RF_CH,CH);                                                      // Set RF channel
   set_register(RF_SETUP,(Mbps<<3)|(dBm<<1)|0x01);                              // Set data rate and power level
   set_register(SETUP_AW,0x03);                                                 // Set address width to 5 bytes
   set_register(EN_AA,0x00);                                                    // Disable auto acknowledgement
   set_register(SETUP_RETR,0x05);                                               // Set auto retransmission for 5 tries
   set_register(TX_ADDR,address);                                               // Set transmit address
   set_register(RX_ADDR_P0,address);                                            // Set receive address
   set_register(EN_RXADDR,0x01);                                                // Enable RX address 0
   set_register(RX_PW_P0,PAYLOAD_SIZE);                                         // Set RX payload to receive up to 32 characters
   transmit_mode(false);                                                        // Enable receive mode
}

IMPLEMENTING THE DRIVER

#include <16F873.h>
#device PASS_STRINGS=IN_RAM
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use delay(clock=4M)
#use rs232(baud=9600, parity=N ,xmit=PIN_C6,rcv=PIN_C7, bits=8)


#include <nrf24L01.c>
#define BUFFER_SIZE 32

/************************ Global Variables *************************************/

const int address[5]={0xE7,0xE7,0xE7,0xE7,0xE7};                                // Declare address array
static int packet[BUFFER_SIZE];
int1 data=false;

/**************** Process Data Packet ******************************************/
void process_packet(unsigned int* data)
{
  printf("DATA IN: %s\r",data);
}

/**************** Process Data Packet ******************************************/
#INT_RDA
void rs232()
{
  gets(packet);                                                                  // Receive string from UART and save in buffer
  data=true;                                                                     // Set data flag to indicated data has been received from the UART
}

/**************** Interrupt Request ********************************************/
#int_ext
void interrupt_request()
{
  check_interrupt();
}

/************************ Main Loop ********************************************/
void main()
{ 
   setup_rf(PIN_C1,PIN_C2,address,2,0,3);                                       // Initialize RF transceiver
   enable_interrupts(INT_RDA);                                                  // Enable UART receive interrupt
   ext_int_edge(H_TO_L);                                                        // Enable interrupt on high to low transition
   enable_interrupts(INT_EXT);                                                  // Enable PORTB.0 interrupt
   enable_interrupts(GLOBAL);                                                   // Enable global interrupts                                                               
   while(true)                                                                  // Loop forever
   {
     if(rf_interrupt){process_packet(rf_receive());}                            // Check to see if RF data has been received, if so process data
     if(data)
     {
         data=false;                                                            // Clear data received flag
         rf_transmit(packet);                                                   // Transmit received data from UART  
     }
   }
}

Were you ever able to get Enhanced ShockBurst working? I implemented your code on a NRF24L01 connected to the SPI port of a Luminary Micro Cortex-M3 processor. Just like you, I had no problem communicating between the two transceivers without Enhanced ShockBurst enabled. If I enable Pipe 0 using the EN_AA register and set the number the retries to 5 I get an MAX_RT interrupt, as the PTx never gets an ACK from the receiver (STATUS = 0x1E).

I have tried everything that I know to get this to work. I’m looking for some ideas on where to even look at this point. I keep thinking that I need to split the code and only load one micro with Rx code and the other with Tx to simplify things.

–Bryan