Difference between revisions of "PIC32MX: High-speed Wireless Communication"

From Mech
Jump to navigationJump to search
Line 64: Line 64:
<code><pre>
<code><pre>
// **************************************************************
// **************************************************************
/*****************************************************************************
/*
*
* File: widePayloadTx.c
* Andrew Kessler, 8/2010
*
* NRF-24L01+
*
* This file waits to recieve a WIDTH number characters via RS232,
* then transmitts them as a single payload to a reciever. WIDTH
* must be a non-zero positive integer no more than 32, and match
* the width of the reciever, and can be adjusted using the "[" and "]" keys.
*
*****************************************************************************/


#include "HardwareProfile.h"
#include "nrf24l01.h"

#define DESIRED_BAUDRATE (19200) // The desired BaudRate for RS232 communication w/ UART

void Initialize(void);
void InitializeIO(void);
void SpiInitDevice(int,int,int,int);
void initUART2(int);
void Delayus(unsigned);
void ToggleLED(void); //toggle the current state of the on-board LED

int width;
char RS232_Out_Buffer[64]; // buffer for printing data to the screen via UART
int main(void)
{
width=32;

char data[32];
int i=0;
char change;
Initialize(); //initialize IO, UART, SPI, set up nRF24L01 as TX
sprintf(RS232_Out_Buffer,"*** Transmitter Intialized (%i)***\r\n",width);
putsUART2(RS232_Out_Buffer);
while(1)
{
nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
//check UART status register to see if data has been received. if so, process
if(DataRdyUART2()){ /* Wait for data in the UARTRx. */
change = (char)ReadUART2(); // Read data from UART
if (change==']'){
width++;
i=0; //reset buffer
if (width>32){
width=width-32;
}
//reset chip to new width
nrf24l01_initialize_debug(false, width, false);
// Echo what we just received.
sprintf(RS232_Out_Buffer,"Width: %d \r\n",width);
putsUART2(RS232_Out_Buffer);
}
else if (change=='['){
width--;
i=0; //reset buffer
if (width<1){
width=width+32;
}
//reset chip to new width
nrf24l01_initialize_debug(false, width, false);
// Echo what we just received.
sprintf(RS232_Out_Buffer,"Width: %d \r\n",width);
putsUART2(RS232_Out_Buffer);
}
else{
data[i]=change; //add char to buffer
sprintf(RS232_Out_Buffer,"%c",data[i]);
putsUART2(RS232_Out_Buffer);
i++;
}
}
if(i==width){//check if buffer is full
nrf24l01_write_tx_payload(data, width, true); //transmit received char over RF
//wait until the packet has been sent
while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));

sprintf(RS232_Out_Buffer,"\r\n");
putsUART2(RS232_Out_Buffer);
nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01

Delayus(130); //wait for receiver to come from standby to RX
i=0; //reset buffer
}
ToggleLED(); //toggle the on-board LED as visual indication that the loop has completed
}
}




void Initialize()
{
int pbClk = SYSTEMConfigPerformance(SYS_FREQ);
InitializeIO(); //set up IO (directions and functions)
initUART2(pbClk);
SpiInitDevice(1,1,0,0);
mInitAllLEDs();
//mLED_2_Toggle();
nrf24l01_initialize_debug(false, width, false); //initialize the 24L01 to the debug configuration as TX, 2 data byte, and auto-ack disabled
//mLED_1_Toggle();
}

//initialize IO pins
void InitializeIO(void)
{
TRISBbits.TRISB0 = 1; // set IRQ pin as input
TRISC &= 0xFFF9; // make CSN, CE digital outputs
LATC |= 0x0004; // set CSN bit active
}
//toggles on-board LED
void ToggleLED(void)
{
mLED_3_Toggle();
}

