Alright… after much struggling, I have got the wireless module to work.
For those who are interested, here is the code.
Once again, I’m using CCS S compiler with dsPIC micro-controller for nRF2401a.
Here is the RX code:
#include <30F3013.h> //Include header file of dsPIC30F3013
#include <stdlib.h>
#include <stdio.h>
#use delay(clock = 20MHz,CRYSTAL = 20MHz)
// Oscillation freq. 20MHz
#use rs232(baud=38400,parity=N,UART1A,bits=8,stream=HOST)
//XMIT=PIN_C13,RCV=PIN_C14
#define RX_CE PIN_B4
#define RX_CS PIN_B5
#define RX_CLK1 PIN_B6
#define RX_DATA PIN_B7
#define RX_DR PIN_B8
unsigned int8 data_array[4];
void boot_up(void);
void configure_receiver(void);
void receive_data(void);
void main()
{
boot_up();
while(1)
{
if(input(RX_DR)) //if(RX_DR == 1) //We have data!
receive_data();
else
printf("No data found!\n\r");
delay_ms(1000); //Have a second between transmissions just for evaluation
}
}
void boot_up(void)
{
set_tris_B(0b0100000000); //0 = Output, 1 = Input (RX_DR is on RB8)
printf("\n\rRF-24G Testing:\n\r");
delay_ms(100);
configure_receiver();
}
//2.4G Configuration - Receiver
//This setups up a RF-24G for receiving at 1mbps
void configure_receiver(void)
{
unsigned int8 i;
long config_setup, tempRX;
//During configuration of the receiver, we need RX_DATA as an output
set_tris_B(0b0100000000); //0 = Output, 1 = Input (RX_DR is on RB8) (RX_DATA is on RB1)
//Config Mode
output_low(RX_CE); //RX_CE = 0;
output_high(RX_CS); //RX_CS = 1;
//Delay of 5us from CS to Data (page 25) is taken care of by the for loop
delay_us(5);
//Setup configuration word
config_setup = 0b001000110110111100000011;
//Look at pages 18-23 for more bit info
//Bit 0: CRC generation/checking enabled; To check if system is RX or TX (1=enable, 0=disable)
//Bit 1: 8 bit CRC (1=16bit, 0=8bit)
//Bit 2-7: ADDR_W address width of the channel (00001 = 0x01)
//Bit 8-23: ADDR1; Up to 5 byte address for RX channel 1 (0x236D)
for(i = 0 ; i < 24 ; i++) //8 bit per hexa, per byte
{
tempRX = 0x000000;
if( ((tempRX|config_setup)&(0x800000)) == 0x800000)
{
output_high(RX_DATA);
}
else
{
output_low(RX_DATA);
}
//TX_DATA = config_setup.23;
config_setup = config_setup << 1;
delay_us(1/2); //page 28 figure 15
output_high(RX_CLK1); //TX_CLK1 = 1;
delay_us(1/2); //page 28 figure 15
output_low(RX_CLK1); //TX_CLK1 = 0;
delay_us(1/2); //page 28 figure 15
output_low(RX_DATA);
}
//Configuration is active on falling edge of CS (page 27)
output_low(RX_CE); //RX_CE = 0;
output_low(RX_CS); //RX_CS = 0;
delay_us(1);
//After configuration of the receiver, we need RX_DATA as an input
set_tris_B(0b0110000000); //TRISA = 0b.0000.0011; //0 = Output, 1 = Input (RX_DR is on RB8) (RX_DATA is on RB7)
//Start monitoring the air
output_high(RX_CE); //RX_CE = 1;
output_low(RX_CS); //RX_CS = 0;
delay_us(5);
printf("RX Configuration finished...\n\r");
}
//This will clock out the current payload into the data_array
void receive_data(void)
{
unsigned int8 i, j, tempRX;
output_low(RX_CE); //RX_CE = 0;//Power down RF Front end
//delay_us(203);
//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;
tempRX = 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
{
tempRX = tempRX << 1;
delay_us(1/2); //page 28 figure 15
output_high(RX_CLK1); //RX_CLK1 = 1
//output_high(RX_DATA);
if(input(RX_DATA))
{
tempRX |= 0x01;
}
delay_us(1/2); //page 28 figure 15
output_low(RX_CLK1); //RX_CLK1 = 0
delay_us(1/2); //page 28 figure 15
}
// tempRX = data_array[i]; //Store this byte
data_array[i] = tempRX;
}
if(!(input(RX_DR))) //Once the data is clocked completely, the receiver should make DR go low
printf("DR went low\n\r");
printf("\n\rData Received:\n\r");
printf("[0] : %x\n\r", data_array[0]);
printf("[1] : %x\n\r", data_array[1]);
printf("[2] : %x\n\r", data_array[2]);
printf("[3] : %x\n\r", data_array[3]);
output_high(RX_CE); //RX_CE = 1; //Power up RF Front end
}
TX:
#include <30F3013.h> //Include header file of dsPIC30F3013
#include <stdlib.h>
#include <stdio.h>
#use delay(clock = 20MHz,CRYSTAL = 20MHz)
// Oscillation freq. 20MHz
#use rs232(baud=38400,parity=N,UART1A,bits=8,stream=HOST)
//XMIT=PIN_C13,RCV=PIN_C14
#define TX_CE PIN_B0
#define TX_CS PIN_B1
#define TX_CLK1 PIN_B2
#define TX_DATA PIN_B3
void boot_up(void);
void configure_transmitter(void);
void transmit_data(void);
unsigned int8 data_array[4];
int counter;
void main()
{
boot_up();
counter = 0;
while(1)
{
delay_ms(1000);
data_array[0] = 0x10;
data_array[1] = 0x20;
data_array[2] = 0x30;
data_array[3] = counter++;
transmit_data();
}
}
void boot_up(void)
{
printf("\n\rRF-24G Testing:\n\r");
delay_ms(100);
configure_transmitter();
}
//2.4G Configuration - Transmitter
//This sets up one RF-24G for shockburst transmission
void configure_transmitter(void)
{
unsigned int8 i;
long config_setup, tempTX;
delay_us(1/10); //page 25 figure 12
//Config Mode
output_low(TX_CE); //TX_CE = 0;
output_high(TX_CS); //TX_CS = 1;
//Delay of 5us from CS to Data (page 30) is taken care of by the for loop
delay_us(5);
//Setup configuration word
config_setup = 0b001000110110111100000010;
//Look at pages 18-23 for more bit info
//Bit 0: CRC generation/checking disabled; To check if system is RX or TX (1=enable, 0=disable)
//Bit 1: 8 bit CRC (1=16bit, 0=8bit)
//Bit 2-7: ADDR_W address width of the channel
//Bit 8-23: ADDR1; Up to 5 byte address for RX channel 1
for(i = 0 ; i < 24 ; i++) //8 bit per hexa, per byte
{
tempTX = 0x000000;
if( ((tempTX|config_setup)&(0x800000)) == 0x800000)
//if(input(TX_CS))
{
output_high(TX_DATA);
}
else
{
output_low(TX_DATA);
}
//TX_DATA = config_setup.23;
//tempTX = tempTX << 1;
config_setup = config_setup << 1;
delay_us(1/2); //page 27 figure 14
output_high(TX_CLK1); //TX_CLK1 = 1;
delay_us(1/2); //page 27 figure 14
output_low(TX_CLK1); //TX_CLK1 = 0;
delay_us(1/2); //page 27 figure 14
output_low(TX_DATA);
}
//standby mode
output_low(TX_CE); //TX_CE = 0;
output_low(TX_CS); //TX_CS = 0; //Configuration is actived on falling edge of CS (page 17)
delay_us(1);
output_low(TX_DATA);
printf("TX Configuration finished...\n\r");
}
void transmit_data(void)
{
unsigned int8 i, j, k, tempTX, ADDR1;
delay_us(1/20); //page 28 figure 15
output_high(TX_CE); //TX_CE = 1;
output_low(TX_CS); //TX_CS = 0;
//Delay of 5us from CS to Data (page 30) is taken care of by the for loop
delay_us(5);
//Clock in address
ADDR1 = 0b11100111; //Power-on Default for all units (on page 19)
for(k = 0 ; k < 8 ; k++)
{
if( (ADDR1 & 0x80) == 0x80 )
{
output_high(TX_DATA); //TX_DATA = 1; Set Data high
}
else
{
output_low(TX_DATA); //TX_DATA = 0; Set Data low
}
delay_us(1/2); //page 28 figure 15
output_high(TX_CLK1); //TX_CLK1 = 1;
delay_us(1/2); //page 28 figure 15
output_low(TX_CLK1); //TX_CLK1 = 0;
delay_us(1/2); //page 28 figure 15
output_low(TX_DATA); //TX_DATA = 0; Set Data low
ADDR1 = ADDR1 << 1; //Left Shift to get next bit
}
//Clock in the data_array
for(i = 0 ; i < 4 ; i++)
{
tempTX = data_array[i];
for(j = 0 ; j < 8 ; j++) //One bit at a time
{
if( ((tempTX)&(0x80)) == 0x80)
{
output_high(TX_DATA); //TX_DATA = 1; Set Data high
}
else
{
output_low(TX_DATA); //TX_DATA = 0; Set Data low
}
//TX_DATA = rf_address.7;
delay_us(1/2); //page 28 figure 15
output_high(TX_CLK1); //TX_CLK1 = 1;
delay_us(1/2); //page 28 figure 15
output_low(TX_CLK1); //TX_CLK1 = 0;
delay_us(1/2); //page 28 figure 15
output_low(TX_DATA); //TX_DATA = 0; Set Data low
tempTX = tempTX << 1; //Left Shift to get next bit
}
}
//standby mode
output_low(TX_CE); //TX_CE = 0;
output_low(TX_CS); //TX_CS = 0;
delay_us(1);
output_low(TX_DATA);
}
Feel free to ask me any question. I will help with the best of my knowledge!
P.S. some of the comments are wrong. So please do read with care. Always have the datasheet on hand!