Lab 7


In this lab, you are going to be working with the Nordic nRF24L01+ wireless transceiver. This device can be used to provide a low power wireless solution in systems that do not have high bandwidth requirements.

Similar to the FAT file system, we are going to be leveraging a library to provide much of the functionality for the wireless chip. To use this library, we need to provide physical connections to the nRF24L01+, SPI initialization, and a delay function (ds_delay_uS from Lab6). As an introduction to the nRF24L01+, you should read the following overview by the creator of the library. Other resource materials related to the nRF24L01+ are posted at . Additionally, you should skim the nRF24L01+ datasheet .

Physical Connections

You will receive a transceiver carrier board in lab. Sparkfun provides a solution that includes the transceiver, oscillator, antenna, and supporting discrete components for ~$20. This board brings the necessary external connections to the edge of the board. There are 8 connections that need to be made.

We will be using SPI3 for this device.

nRF24L01+ STM

SPI3 Initialization and associated pin setup.

You will need to create driver files ds_nordic.c/h. This driver will contain an initialization function along with a low level spi send/receive function.

void ds_nordic_init(void)

You will need to initialize SPI3 with similar parameters that were used for SPI2 in lab6. Do not forget to also initialize CSN and CE as outputs and IRQ as an input.

uint8_t ds_nordic_send_spi_byte(uint8_t data)

This function is used to send and receive bytes from the nordic chip. The nRF24L01+ has been tailored to expect the name of this function to be ds_nordic_send_spi_byte.

uint8_t ds_nordic_send_spi_byte(uint8_t data) {
  while(SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_RXNE) == RESET);
  return SPI_ReceiveData8(SPI3);      

Delay Function

Make sure to initialize your ds_delay_uS() function from Lab 6.

Transmitting and Receiving

Once the system is initialized, you will be ready to send and receive from system. The library functions contained in nrf24l01.c/h will be used to provide this functionality. The comments on this code are helpful. However, you may also want to pull the LPC2148 examples from . The code is helpful as a reference but is not directly applicable. However, the tutorial documents are very helpful - especially Tutorials 0, 1, and 2.

For the purposes of this lab, you are going to be sending 32 byte packets to a single base station provided in the room. This base station will receive the packet, upcase any characters between ‘a'-‘z', and then return the packet to you. It should be noted that everyone in the class will be transmitting on the same channel and transceiver pipe so you may get contention or a message sent from another team. In a final system, separate channels would be used along with potentially separate pipes (See MultiCeiver in the datasheet).

Library Initialization: nrf24l01_initialize_debug(bool rx, unsigned char p0_payload_width, bool enable_auto_ack)

This function provides a default minimum configuration for the tranceiver. This will be called after the low level initialization functions that you created earlier.

nrf24l01_initialize_debug(false, 32, true);

Clear queues and interrupts: nrf24l01_clear_flush()

Purge any lingering data in the transceiver queues along with any pending interrupts.

Create payload data:

This can be any 32 byte data. The base station will make the lower case characters into upper case when they are sent back.

Send the data:

Transmit the data and poll to confirm that the transmission is complete.

nrf24l01_write_tx_payload(txdata, 32, true);      
while(!(nrf24l01_irq_pin_active() && (nrf24l01_irq_tx_ds_active() || nrf24l01_irq_max_rt_active()))); 

Confirm that the packet was acknowledged:

If the packet is not acknowledged, the transceiver will time out. In the case of this lab, we will print out a message. In a more realistic system, this case would need to be handled as losing packets is a relatively common occurrence with wireless networks.

if (!nrf24l01_irq_max_rt_active()) {
else {
  nrf24l01_flush_tx(); //get the unsent character out of the TX FIFO
  nrf24l01_irq_clear_all(); //clear all interrupts
  printf("Node: Failed to send %c\n",data);

Listen for the response from the base station

An STM32 board has been provided in the lab. It will reflect packets that are received back with the characters changed to be upper case. In the previous, step notice that the transceiver was put into receive mode once the packet had been acknowledged. This might be curious given that the acknowledgement required the transceiver to be in receive mode. The reason is that the protocol engine that does the handshaking takes control of the transmitter and receiver and does not require any additional programmatic steps.

This being said, once we have received the acknowledgement from the base station, the transmitter will be put in receive mode to capture the modified packet.

while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active()));
nrf24l01_read_rx_payload(rxdata, 32);

Transition back to transmit mode:

When transitioning to transmit mode right after a reception, a minimum of 130uS is required by the receiver. You can use the delay function prior to setting the transceiver back to transmit.


If all went well, you will have setup a wireless connection to the base station. Because of the contention issue, please do not send packets any more often than one per second.


What to Turn in:

This assignment is due by midnight on 3/7. At midnight, your AI will pull the current state of your repository to review your code. In the following lab session, you will be asked to demonstrate your solution. Independently, you will also write a lab report describing in approximately 300 words or less the following:

You will turn in this lab report in the oncourse assignments section.