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
}
}
}