# nrf2401a

**URL:** <https://community.sparkfun.com/t/nrf2401a/9196>\
**Category:** Wireless & IoT\
**Created:** [November 27, 2008, 3:42am UTC](https://community.sparkfun.com/t/nrf2401a/9196 "2008-11-27T03:42:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![meres](https://avatars.discourse-cdn.com/v4/letter/m/43a26b/32.png) [@meres](https://community.sparkfun.com/u/meres)\
**Post date:** [November 27, 2008, 3:42am UTC](https://community.sparkfun.com/t/nrf2401a/9196/1 "2008-11-27T03:42:02Z")

</div>

I recently bought two nrf2401a modules \<[http://www.sparkfun.com/commerce/produc … cts\_id=152](http://www.sparkfun.com/commerce/product_info.php?products_id=152)\> along with the accompanying development nodes \<[http://www.sparkfun.com/commerce/produc … cts\_id=713](http://www.sparkfun.com/commerce/product_info.php?products_id=713)\> -utilizing the infamous PIC 16F88- from Spark Fun.

I was able to successfully compile (version V01\*\*\* of the code provided by SFE using CC5X) and program the modules using WinPic and the PG1 programmer from Olimex/SFE. My problem is that I am not sure whether the transceivers are communicating. I have a couple of questions that I DESPERATELY need help with:

1. How do you modify the code [notably version 1 from SFE] so as to see the data transferred to either of the modules. I was going to rely on the LED’s on the development nodes but one of them on ONE of the board seems to have taken an early thanksgiving break!..

I’ve tried using a rs232 data logger from Eltima Software but unfortunately I only able to get a text file filled with white spaces.

1. Also, in the manual Nordic manual the transceiver seems to require 143 bits for configuration but the code seems to only mention 24 bits (0-23) seen below:

config\_setup[0] = 0b.0000.0101;

config\_setup[1] = 0b.0100.1110;

config\_setup [2] = 0b.0010.0011;

\*\*\*Here’s the code I am trying to implement on the transceivers:

/\*

nRF2401 test code to run on the 24G demo board, V01

This code will generate AUTOMATICALLY send and recieve packets from another demo board running the same V01 code.

This code does not accept user input.

Compiles with the free version of CC5X

Pete Dokter, 2/22/06

config\_setup word 16 bits found on pages 13-15

23: 0 Payloads have an 8 bit address

22: 0

21: 1

20: 0

19: 0

18: 0

17: 1 16-Bit CRC

16: 1 CRC Enabled

15: 0 One channel receive

14: 1 ShockBurst Mode

13: 0 250K Transmission Rate

12: 0

11: 1

10: 1

9: 1 RF Output Power

8: 0 RF Output Power

7: 0 Channel select (channel 2)

6: 0

5: 0

4: 0

3: 0

2: 1

1: 0

0: 0 Transmit mode

\*/

#define Clock\_8MHz

#define Baud\_9600

#include “C:\Global\PIC\C\16F88.h”

#pragma config |= 0x3F30 //Internal Oscillator, No WDT, MCLR Enabled

//#include “C:\Global\PIC\C\Stdio.c” // Basic Serial IO

#define CS PORTA.0 //out

#define CLK1 PORTA.1 //out

#define DATA1 PORTA.2 //I/O

#define DR1 PORTA.3 //in

#define DATA2 PORTA.4 //in

#define CE PORTA.6 //out

#define CLK2 PORTA.7 //out

#define DR2 PORTB.0 //in

#define stat1 PORTB.1 //out

#define stat2 PORTB.3 //out

#define stat3 PORTB.4 //out

uns8 data\_array[4];

//uns8 counter;

void boot\_up(void);

void configure\_receiver(void);

void configure\_transmitter(void);

void transmit\_data(void);

void receive\_data(void);

void delay\_ms(uns16);

void main()

{

uns8 x;

boot\_up();

for (x = 0; x \< 3; x++)

{

stat1 = 1;

delay\_ms(25);

stat1 = 0;

stat2 = 1;

delay\_ms(25);

stat2 = 0;

stat3 = 1;

delay\_ms(25);

stat3 = 0;

}

stat1 = 1;

while(1)

{

configure\_transmitter();

transmit\_data();

configure\_receiver();

delay\_ms(50);

if(DR1 == 1) //We have data!

{

receive\_data();

if ((data\_array[0] == 0x12) && (data\_array[1] == 0x34) && (data\_array[2] == 0xAB) && (data\_array[3] == 0xCD))

{

if (stat3 == 1)

{

stat3 = 0;

stat1 = 1;

}

else if (stat2 == 1)

{

stat2 = 0;

stat3 = 1;

}

else if (stat1 == 1)

{

stat1 = 0;

stat2 = 1;

}

}

}

}

}

void boot\_up(void)

{

OSCCON = 0b.0111.0000; //Setup internal oscillator for 8MHz

while(OSCCON.2 == 0); //Wait for frequency to stabilize

ANSEL = 0b.0000.0000; //Turn pins to Digital instead of Analog

CMCON = 0b.0000.0111; //Turn off comparator on RA port

PORTA = 0b.0000.0000;

TRISA = 0b.0011.1100; //0 = Output, 1 = Input

PORTB = 0b.0000.0000;

TRISB = 0b.1100.0101; //0 = Output, 1 = Input

//enable\_uart\_TX(0);

//enable\_uart\_RX(0);

}

//This will clock out the current payload into the data\_array

void receive\_data(void)

{

uns8 i, j, temp;

CE = 0;//Power down RF Front end

//Erase the current data array so that we know we are looking at actual received data

data\_array[0] = 0x00;

data\_array[1] = 0x00;

data\_array[2] = 0x00;

data\_array[3] = 0x00;

//Clock in data, we are setup for 32-bit payloads

for(i = 0 ; i \< 4 ; i++) //4 bytes

{

for(j = 0 ; j \< 8 ; j++) //8 bits each

{

temp \<\<= 1;

temp.0 = DATA1;

CLK1 = 1;

CLK1 = 0;

}

data\_array _= temp; //Store this byte_  
_}_

_//if(RX\_DR == 0) //Once the data is clocked completely, the receiver should make DR go low_  
_//printf(“DR went low\n\r”, 0);_

_//printf(“\n\rData Received:\n\r”, 0);_  
_//printf(“[0] : %h\n\r”, data\_array[0]);_  
_//printf(“[1] : %h\n\r”, data\_array[1]);_  
_//printf(“[2] : %h\n\r”, data\_array[2]);_  
_//printf(“[3] : %h\n\r”, data\_array[3]);_  
_CE = 1; //Power up RF Front end_  
_}_  
_//This sends out the data stored in the data\_array_  
_//data\_array must be setup before calling this function_  
_void transmit\_data(void)_  
_{_  
_uns8 i, j, temp, rf\_address;_

_data\_array[0] = 0x12;_  
_data\_array[1] = 0x34;_  
_data\_array[2] = 0xAB;_  
_data\_array[3] = 0xCD;_  
_CE = 1;_

_delay\_ms(1);_  
_//Clock in address_  
_rf\_address = 0b.1110.0111; //Power-on Default for all units (on page 11)_  
_for(i = 0 ; i \< 8 ; i++)_  
_{_  
_DATA1 = rf\_address.7;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_rf\_address \<\<= 1;_  
_}_

_//Clock in the data\_array_  
_for(i = 0 ; i \< 4 ; i++) //4 bytes_  
_{_  
_temp = data\_array;_

 

_for(j = 0 ; j \< 8 ; j++) //One bit at a time_  
_{_  
_DATA1 = temp.7;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_temp \<\<= 1;_  
_}_  
_}_

_CE = 0; //Start transmission_  
_}_  
_[//2.4G](https://2.4G) Configuration - Receiver_  
_//This setups up a RF-24G for receiving at 1mbps_  
_void configure\_receiver(void)_  
_{_  
_uns8 i,j;_  
_//uns24 config\_setup;_  
_uns8 config\_setup[3], temp;_  
_//During configuration of the receiver, we need DATA1 as an output_  
_PORTA = 0b.0000.0000;_  
_TRISA = 0b.0011.1000; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_  
_//Config Mode_  
_CE = 0; CS = 1;_

_delay\_ms(1);_

_//Setup configuration word, set up for 250k_  
_//config\_setup = 0b.0010.0011.0100.1110.0000.0101; //Look at pages 13-15 for more bit info_  
_config\_setup[0] = 0b.0000.0101;_  
_config\_setup[1] = 0b.0100.1110;_  
_config\_setup[2] = 0b.0010.0011;_

_/\*//purchased version_  
_for(i = 0 ; i \< 24 ; i++)_  
_{_  
_DATA1 = config\_setup.23;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_config\_setup \<\<= 1;_

_}_  
_\*/_

_//free version_  
_for (j = 3; j \> 0; j–)_  
_{_  
_for(i = 0 ; i \< 8 ; i++)_  
_{_  
_DATA1 = config\_setup[j-1].7;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_config\_setup[j-1] \<\<= 1;_

_}_  
_}_

_//Configuration is actived on falling edge of CS (page 10)_  
_CE = 0; CS = 0;_  
_//After configuration of the receiver, we need DATA1 as an input_  
_PORTA = 0b.0000.0000;_  
_TRISA = 0b.0011.1100; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_

_delay\_ms(1);_  
_//Start monitoring the air_  
_CE = 1; CS = 0;_  
_//printf(“RX Configuration finished…\n\r”, 0);_  
_}_  
_[//2.4G](https://2.4G) Configuration - Transmitter_  
_//This sets up one RF-24G for shockburst transmission_  
_void configure\_transmitter(void)_  
_{_  
_uns8 i,j;_  
_//uns24 config\_setup;_  
_uns8 config\_setup[3], temp;_

_PORTA = 0b.0000.0000;_  
_TRISA = 0b.0011.1000; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_  
_//Config Mode_  
_CE = 0; CS = 1;_

_delay\_ms(1);_

_//Delay of 5us from CS to Data (page 30) is taken care of by the for loop_

_//Setup configuration word_  
_//config\_setup = 0b.0010.0011.0100.1110.0000.0100; //Look at pages 13-15 for more bit info_  
_config\_setup[0] = 0b.0000.0100;_  
_config\_setup[1] = 0b.0100.1110;_  
_config\_setup[2] = 0b.0010.0011;_

_/\*//purchased version_  
_for(i = 0 ; i \< 24 ; i++)_  
_{_  
_DATA1 = config\_setup.23;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_config\_setup \<\<= 1;_  
_}_  
_\*/_

_//free version_  
_for (j = 3; j \> 0; j–)_  
_{_  
_for(i = 0 ; i \< 8 ; i++)_  
_{_  
_DATA1 = config\_setup[j-1].7;_  
_CLK1 = 1;_  
_CLK1 = 0;_

_config\_setup[j-1] \<\<= 1;_

_}_  
_}_

_delay\_ms(1);_

_//Configuration is actived on falling edge of CS (page 10)  
 CE = 0; CS = 0;  
 //printf(“TX Configuration finished…\n\r”, 0);  
 }  
 //General short delay  
 void delay\_ms(uns16 x)  
 {  
 uns8 y, z;  
 for ( ; x \> 0 ; x–)  
 for ( y = 0 ; y \< 4 ; y++)  
 for ( z = 0 ; z \< 176 ; z++);  
 }_

---

<div class="post-metadata">

**Author:** ![Jay\_C](https://avatars.discourse-cdn.com/v4/letter/j/c2a13f/32.png) [@Jay\_C](https://community.sparkfun.com/u/Jay_C)\
**Post date:** [December 3, 2008, 11:21pm UTC](https://community.sparkfun.com/t/nrf2401a/9196/2 "2008-12-03T23:21:25Z")

</div>

> 1. How do you modify the code [notably version 1 from SFE] so as to see the data transferred to either of the modules.

Look at the code you posted. he has commented out the printf statements. You should be able to use hyper term to connect tot he serial port on the dev module. I've not done this, by why else would the DB\_9 be there :)

Jay

---

<div class="post-metadata">

**Author:** ![meres](https://avatars.discourse-cdn.com/v4/letter/m/43a26b/32.png) [@meres](https://community.sparkfun.com/u/meres)\
**Post date:** [December 8, 2008, 8:23am UTC](https://community.sparkfun.com/t/nrf2401a/9196/3 "2008-12-08T08:23:02Z")

</div>

Thanks for the hint Jay C.

I went over the PIC16F88 data sheet and was able to use the txreg to output bytes on the hyper terminal screen using the function below

[void soft\_rs232\_out (unsigned char dat)

{

txreg = dat;

while (pir1.TXIF == 0);

delay\_ms (1);

} // from stdio.c --SFE

]

I went of the SFE code for 4byte payload[[http://www.sparkfun.com/commerce/produc … cts\_id=152](http://www.sparkfun.com/commerce/product_info.php?products_id=152)] and split the program into two sections: TX and Rx.

TX

[/\* Active mode Tx

23: 0 Payloads have an 8 bit address

22: 0

21: 1

20: 0

19: 0

18: 0

17: 1 16-Bit CRC

16: 1 CRC Enabled

15: 0 One channel receive

14: 1 ShockBurst Mode

13: 1 1 Mbps Transmission Rate

12: 0

11: 1

10: 1

9: 1 RF Output Power

8: 0 RF Output Power

7: 0 Channel select (channel 2)

6: 0

5: 0

4: 0

3: 0

2: 1

1: 0

0: 0 Transmit mode\*/

#include \<system.h\>

#include \<PIC16F88.H\>

#pragma DATA \_CONFIG1, \_CP\_OFF & \_CCP1\_RB0 & \_DEBUG\_OFF & \_WRT\_PROTECT\_OFF & \_CPD\_OFF & \_LVP\_OFF & \_BODEN\_OFF & \_MCLR\_ON & \_PWRTE\_ON & \_WDT\_OFF & \_INTRC\_IO

#pragma DATA \_CONFIG2, \_IESO\_ON & \_FCMEN\_ON

#pragma CLOCK\_FREQ 8000000

#define CS porta.0 //out

#define CLK1 porta.1 //out

#define DATA1 porta.2 //I/O

#define DR1 porta.3 //in

#define DATA2 porta.4 //in

#define CE porta.6 //out

#define CLK2 porta.7 //out

#define Serial\_In\_BB portb.2 //

#define Serial\_Out\_BB portb.5 //

#define DR2 portb.0 //in

#define stat1 portb.1 //out

#define stat2 portb.3 //out

#define stat3 portb.4 //out

void boot\_up(void);

void configure\_transmitter(void);

void transmit\_data(void);

void soft\_rs232\_out (unsigned char);

void output\_byte (unsigned char);

unsigned char data\_array[4] ;

unsigned char counter;

void main()

{

boot\_up();

delay\_ms(3); // Tpd2cfgm PWR\_DWN 2 CONFIG MODE

configure\_transmitter ();

counter = 0;

while (1)

{

data\_array[0] = 0x73; // ascii ‘s’

data\_array[1] = 0x6A; // ascii ‘j’

data\_array[2] = 0x75; // ascii ‘u’

data\_array[3] = counter;

delay\_ms (20); //delay for 4 msec before sending next payload

transmit\_data();

counter++ ;

// sprinf(“TX\_STAT”);

soft\_rs232\_out(‘S’);

soft\_rs232\_out(‘T’);

soft\_rs232\_out(‘x’);

soft\_rs232\_out(’ ');

}

}

void boot\_up (void)

{

osccon = 0b01110000; //Setup internal oscillator for 8MHz

while(osccon.2 == 0); //Wait for frequency to stabilize

ansel = 0b00000000; //Turn pins to Digital instead of Analog

cmcon = 0b00000111; //Turn off comparator on RA port

option\_reg.7 = 1;

porta = 0b00000000;

trisa = 0b00111100; //0 = Output, 1 = Input

portb = 0b00000000;

trisb = 0b11000001; //0 = Output, 1 = Input

spbrg = 51; // for 9600baud @ 8MHz && BRGH = 1; High speed.

txsta = 0b01100101; // [CRSC=0:TX9=1:TXEN=1;SYNC=0] [X=0:BRGH=1:TRMT:TX9D]

rcsta.SPEN = 1; // enable tx n rx on ports RB2 n RB5 RCSTA = 0b.1001.0000; //

pie1.TXIE = 0; // disable interrupts

unsigned char x;

for (x = 0 ; x \< 3 ; x++)

{

stat1 = 1 ;

delay\_ms(25);

stat1 = 0;

stat2 = 1;

delay\_ms(25);

stat2 = 0;

stat3 = 1;

delay\_ms(25);

stat3 = 0;

}

stat1 = 1;

}

void soft\_rs232\_out (unsigned char dat)

{

txreg = dat;

while (pir1.TXIF == 0);

delay\_ms (1);

}

//This sends out the data stored in the data\_array

//data\_array must be setup before calling this function

void transmit\_data(void)

{

unsigned char i;

CE = 1 ;

delay\_us(5); // Tcedata ;Minimum delay from CE 2 data

// Clock in address:

// rf\_address = 0b.1110.0111; //Power-on Default for all units (on page 11)

output\_byte (0b11100111);

//Clock in the data\_array:

for(i = 0 ; i \< 4 ; i++) // 4bytes

{

output\_byte ( data\_array\*);\*  
_}_

_CE = 0; // Start transmission_

_delay\_us(195); // Tsby2txSB: ST\_BY 2 TX shockBurst._  
_i = 4; // now delay Toa, 5us per bit_  
_do{_  
_delay\_us (8+8+32+8); // preamble + address + payload + CRC_  
_}while (–i != 0);_  
_}_  
_[//2.4G](https://2.4G) Configuration - Transmitter_  
_//This sets up one RF-24G for shockburst transmission_  
_void configure\_transmitter(void)_  
_{_  
_// config mode_  
_porta = 0b00000000; // Everything low_

- // Need Td here (50ns so we’re ok)\*
- porta = 0b00000001; // CS = 1;\*
- // Now safe to set DATA1 as output.\*  
_trisa = 0b00111000; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_  
_delay\_us (5); // Tcs2data Min Delay from CS 2 DATA_

_//Setup configuration word_  
_//config\_setup = 0b.0010.0011.0100.1110.0000.0100; //Look at pages 13-15 for more bit info_

_output\_byte (0b00100000); //MSB first_  
_output\_byte (0b01101110);_  
_output\_byte (0b00000100);_

_//Configuration is actived on falling edge of CS (page 10)_  
_// nb data one is left as output._

_porta = 0b00000000; // CS = 0;_  
_// Td is req here.\*\*\*\*\*\*\*\*\*\*\*_  
_soft\_rs232\_out(‘T’);_

- soft\_rs232\_out(‘C’); \*  
_soft\_rs232\_out(‘N’);_  
_soft\_rs232\_out(‘f’);_

_}_  
_#pragma OPTIMIZE “1”_  
_void output\_byte (unsigned char byte)_  
_{_  
_unsigned char i = 8;_  
_do{_  
_DATA1 = byte.7;_  
_//TS might be marginal if the CLK is a bit fast_  
_CLK1 = 1;_  
_byte \<\<=1; // Th/Thmin are both 500ns_  
_CLK1 = 0;_  
_} while (–i != 0);_  
_}_  
_]_  
_RX_  
_[/\* Active mode Tx_  
_23: 0 Payloads have an 8 bit address_  
_22: 0_  
_21: 1_  
_20: 0_  
_19: 0_  
_18: 0_  
_17: 1 16-Bit CRC_  
_16: 1 CRC Enabled_  
_15: 0 One channel receive_  
_14: 1 ShockBurst Mode_  
_13: 0 250kbsp Transmission Rate_  
_12: 0_  
_11: 1_  
_10: 1_  
_9: 1 RF Output Power_  
_8: 0 RF Output Power_  
_7: 0 Channel select (channel 2)_  
_6: 0_  
_5: 0_  
_4: 0_  
_3: 0_  
_2: 1_  
_1: 0_  
_0: 1 //receive modede_  
_\*/_  
_#include \<system.h\>_  
_#include \<PIC16F88.h\>_  
_#pragma DATA \_CONFIG1, \_CP\_OFF & \_CCP1\_RB0 & \_DEBUG\_OFF & \_WRT\_PROTECT\_OFF & \_CPD\_OFF & \_LVP\_OFF & \_BODEN\_OFF & \_MCLR\_ON & \_PWRTE\_ON & \_WDT\_OFF & \_INTRC\_IO_  
_#pragma DATA \_CONFIG2, \_IESO\_ON & \_FCMEN\_ON_  
_#pragma CLOCK\_FREQ 8000000_  
_#define CS porta.0 //out_  
_#define CLK1 porta.1 //out_  
_#define DATA1 porta.2 //I/O_  
_#define DR1 porta.3 //in_  
_#define DATA2 porta.4 //in_  
_#define CE porta.6 //out_  
_#define CLK2 porta.7 //out_  
_#define Serial\_In\_BB portb.2 //_  
_#define Serial\_Out\_BB portb.5 //_  
_#define DR2 portb.0 //in_  
_#define stat1 portb.1 //out_  
_#define stat2 portb.3 //out_  
_#define stat3 portb.4 //out_  
_void boot\_up (void );_  
_void configure\_receiver(void);_  
_void receive\_data (void);_  
_void soft\_rs232\_out (unsigned char);_  
_void output\_byte (unsigned char);_  
_unsigned char input\_byte (void);_  
_unsigned char data\_array[4];_  
_void main()_  
_{_

_boot\_up();_  
_delay\_ms(3); // Tpd2cfgm PWR\_DWN 2 CONFIG MODE_  
_configure\_receiver();_

_while(1)_  
_{_  
_if( DR1 == 1 ) //We have data!_  
_{_  
_receive\_data();_  
_soft\_rs232\_out(data\_array[0]); // print data Rc’d_

- soft\_rs232\_out(data\_array[1]);\*
- soft\_rs232\_out(data\_array[2]);\*
- soft\_rs232\_out(data\_array[3]);\*

_if ((data\_array[0] == 0x73) && (data\_array[1] == 0x6A) && (data\_array[2] == 0x75))_  
_{_  
_soft\_rs232\_out(‘R’); // if data matches TX’d data_

- soft\_rs232\_out(‘O’);\*
- soft\_rs232\_out(‘K’);\*  
_}_  
_else_  
_{_  
_// You’r DT!!_
- soft\_rs232\_out (‘D’);\*
- soft\_rs232\_out (‘T’); \*
- soft\_rs232\_out(data\_array[0]); // print data Rc’d\*
- soft\_rs232\_out(data\_array[1]);\*
- soft\_rs232\_out(data\_array[2]);\*
- soft\_rs232\_out(data\_array[3]);\*
- }\*  
_}_  
_else_  
_{_  
_soft\_rs232\_out(‘N’); // No data yet_
- soft\_rs232\_out(‘D’);\*
- soft\_rs232\_out(‘T’);\*

_}_  
_}_

_}_  
_void boot\_up(void)_  
_{_  
_osccon = 0b01110000; //Setup internal oscillator for 8MHz_  
_while(osccon.IOFS == 0); //Wait for frequency to stabilize_  
_ansel = 0b00000000; //Turn pins to Digital instead of Analog_  
_cmcon = 0b00000111; //Turn off comparator on RA port_  
_option\_reg.7 = 1;_  
_porta = 0b00000000;_  
_trisa = 0b00111100; //0 = Output, 1 = Input_  
_portb = 0b00000000;_  
_trisb = 0b11000001; //0 = Output, 1 = Input_

_spbrg = 51; // for 9600baud @ 8MHz && BRGH = 1; High speed._

- txsta = 0b01100101; // [CRSC=0:TX9=1:TXEN=1;SYNC=0] [X=0:BRGH=1:TRMT:TX9D]\*
- rcsta.SPEN = 1; // enable tx n rx on ports RB2 n RB5 RCSTA = 0b.1001.0000; //\*  
_pie1.TXIE = 0; // disable interrupts_  
_unsigned char x;_  
_for (x = 0; x \< 3; x++)_  
_{_  
_stat1 = 1;_  
_delay\_ms(25);_  
_stat1 = 0;_  
_stat2 = 1;_  
_delay\_ms(25);_  
_stat2 = 0;_  
_stat3 = 1;_  
_delay\_ms(25);_  
_stat3 = 0;_  
_}_  
_stat1 = 1;_

_soft\_rs232\_out(‘B’);_

- soft\_rs232\_out(‘t’);\*
- soft\_rs232\_out(‘O’);\*
- soft\_rs232\_out(‘K’);\*

_}_  
_void soft\_rs232\_out (unsigned char dat)_  
_{_  
_txreg = dat;_

_while (pir1.TXIF == 0);_  
_//delay\_ms (1);_  
_}_  
_[//2.4G](https://2.4G) CONFIGURE - RECEIVER_  
_//This setups up a RF-24G for receiving at 1Mbps_  
_void configure\_receiver(void)_  
_{_  
_//During configuration of the receiver, we need DATA1 as an output_  
_porta = 0b00000000;_

- //Need Td here at least 50ns\*  
_porta = 0b00000001; //Config Mode CE = 0; CS = 1;_
- //Now safe to set DATA1 as output\*  
_trisa = 0b00111000; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_

_delay\_us (5); //Tcs2Data: Min Delay from CS 2 DATA_

_//Setup configuration word, set up for 1Mbps_  
_//config\_setup = 0b.23[0010.0011.0110.1110.0000.0101:bit0;_  
_output\_byte (0b00100000); // Load MSB first._  
_output\_byte (0b01101110);_  
_output\_byte (0b00000101);_  
_porta = 0b00000001; // Everything but CS low ie CS=1._  
_//After configuration of the receiver, we need DATA1 as an input_  
_trisa = 0b00111100; //0 = Output, 1 = Input (DR1 is on RA3) (DATA1 is on RA2)_

_porta = 0b00000000; // CS =0:_  
_//Td (50ns) requred here_  
_//Configuration is actived on falling edge of CS (page 10)_

_//Start monitoring the air_  
_CE = 1; //CS = 0;_

_soft\_rs232\_out(‘R’);_  
_soft\_rs232\_out(‘C’);_  
_soft\_rs232\_out(‘N’);_

_}_  
_//This will clock out the current payload into the data\_array_  
_void receive\_data (void)_  
_{_  
_unsigned char i,temp;_

_CE = 0; //Power down RF Front : nb: CS is still 0 from config._  
_//Erase the current data array so that we know we are looking at actual received data_  
_data\_array[0] = 0x00;_  
_data\_array[1] = 0x00;_  
_data\_array[2] = 0x00;_  
_data\_array[3] = 0x00;_  
_//Clock in data, we are setup for 32-bit payloads_  
_for (i=0 ;i\<4 ; i++) // 4bytes_  
_{_  
_temp = input\_byte ();_  
_data\_array = temp; // store this byte_  
 _}  
 CE = 1; //Power up RF Front end  
 soft\_rs232\_out(‘R’);  
 \* soft\_rs232\_out(‘V’);  
 soft\_rs232\_out(‘G’);  
\_}\_  
\_#pragma OPTIMIZE “1”\_  
 void output\_byte(unsigned char byte)  
\_{\_  
 unsigned char i=8;  
 do{  
 DATA1 = byte.7;  
\_//TS might be marginal if the CLK is a bit fast\*\_  
 CLK1 = 1;  
 byte \<\<= 1; // Th/Thmin are both 500ns  
 CLK1 = 0;  
 } while (–i != 0);  
 }_

 

_#pragma OPTIMIZE “1”_  
_unsigned char input\_byte(void)_  
_{_  
_unsigned char byte;_  
_unsigned char j=8;_  
_do{_  
_byte \<\<= 1;_  
_CLK1 = 1;_  
_byte.0 = DATA1; //Ensure Thnmin of 500ns;_  
_CLK1 =0;_  
_}while (–j !=0);_  
_return byte;_  
_}_

_]  
 I initially used CC5X to compile the code but soon turned to BoostC -within the MPLAB IDE- so as to utilise the delay- delay\_us() & delay\_ms(). provided in the SourceBoost library.  
 I have been able to successfully compile both the Tx and Rx code but unfortunately when I program the MCU- using winpic- They don’t talk!!!  
 I’ve tried both 1Mbps and 250 bps with no luck.  
 Ok I am new at this so bear with me as I ponder out loud:  
 1) my Config words- I believe Config1 should be 0x3F30 and Config2 3FFC…???  
 2) Timing especially with the rs232 communication: with the soft\_rs232 function, I am able to determine that both Rx n Tx configure and that the the TX is sending data. The Rx however never sees any data—\> DR1 never goes high. …??  
 Any help/ input will be highly appreciated![/code]_

---

<div class="post-metadata">

**Author:** ![leon\_heller](https://yyz1.discourse-cdn.com/sparkfun/user_avatar/community.sparkfun.com/leon_heller/32/7602_2.png) [@leon\_heller](https://community.sparkfun.com/u/leon_heller)\
**Post date:** [December 8, 2008, 9:39am UTC](https://community.sparkfun.com/t/nrf2401a/9196/4 "2008-12-08T09:39:03Z")

</div>

Here’s some simple test code:

```auto
; ***************************************************************
;Test.asm
;Tx/Rx test program for nRF2401
;MCU: PIC16F88
;
;LED	- RB4 output
;
;nRF2401 connections to 16F88
;CE - RA6 output
;CS - RA0 output
;DR1 - RA3 output
;CLK1 - RA1 output
;DATA - RA2 input/output
; ***************************************************************

#define LED 4
#define CE 6
#define CS 0
#define DR1 3
#define CLK1 1
#define DATA1 2	;DATA is reserved word

	#include	<p16f88.inc>

	CBLOCK 0x50
	scrA:	1	; scratch pad	0X50
	scrB:	1
	count
	data_0
	data_1
	data_2
	data_3
	ENDC

	org 0

; **************************************************************
;main program
; **************************************************************
	call	init
	call	flash_led
loop:	
	call	Tx_config
	call	Tx_data
	call	Rx_config
	call	Rx_data
	call	dly
	goto	loop
	

; ***************************************************************
;initialisation
; ***************************************************************
init:
	BANKSEL	OSCCON
	MOVLW	0x70 ; 8 MHz int. RC osc.
	MOVWF	OSCCON

WAIT1:
	BTFSS	OSCCON,2	; wait until freq. is stable
	GOTO	WAIT1

	BANKSEL PORTB ; select bank of PORTB
	CLRF PORTB ; Initialize PORTB by
						; clearing output
						; data latches
	BANKSEL	ANSEL ; Select Bank of ANSEL
	MOVLW	0x00 ; Configure all pins
	MOVWF	ANSEL ; as digital
	banksel TRISB
	BCF TRISB,LED	; LED (RB4) output
	BCF TRISA,CE	; CE (RA6) output
	BCF TRISA,DATA1	; DATA1 (RA2) output
	BANKSEL	PORTA	
	BSF PORTA,CE	; CE high
	bcf PORTA,CLK1
	return

; ******************************************************************
;flash LED three times
; ******************************************************************
flash_led
	movlw	3
	movwf	count
flash1:
	BSF PORTB,LED	;toggle LED
	call	dly
	BCF PORTB,LED
	call	dly
	decfsz	count,f
	goto	flash1
	return

; ****************************************************************
;transmit configuration
; ****************************************************************
Tx_config:
	banksel	PORTA
	clrf	PORTA
	movlw	0x38
	movwf	TRISA
	bcf PORTA,CE	;set config mode (CE = 0, CS = 1)
	bsf PORTA,CS
	call	dly
	;send 24 bit configuration word 001000110100111000000100 (0x234E04) MS bit first
	movlw	0x23
	call	put_byte
	movlw	0x4E
	call	put_byte
	movlw	0x04
	call	put_byte
	call	dly
	banksel	PORTA
	bcf PORTA,CE
	bsf PORTA,CS	;configuration enabled on falling edge of CS
	return

; ******************************************************************
;receive configuration
; ******************************************************************
Rx_config:
	banksel	PORTA
	clrw
	movfw	PORTA ;all bits low
	movlw	0x38 ;DATA1, DR1 output
	movfw	TRISA
	banksel	PORTA
	bcf PORTA,CE	;set config mode (CE = 0. CS = 1)
	bsf PORTA,CS
	call	dly
	;send 24 bit configuration word 001000110100111000000101 (0x234E05) MS bit first
	movlw	0x23
	call	put_byte
	movlw	0x4E
	call	put_byte
	movlw	0x05
	call	put_byte
	banksel	PORTA
	bcf PORTA,CE
	bcf PORTA,CS
	clrw
	movwf	PORTA
	movlw	0x3A ;DATA1 muse be input
	movwf	TRISA
	bcf PORTA,CE
	bsf PORTA,CS
	return

; *****************************************************************************
;transmit data
; *****************************************************************************
Tx_data:
	banksel	PORTA
	bsf PORTA,CE	;power up RF front end (CE = 1)
	call	dly
	movlw	0xE7 ;RF address 11100111 (0xE7)
	call	put_byte	;clock in address
	movlw	0x11 ;send four data bytes (0x11223344)
	call	put_byte
	movlw	0x22
	call	put_byte
	movlw	0x33
	call	put_byte
	movlw	0x44
	call	put_byte
	bcf PORTA,CE	;start transmission (CE = 0)
	return

; ****************************************************************************
;receive data
; ****************************************************************************
Rx_data:
	banksel	PORTA
	bcf PORTA,CE	;power down RF front end
	clrf	data_0 ;zero buffers so that we can ensure that
	clrf	data_1 ;correct date is being received
	clrf	data_2
	clrf	data_3
	call	get_byte	;receive four bytes and save in buffer
	movwf	data_0
	call	get_byte
	movwf	data_1
	call	get_byte
	movwf	data_2
	call	get_byte
	movwf	data_3
	bsf PORTA,CE	;power up RF front end
	return

; ***************************************************************************
;send byte to nRF2401 (MS bit first)
;byte in WREG
; ***************************************************************************
put_byte:
	movwf	scrA	;save byte
	movlw	8 ;initialise bit counter
	movwf	count
	banksel	PORTA
put_1:
	btfsc	scrA,7 ;bit 7 = 0?
	goto	put_2 ;no, jump
	bcf PORTA,DATA1 ;clear DATA
	bsf PORTA,CLK1 ;clock it
	bcf PORTA,CLK1
	goto	put_3
put_2:
	bsf PORTA,DATA1 ;set DATA
	bsf PORTA,CLK1 ;clock it
	bcf PORTA,CLK1
put_3:
	rlf scrA,f ;left shift for next bit
	decfsz	count,f ;more bits?
	goto	put_1 ;yes, loop back
	return ;no, return			

; ***************************************************************************
;get byte from nRF2401 (MS bit first) by clocking in data from DATA1
;byte returned in WREG
; ***************************************************************************
get_byte:
	banksel	PORTA
	movlw	8 ;initialise bit counter
	movwf	count
get_1:
	btfsc	PORTA,DATA1	;data = 1?
	goto	get_2		
	bcf scrA,0 ;no, clear MS bit
	goto	get_3
get_2:
	bsf scrA,0 ;Yes, set MS bit
get_3:
	bsf PORTA,CLK1
	bcf PORTA,CLK1
	rlf scrA,f ;left shift for next bit
	decfsz	count,f ;more bits?
	goto	get_1 ;no, loop back
	movfw	scrA ;return with byte in WREG
	return

; **************************************************************************
;delay routine
; **************************************************************************
dly:

	return

	movlw	0xFF
	movwf	scrB
dly_1
	movlw	0xFF                        
	movwf	scrA                          
dly_2:	
	decfsz	scrA, F                    
	goto	dly_2
	decfsz	scrB,F
	goto	dly_1                          
	return
	

	end

```

Just run it on both units.

Leon

---

<div class="post-metadata">

**Author:** ![meres](https://avatars.discourse-cdn.com/v4/letter/m/43a26b/32.png) [@meres](https://community.sparkfun.com/u/meres)\
**Post date:** [December 9, 2008, 7:01am UTC](https://community.sparkfun.com/t/nrf2401a/9196/5 "2008-12-09T07:01:07Z")

</div>

Leon!

Thanks for the code, I compiled the code using MPLAB (compiler CC5X) and programmed the PIC16F88 with WinPic ConFig word 1 3F30 and config2 3FFC but no results . I hoped the LED would blink but no luck.

I was wondering whether you had the same code in C or if you / anyone can point me in that direction.

Also, does anyone have a schematic of SFE’ [[http://www.sparkfun.com/commerce/produc … cts\_id=152](http://www.sparkfun.com/commerce/product_info.php?products_id=152)]"nrf2401a with chip antenna schematic ???

---

<div class="post-metadata">

**Author:** ![leon\_heller](https://yyz1.discourse-cdn.com/sparkfun/user_avatar/community.sparkfun.com/leon_heller/32/7602_2.png) [@leon\_heller](https://community.sparkfun.com/u/leon_heller)\
**Post date:** [December 9, 2008, 10:39am UTC](https://community.sparkfun.com/t/nrf2401a/9196/6 "2008-12-09T10:39:41Z")

</div>

It was a long time ago but I’m quite sure it worked for me at the time.

I might be using a different LED on my PCB, is your’s on RB4?

I just looked through the code and it only flashes the LED at the beginning (three times). I must have used the debugger to check that the correct data was being received. If you do that, you should see if your boards are working.

It was based on a CC5X program on the SFE web site, but I can’t find the original C source code.

Leon

---

<div class="post-metadata">

**Author:** ![jdstufu](https://avatars.discourse-cdn.com/v4/letter/j/a587f6/32.png) [@jdstufu](https://community.sparkfun.com/u/jdstufu)\
**Post date:** [February 8, 2009, 3:50pm UTC](https://community.sparkfun.com/t/nrf2401a/9196/7 "2009-02-08T15:50:22Z")

</div>

Hello… What kind of serial interface does the NRf2401 chip use to communicate with a microcontroller? SPI? I2C?

---

<div class="post-metadata">

**Author:** ![leon\_heller](https://yyz1.discourse-cdn.com/sparkfun/user_avatar/community.sparkfun.com/leon_heller/32/7602_2.png) [@leon\_heller](https://community.sparkfun.com/u/leon_heller)\
**Post date:** [February 8, 2009, 5:04pm UTC](https://community.sparkfun.com/t/nrf2401a/9196/8 "2009-02-08T17:04:13Z")

</div>

It’s clocked serial, like SPI, and is usually bit-banged. It isn’t SPI-compatible but Nordic has a hardware fix for that. I don’t know if it works, though.

The nRF24L01 has proper SPI.

Leon