void Delayus( unsigned t) {
WirelessTransmitter.c
OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
Lab 5: High-speed Wireless Communication
while (t--)
Jonathan Drake, Caitlin Ramsey
{ // t x 1ms loop
2010-02-16
WriteTimer1(0);
while (ReadTimer1() < SYS_FREQ/256/1000000);
This code initializes the nRF24L01+ chip as a transmitter and
}
continuously transmits a character every 100ms. The loop contains
CloseTimer1();
code to both output the program's status to the PC via RS232
} // Delayus
cable and onboard LEDs.
unsigned char spi_send_read_byte(unsigned char byte) {
unsigned short txData, rxData; // transmit, receive characters
*/
int chn = 1; // SPI channel to use (1 or 2)
// **************************************************************
txData = byte; // take inputted byte and store into txData
SpiChnPutC(chn, txData); // send data
// Includes
rxData = SpiChnGetC(chn); // retreive over channel chn the received data into rxData
#include "HardwareProfile.h"
#include "nrf24l01.h"
// Function Declarations
// Note: Descriptions of functions found after main() function
void Initialize(void);
void InitializeIO(void);
void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster);
void initUART2(int pbClk);
unsigned char spi_send_read_byte(unsigned char byte);
void Delayms( unsigned t);
void Delayus( unsigned t);
void Delaytus( unsigned t);
// Constants
#define DESIRED_BAUDRATE (19200) // The desired BaudRate for RS232 communication w/ UART
// Main Function
int main(void) {
Initialize(); // initialize onboard LEDs, IO pins, UART2, SPI1, set up nRF24L01+ as TX
char RS232_Out_Buffer[64]; // buffer for printing data to the screen via UART
unsigned char data = 'x'; // char to be transmitted
// print char to screen
sprintf(RS232_Out_Buffer, "data to send = %c\r\n", data);
putsUART2(RS232_Out_Buffer);
while(1)
{
putsUART2("...\r"); // print ... to show transmission
nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
nrf24l01_set_as_tx(); // force 24L01 to be a transmitter (this is a double-check)
//transmit received char over RF, length = 1 byte, true = send away
nrf24l01_write_tx_payload(&data, 1, true);
// is the 24L01 activated?
if (nrf24l01_irq_pin_active()) {
mLED_1_On();
} else {
mLED_1_Off();
}
// is the 24L01 an active transmitter?
if (nrf24l01_irq_tx_ds_active()) {
mLED_2_On();
} else {
mLED_2_Off();
}
// wait until the packet has been sent or the maximum number of retries has been reached
while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));
// toggle onboard LED 3 to indicate loop iterating
mLED_3_Toggle();
Delayms(100);
}
}
// Initialize all initialize functions (function descriptions to follow)
void Initialize(void) {
return rxData;
// initialize peripheral bus clock to SYS_FREQ (80 MHz)
int pbClk;
pbClk = SYSTEMConfigPerformance(SYS_FREQ);
// initialize UART
initUART2(pbClk);
// initialize input/output pins
InitializeIO();
// initialize the SPI channel 1 as master, no frame mode
SpiInitDevice(1, 1, 0, 0);
//initialize 24L01 to debug configuration as transfer, 1 byte data size, and auto-acknowledge mode disabled
nrf24l01_initialize_debug(false, 1, false);
// initialize all onboard LEDs on NU32
mInitAllLEDs();
// if program initialized correctly, indicate on PC & onboard LEDs
putsUART2("\r\n***** System Initialized *****\r\n");
mLED_0_On();
}
}
// initialize IO pins
void InitializeIO(void) {
TRISBbits.TRISB0 = 1; // set IRQ pin as input
TRISC = 0xFFF9; // make CSN, CE digital outputs
PORTC = 0x0004; // set CSN bit active
}
// initialize UART2
void initUART2(int pbClk) {
#define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
#define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR
OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value.
ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
}
// initialize SPI
void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster) {
void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster) {
unsigned int config = SPI_CON_MODE16|SPI_CON_SMP|SPI_CON_ON; // SPI configuration word
unsigned int config = SPI_CON_MODE8|SPI_CON_SMP|SPI_CON_ON; // SPI configuration word
if(isMaster)
if(isMaster)
{
{
Line 205: Line 233:
}
}
void initUART2(int pbClk) {
// ******************************************************
#define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
/*
#define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR
Function: spi_send_read_byte
OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value.
Inputs: unsigned char byte
ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
Outputs: unsigned short rxData
This function is required by the 24L01 header file.
It takes the inputted byte, sends it over the chosen
SPI channel, then waits to retreive data back.
*/
// ******************************************************
unsigned char spi_send_read_byte(unsigned char byte) {
unsigned short txData, rxData; // transmit, receive characters
int chn = 1; // SPI channel to use (1 or 2)
txData = byte; // take inputted byte and store into txData
SpiChnPutC(chn, txData); // send data
rxData = SpiChnGetC(chn); // retreive over channel chn the received data into rxData
return rxData;
}
}

// ******************************************************
/*
Functions: Delayms, Delayus
Inputs: unsigned t
Outputs: none
These functions are required by the 24L01 header file.
They take an input of t (ms, us) and delay the
program.
*/
// ******************************************************
void Delayms( unsigned t) {
// This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ
OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
while (t--)
{ // t x 1ms loop
WriteTimer1(0);
while (ReadTimer1() < SYS_FREQ/256/1000);
}
CloseTimer1();
} // Delayms
void Delayus( unsigned t) {
OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
while (t--)
{ // t x 1ms loop
WriteTimer1(0);
while (ReadTimer1() < SYS_FREQ/256/1000000);
}
CloseTimer1();
} // Delayus
</pre></code>
</pre></code>



Revision as of 16:16, 16 August 2010

Original Assignment

Do not erase this section!

Your assignment is to create the circuit and code that allows two PIC32s to use wireless communication at high speeds using the Transceiver nRF24L01+ Module with Chip Antenna from Sparkfun.

Read up on the nRF24L01+ Module commands and create functions to allow a PIC32 to initialize and send and receive data.

Test your code by sending 1000 bytes of data from one PIC32 to the other and echo the data back. How long does this transmission take? How far can you separate the PIC32s before the transmission is unreliable?

Overview

This wiki describes how to wire a nRF24L01+ chip ("wireless chip") to the transmitting PIC32 board ("transmitter") and receiving PIC32 board ("receiver"), and includes annotated code describing the functions that facilitate the wireless communication.

To operate the system, you must properly connect the wireless chips to the PIC32s, load the transmitter code onto the PIC that you wish to act as a transmitter, load the receiver code onto the PIC that you wish to act as a receiver, properly connect an RS232 cable to the PIC and open a serial communication program (e.g. HyperTerminal or putty), and turn the NU32 boards on. If the system works, the transmitting PIC will broadcast any characters received from the PC via RS232, and the receiving PIC will display what it receives from wireless link on the PC via RS232. The payload width can be adjusted using the "[" and "]" keys on both the transmitting and receiving PICs. Both wireless chips must be set to the same payload width in order to communicate. Payload widths may vary from 1 to 32. The transmitting PIC will not transmit until enough characters have been entered to fill a payload. Once enough characters have been entered into the transmitting PIC, the serial display will move to a new line to signal transmission.

Chip Basics

The nrf24L01+ Module is a breakout of the nrf24L01+ 2.4 GHz transceiver, with an on board antenna. In order to get a wireless link up and running, the following parameters must be consistent between chips:

Channels

The channel of the nrf24L01+ chip is the frequency that it broadcasts and receives data from. The channel can range from 2.4 GHz to 2.525 GHz, at intervals no more than 1 MHz. The exact distance between channels is dependent on the on air data rate. Two wireless chips must be tuned to the same channel in order to communicate. See the Air Data Rate section for necessary channel spacing.

Air Data Rate

The air data rate is the rate at which the chip transmits bits wirelessly (and the rate at which it looks for them). The nrf24L01+ chip has three selectable data rates: 250 kbps, 1 Mbps, and 2 Mbps. Faster data rates draw less current, but require a greater distance between channels. Slower data rates give you the option of more channels and better receiver sensitivity, for the obvious trade off of speed. Data rates of 250 kbps and 1 Mbps require channel spacing of at least 1 MHz (allowing for 125 unique channels), and a data rate of 2 Mbps requires spacing of 2 MHz between channels (allowing for 62 channels). Two wireless chips will not be able to communicate if they are not set to the same on air data rate.

Payload Width

The payload is the actual data you are trying to send over a wireless link, and the payload width is how many bytes are contained within each payload. The nfr24L01+ is capable of supporting payloads up to 32 bytes. A transmitter and receiver must be set to the same payload in order to communicate. Transmission speeds for different sizes payloads are analyzed below.

Addresses & Pipes

Every wireless transmission is preceded by the address of the intended receiver. The nrf24L01+ chip has 6 different receiving pipes, which means it may act as 6 receivers with 6 different addresses. Addresses may be three, four, or five bytes long. The addresses for pipe 0 and 1 may be completely different, but the addresses for pipes 2, 3, and 4 may only differ from the address of pipe 1 by their least significant byte. All active pipes feed into the same 3-packet-deep incoming transmission queue. Each pipe may also be set to a expect a different payload width.

Circuit

Schematic of the nRF24L01+ connected to the PIC32_NU32 board

The wireless chip has 8 pins that need to be wired to the PIC (all I/O are relative to PIC):

  • Vcc: +3.3 Vdc supply
  • CE: uC pin C1 (input)
  • CSN: uC pin C2 (output)
  • SCK: uC pin D10, configured as SCK(SPI) (output)
  • MOSI: uC pin D0, configured as SDO(SPI) (output)
  • MISO: uC pin C4, configured as SDI(SPI) (input)
  • IRQ: uC pin B0 (input)
  • GND: common digital ground

The +3.3V and ground are provided by the NU32 board. The term "uC" above stands for microcontroller, which is the PIC32 in our case.

Descriptions of the wireless chip's pins can be found in Brennan Ball's DIYembedded Tutorial 0. The SCK, MOSI, and MISO pins interface with the SPI on the PIC32 which allows for communication between the PIC and the wireless chip. The GPIO pins will be initialized as digital inputs or outputs in the code to enable/disable the wireless chip and check the wireless data transfer/receive stats.

In order to print information from the PIC to the PC, we need to wire an PIC_RS232 cable's transfer and receive lines to the UART ports of the NU32 board (F4, F5).

Code

Driver

Besides the main C files for the transmitter and receiver, the project also needs the nRF24L01.h header file and C file. These driver files were created by Brennan Ball, and are explained in detail in his tutorials. The following things must be changed in the header file available on his website to make it compatible with the NU32 board:

  • pin registers and masks must be set to the appropriate values
  • the "HardwareProfile.h" NU32 specific file must be included

These changes are accounted for the the driver available on this page. All of the SPI functions trace back to a single function to send and read a single byte, which must be defined in the main c file. Download the nRF24L01+ driver files.

Transmitter Code

 
// ************************************************************** 
   /*****************************************************************************
*
* File: widePayloadTx.c
* Andrew Kessler, 8/2010
*
* NRF-24L01+
* 
* This file waits to recieve a WIDTH number characters via RS232, 
* then transmitts them as a single payload to a reciever. WIDTH
* must be a non-zero positive integer no more than 32, and match 
* the width of the reciever, and can be adjusted using the "[" and "]" keys.
* 
*****************************************************************************/


#include "HardwareProfile.h"
#include "nrf24l01.h"

#define DESIRED_BAUDRATE    	(19200)      // The desired BaudRate for RS232 communication w/ UART

void Initialize(void);
void InitializeIO(void);
void SpiInitDevice(int,int,int,int);
void initUART2(int);
void Delayus(unsigned);
void ToggleLED(void); //toggle the current state of the on-board LED 

int width;
char RS232_Out_Buffer[64]; // buffer for printing data to the screen via UART
int main(void)
{
	width=32;

	char data[32];
	int i=0;
	char change;
	
	Initialize(); //initialize IO, UART, SPI, set up nRF24L01 as TX
	sprintf(RS232_Out_Buffer,"*** Transmitter Intialized (%i)***\r\n",width);
	putsUART2(RS232_Out_Buffer);
	 
	while(1)
	{
		nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
		  
		//check UART status register to see if data has been received.  if so, process
		if(DataRdyUART2()){ /* Wait for data in the UARTRx. */
      		change = (char)ReadUART2(); // Read data from UART 
      		if (change==']'){
				width++;
				i=0; //reset buffer
				if (width>32){
					width=width-32;
				}	
					//reset chip to new width
				nrf24l01_initialize_debug(false, width, false);
				// Echo what we just received.
				sprintf(RS232_Out_Buffer,"Width: %d \r\n",width);
				putsUART2(RS232_Out_Buffer);
			}
			else if (change=='['){
				width--;
				i=0; //reset buffer
				if (width<1){
					width=width+32;
				}		
				//reset chip to new width
				nrf24l01_initialize_debug(false, width, false);
				// Echo what we just received.
				sprintf(RS232_Out_Buffer,"Width: %d \r\n",width);
				putsUART2(RS232_Out_Buffer);
			}	
      		else{
      			data[i]=change; //add char to buffer
      			sprintf(RS232_Out_Buffer,"%c",data[i]);
      			putsUART2(RS232_Out_Buffer);
   				i++;
   			}
		}	
	
		if(i==width){//check if buffer is full
			
			nrf24l01_write_tx_payload(data, width, true); //transmit received char over RF
		
			//wait until the packet has been sent
			while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));

			sprintf(RS232_Out_Buffer,"\r\n");
			putsUART2(RS232_Out_Buffer);
	
			nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01

			Delayus(130); //wait for receiver to come from standby to RX
									
			i=0; //reset buffer
		}	
	
	
	
	
		
		ToggleLED(); //toggle the on-board LED as visual indication that the loop has completed	
	}
}




