2
\$\begingroup\$

I am trying to write simple code for transmitting with the NRF24L01 wireless chip, but the SPI communication is not going very well.

Using the code below I can read any register on the NRF24L01, verified using the registers' default values from the datasheet (a good reference point is that register CONFIG 0x00 reads 8 while register 0x10 reads first byte of E7).

The problem is that when I try to write any value whatsoever to any register it always ends up having a value of zero, verified using GDB server to the L432KC board.

The board is running on max. 80 mHz and the baud rate of the SPI is the lowest for now for debugging purposes (312.5 kbits/s)

The questions are:

  • Why would a write end up as zeros in the registers?
  • Why do I end up getting 3 bytes back for every byte I send? I know that the SPI only gets one byte for every one transmitted, but I get 3 from the module which eventually creates an OVR error. I solved the problem by reading the first two dummy bytes and saving the last one which carries the meaningful data in the while loop of the SPITransfer function below.

SPI function:

uint8_t SPITransfer(uint8_t data) {
  uint8_t temp;

  while (!(SPI1->SR & (1 << 1))); // check the TXE flag
  SPI1->DR = data;                    // write the data
  while ((SPI1->SR & (1 << 7)) || !(SPI1->SR & (1 << 0))); // check bsy and RXNE flag
  while (SPI1->SR & (1 << 0))   // Read ACK bytes and returned data
    temp = SPI1->DR;

  return temp;
}

NRF24Read and Write:

uint8_t NRF24ReadReg(uint8_t reg) {
  uint8_t rx, dummy;

  CS_Select();

  SPITransfer(reg);
  rx = SPITransfer(dummy);

  CS_UnSelect();

  return rx;
}

void NRF24WriteReg(uint8_t reg, uint8_t data) {
  uint8_t buf[2];

  buf[0] = reg | (1 << 5);
  buf[1] = data;

  CS_Select();

  SPITransfer(buf[0]);
  SPITransfer(buf[1]);

  CS_UnSelect();
}

GDB Debug:

(gdb) call NRF24ReadReg(0x10)
$26 = 231 '\347'
(gdb) call NRF24WriteReg(0x10, 4)
(gdb) call NRF24ReadReg(0x10)
$27 = 0 '\000'
(gdb) 
\$\endgroup\$
2
  • \$\begingroup\$ Get out your logic analyzer and probe the lines \$\endgroup\$
    – Voltage Spike
    Commented Sep 2, 2022 at 23:23
  • \$\begingroup\$ I don't have one lying around for now, I was just hoping that I may have missed something obvious, any suggestions would be appreciated apart from that I will try to use one the next day \$\endgroup\$ Commented Sep 2, 2022 at 23:28

1 Answer 1

1
\$\begingroup\$

The following Posts in ST forum here and here recommend to perform the data write and access to SPI_DR register in the following Way:

*(volatile uint8_t *)&SPI1->DR = data;

rx = *(volatile uint8_t*) &SPI1->DR;

The problem is that the Compiler generates the wrong instruction for the FIFO which is 32 bits wide resulting in 3 consecutive transfers in case of transmission and up to 4 in case of reception mentioned in the board reference manual section 40.4.9 the following:

enter image description here

Finally the below code is working on both read and write:


uint8_t SPITransfer(uint8_t data){
  uint8_t rx, dummyByte;

  //wait for the TXE flag
  while( !(SPI1->SR & (1 << 1)) );

  //force 8-bit data write
  *(volatile uint8_t *)&SPI1->DR = data;

  //wait for the RXNE flag
  while( !(SPI1->SR & (1 << 0)) );

  //force 8-bit data access
  rx = *(volatile uint8_t*) &SPI1->DR;

  return rx;
}

void NRF24WriteReg(uint8_t reg, uint8_t data){
  uint8_t cmd;

  cmd = reg | (1 << 5);

  CS_Select();

  SPITransfer(cmd);
  SPITransfer(data);

  //wait for the BSY flag
  while( (SPI1->SR & (1 << 7)) );

  CS_UnSelect();
}


uint8_t NRF24ReadReg(uint8_t reg){
  uint8_t rx;
  uint8_t dummy = 0;

  CS_Select();

  rx = SPITransfer(reg);
  rx = SPITransfer(dummy);

  //wait for the BSY flag
  while( (SPI1->SR & (1 << 7)) );

  CS_UnSelect();

  return rx;
}


(gdb) call NRF24ReadReg(0x0f)
$10 = 198 '\306'
(gdb) call NRF24ReadReg(0x0e)
$11 = 197 '\305'
(gdb) call NRF24WriteReg(0x0f, 4)
(gdb) call NRF24ReadReg(0x0f)
$12 = 4 '\004'
(gdb) 

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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