NRF24L01+ Driver : Part 2 : Commands

The NRF24L01+  and its few registers can be controlled by even fewer commands. There are only 11 commands you will need. Of those 11 commands you may never had the need for some of them, while others you will use and abuse.  It is important to remember the nature of the SPI protocol, that with every byte you send a byte is sent back. That first byte you get back is not the reply to the command request, but just a dummy byte that needs to be sent. Please get a refresher of SPI protocol as this is not an SI tutorial. 

On that note. The first byte the NRF send back after a command is sent is the continents of the STATUS register. But you should not just send any command because you simply want to read the status register, some commands will make the NRF wait for more data. You can use a NOP (NO operation) command if all you wish to do is read the status register. Ok now on to the list of command names and their opcodes.

The R_REGISTER command is used to Read a register and its opcode is 000xxxxx where the x's represent the address of the register you wish to read. For example if you want to read the contents of the RF_SETUP register which is address 0x06 ( 00000110 ) you would simply join the R_REGISTER command with the RF_SETUP address , which if you look at it ends up being just the RF_SETUP command anywyas.. then you send that through SPI and transmit. Then youll get a dummy byte, you can ignore it, to get your actual reply you need to send a dummy byte also because thats how SPI works and you will get the contents of the RF_SETUP register . 

Another way of stating it is that you should do a LOGICL OR operation of R_REGISTER with the address of the register you wish to read. However since the R_REGISTER command is basically 3 leading zeros...and the reaming bits will contain the address, it doesnt even change the address in any manner, so technically speaking to read a register you just send the address and it will reply with its content. the next command is not all zeros so it will indeed need to be ORed. 

Your code would look something like 

//pseudo code
#define R_REGISTER  0x00
#define RF_SETUP    0x06
spi_send ( R_REGISTER | RF_SETUP) ;
//the returned byte will be first a dummy byte and then the contents

This is the Write command and you use it to write to a register. Unlike the previous command this is not just leading zeros. The x's represent the address of the register you want to write to. After sending this command the NRF expects the data that is to be written to . The SPI send would look exactly like the previous one except you OR it with W_REGISTER.

#define W_REGISTER  0x20  // 00100000
#define RF_SETUP    0x06
spi_send ( W_REGISTER | RF_SETUP) ;
.. ...

The R_RX_PAYLOAD is the command you send when you know you have received data, you will know this because the RX_DR interrupt will have been triggered.  Before you read the payload it makes sense to read STATUS register and check the  RX_P_NO bits to figure out which Pipe this data was received on. Or if you're only using one pipe it does not matter. After sending the R_RX_PAYLOAD command the NRF needs to transmit that data to you via SPI and in order to do that you have to send it some dummy bytes, it does not matter what the bytes are it can be 0xF1 or 0xFF... makes no difference, what does make a difference is that you need to send it the number of bytes equal to the data-width that was set in the RX_PW_P# register or alternatively there is a command to check the width of the top most payload. more on that further down. Width can be from 1 to 32 bytes. If this doesnt make sense its ok it shouldnt because I have not gone over the process of data reception and transmission but it will make sense, for now im describing registers and bits that still make no sense to you. 

This is the command to write your payload. You must make sure that before you start the RF transmission  the CE pin must be LOW. Once you send this command the NRF expects your payload data to come next. Your data width can be from 1 to 32 bytes longs.  After the last byte is sent and you stop the SPI communication you have to bring the CE pin HIGH, because a LOW to HIGH transition is what tells the NRF to transmit what is in the TX FIFO. and this command is what writes in the TX FIFO.

These two commands clear the FIFOs, really not much else to be said here aside from the fact that the datasheet says you should not clear the RX FIFO during a transmission of ACK.  Just wait till all transmissions are done before clearing the RX FIFO.

This command allows you to resend the last transmission. You do not need to send W_TX_PAYLOAD.
Simply send this command and it will resend the last packet so long as you have not flushed the FIFO with the commands above this one.

This command activates three features at once, not necessarily enables them, but allows them to be used if desired. So its very important. The features it activates are:
  1. R_RX_PL_WID read RX payload width when using dynamic payload
  2. W_ACK_PAYLOAD allows a payload to be sent with an ack
  3. W_TX_PAYLOAD_NOACK disables ack on this specific packet
these three features are described below also. But those commands are useless unless they are activated by this command. 
The command works by first sending the ACTIVATE command, then sending the ACTIVATE_BYTE 
so basically sending 2 SPI send actions, first the ACTIVATE then the ACTIVATE byte.

This command  reads the data width of the top payload in the RX FIFO

This command is used to write the payload that will go along with an ACK, when ACK Payloads are enabled in the feature register. After this command the NRF expects the payload data which can be from 1 to 32 bytes.

This W_TX_PAYLOAD_NO_ACK command is used to disable auto ACK for the current packet. So you enabled this bit right before sending the W_TX_PAYLOAD command.

This is a No Operation command, when you send it the NRF does nothing with it. But since you are sending a byte the SPI has to send one back so the NRF send you the contents of its STATUS register. 

And that is all for the commands. I know you probably still do not understand when or how or in what order you will use these commands and registers. That is the topic of my next post.



Share your comments with me


Contact Form