void Initialize()
{
	int	pbClk = SYSTEMConfigPerformance(SYS_FREQ);
	InitializeIO(); //set up IO (directions and functions)
	initUART2(pbClk);
	SpiInitDevice(1,1,0,0);
	mInitAllLEDs();
	//mLED_2_Toggle();
	nrf24l01_initialize_debug(false, width, false); //initialize the 24L01 to the debug configuration as TX, 2 data byte, and auto-ack disabled
	//mLED_1_Toggle();
}

//initialize IO pins
void InitializeIO(void)
{
	 TRISBbits.TRISB0 = 1; // set IRQ pin as input
  	 TRISC &= 0xFFF9; // make CSN, CE digital outputs
  	 LATC |= 0x0004; // set CSN bit active
}
//toggles on-board LED
void ToggleLED(void)
{
	mLED_3_Toggle();
}	

 
 void Delayus( unsigned t) {
  	OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
  	while (t--)
  	{  // t x 1ms loop
  		WriteTimer1(0);
  		while (ReadTimer1() < SYS_FREQ/256/1000000);
  	}
  	CloseTimer1();
 } // Delayus
  unsigned char spi_send_read_byte(unsigned char byte) {
  	 unsigned short	txData, rxData; // transmit, receive characters
   	 int chn = 1; // SPI channel to use (1 or 2)
  	 
   	 txData = byte; // take inputted byte and store into txData   
   	 SpiChnPutC(chn, txData);			// send data
 	 rxData = SpiChnGetC(chn);			// retreive over channel chn the received data into rxData
    
  	 return rxData; 
 }
 void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster) {
   	 unsigned int config = SPI_CON_MODE8|SPI_CON_SMP|SPI_CON_ON;	// SPI configuration word
   	 if(isMaster)
   	 {
   		 config|=SPI_CON_MSTEN;
   	 }
   	 if(frmEn)
   	 {
   		 config|=SPI_CON_FRMEN;
   		 if(!frmMaster) {   
   			 config|=SPI_CON_FRMSYNC;
      	 }
   	 }
  	 SpiChnOpen(chn, config, 4);	// divide fpb by 4, configure the I/O ports. Not using SS in this example
 }
 
  void initUART2(int pbClk) {
  	 #define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
  	 #define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	
   	 OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.
   	 ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
   	
 }

