NRF52832

RF Ring oscillator with nrf52.

This RF ring oscillator runs on the NRF52 BLE SOC using the Adafruit feather development board. The NRF52 has an ARM Cortex M4F running at 64 MHz with built in BLE radio. In the oscilloscope trace above, yellow and blue traces each represent a module. A pin is pulled high when the radio is transmitting and pulled low when the radio is receiving. By measuring the period, we can determine the time for a packet round trip (two transmits, two recieves). An arduino sketch for the oscillator is available here, or visible below.


#define toggle_mask 1<<7 //this is for the scope

static uint8_t packet = 12; //declare a buffer for our packet to use with easydma

void wait_for_end(){
  while(!(NRF_RADIO->EVENTS_END)){}
  NRF_RADIO->EVENTS_END = 0; //clear end event  
}
void wait_for_ready(){
  while(!(NRF_RADIO->EVENTS_READY)){} 
  NRF_RADIO->EVENTS_READY = 0; //clear ready event
}
void disable_radio(){
  NRF_RADIO->EVENTS_DISABLED = 0; //clear disabled event
  NRF_RADIO->TASKS_DISABLE = 1;
  while(!(NRF_RADIO->EVENTS_DISABLED)){} 
}

void send_token(){
  NRF_GPIO->OUTSET = toggle_mask; //set toggle pin high  
  NRF_RADIO->EVENTS_READY = 0; //clear ready event
  NRF_RADIO->TASKS_TXEN=1; //trigger tx enable task
  delayMicroseconds(15);
  //wait_for_ready(); //since we're switching, maybe we can get around this?
  NRF_RADIO->TASKS_START=1;  //start
  wait_for_end();
  NRF_GPIO->OUTCLR = toggle_mask; //set toggle pin low

  //put radio in RX mode
  NRF_RADIO->EVENTS_READY = 0; //clear ready event
  NRF_RADIO->TASKS_RXEN=1; //trigger rx enable task
  wait_for_ready();  
  NRF_RADIO->TASKS_START=1;
}

void setup() {
  //helpful bitmasks in nrf52_bitfields.h
  //Serial.begin(115200);  //for debug only
  NRF_GPIO->DIRSET = toggle_mask; //set toggling pin to output

  NRF_RADIO->POWER = RADIO_POWER_POWER_Disabled; //turn off radio to reset registers
  delay(10);
  NRF_RADIO->POWER = RADIO_POWER_POWER_Enabled; //turn on radio
  delay(10);

  // Radio config
  NRF_RADIO->TXPOWER   = (RADIO_TXPOWER_TXPOWER_Pos3dBm << RADIO_TXPOWER_TXPOWER_Pos);
  NRF_RADIO->FREQUENCY = 7UL;  // Frequency bin 7, 2407MHz
  NRF_RADIO->MODE      = (RADIO_MODE_MODE_Nrf_2Mbit << RADIO_MODE_MODE_Pos);

  NRF_RADIO->PREFIX0 = ((uint32_t)0xC0 << 0); // Prefix byte of address 0
  NRF_RADIO->BASE0 = 0x01234567UL;  // Base address for prefix 0
  NRF_RADIO->TXADDRESS   = 0x00UL;  // Set device address 0 to use when transmitting
  NRF_RADIO->RXADDRESSES = 0x01UL;  // Enable device address 0 to use to select which addresses to receive

  // Packet configuration
  NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S1LEN_Pos) | (0 << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos); 
  NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
                     (RADIO_PCNF1_ENDIAN_Big       << RADIO_PCNF1_ENDIAN_Pos)  |
                     (2 << RADIO_PCNF1_BALEN_Pos);

  // CRC Config
  NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Disabled << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
  //NRF_RADIO->CRCINIT = 0xFFFFUL;   // Initial value
  //NRF_RADIO->CRCPOLY = 0x11021UL;  // CRC poly: x^16 + x^12^x^5 + 1

  NRF_RADIO->MODECNF0 |= RADIO_MODECNF0_RU_Fast << RADIO_MODECNF0_RU_Pos; //turn on fast ramp up
  NRF_RADIO->SHORTS = 0; //turn off all shortcuts, for debug
    
  //packet
  NRF_RADIO->PACKETPTR = (uint32_t)&packet; //set pointer to packet buffer

  //start HFCLK
  NRF_CLOCK->TASKS_HFCLKSTART = 1;
  while(!(NRF_CLOCK->HFCLKSTAT & CLOCK_HFCLKSTAT_STATE_Msk)){} //wait for hfclk to start
  delay(10);
  
  send_token(); //send a starting token
  while(1){   
    if ( NRF_RADIO->EVENTS_END ){
      NRF_RADIO->EVENTS_END = 0; //clear end event
      packet += 1; //increment for fun
      send_token();
    }
    //delay(100);
    //Serial.println(packet);  //for debug only
  }
}
 
void loop() {}

This test was run on a board built around the Fanstel BC832 module. The module retails for $7, but other modules are available for $5 from Fanstel. This board has a place for an external 32.768 kHz oscillator, but this isn't necessary and rings at the same speed without it populated. BC832 Board Traces BC832 Board Interior

As seen in the datasheet excerpt below, the NRF52 has faster times for switching between TX and RX as compared to many other transceiver chips.

A) NRF52 Radio Modes. B) Timing

Back