Hello
I got this nordic nrf24l01+ module and trying to interface with pic18f25k22. this is my code. tried lot but unable to communicate (receive any data). I'm able to read the register values through SPI. I verified that all registers have values as configured. Please help me asap thanks in advance
transmitter :-
#include <xc.h>
#include "stdint.h"
#include <p18f25k22.h>
#include <flash.h>
#include <stdio.h>
#include <string.h>
#include<plib/spi.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = OFF // HFINTOSC Fast Start-up (HFINTOSC output and ready status are delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5 // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = OFF // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
#define FOSC 8000000
#define BAUD 9600
#define _XTAL_FREQ 8000000
/* ConfigRegisters */
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DYNPD 0x1C
#define FEATURE 0x1D
/* Bit Mnemonics */
/* configuration register */
#define MASK_RX_DR 6
#define MASK_TX_DS 5
#define MASK_MAX_RT 4
#define EN_CRC 3
#define CRCO 2
#define PWR_UP 1
#define PRIM_RX 0
/* enable auto acknowledgment */
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
/* enable rx addresses */
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
/* setup of address width */
#define AW 0 /* 2 bits */
/* setup of auto re-transmission */
#define ARD 4 /* 4 bits */
#define ARC 0 /* 4 bits */
/* RF setup register */
#define PLL_LOCK 4
#define RF_DR_HIGH 3
#define RF_PWR 1 /* 2 bits */
/* general status register */
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define RX_P_NO 1 /* 3 bits */
#define TX_FULL 0
/* transmit observe register */
#define PLOS_CNT 4 /* 4 bits */
#define ARC_CNT 0 /* 4 bits */
/* FIFO status */
#define TX_REUSE 6
#define FIFO_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
/* dynamic length */
#define DPL_P0 0
#define DPL_P1 1
#define DPL_P2 2
#define DPL_P3 3
#define DPL_P4 4
#define DPL_P5 5
/* Instruction Mnemonics */
#define R_REGISTER 0x00 /* last 4 bits will indicate reg. address */
#define W_REGISTER 0x20 /* last 4 bits will indicate reg. address */
#define REGISTER_MASK 0x1F
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define W_TX_PAYLOAD_NA 0xB0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define NOP1 0xFF
#define nrf24_CONFIG ((1 << MASK_RX_DR)|(1<<EN_CRC)|(1<<CRCO)|(1<<EN_CRC))
/// hardware SPI pin defined
#define CS_Pin PORTAbits.RA5 //set port as output
#define CE_Pin PORTBbits.RB1 //set port as output
#define SCK_Pin PORTCbits.RC3 //set port as output
#define Mosi_Pin PORTCbits.RC5 //set port as output
#define Miso_Pin PORTCbits.RC4 //set port as input
#define HIGH 1
#define LOW 0
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }
void uart_init(){
OSCTUNE = 0x00; //(INTSRC|PLLEN|TUN<5:0>)
OSCCON = 0x67; //(IDLEN|IRCF<2:0>|OSTS|HFIOFS|SCS<1:0>)
TRISB = 0x04; //(TRISB7|TRISB6|TRISB5|TRISB4|TRISB3|TRISB2|TRISB1|TRISB0)
TRISC = 0x90; //(TRISC7|TRISC6|TRISC5|TRISC4|TRISC3|TRISC2|TRISC1|TRISC0)
TRISAbits.RA5=0;
ANSELC = 0x00;
ANSELB = 0x00;
ANSELA = 0x00;
/*UART1 Initialization*/
PORTCbits.RC6 = 1;
PORTCbits.RC7 = 1;
TXSTA1 = 0x24; //(CSRC|TX9|TXEN|SYNC|SENDB|BRGH|TRMT|TX9D)
//SPBRGH1= 0x01;
SPBRG1= 207; //0xA0;
RCSTA1 = 0x96; //(SPEN|RX9|SREN|CREN|ADDEN|FERR|OERR|RX9D)
BAUDCON1 =0x08;//(ABDOVF|RCIDL|DTRXP|CKTXP|BRG16|?|WUE|ABDEN)
}
void _delay_ms(unsigned int ms){
unsigned int i;
do {
i = 6; //4;
do {
_delay_us(210);
} while(--i);
} while(--ms);
}
void SendByteSerially1(unsigned char Byte){ // Writes a character to the serial port
while(!PIR1bits.TX1IF); // wait for previous transmission to finish
TXREG1 = Byte;
_delay_ms(1);
}
void SPI_Init(){
SSP1CON1bits.SSPEN = 0;
SSP1CON1 = 0x01; // SPI Master mode, clock = Fosc/64
SSP1STAT= 0xC0; // CKE = 1
SSP1CON1bits.SSPEN = 1;
}
void nrf24_ce_digitalwrite(uint8_t state){
if (state)
{
CE_Pin = 1;
}
else
{
CE_Pin = 0;
}
}
void nrf24_csn_digitalwrite(uint8_t state){
if (state)
{
CS_Pin = 1;
}
else
{
CS_Pin = 0;
}
}
/* software SPI routine */
uint8_t spi_transfer(uint8_t tx){
unsigned char temp;
SSP1BUF = tx; // send data to the BUFFER
while(!SSP1STATbits.BF && !PIR1bits.SSP1IF); // wait for the tramsit/recieve to finish
// has to be SSPSTAT.BF not just BF!! (for some reason)
temp = SSP1BUF; // clear the BF flag
PIR1bits.SSP1IF = 0;
return temp;
}
/* send and receive multiple bytes over SPI */ // checked with mirf
void nrf24_transferSync(uint8_t *dataout,uint8_t *datain,uint8_t len){
uint8_t i;
for(i=0;i<len;i++){
datain[i] = spi_transfer(dataout[i]);
}
}
//send multiple bytes over SPI // checked with mirf
void nrf24_transmitSync(uint8_t *dataout,uint8_t len){
uint8_t i;
for(i=0;i<len;i++){
spi_transfer(dataout[i]);
}
}
void nrf24_readRegister(uint8_t reg,uint8_t *value,uint8_t len) //checked with mirf
{
nrf24_csn_digitalwrite(LOW);
spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
nrf24_transferSync(value,value,len);
nrf24_csn_digitalwrite(HIGH);
}
void nrf24_configRegister(uint8_t reg, uint8_t *value, int num){
int i;
nrf24_csn_digitalwrite(LOW);
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
for(i=0;i<num; i++)
{
//SendByteSerially1(value[i]);
spi_transfer(value[i]);
}
nrf24_csn_digitalwrite(HIGH);
// SendByteSerially1(0x51);
}
// checked with mirf
void nrf24_powerUpTx(){
unsigned char flags;
flags = nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX));
// PTX = 1;
nrf24_configRegister(CONFIG,(unsigned char*)&flags,1);
}
void setRFPWR(){
unsigned char temp;
temp=0x06;
nrf24_configRegister(RF_SETUP,&temp,1);
// nrf24_readRegister(RF_SETUP,&temp,1);
// SendByteSerially1(temp);
// SendByteSerially1(0x52);
}
void nrf24_init(uint8_t inittype){
nrf24_ce_digitalwrite(LOW);
nrf24_csn_digitalwrite(HIGH);
nrf24_ce_digitalwrite(HIGH);
_delay_us(15);
nrf24_ce_digitalwrite(LOW);
nrf24_powerUpTx();
uint8_t val[5];
uint8_t i;
val[0]=108;
nrf24_configRegister(RF_CH,val,1);
val[0]=0x01;
nrf24_configRegister(EN_AA,val,1);
for(i=0;i<5;i++)
{
val[i]=0xC2;
}
nrf24_configRegister(RX_ADDR_P0,val,5);
for(i=0;i<5;i++)
{
val[i]=0xE7;
}
nrf24_configRegister(TX_ADDR,val,5);
val[0]=0x01;
nrf24_configRegister(RX_PW_P0,val,1);
val[0]=0x00;
nrf24_configRegister(DYNPD,val,1);
val[0]=0x7E;
nrf24_configRegister(STATUS,val,1);
val[0]=0x00;
nrf24_configRegister(FEATURE,val,1);
if(inittype==1) //TX
{
val[0]=0x0E;
}
if(inittype==0) //RX
{
val[0]=0x0F;
}
//nrf24_configRegister(CONFIG,val,1);
}
// check with mirf
void nrf24_send(uint8_t* value){
/* Go to Standby-I first */
nrf24_ce_digitalwrite(LOW);
/* Set to transmitter mode , Power up if needed */
//nrf24_powerUpTx();
nrf24_csn_digitalwrite(LOW);
spi_transfer(FLUSH_TX);
nrf24_csn_digitalwrite(HIGH);
/* Pull down chip select */
nrf24_csn_digitalwrite(LOW);
/* Write cmd to write payload */
spi_transfer(W_TX_PAYLOAD);
/* Write payload */
nrf24_transmitSync(value,2);
/* Pull up chip select */
nrf24_csn_digitalwrite(HIGH);
/* Start the transmission */
nrf24_ce_digitalwrite(HIGH);
}
uint8_t data_array[3];
void main()
{
unsigned char i;
uart_init();
SPI_Init();
nrf24_init(1);
//nrf24_powerUpTx();
setRFPWR();
nrf24_csn_digitalwrite(LOW);
spi_transfer(FLUSH_TX);
nrf24_csn_digitalwrite(HIGH);
while(1)
{
data_array[0] = 0x6F;
data_array[1] = 0x12;
data_array[2] = 0x12;
nrf24_send(data_array);
_delay_ms(5000); // wait some time
SendByteSerially1(data_array[0]);
SendByteSerially1(data_array[1]);
//SendByteSerially1(data_array[2]);
}
}
Receiver :-
#include <xc.h>
#include "stdint.h"
#include <p18f25k22.h>
#include <flash.h>
#include <stdio.h>
#include <string.h>
#include<plib/spi.h>
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
// CONFIG1H
#pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF // 4X PLL Enable (Oscillator used directly)
#pragma config PRICLKEN = OFF // Primary clock enable bit (Primary clock can be disabled by software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (Power up timer disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 190 // Brown Out Reset Voltage bits (VBOR set to 1.90 V nominal)
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC1 // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
#pragma config CCP3MX = PORTB5 // P3A/CCP3 Mux bit (P3A/CCP3 input/output is multiplexed with RB5)
#pragma config HFOFST = OFF // HFINTOSC Fast Start-up (HFINTOSC output and ready status are delayed by the oscillator stable status)
#pragma config T3CMX = PORTC0 // Timer3 Clock input mux bit (T3CKI is on RC0)
#pragma config P2BMX = PORTB5 // ECCP2 B output mux bit (P2B is on RB5)
#pragma config MCLRE = EXTMCLR // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = OFF // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks)
#define FOSC 8000000
#define BAUD 9600
#define _XTAL_FREQ 8000000
/* Memory Map */
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define CD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define DYNPD 0x1C
#define FEATURE 0x1D
/* Bit Mnemonics */
/* configuration register */
#define MASK_RX_DR 6
#define MASK_TX_DS 5
#define MASK_MAX_RT 4
#define EN_CRC 3
#define CRCO 2
#define PWR_UP 1
#define PRIM_RX 0
/* enable auto acknowledgment */
#define ENAA_P5 5
#define ENAA_P4 4
#define ENAA_P3 3
#define ENAA_P2 2
#define ENAA_P1 1
#define ENAA_P0 0
/* enable rx addresses */
#define ERX_P5 5
#define ERX_P4 4
#define ERX_P3 3
#define ERX_P2 2
#define ERX_P1 1
#define ERX_P0 0
/* setup of address width */
#define AW 0 /* 2 bits */
/* setup of auto re-transmission */
#define ARD 4 /* 4 bits */
#define ARC 0 /* 4 bits */
/* RF setup register */
#define PLL_LOCK 4
#define RF_DR_HIGH 3
#define RF_PWR 1 /* 2 bits */
/* general status register */
#define RX_DR 6
#define TX_DS 5
#define MAX_RT 4
#define RX_P_NO 1 /* 3 bits */
#define TX_FULL 0
/* transmit observe register */
#define PLOS_CNT 4 /* 4 bits */
#define ARC_CNT 0 /* 4 bits */
/* fifo status */
#define TX_REUSE 6
#define FIFO_FULL 5
#define TX_EMPTY 4
#define RX_FULL 1
#define RX_EMPTY 0
/* dynamic length */
#define DPL_P0 0
#define DPL_P1 1
#define DPL_P2 2
#define DPL_P3 3
#define DPL_P4 4
#define DPL_P5 5
/* Instruction Mnemonics */
#define R_REGISTER 0x00 /* last 4 bits will indicate reg. address */
#define W_REGISTER 0x20 /* last 4 bits will indicate reg. address */
#define REGISTER_MASK 0x1F
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define ACTIVATE 0x50
#define R_RX_PL_WID 0x60
#define NOP1 0xFF
#define nrf24_CONFIG ((1 << MASK_RX_DR)|(1<<EN_CRC)|(1<<CRCO)|(1<<EN_CRC))
/// hardware spi pin defined
#define CS_Pin PORTAbits.RA5 //set port as output
#define CE_Pin PORTBbits.RB1 //set port as output
#define SCK_Pin PORTCbits.RC3 //set port as output
#define Mosi_Pin PORTCbits.RC5 //set port as output
#define Miso_Pin PORTCbits.RC4 //set port as input
#define HIGH 1
#define LOW 0
#define _delay_us(x) { unsigned char us; \
us = (x)/(12000000/FOSC)|1; \
while(--us != 0) continue; }
void uart_init(){
OSCTUNE = 0x00; //(INTSRC|PLLEN|TUN<5:0>)
OSCCON = 0x67; //(IDLEN|IRCF<2:0>|OSTS|HFIOFS|SCS<1:0>)
TRISB = 0x04; //(TRISB7|TRISB6|TRISB5|TRISB4|TRISB3|TRISB2|TRISB1|TRISB0)
TRISC = 0x90; //(TRISC7|TRISC6|TRISC5|TRISC4|TRISC3|TRISC2|TRISC1|TRISC0)
TRISAbits.RA5=0;
ANSELC = 0x00;
ANSELB = 0x00;
ANSELA = 0x00;
/*UART1 Initialization*/
PORTCbits.RC6 = 1;
PORTCbits.RC7 = 1;
TXSTA1 = 0x24; //(CSRC|TX9|TXEN|SYNC|SENDB|BRGH|TRMT|TX9D)
//SPBRGH1= 0x01;
SPBRG1= 207; //0xA0;
RCSTA1 = 0x96; //(SPEN|RX9|SREN|CREN|ADDEN|FERR|OERR|RX9D)
BAUDCON1 =0x08;//(ABDOVF|RCIDL|DTRXP|CKTXP|BRG16|?|WUE|ABDEN)
}
void _delay_ms(unsigned int ms){
unsigned int i;
do {
i = 6; //4;
do {
_delay_us(210);
} while(--i);
} while(--ms);
}
void SendByteSerially1(unsigned char Byte){ // Writes a character to the serial port
while(!PIR1bits.TX1IF); // wait for previous transmission to finish
TXREG1 = Byte;
_delay_ms(1);
}
void SPI_Init(){
SSP1CON1bits.SSPEN = 0;
SSP1CON1 = 0x01; // SPI Master mode, clock = Fosc/64
SSP1STAT= 0xC0; // CKE = 1
SSP1CON1bits.SSPEN = 1;
}
void nrf24_ce_digitalwrite(uint8_t state)
{
if (state)
{
CE_Pin = 1;
}
else
{
CE_Pin = 0;
}
}
void nrf24_csn_digitalwrite(uint8_t state)
{
if (state)
{
CS_Pin = 1;
}
else
{
CS_Pin = 0;
}
}
/* software spi routine */
uint8_t spi_transfer(uint8_t tx)
{
unsigned char temp;
SSP1BUF = tx; // send data to the BUFFER
while(!SSP1STATbits.BF && !PIR1bits.SSP1IF); // wait for the tramsit/recieve to finish
// has to be SSPSTAT.BF not just BF!! (for some reason)
temp = SSP1BUF;
PIR1bits.SSP1IF = 0;
return temp;
}
/* send and receive multiple bytes over SPI */ // checked with mirf
void nrf24_transferSync(uint8_t *dataout,uint8_t *datain,uint8_t len)
{
uint8_t i;
for(i=0;i<len;i++){
datain[i] = spi_transfer(dataout[i]);
}
}
//send multiple bytes over SPI // checked with mirf
void nrf24_transmitSync(uint8_t *dataout,uint8_t len)
{
uint8_t i;
for(i=0;i<len;i++){
spi_transfer(dataout[i]);
}
}
/* Read single register from nrf24 */
void nrf24_readRegister(uint8_t reg,uint8_t *value,uint8_t len) //checked with mirf
{
nrf24_csn_digitalwrite(LOW);
spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
nrf24_transferSync(value,value,len);
nrf24_csn_digitalwrite(HIGH);
}
void nrf24_configRegister(uint8_t reg, uint8_t *value, int num)
{ int i;
nrf24_csn_digitalwrite(LOW);
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
for(i=0;i<num; i++)
{
spi_transfer(value[i]);
}
nrf24_csn_digitalwrite(HIGH);
// SendByteSerially1(0x51);
}
void nrf24_powerUpTx() // checked with mirf
{
unsigned char val;
val=nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX));
// PTX = 1;
nrf24_configRegister(CONFIG, (unsigned char*)&val,1);
}
void nrf24_powerUpRx() // checked with mirf
{
unsigned char val;
// PTX = 0;
val=nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX));
nrf24_configRegister(CONFIG, (unsigned char*)&val,1);
}
void setRFPWR(){
unsigned char temp;
temp=0x06;
nrf24_configRegister(RF_SETUP,&temp,1);
// nrf24_readRegister(RF_SETUP,&temp,1);
// SendByteSerially1(temp);
// SendByteSerially1(0x52);
}
void nrf24_init(uint8_t inittype)
{
nrf24_ce_digitalwrite(LOW);
nrf24_csn_digitalwrite(HIGH);
_delay_us(10);
nrf24_ce_digitalwrite(HIGH);
nrf24_powerUpRx();
uint8_t val[5];
uint8_t i;
val[0]=108;
nrf24_configRegister(RF_CH,val,1);
val[0]=0x01;
nrf24_configRegister(EN_AA,val,1);
val[0]=0x01;
nrf24_configRegister(EN_RXADDR,val,1);
for(i=0;i<5;i++)
{
val[i]=0xE7;
}
nrf24_configRegister(RX_ADDR_P0,val,5);
for(i=0;i<5;i++)
{
val[i]=0xC2;
}
nrf24_configRegister(TX_ADDR,val,5);
val[0]=0x01;
nrf24_configRegister(RX_PW_P0,val,1);
val[0]=0x00;
nrf24_configRegister(DYNPD,val,1);
val[0]=0x7E;
nrf24_configRegister(STATUS,val,1);
val[0]=0x00;
nrf24_configRegister(FEATURE,val,1);
if(inittype==1) //TX
{
val[0]=0x0E;
}
if(inittype==0) //RX
{
val[0]=0x0F;
}
// nrf24_configRegister(CONFIG,val,1);
}
void nrf24_send(uint8_t* value) // check with mirf
{
/* Go to Standby-I first */
nrf24_ce_digitalwrite(LOW);
/* Set to transmitter mode , Power up if needed */
// nrf24_powerUpTx();
nrf24_csn_digitalwrite(LOW);
spi_transfer(FLUSH_TX);
nrf24_csn_digitalwrite(HIGH);
/* Pull down chip select */
nrf24_csn_digitalwrite(LOW);
/* Write cmd to write payload */
spi_transfer(W_TX_PAYLOAD);
/* Write payload */
nrf24_transmitSync(value,2);
/* Pull up chip select */
nrf24_csn_digitalwrite(HIGH);
/* Start the transmission */
nrf24_ce_digitalwrite(HIGH);
}
uint8_t nrf24_getStatus() // checked with mirf
{
uint8_t rv;
nrf24_readRegister(STATUS,&rv,1);
return rv;
}
uint8_t nrf24_dataReady() // check with mirf
// checks if data is available for reading
{
// See note in getData() function - just checking RX_DR isn't good enough
uint8_t status = nrf24_getStatus();
// We can short circuit on RX_DR, but if it's not set, we still need
// to check the FIFO for any pending packets
return status & (1 << RX_DR);
}
/* Reads payload bytes uint8_to data array */
void nrf24_getData(uint8_t *data1) // check with mirf
{
unsigned char val;
/* Pull down chip select */
nrf24_csn_digitalwrite(LOW);
/* Send cmd to read rx payload */
spi_transfer(R_RX_PAYLOAD);
/* Read payload */
nrf24_transferSync(data1,data1,2);
/* Pull up chip select */
nrf24_csn_digitalwrite(HIGH);
nrf24_csn_digitalwrite(LOW);
spi_transfer(FLUSH_RX);
nrf24_csn_digitalwrite(HIGH);
val=1<<RX_DR;
/* Reset status register */
nrf24_configRegister(STATUS,(unsigned char*)&val,1);
}
void main()
{
unsigned char x;
uint8_t data_array[3];
uart_init();
SPI_Init();
nrf24_init(0);
//nrf24_powerUpRx();
setRFPWR();
nrf24_csn_digitalwrite(LOW);
spi_transfer(FLUSH_RX);
nrf24_csn_digitalwrite(HIGH);
while(1)
{
x=nrf24_dataReady();
SendByteSerially1(x);
while(x);
nrf24_getData(data_array);
if(data_array[0]>0)
SendByteSerially1(data_array[0]);
if(data_array[1]>0)
SendByteSerially1(data_array[1]);
//SendByteSerially1(data_array[2]);
if(data_array[0] == 0x6F)
SendByteSerially1('Y');
//else
// SendByteSerially1('N');
data_array[0]=0x00;
data_array[1]=0x00;
x=0;
nrf24_ce_digitalwrite(LOW);
}
}