Receiver Code

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

	WirelessReceiver.c
	Lab 5: High-speed Wireless Communication
	Jonathan Drake, Caitlin Ramsey 
	2010-02-16
	
	This code initializes the nRF24L01+ chip as a receiver to 
	continuously listen over its wireless antenna. If data is 
	received, the program prints the data on a PC. The loop contains
	code to both output the program's status to the PC via RS232
	cable and onboard LEDs. 

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

// Includes
#include "HardwareProfile.h"
#include "nrf24l01.h"


// Function Declarations
// Note: Descriptions of functions found after main() function
void Initialize(void);
void InitializeIO(void);
void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster);
void initUART2(int pbClk);
unsigned char spi_send_read_byte(unsigned char byte);
void Delayms( unsigned t);
void Delayus( unsigned t);
void Delaytus( unsigned t);


// Constants
#define DESIRED_BAUDRATE (19200) // The desired BaudRate for RS232 communication w/ UART

// Main Function
int main(void)
{
	// initialize onboard LEDs, IO pins, UART2, SPI1, set up nRF24L01+ as RX
	Initialize(); 

	char RS232_Out_Buffer[64]; // buffer for printing data to the screen via UART
	unsigned char data; //register to hold letter sent and received
	
	while(1)
	{
		nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01
		nrf24l01_set_as_rx(true); // force 24L01 to be a receiver (this is a double-check)

		// is the 24L01 activated?
		if (nrf24l01_irq_pin_active()) {
			mLED_1_On();
		} else {
			mLED_1_Off();
		}

		// is the 24L01 receiving data?
		if (nrf24l01_irq_rx_dr_active()) {
			mLED_2_On();
		} else {
			mLED_2_Off();
		}		

		//check to see if the data has been received.  if so, get the data
		if((nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active()))
		{
			mLED_3_On();
			nrf24l01_read_rx_payload(&data, 1); //get the payload into data
			sprintf(RS232_Out_Buffer, "\r\nrec data = %d\r\n", data); // show the data
			putsUART2(RS232_Out_Buffer);
			Delayms(2000);
		} else { // otherwise, show that chip is still listening
			putsUART2("...\r");
		}

		// toggle onboard LED 3 to indicate loop iterating
		mLED_3_Off();
		Delayms(10);
	}

}

