nRF24L01 communication problem

Hello,

I started using this forum and it’s really helping me!

But I still have a problem.

I am using the C8051F320 microcontroller to configure the nRF24L01 module via SPI.

I send the configuration commands to the RF module and the data. I can see them on the MOSI pin and also the answer on the MISO pin but the RF module is not sending these data via RF! (I check if the VDD_PA pin on the RF module is going high).

Here is my code for TX mode:

void TX_Mode(void)
{
  CE = 0;
  SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADDR_WIDTH);    // Writes TX_Address to nRF24L01
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADDR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
  SPI_Write_reg(WRITE_REG + EN_AA, 0x00);            // Disable Auto.Ack:Pipe0
  SPI_Write_reg(WRITE_REG + EN_RXADDR, 0x01);        // Enable Pipe0
  SPI_Write_reg(WRITE_REG + SETUP_RETR, 0x00);       // Setup retry off
  SPI_Write_reg(WRITE_REG + RF_CH, 2);              // Select RF channel 2
  SPI_Write_reg(WRITE_REG + RF_SETUP, 0x0F);         // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  SPI_Write_reg(WRITE_REG + CONFIG, 0x38);           // PTX enabled, enable CRC(1 byte), interrupt RXDR enabled, power down mode
}


//--------------------------------------------------------------------
// Main Routine
//--------------------------------------------------------------------

void main(void)
{ 
  MCU_Init();
  Port_Init();
  ADC_Init();   
  Init_T0();
  Init_T2();
  Start_T2();  
  SPI_Init();
  Int_Init();
  TX_Mode();

  while (TRUE)
  {
  }
} 


/**********************************************************************
 * General interrupts definitions
 **********************************************************************///*****************************************


// Timer0 Overflow interrupt
//
// Used for CE pulse signal
// Timeout:12µs
//*****************************************
void T0_Overflow(void) interrupt T0_INTERRUPT
{
  EA = 0;                 // disable global interrupt during processing	
  CE = 0;				  // Clear CE pulse after 20 us
  TR0 = 0;
  EA = 1;				  // enable global interrupt again
  Led3 = ~Led3;
} 

//*****************************************
// Timer2 Overflow interrupt
//
// Used to read ADC value every 30 ms
//*****************************************
void T2_Overflow(void) interrupt T2_INTERRUPT
{
//  EA = 0;               
  TF2H = 0;				  // Clear interrupt flag
  Led2 = ~Led2;
//  EA = 1;				  // enable global interrupt again
} 

//******************************************
// ADC end of conversion interrupt
//
// When ADC finish conversion than ADC 
// interrupt flag is cleared
//*****************************************
void ADC_EndConversion(void)interrupt INTERRUPT_ADC0_EOC          
{
  EA = 0;
  Led1 = ~Led1;
  TX_PAYLOAD[0] = ADC0L;			            // Write first byte (ADC low) into the SPI buffer
  TX_PAYLOAD[1] = ADC0H;			            // Write second byte (ADC high) into the SPI buffer
  SPI_Write_reg(WRITE_REG + STATUS, 0x7E);		// Write register status, clear previous interrupts
  SPI_Write_reg(WRITE_REG + CONFIG, 0x3A);      // Power up TX mode
  Flush_TX();									// Flush TX FIFO
  SPI_Write_Buf(WR_TX_PLOAD, TX_PAYLOAD, 0x02); // Writes data to TX payload and send them to SPI MOSI	                        
  EA = 1;
  CE = 1;
  Start_T0();
  ADC0CN = 0x82;								// Clear ADC Interrupt flag and enable ADC again
}

Can anyone help me?

Is there any time issue or configuration issue?

Thanks!

Take a look at the code I have posted links to on this forum (just do a search for nrf24l01.c and it should show up). Since my code works, check out the timing to make sure that yours matches. You should also make sure that you have the TX_DS interrupt set in the CONFIG register of the 24L01. This will allow you to see if your transmitting 24L01 sent anything because it will activate the IRQ pin (bringing it low) after it sends a packet. If you try to send data and this interrupt does not occur, then you have some issue in either your configuration bits or possibly not having the CE pin connected properly or set up correctly in your microcontroller.

Thank you Brennen,

I already tried to use your code but I am having problems in adapting it for my uC.

I checked if TX_DS is set and I corrected it. I still don’t see any changes on the IRQ pin (always high).

CE pin is connected properly between uC and RF and I can see the 130us pulse after I send the data on the MOSI pin.

I know that RF module is still working because if I use the original firmware from nordic I can see the VDD_PA pin high when data are sent.

Does anyone have already tried to adapt Brennen code for the C8051F320 microcontroller?

OK, I’m still not clear on your TX_DS interrupt. I am talking here about the transmitting unit. You can do this a couple of ways. Assuming you are using the IRQ pin, then make sure that MASK_TS_DS bit (bit 5) in the CONFIG register is set (value of 1). I haven’t looked too closely at your setup code, but make sure that your PWR_UP bit is set, also. You must finally make sure that the payload width register for the pipe you are receiving data on in the receiver is set to some valid value (other than 0). In your receiver, you must make sure the MASK_RX_DR bit (6) is set. This is the baseline configuration, and should get you started.

At this point, you can try to transmit a packet. After some small amount of time, the TX_DS interrupt will go active on the 24L01 once the packet has been sent. This will cause the IRQ pin to go low and the TX_DS bit in the STATUS register to go high. At this point, you will know the packet has been sent.

When you have verified you can send a packet, you can check the receiver. When a packet has been received, the RX_DR interrupt will go active and will cause the IRQ pin to go low. The RX_DR bit in the STATUS register will go high, and then you can read out the payload.

If you would like to send me your setup parameters (preferrably over PM), then I will try to take a look at stuff to make it work with your setup. I have discovered an issue with my code that prevents it working properly with microcontrollers that don’t have FIFOs. If your micro doesn’t have one, you should be able to do most everything except receive multi-byte data (data payloads and address registers).

You are supposed to wait 1.5mS after power up before you set CE.

Wow, I can’t believe I missed that when I was looking through the code. :?

Ok, I will try this and tell you if it works!

Thanks!