asking
Full Member level 5
- Joined
- Sep 21, 2010
- Messages
- 279
- Helped
- 6
- Reputation
- 12
- Reaction score
- 6
- Trophy points
- 1,298
- Activity points
- 3,377
Hi,
I have been trying from last many days regarding the communication between PIC16F628A (my mcu) and NRF24L01+ communication module. But i am unsuccessful.. i am not having any idea whether the data is written into the NRF24L01+ register or not ?
So is there any methods available for SPI Debug ? I have pickit3, MPLAB X IDE 1.90, MPLAB IDE v8.92 and Mikroc Pro v6.0.0 how can i simply check whether the sPI communication is perfect or not ?
Thanks.
Here's My NRF24L01+ Receiver side code :
I have been trying from last many days regarding the communication between PIC16F628A (my mcu) and NRF24L01+ communication module. But i am unsuccessful.. i am not having any idea whether the data is written into the NRF24L01+ register or not ?
So is there any methods available for SPI Debug ? I have pickit3, MPLAB X IDE 1.90, MPLAB IDE v8.92 and Mikroc Pro v6.0.0 how can i simply check whether the sPI communication is perfect or not ?
Thanks.
Here's My NRF24L01+ Receiver side code :
Code:
#include <htc.h>
__CONFIG(FOSC_EXTRCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & BOREN_OFF & LVP_OFF & CPD_OFF & CP_OFF); //16F628A
#include "stdint.h"
/* 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
/* Bit Mnemonics */
/* configuratio nregister */
#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 NOP 0xFF
/// hardware spi pin defined
#define LED_PIN PORTBbits.RA1 // led test
#define CS_Pin PORTBbits.RB0// //set port as output
#define CE_Pin PORTBbits.RB4 //set port as output
#define SCK_Pin PORTBbits.RB1 //set port as output
#define Mosi_Pin PORTBbits.RB2 //set port as output
#define Miso_Pin PORTBbits.RB3 //set port as input
#define HIGH 1
#define LOW 0
//#ifndef NRF24
#define NRF24
//#include "nRF24L01.h"
//#include <stduint8_t.h>
#define LOW 0
#define HIGH 1
#define nrf24_ADDR_LEN 5
#define nrf24_CONFIG ((1<<EN_CRC)|(0<<CRCO))
#define NRF24_TRANSMISSON_OK 0
#define NRF24_MESSAGE_LOST 1
//spi pins defined for PIC16F628A
/*
sbit Chip_Select at RB0_bit; //
sbit SoftSpi_CLK at RB1_bit;
sbit SoftSpi_SDI at RB2_bit;
sbit SoftSpi_SDO at RB3_bit;
sbit CE_Pin_select at RB4_bit;
sbit Chip_Select_Direction at TRISB0_bit; //csn PIN
sbit SoftSpi_CLK_Direction at TRISB1_bit; //SCK
sbit SoftSpi_SDI_Direction at TRISB2_bit; //MISO
sbit SoftSpi_SDO_Direction at TRISB3_bit; //MOSI
*/
// End DAC module connections
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;
}
}
void nrf24_sck_digitalwrite(uint8_t state)
{
if (state)
{
SCK_Pin = 1;
}
else
{
SCK_Pin = 0;
}
}
void nrf24_mosi_digitalwrite( uint8_t state)
{
if (state)
{
Mosi_Pin = 1;
}
else
{
Mosi_Pin = 0;
}
}
uint8_t nrf24_miso_digitalread(uint8_t state)
{
return (state);
}
/* software spi routine */
uint8_t spi_transfer(uint8_t tx)
{
uint8_t i = 0;
uint8_t rs = 0;
nrf24_sck_digitalWrite(LOW);
for(i=0;i<8;i++)
{
if(tx & (1<<(7-i)))
{
nrf24_mosi_digitalWrite(HIGH);
}
else
{
nrf24_mosi_digitalWrite(LOW);
}
nrf24_sck_digitalWrite(HIGH);
rs = rs << 1;
if(nrf24_miso_digitalRead())
{
rs |= 0x01;
}
nrf24_sck_digitalWrite(LOW);
}
return rs;
}
/* send and receive multiple bytes over SPI */
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
void nrf24_transmitSync(uint8_t* dataout,uint8_t len)
{
uint8_t i;
for(i=0;i<len;i++)
{
spi_transfer(dataout[i]);
}
}
//Clocks only one byte uint8_to the given nrf24 register */
void nrf24_configRegister(uint8_t reg, uint8_t value)
{
nrf24_csn_digitalWrite(LOW);
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
spi_transfer(value);
nrf24_csn_digitalWrite(HIGH);
}
/* Read single register from nrf24 */
void nrf24_readRegister(uint8_t reg,uint8_t* value,uint8_t len)
{
nrf24_csn_digitalWrite(LOW);
spi_transfer(R_REGISTER | (REGISTER_MASK & reg));
nrf24_transferSync(value,value,len);
nrf24_csn_digitalWrite(HIGH);
}
/* Write to a single register of nrf24 */
void nrf24_writeRegister(uint8_t reg,uint8_t* value,uint8_t len)
{
nrf24_csn_digitalWrite(LOW);
spi_transfer(W_REGISTER | (REGISTER_MASK & reg));
nrf24_transmitSync(value,len);
nrf24_csn_digitalWrite(HIGH);
}
uint8_t payload_len;
// init the hardware pins
void nrf24_init()
{
//nrf24_setupPins();
nrf24_ce_digitalWrite(LOW);
nrf24_csn_digitalWrite(HIGH);
}
void nrf24_powerUpRx()
{
nrf24_csn_digitalWrite(LOW);
spi_transfer(FLUSH_RX);
nrf24_csn_digitalWrite(HIGH);
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(1<<PRIM_RX)));
}
void nrf24_config(uint8_t channel,uint8_t pay_length)
{
/* Use static payload length ... */
payload_len = pay_length;
// Set RF channel
nrf24_configRegister(RF_CH,channel);
// Set length of incoming payload
nrf24_configRegister(RX_PW_P0, payload_len); // Auto-ACK pipe ...
nrf24_configRegister(RX_PW_P1, 0x00); // Data payload pipe
nrf24_configRegister(RX_PW_P2, 0x00); // Pipe not used
nrf24_configRegister(RX_PW_P3, 0x00); // Pipe not used
nrf24_configRegister(RX_PW_P4, 0x00); // Pipe not used
nrf24_configRegister(RX_PW_P5, 0x00); // Pipe not used
// 1 Mbps, TX gain: 0dbm
nrf24_configRegister(RF_SETUP, (0<<RF_DR_HIGH)|((0x03)<<RF_PWR));
// CRC enable, 1 byte CRC length
nrf24_configRegister(CONFIG,nrf24_CONFIG);
// Auto Acknowledgment
nrf24_configRegister(EN_AA,(1<<ENAA_P0)|(1<<ENAA_P1)|(0<<ENAA_P2)|(0<<ENAA_P3)|(0<<ENAA_P4)|(0<<ENAA_P5));
// Enable RX addresses
nrf24_configRegister(EN_RXADDR,(1<<ERX_P0)|(1<<ERX_P1)|(0<<ERX_P2)|(0<<ERX_P3)|(0<<ERX_P4)|(0<<ERX_P5));
// Auto retransmit delay: 1000 us and Up to 15 retransmit trials
nrf24_configRegister(SETUP_RETR,(0x04<<ARD)|(0x0F<<ARC));
// Dynamic length configurations: No dynamic length
nrf24_configRegister(DYNPD,(0<<DPL_P0)|(0<<DPL_P1)|(0<<DPL_P2)|(0<<DPL_P3)|(0<<DPL_P4)|(0<<DPL_P5));
// Start listening
nrf24_powerUpRx();
}
void nrf24_powerUpTx()
{
nrf24_configRegister(STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT));
nrf24_configRegister(CONFIG,nrf24_CONFIG|((1<<PWR_UP)|(0<<PRIM_RX)));
}
void nrf24_powerDown()
{
nrf24_ce_digitalWrite(LOW);
nrf24_configRegister(CONFIG,nrf24_CONFIG);
}
/* Set the RX address */
void nrf24_rx_address(uint8_t* adr)
{
nrf24_ce_digitalWrite(LOW);
nrf24_writeRegister(RX_ADDR_P1,adr,nrf24_ADDR_LEN);
nrf24_ce_digitalWrite(HIGH);
}
/* Set the RX address
void nrf24_rx_address(unsigned * adr)
{
nrf24_ce_digitalWrite(LOW);
nrf24_writeRegister(RX_ADDR_P1,adr,nrf24_ADDR_LEN);
nrf24_ce_digitalWrite(HIGH);
}
*/
/* Returns the payload length */
uint8_t nrf24_payload_length()
{
return payload_len;
}
/* Set the TX address */
void nrf24_tx_address(uint8_t* adr)
{
/* RX_ADDR_P0 must be set to the sending addr for auto ack to work. */
nrf24_writeRegister(RX_ADDR_P0,adr,nrf24_ADDR_LEN);
nrf24_writeRegister(TX_ADDR,adr,nrf24_ADDR_LEN);
}
/* Checks if receive FIFO is empty or not */
uint8_t nrf24_rxFifoEmpty()
{
uint8_t fifoStatus;
nrf24_readRegister(FIFO_STATUS,&fifoStatus,1);
return (fifoStatus & (1 << RX_EMPTY));
}
/* Checks if data is available for reading */
/* Returns 1 if data is ready ... */
uint8_t nrf24_dataReady()
{
// See note in getData() function - just checking RX_DR isn't good enough
// unsigned status = nrf24_getStatus();
uint8_t status;
// We can circuit on RX_DR, but if it's not set, we still need
// to check the FIFO for any pending packets
if ( status & (1 << RX_DR) )
{
return 1;
}
else
return !nrf24_rxFifoEmpty();;
}
/* Returns the length of data waiting in the RX fifo */
uint8_t nrf24_payloadLength()
{
uint8_t status;
nrf24_csn_digitalWrite(LOW);
spi_transfer(R_RX_PL_WID);
status = spi_transfer(0x00);
nrf24_csn_digitalWrite(HIGH);
return status;
}
/* Reads payload bytes uint8_to data array */
void nrf24_getData(uint8_t* data1)
{
/* 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,payload_len);
/* Pull up chip select */
nrf24_csn_digitalWrite(HIGH);
/* Reset status register */
nrf24_configRegister(STATUS,(1<<RX_DR));
}
/* Returns the number of retransmissions occured for the last message */
uint8_t nrf24_retransmissionCount()
{
uint8_t rv;
nrf24_readRegister(OBSERVE_TX,&rv,1);
rv = rv & 0x0F;
return rv;
}
// Sends a data package to the default address. Be sure to send the correct
// amount of bytes as configured as payload on the receiver.
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();
/* Do we really need to flush TX fifo each time ? */
// #if 1
/* Pull down chip select */
nrf24_csn_digitalWrite(LOW);
/* Write cmd to flush transmit FIFO */
spi_transfer(FLUSH_TX);
/* Pull up chip select */
nrf24_csn_digitalWrite(HIGH);
// #endif
/* Pull down chip select */
nrf24_csn_digitalWrite(LOW);
/* Write cmd to write payload */
spi_transfer(W_TX_PAYLOAD);
/* Write payload */
nrf24_transmitSync(value,payload_len);
/* Pull up chip select */
nrf24_csn_digitalWrite(HIGH);
/* Start the transmission */
nrf24_ce_digitalWrite(HIGH);
}
uint8_t nrf24_getStatus()
{
uint8_t rv;
nrf24_csn_digitalWrite(LOW);
// rv = spi_transfer(NOP);
nrf24_csn_digitalWrite(HIGH);
return rv;
}
uint8_t nrf24_lastMessageStatus()
{
uint8_t rv;
rv = nrf24_getStatus();
/* Transmission went OK */
if((rv & ((1 << TX_DS))))
{
return NRF24_TRANSMISSON_OK;
}
/* Maximum retransmission count is reached */
/* Last message probably went missing ... */
else if((rv & ((1 << MAX_RT))))
{
return NRF24_MESSAGE_LOST;
}
/* Probably still sending ... */
else
{
return 0xFF;
}
}
uint8_t nrf24_isSending()
{
uint8_t status;
/* read the current status */
status = nrf24_getStatus();
/* if sending successful (TX_DS) or max retries exceded (MAX_RT). */
if((status & ((1 << TX_DS) | (1 << MAX_RT))))
{
return 0; /* false */
}
return 1; /* true */
}
void nrf24_SETUP_PINS()
{
CMCON |= 7;
TRISB = 0b00001000;
TRISA = 0b00000000;
//nothing required here as we have already defined the pins and set their direcitons.(input/output)
}
//before main initilization
uint8_t temp;
uint8_t q = 0;
uint8_t msg[4];
uint8_t tx_address[5] = {0xE8,0xE8,0xF0,0xF0,0xE1};
uint8_t rx_address[5] = {0xE8,0xE8,0xF0,0xF0,0xE1};
uint8_t temp1,temp2;
void main() {
//LED_PIN = HIGH;
//CMCON = 0X07;
CMCON |= 7;
TRISB = 0b00001000;
TRISA = 0b00000000;
// temp2 = 1;
// temp2 = Soft_SPI_Write(PRIM_RX);
/* init hardware pins */
nrf24_init();
nrf24_powerUpRx();
/* Channel #2 , payload length: 4 */
nrf24_config(2,4);
/* Set the device addresses */
nrf24_tx_address(tx_address);
nrf24_rx_address(rx_address);
while(1)
{
if(nrf24_dataReady())
{
// LED_PIN = HIGH;
nrf24_getData(msg);
if (msg[0] == 1);
{
// LED_PIN = HIGH;
}
}
}
}