// Initialize all initialize functions (function descriptions to follow)
void Initialize(void) {

	// initialize peripheral bus clock to SYS_FREQ (80 MHz)    
	int	pbClk;
	pbClk = SYSTEMConfigPerformance(SYS_FREQ);
	
	// initialize UART   
	initUART2(pbClk);	
	
	// initialize input/output pins     
	InitializeIO();
	
	// initialize the SPI channel 1 as master, no frame mode   
	SpiInitDevice(1, 1, 0, 0);	   
	
	//initialize 24L01 to debug configuration as receiver, 1 byte data size, and auto-acknowledge mode disabled   
	nrf24l01_initialize_debug(true, 1, false);   
	
	// initialize all onboard LEDs on NU32   
	mInitAllLEDs();    
	
	// if program initialized correctly, indicate on PC & onboard LEDs     
	putsUART2("\r\n***** System Initialized *****\r\n");    
	mLED_0_On();   

}

// initialize IO pins
void InitializeIO(void) {	
	TRISBbits.TRISB0 = 1; // set IRQ pin as input
	TRISC = 0xFFF9; // make CSN, CE digital outputs
	PORTC = 0x0004; // set CSN bit active
}

// initialize UART2
void initUART2(int pbClk)
{
	#define config1 	UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
	#define config2		UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR	
 	OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1);	// calculate actual BAUD generate value.
 	ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
}


