3
\$\begingroup\$

I'm trying to communicate with a NRF24L01 transceiver module with a PIC24HJ128GP202. Besides all the code, here is the important part:

void NRF_Config()
{
  NRF_WriteRegister(0x02, 0x01); //PIPE 0 ENABLE
  NRF_ActivateSR();
  NRF_WriteRegister(0x1D, 0x06); //FEATURE REG - Enable Dynamic Payload && Enable ACK Payload
  NRF_WriteRegister(0x1C, 0x01); //ENABLE DYNAMIC PAYLOAD PIPE0
  NRF_WriteRegister(0x00, 0x5A); //CONFIG REG
  Delay(Delay_2ms);
  NRF_EN(); //CHIP ENABLED PIN = TRUE
}

with the WriteRegister function being:

unsigned char NRF_WriteRegister(unsigned char reg, unsigned char data)
{
   SPI1_BEGIN(); //CHIP SELECT = LOW  (START COMMUNICATION)

   IFS0bits.SPI1IF = 0;
   while (SPI1STATbits.SPITBF);
   WriteSPI1(0x20 | reg);
   while (!IFS0bits.SPI1IF);

   IFS0bits.SPI1IF = 0;
   while (SPI1STATbits.SPITBF);
   WriteSPI1(data);
   while (!IFS0bits.SPI1IF);

   SPI1_END(); //CHIP SELECT = HIGH (END COMMUNICATION)
   return ReadSPI1();
}

This works fine (at least it seems to work). Code runs ok and O'scope shows CS pin going low, then 2 groups of 8 pulses in the SCK pin followed by CS going high.

Then I have this:

unsigned char NRF_PutTXPayload(unsigned char *data, char len)
{

   if (len > TX_DATA_SIZE)
       return 0;
   SPI1_BEGIN();

   //SEND BYTE 1
   IFS0bits.SPI1IF = 0;
   while (SPI1STATbits.SPITBF);
   WriteSPI1(0xA0);
   while (!IFS0bits.SPI1IF);

   //SEND BYTE 2
   IFS0bits.SPI1IF = 0;
   while (SPI1STATbits.SPITBF);
   WriteSPI1(0xEF);
   while (!IFS0bits.SPI1IF);

   //SEND BYTE 3
   IFS0bits.SPI1IF = 0;
   while (SPI1STATbits.SPITBF);
   WriteSPI1(0xEF);
   while (!IFS0bits.SPI1IF);

  SPI1_END();
  return ReadSPI1();

}

As you can see this function above is a modified version of the original one I wanted to use. I'm currently not using those arguments and I used to have a For loop to send variable length group of bytes. Then I came into to this version above because it was freezing my PIC somewhere inside the For loop. Then I realize that if I keep only the first two blocks (SEND BYTE 1 and SEND BYTE 2) it's ok. When I add the third one, it freezes the PIC.

I know that I could reduce my code when taking care of flag bits but I copied exaclty the same lines from the WriteRegister function on purpose to make sure it should work. Also, it should work because first I reset interrupt flag; then I wait for TX empty buffer to start copying; then I simply write to TX buf; and then I wait to interrupt flag which means transmission has finished. Altough not being the best/fastest way to do that, I think it should work well, but it does not.

It's strange because it works with 2 bytes but not with three. The O'scope shows CS pin going Low, then it shows the three groups of 8 clocks in SCK pin but the CS pin never goes back high (and the PIC is freezed).

Any idea what might be happening?

\$\endgroup\$
1
  • \$\begingroup\$ Have you tried checking SPI1STATbits.SPIROV flag? I've recently read somewhere that it's "SPI overflow" flag that is set when the SPI hardware detects that the data is being pushed/pulled too fast/slow and the buffer gets overrun, and I think they said that while it's raised the SPI interface halts communication (so probably halts CS/CLK and therefore SPI1IF would be blocked). Just a guess though. I don't know why you'd get an overflow here :/ \$\endgroup\$ Mar 26 '14 at 10:41
1
\$\begingroup\$

One of the errata on that chip is:

  1. SPI Module The SPI transmit buffer full (SPITBF) flag does not get set immediately after writing to the buffer.

So perhaps try a delay (maybe 10 NOPs or something like that) before testing the SPITBF flag. There does not appear to be an official work-around.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the answer but it does not seem to be it. Note that a wrong timing in SPITBF would only make it try to load TX Buffer again before the last transmission. Sure it could be a problem but in this case I check SPITBF only before writing new data and not right after it. Anyway, I commented the last two lines from the third byte sending (which are the WriteSPI1 and check for Interrupt flag) and then it worked again. So my problem is definitely in the Interrupt flag checking line (SPI1IF). Any other suggestions? \$\endgroup\$ Feb 22 '14 at 6:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.