nRF24L01 Program Example

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 9

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

//
// nRF24L01 Program example
//
// Description:
// This example code is contains two functions,
// 'TX_Mode': program nRF24L01 to function as a PRIM:TX,
// i.e. program TX_Address, RX_Address for auto ack,
// TX Payload, setup of 'Auto Retransmit Delay' &
// 'Auto Retransmit Count', select RF channel,
// Datarate & RF output power.
//
// 'RX_Mode': program nRF24L01 to function as a PRIM:RX,
// i.e. ready to receive the packet that was sent with
// the 'TX_Mode' function.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************
#include <c8051F330.h>
//#include "defines.h"
//#include "nRF_API.h"
//#include "LL_API.h"
//#include "Protocol_API.h"
//**********************************************************
// Prototypes
void Init_Device(void) ;
//**********************************************************
#define TX_ADR_LENGTH 5 // 5 bytes TX(RX) address widt
h
#define TX_PLOAD_WIDTH 16 // 16 bytes TX payload
#define BYTE unsigned char
//******************************************************************************
**************************************//
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
//******************************************************************************
**************************************//
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read stat
us register
// Define nRF24L01 interrupt flag's
#define IDLE 0x00 // Idle, no interrupt pending
#define MAX_RT 0x10 // Max #of TX retrans interrupt
#define TX_DS 0x20 // TX data sent interrupt
#define RX_DR 0x40 // RX data received
#define SPI_CFG 0x40 // SPI Configuration register value
#define SPI_CTR 0x01 // SPI Control register values
#define SPI_CLK 0x00 // SYSCLK/2*(SPI_CLK+1) == > 12MHz / 2 = 6MHz
#define SPI0E 0x02 // SPI Enable in XBR0 register
#define EXT_INT0 0x00
BYTE IRQ_Source = 0; // Indicates IRQ source from n
RF24L01
BYTE SPI_Buffer[32]; // Buffer to hold data from 'S
PI_Read_Buf()' function
// Predefine a static TX address
BYTE const TX_ADDRESS[TX_ADR_LENGTH] = {0xe7,0xe7,0xe7,0xe7,0xe7};
// Predefine TX payload packet..
BYTE const TX_PAYLOAD[TX_PLOAD_WIDTH] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
};
// Define CE & IRQ pins
sbit CS = P0^3 ; // CS for SPI
sbit CE = P0^4; // Chip Enable pin signal (output)
sbit IRQ = P0^5; // Interrupt signal, from nRF24L01 (input)
//**********************************************************//
//
// Function: CSN_Pin
//
// CSN Pin handling
//
// In/Out parameters:
// In: "state"
// Out: --
//
//**********************************************************//
void CSN_Pin(BYTE state) // Set/reset CSN pin
{
if ( state )
CS = 1 ;
else
CS = 0 ;
}
//**********************************************************//
//
// Function: SPI_RW
//
// Description:
// Writes one byte to nRF24L01, and return the byte read
// from nRF24L01 during write, according to SPI protocol
//
// In/Out parameters:
// In: 'byte', current byte to be written
// Out: 'SPI0DAT', HW SPI mode, 'byte' SW SPI mode,
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_RW(BYTE byte) // Write one byte using
F320's hardware SPI
{
while(!SPIF);
{ }
SPIF = 0 ;
SPI0DAT = byte; // Writes 'byte' to nRF2
4L01


while(!SPIF);
{ }
return(SPI0DAT); // return received byte
}
//**********************************************************//
//
// Function: SPI_Read
//
// Description:
// Read one byte from nRF24L01 register, 'reg'
//
//
// In/Out parameters:
// In: reg, register to read
// Out: return reg_val, register value.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;
CSN_Pin(0);
SPI_RW(reg); // Select register to read fro
m..
reg_val = SPI_RW(0); // ..then read registervalue
CSN_Pin(1); // CSN high, terminate SPI com
munication
return(reg_val); // return register value
}
//**********************************************************//
//
// Function: SPI_RW_Reg
//
// Description:
// Writes value 'value' to register 'reg'
//
//
// In/Out parameters:
// In: 'reg' register to write value 'value' to.
// Return status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_RW_Reg(BYTE reg, BYTE value)
{
BYTE status;
CSN_Pin(0); // CSN low, init SPI transacti
on
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN_Pin(1); // CSN high again
return(status); // return nRF24L01 status byte
}
//**********************************************************//
//
// Function: SPI_Write_Buf
//
// Description:
// Writes contents of buffer '*pBuf' to nRF24L01
// Typically used to write TX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: register 'reg' to write, buffer '*pBuf*' contains
// data to be written and buffer size 'buf_size' is #of
// bytes to be written
// Out: return nRF24L01 status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
BYTE status,byte_ctr;
CSN_Pin(0); // Set CSN low, init SPI trana
ction
status = SPI_RW(reg); // Select register to write to
and read status byte
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buff
er(*pBuf)
SPI_RW(*pBuf++);
CSN_Pin(1); // Set CSN high again
return(status); // return nRF24L01 status byte
}
//**********************************************************//
//
// Function: SPI_Read_Buf
//
// Description:
// Reads 'bytes' #of bytes from register 'reg'
// Typically used to read RX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: 'reg', register to read from, '*pBuf' are buffer
// the read bytes are stored to and 'bytes' are #of bytes
// to read.
// Out: return nRF24L01 status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
BYTE status,byte_ctr;
CSN_Pin(0); // Set CSN low, init SPI trana
ction
status = SPI_RW(reg); // Select register to write to
and read status byte
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte
from nRF24L01
CSN_Pin(1); // Set CSN high again
return(status); // return nRF24L01 status byte
}
BYTE NRFStat ;
//**********************************************************
//
// Function: TX_Mode
//
// Description:
// This function initializes one nRF24L01 device to
// TX mode, set TX address, set RX address for auto.ack,
// fill TX payload, select RF channel, datarate & TX pwr.
// PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.
//
// ToDo: One high pulse(>10s) on CE will now send this !!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!
// packet and expext an acknowledgment from the RX device.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************
void TX_Mode(void)
{
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_LENGTH); // W
rites TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_LENGTH); // R
X_Addr0 same as TX_Adr for Auto.Ack
SPI_Write_Buf(WR_TX_PLOAD, TX_PAYLOAD, TX_PLOAD_WIDTH); // W
rites data to TX payload
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // E
nable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // E
nable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 5
00s + 86s, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // S
elect RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // T
X_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // S
et PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
// This device is now ready to transmit one packet of 16 bytes payload to a R
X device at address
// '3443101001', with auto acknowledgment, retransmit count of 10(retransmit
delay of 500s+86s)
// RF channel 40, datarate = 2Mbps with TX power = 0dBm.
}
void Delay100us(volatile unsigned char n) // Schleifenbeis
piel von Nordic
{
unsigned char i;
while(n--)
for(i=0;i<32;i++);
}
//**********************************************************
//
// Function: RX_Mode
//
// Description:
// This function initializes one nRF24L01 device to
// RX Mode, set RX address, writes RX payload width,
// select RF channel, datarate & LNA HCURR.
// After init, CE is toggled high, which means that
// this device is now ready to receive a datapacket.
//
// Author: RSK Date: 28.11.05
//**********************************************************
void RX_Mode(void)
{
unsigned int i ;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_LENGTH); // Use the s
ame address on the RX device as the TX device
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload wi
dth as TX Payload width
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // TX_PWR:0dBm, Datarate:2Mbps
, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(
2 bytes) & Prim:RX. RX_DR enabled..
CE = 1; // Set CE pin high to enable RX device
Delay100us(15);
//for ( i = 0 ; i< 30000 ; )
// { i++;
// }
// This device is now ready to receive one packet of 16 bytes payload from a
TX device sending to address
// '3443101001', with auto acknowledgment, retransmit count of 10, RF channel
40 and datarate = 2Mbps.
}
//BYTE IRQCNT ;
void nRF24L01_IRQ (void) interrupt EXT_INT0
{
BYTE temp,rx_pw;
//IRQCNT++;
EA = 0; // disable global interrupt d
uring processing
temp = SPI_RW_Reg(WRITE_REG + STATUS, 0x70); // Read STATUS byte and clear
IRQ flag's(nRF24L01)
if(temp & MAX_RT) IRQ_Source = MAX_RT; // Indicates max #of retransmi
t interrupt
if(temp & TX_DS) IRQ_Source = TX_DS; // Indicates TX data succsessf
ully sent
if(temp & RX_DR) // In RX mode, check for data
received
{
// Data received, so find out which datapipe the data was received on:
temp = (0x07 & (temp > 1)); // Shift bits in status
byte one bit to LSB and mask 'Data Pipe Number'
rx_pw = SPI_Read(READ_REG + RX_PW_P0 + temp); // Read current RX_PW_P
register, where Pn is the pipe the data was received on..
SPI_Read_Buf( RD_RX_PLOAD, SPI_Buffer, rx_pw ); // Data from RX Paylo
ad register is now copied to SPI_Buffer[].
IRQ_Source = RX_DR; // Indicates RX data rec
eived
}
EA = 1;
// enable global interrupt again
}
BYTE temp,rx_pw;
void main ( void )
{
unsigned int CDD=0;
RX_Mode ();
Init_Device() ;
SPIF = 1 ; // SPI IRQ-Flag
IT0 = 1 ; // Edge trigger for Int0
CE = 0 ;
EA = 1 ; // enable IRQ global
while ( 1 )
{
NRFStat = SPI_Read(READ_REG + STATUS );
// if ( NRFStat == 1 )
// { CDD++; }
;
}
}

You might also like