// initialize SPI
void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster)
{
	unsigned int config = SPI_CON_MODE16|SPI_CON_SMP|SPI_CON_ON;	// SPI configuration word
	if(isMaster)
	{
		config|=SPI_CON_MSTEN;
	}
	if(frmEn)
	{
		config|=SPI_CON_FRMEN;
		if(!frmMaster)
		{
			config|=SPI_CON_FRMSYNC;
		}
	}
	SpiChnOpen(chn, config, 4);	// divide fpb by 4, configure the I/O ports. Not using SS in this example
}

// ******************************************************
/*      
	Function:	spi_send_read_byte
	Inputs:		unsigned char byte
  	Outputs:	unsigned short rxData
    
	This function is required by the 24L01 header file. 
  	It takes the inputted byte, sends it over the chosen 
  	SPI channel, then waits to retreive data back. 
*/      
// ****************************************************** 
unsigned char spi_send_read_byte(unsigned char byte) {
 	 unsigned short	txData, rxData; // transmit, receive characters
  	 int chn = 1; // SPI channel to use (1 or 2)
 	 
  	 txData = byte; // take inputted byte and store into txData   
  	 SpiChnPutC(chn, txData);			// send data
	 rxData = SpiChnGetC(chn);			// retreive over channel chn the received data into rxData
   
 	 return rxData; 
}


// ******************************************************
/*
 
	 Functions:	Delayms, Delayus
	 Inputs:	unsigned t
	 Outputs:	none
 
	 These functions are required by the 24L01 header file. 
 	 They take an input of t (ms, us) and delay the 
	 program. 
 
*/
// ****************************************************** 
void Delayms( unsigned t) {
 	// This uses Timer 1, can be changed to another timer. Assumes FPB = SYS_FREQ
 	OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
 	while (t--)
 	{  // t x 1ms loop
 		WriteTimer1(0);
 		while (ReadTimer1() < SYS_FREQ/256/1000);
 	}
 	CloseTimer1();
} // Delayms

void Delayus( unsigned t) {
 	OpenTimer1(T1_ON | T1_PS_1_256, 0xFFFF);
 	while (t--)
 	{  // t x 1ms loop
 		WriteTimer1(0);
 		while (ReadTimer1() < SYS_FREQ/256/1000000);
 	}
 	CloseTimer1();
} // Delayus

Data Rates

Basic timed tests were done to find out how long it took to transmit and receive different sized payloads.