This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52 timer as counter, Adafruit Feather

This question has been asked before.  I have been using the previous threads to cobble together what is below.  I opened a new ticket as reopening (really) old threads is generally frowned upon.

I am trying to get the hardware counter of and nRF52 on an Adafruit Feather development board working.  I am attempting to count pulses coming though a GPIO pin. Using the previous examples, I have put together something that I think should be working but is not. It is very similar to two previous examples. It compiles, but the input pulse is not indexing the counter. Can anybody spot any glaring problems?

Thanks in advance,

#include <nrf52_bitfields.h>

#define FREQ_MEASURE_PIN 7

void setup() {

  pinMode(LED_RED, OUTPUT);

  NRF_TIMER2->TASKS_STOP = 1;   
  NRF_TIMER2->MODE = TIMER_MODE_MODE_Counter;
  NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
  NRF_TIMER2->TASKS_CLEAR = 1;

  NRF_GPIO->PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos |
                                        GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos |
                                        GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos |
                                        GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;
  
  NRF_PPI->CH[6].EEP = (uint32_t)NRF_GPIOTE->EVENTS_IN[6];  // Connect to channel 6, 6 is arbitrary at this point
  NRF_PPI->CH[6].TEP = (uint32_t)&NRF_TIMER2->TASKS_COUNT;  // Connect task to timer/counter input

  NRF_GPIOTE->CONFIG[6] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
                          FREQ_MEASURE_PIN << GPIOTE_CONFIG_PSEL_Pos |
                          GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos;   

  NRF_PPI->CHENSET = 1 << 6;

  //NRF_GPIOTE -> INTENCLR = 0xFFFFFFFF;

  NRF_TIMER2->TASKS_START = 1;

  Serial.begin(115200);
}


void loop() 
{  
  readCounter();
  delay(1000);
  digitalToggle(LED_RED);
}


//extern "C"
//{
  void readCounter()
  {
    NRF_TIMER2->TASKS_CAPTURE[0] = 1;
    static int counts = NRF_TIMER2->CC[0];
    Serial.print("pulses: "); Serial.println(counts);

    //NRF_TIMER2->TASKS_CLEAR = 1;                  
    //NRF_TIMER2->TASKS_START = 1;
  }
//}

Parents
  • The above code has small problems, but I think the biggest problem was my misuse of the static variable.  I think the compiler should have probably complained but it didn't.  So it is working. Yay.

    Below is the result.  This is tested working on an Adafruit Feather nRF25832, but should probably work on an 840 as well?

    #define FREQ_MEASURE_PIN 7u
    #define PPI_CHANNEL 1u
    
    void setup() {
      Serial.begin(115200);
      pinMode(LED_RED, OUTPUT);
      initCounter();
    }
    
    void loop() 
    {  
      readCounter();
      digitalToggle(LED_RED);
      delay(1000);
    }
    
    void readCounter()
    {
      static int counts;
      NRF_TIMER2->TASKS_CAPTURE[0] = 1;
      counts = NRF_TIMER2->CC[0];
      Serial.print("pulses: "); Serial.println(counts);
      //NRF_TIMER2->TASKS_CLEAR = 1;                  
      //NRF_TIMER2->TASKS_START = 1;
    }
    
    void initCounter()
    {    
      NRF_P0->PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos |
                                          GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos |
                                          GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos |
                                          GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
    
      NRF_PPI->CHEN |= 1 << PPI_CHANNEL;
      NRF_PPI->CH[PPI_CHANNEL].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[PPI_CHANNEL];
      NRF_PPI->CH[PPI_CHANNEL].TEP = (uint32_t)&NRF_TIMER2->TASKS_COUNT;
    
      NRF_GPIOTE->CONFIG[PPI_CHANNEL] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
                                        FREQ_MEASURE_PIN << GPIOTE_CONFIG_PSEL_Pos |
                                        GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; 
    
      NRF_TIMER2->TASKS_STOP = 1;   
      NRF_TIMER2->TASKS_CLEAR = 1;
      NRF_TIMER2->MODE = TIMER_MODE_MODE_LowPowerCounter << TIMER_MODE_MODE_Pos;
      NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
      NRF_TIMER2->TASKS_START = 1;
    }
    

Reply
  • The above code has small problems, but I think the biggest problem was my misuse of the static variable.  I think the compiler should have probably complained but it didn't.  So it is working. Yay.

    Below is the result.  This is tested working on an Adafruit Feather nRF25832, but should probably work on an 840 as well?

    #define FREQ_MEASURE_PIN 7u
    #define PPI_CHANNEL 1u
    
    void setup() {
      Serial.begin(115200);
      pinMode(LED_RED, OUTPUT);
      initCounter();
    }
    
    void loop() 
    {  
      readCounter();
      digitalToggle(LED_RED);
      delay(1000);
    }
    
    void readCounter()
    {
      static int counts;
      NRF_TIMER2->TASKS_CAPTURE[0] = 1;
      counts = NRF_TIMER2->CC[0];
      Serial.print("pulses: "); Serial.println(counts);
      //NRF_TIMER2->TASKS_CLEAR = 1;                  
      //NRF_TIMER2->TASKS_START = 1;
    }
    
    void initCounter()
    {    
      NRF_P0->PIN_CNF[FREQ_MEASURE_PIN] = GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos |
                                          GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos |
                                          GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos |
                                          GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
    
      NRF_PPI->CHEN |= 1 << PPI_CHANNEL;
      NRF_PPI->CH[PPI_CHANNEL].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[PPI_CHANNEL];
      NRF_PPI->CH[PPI_CHANNEL].TEP = (uint32_t)&NRF_TIMER2->TASKS_COUNT;
    
      NRF_GPIOTE->CONFIG[PPI_CHANNEL] = GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos |
                                        FREQ_MEASURE_PIN << GPIOTE_CONFIG_PSEL_Pos |
                                        GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; 
    
      NRF_TIMER2->TASKS_STOP = 1;   
      NRF_TIMER2->TASKS_CLEAR = 1;
      NRF_TIMER2->MODE = TIMER_MODE_MODE_LowPowerCounter << TIMER_MODE_MODE_Pos;
      NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
      NRF_TIMER2->TASKS_START = 1;
    }
    

Children
Related