SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By meres
#60075
I recently bought two nrf2401a modules <http://www.sparkfun.com/commerce/produc ... cts_id=152> along with the accompanying development nodes <http://www.sparkfun.com/commerce/produc ... cts_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.
2) 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 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 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++);
}
By Jay C
#60548
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
By meres
#60869
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] 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 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 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]
User avatar
By leon_heller
#60872
Here's some simple test code:
Code: Select all
;***************************************************************
;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
By meres
#60958
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]"nrf2401a with chip antenna schematic ???




[/url]
User avatar
By leon_heller
#60965
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
By jdstufu
#65634
Hello... What kind of serial interface does the NRf2401 chip use to communicate with a microcontroller? SPI? I2C?
User avatar
By leon_heller
#65641
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